From e492087dbed03f6d25de2e94e595e3b3ec05c1e2 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Tue, 18 Jul 2006 21:42:16 +0000 Subject: [PATCH] 64-bit fixes General 64-bit fixes and a hack for x86 to Sparc64 crosscompiling problem, where x86 misses 128-bit types. git-svn-id: svn://coreboot.org/openbios/openbios-devel@68 f158a5a8-5612-0410-a976-696ce0be7e32 --- arch/sparc64/entry.S | 5 +++-- arch/sparc64/openbios.c | 5 ++--- config/examples/sparc64_rules.xml | 3 +++ include/openbios/stack.h | 12 ++++++++++++ include/sparc64/io.h | 27 +++++++++++++++++++++------ include/sparc64/pci.h | 27 ++++++++++++++------------- include/sparc64/types.h | 10 ++++++++++ kernel/bootstrap.c | 14 +++++++------- kernel/cross.h | 21 ++++++++++++++++----- kernel/dict.c | 2 +- kernel/forth.c | 25 +++++++++++++++++++++++++ kernel/stack.c | 5 +++-- 12 files changed, 117 insertions(+), 39 deletions(-) diff --git a/arch/sparc64/entry.S b/arch/sparc64/entry.S index 278b667..f7ffede 100644 --- a/arch/sparc64/entry.S +++ b/arch/sparc64/entry.S @@ -35,6 +35,7 @@ entry: ! Extract NWINDOWS from %ver rdpr %ver, %g1 and %g1, 0xf, %g1 + dec %g1 wrpr %g1, 0, %cleanwin wrpr %g1, 0, %cansave wrpr %g0, 0, %canrestore @@ -102,9 +103,9 @@ entry: bne 1b nop - ! setup .rodata + ! setup .rodata, also make .text readable setx _data, %g7, %g5 - setx _rodata, %g7, %g4 + setx _start, %g7, %g4 sub %g5, %g4, %g5 srlx %g5, 16, %g6 ! %g6 = # of 64k .rodata pages set 48, %g7 diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c index 34e18c4..82aabe8 100644 --- a/arch/sparc64/openbios.c +++ b/arch/sparc64/openbios.c @@ -49,8 +49,8 @@ static void init_memory(void) * than that we have serious bloat. */ - PUSH((unsigned int)&_heap); - PUSH((unsigned int)&_eheap); + PUSH((ucell)&_heap); + PUSH((ucell)&_eheap); } static void @@ -128,6 +128,5 @@ int openbios(void) #endif enterforth((xt_t)PC); - return 0; } diff --git a/config/examples/sparc64_rules.xml b/config/examples/sparc64_rules.xml index 9c4645a1..3ed16fa 100644 --- a/config/examples/sparc64_rules.xml +++ b/config/examples/sparc64_rules.xml @@ -10,6 +10,9 @@ ARCH := sparc64 ODIR := obj-$(ARCH) HOSTCC := gcc HOSTCFLAGS := -O2 -g -Wall -W -DFCOMPILER -DBOOTSTRAP $(CROSSCFLAGS) +HOSTCFLAGS+= -Wa,-xarch=v9 -Wa,-64 -m64 -mcpu=ultrasparc -mcmodel=medany +HOSTCFLAGS+= -Wredundant-decls -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations +HOSTCFLAGS+= -Wundef -Wendif-labels -Wstrict-aliasing HOSTINCLUDES := -Iinclude -Ikernel/include -I$(ODIR)/target/include CC := gcc diff --git a/include/openbios/stack.h b/include/openbios/stack.h index c1d786f..90cfee4 100644 --- a/include/openbios/stack.h +++ b/include/openbios/stack.h @@ -52,15 +52,27 @@ static inline void DDROP(void) { } static inline void DPUSH(ducell value) { +#ifdef NEED_FAKE_INT128_T + dstack[++dstackcnt] = (cell) value.lo; + dstack[++dstackcnt] = (cell) value.hi; +#else dstack[++dstackcnt] = (cell) value; dstack[++dstackcnt] = (cell) (value >> bitspercell); +#endif } static inline ducell DPOP(void) { +#ifdef NEED_FAKE_INT128_T + ducell du; + du.hi = (ucell) dstack[dstackcnt--]; + du.lo = (ucell) dstack[dstackcnt--]; + return du; +#else ducell du; du = ((ducell) ((ucell) dstack[dstackcnt--]) << bitspercell); du |= (ucell) dstack[dstackcnt--]; return du; +#endif } static inline ucell GETTOS(void) { diff --git a/include/sparc64/io.h b/include/sparc64/io.h index d284e67..b368e0f 100644 --- a/include/sparc64/io.h +++ b/include/sparc64/io.h @@ -74,13 +74,15 @@ static inline void out_8(volatile unsigned char *addr, int val) static inline int in_le16(volatile unsigned short *addr) { - int ret; + int ret, tmp; // XXX __asm__ __volatile__("lduha [%1] 0x15, %0\n\t" :"=r"(ret):"r"(addr):"memory"); - return ret; + tmp = (ret << 8) & 0xff00; + tmp |= (ret >> 8) & 0xff; + return tmp; } static inline int in_be16(volatile unsigned short *addr) @@ -95,9 +97,13 @@ static inline int in_be16(volatile unsigned short *addr) static inline void out_le16(volatile unsigned short *addr, int val) { + unsigned tmp; + // XXX + tmp = (val << 8) & 0xff00; + tmp |= (val >> 8) & 0xff; __asm__ __volatile__("stha %0, [%1] 0x15\n\t" - : : "r"(val), "r"(addr):"memory"); + : : "r"(tmp), "r"(addr):"memory"); } static inline void out_be16(volatile unsigned short *addr, int val) @@ -108,13 +114,17 @@ static inline void out_be16(volatile unsigned short *addr, int val) static inline unsigned in_le32(volatile unsigned *addr) { - unsigned ret; + unsigned ret, tmp; // XXX __asm__ __volatile__("lduwa [%1] 0x15, %0\n\t" :"=r"(ret):"r"(addr):"memory"); - return ret; + tmp = ret << 24; + tmp |= (ret << 8) & 0xff0000; + tmp |= (ret >> 8) & 0xff00; + tmp |= (ret >> 24) & 0xff; + return tmp; } static inline unsigned in_be32(volatile unsigned *addr) @@ -129,9 +139,14 @@ static inline unsigned in_be32(volatile unsigned *addr) static inline void out_le32(volatile unsigned *addr, int val) { + unsigned tmp; // XXX + tmp = val << 24; + tmp |= (val << 8) & 0xff0000; + tmp |= (val >> 8) & 0xff00; + tmp |= (val >> 24) & 0xff; __asm__ __volatile__("stwa %0, [%1] 0x15\n\t" - : : "r"(val), "r"(addr):"memory"); + : : "r"(tmp), "r"(addr):"memory"); } static inline void out_be32(volatile unsigned *addr, int val) diff --git a/include/sparc64/pci.h b/include/sparc64/pci.h index d6e24dd..1128166 100644 --- a/include/sparc64/pci.h +++ b/include/sparc64/pci.h @@ -24,42 +24,43 @@ #define PCI_FN(pcidev) ((uint8_t) ((pcidev) >> 8) & 7) #define APB_SPECIAL_BASE 0x1fe00000000ULL -#define PCI_CONFIG (APB_SPECIAL_BASE + 0x2000) +#define PCI_CONFIG (APB_SPECIAL_BASE + 0x1000000ULL) +#define APB_MEM_BASE 0x1ff00000000ULL static inline uint8_t pci_config_read8(pci_addr dev, uint8_t reg) { - out_be32((void *)PCI_CONFIG, dev | (reg & ~3)); - return in_8((void *)(PCI_CONFIG | (reg & 3))); + out_le32((void *)PCI_CONFIG, dev | (reg & ~3)); + return in_8((void *)(APB_MEM_BASE | (reg & 3))); } static inline uint16_t pci_config_read16(pci_addr dev, uint8_t reg) { - out_be32((void *)PCI_CONFIG, dev | (reg & ~3)); - return in_be16((void *)(PCI_CONFIG | (reg & 2))); + out_le32((void *)PCI_CONFIG, dev | (reg & ~3)); + return in_le16((void *)(APB_MEM_BASE | (reg & 2))); } static inline uint32_t pci_config_read32(pci_addr dev, uint8_t reg) { - out_be32((void *)PCI_CONFIG, dev | reg); - return in_be32((void *)(PCI_CONFIG | reg)); + out_le32((void *)PCI_CONFIG, dev | reg); + return in_le32((void *)(APB_MEM_BASE | reg)); } static inline void pci_config_write8(pci_addr dev, uint8_t reg, uint8_t val) { - out_be32((void *)PCI_CONFIG, dev | (reg & ~3)); - out_8((void *)(PCI_CONFIG | (reg & 3)), val); + out_le32((void *)PCI_CONFIG, dev | (reg & ~3)); + out_8((void *)(APB_MEM_BASE | (reg & 3)), val); } static inline void pci_config_write16(pci_addr dev, uint8_t reg, uint16_t val) { - out_be32((void *)PCI_CONFIG, dev | (reg & ~3)); - out_be16((void *)(PCI_CONFIG | (reg & 2)), val); + out_le32((void *)PCI_CONFIG, dev | (reg & ~3)); + out_le16((void *)(APB_MEM_BASE | (reg & 2)), val); } static inline void pci_config_write32(pci_addr dev, uint8_t reg, uint32_t val) { - out_be32((void *)PCI_CONFIG, dev | reg); - out_be32((void *)(PCI_CONFIG | reg), val); + out_le32((void *)PCI_CONFIG, dev | reg); + out_le32((void *)(APB_MEM_BASE | reg), val); } #else /* !PCI_CONFIG_1 */ diff --git a/include/sparc64/types.h b/include/sparc64/types.h index 5356e70..b512125 100644 --- a/include/sparc64/types.h +++ b/include/sparc64/types.h @@ -13,6 +13,16 @@ #include +#ifdef NEED_FAKE_INT128_T +typedef struct { + uint64_t hi; + uint64_t lo; +} blob_128_t; + +typedef blob_128_t __int128_t; +typedef blob_128_t __uint128_t; +#endif + /* cell based types */ typedef int64_t cell; typedef uint64_t ucell; diff --git a/kernel/bootstrap.c b/kernel/bootstrap.c index e266092..e53c88c 100644 --- a/kernel/bootstrap.c +++ b/kernel/bootstrap.c @@ -43,11 +43,11 @@ static int errors = 0; static int segfault = 0; int verbose = 0; -static FILE *srcfiles[64]; +static FILE *srcfiles[128]; static unsigned int cursrc = 0; #ifdef NATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH -unsigned long base_address; +ucell base_address; #endif /* include path handling */ @@ -116,7 +116,7 @@ static void relocation_table(unsigned char * dict_one, unsigned char *dict_two, bit=i&~(-BITS); if(d1[i]==d2[i]) { - reloc_table[pos] &= target_ucell(~(1UL<= pointer2cell(dict_one) && @@ -124,7 +124,7 @@ static void relocation_table(unsigned char * dict_one, unsigned char *dict_two, // printk("\nWARNING: inconsistent relocation (%x:%x)!\n", d1[i], d2[i]); } else { /* This is a pointer, it needs relocation, d2==dict */ - reloc_table[pos] |= target_ucell(1UL<si_addr); - printk("dict=%p here=%p(dict+0x%x) pc=0x%x(dict+0x%x)\n", + printk("dict=%p here=%p(dict+0x%" FMT_CELL_x ") pc=0x%" FMT_CELL_x "(dict+0x%" FMT_CELL_x ")\n", dict, dict + dicthead, dicthead, PC, PC - pointer2cell(dict)); - printk("dstackcnt=%d rstackcnt=%d instruction=%x\n", + printk("dstackcnt=%d rstackcnt=%d instruction=%" FMT_CELL_x "\n", dstackcnt, rstackcnt, addr); printdstack(); @@ -833,7 +833,7 @@ void exception(cell no) printk(" undefined word.\n"); break; default: - printk("\nError %d occured.\n", no); + printk("\nError %" FMT_CELL_d " occured.\n", no); } exit(1); } diff --git a/kernel/cross.h b/kernel/cross.h index 480dace..90e5085 100644 --- a/kernel/cross.h +++ b/kernel/cross.h @@ -46,10 +46,15 @@ #define target_ucell(value) (target_long(value)) #define target_cell(value) (target_long(value)) #elif BITS==64 +#ifdef NATIVE_BITWIDTH_LARGER_THAN_HOST_BITWIDTH +#define target_ucell(value) ( ((ucell)target_long((value)&0xffffffff))<<32 ) +#define target_cell(value) ( ((cell)target_long((value)&0xffffffff))<<32 ) +#else #define target_ucell(value) ( ((ucell)target_long((value)&0xffffffff))<<32 | \ ((ucell)target_long((value)>>32)) ) #define target_cell(value) ( ((cell)target_long((value)&0xffffffff))<<32 | \ ((cell)target_long((value)>>32)) ) +#endif #else #error "Endianness not supported. Please report." #endif @@ -103,17 +108,23 @@ #ifdef NATIVE_BITWIDTH_EQUALS_HOST_BITWIDTH #define pointer2cell(x) ((ucell)(x)) #define cell2pointer(x) ((u8 *)(x)) +#define FMT_CELL_x "x" +#define FMT_CELL_d "d" #endif #ifdef NATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH -extern unsigned long base_address; -#define pointer2cell(x) ((ucell)(((unsigned long)x)-base_address)) -#define cell2pointer(x) ((u8 *)(((unsigned long)x)+base_address)) +extern ucell base_address; +#define pointer2cell(x) ((ucell)(((unsigned long)(x))-base_address)) +#define cell2pointer(x) ((u8 *)(((unsigned long)(x))+base_address)) +#define FMT_CELL_x "x" +#define FMT_CELL_d "d" #endif #ifdef NATIVE_BITWIDTH_LARGER_THAN_HOST_BITWIDTH -#define pointer2cell(x) ((ucell)(x)) -#define cell2pointer(x) ((u8 *)((unsigned long)x&0xFFFFFFFFUL)) +#define pointer2cell(x) ((ucell)(unsigned long)(x)) +#define cell2pointer(x) ((u8 *)((unsigned long)(x)&0xFFFFFFFFUL)) +#define FMT_CELL_x "llx" +#define FMT_CELL_d "lld" #endif #endif diff --git a/kernel/dict.c b/kernel/dict.c index b67b58c..8df807d 100644 --- a/kernel/dict.c +++ b/kernel/dict.c @@ -119,7 +119,7 @@ void dump_header(dictionary_header_t *header) printk(" relocation: %s\n", header->relocation?"yes":"no"); printk(" checksum: %08x\n", target_long(header->checksum)); printk(" length: %08x\n", target_long(header->length)); - printk(" last: %08x\n", target_cell(header->last)); + printk(" last: %0" FMT_CELL_x "\n", target_cell(header->last)); } ucell load_dictionary(const char *data, ucell len) diff --git a/kernel/forth.c b/kernel/forth.c index 5869a39..8fb2688 100644 --- a/kernel/forth.c +++ b/kernel/forth.c @@ -330,8 +330,13 @@ static void mudivmod(void) { const ucell b = POP(); const ducell a = DPOP(); +#ifdef NEED_FAKE_INT128_T + fprintf(stderr, "mudivmode called\n"); + exit(-1); +#else PUSH(a % b); DPUSH(a / b); +#endif } @@ -475,7 +480,12 @@ static void dplus(void) { const dcell d2 = DPOP(); const dcell d1 = DPOP(); +#ifdef NEED_FAKE_INT128_T + fprintf(stderr, "dplus called\n"); + exit(-1); +#else DPUSH(d1 + d2); +#endif } @@ -487,7 +497,12 @@ static void dminus(void) { const dcell d2 = DPOP(); const dcell d1 = DPOP(); +#ifdef NEED_FAKE_INT128_T + fprintf(stderr, "dminus called\n"); + exit(-1); +#else DPUSH(d1 - d2); +#endif } @@ -499,7 +514,12 @@ static void mmult(void) { const cell u2 = POP(); const cell u1 = POP(); +#ifdef NEED_FAKE_INT128_T + fprintf(stderr, "mmult called\n"); + exit(-1); +#else DPUSH((dcell) u1 * u2); +#endif } @@ -511,7 +531,12 @@ static void ummult(void) { const ucell u2 = POP(); const ucell u1 = POP(); +#ifdef NEED_FAKE_INT128_T + fprintf(stderr, "ummult called\n"); + exit(-1); +#else DPUSH((ducell) u1 * u2); +#endif } diff --git a/kernel/stack.c b/kernel/stack.c index 043a42e..b32fc3a 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -9,6 +9,7 @@ #include "openbios/config.h" #include "openbios/stack.h" +#include "cross.h" #define dstacksize 512 int dstackcnt = 0; @@ -24,7 +25,7 @@ void printdstack(void) int i; printk("dstack:"); for (i = 0; i <= dstackcnt; i++) { - printk(" 0x%x", dstack[i]); + printk(" 0x%" FMT_CELL_x , dstack[i]); } printk("\n"); } @@ -35,7 +36,7 @@ void printrstack(void) int i; printk("rstack:"); for (i = 0; i <= rstackcnt; i++) { - printk(" 0x%x", rstack[i]); + printk(" 0x%" FMT_CELL_x , rstack[i]); } printk("\n"); }