mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
blueswirl -14 sparc32 related
git-svn-id: svn://coreboot.org/openbios/openbios-devel@24 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -92,16 +92,16 @@ int aout_load(struct sys_info *info, const char *filename, const char *cmdline)
|
||||
|
||||
if (N_MAGIC(ehdr) == NMAGIC) {
|
||||
if (lfile_read(start, ehdr.a_text) != ehdr.a_text) {
|
||||
printf("Can't read program text segment (size 0x%x)\n", ehdr.a_text);
|
||||
printf("Can't read program text segment (size 0x%lx)\n", ehdr.a_text);
|
||||
goto out;
|
||||
}
|
||||
if (lfile_read(start + N_DATADDR(ehdr), ehdr.a_data) != ehdr.a_data) {
|
||||
printf("Can't read program data segment (size 0x%x)\n", ehdr.a_data);
|
||||
printf("Can't read program data segment (size 0x%lx)\n", ehdr.a_data);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (lfile_read(start, size) != size) {
|
||||
printf("Can't read program (size 0x%x)\n", size);
|
||||
printf("Can't read program (size 0x%lx)\n", size);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ void __exit_context(void); /* assembly routine */
|
||||
* It is placed at the bottom of our stack, and loaded by assembly routine
|
||||
* to start us up.
|
||||
*/
|
||||
struct context main_ctx __attribute__((section (".initctx"))) = {
|
||||
.regs[REG_SP] = (uint32_t) SP_LOC(&main_ctx),
|
||||
struct context main_ctx = {
|
||||
.regs[REG_SP] = (uint32_t) &_estack - 96,
|
||||
.pc = (uint32_t) start_main,
|
||||
.npc = (uint32_t) start_main + 4,
|
||||
.return_addr = (uint32_t) __exit_context,
|
||||
|
||||
@@ -64,6 +64,7 @@ entry:
|
||||
or %g3, 0x1, %g3
|
||||
sta %g3, [%g2] ASI_M_BYPASS
|
||||
add %g2, 0x4, %g2 ! s+0x800
|
||||
#if 0
|
||||
set 0x40, %g6
|
||||
set ((7 << 2) | 2), %g3 ! 7 = U: --- S: RWX (main memory)
|
||||
1: sta %g3, [%g2] ASI_M_BYPASS
|
||||
@@ -71,6 +72,9 @@ entry:
|
||||
deccc %g6
|
||||
bne 1b
|
||||
nop
|
||||
#else
|
||||
add %g2, 0x100, %g2
|
||||
#endif
|
||||
! s+0x900
|
||||
add %g2, 0xa00 - 0x900, %g3 ! l3 table for rom at s+0xa00
|
||||
add %g2, 0x0d0, %g2 ! s+0x9d0
|
||||
@@ -182,7 +186,7 @@ entry:
|
||||
|
||||
/* Zero out our BSS section. */
|
||||
set _bss - 4, %o0 ! First address of BSS
|
||||
set _end, %o1 ! Last address of BSS
|
||||
set _estack, %o1 ! Last address of BSS
|
||||
ba 2f
|
||||
nop
|
||||
1:
|
||||
@@ -192,8 +196,6 @@ entry:
|
||||
bl 1b
|
||||
add %o0, 0x4, %o0
|
||||
|
||||
set _estack, %sp
|
||||
mov 0, %fp
|
||||
mov 2, %g1
|
||||
wr %g1, 0x0, %wim ! make window 1 invalid
|
||||
WRITE_PAUSE
|
||||
@@ -218,7 +220,7 @@ entry:
|
||||
wr %g3, PSR_ET, %psr
|
||||
WRITE_PAUSE
|
||||
|
||||
call openbios
|
||||
call __switch_context_nosave
|
||||
nop
|
||||
|
||||
/* We get here when the main context switches back to
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
OUTPUT_FORMAT(elf32-sparc)
|
||||
OUTPUT_ARCH(sparc)
|
||||
|
||||
/* Qemu ELF loader can't handle very complex files, so we put ELFBoot
|
||||
info to rodata and put initctx to data.*/
|
||||
|
||||
ENTRY(trap_table)
|
||||
|
||||
/* Initial load address
|
||||
@@ -35,6 +38,7 @@ SECTIONS
|
||||
sound_drivers_end = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.note.ELFBoot)
|
||||
}
|
||||
.data ALIGN(4096): {
|
||||
_data = .;
|
||||
@@ -68,18 +72,12 @@ SECTIONS
|
||||
_estack = .;
|
||||
}
|
||||
|
||||
.initctx : {
|
||||
/* Initial contents of stack. This MUST BE just after the stack. */
|
||||
*(.initctx)
|
||||
}
|
||||
/* Putting ELF notes near beginning of file might help bootloaders.
|
||||
* We discard .note sections other than .note.ELFBoot,
|
||||
* because some versions of GCC generates useless ones. */
|
||||
.note : { *(.note.ELFBoot) }
|
||||
|
||||
. = ALIGN(4096);
|
||||
_end = .;
|
||||
_iomem = _end + IOMEM_SIZE;
|
||||
|
||||
/DISCARD/ : { *(.comment.*) *(.note.*) }
|
||||
/* We discard .note sections other than .note.ELFBoot,
|
||||
* because some versions of GCC generates useless ones. */
|
||||
|
||||
/DISCARD/ : { *(.comment*) *(.note.*) }
|
||||
}
|
||||
|
||||
@@ -32,22 +32,11 @@ int printk( const char *fmt, ... )
|
||||
return i;
|
||||
}
|
||||
|
||||
// dumb quick memory allocator until we get a decent thing here.
|
||||
|
||||
#define MEMSIZE 128*1024
|
||||
static char memory[MEMSIZE];
|
||||
static void *memptr=memory;
|
||||
static int memsize=MEMSIZE;
|
||||
|
||||
void *malloc(int size)
|
||||
{
|
||||
void *ret=(void *)0;
|
||||
if(memsize>=size) {
|
||||
memsize-=size;
|
||||
ret=memptr;
|
||||
memptr+=size;
|
||||
}
|
||||
return ret;
|
||||
extern struct mem cmem;
|
||||
|
||||
return mem_alloc(&cmem, size, 4);
|
||||
}
|
||||
|
||||
void free(void *ptr)
|
||||
|
||||
62
arch/sparc32/libgcc/__lshrdi3.c
Normal file
62
arch/sparc32/libgcc/__lshrdi3.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
|
||||
/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
typedef int SItype __attribute__ ((mode (SI)));
|
||||
typedef unsigned int USItype __attribute__ ((mode (SI)));
|
||||
typedef int DItype __attribute__ ((mode (DI)));
|
||||
typedef int word_type __attribute__ ((mode (__word__)));
|
||||
|
||||
struct DIstruct {SItype high, low;};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct DIstruct s;
|
||||
DItype ll;
|
||||
} DIunion;
|
||||
|
||||
DItype
|
||||
__lshrdi3 (DItype u, word_type b)
|
||||
{
|
||||
DIunion w;
|
||||
word_type bm;
|
||||
DIunion uu;
|
||||
|
||||
if (b == 0)
|
||||
return u;
|
||||
|
||||
uu.ll = u;
|
||||
|
||||
bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
|
||||
if (bm <= 0)
|
||||
{
|
||||
w.s.high = 0;
|
||||
w.s.low = (USItype)uu.s.high >> -bm;
|
||||
}
|
||||
else
|
||||
{
|
||||
USItype carries = (USItype)uu.s.high << bm;
|
||||
w.s.high = (USItype)uu.s.high >> b;
|
||||
w.s.low = ((USItype)uu.s.low >> b) | carries;
|
||||
}
|
||||
|
||||
return w.ll;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
<object source="__udivdi3.c"/>
|
||||
<object source="__udivmoddi4.c"/>
|
||||
<object source="__umoddi3.c"/>
|
||||
<object source="__lshrdi3.c"/>
|
||||
</library>
|
||||
|
||||
</build>
|
||||
|
||||
@@ -8,26 +8,35 @@ static int load_fd=-1;
|
||||
int file_open(const char *filename)
|
||||
{
|
||||
load_fd=open_io(filename);
|
||||
/* if(load_fd!=-1) */ seek_io(load_fd, 0);
|
||||
if(load_fd >= 0)
|
||||
seek_io(load_fd, 0);
|
||||
return load_fd>-1;
|
||||
}
|
||||
|
||||
int lfile_read(void *buf, unsigned long len)
|
||||
{
|
||||
int ret;
|
||||
ret=read_io(load_fd, buf, len);
|
||||
int ret = 0;
|
||||
|
||||
if (load_fd >= 0)
|
||||
ret=read_io(load_fd, buf, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int file_seek(unsigned long offset)
|
||||
{
|
||||
return seek_io(load_fd, offset);
|
||||
if (load_fd >= 0)
|
||||
return seek_io(load_fd, offset);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long file_size(void)
|
||||
{
|
||||
llong fpos, fsize;
|
||||
|
||||
if (load_fd < 0)
|
||||
return 0;
|
||||
|
||||
/* save current position */
|
||||
fpos=tell(load_fd);
|
||||
|
||||
|
||||
@@ -19,11 +19,10 @@
|
||||
void boot(void);
|
||||
void ob_ide_init(void);
|
||||
|
||||
static char intdict[256 * 1024];
|
||||
static unsigned char intdict[256 * 1024];
|
||||
|
||||
static void init_memory(void)
|
||||
{
|
||||
extern char _heap, _eheap;
|
||||
|
||||
/* push start and end of available memory to the stack
|
||||
* so that the forth word QUIT can initialize memory
|
||||
@@ -36,7 +35,7 @@ static void init_memory(void)
|
||||
PUSH((unsigned int)&_eheap);
|
||||
}
|
||||
|
||||
void exception(cell no)
|
||||
void exception(__attribute__((unused))cell no)
|
||||
{
|
||||
/* The exception mechanism is used during bootstrap to catch
|
||||
* build errors. In a running system this is a noop since we
|
||||
@@ -68,6 +67,9 @@ arch_init( void )
|
||||
int openbios(void)
|
||||
{
|
||||
extern struct sys_info sys_info;
|
||||
extern struct mem cmem;
|
||||
|
||||
mem_init(&cmem, (char *) &_vmem, (char *)&_evmem);
|
||||
#ifdef CONFIG_DEBUG_CONSOLE
|
||||
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
|
||||
uart_init(CONFIG_SERIAL_PORT, CONFIG_SERIAL_SPEED);
|
||||
|
||||
@@ -65,7 +65,8 @@ static int prop_mem_reg[3];
|
||||
static int prop_mem_avail[3];
|
||||
static int prop_vmem_avail[6];
|
||||
|
||||
static void doublewalk(unsigned ptab1, unsigned va)
|
||||
static void doublewalk(__attribute__((unused)) unsigned int ptab1,
|
||||
__attribute__((unused)) unsigned int va)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -215,14 +216,14 @@ static void obp_reboot(char *str)
|
||||
for (;;) {}
|
||||
}
|
||||
|
||||
static void obp_abort()
|
||||
static void obp_abort(void)
|
||||
{
|
||||
printk("abort, power off\n");
|
||||
outb(0x71910000, 1);
|
||||
for (;;) {}
|
||||
}
|
||||
|
||||
static void obp_halt()
|
||||
static void obp_halt(void)
|
||||
{
|
||||
printk("halt, power off\n");
|
||||
outb(0x71910000, 1);
|
||||
@@ -278,7 +279,7 @@ static char *obp_dumb_mmap(char *va, __attribute__((unused)) int which_io,
|
||||
unsigned int off;
|
||||
unsigned int mva;
|
||||
|
||||
DPRINTF("obp_dumb_mmap: virta 0x%x, which_io %d, paddr 0x%x, sz %d\n", va, which_io, pa, size);
|
||||
DPRINTF("obp_dumb_mmap: virta 0x%x, which_io %d, paddr 0x%x, sz %d\n", (unsigned int)va, which_io, pa, size);
|
||||
off = pa & (PAGE_SIZE-1);
|
||||
npages = (off + size + (PAGE_SIZE-1)) / PAGE_SIZE;
|
||||
pa &= ~(PAGE_SIZE-1);
|
||||
@@ -296,7 +297,7 @@ static char *obp_dumb_mmap(char *va, __attribute__((unused)) int which_io,
|
||||
static void obp_dumb_munmap(__attribute__((unused)) char *va,
|
||||
__attribute__((unused)) unsigned int size)
|
||||
{
|
||||
DPRINTF("obp_dumb_munmap: virta 0x%x, sz %d\n", va, size);
|
||||
DPRINTF("obp_dumb_munmap: virta 0x%x, sz %d\n", (unsigned int)va, size);
|
||||
}
|
||||
|
||||
static int obp_devread(int dev_desc, char *buf, int nbytes)
|
||||
@@ -360,14 +361,18 @@ static int obp_inst2pkg(int dev_desc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int obp_cpustart(unsigned int whichcpu, int ctxtbl_ptr,
|
||||
int thiscontext, char *prog_counter)
|
||||
static int obp_cpustart(__attribute__((unused))unsigned int whichcpu,
|
||||
__attribute__((unused))int ctxtbl_ptr,
|
||||
__attribute__((unused))int thiscontext,
|
||||
__attribute__((unused))char *prog_counter)
|
||||
{
|
||||
//int cpu, found;
|
||||
#ifdef CONFIG_DEBUG_OBP
|
||||
struct linux_prom_registers *smp_ctable = (void *)ctxtbl_ptr;
|
||||
#endif
|
||||
|
||||
DPRINTF("obp_cpustart: cpu %d, ctxptr 0x%x, ctx %d, pc 0x%x\n", whichcpu,
|
||||
smp_ctable->phys_addr, thiscontext, prog_counter);
|
||||
smp_ctable->phys_addr, thiscontext, (unsigned int)prog_counter);
|
||||
#if 0
|
||||
found = obp_getprop(whichcpu, "mid", (char *)&cpu);
|
||||
if (found == -1)
|
||||
|
||||
@@ -21,6 +21,40 @@
|
||||
/* XXX: totally bogus for sparc, need to save and restore all windows */
|
||||
__switch_context:
|
||||
/* Save everything in current stack */
|
||||
set __context, %g1
|
||||
st %g2, [%g1 + 8]
|
||||
st %g3, [%g1 + 12]
|
||||
st %g4, [%g1 + 16]
|
||||
st %g5, [%g1 + 20]
|
||||
st %g6, [%g1 + 24]
|
||||
st %g7, [%g1 + 28]
|
||||
|
||||
st %o0, [%g1 + 32]
|
||||
st %o1, [%g1 + 36]
|
||||
st %o2, [%g1 + 40]
|
||||
st %o3, [%g1 + 44]
|
||||
st %o4, [%g1 + 48]
|
||||
st %o5, [%g1 + 52]
|
||||
st %o6, [%g1 + 56]
|
||||
st %o7, [%g1 + 60]
|
||||
|
||||
st %l0, [%g1 + 64]
|
||||
st %l1, [%g1 + 68]
|
||||
st %l2, [%g1 + 72]
|
||||
st %l3, [%g1 + 76]
|
||||
st %l4, [%g1 + 80]
|
||||
st %l5, [%g1 + 84]
|
||||
st %l6, [%g1 + 88]
|
||||
st %l7, [%g1 + 92]
|
||||
|
||||
st %i0, [%g1 + 96]
|
||||
st %i1, [%g1 + 100]
|
||||
st %i2, [%g1 + 104]
|
||||
st %i3, [%g1 + 108]
|
||||
st %i4, [%g1 + 112]
|
||||
st %i5, [%g1 + 116]
|
||||
st %i6, [%g1 + 120]
|
||||
st %i7, [%g1 + 124]
|
||||
|
||||
__switch_context_nosave:
|
||||
/* Interrupts are not allowed... */
|
||||
@@ -28,55 +62,53 @@ __switch_context_nosave:
|
||||
/* Turn on Supervisor, EnableFloating, and all the PIL bits.
|
||||
* Also puts us in register window zero with traps off.
|
||||
*/
|
||||
#if 0
|
||||
set (PSR_PS | PSR_S | PSR_PIL | PSR_EF), %g2
|
||||
wr %g2, 0x0, %psr
|
||||
#endif
|
||||
|
||||
/* Load all registers
|
||||
*/
|
||||
set __context, %g1
|
||||
lda [%g1] ASI_BP, %g1
|
||||
add %g1, 8, %g1 /* skip %g0 and %g1*/
|
||||
ld [%g1], %g1
|
||||
ld [%g1 + 8], %g2
|
||||
ld [%g1 + 12], %g3
|
||||
ld [%g1 + 16], %g4
|
||||
ld [%g1 + 20], %g5
|
||||
ld [%g1 + 24], %g6
|
||||
ld [%g1 + 28], %g7
|
||||
|
||||
#define load_reg(reg) lda [%g1] ASI_BP, reg ; add %g1, 4, %g1
|
||||
ld [%g1 + 32], %o0
|
||||
ld [%g1 + 36], %o1
|
||||
ld [%g1 + 40], %o2
|
||||
ld [%g1 + 44], %o3
|
||||
ld [%g1 + 48], %o4
|
||||
ld [%g1 + 52], %o5
|
||||
ld [%g1 + 56], %o6
|
||||
ld [%g1 + 60], %o7
|
||||
|
||||
load_reg(%g2)
|
||||
load_reg(%g3)
|
||||
load_reg(%g4)
|
||||
load_reg(%g5)
|
||||
load_reg(%g6)
|
||||
load_reg(%g7)
|
||||
ld [%g1 + 64], %l0
|
||||
ld [%g1 + 68], %l1
|
||||
ld [%g1 + 72], %l2
|
||||
ld [%g1 + 76], %l3
|
||||
ld [%g1 + 80], %l4
|
||||
ld [%g1 + 84], %l5
|
||||
ld [%g1 + 88], %l6
|
||||
ld [%g1 + 92], %l7
|
||||
|
||||
load_reg(%o0)
|
||||
load_reg(%o1)
|
||||
load_reg(%o2)
|
||||
load_reg(%o3)
|
||||
load_reg(%o4)
|
||||
load_reg(%o5)
|
||||
load_reg(%o6)
|
||||
load_reg(%o7)
|
||||
|
||||
load_reg(%l0)
|
||||
load_reg(%l1)
|
||||
load_reg(%l2)
|
||||
load_reg(%l3)
|
||||
load_reg(%l4)
|
||||
load_reg(%l5)
|
||||
load_reg(%l6)
|
||||
load_reg(%l7)
|
||||
|
||||
load_reg(%i0)
|
||||
load_reg(%i1)
|
||||
load_reg(%i2)
|
||||
load_reg(%i3)
|
||||
load_reg(%i4)
|
||||
load_reg(%i5)
|
||||
load_reg(%i6)
|
||||
load_reg(%i7)
|
||||
ld [%g1 + 96], %i0
|
||||
ld [%g1 + 100], %i1
|
||||
ld [%g1 + 104], %i2
|
||||
ld [%g1 + 108], %i3
|
||||
ld [%g1 + 112], %i4
|
||||
ld [%g1 + 116], %i5
|
||||
ld [%g1 + 120], %i6
|
||||
ld [%g1 + 124], %i7
|
||||
|
||||
ld [%g1 + 128], %g1
|
||||
/* Finally, load new %pc */
|
||||
lda [%g1] ASI_BP, %g1
|
||||
jmp %g1
|
||||
nop
|
||||
clr %g1
|
||||
|
||||
__exit_context:
|
||||
/* Get back to the original context */
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "openbios/config.h"
|
||||
#include "openbios/kernel.h"
|
||||
#include "elf_boot.h"
|
||||
#include "sys_info.h"
|
||||
#include "context.h"
|
||||
|
||||
@@ -19,6 +20,7 @@ void collect_sys_info(struct sys_info *info)
|
||||
int i;
|
||||
unsigned long long total = 0;
|
||||
struct memrange *mmap;
|
||||
extern struct elf_image_note elf_image_notes;
|
||||
|
||||
/* Pick up paramters given by bootloader to us */
|
||||
//info->boot_type = boot_ctx->eax;
|
||||
@@ -26,6 +28,8 @@ void collect_sys_info(struct sys_info *info)
|
||||
info->boot_arg = boot_ctx->param[0];
|
||||
//debug("boot eax = %#lx\n", info->boot_type);
|
||||
//debug("boot ebx = %#lx\n", info->boot_data);
|
||||
info->boot_type = ELF_BHDR_MAGIC;
|
||||
info->boot_data = virt_to_phys(&elf_image_notes);
|
||||
debug("boot arg = %#lx\n", info->boot_arg);
|
||||
|
||||
collect_elfboot_info(info);
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
h# 01800000 encode-int 0 encode-int encode+ 0 encode-int encode+ h# 00000081 encode-int encode+
|
||||
0 encode-int encode+ 0 encode-int encode+ 0 encode-int encode+ 0 encode-int encode+
|
||||
" idprom" property \ XXX
|
||||
" /obio/zs@0,100000:a" encode-string " stdin-path" property
|
||||
" /obio/zs@0,100000:a" encode-string " stdout-path" property
|
||||
: encode-unit encode-unit-sbus ;
|
||||
: decode-unit decode-unit-sbus ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user