mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -13,6 +13,16 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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<<bit));
|
||||
reloc_table[pos] &= target_ucell(~((ucell)1UL<<bit));
|
||||
|
||||
// This check might bring false positives in data.
|
||||
//if(d1[i] >= 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<<bit);
|
||||
reloc_table[pos] |= target_ucell((ucell)1UL<<bit);
|
||||
d2[i] = target_ucell(target_ucell(d2[i]) - pointer2cell(d2));
|
||||
}
|
||||
}
|
||||
@@ -792,9 +792,9 @@ segv_handler(int signo __attribute__ ((unused)),
|
||||
addr = read_cell(cell2pointer(PC));
|
||||
|
||||
printk("panic: segmentation violation at %p\n", (char *)si->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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user