amd64 port (Jocelyn Mayer)

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@762 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2004-04-26 19:44:02 +00:00
parent f658b4db79
commit 4f2ac23784
9 changed files with 55 additions and 198 deletions

171
amd64.ld
View file

@ -169,174 +169,3 @@ SECTIONS
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64");
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0x60000000 + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init :
{
KEEP (*(.init))
} =0x90909090
.plt : { *(.plt) }
.text :
{
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
} =0x90909090
.fini :
{
KEEP (*(.fini))
} =0x90909090
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(64 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { *(.preinit_array) }
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { *(.init_array) }
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { *(.fini_array) }
PROVIDE (__fini_array_end = .);
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
.dynamic : { *(.dynamic) }
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.got : { *(.got.plt) *(.got) }
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(64 / 8);
}
. = ALIGN(64 / 8);
_end = .;
PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View file

@ -335,7 +335,7 @@ static inline int ldsw_raw(void *ptr)
static inline int ldl_raw(void *ptr)
{
#if defined(__i386__)
#if defined(__i386__) || defined(__x86_64__)
int val;
asm volatile ("movl %1, %0\n"
"bswap %0\n"
@ -372,7 +372,7 @@ static inline void stw_raw(void *ptr, int v)
static inline void stl_raw(void *ptr, int v)
{
#if defined(__i386__)
#if defined(__i386__) || defined(__x86_64__)
asm volatile ("bswap %0\n"
"movl %0, %1\n"
: "=r" (v)

View file

@ -29,8 +29,18 @@
#error TARGET_LONG_BITS must be defined before including this header
#endif
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define HOST_LONG_BITS 64
#else
#define HOST_LONG_BITS 32
#endif
#ifndef TARGET_PHYS_ADDR_BITS
#if TARGET_LONG_BITS >= HOST_LONG_BITS
#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
#else
#define TARGET_PHYS_ADDR_BITS HOST_LONG_BITS
#endif
#endif
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
@ -47,7 +57,11 @@ typedef uint64_t target_ulong;
#endif
/* target_phys_addr_t is the type of a physical address (its size can
be different from 'target_ulong') */
be different from 'target_ulong'). We have sizeof(target_phys_addr)
= max(sizeof(unsigned long),
sizeof(size_of_target_physical_address)) because we must pass a
host pointer to memory operations in some cases */
#if TARGET_PHYS_ADDR_BITS == 32
typedef uint32_t target_phys_addr_t;
#elif TARGET_PHYS_ADDR_BITS == 64
@ -56,12 +70,6 @@ typedef uint64_t target_phys_addr_t;
#error TARGET_PHYS_ADDR_BITS undefined
#endif
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define HOST_LONG_BITS 64
#else
#define HOST_LONG_BITS 32
#endif
#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
#define EXCP_INTERRUPT 256 /* async interruption */
@ -79,9 +87,9 @@ typedef struct CPUTLBEntry {
bit 3 : indicates that the entry is invalid
bit 2..0 : zero
*/
uint32_t address;
target_ulong address;
/* addend to virtual address to get physical address */
uint32_t addend;
target_phys_addr_t addend;
} CPUTLBEntry;
#endif

View file

@ -25,12 +25,21 @@
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
/* XXX may be done for all 64 bits targets ? */
#if defined (__x86_64__)
typedef unsigned long uint64_t;
#else
typedef unsigned long long uint64_t;
#endif
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
#if defined (__x86_64__)
typedef signed long int64_t;
#else
typedef signed long long int64_t;
#endif
#define INT8_MIN (-128)
#define INT16_MIN (-32767-1)

25
exec.c
View file

@ -167,8 +167,8 @@ static inline PageDesc *page_find(unsigned int index)
}
#if !defined(CONFIG_USER_ONLY)
static void tlb_protect_code(CPUState *env, uint32_t addr);
static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr, target_ulong vaddr);
static void tlb_protect_code(CPUState *env, target_ulong addr);
static void tlb_unprotect_code_phys(CPUState *env, unsigned long phys_addr, target_ulong vaddr);
static inline VirtPageDesc *virt_page_find_alloc(unsigned int index)
{
@ -1270,7 +1270,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
#endif
}
static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, uint32_t addr)
static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, target_ulong addr)
{
if (addr == (tlb_entry->address &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
@ -1282,7 +1282,7 @@ static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, uint32_t addr)
/* update the TLBs so that writes to code in the virtual page 'addr'
can be detected */
static void tlb_protect_code(CPUState *env, uint32_t addr)
static void tlb_protect_code(CPUState *env, target_ulong addr)
{
int i;
@ -1299,7 +1299,7 @@ static void tlb_protect_code(CPUState *env, uint32_t addr)
}
static inline void tlb_unprotect_code2(CPUTLBEntry *tlb_entry,
uint32_t phys_addr)
unsigned long phys_addr)
{
if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_CODE &&
((tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend) == phys_addr) {
@ -1309,7 +1309,7 @@ static inline void tlb_unprotect_code2(CPUTLBEntry *tlb_entry,
/* update the TLB so that writes in physical page 'phys_addr' are no longer
tested self modifying code */
static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr, target_ulong vaddr)
static void tlb_unprotect_code_phys(CPUState *env, unsigned long phys_addr, target_ulong vaddr)
{
int i;
@ -1335,7 +1335,7 @@ static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
{
CPUState *env;
target_ulong length, start1;
unsigned long length, start1;
int i;
start &= TARGET_PAGE_MASK;
@ -1420,10 +1420,11 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
int is_user, int is_softmmu)
{
PageDesc *p;
target_ulong pd;
unsigned long pd;
TranslationBlock *first_tb;
unsigned int index;
target_ulong address, addend;
target_ulong address;
unsigned long addend;
int ret;
p = page_find(paddr >> TARGET_PAGE_BITS);
@ -1825,19 +1826,19 @@ static CPUWriteMemoryFunc *code_mem_write[3] = {
code_mem_writel,
};
static void notdirty_mem_writeb(uint32_t addr, uint32_t val)
static void notdirty_mem_writeb(target_phys_addr_t addr, uint32_t val)
{
stb_raw((uint8_t *)addr, val);
tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
}
static void notdirty_mem_writew(uint32_t addr, uint32_t val)
static void notdirty_mem_writew(target_phys_addr_t addr, uint32_t val)
{
stw_raw((uint8_t *)addr, val);
tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
}
static void notdirty_mem_writel(uint32_t addr, uint32_t val)
static void notdirty_mem_writel(target_phys_addr_t addr, uint32_t val)
{
stl_raw((uint8_t *)addr, val);
tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);

View file

@ -92,7 +92,7 @@ typedef struct VGAState {
uint8_t dac_write_index;
uint8_t dac_cache[3]; /* used when writing */
uint8_t palette[768];
uint32_t bank_offset;
int32_t bank_offset;
#ifdef CONFIG_BOCHS_VBE
uint16_t vbe_index;
uint16_t vbe_regs[VBE_DISPI_INDEX_NB];

View file

@ -152,6 +152,9 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
int flags, int fd, unsigned long offset)
{
unsigned long ret, end, host_start, host_end, retaddr, host_offset, host_len;
#if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__)
static unsigned long last_start = 0x40000000;
#endif
#ifdef DEBUG_MMAP
{
@ -190,8 +193,10 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
if (!(flags & MAP_FIXED)) {
#if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__)
/* tell the kenel to search at the same place as i386 */
if (host_start == 0)
host_start = 0x40000000;
if (host_start == 0) {
host_start = last_start;
last_start += HOST_PAGE_ALIGN(len);
}
#endif
if (host_page_size != real_host_page_size) {
/* NOTE: this code is only for debugging with '-p' option */

View file

@ -2402,9 +2402,14 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
goto unimplemented;
case TARGET_NR__llseek:
{
#if defined (__x86_64__)
ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
*(int64_t *)arg4 = ret;
#else
int64_t res;
ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
*(int64_t *)arg4 = tswap64(res);
#endif
}
break;
case TARGET_NR_getdents:

View file

@ -194,7 +194,7 @@ int cpu_restore_state(TranslationBlock *tb,
fprintf(logfile, "0x%04x: 0x%08x\n", i, gen_opc_pc[i]);
}
}
fprintf(logfile, "spc=0x%08lx j=0x%x eip=0x%lx cs_base=%lx\n",
fprintf(logfile, "spc=0x%08lx j=0x%x eip=0x%x cs_base=%x\n",
searched_pc, j, gen_opc_pc[j] - tb->cs_base, tb->cs_base);
}
#endif