Author: stepan Date: 2006-06-10 03:37:53 +0200 (Sat, 10 Jun 2006) New Revision: 58
Added: openbios-devel/arch/sparc64/ openbios-devel/arch/sparc64/asi.h openbios-devel/arch/sparc64/boot.c openbios-devel/arch/sparc64/boot.h openbios-devel/arch/sparc64/build.xml openbios-devel/arch/sparc64/builtin.c openbios-devel/arch/sparc64/console.c openbios-devel/arch/sparc64/const.h openbios-devel/arch/sparc64/context.c openbios-devel/arch/sparc64/context.h openbios-devel/arch/sparc64/elfload.c openbios-devel/arch/sparc64/entry.S openbios-devel/arch/sparc64/forthload.c openbios-devel/arch/sparc64/init.fs openbios-devel/arch/sparc64/ldscript openbios-devel/arch/sparc64/lib.c openbios-devel/arch/sparc64/linux_load.c openbios-devel/arch/sparc64/loadfs.c openbios-devel/arch/sparc64/loadfs.h openbios-devel/arch/sparc64/lsu.h openbios-devel/arch/sparc64/multiboot.c openbios-devel/arch/sparc64/multiboot.h openbios-devel/arch/sparc64/openbios.c openbios-devel/arch/sparc64/openbios.h openbios-devel/arch/sparc64/openprom.h openbios-devel/arch/sparc64/plainboot.c openbios-devel/arch/sparc64/pstate.h openbios-devel/arch/sparc64/spitfire.h openbios-devel/arch/sparc64/switch.S openbios-devel/arch/sparc64/sys_info.c openbios-devel/arch/sparc64/tree.fs openbios-devel/arch/sparc64/ttable.h openbios-devel/arch/sparc64/vectors.S openbios-devel/arch/sparc64/winfixup.S openbios-devel/config/examples/cross-sparc64_config.xml openbios-devel/config/examples/cross-sparc64_rules.xml openbios-devel/config/examples/sparc64_config.xml openbios-devel/config/examples/sparc64_rules.xml openbios-devel/include/sparc64/ openbios-devel/include/sparc64/elf.h openbios-devel/include/sparc64/io.h openbios-devel/include/sparc64/types.h Modified: openbios-devel/arch/build.xml Log: initial sparc64 version
Modified: openbios-devel/arch/build.xml =================================================================== --- openbios-devel/arch/build.xml 2006-06-10 01:31:30 UTC (rev 57) +++ openbios-devel/arch/build.xml 2006-06-10 01:37:53 UTC (rev 58) @@ -6,4 +6,5 @@ <include href="ia64/build.xml"/> <include href="unix/build.xml"/> <include href="sparc32/build.xml"/> + <include href="sparc64/build.xml"/> </build>
Added: openbios-devel/arch/sparc64/asi.h =================================================================== --- openbios-devel/arch/sparc64/asi.h (rev 0) +++ openbios-devel/arch/sparc64/asi.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,145 @@ +/* $Id: asi.h,v 1.5 2001/03/29 11:47:47 davem Exp $ */ +#ifndef _SPARC64_ASI_H +#define _SPARC64_ASI_H + +/* asi.h: Address Space Identifier values for the V9. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +/* V9 Architecture mandary ASIs. */ +#define ASI_N 0x04 /* Nucleus */ +#define ASI_NL 0x0c /* Nucleus, little endian */ +#define ASI_AIUP 0x10 /* Primary, user */ +#define ASI_AIUS 0x11 /* Secondary, user */ +#define ASI_AIUPL 0x18 /* Primary, user, little endian */ +#define ASI_AIUSL 0x19 /* Secondary, user, little endian */ +#define ASI_P 0x80 /* Primary, implicit */ +#define ASI_S 0x81 /* Secondary, implicit */ +#define ASI_PNF 0x82 /* Primary, no fault */ +#define ASI_SNF 0x83 /* Secondary, no fault */ +#define ASI_PL 0x88 /* Primary, implicit, l-endian */ +#define ASI_SL 0x89 /* Secondary, implicit, l-endian */ +#define ASI_PNFL 0x8a /* Primary, no fault, l-endian */ +#define ASI_SNFL 0x8b /* Secondary, no fault, l-endian */ + +/* SpitFire and later extended ASIs. The "(III)" marker designates + * UltraSparc-III and later specific ASIs. The "(CMT)" marker designates + * Chip Multi Threading specific ASIs. + */ +#define ASI_PHYS_USE_EC 0x14 /* PADDR, E-cachable */ +#define ASI_PHYS_BYPASS_EC_E 0x15 /* PADDR, E-bit */ +#define ASI_PHYS_USE_EC_L 0x1c /* PADDR, E-cachable, little endian*/ +#define ASI_PHYS_BYPASS_EC_E_L 0x1d /* PADDR, E-bit, little endian */ +#define ASI_NUCLEUS_QUAD_LDD 0x24 /* Cachable, qword load */ +#define ASI_NUCLEUS_QUAD_LDD_L 0x2c /* Cachable, qword load, l-endian */ +#define ASI_PCACHE_DATA_STATUS 0x30 /* (III) PCache data stat RAM diag */ +#define ASI_PCACHE_DATA 0x31 /* (III) PCache data RAM diag */ +#define ASI_PCACHE_TAG 0x32 /* (III) PCache tag RAM diag */ +#define ASI_PCACHE_SNOOP_TAG 0x33 /* (III) PCache snoop tag RAM diag */ +#define ASI_QUAD_LDD_PHYS 0x34 /* (III+) PADDR, qword load */ +#define ASI_WCACHE_VALID_BITS 0x38 /* (III) WCache Valid Bits diag */ +#define ASI_WCACHE_DATA 0x39 /* (III) WCache data RAM diag */ +#define ASI_WCACHE_TAG 0x3a /* (III) WCache tag RAM diag */ +#define ASI_WCACHE_SNOOP_TAG 0x3b /* (III) WCache snoop tag RAM diag */ +#define ASI_QUAD_LDD_PHYS_L 0x3c /* (III+) PADDR, qw-load, l-endian */ +#define ASI_SRAM_FAST_INIT 0x40 /* (III+) Fast SRAM init */ +#define ASI_CORE_AVAILABLE 0x41 /* (CMT) LP Available */ +#define ASI_CORE_ENABLE_STAT 0x41 /* (CMT) LP Enable Status */ +#define ASI_CORE_ENABLE 0x41 /* (CMT) LP Enable RW */ +#define ASI_XIR_STEERING 0x41 /* (CMT) XIR Steering RW */ +#define ASI_CORE_RUNNING_RW 0x41 /* (CMT) LP Running RW */ +#define ASI_CORE_RUNNING_W1S 0x41 /* (CMT) LP Running Write-One Set */ +#define ASI_CORE_RUNNING_W1C 0x41 /* (CMT) LP Running Write-One Clr */ +#define ASI_CORE_RUNNING_STAT 0x41 /* (CMT) LP Running Status */ +#define ASI_CMT_ERROR_STEERING 0x41 /* (CMT) Error Steering RW */ +#define ASI_DCACHE_INVALIDATE 0x42 /* (III) DCache Invalidate diag */ +#define ASI_DCACHE_UTAG 0x43 /* (III) DCache uTag diag */ +#define ASI_DCACHE_SNOOP_TAG 0x44 /* (III) DCache snoop tag RAM diag */ +#define ASI_LSU_CONTROL 0x45 /* Load-store control unit */ +#define ASI_DCU_CONTROL_REG 0x45 /* (III) DCache Unit Control reg */ +#define ASI_DCACHE_DATA 0x46 /* DCache data-ram diag access */ +#define ASI_DCACHE_TAG 0x47 /* Dcache tag/valid ram diag access*/ +#define ASI_INTR_DISPATCH_STAT 0x48 /* IRQ vector dispatch status */ +#define ASI_INTR_RECEIVE 0x49 /* IRQ vector receive status */ +#define ASI_UPA_CONFIG 0x4a /* UPA config space */ +#define ASI_JBUS_CONFIG 0x4a /* (IIIi) JBUS Config Register */ +#define ASI_SAFARI_CONFIG 0x4a /* (III) Safari Config Register */ +#define ASI_SAFARI_ADDRESS 0x4a /* (III) Safari Address Register */ +#define ASI_ESTATE_ERROR_EN 0x4b /* E-cache error enable space */ +#define ASI_AFSR 0x4c /* Async fault status register */ +#define ASI_AFAR 0x4d /* Async fault address register */ +#define ASI_EC_TAG_DATA 0x4e /* E-cache tag/valid ram diag acc */ +#define ASI_IMMU 0x50 /* Insn-MMU main register space */ +#define ASI_IMMU_TSB_8KB_PTR 0x51 /* Insn-MMU 8KB TSB pointer reg */ +#define ASI_IMMU_TSB_64KB_PTR 0x52 /* Insn-MMU 64KB TSB pointer reg */ +#define ASI_ITLB_DATA_IN 0x54 /* Insn-MMU TLB data in reg */ +#define ASI_ITLB_DATA_ACCESS 0x55 /* Insn-MMU TLB data access reg */ +#define ASI_ITLB_TAG_READ 0x56 /* Insn-MMU TLB tag read reg */ +#define ASI_IMMU_DEMAP 0x57 /* Insn-MMU TLB demap */ +#define ASI_DMMU 0x58 /* Data-MMU main register space */ +#define ASI_DMMU_TSB_8KB_PTR 0x59 /* Data-MMU 8KB TSB pointer reg */ +#define ASI_DMMU_TSB_64KB_PTR 0x5a /* Data-MMU 16KB TSB pointer reg */ +#define ASI_DMMU_TSB_DIRECT_PTR 0x5b /* Data-MMU TSB direct pointer reg */ +#define ASI_DTLB_DATA_IN 0x5c /* Data-MMU TLB data in reg */ +#define ASI_DTLB_DATA_ACCESS 0x5d /* Data-MMU TLB data access reg */ +#define ASI_DTLB_TAG_READ 0x5e /* Data-MMU TLB tag read reg */ +#define ASI_DMMU_DEMAP 0x5f /* Data-MMU TLB demap */ +#define ASI_IIU_INST_TRAP 0x60 /* (III) Instruction Breakpoint */ +#define ASI_INTR_ID 0x63 /* (CMT) Interrupt ID register */ +#define ASI_CORE_ID 0x63 /* (CMT) LP ID register */ +#define ASI_CESR_ID 0x63 /* (CMT) CESR ID register */ +#define ASI_IC_INSTR 0x66 /* Insn cache instrucion ram diag */ +#define ASI_IC_TAG 0x67 /* Insn cache tag/valid ram diag */ +#define ASI_IC_STAG 0x68 /* (III) Insn cache snoop tag ram */ +#define ASI_IC_PRE_DECODE 0x6e /* Insn cache pre-decode ram diag */ +#define ASI_IC_NEXT_FIELD 0x6f /* Insn cache next-field ram diag */ +#define ASI_BRPRED_ARRAY 0x6f /* (III) Branch Prediction RAM diag*/ +#define ASI_BLK_AIUP 0x70 /* Primary, user, block load/store */ +#define ASI_BLK_AIUS 0x71 /* Secondary, user, block ld/st */ +#define ASI_MCU_CTRL_REG 0x72 /* (III) Memory controller regs */ +#define ASI_EC_DATA 0x74 /* (III) E-cache data staging reg */ +#define ASI_EC_CTRL 0x75 /* (III) E-cache control reg */ +#define ASI_EC_W 0x76 /* E-cache diag write access */ +#define ASI_UDB_ERROR_W 0x77 /* External UDB error regs W */ +#define ASI_UDB_CONTROL_W 0x77 /* External UDB control regs W */ +#define ASI_INTR_W 0x77 /* IRQ vector dispatch write */ +#define ASI_INTR_DATAN_W 0x77 /* (III) Out irq vector data reg N */ +#define ASI_INTR_DISPATCH_W 0x77 /* (III) Interrupt vector dispatch */ +#define ASI_BLK_AIUPL 0x78 /* Primary, user, little, blk ld/st*/ +#define ASI_BLK_AIUSL 0x79 /* Secondary, user, little, blk ld/st*/ +#define ASI_EC_R 0x7e /* E-cache diag read access */ +#define ASI_UDBH_ERROR_R 0x7f /* External UDB error regs rd hi */ +#define ASI_UDBL_ERROR_R 0x7f /* External UDB error regs rd low */ +#define ASI_UDBH_CONTROL_R 0x7f /* External UDB control regs rd hi */ +#define ASI_UDBL_CONTROL_R 0x7f /* External UDB control regs rd low*/ +#define ASI_INTR_R 0x7f /* IRQ vector dispatch read */ +#define ASI_INTR_DATAN_R 0x7f /* (III) In irq vector data reg N */ +#define ASI_PST8_P 0xc0 /* Primary, 8 8-bit, partial */ +#define ASI_PST8_S 0xc1 /* Secondary, 8 8-bit, partial */ +#define ASI_PST16_P 0xc2 /* Primary, 4 16-bit, partial */ +#define ASI_PST16_S 0xc3 /* Secondary, 4 16-bit, partial */ +#define ASI_PST32_P 0xc4 /* Primary, 2 32-bit, partial */ +#define ASI_PST32_S 0xc5 /* Secondary, 2 32-bit, partial */ +#define ASI_PST8_PL 0xc8 /* Primary, 8 8-bit, partial, L */ +#define ASI_PST8_SL 0xc9 /* Secondary, 8 8-bit, partial, L */ +#define ASI_PST16_PL 0xca /* Primary, 4 16-bit, partial, L */ +#define ASI_PST16_SL 0xcb /* Secondary, 4 16-bit, partial, L */ +#define ASI_PST32_PL 0xcc /* Primary, 2 32-bit, partial, L */ +#define ASI_PST32_SL 0xcd /* Secondary, 2 32-bit, partial, L */ +#define ASI_FL8_P 0xd0 /* Primary, 1 8-bit, fpu ld/st */ +#define ASI_FL8_S 0xd1 /* Secondary, 1 8-bit, fpu ld/st */ +#define ASI_FL16_P 0xd2 /* Primary, 1 16-bit, fpu ld/st */ +#define ASI_FL16_S 0xd3 /* Secondary, 1 16-bit, fpu ld/st */ +#define ASI_FL8_PL 0xd8 /* Primary, 1 8-bit, fpu ld/st, L */ +#define ASI_FL8_SL 0xd9 /* Secondary, 1 8-bit, fpu ld/st, L*/ +#define ASI_FL16_PL 0xda /* Primary, 1 16-bit, fpu ld/st, L */ +#define ASI_FL16_SL 0xdb /* Secondary, 1 16-bit, fpu ld/st,L*/ +#define ASI_BLK_COMMIT_P 0xe0 /* Primary, blk store commit */ +#define ASI_BLK_COMMIT_S 0xe1 /* Secondary, blk store commit */ +#define ASI_BLK_P 0xf0 /* Primary, blk ld/st */ +#define ASI_BLK_S 0xf1 /* Secondary, blk ld/st */ +#define ASI_BLK_PL 0xf8 /* Primary, blk ld/st, little */ +#define ASI_BLK_SL 0xf9 /* Secondary, blk ld/st, little */ + +#endif /* _SPARC64_ASI_H */
Added: openbios-devel/arch/sparc64/boot.c =================================================================== --- openbios-devel/arch/sparc64/boot.c (rev 0) +++ openbios-devel/arch/sparc64/boot.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,82 @@ +/* + * + */ +#undef BOOTSTRAP +#include "openbios/config.h" +#include "openbios/bindings.h" +#include "openbios/elfload.h" +#include "openbios/nvram.h" +#include "libc/diskio.h" +#include "sys_info.h" + +int elf_load(struct sys_info *, const char *filename, const char *cmdline); +int aout_load(struct sys_info *, const char *filename, const char *cmdline); +int linux_load(struct sys_info *, const char *filename, const char *cmdline); + +void boot(void); + +struct sys_info sys_info; +uint32_t kernel_image; +uint32_t kernel_size; +uint32_t cmdline; +uint32_t cmdline_size; +char boot_device; + +void boot(void) +{ + char *path=pop_fstr_copy(), *param; + char altpath[256]; + + if (kernel_size) { + int (*entry)(const void *romvec, int p2, int p3, int p4, int p5); + + printk("[sparc64] Kernel already loaded\n"); + entry = (void *) kernel_image; + entry(0, 0, 0, 0, 0); + } + + if(!path) { + switch(boot_device) { + case 'a': + path = "/obio/SUNW,fdtwo"; + break; + case 'c': + path = "disk"; + break; + default: + case 'd': + path = "cdrom"; + break; + case 'n': + path = "net"; + break; + } + } + + param = strchr(path, ' '); + if(param) { + *param = '\0'; + param++; + } else if (cmdline_size) { + param = (char *)cmdline; + } + + printk("[sparc64] Booting file '%s' ", path); + if(param) + printk("with parameters '%s'\n", param); + else + printk("without parameters.\n"); + + + if (elf_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) + if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) { + + sprintf(altpath, "%s:d", path); + + if (elf_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT) + if (linux_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT) + printk("Unsupported image format\n"); + } + + free(path); +}
Added: openbios-devel/arch/sparc64/boot.h =================================================================== --- openbios-devel/arch/sparc64/boot.h (rev 0) +++ openbios-devel/arch/sparc64/boot.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,14 @@ +/* tag: openbios loader prototypes for sparc64 + * + * Copyright (C) 2004 Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +int forth_load(struct sys_info *info, const char *filename, const char *cmdline); +int elf_load(struct sys_info *info, const char *filename, const char *cmdline); +int linux_load(struct sys_info *info, const char *file, const char *cmdline); + +unsigned int start_elf(unsigned long entry_point, unsigned long param); +
Added: openbios-devel/arch/sparc64/build.xml =================================================================== --- openbios-devel/arch/sparc64/build.xml (rev 0) +++ openbios-devel/arch/sparc64/build.xml 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,108 @@ +<build condition="SPARC64"> + + <dictionary name="openbios-sparc64" init="openbios"> + <object source="tree.fs" target="forth"/> + <object source="init.fs" target="forth"/> + </dictionary> + + <library name="sparc64" type="static" target="target"> + <object source="openbios.c"/> + <object source="console.c"/> + <object source="lib.c"/> + <object source="boot.c"/> + <object source="context.c"/> + <object source="switch.S"/> + <object source="linux_load.c"/> + <object source="sys_info.c"/> + <object source="elfload.c"/> + <object source="forthload.c"/> + <object source="loadfs.c"/> + </library> + + <executable name="target/arch/sparc64/entry.o" target="target"> + <rule><![CDATA[ + $(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ arch/sparc64/entry.S + ]]></rule> + </executable> + <executable name="target/arch/sparc64/vectors.o" target="target"> + <rule><![CDATA[ + $(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ arch/sparc64/vectors.S + ]]></rule> + </executable> + + <executable name="openbios.multiboot" target="target" condition="IMAGE_ELF_MULTIBOOT"> + <rule> + $(LD) -T arch/sparc64/ldscript -o $@.nostrip $^ + $(NM) $@.nostrip | sort > $(ODIR)/openbios-multiboot.syms + cp $@.nostrip $@ + $(STRIP) $@ + </rule> + <object source="multiboot.c"/> + <external-object source="target/arch/sparc64/vectors.o"/> + <external-object source="target/arch/sparc64/entry.o"/> + <external-object source="libsparc64.a"/> + <external-object source="libbootstrap.a"/> + <external-object source="libmodules.a"/> + <external-object source="libdrivers.a"/> + <external-object source="liblibc.a"/> + <external-object source="libfs.a"/> + </executable> + + <executable name="openbios-plain.elf" target="target" condition="IMAGE_ELF"> + <rule> + $(LD) -T arch/sparc64/ldscript -o $@.nostrip $^ + $(NM) $@.nostrip | sort > $(ODIR)/openbios-plain.syms + cp $@.nostrip $@ + $(STRIP) $@ + </rule> + <object source="plainboot.c"/> + <external-object source="target/arch/sparc64/vectors.o"/> + <external-object source="target/arch/sparc64/entry.o"/> + <external-object source="libsparc64.a"/> + <external-object source="libbootstrap.a"/> + <external-object source="libmodules.a"/> + <external-object source="libdrivers.a"/> + <external-object source="liblibc.a"/> + <external-object source="libfs.a"/> + </executable> + + <!-- HACK ALERT --> + + <executable name="target/include/static-dict.h" target="target" condition="IMAGE_ELF_EMBEDDED"> + <rule><![CDATA[ + @echo "static const char forth_dictionary[] = {" > $@ + @cat $< | hexdump -ve '1/0 "\t" 8/1 "0x%02x, " 1/0 "\n"' \ + | sed 's/0x ,//g' >> $@ + @echo "};" >> $@ + ]]></rule> + <external-object source="openbios-sparc64.dict"/> + </executable> + + <executable name="target/arch/sparc64/builtin.o" target="target" condition="IMAGE_ELF_EMBEDDED"> + <rule><![CDATA[ + $(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ arch/sparc64/builtin.c + ]]></rule> + <external-object source="target/include/static-dict.h"/> + </executable> + + <!-- END OF HACK ALERT --> + + <executable name="openbios-builtin.elf" target="target" condition="IMAGE_ELF_EMBEDDED"> + <rule> + $(LD) -T arch/sparc64/ldscript -o $@.nostrip $^ + $(NM) $@.nostrip | sort > $(ODIR)/openbios-builtin.syms + cp $@.nostrip $@ + $(STRIP) $@ + </rule> + <external-object source="target/arch/sparc64/vectors.o"/> + <external-object source="target/arch/sparc64/entry.o"/> + <external-object source="target/arch/sparc64/builtin.o"/> + <external-object source="libsparc64.a"/> + <external-object source="libbootstrap.a"/> + <external-object source="libmodules.a"/> + <external-object source="libdrivers.a"/> + <external-object source="liblibc.a"/> + <external-object source="libfs.a"/> + </executable> + +</build>
Added: openbios-devel/arch/sparc64/builtin.c =================================================================== --- openbios-devel/arch/sparc64/builtin.c (rev 0) +++ openbios-devel/arch/sparc64/builtin.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,26 @@ +/* tag: openbios forth starter for builtin dictionary for sparc64 + * + * Copyright (C) 2003 Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +#include "openbios/config.h" +#include <asm/types.h> +#include "sys_info.h" + +/* + * wrap an array around the hex'ed dictionary file + */ + +#include "static-dict.h" + +void collect_multiboot_info(struct sys_info *info); +void collect_multiboot_info(struct sys_info *info) +{ + info->dict_start=(unsigned long *)forth_dictionary; + info->dict_end=(unsigned long *)((ucell)forth_dictionary + + sizeof(forth_dictionary)); +} +
Added: openbios-devel/arch/sparc64/console.c =================================================================== --- openbios-devel/arch/sparc64/console.c (rev 0) +++ openbios-devel/arch/sparc64/console.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2003, 2004 Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +#include "openbios/config.h" +#include "openbios/kernel.h" +#include "openbios.h" + +#ifdef CONFIG_DEBUG_CONSOLE + +/* ****************************************************************** + * serial console functions + * ****************************************************************** */ + +#ifdef CONFIG_DEBUG_CONSOLE_SERIAL + +#define RBR(x) x==2?0x2f8:0x3f8 +#define THR(x) x==2?0x2f8:0x3f8 +#define IER(x) x==2?0x2f9:0x3f9 +#define IIR(x) x==2?0x2fa:0x3fa +#define LCR(x) x==2?0x2fb:0x3fb +#define MCR(x) x==2?0x2fc:0x3fc +#define LSR(x) x==2?0x2fd:0x3fd +#define MSR(x) x==2?0x2fe:0x3fe +#define SCR(x) x==2?0x2ff:0x3ff +#define DLL(x) x==2?0x2f8:0x3f8 +#define DLM(x) x==2?0x2f9:0x3f9 + +static int uart_charav(int port) +{ + return ((inb(LSR(port)) & 1) != 0); +} + +static char uart_getchar(int port) +{ + while (!uart_charav(port)); + return ((char) inb(RBR(port)) & 0177); +} + +static void uart_putchar(int port, unsigned char c) +{ + if (c == '\n') + uart_putchar(port, '\r'); + while (!(inb(LSR(port)) & 0x20)); + outb(c, THR(port)); +} + +static void uart_init_line(int port, unsigned long baud) +{ + int i, baudconst; + + switch (baud) { + case 115200: + baudconst = 1; + break; + case 57600: + baudconst = 2; + break; + case 38400: + baudconst = 3; + break; + case 19200: + baudconst = 6; + break; + case 9600: + default: + baudconst = 12; + break; + } + + outb(0x87, LCR(port)); + outb(0x00, DLM(port)); + outb(baudconst, DLL(port)); + outb(0x07, LCR(port)); + outb(0x0f, MCR(port)); + + for (i = 10; i > 0; i--) { + if (inb(LSR(port)) == (unsigned int) 0) + break; + inb(RBR(port)); + } +} + +static void serial_cls(void); +static void serial_putchar(int c); + +int uart_init(int port, unsigned long speed) +{ + uart_init_line(port, speed); + return -1; +} + +static void serial_putchar(int c) +{ + uart_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff)); +} + +static void serial_cls(void) +{ + serial_putchar(27); + serial_putchar('['); + serial_putchar('H'); + serial_putchar(27); + serial_putchar('['); + serial_putchar('J'); +} + +#endif + +/* ****************************************************************** + * simple polling video/keyboard console functions + * ****************************************************************** */ + +#ifdef CONFIG_DEBUG_CONSOLE_VGA + +/* raw vga text mode */ +#define COLUMNS 80 /* The number of columns. */ +#define LINES 25 /* The number of lines. */ +#define ATTRIBUTE 7 /* The attribute of an character. */ + +#define APB_MEM_BASE 0x1ff00000000ULL +#define VGA_BASE (APB_MEM_BASE + 0x4b8000ULL) /* The video memory address. */ + +/* VGA Index and Data Registers */ +#define VGA_REG_INDEX 0x03D4 /* VGA index register */ +#define VGA_REG_DATA 0x03D5 /* VGA data register */ + +#define VGA_IDX_CURMSL 0x09 /* cursor maximum scan line */ +#define VGA_IDX_CURSTART 0x0A /* cursor start */ +#define VGA_IDX_CUREND 0x0B /* cursor end */ +#define VGA_IDX_CURLO 0x0F /* cursor position (low 8 bits) */ +#define VGA_IDX_CURHI 0x0E /* cursor position (high 8 bits) */ + +/* Save the X and Y position. */ +static int xpos, ypos; +/* Point to the video memory. */ +static volatile unsigned char *video = (unsigned char *) VGA_BASE; + +static void video_initcursor(void) +{ + u8 val; + outb(VGA_IDX_CURMSL, VGA_REG_INDEX); + val = inb(VGA_REG_DATA) & 0x1f; /* maximum scan line -1 */ + + outb(VGA_IDX_CURSTART, VGA_REG_INDEX); + outb(0, VGA_REG_DATA); + + outb(VGA_IDX_CUREND, VGA_REG_INDEX); + outb(val, VGA_REG_DATA); +} + + + +static void video_poscursor(unsigned int x, unsigned int y) +{ + unsigned short pos; + + /* Calculate new cursor position as a function of x and y */ + pos = (y * COLUMNS) + x; + + /* Output the new position to VGA card */ + outb(VGA_IDX_CURLO, VGA_REG_INDEX); /* output low 8 bits */ + outb((u8) (pos), VGA_REG_DATA); + outb(VGA_IDX_CURHI, VGA_REG_INDEX); /* output high 8 bits */ + outb((u8) (pos >> 8), VGA_REG_DATA); + +}; + + +static void video_newline(void) +{ + xpos = 0; + + if (ypos < LINES - 1) { + ypos++; + } else { + int i; + memmove((void *) video, (void *) (video + 2 * COLUMNS), + (LINES - 1) * COLUMNS * 2); + + for (i = ((LINES - 1) * 2 * COLUMNS); + i < 2 * COLUMNS * LINES;) { + video[i++] = 0; + video[i++] = ATTRIBUTE; + } + } + +} + +/* Put the character C on the screen. */ +static void video_putchar(int c) +{ + int p=1; + + if (c == '\n' || c == '\r') { + video_newline(); + return; + } + + if (c == '\b') { + if (xpos) xpos--; + c=' '; + p=0; + } + + + if (xpos >= COLUMNS) + video_newline(); + + *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF; + *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE; + + if (p) + xpos++; + + video_poscursor(xpos, ypos); +} + +static void video_cls(void) +{ + int i; + + for (i = 0; i < 2 * COLUMNS * LINES;) { + video[i++] = 0; + video[i++] = ATTRIBUTE; + } + + + xpos = 0; + ypos = 0; + + video_initcursor(); + video_poscursor(xpos, ypos); +} + +void video_init(void) +{ + video=(unsigned char *)VGA_BASE; +} + +/* + * keyboard driver + */ + +static const char normal[] = { + 0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', + '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', + 'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j', + 'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b', + 'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f +}; + +static const char shifted[] = { + 0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', + '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', + 'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', + 'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B', + 'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8', + '9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f +}; + +static int key_ext; +static int key_lshift = 0, key_rshift = 0, key_caps = 0; + +static char last_key; + +static void keyboard_cmd(unsigned char cmd, unsigned char val) +{ + outb(cmd, 0x60); + /* wait until keyboard controller accepts cmds: */ + while (inb(0x64) & 2); + outb(val, 0x60); + while (inb(0x64) & 2); +} + +static char keyboard_poll(void) +{ + unsigned int c; + if (inb(0x64) & 1) { + c = inb(0x60); + switch (c) { + case 0xe0: + key_ext = 1; + return 0; + case 0x2a: + key_lshift = 1; + return 0; + case 0x36: + key_rshift = 1; + return 0; + case 0xaa: + key_lshift = 0; + return 0; + case 0xb6: + key_rshift = 0; + return 0; + case 0x3a: + if (key_caps) { + key_caps = 0; + keyboard_cmd(0xed, 0); + } else { + key_caps = 1; + keyboard_cmd(0xed, 4); /* set caps led */ + } + return 0; + } + + if (key_ext) { + // void printk(const char *format, ...); + printk("extended keycode: %x\n", c); + + key_ext = 0; + return 0; + } + + if (c & 0x80) /* unhandled key release */ + return 0; + + if (key_lshift || key_rshift) + return key_caps ? normal[c] : shifted[c]; + else + return key_caps ? shifted[c] : normal[c]; + } + return 0; +} + +static int keyboard_dataready(void) +{ + if (last_key) + return 1; + + last_key = keyboard_poll(); + + return (last_key != 0); +} + +static unsigned char keyboard_readdata(void) +{ + char tmp; + while (!keyboard_dataready()); + tmp = last_key; + last_key = 0; + return tmp; +} +#endif + + +/* ****************************************************************** + * common functions, implementing simple concurrent console + * ****************************************************************** */ + +int putchar(int c) +{ +#ifdef CONFIG_DEBUG_CONSOLE_SERIAL + serial_putchar(c); +#endif +#ifdef CONFIG_DEBUG_CONSOLE_VGA + video_putchar(c); +#endif + return c; +} + +int availchar(void) +{ +#ifdef CONFIG_DEBUG_CONSOLE_SERIAL + if (uart_charav(CONFIG_SERIAL_PORT)) + return 1; +#endif +#ifdef CONFIG_DEBUG_CONSOLE_VGA + if (keyboard_dataready()) + return 1; +#endif + return 0; +} + +int getchar(void) +{ +#ifdef CONFIG_DEBUG_CONSOLE_SERIAL + if (uart_charav(CONFIG_SERIAL_PORT)) + return (uart_getchar(CONFIG_SERIAL_PORT)); +#endif +#ifdef CONFIG_DEBUG_CONSOLE_VGA + if (keyboard_dataready()) + return (keyboard_readdata()); +#endif + return 0; +} + +void cls(void) +{ +#ifdef CONFIG_DEBUG_CONSOLE_SERIAL + serial_cls(); +#endif +#ifdef CONFIG_DEBUG_CONSOLE_VGA + video_cls(); +#endif +} + + +#endif // CONFIG_DEBUG_CONSOLE
Added: openbios-devel/arch/sparc64/const.h =================================================================== --- openbios-devel/arch/sparc64/const.h (rev 0) +++ openbios-devel/arch/sparc64/const.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,19 @@ +/* const.h: Macros for dealing with constants. */ + +#ifndef _SPARC64_CONST_H +#define _SPARC64_CONST_H + +/* Some constant macros are used in both assembler and + * C code. Therefore we cannot annotate them always with + * 'UL' and other type specificers unilaterally. We + * use the following macros to deal with this. + */ + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#else +#define _AC(X,Y) (X##Y) +#endif + + +#endif /* !(_SPARC64_CONST_H) */
Added: openbios-devel/arch/sparc64/context.c =================================================================== --- openbios-devel/arch/sparc64/context.c (rev 0) +++ openbios-devel/arch/sparc64/context.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,109 @@ +/* + * context switching + * 2003-10 by SONE Takeshi + */ + +#include "openbios/config.h" +#include "openbios/kernel.h" +#include "context.h" + +#define MAIN_STACK_SIZE 16384 +#define IMAGE_STACK_SIZE 4096 + +#define debug printk + +static void start_main(void); /* forward decl. */ +void __exit_context(void); /* assembly routine */ + +/* + * Main context structure + * It is placed at the bottom of our stack, and loaded by assembly routine + * to start us up. + */ +struct context main_ctx = { + .regs[REG_SP] = (uint64_t) &_estack - 96, + .pc = (uint64_t) start_main, + .npc = (uint64_t) start_main + 4, + .return_addr = (uint64_t) __exit_context, +}; + +/* This is used by assembly routine to load/store the context which + * it is to switch/switched. */ +struct context *__context = &main_ctx; + +/* Stack for loaded ELF image */ +static uint8_t image_stack[IMAGE_STACK_SIZE]; + +/* Pointer to startup context (physical address) */ +unsigned long __boot_ctx; + +/* + * Main starter + * This is the C function that runs first. + */ +static void start_main(void) +{ + int retval; + extern int openbios(void); + + /* Save startup context, so we can refer to it later. + * We have to keep it in physical address since we will relocate. */ + __boot_ctx = virt_to_phys(__context); + + /* Start the real fun */ + retval = openbios(); + + /* Pass return value to startup context. Bootloader may see it. */ + //boot_ctx->eax = retval; + + /* Returning from here should jump to __exit_context */ + __context = boot_ctx; +} + +/* Setup a new context using the given stack. + */ +struct context * +init_context(uint8_t *stack, uint64_t stack_size, int num_params) +{ + struct context *ctx; + + ctx = (struct context *) + (stack + stack_size - (sizeof(*ctx) + num_params*sizeof(uint32_t))); + memset(ctx, 0, sizeof(*ctx)); + + /* Fill in reasonable default for flat memory model */ + ctx->regs[REG_SP] = virt_to_phys(SP_LOC(ctx)); + ctx->return_addr = virt_to_phys(__exit_context); + + return ctx; +} + +/* Switch to another context. */ +struct context *switch_to(struct context *ctx) +{ + struct context *save, *ret; + + debug("switching to new context:\n"); + save = __context; + __context = ctx; + //asm ("pushl %cs; call __switch_context"); + ret = __context; + __context = save; + return ret; +} + +/* Start ELF Boot image */ +uint64_t start_elf(uint64_t entry_point, uint64_t param) +{ + struct context *ctx; + + ctx = init_context(image_stack, sizeof image_stack, 1); + ctx->pc = entry_point; + ctx->param[0] = param; + //ctx->eax = 0xe1fb007; + //ctx->ebx = param; + + ctx = switch_to(ctx); + //return ctx->eax; + return 0; +}
Added: openbios-devel/arch/sparc64/context.h =================================================================== --- openbios-devel/arch/sparc64/context.h (rev 0) +++ openbios-devel/arch/sparc64/context.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,31 @@ +#ifndef SPARC64_CONTEXT_H +#define SPARC64_CONTEXT_H + +struct context { + /* General registers */ + uint64_t regs[32]; + uint64_t pc; + uint64_t npc; +#define REG_O0 8 +#define REG_SP 14 +#define SP_LOC(ctx) (&(ctx)->regs[REG_SP]) + /* Flags */ + /* Optional stack contents */ + uint64_t return_addr; + uint64_t param[0]; +}; + +/* Create a new context in the given stack */ +struct context * +init_context(uint8_t *stack, uint64_t stack_size, int num_param); + +/* Switch context */ +struct context *switch_to(struct context *); + +/* Holds physical address of boot context */ +extern unsigned long __boot_ctx; + +/* This can always be safely used to refer to the boot context */ +#define boot_ctx ((struct context *) phys_to_virt(__boot_ctx)) + +#endif /* SPARC64_CONTEXT_H */
Added: openbios-devel/arch/sparc64/elfload.c =================================================================== --- openbios-devel/arch/sparc64/elfload.c (rev 0) +++ openbios-devel/arch/sparc64/elfload.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,416 @@ +/* ELF Boot loader + * As we have seek, this implementation can be straightforward. + * 2003-07 by SONE Takeshi + */ + +#include "openbios/config.h" +#include "openbios/kernel.h" +#include "openbios/elf.h" +#include "asm/elf.h" +#include "elf_boot.h" +#include "sys_info.h" +#include "ipchecksum.h" +#include "loadfs.h" +#define printf printk +#define debug printk + +extern unsigned int start_elf(unsigned long entry_point, unsigned long param); +#define addr_fixup(addr) ((addr) & 0x00ffffff) + +static char *image_name, *image_version; +const char *program_name, *program_version; + +static void *calloc(size_t nmemb, size_t size) +{ + size_t alloc_size = nmemb * size; + void *mem; + + if (alloc_size < nmemb || alloc_size < size) { + printf("calloc overflow: %u, %u\n", nmemb, size); + return 0; + } + + mem = malloc(alloc_size); + memset(mem, 0, alloc_size); + + return mem; +} + + +static int check_mem_ranges(struct sys_info *info, + Elf_phdr *phdr, int phnum) +{ + int i, j; + unsigned long start, end; + unsigned long prog_start, prog_end; + struct memrange *mem; + + prog_start = virt_to_phys(&_start); + prog_end = virt_to_phys(&_end); + + for (i = 0; i < phnum; i++) { + if (phdr[i].p_type != PT_LOAD) + continue; + start = addr_fixup(phdr[i].p_paddr); + end = start + phdr[i].p_memsz; + if (start < prog_start && end > prog_start) + goto conflict; + if (start < prog_end && end > prog_end) + goto conflict; + mem=info->memrange; + for (j = 0; j < info->n_memranges; j++) { + if (mem[j].base <= start && mem[j].base + mem[j].size >= end) + break; + } + if (j >= info->n_memranges) + goto badseg; + } + return 1; + +conflict: + printf("%s occupies [%#lx-%#lx]\n", program_name, prog_start, prog_end); + +badseg: + printf("Segment %d [%#lx-%#lx] doesn't fit into memory\n", i, start, end-1); + return 0; +} + +static unsigned long process_image_notes(Elf_phdr *phdr, int phnum, + unsigned short *sum_ptr, + unsigned int offset) +{ + int i; + char *buf = NULL; + int retval = 0; + unsigned long addr, end; + Elf_Nhdr *nhdr; + const char *name; + void *desc; + + for (i = 0; i < phnum; i++) { + if (phdr[i].p_type != PT_NOTE) + continue; + buf = malloc(phdr[i].p_filesz); + file_seek(offset + phdr[i].p_offset); + if (lfile_read(buf, phdr[i].p_filesz) != phdr[i].p_filesz) { + printf("Can't read note segment\n"); + goto out; + } + addr = (unsigned long) buf; + end = addr + phdr[i].p_filesz; + while (addr < end) { + nhdr = (Elf_Nhdr *) addr; + addr += sizeof(Elf_Nhdr); + name = (const char *) addr; + addr += (nhdr->n_namesz+3) & ~3; + desc = (void *) addr; + addr += (nhdr->n_descsz+3) & ~3; + + if (nhdr->n_namesz==sizeof(ELF_NOTE_BOOT) + && memcmp(name, ELF_NOTE_BOOT, sizeof(ELF_NOTE_BOOT))==0) { + if (nhdr->n_type == EIN_PROGRAM_NAME) { + image_name = calloc(1, nhdr->n_descsz + 1); + memcpy(image_name, desc, nhdr->n_descsz); + } + if (nhdr->n_type == EIN_PROGRAM_VERSION) { + image_version = calloc(1, nhdr->n_descsz + 1); + memcpy(image_version, desc, nhdr->n_descsz); + } + if (nhdr->n_type == EIN_PROGRAM_CHECKSUM) { + *sum_ptr = *(unsigned short *) desc; + debug("Image checksum: %#04x\n", *sum_ptr); + /* Where in the file */ + retval = phdr[i].p_offset + + (unsigned long) desc - (unsigned long) buf; + } + } + } + } +out: + file_close(); + if (buf) + free(buf); + return retval; +} + +static int load_segments(Elf_phdr *phdr, int phnum, + unsigned long checksum_offset, + unsigned int offset) +{ + unsigned long bytes; + //unsigned int start_time, time; + int i; + + bytes = 0; + // start_time = currticks(); + for (i = 0; i < phnum; i++) { + if (phdr[i].p_type != PT_LOAD) + continue; + debug("segment %d addr:%#lx file:%#lx mem:%#lx ", + i, addr_fixup(phdr[i].p_paddr), phdr[i].p_filesz, phdr[i].p_memsz); + file_seek(offset + phdr[i].p_offset); + debug("loading... "); + if (lfile_read(phys_to_virt(addr_fixup(phdr[i].p_paddr)), phdr[i].p_filesz) + != phdr[i].p_filesz) { + printf("Can't read program segment %d\n", i); + return 0; + } + bytes += phdr[i].p_filesz; + debug("clearing... "); + memset(phys_to_virt(addr_fixup(phdr[i].p_paddr) + phdr[i].p_filesz), 0, + phdr[i].p_memsz - phdr[i].p_filesz); + if (phdr[i].p_offset <= checksum_offset + && phdr[i].p_offset + phdr[i].p_filesz >= checksum_offset+2) { + debug("clearing checksum... "); + memset(phys_to_virt(addr_fixup(phdr[i].p_paddr) + checksum_offset + - phdr[i].p_offset), 0, 2); + } + debug("ok\n"); + + } + // time = currticks() - start_time; + //debug("Loaded %lu bytes in %ums (%luKB/s)\n", bytes, time, + // time? bytes/time : 0); + debug("Loaded %lu bytes \n", bytes); + + return 1; +} + +static int verify_image(Elf_ehdr *ehdr, Elf_phdr *phdr, int phnum, + unsigned short image_sum) +{ + unsigned short sum, part_sum; + unsigned long offset; + int i; + + sum = 0; + offset = 0; + + part_sum = ipchksum(ehdr, sizeof *ehdr); + sum = add_ipchksums(offset, sum, part_sum); + offset += sizeof *ehdr; + + part_sum = ipchksum(phdr, phnum * sizeof(*phdr)); + sum = add_ipchksums(offset, sum, part_sum); + offset += phnum * sizeof(*phdr); + + for (i = 0; i < phnum; i++) { + if (phdr[i].p_type != PT_LOAD) + continue; + part_sum = ipchksum(phys_to_virt(addr_fixup(phdr[i].p_paddr)), phdr[i].p_memsz); + sum = add_ipchksums(offset, sum, part_sum); + offset += phdr[i].p_memsz; + } + + if (sum != image_sum) { + printf("Verify FAILED (image:%#04x vs computed:%#04x)\n", + image_sum, sum); + return 0; + } + return 1; +} + +static inline unsigned padded(unsigned s) +{ + return (s + 3) & ~3; +} + +static Elf_Bhdr *add_boot_note(Elf_Bhdr *bhdr, const char *name, + unsigned type, const char *desc, unsigned descsz) +{ + Elf_Nhdr nhdr; + unsigned ent_size, new_size, pad; + char *addr; + + if (!bhdr) + return NULL; + + nhdr.n_namesz = name? strlen(name)+1 : 0; + nhdr.n_descsz = descsz; + nhdr.n_type = type; + ent_size = sizeof(nhdr) + padded(nhdr.n_namesz) + padded(nhdr.n_descsz); + if (bhdr->b_size + ent_size > 0xffff) { + printf("Boot notes too big\n"); + free(bhdr); + return NULL; + } + if (bhdr->b_size + ent_size > bhdr->b_checksum) { + do { + new_size = bhdr->b_checksum * 2; + } while (new_size < bhdr->b_size + ent_size); + if (new_size > 0xffff) + new_size = 0xffff; + debug("expanding boot note size to %u\n", new_size); +#ifdef HAVE_REALLOC + bhdr = realloc(bhdr, new_size); + bhdr->b_checksum = new_size; +#else + printf("Boot notes too big\n"); + free(bhdr); + return NULL; +#endif + } + + addr = (char *) bhdr; + addr += bhdr->b_size; + memcpy(addr, &nhdr, sizeof(nhdr)); + addr += sizeof(nhdr); + + memcpy(addr, name, nhdr.n_namesz); + addr += nhdr.n_namesz; + pad = padded(nhdr.n_namesz) - nhdr.n_namesz; + memset(addr, 0, pad); + addr += pad; + + memcpy(addr, desc, nhdr.n_descsz); + addr += nhdr.n_descsz; + pad = padded(nhdr.n_descsz) - nhdr.n_descsz; + memset(addr, 0, pad); + addr += pad; + + bhdr->b_size += ent_size; + bhdr->b_records++; + return bhdr; +} + +static inline Elf_Bhdr *add_note_string(Elf_Bhdr *bhdr, const char *name, + unsigned type, const char *desc) +{ + return add_boot_note(bhdr, name, type, desc, strlen(desc) + 1); +} + +static Elf_Bhdr *build_boot_notes(struct sys_info *info, const char *cmdline) +{ + Elf_Bhdr *bhdr; + + bhdr = malloc(256); + bhdr->b_signature = ELF_BHDR_MAGIC; + bhdr->b_size = sizeof *bhdr; + bhdr->b_checksum = 256; /* XXX cache the current buffer size here */ + bhdr->b_records = 0; + + if (info->firmware) + bhdr = add_note_string(bhdr, NULL, EBN_FIRMWARE_TYPE, info->firmware); + bhdr = add_note_string(bhdr, NULL, EBN_BOOTLOADER_NAME, program_name); + bhdr = add_note_string(bhdr, NULL, EBN_BOOTLOADER_VERSION, program_version); + if (cmdline) + bhdr = add_note_string(bhdr, NULL, EBN_COMMAND_LINE, cmdline); + if (!bhdr) + return bhdr; + bhdr->b_checksum = 0; + bhdr->b_checksum = ipchksum(bhdr, bhdr->b_size); + return bhdr; +} + +int elf_load(struct sys_info *info, const char *filename, const char *cmdline) +{ + Elf_ehdr ehdr; + Elf_phdr *phdr = NULL; + unsigned long phdr_size; + unsigned long checksum_offset; + unsigned short checksum; + Elf_Bhdr *boot_notes = NULL; + int retval = -1; + int image_retval; + unsigned int offset; + + image_name = image_version = 0; + + if (!file_open(filename)) + goto out; + + for (offset = 0; offset < 16 * 512; offset += 512) { + if (lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) { + debug("Can't read ELF header\n"); + retval = LOADER_NOT_SUPPORT; + goto out; + } + + if (ehdr.e_ident[EI_MAG0] == ELFMAG0) + break; + + file_seek(offset); + } + + if (ehdr.e_ident[EI_MAG0] != ELFMAG0 + || ehdr.e_ident[EI_MAG1] != ELFMAG1 + || ehdr.e_ident[EI_MAG2] != ELFMAG2 + || ehdr.e_ident[EI_MAG3] != ELFMAG3 + || ehdr.e_ident[EI_CLASS] != ARCH_ELF_CLASS + || ehdr.e_ident[EI_DATA] != ARCH_ELF_DATA + || ehdr.e_ident[EI_VERSION] != EV_CURRENT + || ehdr.e_type != ET_EXEC + || !ARCH_ELF_MACHINE_OK(ehdr.e_machine) + || ehdr.e_version != EV_CURRENT + || ehdr.e_phentsize != sizeof(Elf_phdr)) { + debug("Not a bootable ELF image\n"); + retval = LOADER_NOT_SUPPORT; + goto out; + } + + phdr_size = ehdr.e_phnum * sizeof *phdr; + phdr = malloc(phdr_size); + file_seek(offset + ehdr.e_phoff); + if (lfile_read(phdr, phdr_size) != phdr_size) { + printf("Can't read program header\n"); + goto out; + } + + if (!check_mem_ranges(info, phdr, ehdr.e_phnum)) + goto out; + + checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum, offset); + + printf("Loading %s", image_name ? image_name : "image"); + if (image_version) + printf(" version %s", image_version); + printf("...\n"); + + if (!load_segments(phdr, ehdr.e_phnum, checksum_offset, offset)) + goto out; + + if (checksum_offset) { + if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum)) + goto out; + } + + boot_notes = build_boot_notes(info, cmdline); + + //debug("current time: %lu\n", currticks()); + + debug("entry point is %#lx\n", addr_fixup(ehdr.e_entry)); + printf("Jumping to entry point...\n"); + +#if 0 + { + extern unsigned int qemu_mem_size; + extern char boot_device; + void *init_openprom(unsigned long memsize, const char *cmdline, char boot_device); + + int (*entry)(const void *romvec, int p2, int p3, int p4, int p5); + const void *romvec; + + romvec = init_openprom(qemu_mem_size, cmdline, boot_device); + entry = (void *) addr_fixup(ehdr.e_entry); + image_retval = entry(romvec, 0, 0, 0, 0); + } +#else + image_retval = start_elf(addr_fixup(ehdr.e_entry), virt_to_phys(boot_notes)); +#endif + + // console_init(); FIXME + printf("Image returned with return value %#x\n", image_retval); + retval = 0; + +out: + file_close(); + if (phdr) + free(phdr); + if (boot_notes) + free(boot_notes); + if (image_name) + free(image_name); + if (image_version) + free(image_version); + return retval; +}
Added: openbios-devel/arch/sparc64/entry.S =================================================================== --- openbios-devel/arch/sparc64/entry.S (rev 0) +++ openbios-devel/arch/sparc64/entry.S 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,250 @@ +/** + ** Standalone startup code for Linux PROM emulator. + ** Copyright 1999 Pete A. Zaitcev + ** This code is licensed under GNU General Public License. + **/ +/* + * $Id: head.S,v 1.12 2002/07/23 05:47:09 zaitcev Exp $ + */ + +#define __ASSEMBLY__ +#include "asi.h" +#include "pstate.h" +#include "lsu.h" + + .globl entry, _entry + + .section ".text", "ax" + .align 8 + .register %g2, #scratch + .register %g3, #scratch + .register %g6, #scratch + .register %g7, #scratch + +/* + * Entry point + * We start execution from here. + */ +_entry: +entry: + ! Set up CPU state + wrpr %g0, PSTATE_PRIV, %pstate + wr %g0, 0, %fprs + wrpr %g0, 0x0, %tl + + ! Extract NWINDOWS from %ver + rdpr %ver, %g1 + and %g1, 0xf, %g1 + wrpr %g1, 0, %cleanwin + wrpr %g1, 0, %cansave + wrpr %g0, 0, %canrestore + wrpr %g0, 0, %otherwin + wrpr %g0, 0, %wstate + + ! Disable I/D MMUs and caches + stxa %g0, [%g0] ASI_LSU_CONTROL + + ! Get memory size from NVRAM + setx 0x1fe02000074, %g2, %g5 + mov 0x30, %g2 + stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E + add %g5, 1, %g1 + stba %g0, [%g1] ASI_PHYS_BYPASS_EC_E + add %g1, 2, %g1 + lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g4 + + sll %g4, 8, %g4 + inc %g2 + stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E + lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3 + or %g3, %g4, %g4 + + sll %g4, 8, %g4 + inc %g2 + stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E + lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3 + or %g3, %g4, %g4 + + sll %g4, 8, %g4 + inc %g2 + stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E + lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3 + or %g3, %g4, %g1 + ! %g1 contains end of memory + + + setx _end, %g7, %g3 + set 0xffff, %g2 + add %g3, %g2, %g3 + andn %g3, %g2, %g3 + setx _data, %g7, %g2 + sub %g3, %g2, %g2 + sub %g1, %g2, %g2 ! %g2 = start of private memory + mov %g2, %l0 + + ! setup .data & .bss + setx _data, %g7, %g4 + sub %g3, %g4, %g5 + srlx %g5, 16, %g6 ! %g6 = # of 64k .bss pages + set 0xa0000000, %g3 + sllx %g3, 32, %g3 + or %g3, 0x76, %g3 + ! valid, 64k, locked, cacheable(I/E/C), priv, writable + set 48, %g7 +1: stxa %g4, [%g7] ASI_DMMU ! vaddr = _data + N * 0x10000, ctx=0 + or %g2, %g3, %g5 + ! paddr = start_mem + N * 0x10000 + stxa %g5, [%g0] ASI_DTLB_DATA_IN + set 0x10000, %g5 + add %g2, %g5, %g2 + add %g4, %g5, %g4 + deccc %g6 + bne 1b + nop + + ! setup .rodata + setx _data, %g7, %g5 + setx _rodata, %g7, %g4 + sub %g5, %g4, %g5 + srlx %g5, 16, %g6 ! %g6 = # of 64k .rodata pages + set 48, %g7 + set 0x10000, %g5 +1: stxa %g4, [%g7] ASI_DMMU ! vaddr = _rodata, ctx=0 + set 0xa0000000, %g3 + sllx %g3, 32, %g3 + or %g3, 0x74, %g3 + or %g4, %g3, %g3 + ! valid, 64k, locked, cacheable(I/E/C), priv + ! paddr = _rodata + N * 0x10000 + stxa %g3, [%g0] ASI_DTLB_DATA_IN + add %g4, %g5, %g4 + deccc %g6 + bne 1b + nop + + ! setup VGA buffer + setx 0x1ff004a0000, %g7, %g4 + mov 2, %g6 + set 48, %g7 + set 0x10000, %g5 +1: stxa %g4, [%g7] ASI_DMMU ! vaddr = 0x1ff004a0000, ctx=0 + set 0xa0000000, %g3 + sllx %g3, 32, %g3 + or %g3, 0x76, %g3 + or %g4, %g3, %g3 + ! valid, 64k, locked, cacheable(I/E/C), priv, writable + ! paddr = 0x1ff004a0000 + stxa %g3, [%g0] ASI_DTLB_DATA_IN + add %g4, %g5, %g4 + deccc %g6 + bne 1b + nop + +#if 0 + ! setup 0-4M + set 48, %g7 + stxa %g0, [%g7] ASI_DMMU ! vaddr = 0, ctx=0 + set 0xe0000000, %g3 + sllx %g3, 32, %g3 + or %g3, 0x36, %g3 + ! valid, 4M, cacheable(I/E/C), priv, writable + ! paddr = 0 + stxa %g3, [%g0] ASI_DTLB_DATA_IN +#endif + + membar #Sync + + setx _start, %g7, %g4 + setx _rodata, %g7, %g5 + sub %g5, %g4, %g5 + srlx %g5, 16, %g6 ! %g6 = # of 64k .text pages + set 48, %g7 +1: stxa %g4, [%g7] ASI_IMMU ! vaddr = _start, ctx=0 + set 0xa0000000, %g3 + sllx %g3, 32, %g3 + or %g3, 0x74, %g3 + or %g4, %g3, %g3 + ! valid, 64k, locked, cacheable(I/E/C), priv + ! paddr = _start + N * 0x10000 + stxa %g3, [%g0] ASI_ITLB_DATA_IN + set 0x10000, %g5 + add %g4, %g5, %g4 + deccc %g6 + bne 1b + nop + +#if 0 + ! setup 0-4M + stxa %g0, [%g7] ASI_IMMU ! vaddr = 0, ctx=0 + set 0xe0000000, %g3 + sllx %g3, 32, %g3 + or %g3, 0x34, %g3 + ! valid, 4M, cacheable(I/E/C), priv + ! paddr = 0 + stxa %g3, [%g0] ASI_ITLB_DATA_IN +#endif + + flush %g4 + + mov %g1, %g3 + + set 8, %g2 + sta %g0, [%g2] ASI_DMMU ! set primary ctx=0 + + ! Enable I/D MMUs and caches + set LSU_CONTROL_DM|LSU_CONTROL_IM|LSU_CONTROL_DC|LSU_CONTROL_IC, %g2 + stxa %g2, [%g0] ASI_LSU_CONTROL + + /* Copy the DATA section from ROM. */ + setx _data - 8, %o7, %o0 ! First address of DATA + setx _bss, %o7, %o1 ! Last address of DATA + ba 2f + nop +1: + ldxa [%o0] ASI_PHYS_BYPASS_EC_E, %g1 + stx %g1, [%o0] +2: + subcc %o0, %o1, %g0 + bl 1b + add %o0, 0x8, %o0 + + /* Zero out our BSS section. */ + setx _bss - 8, %o7, %o0 ! First address of BSS + setx _end, %o7, %o1 ! Last address of BSS + ba 2f + nop +1: + stx %g0, [%o0] +2: + subcc %o0, %o1, %g0 + bl 1b + add %o0, 0x8, %o0 + + setx trap_table, %g2, %g1 + wrpr %g1, %tba + + setx qemu_mem_size, %g7, %g1 + stx %g3, [%g1] + + setx _data, %g7, %g1 ! Store va->pa conversion factor + sub %g1, %l0, %g2 + setx va_shift, %g7, %g1 + stx %g2, [%g1] + + /* Finally, turn on traps so that we can call c-code. */ + wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate + + /* Switch to our main context. + * Main context is statically defined in C. + */ + + call __switch_context_nosave + nop + + /* We get here when the main context switches back to + * the boot context. + * Return to previous bootloader. + */ + ret + nop +
Added: openbios-devel/arch/sparc64/forthload.c =================================================================== --- openbios-devel/arch/sparc64/forthload.c (rev 0) +++ openbios-devel/arch/sparc64/forthload.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,62 @@ +/* tag: forth source loader + * + * Copyright (C) 2004 Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +#include "openbios/config.h" +#include "openbios/kernel.h" +#include "openbios/bindings.h" +#include "sys_info.h" +#include "loadfs.h" +#include "boot.h" +#define printk printk +#define debug printk + +static char *forthtext=NULL; +int forth_load(struct sys_info *info, const char *filename, const char *cmdline) +{ + char magic[2]; + unsigned long forthsize; + int retval = -1; + + if (!file_open(filename)) + goto out; + + if (lfile_read(magic, 2) != 2) { + debug("Can't read magic header\n"); + retval = LOADER_NOT_SUPPORT; + goto out; + } + + if (magic[0] != '\' || magic[1] != ' ') { + debug("No forth source image\n"); + retval = LOADER_NOT_SUPPORT; + goto out; + } + + forthsize = file_size(); + + forthtext = malloc(forthsize+1); + file_seek(0); + + printk("Loading forth source ..."); + if ((unsigned long)lfile_read(forthtext, forthsize) != forthsize) { + printk("Can't read forth text\n"); + goto out; + } + forthtext[forthsize]=0; + printk("ok\n"); + + PUSH ( (ucell)forthtext ); + PUSH ( (ucell)forthsize ); + fword("eval2"); + retval=0; + +out: + //if (forthtext) + // free(forthtext); + return retval; +}
Added: openbios-devel/arch/sparc64/init.fs =================================================================== --- openbios-devel/arch/sparc64/init.fs (rev 0) +++ openbios-devel/arch/sparc64/init.fs 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,58 @@ +:noname + ." Type 'help' for detailed information" cr + \ ." boot secondary slave cdrom: " cr + \ ." 0 > boot hd:2,\boot\vmlinuz root=/dev/hda2" cr + ; DIAG-initializer + +: make-openable ( path ) + find-dev if + begin ?dup while + \ install trivial open and close methods + dup active-package! is-open + parent + repeat + then +; + +: preopen ( chosen-str node-path ) + 2dup make-openable + + " /chosen" find-device + open-dev ?dup if + encode-int 2swap property + else + 2drop + then +; + +:noname + set-defaults +; SYSTEM-initializer + +\ preopen device nodes (and store the ihandles under /chosen) +:noname + " memory" " /memory" preopen + " mmu" " /cpus/@0" preopen + " stdout" " /builtin/console" preopen + " stdin" " /builtin/console" preopen + +; SYSTEM-initializer + +\ use the tty interface if available +:noname + " /builtin/console" find-dev if drop + " /builtin/console" " input-device" $setenv + " /builtin/console" " output-device" $setenv + then +; SYSTEM-initializer + +:noname + " keyboard" input +; CONSOLE-IN-initializer + +device-end + +: rmap@ ( virt -- rmentry ) + drop 0 + ; +
Added: openbios-devel/arch/sparc64/ldscript =================================================================== --- openbios-devel/arch/sparc64/ldscript (rev 0) +++ openbios-devel/arch/sparc64/ldscript 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,83 @@ +OUTPUT_FORMAT(elf64-sparc) +OUTPUT_ARCH(sparc:v9) + +/* 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 + */ +BASE_ADDR = 0x000001fff0000000; + +/* 16KB heap and stack */ +HEAP_SIZE = 16384; +STACK_SIZE = 16384; +VMEM_SIZE = 128 * 1024; +IOMEM_SIZE = 256 * 1024 + 768 * 1024; + +SECTIONS +{ + . = BASE_ADDR; + + /* Start of the program. + * Now the version string is in the note, we must include it + * in the program. Otherwise we lose the string after relocation. */ + _start = .; + + /* Normal sections */ + .text ALIGN(65536): { + *(.text.vectors) + *(.text) + *(.text.*) + } + .rodata ALIGN(65536): { + _rodata = .; + sound_drivers_start = .; + *(.rodata.sound_drivers) + sound_drivers_end = .; + *(.rodata) + *(.rodata.*) + *(.note.ELFBoot) + } + .data ALIGN(65536): { + _data = .; + *(.data) + *(.data.*) + } + + .bss ALIGN(4096): { + _bss = .; + *(.bss) + *(.bss.*) + *(COMMON) + + /* Put heap and stack here, so they are included in PT_LOAD segment + * and the bootloader is aware of it. */ + + . = ALIGN(16); + _heap = .; + . += HEAP_SIZE; + . = ALIGN(16); + _eheap = .; + + . = ALIGN(4096); + _vmem = .; + . += VMEM_SIZE; + _evmem = .; + + _stack = .; + . += STACK_SIZE; + . = ALIGN(16); + _estack = .; + } + + . = ALIGN(4096); + _end = .; + _iomem = _end + IOMEM_SIZE; + + /* We discard .note sections other than .note.ELFBoot, + * because some versions of GCC generates useless ones. */ + + /DISCARD/ : { *(.comment*) *(.note.*) } +}
Added: openbios-devel/arch/sparc64/lib.c =================================================================== --- openbios-devel/arch/sparc64/lib.c (rev 0) +++ openbios-devel/arch/sparc64/lib.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,59 @@ +/* lib.c + * tag: simple function library + * + * Copyright (C) 2003 Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +#include "openbios/config.h" +#include "asm/types.h" +#include <stdarg.h> +#include "libc/stdlib.h" +#include "libc/vsprintf.h" +#include "openbios/kernel.h" + +/* Format a string and print it on the screen, just like the libc + * function printf. + */ +int printk( const char *fmt, ... ) +{ + char *p, buf[512]; /* XXX: no buffer overflow protection... */ + va_list args; + int i; + + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + + for( p=buf; *p; p++ ) + putchar(*p); + return i; +} + +#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; +} + +void free(void *ptr) +{ + /* Nothing yet */ +} + +unsigned long map_page(unsigned long va, unsigned long epa, int type) +{ +}
Added: openbios-devel/arch/sparc64/linux_load.c =================================================================== --- openbios-devel/arch/sparc64/linux_load.c (rev 0) +++ openbios-devel/arch/sparc64/linux_load.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,623 @@ +/* + * Linux/i386 loader + * Supports bzImage, zImage and Image format. + * + * Based on work by Steve Gehlbach. + * Portions are taken from mkelfImage. + * + * 2003-09 by SONE Takeshi + */ + +#include "openbios/config.h" +#include "openbios/kernel.h" +#include "openbios/bindings.h" +#include "sys_info.h" +#include "context.h" +#include "loadfs.h" + +#define printf printk +#define debug printk +#define strtoull_with_suffix strtol + +#define LINUX_PARAM_LOC 0x90000 +#define COMMAND_LINE_LOC 0x91000 +#define GDT_LOC 0x92000 +#define STACK_LOC 0x93000 + +#define E820MAX 32 /* number of entries in E820MAP */ +struct e820entry { + unsigned long long addr; /* start of memory segment */ + unsigned long long size; /* size of memory segment */ + unsigned long type; /* type of memory segment */ +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */ +#define E820_NVS 4 +}; + +/* The header of Linux/i386 kernel */ +struct linux_header { + uint8_t reserved1[0x1f1]; /* 0x000 */ + uint8_t setup_sects; /* 0x1f1 */ + uint16_t root_flags; /* 0x1f2 */ + uint8_t reserved2[6]; /* 0x1f4 */ + uint16_t vid_mode; /* 0x1fa */ + uint16_t root_dev; /* 0x1fc */ + uint16_t boot_sector_magic; /* 0x1fe */ + /* 2.00+ */ + uint8_t reserved3[2]; /* 0x200 */ + uint8_t header_magic[4]; /* 0x202 */ + uint16_t protocol_version; /* 0x206 */ + uint32_t realmode_swtch; /* 0x208 */ + uint16_t start_sys; /* 0x20c */ + uint16_t kver_addr; /* 0x20e */ + uint8_t type_of_loader; /* 0x210 */ + uint8_t loadflags; /* 0x211 */ + uint16_t setup_move_size; /* 0x212 */ + uint32_t code32_start; /* 0x214 */ + uint32_t ramdisk_image; /* 0x218 */ + uint32_t ramdisk_size; /* 0x21c */ + uint8_t reserved4[4]; /* 0x220 */ + /* 2.01+ */ + uint16_t heap_end_ptr; /* 0x224 */ + uint8_t reserved5[2]; /* 0x226 */ + /* 2.02+ */ + uint32_t cmd_line_ptr; /* 0x228 */ + /* 2.03+ */ + uint32_t initrd_addr_max; /* 0x22c */ +} __attribute__ ((packed)); + + +/* Paramters passed to 32-bit part of Linux + * This is another view of the structure above.. */ +struct linux_params { + uint8_t orig_x; /* 0x00 */ + uint8_t orig_y; /* 0x01 */ + uint16_t ext_mem_k; /* 0x02 -- EXT_MEM_K sits here */ + uint16_t orig_video_page; /* 0x04 */ + uint8_t orig_video_mode; /* 0x06 */ + uint8_t orig_video_cols; /* 0x07 */ + uint16_t unused2; /* 0x08 */ + uint16_t orig_video_ega_bx; /* 0x0a */ + uint16_t unused3; /* 0x0c */ + uint8_t orig_video_lines; /* 0x0e */ + uint8_t orig_video_isVGA; /* 0x0f */ + uint16_t orig_video_points; /* 0x10 */ + + /* VESA graphic mode -- linear frame buffer */ + uint16_t lfb_width; /* 0x12 */ + uint16_t lfb_height; /* 0x14 */ + uint16_t lfb_depth; /* 0x16 */ + uint32_t lfb_base; /* 0x18 */ + uint32_t lfb_size; /* 0x1c */ + uint16_t cl_magic; /* 0x20 */ +#define CL_MAGIC_VALUE 0xA33F + uint16_t cl_offset; /* 0x22 */ + uint16_t lfb_linelength; /* 0x24 */ + uint8_t red_size; /* 0x26 */ + uint8_t red_pos; /* 0x27 */ + uint8_t green_size; /* 0x28 */ + uint8_t green_pos; /* 0x29 */ + uint8_t blue_size; /* 0x2a */ + uint8_t blue_pos; /* 0x2b */ + uint8_t rsvd_size; /* 0x2c */ + uint8_t rsvd_pos; /* 0x2d */ + uint16_t vesapm_seg; /* 0x2e */ + uint16_t vesapm_off; /* 0x30 */ + uint16_t pages; /* 0x32 */ + uint8_t reserved4[12]; /* 0x34 -- 0x3f reserved for future expansion */ + + //struct apm_bios_info apm_bios_info; /* 0x40 */ + uint8_t apm_bios_info[0x40]; + //struct drive_info_struct drive_info; /* 0x80 */ + uint8_t drive_info[0x20]; + //struct sys_desc_table sys_desc_table; /* 0xa0 */ + uint8_t sys_desc_table[0x140]; + uint32_t alt_mem_k; /* 0x1e0 */ + uint8_t reserved5[4]; /* 0x1e4 */ + uint8_t e820_map_nr; /* 0x1e8 */ + uint8_t reserved6[9]; /* 0x1e9 */ + uint16_t mount_root_rdonly; /* 0x1f2 */ + uint8_t reserved7[4]; /* 0x1f4 */ + uint16_t ramdisk_flags; /* 0x1f8 */ +#define RAMDISK_IMAGE_START_MASK 0x07FF +#define RAMDISK_PROMPT_FLAG 0x8000 +#define RAMDISK_LOAD_FLAG 0x4000 + uint8_t reserved8[2]; /* 0x1fa */ + uint16_t orig_root_dev; /* 0x1fc */ + uint8_t reserved9[1]; /* 0x1fe */ + uint8_t aux_device_info; /* 0x1ff */ + uint8_t reserved10[2]; /* 0x200 */ + uint8_t param_block_signature[4]; /* 0x202 */ + uint16_t param_block_version; /* 0x206 */ + uint8_t reserved11[8]; /* 0x208 */ + uint8_t loader_type; /* 0x210 */ +#define LOADER_TYPE_LOADLIN 1 +#define LOADER_TYPE_BOOTSECT_LOADER 2 +#define LOADER_TYPE_SYSLINUX 3 +#define LOADER_TYPE_ETHERBOOT 4 +#define LOADER_TYPE_KERNEL 5 + uint8_t loader_flags; /* 0x211 */ + uint8_t reserved12[2]; /* 0x212 */ + uint32_t kernel_start; /* 0x214 */ + uint32_t initrd_start; /* 0x218 */ + uint32_t initrd_size; /* 0x21c */ + uint8_t reserved12_5[8]; /* 0x220 */ + uint32_t cmd_line_ptr; /* 0x228 */ + uint8_t reserved13[164]; /* 0x22c */ + struct e820entry e820_map[E820MAX]; /* 0x2d0 */ + uint8_t reserved16[688]; /* 0x550 */ +#define COMMAND_LINE_SIZE 256 + /* Command line is copied here by 32-bit i386/kernel/head.S. + * So I will follow the boot protocol, rather than putting it + * directly here. --ts1 */ + uint8_t command_line[COMMAND_LINE_SIZE]; /* 0x800 */ + uint8_t reserved17[1792]; /* 0x900 - 0x1000 */ +}; + +uint64_t forced_memsize; + +/* Load the first part the file and check if it's Linux */ +static uint32_t load_linux_header(struct linux_header *hdr) +{ + int load_high; + uint32_t kern_addr; + + if (lfile_read(hdr, sizeof *hdr) != sizeof *hdr) { + debug("Can't read Linux header\n"); + return 0; + } + if (hdr->boot_sector_magic != 0xaa55) { + debug("Not a Linux kernel image\n"); + return 0; + } + + /* Linux is found. Print some information */ + if (memcmp(hdr->header_magic, "HdrS", 4) != 0) { + /* This may be floppy disk image or something. + * Perform a simple (incomplete) sanity check. */ + if (hdr->setup_sects >= 16 + || file_size() - (hdr->setup_sects<<9) >= 512<<10) { + debug("This looks like a bootdisk image but not like Linux...\n"); + return 0; + } + + printf("Possible very old Linux"); + /* This kernel does not even have a protocol version. + * Force the value. */ + hdr->protocol_version = 0; /* pre-2.00 */ + } else + printf("Found Linux"); + if (hdr->protocol_version >= 0x200 && hdr->kver_addr) { + char kver[256]; + file_seek(hdr->kver_addr + 0x200); + if (lfile_read(kver, sizeof kver) != 0) { + kver[255] = 0; + printf(" version %s", kver); + } + } + debug(" (protocol %#x)", hdr->protocol_version); + load_high = 0; + if (hdr->protocol_version >= 0x200) { + debug(" (loadflags %#x)", hdr->loadflags); + load_high = hdr->loadflags & 1; + } + if (load_high) { + printf(" bzImage"); + kern_addr = 0x100000; + } else { + printf(" zImage or Image"); + kern_addr = 0x1000; + } + printf(".\n"); + + return kern_addr; +} + +/* Set up parameters for 32-bit kernel */ +static void +init_linux_params(struct linux_params *params, struct linux_header *hdr) +{ + debug("Setting up paramters at %#lx\n", virt_to_phys(params)); + memset(params, 0, sizeof *params); + + /* Copy some useful values from header */ + params->mount_root_rdonly = hdr->root_flags; + params->orig_root_dev = hdr->root_dev; + + /* Video parameters. + * This assumes we have VGA in standard 80x25 text mode, + * just like our vga.c does. + * Cursor position is filled later to allow some more printf's. */ + params->orig_video_mode = 3; + params->orig_video_cols = 80; + params->orig_video_lines = 25; + params->orig_video_isVGA = 1; + params->orig_video_points = 16; + + params->loader_type = 0xff; /* Unregistered Linux loader */ +} + +/* Memory map */ +static void +set_memory_size(struct linux_params *params, struct sys_info *info) +{ + int i; + uint64_t end; + uint32_t ramtop = 0; + struct e820entry *linux_map; + struct memrange *filo_map; + + linux_map = params->e820_map; + filo_map = info->memrange; + for (i = 0; i < info->n_memranges; i++, linux_map++, filo_map++) { + if (i < E820MAX) { + /* Convert to BIOS e820 style */ + linux_map->addr = filo_map->base; + linux_map->size = filo_map->size; + linux_map->type = E820_RAM; + debug("%016Lx - %016Lx\n", linux_map->addr, + linux_map->addr + linux_map->size); + params->e820_map_nr = i+1; + } + + /* Find out top of RAM. XXX This ignores hole above 1MB */ + end = filo_map->base + filo_map->size; + if (end < (1ULL << 32)) { /* don't count memory above 4GB */ + if (end > ramtop) + ramtop = (uint32_t) end; + } + } + debug("ramtop=%#x\n", ramtop); + /* Size of memory above 1MB in KB */ + params->alt_mem_k = (ramtop - (1<<20)) >> 10; + /* old style, 64MB max */ + if (ramtop >= (64<<20)) + params->ext_mem_k = (63<<10); + else + params->ext_mem_k = params->alt_mem_k; + debug("ext_mem_k=%d, alt_mem_k=%d\n", params->ext_mem_k, params->alt_mem_k); +} + +/* + * Parse command line + * Some parameters, like initrd=<file>, are not passed to kernel, + * we are responsible to process them. + * Parameters for kernel are copied to kern_cmdline. Returns name of initrd. + */ +static char *parse_command_line(const char *orig_cmdline, char *kern_cmdline) +{ + const char *start, *sep, *end, *val; + char name[64]; + unsigned long len; + int k_len; + int to_kern; + char *initrd = 0; + int toolong = 0; + + forced_memsize = 0; + + if (!orig_cmdline) { + *kern_cmdline = 0; + return 0; + } + + k_len = 0; + debug("original command line: "%s"\n", orig_cmdline); + debug("kernel command line at %#lx\n", virt_to_phys(kern_cmdline)); + + start = orig_cmdline; + while (*start == ' ') + start++; + while (*start) { + end = strchr(start, ' '); + if (!end) + end = start + strlen(start); + sep = strchr(start, '='); + if (!sep || sep > end) + sep = end; + len = sep - start; + if (len >= sizeof(name)) + len = sizeof(name) - 1; + memcpy(name, start, len); + name[len] = 0; + + if (*sep == '=') { + val = sep + 1; + len = end - val; + } else { + val = 0; + len = 0; + } + + /* Only initrd= and mem= are handled here. vga= is not, + * which I believe is a paramter to the realmode part of Linux, + * which we don't execute. */ + if (strcmp(name, "initrd") == 0) { + if (!val) + printf("Missing filename to initrd parameter\n"); + else { + initrd = malloc(len + 1); + memcpy(initrd, val, len); + initrd[len] = 0; + debug("initrd=%s\n", initrd); + } + /* Don't pass this to kernel */ + to_kern = 0; + } else if (strcmp(name, "mem") == 0) { + if (!val) + printf("Missing value for mem parameter\n"); + else { + forced_memsize = strtoull_with_suffix(val, (char**)&val, 0); + if (forced_memsize == 0) + printf("Invalid mem option, ignored\n"); + if (val != end) { + printf("Garbage after mem=<size>, ignored\n"); + forced_memsize = 0; + } + debug("mem=%Lu\n", forced_memsize); + } + /* mem= is for both loader and kernel */ + to_kern = 1; + } else + to_kern = 1; + + if (to_kern) { + /* Copy to kernel command line buffer */ + if (k_len != 0) + kern_cmdline[k_len++] = ' '; /* put separator */ + len = end - start; + if (k_len + len >= COMMAND_LINE_SIZE) { + len = COMMAND_LINE_SIZE - k_len - 1; + if (!toolong) { + printf("Kernel command line is too long; truncated to " + "%d bytes\n", COMMAND_LINE_SIZE-1); + toolong = 1; + } + } + memcpy(kern_cmdline + k_len, start, len); + k_len += len; + } + + start = end; + while (*start == ' ') + start++; + } + kern_cmdline[k_len] = 0; + debug("kernel command line (%d bytes): "%s"\n", k_len, kern_cmdline); + + return initrd; +} + +/* Set command line location */ +static void set_command_line_loc(struct linux_params *params, + struct linux_header *hdr) +{ + if (hdr->protocol_version >= 0x202) { + /* new style */ + params->cmd_line_ptr = COMMAND_LINE_LOC; + } else { + /* old style */ + params->cl_magic = CL_MAGIC_VALUE; + params->cl_offset = COMMAND_LINE_LOC - LINUX_PARAM_LOC; + } +} + +/* Load 32-bit part of kernel */ +static int load_linux_kernel(struct linux_header *hdr, uint32_t kern_addr) +{ + uint32_t kern_offset, kern_size; + + if (hdr->setup_sects == 0) + hdr->setup_sects = 4; + kern_offset = (hdr->setup_sects + 1) * 512; + file_seek(kern_offset); + kern_size = file_size() - kern_offset; + debug("offset=%#x addr=%#x size=%#x\n", kern_offset, kern_addr, kern_size); + +#if 0 + if (using_devsize) { + printf("Attempt to load up to end of device as kernel; " + "specify the image size\n"); + return 0; + } +#endif + + printf("Loading kernel... "); + if (lfile_read(phys_to_virt(kern_addr), kern_size) != kern_size) { + printf("Can't read kernel\n"); + return 0; + } + printf("ok\n"); + + return kern_size; +} + +static int load_initrd(struct linux_header *hdr, struct sys_info *info, + uint32_t kern_end, struct linux_params *params, const char *initrd_file) +{ + uint32_t max; + uint32_t start, end, size; + uint64_t forced; + + if (!file_open(initrd_file)) { + printf("Can't open initrd: %s\n", initrd_file); + return -1; + } + +#if 0 + if (using_devsize) { + printf("Attempt to load up to end of device as initrd; " + "specify the image size\n"); + return -1; + } +#endif + + size = file_size(); + + + /* Find out the kernel's restriction on how high the initrd can be + * placed */ + if (hdr->protocol_version >= 0x203) + max = hdr->initrd_addr_max; + else + max = 0x38000000; /* Hardcoded value for older kernels */ + + /* FILO itself is at the top of RAM. (relocated) + * So, try putting initrd just below us. */ + end = virt_to_phys(_start); + if (end > max) + end = max; + + /* If "mem=" option is given, we have to put the initrd within + * the specified range. */ + if (forced_memsize) { + forced = forced_memsize; + if (forced > max) + forced = max; + /* If the "mem=" is lower, it's easy */ + if (forced <= end) + end = forced; + else { + /* Otherwise, see if we can put it above us */ + if (virt_to_phys(_end) + size <= forced) + end = forced; /* Ok */ + } + } + + start = end - size; + start &= ~0xfff; /* page align */ + end = start + size; + + debug("start=%#x end=%#x\n", start, end); + + if (start < kern_end) { + printf("Initrd is too big to fit in memory\n"); + return -1; + } + + printf("Loading initrd... "); + if (lfile_read(phys_to_virt(start), size) != size) { + printf("Can't read initrd\n"); + return -1; + } + printf("ok\n"); + + params->initrd_start = start; + params->initrd_size = size; + + return 0; +} + +static void hardware_setup(void) +{ + /* Disable nmi */ + outb(0x80, 0x70); + + /* Make sure any coprocessor is properly reset.. */ + outb(0, 0xf0); + outb(0, 0xf1); + + /* we're getting screwed again and again by this problem of the 8259. + * so we're going to leave this lying around for inclusion into + * crt0.S on an as-needed basis. + * + * well, that went ok, I hope. Now we have to reprogram the interrupts :-( + * we put them right after the intel-reserved hardware interrupts, at + * int 0x20-0x2F. There they won't mess up anything. Sadly IBM really + * messed this up with the original PC, and they haven't been able to + * rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f, + * which is used for the internal hardware interrupts as well. We just + * have to reprogram the 8259's, and it isn't fun. + */ + + outb(0x11, 0x20); /* initialization sequence to 8259A-1 */ + outb(0x11, 0xA0); /* and to 8259A-2 */ + + outb(0x20, 0x21); /* start of hardware int's (0x20) */ + outb(0x28, 0xA1); /* start of hardware int's 2 (0x28) */ + + outb(0x04, 0x21); /* 8259-1 is master */ + outb(0x02, 0xA1); /* 8259-2 is slave */ + + outb(0x01, 0x21); /* 8086 mode for both */ + outb(0x01, 0xA1); + + outb(0xFF, 0xA1); /* mask off all interrupts for now */ + outb(0xFB, 0x21); /* mask all irq's but irq2 which is cascaded */ +} + +/* Start Linux */ +static int start_linux(uint32_t kern_addr, struct linux_params *params) +{ + struct context *ctx; + //extern int cursor_x, cursor_y; + + ctx = init_context(phys_to_virt(STACK_LOC), 4096, 0); + + /* Entry point */ + ctx->pc = kern_addr; + ctx->npc = kern_addr + 4; + + debug("pc=%#x\n", kern_addr); + printf("Jumping to entry point...\n"); + +#ifdef VGA_CONSOLE + /* Update VGA cursor position. + * This must be here because the printf changes the value! */ + params->orig_x = cursor_x; + params->orig_y = cursor_y; +#endif + + /* Go... */ + ctx = switch_to(ctx); + + /* It's impossible but... */ + printf("Returned with o0=%#x\n", ctx->regs[REG_O0]); + + return ctx->regs[REG_O0]; +} + +int linux_load(struct sys_info *info, const char *file, const char *cmdline) +{ + struct linux_header hdr; + struct linux_params *params; + uint32_t kern_addr, kern_size; + char *initrd_file = 0; + + if (!file_open(file)) + return -1; + + kern_addr = load_linux_header(&hdr); + if (kern_addr == 0) { + file_close(); + return LOADER_NOT_SUPPORT; + } + + params = phys_to_virt(LINUX_PARAM_LOC); + init_linux_params(params, &hdr); + set_memory_size(params, info); + initrd_file = parse_command_line(cmdline, phys_to_virt(COMMAND_LINE_LOC)); + set_command_line_loc(params, &hdr); + + kern_size = load_linux_kernel(&hdr, kern_addr); + if (kern_size == 0) { + if (initrd_file) + free(initrd_file); + return -1; + } + + if (initrd_file) { + if (load_initrd(&hdr, info, kern_addr+kern_size, params, initrd_file) + != 0) { + free(initrd_file); + return -1; + } + free(initrd_file); + } + + hardware_setup(); + + start_linux(kern_addr, params); + return 0; +}
Added: openbios-devel/arch/sparc64/loadfs.c =================================================================== --- openbios-devel/arch/sparc64/loadfs.c (rev 0) +++ openbios-devel/arch/sparc64/loadfs.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,64 @@ +#include "openbios/config.h" +#include "openbios/kernel.h" +#include "libc/diskio.h" +#include "loadfs.h" + +static int load_fd=-1; + +int file_open(const char *filename) +{ + load_fd=open_io(filename); + if(load_fd >= 0) + seek_io(load_fd, 0); + return load_fd>-1; +} + +void file_close(void) +{ + if(load_fd==-1) + return; + + close_io(load_fd); + load_fd=-1; +} + +int lfile_read(void *buf, unsigned long len) +{ + int ret = 0; + + if (load_fd >= 0) + ret=read_io(load_fd, buf, len); + return ret; +} + +int file_seek(unsigned long 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); + + /* go to end of file and get position */ + seek_io(load_fd, -1); + fsize=tell(load_fd); + + /* go back to old position */ + seek_io(load_fd, 0); + seek_io(load_fd, fpos); + + return fsize; +} + + +
Added: openbios-devel/arch/sparc64/loadfs.h =================================================================== --- openbios-devel/arch/sparc64/loadfs.h (rev 0) +++ openbios-devel/arch/sparc64/loadfs.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,7 @@ +int file_open(const char *filename); +int lfile_read(void *buf, unsigned long len); +int file_seek(unsigned long offset); +unsigned long file_size(void); + + +
Added: openbios-devel/arch/sparc64/lsu.h =================================================================== --- openbios-devel/arch/sparc64/lsu.h (rev 0) +++ openbios-devel/arch/sparc64/lsu.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,20 @@ +/* $Id: lsu.h,v 1.2 1997/04/04 00:50:22 davem Exp $ */ +#ifndef _SPARC64_LSU_H +#define _SPARC64_LSU_H + +#include "const.h" + +/* LSU Control Register */ +#define LSU_CONTROL_PM _AC(0x000001fe00000000,UL) /* Phys-watchpoint byte mask*/ +#define LSU_CONTROL_VM _AC(0x00000001fe000000,UL) /* Virt-watchpoint byte mask*/ +#define LSU_CONTROL_PR _AC(0x0000000001000000,UL) /* Phys-rd watchpoint enable*/ +#define LSU_CONTROL_PW _AC(0x0000000000800000,UL) /* Phys-wr watchpoint enable*/ +#define LSU_CONTROL_VR _AC(0x0000000000400000,UL) /* Virt-rd watchpoint enable*/ +#define LSU_CONTROL_VW _AC(0x0000000000200000,UL) /* Virt-wr watchpoint enable*/ +#define LSU_CONTROL_FM _AC(0x00000000000ffff0,UL) /* Parity mask enables. */ +#define LSU_CONTROL_DM _AC(0x0000000000000008,UL) /* Data MMU enable. */ +#define LSU_CONTROL_IM _AC(0x0000000000000004,UL) /* Instruction MMU enable. */ +#define LSU_CONTROL_DC _AC(0x0000000000000002,UL) /* Data cache enable. */ +#define LSU_CONTROL_IC _AC(0x0000000000000001,UL) /* Instruction cache enable.*/ + +#endif /* !(_SPARC64_LSU_H) */
Added: openbios-devel/arch/sparc64/multiboot.c =================================================================== --- openbios-devel/arch/sparc64/multiboot.c (rev 0) +++ openbios-devel/arch/sparc64/multiboot.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,125 @@ +/* Support for Multiboot */ + +#include "openbios/config.h" +#include "asm/io.h" +#include "sys_info.h" +#include "multiboot.h" + +#define printf printk +#ifdef CONFIG_DEBUG_BOOT +#define debug printk +#else +#define debug(x...) +#endif + +struct mbheader { + unsigned int magic, flags, checksum; +}; +const struct mbheader multiboot_header + __attribute__((section (".hdr"))) = +{ + MULTIBOOT_HEADER_MAGIC, + MULTIBOOT_HEADER_FLAGS, + -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) +}; + +/* Multiboot information structure, provided by loader to us */ + +struct multiboot_mmap { + unsigned entry_size; + unsigned base_lo, base_hi; + unsigned size_lo, size_hi; + unsigned type; +}; + +#define MULTIBOOT_MEM_VALID 0x01 +#define MULTIBOOT_BOOT_DEV_VALID 0x02 +#define MULTIBOOT_CMDLINE_VALID 0x04 +#define MULTIBOOT_MODS_VALID 0x08 +#define MULTIBOOT_AOUT_SYMS_VALID 0x10 +#define MULTIBOOT_ELF_SYMS_VALID 0x20 +#define MULTIBOOT_MMAP_VALID 0x40 + +void collect_multiboot_info(struct sys_info *info); +void collect_multiboot_info(struct sys_info *info) +{ + struct multiboot_info *mbinfo; + struct multiboot_mmap *mbmem; + unsigned mbcount, mbaddr; + unsigned int i; + struct memrange *mmap; + int mmap_count; + module_t *mod; + + if (info->boot_type != 0x2BADB002) + return; + + debug("Using Multiboot information at %#lx\n", info->boot_data); + + mbinfo = phys_to_virt(info->boot_data); + + if (mbinfo->mods_count != 1) { + printf("Multiboot: no dictionary\n"); + return; + } + + mod = (module_t *) mbinfo->mods_addr; + info->dict_start=(unsigned long *)mod->mod_start; + info->dict_end=(unsigned long *)mod->mod_end; + + if (mbinfo->flags & MULTIBOOT_MMAP_VALID) { + /* convert mmap records */ + mbmem = phys_to_virt(mbinfo->mmap_addr); + mbcount = mbinfo->mmap_length / (mbmem->entry_size + 4); + mmap = malloc(mbcount * sizeof(struct memrange)); + mmap_count = 0; + mbaddr = mbinfo->mmap_addr; + for (i = 0; i < mbcount; i++) { + mbmem = phys_to_virt(mbaddr); + debug("%08x%08x %08x%08x (%d)\n", + mbmem->base_hi, + mbmem->base_lo, + mbmem->size_hi, + mbmem->size_lo, + mbmem->type); + if (mbmem->type == 1) { /* Only normal RAM */ + mmap[mmap_count].base = mbmem->base_lo + + (((unsigned long long) mbmem->base_hi) << 32); + mmap[mmap_count].size = mbmem->size_lo + + (((unsigned long long) mbmem->size_hi) << 32); + mmap_count++; + } + mbaddr += mbmem->entry_size + 4; + if (mbaddr >= mbinfo->mmap_addr + mbinfo->mmap_length) + break; + } + /* simple sanity check - there should be at least 2 RAM segments + * (base 640k and extended) */ + if (mmap_count >= 2) + goto got_it; + + printf("Multiboot mmap is broken\n"); + free(mmap); + /* fall back to mem_lower/mem_upper */ + } + + if (mbinfo->flags & MULTIBOOT_MEM_VALID) { + /* use mem_lower and mem_upper */ + mmap_count = 2; + mmap = malloc(2 * sizeof(*mmap)); + mmap[0].base = 0; + mmap[0].size = mbinfo->mem_lower << 10; + mmap[1].base = 1 << 20; /* 1MB */ + mmap[1].size = mbinfo->mem_upper << 10; + goto got_it; + } + + printf("Can't get memory information from Multiboot\n"); + return; + +got_it: + info->memrange = mmap; + info->n_memranges = mmap_count; + + return; +}
Added: openbios-devel/arch/sparc64/multiboot.h =================================================================== --- openbios-devel/arch/sparc64/multiboot.h (rev 0) +++ openbios-devel/arch/sparc64/multiboot.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,96 @@ +/* multiboot.h + * tag: header for multiboot + * + * Copyright (C) 2003-2004 Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +/* magic number for multiboot header */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* flags for multiboot header */ +#define MULTIBOOT_HEADER_FLAGS 0x00010003 + +/* magic number passed by multiboot-compliant boot loader. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* The size of our stack (8KB). */ +#define STACK_SIZE 0x2000 + +/* C symbol format. HAVE_ASM_USCORE is defined by configure. */ +#ifdef HAVE_ASM_USCORE +# define EXT_C(sym) _ ## sym +#else +# define EXT_C(sym) sym +#endif + +#ifndef ASM +/* We don't want these declarations in boot.S */ + +/* multiboot header */ +typedef struct multiboot_header { + unsigned long magic; + unsigned long flags; + unsigned long checksum; + unsigned long header_addr; + unsigned long load_addr; + unsigned long load_end_addr; + unsigned long bss_end_addr; + unsigned long entry_addr; +} multiboot_header_t; + +/* symbol table for a.out */ +typedef struct aout_symbol_table { + unsigned long tabsize; + unsigned long strsize; + unsigned long addr; + unsigned long reserved; +} aout_symbol_table_t; + +/* section header table for ELF */ +typedef struct elf_section_header_table { + unsigned long num; + unsigned long size; + unsigned long addr; + unsigned long shndx; +} elf_section_header_table_t; + +/* multiboot information */ +typedef struct multiboot_info { + unsigned long flags; + unsigned long mem_lower; + unsigned long mem_upper; + unsigned long boot_device; + unsigned long cmdline; + unsigned long mods_count; + unsigned long mods_addr; + union { + aout_symbol_table_t aout_sym; + elf_section_header_table_t elf_sec; + } u; + unsigned long mmap_length; + unsigned long mmap_addr; +} multiboot_info_t; + +/* module structure */ +typedef struct module { + unsigned long mod_start; + unsigned long mod_end; + unsigned long string; + unsigned long reserved; +} module_t; + +/* memory map. Be careful that the offset 0 is base_addr_low + but no size. */ +typedef struct memory_map { + unsigned long size; + unsigned long base_addr_low; + unsigned long base_addr_high; + unsigned long length_low; + unsigned long length_high; + unsigned long type; +} memory_map_t; + +#endif /* ! ASM */
Added: openbios-devel/arch/sparc64/openbios.c =================================================================== --- openbios-devel/arch/sparc64/openbios.c (rev 0) +++ openbios-devel/arch/sparc64/openbios.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,115 @@ +/* tag: openbios forth environment, executable code + * + * Copyright (C) 2003 Patrick Mauritz, Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +#include "openbios/config.h" +#include "openbios/bindings.h" +#include "openbios/drivers.h" +#include "asm/types.h" +#include "dict.h" +#include "openbios/kernel.h" +#include "openbios/stack.h" +#include "sys_info.h" +#include "openbios.h" + +void boot(void); + +static unsigned char intdict[256 * 1024]; + +// XXX +void arch_nvram_put() +{ +} + +void arch_nvram_get() +{ +} + +int arch_nvram_size; + +static void init_memory(void) +{ + + /* push start and end of available memory to the stack + * so that the forth word QUIT can initialize memory + * management. For now we use hardcoded memory between + * 0x10000 and 0x9ffff (576k). If we need more memory + * than that we have serious bloat. + */ + + PUSH((unsigned int)&_heap); + PUSH((unsigned int)&_eheap); +} + +static void +arch_init( void ) +{ + void setup_timers(void); + + modules_init(); +#ifdef CONFIG_DEBUG_CONSOLE_VIDEO + init_video(); +#endif + + nvram_init(); + device_end(); + + bind_func("platform-boot", boot ); +} + +int openbios(void) +{ + extern struct sys_info sys_info; + +#ifdef CONFIG_DEBUG_CONSOLE +#ifdef CONFIG_DEBUG_CONSOLE_SERIAL + uart_init(CONFIG_SERIAL_PORT, CONFIG_SERIAL_SPEED); +#endif +#ifdef CONFIG_DEBUG_CONSOLE_VGA + video_init(); +#endif + /* Clear the screen. */ + cls(); + printk("OpenBIOS for Sparc64\n"); +#endif + + collect_sys_info(&sys_info); + + dict=intdict; + load_dictionary((char *)sys_info.dict_start, + (unsigned long)sys_info.dict_end + - (unsigned long)sys_info.dict_start); + +#ifdef CONFIG_DEBUG_BOOT + printk("forth started.\n"); + printk("initializing memory..."); +#endif + + init_memory(); + +#ifdef CONFIG_DEBUG_BOOT + printk("done\n"); +#endif + + PUSH_xt( bind_noname_func(arch_init) ); + fword("PREPOST-initializer"); + + PC = (ucell)findword("initialize-of"); + + if (!PC) { + printk("panic: no dictionary entry point.\n"); + return -1; + } +#ifdef CONFIG_DEBUG_DICTIONARY + printk("done (%d bytes).\n", dicthead); + printk("Jumping to dictionary...\n"); +#endif + + enterforth((xt_t)PC); + + return 0; +}
Added: openbios-devel/arch/sparc64/openbios.h =================================================================== --- openbios-devel/arch/sparc64/openbios.h (rev 0) +++ openbios-devel/arch/sparc64/openbios.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,29 @@ +/* + * Creation Date: <2004/01/15 16:14:05 samuel> + * Time-stamp: <2004/01/15 16:14:05 samuel> + * + * <openbios.h> + * + * + * + * Copyright (C) 2004 Samuel Rydh (samuel@ibrium.se) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 + * + */ + +#ifndef _H_OPENBIOS +#define _H_OPENBIOS + +int openbios(void); + +/* console.c */ +extern void cls(void); +#ifdef CONFIG_DEBUG_CONSOLE +extern int uart_init(int port, unsigned long speed); +extern void video_init(void); +#endif + +#endif /* _H_OPENBIOS */
Added: openbios-devel/arch/sparc64/openprom.h =================================================================== --- openbios-devel/arch/sparc64/openprom.h (rev 0) +++ openbios-devel/arch/sparc64/openprom.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,281 @@ +/* $Id: openprom.h,v 1.9 2001/03/16 10:22:02 davem Exp $ */ +#ifndef __SPARC64_OPENPROM_H +#define __SPARC64_OPENPROM_H + +/* openprom.h: Prom structures and defines for access to the OPENBOOT + * prom routines and data areas. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __ASSEMBLY__ +/* V0 prom device operations. */ +struct linux_dev_v0_funcs { + int (*v0_devopen)(char *device_str); + int (*v0_devclose)(int dev_desc); + int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_seekdev)(int dev_desc, long logical_offst, int from); +}; + +/* V2 and later prom device operations. */ +struct linux_dev_v2_funcs { + int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ + char * (*v2_dumb_mem_alloc)(char *va, unsigned sz); + void (*v2_dumb_mem_free)(char *va, unsigned sz); + + /* To map devices into virtual I/O space. */ + char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz); + void (*v2_dumb_munmap)(char *virta, unsigned size); + + int (*v2_dev_open)(char *devpath); + void (*v2_dev_close)(int d); + int (*v2_dev_read)(int d, char *buf, int nbytes); + int (*v2_dev_write)(int d, char *buf, int nbytes); + int (*v2_dev_seek)(int d, int hi, int lo); + + /* Never issued (multistage load support) */ + void (*v2_wheee2)(void); + void (*v2_wheee3)(void); +}; + +struct linux_mlist_v0 { + struct linux_mlist_v0 *theres_more; + unsigned start_adr; + unsigned num_bytes; +}; + +struct linux_mem_v0 { + struct linux_mlist_v0 **v0_totphys; + struct linux_mlist_v0 **v0_prommap; + struct linux_mlist_v0 **v0_available; /* What we can use */ +}; + +/* Arguments sent to the kernel from the boot prompt. */ +struct linux_arguments_v0 { + char *argv[8]; + char args[100]; + char boot_dev[2]; + int boot_dev_ctrl; + int boot_dev_unit; + int dev_partition; + char *kernel_file_name; + void *aieee1; /* XXX */ +}; + +/* V2 and up boot things. */ +struct linux_bootargs_v2 { + char **bootpath; + char **bootargs; + int *fd_stdin; + int *fd_stdout; +}; + +/* The top level PROM vector. */ +struct linux_romvec { + /* Version numbers. */ + unsigned int pv_magic_cookie; + unsigned int pv_romvers; + unsigned int pv_plugin_revision; + unsigned int pv_printrev; + + /* Version 0 memory descriptors. */ + struct linux_mem_v0 pv_v0mem; + + /* Node operations. */ + struct linux_nodeops *pv_nodeops; + + char **pv_bootstr; + struct linux_dev_v0_funcs pv_v0devops; + + char *pv_stdin; + char *pv_stdout; +#define PROMDEV_KBD 0 /* input from keyboard */ +#define PROMDEV_SCREEN 0 /* output to screen */ +#define PROMDEV_TTYA 1 /* in/out to ttya */ +#define PROMDEV_TTYB 2 /* in/out to ttyb */ + + /* Blocking getchar/putchar. NOT REENTRANT! (grr) */ + int (*pv_getchar)(void); + void (*pv_putchar)(int ch); + + /* Non-blocking variants. */ + int (*pv_nbgetchar)(void); + int (*pv_nbputchar)(int ch); + + void (*pv_putstr)(char *str, int len); + + /* Miscellany. */ + void (*pv_reboot)(char *bootstr); + void (*pv_printf)(__const__ char *fmt, ...); + void (*pv_abort)(void); + __volatile__ int *pv_ticks; + void (*pv_halt)(void); + void (**pv_synchook)(void); + + /* Evaluate a forth string, not different proto for V0 and V2->up. */ + union { + void (*v0_eval)(int len, char *str); + void (*v2_eval)(char *str); + } pv_fortheval; + + struct linux_arguments_v0 **pv_v0bootargs; + + /* Get ether address. */ + unsigned int (*pv_enaddr)(int d, char *enaddr); + + struct linux_bootargs_v2 pv_v2bootargs; + struct linux_dev_v2_funcs pv_v2devops; + + int filler[15]; + + /* This one is sun4c/sun4 only. */ + void (*pv_setctxt)(int ctxt, char *va, int pmeg); + + /* Prom version 3 Multiprocessor routines. This stuff is crazy. + * No joke. Calling these when there is only one cpu probably + * crashes the machine, have to test this. :-) + */ + + /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context + * 'thiscontext' executing at address 'prog_counter' + */ + int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr, + int thiscontext, char *prog_counter); + + /* v3_cpustop() will cause cpu 'whichcpu' to stop executing + * until a resume cpu call is made. + */ + int (*v3_cpustop)(unsigned int whichcpu); + + /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or + * resume cpu call is made. + */ + int (*v3_cpuidle)(unsigned int whichcpu); + + /* v3_cpuresume() will resume processor 'whichcpu' executing + * starting with whatever 'pc' and 'npc' were left at the + * last 'idle' or 'stop' call. + */ + int (*v3_cpuresume)(unsigned int whichcpu); +}; + +/* Routines for traversing the prom device tree. */ +struct linux_nodeops { + int (*no_nextnode)(int node); + int (*no_child)(int node); + int (*no_proplen)(int node, char *name); + int (*no_getprop)(int node, char *name, char *val); + int (*no_setprop)(int node, char *name, char *val, int len); + char * (*no_nextprop)(int node, char *name); +}; + +/* More fun PROM structures for device probing. */ +#define PROMREG_MAX 16 +#define PROMVADDR_MAX 16 +#define PROMINTR_MAX 15 + +struct linux_prom_registers { + unsigned which_io; /* hi part of physical address */ + unsigned phys_addr; /* The physical address of this register */ + int reg_size; /* How many bytes does this register take up? */ +}; + +struct linux_prom64_registers { + long phys_addr; + long reg_size; +}; + +struct linux_prom_irqs { + int pri; /* IRQ priority */ + int vector; /* This is foobar, what does it do? */ +}; + +/* Element of the "ranges" vector */ +struct linux_prom_ranges { + unsigned int ot_child_space; + unsigned int ot_child_base; /* Bus feels this */ + unsigned int ot_parent_space; + unsigned int ot_parent_base; /* CPU looks from here */ + unsigned int or_size; +}; + +struct linux_prom64_ranges { + unsigned long ot_child_base; /* Bus feels this */ + unsigned long ot_parent_base; /* CPU looks from here */ + unsigned long or_size; +}; + +/* Ranges and reg properties are a bit different for PCI. */ +struct linux_prom_pci_registers { + unsigned int phys_hi; + unsigned int phys_mid; + unsigned int phys_lo; + + unsigned int size_hi; + unsigned int size_lo; +}; + +struct linux_prom_pci_ranges { + unsigned int child_phys_hi; /* Only certain bits are encoded here. */ + unsigned int child_phys_mid; + unsigned int child_phys_lo; + + unsigned int parent_phys_hi; + unsigned int parent_phys_lo; + + unsigned int size_hi; + unsigned int size_lo; +}; + +struct linux_prom_pci_intmap { + unsigned int phys_hi; + unsigned int phys_mid; + unsigned int phys_lo; + + unsigned int interrupt; + + int cnode; + unsigned int cinterrupt; +}; + +struct linux_prom_pci_intmask { + unsigned int phys_hi; + unsigned int phys_mid; + unsigned int phys_lo; + unsigned int interrupt; +}; + +struct linux_prom_ebus_ranges { + unsigned int child_phys_hi; + unsigned int child_phys_lo; + + unsigned int parent_phys_hi; + unsigned int parent_phys_mid; + unsigned int parent_phys_lo; + + unsigned int size; +}; + +struct linux_prom_ebus_intmap { + unsigned int phys_hi; + unsigned int phys_lo; + + unsigned int interrupt; + + int cnode; + unsigned int cinterrupt; +}; + +struct linux_prom_ebus_intmask { + unsigned int phys_hi; + unsigned int phys_lo; + unsigned int interrupt; +}; +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC64_OPENPROM_H) */
Added: openbios-devel/arch/sparc64/plainboot.c =================================================================== --- openbios-devel/arch/sparc64/plainboot.c (rev 0) +++ openbios-devel/arch/sparc64/plainboot.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,22 @@ +/* tag: openbios fixed address forth starter + * + * Copyright (C) 2003 Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +#include "openbios/config.h" +#include "sys_info.h" +#include "multiboot.h" + +#define FIXED_DICTSTART 0xfffe0000 +#define FIXED_DICTEND 0xfffeffff + +void collect_multiboot_info(struct sys_info *info); +void collect_multiboot_info(struct sys_info *info) +{ + info->dict_start=(unsigned long *)FIXED_DICTSTART; + info->dict_end=(unsigned long *)FIXED_DICTEND; +} +
Added: openbios-devel/arch/sparc64/pstate.h =================================================================== --- openbios-devel/arch/sparc64/pstate.h (rev 0) +++ openbios-devel/arch/sparc64/pstate.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,90 @@ +/* $Id: pstate.h,v 1.6 1997/06/25 07:39:45 jj Exp $ */ +#ifndef _SPARC64_PSTATE_H +#define _SPARC64_PSTATE_H + +#include "const.h" + +/* The V9 PSTATE Register (with SpitFire extensions). + * + * ----------------------------------------------------------------------- + * | Resv | IG | MG | CLE | TLE | MM | RED | PEF | AM | PRIV | IE | AG | + * ----------------------------------------------------------------------- + * 63 12 11 10 9 8 7 6 5 4 3 2 1 0 + */ +#define PSTATE_IG _AC(0x0000000000000800,UL) /* Interrupt Globals. */ +#define PSTATE_MG _AC(0x0000000000000400,UL) /* MMU Globals. */ +#define PSTATE_CLE _AC(0x0000000000000200,UL) /* Current Little Endian.*/ +#define PSTATE_TLE _AC(0x0000000000000100,UL) /* Trap Little Endian. */ +#define PSTATE_MM _AC(0x00000000000000c0,UL) /* Memory Model. */ +#define PSTATE_TSO _AC(0x0000000000000000,UL) /* MM: TotalStoreOrder */ +#define PSTATE_PSO _AC(0x0000000000000040,UL) /* MM: PartialStoreOrder */ +#define PSTATE_RMO _AC(0x0000000000000080,UL) /* MM: RelaxedMemoryOrder*/ +#define PSTATE_RED _AC(0x0000000000000020,UL) /* Reset Error Debug. */ +#define PSTATE_PEF _AC(0x0000000000000010,UL) /* Floating Point Enable.*/ +#define PSTATE_AM _AC(0x0000000000000008,UL) /* Address Mask. */ +#define PSTATE_PRIV _AC(0x0000000000000004,UL) /* Privilege. */ +#define PSTATE_IE _AC(0x0000000000000002,UL) /* Interrupt Enable. */ +#define PSTATE_AG _AC(0x0000000000000001,UL) /* Alternate Globals. */ + +/* The V9 TSTATE Register (with SpitFire and Linux extensions). + * + * --------------------------------------------------------------- + * | Resv | CCR | ASI | %pil | PSTATE | Resv | CWP | + * --------------------------------------------------------------- + * 63 40 39 32 31 24 23 20 19 8 7 5 4 0 + */ +#define TSTATE_CCR _AC(0x000000ff00000000,UL) /* Condition Codes. */ +#define TSTATE_XCC _AC(0x000000f000000000,UL) /* Condition Codes. */ +#define TSTATE_XNEG _AC(0x0000008000000000,UL) /* %xcc Negative. */ +#define TSTATE_XZERO _AC(0x0000004000000000,UL) /* %xcc Zero. */ +#define TSTATE_XOVFL _AC(0x0000002000000000,UL) /* %xcc Overflow. */ +#define TSTATE_XCARRY _AC(0x0000001000000000,UL) /* %xcc Carry. */ +#define TSTATE_ICC _AC(0x0000000f00000000,UL) /* Condition Codes. */ +#define TSTATE_INEG _AC(0x0000000800000000,UL) /* %icc Negative. */ +#define TSTATE_IZERO _AC(0x0000000400000000,UL) /* %icc Zero. */ +#define TSTATE_IOVFL _AC(0x0000000200000000,UL) /* %icc Overflow. */ +#define TSTATE_ICARRY _AC(0x0000000100000000,UL) /* %icc Carry. */ +#define TSTATE_ASI _AC(0x00000000ff000000,UL) /* AddrSpace ID. */ +#define TSTATE_PIL _AC(0x0000000000f00000,UL) /* %pil (Linux traps)*/ +#define TSTATE_PSTATE _AC(0x00000000000fff00,UL) /* PSTATE. */ +#define TSTATE_IG _AC(0x0000000000080000,UL) /* Interrupt Globals.*/ +#define TSTATE_MG _AC(0x0000000000040000,UL) /* MMU Globals. */ +#define TSTATE_CLE _AC(0x0000000000020000,UL) /* CurrLittleEndian. */ +#define TSTATE_TLE _AC(0x0000000000010000,UL) /* TrapLittleEndian. */ +#define TSTATE_MM _AC(0x000000000000c000,UL) /* Memory Model. */ +#define TSTATE_TSO _AC(0x0000000000000000,UL) /* MM: TSO */ +#define TSTATE_PSO _AC(0x0000000000004000,UL) /* MM: PSO */ +#define TSTATE_RMO _AC(0x0000000000008000,UL) /* MM: RMO */ +#define TSTATE_RED _AC(0x0000000000002000,UL) /* Reset Error Debug.*/ +#define TSTATE_PEF _AC(0x0000000000001000,UL) /* FPU Enable. */ +#define TSTATE_AM _AC(0x0000000000000800,UL) /* Address Mask. */ +#define TSTATE_PRIV _AC(0x0000000000000400,UL) /* Privilege. */ +#define TSTATE_IE _AC(0x0000000000000200,UL) /* Interrupt Enable. */ +#define TSTATE_AG _AC(0x0000000000000100,UL) /* Alternate Globals.*/ +#define TSTATE_CWP _AC(0x000000000000001f,UL) /* Curr Win-Pointer. */ + +/* Floating-Point Registers State Register. + * + * -------------------------------- + * | Resv | FEF | DU | DL | + * -------------------------------- + * 63 3 2 1 0 + */ +#define FPRS_FEF _AC(0x0000000000000004,UL) /* FPU Enable. */ +#define FPRS_DU _AC(0x0000000000000002,UL) /* Dirty Upper. */ +#define FPRS_DL _AC(0x0000000000000001,UL) /* Dirty Lower. */ + +/* Version Register. + * + * ------------------------------------------------------ + * | MANUF | IMPL | MASK | Resv | MAXTL | Resv | MAXWIN | + * ------------------------------------------------------ + * 63 48 47 32 31 24 23 16 15 8 7 5 4 0 + */ +#define VERS_MANUF _AC(0xffff000000000000,UL) /* Manufacturer. */ +#define VERS_IMPL _AC(0x0000ffff00000000,UL) /* Implementation. */ +#define VERS_MASK _AC(0x00000000ff000000,UL) /* Mask Set Revision.*/ +#define VERS_MAXTL _AC(0x000000000000ff00,UL) /* Max Trap Level. */ +#define VERS_MAXWIN _AC(0x000000000000001f,UL) /* Max RegWindow Idx.*/ + +#endif /* !(_SPARC64_PSTATE_H) */
Added: openbios-devel/arch/sparc64/spitfire.h =================================================================== --- openbios-devel/arch/sparc64/spitfire.h (rev 0) +++ openbios-devel/arch/sparc64/spitfire.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,502 @@ +/* $Id: spitfire.h,v 1.18 2001/11/29 16:42:10 kanoj Exp $ + * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC64_SPITFIRE_H +#define _SPARC64_SPITFIRE_H + +#include <asm/asi.h> + +/* The following register addresses are accessible via ASI_DMMU + * and ASI_IMMU, that is there is a distinct and unique copy of + * each these registers for each TLB. + */ +#define TSB_TAG_TARGET 0x0000000000000000 /* All chips */ +#define TLB_SFSR 0x0000000000000018 /* All chips */ +#define TSB_REG 0x0000000000000028 /* All chips */ +#define TLB_TAG_ACCESS 0x0000000000000030 /* All chips */ +#define VIRT_WATCHPOINT 0x0000000000000038 /* All chips */ +#define PHYS_WATCHPOINT 0x0000000000000040 /* All chips */ +#define TSB_EXTENSION_P 0x0000000000000048 /* Ultra-III and later */ +#define TSB_EXTENSION_S 0x0000000000000050 /* Ultra-III and later, D-TLB only */ +#define TSB_EXTENSION_N 0x0000000000000058 /* Ultra-III and later */ +#define TLB_TAG_ACCESS_EXT 0x0000000000000060 /* Ultra-III+ and later */ + +/* These registers only exist as one entity, and are accessed + * via ASI_DMMU only. + */ +#define PRIMARY_CONTEXT 0x0000000000000008 +#define SECONDARY_CONTEXT 0x0000000000000010 +#define DMMU_SFAR 0x0000000000000020 +#define VIRT_WATCHPOINT 0x0000000000000038 +#define PHYS_WATCHPOINT 0x0000000000000040 + +#define SPITFIRE_HIGHEST_LOCKED_TLBENT (64 - 1) + +#ifndef __ASSEMBLY__ + +enum ultra_tlb_layout { + spitfire = 0, + cheetah = 1, + cheetah_plus = 2, +}; + +extern enum ultra_tlb_layout tlb_type; + +#define CHEETAH_HIGHEST_LOCKED_TLBENT (16 - 1) + +#define L1DCACHE_SIZE 0x4000 + +#define sparc64_highest_locked_tlbent() \ + (tlb_type == spitfire ? \ + SPITFIRE_HIGHEST_LOCKED_TLBENT : \ + CHEETAH_HIGHEST_LOCKED_TLBENT) + +static __inline__ unsigned long spitfire_get_isfsr(void) +{ + unsigned long ret; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (ret) + : "r" (TLB_SFSR), "i" (ASI_IMMU)); + return ret; +} + +static __inline__ unsigned long spitfire_get_dsfsr(void) +{ + unsigned long ret; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (ret) + : "r" (TLB_SFSR), "i" (ASI_DMMU)); + return ret; +} + +static __inline__ unsigned long spitfire_get_sfar(void) +{ + unsigned long ret; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (ret) + : "r" (DMMU_SFAR), "i" (ASI_DMMU)); + return ret; +} + +static __inline__ void spitfire_put_isfsr(unsigned long sfsr) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (sfsr), "r" (TLB_SFSR), "i" (ASI_IMMU)); +} + +static __inline__ void spitfire_put_dsfsr(unsigned long sfsr) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (sfsr), "r" (TLB_SFSR), "i" (ASI_DMMU)); +} + +static __inline__ unsigned long spitfire_get_primary_context(void) +{ + unsigned long ctx; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (ctx) + : "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); + return ctx; +} + +static __inline__ void spitfire_set_primary_context(unsigned long ctx) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (ctx & 0x3ff), + "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); + __asm__ __volatile__ ("membar #Sync" : : : "memory"); +} + +static __inline__ unsigned long spitfire_get_secondary_context(void) +{ + unsigned long ctx; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (ctx) + : "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU)); + return ctx; +} + +static __inline__ void spitfire_set_secondary_context(unsigned long ctx) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (ctx & 0x3ff), + "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU)); + __asm__ __volatile__ ("membar #Sync" : : : "memory"); +} + +/* The data cache is write through, so this just invalidates the + * specified line. + */ +static __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG)); + __asm__ __volatile__ ("membar #Sync" : : : "memory"); +} + +/* The instruction cache lines are flushed with this, but note that + * this does not flush the pipeline. It is possible for a line to + * get flushed but stale instructions to still be in the pipeline, + * a flush instruction (to any address) is sufficient to handle + * this issue after the line is invalidated. + */ +static __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (tag), "r" (addr), "i" (ASI_IC_TAG)); +} + +static __inline__ unsigned long spitfire_get_dtlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (data) + : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS)); + + /* Clear TTE diag bits. */ + data &= ~0x0003fe0000000000UL; + + return data; +} + +static __inline__ unsigned long spitfire_get_dtlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" (entry << 3), "i" (ASI_DTLB_TAG_READ)); + return tag; +} + +static __inline__ void spitfire_put_dtlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), "r" (entry << 3), + "i" (ASI_DTLB_DATA_ACCESS)); +} + +static __inline__ unsigned long spitfire_get_itlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (data) + : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS)); + + /* Clear TTE diag bits. */ + data &= ~0x0003fe0000000000UL; + + return data; +} + +static __inline__ unsigned long spitfire_get_itlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" (entry << 3), "i" (ASI_ITLB_TAG_READ)); + return tag; +} + +static __inline__ void spitfire_put_itlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), "r" (entry << 3), + "i" (ASI_ITLB_DATA_ACCESS)); +} + +/* Spitfire hardware assisted TLB flushes. */ + +/* Context level flushes. */ +static __inline__ void spitfire_flush_dtlb_primary_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x40), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_primary_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x40), "i" (ASI_IMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_dtlb_secondary_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x50), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_secondary_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x50), "i" (ASI_IMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_dtlb_nucleus_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x60), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_nucleus_context(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x60), "i" (ASI_IMMU_DEMAP)); +} + +/* Page level flushes. */ +static __inline__ void spitfire_flush_dtlb_primary_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_primary_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page), "i" (ASI_IMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_dtlb_secondary_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page | 0x10), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_secondary_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page | 0x10), "i" (ASI_IMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP)); +} + +/* Cheetah has "all non-locked" tlb flushes. */ +static __inline__ void cheetah_flush_dtlb_all(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x80), "i" (ASI_DMMU_DEMAP)); +} + +static __inline__ void cheetah_flush_itlb_all(void) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (0x80), "i" (ASI_IMMU_DEMAP)); +} + +/* Cheetah has a 4-tlb layout so direct access is a bit different. + * The first two TLBs are fully assosciative, hold 16 entries, and are + * used only for locked and >8K sized translations. One exists for + * data accesses and one for instruction accesses. + * + * The third TLB is for data accesses to 8K non-locked translations, is + * 2 way assosciative, and holds 512 entries. The fourth TLB is for + * instruction accesses to 8K non-locked translations, is 2 way + * assosciative, and holds 128 entries. + * + * Cheetah has some bug where bogus data can be returned from + * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes + * the problem for me. -DaveM + */ +static __inline__ unsigned long cheetah_get_ldtlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" + "ldxa [%1] %2, %0" + : "=r" (data) + : "r" ((0 << 16) | (entry << 3)), + "i" (ASI_DTLB_DATA_ACCESS)); + + return data; +} + +static __inline__ unsigned long cheetah_get_litlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" + "ldxa [%1] %2, %0" + : "=r" (data) + : "r" ((0 << 16) | (entry << 3)), + "i" (ASI_ITLB_DATA_ACCESS)); + + return data; +} + +static __inline__ unsigned long cheetah_get_ldtlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" ((0 << 16) | (entry << 3)), + "i" (ASI_DTLB_TAG_READ)); + + return tag; +} + +static __inline__ unsigned long cheetah_get_litlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" ((0 << 16) | (entry << 3)), + "i" (ASI_ITLB_TAG_READ)); + + return tag; +} + +static __inline__ void cheetah_put_ldtlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), + "r" ((0 << 16) | (entry << 3)), + "i" (ASI_DTLB_DATA_ACCESS)); +} + +static __inline__ void cheetah_put_litlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), + "r" ((0 << 16) | (entry << 3)), + "i" (ASI_ITLB_DATA_ACCESS)); +} + +static __inline__ unsigned long cheetah_get_dtlb_data(int entry, int tlb) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" + "ldxa [%1] %2, %0" + : "=r" (data) + : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS)); + + return data; +} + +static __inline__ unsigned long cheetah_get_dtlb_tag(int entry, int tlb) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ)); + return tag; +} + +static __inline__ void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), + "r" ((tlb << 16) | (entry << 3)), + "i" (ASI_DTLB_DATA_ACCESS)); +} + +static __inline__ unsigned long cheetah_get_itlb_data(int entry) +{ + unsigned long data; + + __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" + "ldxa [%1] %2, %0" + : "=r" (data) + : "r" ((2 << 16) | (entry << 3)), + "i" (ASI_ITLB_DATA_ACCESS)); + + return data; +} + +static __inline__ unsigned long cheetah_get_itlb_tag(int entry) +{ + unsigned long tag; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=r" (tag) + : "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ)); + return tag; +} + +static __inline__ void cheetah_put_itlb_data(int entry, unsigned long data) +{ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : /* No outputs */ + : "r" (data), "r" ((2 << 16) | (entry << 3)), + "i" (ASI_ITLB_DATA_ACCESS)); +} + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_SPARC64_SPITFIRE_H) */
Added: openbios-devel/arch/sparc64/switch.S =================================================================== --- openbios-devel/arch/sparc64/switch.S (rev 0) +++ openbios-devel/arch/sparc64/switch.S 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,118 @@ +#include "pstate.h" +#include "asi.h" +#define ASI_BP ASI_M_BYPASS +#define REGWIN_SZ 0x40 + + .globl __switch_context, __switch_context_nosave, __exit_context, halt + + .text + .align 4 + .register %g2, #scratch + .register %g3, #scratch + .register %g6, #scratch + .register %g7, #scratch + +/* + * Switch execution context + * This saves registers in the stack, then + * switches the stack, and restores everything from the new stack. + * This function takes no argument. New stack pointer is + * taken from global variable __context, and old stack pointer + * is also saved to __context. This way we can just jump to + * this routine to get back to the original context. + */ + +/* XXX: totally bogus for sparc, need to save and restore all windows */ +__switch_context: + /* Save everything in current stack */ + setx __context, %g2, %g1 + stx %g3, [%g1 + 24] + stx %g4, [%g1 + 32] + stx %g5, [%g1 + 40] + stx %g6, [%g1 + 48] + stx %g7, [%g1 + 56] + + stx %o0, [%g1 + 64] + stx %o1, [%g1 + 72] + stx %o2, [%g1 + 80] + stx %o3, [%g1 + 88] + stx %o4, [%g1 + 96] + stx %o5, [%g1 + 104] + stx %o6, [%g1 + 112] + stx %o7, [%g1 + 120] + + stx %l0, [%g1 + 128] + stx %l1, [%g1 + 136] + stx %l2, [%g1 + 144] + stx %l3, [%g1 + 152] + stx %l4, [%g1 + 160] + stx %l5, [%g1 + 168] + stx %l6, [%g1 + 176] + stx %l7, [%g1 + 184] + + stx %i0, [%g1 + 192] + stx %i1, [%g1 + 200] + stx %i2, [%g1 + 208] + stx %i3, [%g1 + 216] + stx %i4, [%g1 + 224] + stx %i5, [%g1 + 232] + stx %i6, [%g1 + 240] + stx %i7, [%g1 + 248] + +__switch_context_nosave: + /* Interrupts are not allowed... */ + + /* Load all registers + */ + setx __context, %g2, %g1 + ldx [%g1], %g1 + ldx [%g1 + 16], %g2 + ldx [%g1 + 24], %g3 + ldx [%g1 + 32], %g4 + ldx [%g1 + 40], %g5 + ldx [%g1 + 48], %g6 + ldx [%g1 + 56], %g7 + + ldx [%g1 + 64], %o0 + ldx [%g1 + 72], %o1 + ldx [%g1 + 80], %o2 + ldx [%g1 + 88], %o3 + ldx [%g1 + 96], %o4 + ldx [%g1 + 104], %o5 + ldx [%g1 + 112], %o6 + ldx [%g1 + 120], %o7 + + ldx [%g1 + 128], %l0 + ldx [%g1 + 136], %l1 + ldx [%g1 + 144], %l2 + ldx [%g1 + 152], %l3 + ldx [%g1 + 160], %l4 + ldx [%g1 + 168], %l5 + ldx [%g1 + 176], %l6 + ldx [%g1 + 184], %l7 + + ldx [%g1 + 192], %i0 + ldx [%g1 + 200], %i1 + ldx [%g1 + 208], %i2 + ldx [%g1 + 216], %i3 + ldx [%g1 + 224], %i4 + ldx [%g1 + 232], %i5 + ldx [%g1 + 240], %i6 + ldx [%g1 + 248], %i7 + + ldx [%g1 + 256], %g1 + /* Finally, load new %pc */ + jmp %g1 + clr %g1 + +__exit_context: + /* Get back to the original context */ + call __switch_context + nop + + /* We get here if the other context attempt to switch to this + * dead context. This should not happen. */ + +halt: + b halt + nop
Added: openbios-devel/arch/sparc64/sys_info.c =================================================================== --- openbios-devel/arch/sparc64/sys_info.c (rev 0) +++ openbios-devel/arch/sparc64/sys_info.c 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,59 @@ +#include "openbios/config.h" +#include "openbios/kernel.h" +#include "elf_boot.h" +#include "sys_info.h" +#include "context.h" + +#define printf printk +#ifdef CONFIG_DEBUG_BOOT +#define debug printk +#else +#define debug(x...) +#endif + +unsigned long qemu_mem_size; +unsigned long va_shift; + +void collect_multiboot_info(struct sys_info *); + +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; + //info->boot_data = boot_ctx->ebx; + 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); +#ifdef CONFIG_LINUXBIOS + collect_linuxbios_info(info); +#endif +#ifdef CONFIG_IMAGE_ELF_MULTIBOOT + collect_multiboot_info(info); +#endif + + if (!info->memrange) { + info->n_memranges = 1; + info->memrange = malloc(1 * sizeof(struct memrange)); + info->memrange[0].base = 0; + info->memrange[0].size = qemu_mem_size; + } + + debug("\n"); + mmap=info->memrange; + for (i = 0; i < info->n_memranges; i++) { + debug("%08lx-", (long)mmap[i].base); + debug("%08lx\n", (long)mmap[i].base + (long)mmap[i].size); + total += mmap[i].size; + } + debug("RAM %ld MB\n", (long)total >> 20); +}
Added: openbios-devel/arch/sparc64/tree.fs =================================================================== --- openbios-devel/arch/sparc64/tree.fs (rev 0) +++ openbios-devel/arch/sparc64/tree.fs 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,29 @@ + +" /" find-device + 2 encode-int " #address-cells" property + 1 encode-int " #size-cells" property + + : encode-unit encode-unit-sbus ; + : decode-unit decode-unit-sbus ; + +new-device + " memory" device-name + external + : open true ; + : close ; + \ claim ( phys size align -- base ) + \ release ( phys size -- ) +finish-device + +new-device + " virtual-memory" device-name + external + : open true ; + : close ; + \ claim ( phys size align -- base ) + \ release ( phys size -- ) +finish-device + +" /options" find-device + " disk" encode-string " boot-from" property +
Added: openbios-devel/arch/sparc64/ttable.h =================================================================== --- openbios-devel/arch/sparc64/ttable.h (rev 0) +++ openbios-devel/arch/sparc64/ttable.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,407 @@ +/* $Id: ttable.h,v 1.18 2002/02/09 19:49:32 davem Exp $ */ +#ifndef _SPARC64_TTABLE_H +#define _SPARC64_TTABLE_H + +//#include <linux/config.h> +//#include <asm/utrap.h> + +//#ifdef __ASSEMBLY__ +//#include <asm/thread_info.h> +//#endif + +//#define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop; + +/* We need a "cleaned" instruction... */ +#define CLEAN_WINDOW \ + rdpr %cleanwin, %l0; add %l0, 1, %l0; \ + wrpr %l0, 0x0, %cleanwin; \ + clr %o0; clr %o1; clr %o2; clr %o3; \ + clr %o4; clr %o5; clr %o6; clr %o7; \ + clr %l0; clr %l1; clr %l2; clr %l3; \ + clr %l4; clr %l5; clr %l6; clr %l7; \ + retry; \ + nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; + +#define TRAP(routine) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etrap; \ +109: or %g7, %lo(109b), %g7; \ + call routine; \ + add %sp, PTREGS_OFF, %o0; \ + ba,pt %xcc, rtrap; \ + clr %l6; \ + nop; + +#define TRAP_7INSNS(routine) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etrap; \ +109: or %g7, %lo(109b), %g7; \ + call routine; \ + add %sp, PTREGS_OFF, %o0; \ + ba,pt %xcc, rtrap; \ + clr %l6; + +#define TRAP_SAVEFPU(routine) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, do_fptrap; \ +109: or %g7, %lo(109b), %g7; \ + call routine; \ + add %sp, PTREGS_OFF, %o0; \ + ba,pt %xcc, rtrap; \ + clr %l6; \ + nop; + +#define TRAP_NOSAVE(routine) \ + ba,pt %xcc, routine; \ + nop; \ + nop; nop; nop; nop; nop; nop; + +#define TRAP_NOSAVE_7INSNS(routine) \ + ba,pt %xcc, routine; \ + nop; \ + nop; nop; nop; nop; nop; + +#define TRAPTL1(routine) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etraptl1; \ +109: or %g7, %lo(109b), %g7; \ + call routine; \ + add %sp, PTREGS_OFF, %o0; \ + ba,pt %xcc, rtrap; \ + clr %l6; \ + nop; + +#define TRAP_ARG(routine, arg) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etrap; \ +109: or %g7, %lo(109b), %g7; \ + add %sp, PTREGS_OFF, %o0; \ + call routine; \ + mov arg, %o1; \ + ba,pt %xcc, rtrap; \ + clr %l6; + +#define TRAPTL1_ARG(routine, arg) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etraptl1; \ +109: or %g7, %lo(109b), %g7; \ + add %sp, PTREGS_OFF, %o0; \ + call routine; \ + mov arg, %o1; \ + ba,pt %xcc, rtrap; \ + clr %l6; + +#define SYSCALL_TRAP(routine, systbl) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, scetrap; \ +109: or %g7, %lo(109b), %g7; \ + sethi %hi(systbl), %l7; \ + ba,pt %xcc, routine; \ + or %l7, %lo(systbl), %l7; \ + nop; nop; + +#define INDIRECT_SOLARIS_SYSCALL(num) \ + sethi %hi(109f), %g7; \ + ba,pt %xcc, etrap; \ +109: or %g7, %lo(109b), %g7; \ + ba,pt %xcc, tl0_solaris + 0xc; \ + mov num, %g1; \ + nop;nop;nop; + +#define TRAP_UTRAP(handler,lvl) \ + ldx [%g6 + TI_UTRAPS], %g1; \ + sethi %hi(109f), %g7; \ + brz,pn %g1, utrap; \ + or %g7, %lo(109f), %g7; \ + ba,pt %xcc, utrap; \ +109: ldx [%g1 + handler*8], %g1; \ + ba,pt %xcc, utrap_ill; \ + mov lvl, %o1; + +#ifdef CONFIG_SUNOS_EMUL +#define SUNOS_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sunos_sys_table) +#else +#define SUNOS_SYSCALL_TRAP TRAP(sunos_syscall) +#endif +#ifdef CONFIG_COMPAT +#define LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32) +#else +#define LINUX_32BIT_SYSCALL_TRAP BTRAP(0x110) +#endif +#define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64) +#define GETCC_TRAP TRAP(getcc) +#define SETCC_TRAP TRAP(setcc) +#ifdef CONFIG_SOLARIS_EMUL +#define SOLARIS_SYSCALL_TRAP TRAP(solaris_sparc_syscall) +#else +#define SOLARIS_SYSCALL_TRAP TRAP(solaris_syscall) +#endif +/* FIXME: Write these actually */ +#define NETBSD_SYSCALL_TRAP TRAP(netbsd_syscall) +#define BREAKPOINT_TRAP TRAP(breakpoint_trap) + +#define TRAP_IRQ(routine, level) \ + rdpr %pil, %g2; \ + wrpr %g0, 15, %pil; \ + b,pt %xcc, etrap_irq; \ + rd %pc, %g7; \ + mov level, %o0; \ + call routine; \ + add %sp, PTREGS_OFF, %o1; \ + ba,a,pt %xcc, rtrap_irq; + +#define TICK_SMP_IRQ \ + rdpr %pil, %g2; \ + wrpr %g0, 15, %pil; \ + sethi %hi(109f), %g7; \ + b,pt %xcc, etrap_irq; \ +109: or %g7, %lo(109b), %g7; \ + call smp_percpu_timer_interrupt; \ + add %sp, PTREGS_OFF, %o0; \ + ba,a,pt %xcc, rtrap_irq; + +#define TRAP_IVEC TRAP_NOSAVE(do_ivec) + +#define BTRAP(lvl) TRAP_ARG(bad_trap, lvl) + +#define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl) + +#define FLUSH_WINDOW_TRAP \ + ba,pt %xcc, etrap; \ + rd %pc, %g7; \ + flushw; \ + ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1; \ + add %l1, 4, %l2; \ + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]; \ + ba,pt %xcc, rtrap_clr_l6; \ + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]; + +#ifdef CONFIG_KPROBES +#define KPROBES_TRAP(lvl) TRAP_IRQ(kprobe_trap, lvl) +#else +#define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl) +#endif + +/* Before touching these macros, you owe it to yourself to go and + * see how arch/sparc64/kernel/winfixup.S works... -DaveM + * + * For the user cases we used to use the %asi register, but + * it turns out that the "wr xxx, %asi" costs ~5 cycles, so + * now we use immediate ASI loads and stores instead. Kudos + * to Greg Onufer for pointing out this performance anomaly. + * + * Further note that we cannot use the g2, g4, g5, and g7 alternate + * globals in the spill routines, check out the save instruction in + * arch/sparc64/kernel/etrap.S to see what I mean about g2, and + * g4/g5 are the globals which are preserved by etrap processing + * for the caller of it. The g7 register is the return pc for + * etrap. Finally, g6 is the current thread register so we cannot + * us it in the spill handlers either. Most of these rules do not + * apply to fill processing, only g6 is not usable. + */ + +/* Normal kernel spill */ +#define SPILL_0_NORMAL \ + stx %l0, [%sp + STACK_BIAS + 0x00]; \ + stx %l1, [%sp + STACK_BIAS + 0x08]; \ + stx %l2, [%sp + STACK_BIAS + 0x10]; \ + stx %l3, [%sp + STACK_BIAS + 0x18]; \ + stx %l4, [%sp + STACK_BIAS + 0x20]; \ + stx %l5, [%sp + STACK_BIAS + 0x28]; \ + stx %l6, [%sp + STACK_BIAS + 0x30]; \ + stx %l7, [%sp + STACK_BIAS + 0x38]; \ + stx %i0, [%sp + STACK_BIAS + 0x40]; \ + stx %i1, [%sp + STACK_BIAS + 0x48]; \ + stx %i2, [%sp + STACK_BIAS + 0x50]; \ + stx %i3, [%sp + STACK_BIAS + 0x58]; \ + stx %i4, [%sp + STACK_BIAS + 0x60]; \ + stx %i5, [%sp + STACK_BIAS + 0x68]; \ + stx %i6, [%sp + STACK_BIAS + 0x70]; \ + stx %i7, [%sp + STACK_BIAS + 0x78]; \ + saved; retry; nop; nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; nop; nop; nop; nop; + +/* Normal 64bit spill */ +#define SPILL_1_GENERIC(ASI) \ + add %sp, STACK_BIAS + 0x00, %g1; \ + stxa %l0, [%g1 + %g0] ASI; \ + mov 0x08, %g3; \ + stxa %l1, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %l2, [%g1 + %g0] ASI; \ + stxa %l3, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %l4, [%g1 + %g0] ASI; \ + stxa %l5, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %l6, [%g1 + %g0] ASI; \ + stxa %l7, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %i0, [%g1 + %g0] ASI; \ + stxa %i1, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %i2, [%g1 + %g0] ASI; \ + stxa %i3, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %i4, [%g1 + %g0] ASI; \ + stxa %i5, [%g1 + %g3] ASI; \ + add %g1, 0x10, %g1; \ + stxa %i6, [%g1 + %g0] ASI; \ + stxa %i7, [%g1 + %g3] ASI; \ + saved; \ + retry; nop; nop; \ + b,a,pt %xcc, spill_fixup_dax; \ + b,a,pt %xcc, spill_fixup_mna; \ + b,a,pt %xcc, spill_fixup; + +/* Normal 32bit spill */ +#define SPILL_2_GENERIC(ASI) \ + srl %sp, 0, %sp; \ + stwa %l0, [%sp + %g0] ASI; \ + mov 0x04, %g3; \ + stwa %l1, [%sp + %g3] ASI; \ + add %sp, 0x08, %g1; \ + stwa %l2, [%g1 + %g0] ASI; \ + stwa %l3, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %l4, [%g1 + %g0] ASI; \ + stwa %l5, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %l6, [%g1 + %g0] ASI; \ + stwa %l7, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %i0, [%g1 + %g0] ASI; \ + stwa %i1, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %i2, [%g1 + %g0] ASI; \ + stwa %i3, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %i4, [%g1 + %g0] ASI; \ + stwa %i5, [%g1 + %g3] ASI; \ + add %g1, 0x08, %g1; \ + stwa %i6, [%g1 + %g0] ASI; \ + stwa %i7, [%g1 + %g3] ASI; \ + saved; \ + retry; nop; nop; \ + b,a,pt %xcc, spill_fixup_dax; \ + b,a,pt %xcc, spill_fixup_mna; \ + b,a,pt %xcc, spill_fixup; + +#define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP) +#define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP) +#define SPILL_3_NORMAL SPILL_0_NORMAL +#define SPILL_4_NORMAL SPILL_0_NORMAL +#define SPILL_5_NORMAL SPILL_0_NORMAL +#define SPILL_6_NORMAL SPILL_0_NORMAL +#define SPILL_7_NORMAL SPILL_0_NORMAL + +#define SPILL_0_OTHER SPILL_0_NORMAL +#define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS) +#define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS) +#define SPILL_3_OTHER SPILL_3_NORMAL +#define SPILL_4_OTHER SPILL_4_NORMAL +#define SPILL_5_OTHER SPILL_5_NORMAL +#define SPILL_6_OTHER SPILL_6_NORMAL +#define SPILL_7_OTHER SPILL_7_NORMAL + +/* Normal kernel fill */ +#define FILL_0_NORMAL \ + ldx [%sp + STACK_BIAS + 0x00], %l0; \ + ldx [%sp + STACK_BIAS + 0x08], %l1; \ + ldx [%sp + STACK_BIAS + 0x10], %l2; \ + ldx [%sp + STACK_BIAS + 0x18], %l3; \ + ldx [%sp + STACK_BIAS + 0x20], %l4; \ + ldx [%sp + STACK_BIAS + 0x28], %l5; \ + ldx [%sp + STACK_BIAS + 0x30], %l6; \ + ldx [%sp + STACK_BIAS + 0x38], %l7; \ + ldx [%sp + STACK_BIAS + 0x40], %i0; \ + ldx [%sp + STACK_BIAS + 0x48], %i1; \ + ldx [%sp + STACK_BIAS + 0x50], %i2; \ + ldx [%sp + STACK_BIAS + 0x58], %i3; \ + ldx [%sp + STACK_BIAS + 0x60], %i4; \ + ldx [%sp + STACK_BIAS + 0x68], %i5; \ + ldx [%sp + STACK_BIAS + 0x70], %i6; \ + ldx [%sp + STACK_BIAS + 0x78], %i7; \ + restored; retry; nop; nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; nop; nop; nop; nop; + +/* Normal 64bit fill */ +#define FILL_1_GENERIC(ASI) \ + add %sp, STACK_BIAS + 0x00, %g1; \ + ldxa [%g1 + %g0] ASI, %l0; \ + mov 0x08, %g2; \ + mov 0x10, %g3; \ + ldxa [%g1 + %g2] ASI, %l1; \ + mov 0x18, %g5; \ + ldxa [%g1 + %g3] ASI, %l2; \ + ldxa [%g1 + %g5] ASI, %l3; \ + add %g1, 0x20, %g1; \ + ldxa [%g1 + %g0] ASI, %l4; \ + ldxa [%g1 + %g2] ASI, %l5; \ + ldxa [%g1 + %g3] ASI, %l6; \ + ldxa [%g1 + %g5] ASI, %l7; \ + add %g1, 0x20, %g1; \ + ldxa [%g1 + %g0] ASI, %i0; \ + ldxa [%g1 + %g2] ASI, %i1; \ + ldxa [%g1 + %g3] ASI, %i2; \ + ldxa [%g1 + %g5] ASI, %i3; \ + add %g1, 0x20, %g1; \ + ldxa [%g1 + %g0] ASI, %i4; \ + ldxa [%g1 + %g2] ASI, %i5; \ + ldxa [%g1 + %g3] ASI, %i6; \ + ldxa [%g1 + %g5] ASI, %i7; \ + restored; \ + retry; nop; nop; nop; nop; \ + b,a,pt %xcc, fill_fixup_dax; \ + b,a,pt %xcc, fill_fixup_mna; \ + b,a,pt %xcc, fill_fixup; + +/* Normal 32bit fill */ +#define FILL_2_GENERIC(ASI) \ + srl %sp, 0, %sp; \ + lduwa [%sp + %g0] ASI, %l0; \ + mov 0x04, %g2; \ + mov 0x08, %g3; \ + lduwa [%sp + %g2] ASI, %l1; \ + mov 0x0c, %g5; \ + lduwa [%sp + %g3] ASI, %l2; \ + lduwa [%sp + %g5] ASI, %l3; \ + add %sp, 0x10, %g1; \ + lduwa [%g1 + %g0] ASI, %l4; \ + lduwa [%g1 + %g2] ASI, %l5; \ + lduwa [%g1 + %g3] ASI, %l6; \ + lduwa [%g1 + %g5] ASI, %l7; \ + add %g1, 0x10, %g1; \ + lduwa [%g1 + %g0] ASI, %i0; \ + lduwa [%g1 + %g2] ASI, %i1; \ + lduwa [%g1 + %g3] ASI, %i2; \ + lduwa [%g1 + %g5] ASI, %i3; \ + add %g1, 0x10, %g1; \ + lduwa [%g1 + %g0] ASI, %i4; \ + lduwa [%g1 + %g2] ASI, %i5; \ + lduwa [%g1 + %g3] ASI, %i6; \ + lduwa [%g1 + %g5] ASI, %i7; \ + restored; \ + retry; nop; nop; nop; nop; \ + b,a,pt %xcc, fill_fixup_dax; \ + b,a,pt %xcc, fill_fixup_mna; \ + b,a,pt %xcc, fill_fixup; + +#define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP) +#define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP) +#define FILL_3_NORMAL FILL_0_NORMAL +#define FILL_4_NORMAL FILL_0_NORMAL +#define FILL_5_NORMAL FILL_0_NORMAL +#define FILL_6_NORMAL FILL_0_NORMAL +#define FILL_7_NORMAL FILL_0_NORMAL + +#define FILL_0_OTHER FILL_0_NORMAL +#define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS) +#define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS) +#define FILL_3_OTHER FILL_3_NORMAL +#define FILL_4_OTHER FILL_4_NORMAL +#define FILL_5_OTHER FILL_5_NORMAL +#define FILL_6_OTHER FILL_6_NORMAL +#define FILL_7_OTHER FILL_7_NORMAL + +#endif /* !(_SPARC64_TTABLE_H) */
Added: openbios-devel/arch/sparc64/vectors.S =================================================================== --- openbios-devel/arch/sparc64/vectors.S (rev 0) +++ openbios-devel/arch/sparc64/vectors.S 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,322 @@ +/* + * <vectors.S> + * + * Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions. + * + * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License V2 + * as published by the Free Software Foundation + */ + +#define __ASSEMBLY__ +#include "pstate.h" +#include "asi.h" +#include "ttable.h" +#define ASI_BP ASI_PHYS_BYPASS_EC_E +#define SER_ADDR 0x1fe020003f8 + + .section ".text.vectors", "ax" + .align 16384 +/* Sparc64 trap table */ + .globl trap_table, __divide_error + .register %g2, #scratch + .register %g3, #scratch + .register %g6, #scratch + .register %g7, #scratch +trap_table: +#undef TRAP_IRQ +#define TRAP_IRQ(routine, level) \ + ba routine; nop; nop; nop; nop; nop; nop; nop; +#undef BTRAP +#define BTRAP(lvl) \ + ba bug; mov lvl, %g1; nop; nop; nop; nop; nop; nop; +#undef BTRAPTL1 +#define BTRAPTL1(lvl) BTRAP(lvl) +#define BTRAPS(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3) BTRAP(x+4) BTRAP(x+5) BTRAP(x+6) BTRAP(x+7) + +#define STACK_BIAS 2047 + .globl sparc64_ttable_tl0, sparc64_ttable_tl1 +sparc64_ttable_tl0: + ba entry; nop; nop; nop; nop; nop; nop; nop; + BTRAP(0x01) BTRAP(0x02) BTRAP(0x03) BTRAP(0x04) BTRAP(0x05) BTRAP(0x06) BTRAP(0x07) + BTRAPS(0x08) + BTRAPS(0x10) BTRAPS(0x18) + BTRAP(0x20) BTRAP(0x21) BTRAP(0x22) BTRAP(0x23) + CLEAN_WINDOW ! 24-27 + BTRAPS(0x28) + BTRAPS(0x30) BTRAPS(0x38) +#if 0 + BTRAP(0x40) BTRAP(0x41) BTRAP(0x42) BTRAP(0x43) +tl0_irq4: TRAP_IRQ(handler_irq, 4) +tl0_irq5: TRAP_IRQ(handler_irq, 5) TRAP_IRQ(handler_irq, 6) +tl0_irq7: TRAP_IRQ(handler_irq, 7) TRAP_IRQ(handler_irq, 8) +tl0_irq9: TRAP_IRQ(handler_irq, 9) TRAP_IRQ(handler_irq, 10) +tl0_irq11: TRAP_IRQ(handler_irq, 11) TRAP_IRQ(handler_irq, 12) +tl0_irq13: TRAP_IRQ(handler_irq, 13) +tl0_irq14: TRAP_IRQ(handler_irq, 14) +tl0_irq15: TRAP_IRQ(handler_irq, 15) +#else + BTRAPS(0x40) BTRAPS(0x48) +#endif + BTRAPS(0x50) BTRAPS(0x58) + BTRAPS(0x60) BTRAPS(0x68) + BTRAPS(0x70) BTRAPS(0x78) +tl0_s0n: SPILL_0_NORMAL +tl0_s1n: SPILL_1_NORMAL +tl0_s2n: SPILL_2_NORMAL +tl0_s3n: SPILL_3_NORMAL +tl0_s4n: SPILL_4_NORMAL +tl0_s5n: SPILL_5_NORMAL +tl0_s6n: SPILL_6_NORMAL +tl0_s7n: SPILL_7_NORMAL +tl0_s0o: SPILL_0_OTHER +tl0_s1o: SPILL_1_OTHER +tl0_s2o: SPILL_2_OTHER +tl0_s3o: SPILL_3_OTHER +tl0_s4o: SPILL_4_OTHER +tl0_s5o: SPILL_5_OTHER +tl0_s6o: SPILL_6_OTHER +tl0_s7o: SPILL_7_OTHER +tl0_f0n: FILL_0_NORMAL +tl0_f1n: FILL_1_NORMAL +tl0_f2n: FILL_2_NORMAL +tl0_f3n: FILL_3_NORMAL +tl0_f4n: FILL_4_NORMAL +tl0_f5n: FILL_5_NORMAL +tl0_f6n: FILL_6_NORMAL +tl0_f7n: FILL_7_NORMAL +tl0_f0o: FILL_0_OTHER +tl0_f1o: FILL_1_OTHER +tl0_f2o: FILL_2_OTHER +tl0_f3o: FILL_3_OTHER +tl0_f4o: FILL_4_OTHER +tl0_f5o: FILL_5_OTHER +tl0_f6o: FILL_6_OTHER +tl0_f7o: FILL_7_OTHER +tl0_resv100: BTRAPS(0x100) BTRAPS(0x108) +tl0_resv110: BTRAPS(0x110) BTRAPS(0x118) +tl0_resv120: BTRAPS(0x120) BTRAPS(0x128) +tl0_resv130: BTRAPS(0x130) BTRAPS(0x138) +tl0_resv140: BTRAPS(0x140) BTRAPS(0x148) +tl0_resv150: BTRAPS(0x150) BTRAPS(0x158) +tl0_resv160: BTRAPS(0x160) BTRAPS(0x168) +tl0_resv170: BTRAPS(0x170) BTRAPS(0x178) +tl0_resv180: BTRAPS(0x180) BTRAPS(0x188) +tl0_resv190: BTRAPS(0x190) BTRAPS(0x198) +tl0_resv1a0: BTRAPS(0x1a0) BTRAPS(0x1a8) +tl0_resv1b0: BTRAPS(0x1b0) BTRAPS(0x1b8) +tl0_resv1c0: BTRAPS(0x1c0) BTRAPS(0x1c8) +tl0_resv1d0: BTRAPS(0x1d0) BTRAPS(0x1d8) +tl0_resv1e0: BTRAPS(0x1e0) BTRAPS(0x1e8) +tl0_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8) + +#undef BTRAPS +#define BTRAPS(x) BTRAPTL1(x) BTRAPTL1(x+1) BTRAPTL1(x+2) BTRAPTL1(x+3) BTRAPTL1(x+4) BTRAPTL1(x+5) BTRAPTL1(x+6) BTRAPTL1(x+7) + +sparc64_ttable_tl1: + BTRAPS(0x00) BTRAPS(0x08) + BTRAPS(0x10) BTRAPS(0x18) + BTRAPTL1(0x20) BTRAPTL1(0x21) BTRAPTL1(0x22) BTRAPTL1(0x23) + CLEAN_WINDOW ! 24-27 + BTRAPS(0x28) + BTRAPS(0x30) BTRAPS(0x38) +#if 0 + BTRAPTL1(0x40) BTRAPTL1(0x41) BTRAPTL1(0x42) BTRAPTL1(0x43) +tl1_irq4: TRAP_IRQ(handler_irq, 4) +tl1_irq5: TRAP_IRQ(handler_irq, 5) TRAP_IRQ(handler_irq, 6) +tl1_irq7: TRAP_IRQ(handler_irq, 7) TRAP_IRQ(handler_irq, 8) +tl1_irq9: TRAP_IRQ(handler_irq, 9) TRAP_IRQ(handler_irq, 10) +tl1_irq11: TRAP_IRQ(handler_irq, 11) TRAP_IRQ(handler_irq, 12) +tl1_irq13: TRAP_IRQ(handler_irq, 13) +tl1_irq14: TRAP_IRQ(handler_irq, 14) +tl1_irq15: TRAP_IRQ(handler_irq, 15) +#else + BTRAPS(0x40) BTRAPS(0x48) +#endif + BTRAPS(0x50) BTRAPS(0x58) + BTRAPS(0x60) BTRAPS(0x68) + BTRAPS(0x70) BTRAPS(0x78) +tl1_s0n: SPILL_0_NORMAL +tl1_s1n: SPILL_1_NORMAL +tl1_s2n: SPILL_2_NORMAL +tl1_s3n: SPILL_3_NORMAL +tl1_s4n: SPILL_4_NORMAL +tl1_s5n: SPILL_5_NORMAL +tl1_s6n: SPILL_6_NORMAL +tl1_s7n: SPILL_7_NORMAL +tl1_s0o: SPILL_0_OTHER +tl1_s1o: SPILL_1_OTHER +tl1_s2o: SPILL_2_OTHER +tl1_s3o: SPILL_3_OTHER +tl1_s4o: SPILL_4_OTHER +tl1_s5o: SPILL_5_OTHER +tl1_s6o: SPILL_6_OTHER +tl1_s7o: SPILL_7_OTHER +tl1_f0n: FILL_0_NORMAL +tl1_f1n: FILL_1_NORMAL +tl1_f2n: FILL_2_NORMAL +tl1_f3n: FILL_3_NORMAL +tl1_f4n: FILL_4_NORMAL +tl1_f5n: FILL_5_NORMAL +tl1_f6n: FILL_6_NORMAL +tl1_f7n: FILL_7_NORMAL +tl1_f0o: FILL_0_OTHER +tl1_f1o: FILL_1_OTHER +tl1_f2o: FILL_2_OTHER +tl1_f3o: FILL_3_OTHER +tl1_f4o: FILL_4_OTHER +tl1_f5o: FILL_5_OTHER +tl1_f6o: FILL_6_OTHER +tl1_f7o: FILL_7_OTHER +tl1_resv100: BTRAPS(0x100) BTRAPS(0x108) +tl1_resv110: BTRAPS(0x110) BTRAPS(0x118) +tl1_resv120: BTRAPS(0x120) BTRAPS(0x128) +tl1_resv130: BTRAPS(0x130) BTRAPS(0x138) +tl1_resv140: BTRAPS(0x140) BTRAPS(0x148) +tl1_resv150: BTRAPS(0x150) BTRAPS(0x158) +tl1_resv160: BTRAPS(0x160) BTRAPS(0x168) +tl1_resv170: BTRAPS(0x170) BTRAPS(0x178) +tl1_resv180: BTRAPS(0x180) BTRAPS(0x188) +tl1_resv190: BTRAPS(0x190) BTRAPS(0x198) +tl1_resv1a0: BTRAPS(0x1a0) BTRAPS(0x1a8) +tl1_resv1b0: BTRAPS(0x1b0) BTRAPS(0x1b8) +tl1_resv1c0: BTRAPS(0x1c0) BTRAPS(0x1c8) +tl1_resv1d0: BTRAPS(0x1d0) BTRAPS(0x1d8) +tl1_resv1e0: BTRAPS(0x1e0) BTRAPS(0x1e8) +tl1_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8) + +spill_fixup: +spill_fixup_dax: +spill_fixup_mna: +fill_fixup: +fill_fixup_dax: +fill_fixup_mna: +__divide_error: +bug: + /* Dump the exception and its context */ + ! Set up CPU state + wrpr %g0, PSTATE_PRIV, %pstate + wr %g0, 0, %fprs + wrpr %g0, 0x0, %tl + + ! Disable I/D MMUs and caches + stxa %g0, [%g0] ASI_LSU_CONTROL + + ! Extract NWINDOWS from %ver + rdpr %ver, %g2 + and %g2, 0xf, %g2 + wrpr %g2, 0, %cleanwin + wrpr %g2, 0, %cansave + wrpr %g0, 0, %canrestore + wrpr %g0, 0, %otherwin + wrpr %g0, 0, %wstate + + call dump_exception + nop +_forever: + /* Loop forever */ + b _forever ; + nop +outstr: + /* void outstr (unsigned long port, const unsigned char *str); + * Writes a string on an IO port. + */ +1: ldub [%o1], %o3 + cmp %o3, 0 + be 2f + nop + stba %o3, [%o0] ASI_BP + b 1b + inc %o1 +2: retl + nop + +outdigit: + /* void outdigit (unsigned long port, uint8_t digit); + * Dumps a single digit on serial port. + */ + add %o1, '0', %o1 + retl + stba %o1, [%o0] ASI_BP + +outhex: + /* void outhex (unsigned long port, uint64_t value); + * Dumps a 64 bits hex number on serial port + */ + mov %o1, %o2 + set 60, %o3 + srlx %o2, %o3, %o1 +1: and %o1, 0xf, %o1 + cmp %o1, 9 + bgt 2f + nop + b 3f + add %o1, '0', %o1 +2: add %o1, 'a' - 10, %o1 +3: stba %o1, [%o0] ASI_BP + subcc %o3, 4, %o3 + bge 1b + srlx %o2, %o3, %o1 + retl + nop + + /* void dump_exception (); + * + * Dump a message when catching an exception + */ +dump_exception: + setx SER_ADDR, %o3, %o0 + setx (_BUG_message_0), %o3, %o1 + call outstr + nop + + call outhex + mov %g1, %o1 + + setx (_BUG_message_1), %o3, %o1 + call outstr + nop + + call outhex + rdpr %tpc, %o1 + + setx (_BUG_message_2), %o3, %o1 + call outstr + nop + + call outhex + rdpr %tnpc, %o1 + + setx (_BUG_message_3), %o3, %o1 + call outstr + nop + + retl + nop + +//#include "winfixup.S" + + .section .rodata +_BUG_message_0: + .string "Unhandled Exception 0x" +_BUG_message_1: + .string "\nPC = 0x" +_BUG_message_2: + .string " NPC = 0x" +_BUG_message_3: + .string "\nStopping execution\n"
Added: openbios-devel/arch/sparc64/winfixup.S =================================================================== --- openbios-devel/arch/sparc64/winfixup.S (rev 0) +++ openbios-devel/arch/sparc64/winfixup.S 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,240 @@ +/* $Id: winfixup.S,v 1.30 2002/02/09 19:49:30 davem Exp $ + * + * winfixup.S: Handle cases where user stack pointer is found to be bogus. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + */ + +#include "asi.h" +#include "spitfire.h" +#if 0 +#include <asm/head.h> +#include <asm/page.h> +#include <asm/ptrace.h> +#include <asm/processor.h> +#include <asm/thread_info.h> +#else +#define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */ +#define FAULT_CODE_DTLB 0x02 /* Miss happened in D-TLB */ +#define FAULT_CODE_ITLB 0x04 /* Miss happened in I-TLB */ +#define FAULT_CODE_WINFIXUP 0x08 /* Miss happened during spill/fill */ +#define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ +#endif + .text + .align 32 + + /* Here are the rules, pay attention. + * + * The kernel is disallowed from touching user space while + * the trap level is greater than zero, except for from within + * the window spill/fill handlers. This must be followed + * so that we can easily detect the case where we tried to + * spill/fill with a bogus (or unmapped) user stack pointer. + * + * These are layed out in a special way for cache reasons, + * don't touch... + */ + .globl fill_fixup, spill_fixup +fill_fixup: + rdpr %tstate, %g1 + or %g4, FAULT_CODE_WINFIXUP, %g4 + and %g1, TSTATE_CWP, %g1 + + /* This is the extremely complex case, but it does happen from + * time to time if things are just right. Essentially the restore + * done in rtrap right before going back to user mode, with tl=1 + * and that levels trap stack registers all setup, took a fill trap, + * the user stack was not mapped in the tlb, and tlb miss occurred, + * the pte found was not valid, and a simple ref bit watch update + * could not satisfy the miss, so we got here. + * + * We must carefully unwind the state so we get back to tl=0, preserve + * all the register values we were going to give to the user. Luckily + * most things are where they need to be, we also have the address + * which triggered the fault handy as well. + * + * Also note that we must preserve %l5 and %l6. If the user was + * returning from a system call, we must make it look this way + * after we process the fill fault on the users stack. + * + * First, get into the window where the original restore was executed. + */ + + rdpr %wstate, %g2 ! Grab user mode wstate. + wrpr %g1, %cwp ! Get into the right window. + sll %g2, 3, %g2 ! NORMAL-->OTHER + + wrpr %g0, 0x0, %canrestore ! Standard etrap stuff. + wrpr %g2, 0x0, %wstate ! This must be consistent. + wrpr %g0, 0x0, %otherwin ! We know this. + mov PRIMARY_CONTEXT, %g1 ! Change contexts... + stxa %g0, [%g1] ASI_DMMU ! Back into the nucleus. + flush %g6 ! Flush instruction buffers + rdpr %pstate, %l1 ! Prepare to change globals. + mov %g6, %o7 ! Get current. + + andn %l1, PSTATE_MM, %l1 ! We want to be in RMO + stb %g4, [%g6 + TI_FAULT_CODE] + stx %g5, [%g6 + TI_FAULT_ADDR] + wrpr %g0, 0x0, %tl ! Out of trap levels. + wrpr %l1, (PSTATE_IE | PSTATE_AG | PSTATE_RMO), %pstate + mov %o7, %g6 + ldx [%g6 + TI_TASK], %g4 + + /* This is the same as below, except we handle this a bit special + * since we must preserve %l5 and %l6, see comment above. + */ + call do_sparc64_fault + add %sp, PTREGS_OFF, %o0 + ba,pt %xcc, rtrap + nop ! yes, nop is correct + + /* Be very careful about usage of the alternate globals here. + * You cannot touch %g4/%g5 as that has the fault information + * should this be from usermode. Also be careful for the case + * where we get here from the save instruction in etrap.S when + * coming from either user or kernel (does not matter which, it + * is the same problem in both cases). Essentially this means + * do not touch %g7 or %g2 so we handle the two cases fine. + */ +spill_fixup: + ldx [%g6 + TI_FLAGS], %g1 + andcc %g1, _TIF_32BIT, %g0 + ldub [%g6 + TI_WSAVED], %g1 + + sll %g1, 3, %g3 + add %g6, %g3, %g3 + stx %sp, [%g3 + TI_RWIN_SPTRS] + sll %g1, 7, %g3 + bne,pt %xcc, 1f + add %g6, %g3, %g3 + stx %l0, [%g3 + TI_REG_WINDOW + 0x00] + stx %l1, [%g3 + TI_REG_WINDOW + 0x08] + + stx %l2, [%g3 + TI_REG_WINDOW + 0x10] + stx %l3, [%g3 + TI_REG_WINDOW + 0x18] + stx %l4, [%g3 + TI_REG_WINDOW + 0x20] + stx %l5, [%g3 + TI_REG_WINDOW + 0x28] + stx %l6, [%g3 + TI_REG_WINDOW + 0x30] + stx %l7, [%g3 + TI_REG_WINDOW + 0x38] + stx %i0, [%g3 + TI_REG_WINDOW + 0x40] + stx %i1, [%g3 + TI_REG_WINDOW + 0x48] + + stx %i2, [%g3 + TI_REG_WINDOW + 0x50] + stx %i3, [%g3 + TI_REG_WINDOW + 0x58] + stx %i4, [%g3 + TI_REG_WINDOW + 0x60] + stx %i5, [%g3 + TI_REG_WINDOW + 0x68] + stx %i6, [%g3 + TI_REG_WINDOW + 0x70] + b,pt %xcc, 2f + stx %i7, [%g3 + TI_REG_WINDOW + 0x78] +1: stw %l0, [%g3 + TI_REG_WINDOW + 0x00] + + stw %l1, [%g3 + TI_REG_WINDOW + 0x04] + stw %l2, [%g3 + TI_REG_WINDOW + 0x08] + stw %l3, [%g3 + TI_REG_WINDOW + 0x0c] + stw %l4, [%g3 + TI_REG_WINDOW + 0x10] + stw %l5, [%g3 + TI_REG_WINDOW + 0x14] + stw %l6, [%g3 + TI_REG_WINDOW + 0x18] + stw %l7, [%g3 + TI_REG_WINDOW + 0x1c] + stw %i0, [%g3 + TI_REG_WINDOW + 0x20] + + stw %i1, [%g3 + TI_REG_WINDOW + 0x24] + stw %i2, [%g3 + TI_REG_WINDOW + 0x28] + stw %i3, [%g3 + TI_REG_WINDOW + 0x2c] + stw %i4, [%g3 + TI_REG_WINDOW + 0x30] + stw %i5, [%g3 + TI_REG_WINDOW + 0x34] + stw %i6, [%g3 + TI_REG_WINDOW + 0x38] + stw %i7, [%g3 + TI_REG_WINDOW + 0x3c] +2: add %g1, 1, %g1 + + stb %g1, [%g6 + TI_WSAVED] + rdpr %tstate, %g1 + saved + and %g1, TSTATE_CWP, %g1 + mov FAULT_CODE_WRITE | FAULT_CODE_DTLB | FAULT_CODE_WINFIXUP, %g4 + retry + + .globl winfix_mna, fill_fixup_mna, spill_fixup_mna +winfix_mna: + andn %g3, 0x7f, %g3 + add %g3, 0x78, %g3 + wrpr %g3, %tnpc + done +fill_fixup_mna: + rdpr %tstate, %g1 + and %g1, TSTATE_CWP, %g1 + + /* Please, see fill_fixup commentary about why we must preserve + * %l5 and %l6 to preserve absolute correct semantics. + */ + rdpr %wstate, %g2 ! Grab user mode wstate. + wrpr %g1, %cwp ! Get into the right window. + sll %g2, 3, %g2 ! NORMAL-->OTHER + wrpr %g0, 0x0, %canrestore ! Standard etrap stuff. + + wrpr %g2, 0x0, %wstate ! This must be consistent. + wrpr %g0, 0x0, %otherwin ! We know this. + mov PRIMARY_CONTEXT, %g1 ! Change contexts... + stxa %g0, [%g1] ASI_DMMU ! Back into the nucleus. + flush %g6 ! Flush instruction buffers + rdpr %pstate, %l1 ! Prepare to change globals. + mov %g4, %o2 ! Setup args for + mov %g5, %o1 ! final call to mem_address_unaligned. + andn %l1, PSTATE_MM, %l1 ! We want to be in RMO + + mov %g6, %o7 ! Stash away current. + wrpr %g0, 0x0, %tl ! Out of trap levels. + wrpr %l1, (PSTATE_IE | PSTATE_AG | PSTATE_RMO), %pstate + mov %o7, %g6 ! Get current back. + ldx [%g6 + TI_TASK], %g4 ! Finish it. + call mem_address_unaligned + add %sp, PTREGS_OFF, %o0 + + b,pt %xcc, rtrap + nop ! yes, the nop is correct +spill_fixup_mna: + ldx [%g6 + TI_FLAGS], %g1 + andcc %g1, _TIF_32BIT, %g0 + ldub [%g6 + TI_WSAVED], %g1 + sll %g1, 3, %g3 + add %g6, %g3, %g3 + stx %sp, [%g3 + TI_RWIN_SPTRS] + + sll %g1, 7, %g3 + bne,pt %xcc, 1f + add %g6, %g3, %g3 + stx %l0, [%g3 + TI_REG_WINDOW + 0x00] + stx %l1, [%g3 + TI_REG_WINDOW + 0x08] + stx %l2, [%g3 + TI_REG_WINDOW + 0x10] + stx %l3, [%g3 + TI_REG_WINDOW + 0x18] + stx %l4, [%g3 + TI_REG_WINDOW + 0x20] + + stx %l5, [%g3 + TI_REG_WINDOW + 0x28] + stx %l6, [%g3 + TI_REG_WINDOW + 0x30] + stx %l7, [%g3 + TI_REG_WINDOW + 0x38] + stx %i0, [%g3 + TI_REG_WINDOW + 0x40] + stx %i1, [%g3 + TI_REG_WINDOW + 0x48] + stx %i2, [%g3 + TI_REG_WINDOW + 0x50] + stx %i3, [%g3 + TI_REG_WINDOW + 0x58] + stx %i4, [%g3 + TI_REG_WINDOW + 0x60] + + stx %i5, [%g3 + TI_REG_WINDOW + 0x68] + stx %i6, [%g3 + TI_REG_WINDOW + 0x70] + stx %i7, [%g3 + TI_REG_WINDOW + 0x78] + b,pt %xcc, 2f + add %g1, 1, %g1 +1: std %l0, [%g3 + TI_REG_WINDOW + 0x00] + std %l2, [%g3 + TI_REG_WINDOW + 0x08] + std %l4, [%g3 + TI_REG_WINDOW + 0x10] + + std %l6, [%g3 + TI_REG_WINDOW + 0x18] + std %i0, [%g3 + TI_REG_WINDOW + 0x20] + std %i2, [%g3 + TI_REG_WINDOW + 0x28] + std %i4, [%g3 + TI_REG_WINDOW + 0x30] + std %i6, [%g3 + TI_REG_WINDOW + 0x38] + add %g1, 1, %g1 +2: stb %g1, [%g6 + TI_WSAVED] + + saved + retry +
Added: openbios-devel/config/examples/cross-sparc64_config.xml =================================================================== --- openbios-devel/config/examples/cross-sparc64_config.xml (rev 0) +++ openbios-devel/config/examples/cross-sparc64_config.xml 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<config> + + <!-- generic --> + <option name="CONFIG_SPARC" type="boolean" value="true"/> + <option name="CONFIG_SPARC64" type="boolean" value="true"/> + <option name="CONFIG_BIG_ENDIAN" type="boolean" value="true"/> + + <!-- kernel binaries (SPARC64) --> + <option name="CONFIG_IMAGE_ELF" type="boolean" value="true"/> + <option name="CONFIG_IMAGE_ELF_EMBEDDED" type="boolean" value="true"/> + <option name="CONFIG_IMAGE_ELF_MULTIBOOT" type="boolean" value="true"/> + + <!-- Build hosted UNIX Binary --> + <option name="CONFIG_HOST_UNIX" type="boolean" value="false"/> + <option name="CONFIG_UNIX_QT" type="boolean" value="false"/> + <option name="CONFIG_PLUGINS" type="boolean" value="false"/> + + <!-- Kernel Debugging --> + <option name="CONFIG_DEBUG" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_BOOT" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_DSTACK" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_RSTACK" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_DICTIONARY" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_INTERNAL" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_INTERPRETER" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_CONSOLE" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_CONSOLE_SERIAL" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_SUN_PARTS" type="boolean" value="false"/> + <option name="CONFIG_SERIAL_PORT" type="integer" value="0"/> + <option name="CONFIG_SERIAL_SPEED" type="integer" value="115200"/> + <option name="CONFIG_DEBUG_CONSOLE_VGA" type="boolean" value="true"/> + + + <!-- Module Configuration --> + <option name="CONFIG_CMDLINE" type="boolean" value="true"/> + <option name="CONFIG_DEBLOCKER" type="boolean" value="true"/> + + + <!-- Filesystem Configuration --> + <option name="CONFIG_DISK_LABEL" type="boolean" value="true"/> + <option name="CONFIG_PART_SUPPORT" type="boolean" value="true"/> + <option name="CONFIG_PC_PARTS" type="boolean" value="false"/> + <option name="CONFIG_SUN_PARTS" type="boolean" value="true"/> + <option name="CONFIG_FS" type="boolean" value="true"/> + <option name="CONFIG_HFS" type="boolean" value="false"/> + <option name="CONFIG_HFSP" type="boolean" value="true"/> + <option name="CONFIG_GRUBFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_EXT2FS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_FAT" type="boolean" value="true"/> + <option name="CONFIG_FSYS_JFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_MINIX" type="boolean" value="true"/> + <option name="CONFIG_FSYS_REISERFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_XFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_UFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_ISO9660" type="boolean" value="true"/> + <option name="CONFIG_FSYS_FFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_VSTAFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_NTFS" type="boolean" value="false"/> + <option name="CONFIG_FSYS_AFFS" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_FS" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_EXT2FS" type="boolean" value="false"/> + + <!-- Miscellaneous --> + <option name="CONFIG_LINUXBIOS" type="boolean" value="false"/> + + <!-- Drivers --> + <option name="CONFIG_DRIVER_PCI" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_PCI" type="boolean" value="true"/> + <option name="CONFIG_DRIVER_IDE" type="boolean" value="true"/> + <option name="CONFIG_IDE_NUM_CHANNELS" type="integer" value="4"/> + <option name="CONFIG_DEBUG_IDE" type="boolean" value="true"/> + <option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="true"/> + +</config> +
Added: openbios-devel/config/examples/cross-sparc64_rules.xml =================================================================== --- openbios-devel/config/examples/cross-sparc64_rules.xml (rev 0) +++ openbios-devel/config/examples/cross-sparc64_rules.xml 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,82 @@ +<rules> + +<pre><![CDATA[ +# +# Autogenerated OpenBIOS Makefile +# (C) 2004-2006 by the OpenBIOS team +# + +ARCH := sparc64 +ODIR := obj-$(ARCH) +HOSTCC := gcc +CROSSCFLAGS := -DNATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH -DSWAP_ENDIANNESS +HOSTCFLAGS := -O2 -g -Wall -W -DFCOMPILER -DBOOTSTRAP $(CROSSCFLAGS) +HOSTINCLUDES := -Iinclude -Ikernel/include -I$(ODIR)/target/include + +CC := sparc-linux-gcc +AS := sparc-linux-as +AR := sparc-linux-ar +LD := sparc-linux-ld +NM := sparc-linux-nm +STRIP := sparc-linux-strip +RANLIB := sparc-linux-ranlib +CFLAGS := -Os -Wall -W -DNATIVE_BITWIDTH_EQUALS_HOST_BITWIDTH -USWAP_ENDIANNESS -fno-builtin -g +CFLAGS+= -Wa,-xarch=v9 -Wa,-64 -m64 -mcpu=ultrasparc -mcmodel=medany +CFLAGS+= -Wredundant-decls -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations +CFLAGS+= -Wundef -Wendif-labels -Wstrict-aliasing +INCLUDES := -Iinclude -Ikernel/include -I$(ODIR)/target/include +AS_FLAGS := -Wa,-xarch=v9 -Wa,-64 -g + +# +# pre rules +# + +all: versions dictionaries host-libraries target-libraries host-executables target-executables + +VERSION := "1.0RC1" + +versions: $(ODIR)/target/include/openbios-version.h $(ODIR)/forth/version.fs + +$(ODIR)/forth/version.fs: + @DATE="$(shell echo `date +'%b %e %Y %H:%M'`)" ; \ + ( echo ": builddate \" $$DATE\" ; " ; \ + echo ": version \" $(VERSION)\" ; " ; ) \ + > $(dir $@)/version.fs + +$(ODIR)/target/include/openbios-version.h: + @DATE="$(shell echo `date +'%b %e %Y %H:%M'`)" ; \ + ( echo "#define OPENBIOS_BUILD_DATE \"$$DATE\"" ; \ + echo "#define OPENBIOS_VERSION_STR \"$(VERSION)\"" ; \ + echo "#define OPENBIOS_RELEASE \"$(VERSION)\"" ; ) \ + > $(dir $@)/openbios-version.h +]]></pre> + + <!-- host compiler build rules --> + +<rule target="host" entity="executable"> + $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ +</rule> + +<rule target="host" entity="object"> + $(HOSTCC) $(HOSTCFLAGS) $(HOSTINCLUDES) -c -o $@ $^ +</rule> + +<rule target="host" entity="library"> + $(AR) cru $@ $^; $(RANLIB) $@ +</rule> + + <!-- target/cross compiler build rules --> + +<rule target="target" entity="executable"> + $(CC) $(CFLAGS) -o $@ $^ +</rule> + +<rule target="target" entity="object"> + $(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ $^ +</rule> + +<rule target="target" entity="library"> + $(AR) cru $@ $^; $(RANLIB) $@ +</rule> + +</rules>
Added: openbios-devel/config/examples/sparc64_config.xml =================================================================== --- openbios-devel/config/examples/sparc64_config.xml (rev 0) +++ openbios-devel/config/examples/sparc64_config.xml 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<config> + + <!-- generic --> + <option name="CONFIG_SPARC" type="boolean" value="true"/> + <option name="CONFIG_SPARC64" type="boolean" value="true"/> + <option name="CONFIG_BIG_ENDIAN" type="boolean" value="true"/> + + <!-- kernel binaries (SPARC64) --> + <option name="CONFIG_IMAGE_ELF" type="boolean" value="true"/> + <option name="CONFIG_IMAGE_ELF_EMBEDDED" type="boolean" value="true"/> + <option name="CONFIG_IMAGE_ELF_MULTIBOOT" type="boolean" value="true"/> + + <!-- Build hosted UNIX Binary --> + <option name="CONFIG_HOST_UNIX" type="boolean" value="true"/> + <option name="CONFIG_UNIX_QT" type="boolean" value="false"/> + <option name="CONFIG_PLUGINS" type="boolean" value="false"/> + + <!-- Kernel Debugging --> + <option name="CONFIG_DEBUG" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_BOOT" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_DSTACK" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_RSTACK" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_DICTIONARY" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_INTERNAL" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_INTERPRETER" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_CONSOLE" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_CONSOLE_SERIAL" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_SUN_PARTS" type="boolean" value="false"/> + <option name="CONFIG_SERIAL_PORT" type="integer" value="0"/> + <option name="CONFIG_SERIAL_SPEED" type="integer" value="115200"/> + <option name="CONFIG_DEBUG_CONSOLE_VGA" type="boolean" value="true"/> + + + <!-- Module Configuration --> + <option name="CONFIG_CMDLINE" type="boolean" value="true"/> + <option name="CONFIG_DEBLOCKER" type="boolean" value="true"/> + + + <!-- Filesystem Configuration --> + <option name="CONFIG_DISK_LABEL" type="boolean" value="true"/> + <option name="CONFIG_PART_SUPPORT" type="boolean" value="true"/> + <option name="CONFIG_PC_PARTS" type="boolean" value="false"/> + <option name="CONFIG_SUN_PARTS" type="boolean" value="true"/> + <option name="CONFIG_FS" type="boolean" value="true"/> + <option name="CONFIG_HFS" type="boolean" value="false"/> + <option name="CONFIG_HFSP" type="boolean" value="true"/> + <option name="CONFIG_GRUBFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_EXT2FS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_FAT" type="boolean" value="true"/> + <option name="CONFIG_FSYS_JFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_MINIX" type="boolean" value="true"/> + <option name="CONFIG_FSYS_REISERFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_XFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_UFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_ISO9660" type="boolean" value="true"/> + <option name="CONFIG_FSYS_FFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_VSTAFS" type="boolean" value="true"/> + <option name="CONFIG_FSYS_NTFS" type="boolean" value="false"/> + <option name="CONFIG_FSYS_AFFS" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_FS" type="boolean" value="false"/> + <option name="CONFIG_DEBUG_EXT2FS" type="boolean" value="false"/> + + <!-- Miscellaneous --> + <option name="CONFIG_LINUXBIOS" type="boolean" value="false"/> + + <!-- Drivers --> + <option name="CONFIG_DRIVER_PCI" type="boolean" value="true"/> + <option name="CONFIG_DEBUG_PCI" type="boolean" value="true"/> + <option name="CONFIG_DRIVER_IDE" type="boolean" value="true"/> + <option name="CONFIG_IDE_NUM_CHANNELS" type="integer" value="4"/> + <option name="CONFIG_DEBUG_IDE" type="boolean" value="true"/> + <option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="true"/> + +</config> +
Added: openbios-devel/config/examples/sparc64_rules.xml =================================================================== --- openbios-devel/config/examples/sparc64_rules.xml (rev 0) +++ openbios-devel/config/examples/sparc64_rules.xml 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,88 @@ +<rules> + +<pre><![CDATA[ +# +# Autogenerated OpenBIOS Makefile +# (C) 2004-2006 by the OpenBIOS team +# + +ARCH := sparc64 +ODIR := obj-$(ARCH) +HOSTCC := gcc +CROSSCFLAGS := -DNATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH -USWAP_ENDIANNESS +HOSTCFLAGS := -O2 -g -Wall -W -DFCOMPILER -DBOOTSTRAP $(CROSSCFLAGS) +HOSTINCLUDES := -Iinclude -Ikernel/include -I$(ODIR)/target/include + +CC := gcc +AS := as +AR := ar +LD := ld +NM := nm +STRIP := strip +RANLIB := ranlib +INSTALL := install + +ifeq ($(shell uname), Linux) + LIBDL_LDFLAGS=-ldl +endif + +CFLAGS := -Os -Wall -W -DNATIVE_BITWIDTH_EQUALS_HOST_BITWIDTH -USWAP_ENDIANNESS -fno-builtin -g +CFLAGS+= -Wa,-xarch=v9 -Wa,-64 -m64 -mcpu=ultrasparc -mcmodel=medany +CFLAGS+= -Wredundant-decls -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations +CFLAGS+= -Wundef -Wendif-labels -Wstrict-aliasing +INCLUDES := -Iinclude -Ikernel/include -I$(ODIR)/target/include +AS_FLAGS := -Wa,-xarch=v9 -Wa,-64 -g + +# +# pre rules +# + +all: versions dictionaries host-libraries target-libraries host-executables target-executables + +VERSION := "1.0RC1" + +versions: $(ODIR)/target/include/openbios-version.h $(ODIR)/forth/version.fs + +$(ODIR)/forth/version.fs: + @DATE="$(shell echo `date +'%b %e %Y %H:%M'`)" ; \ + ( echo ": builddate \" $$DATE\" ; " ; \ + echo ": version \" $(VERSION)\" ; " ; ) \ + > $(dir $@)/version.fs + +$(ODIR)/target/include/openbios-version.h: + @DATE="$(shell echo `date +'%b %e %Y %H:%M'`)" ; \ + ( echo "#define OPENBIOS_BUILD_DATE \"$$DATE\"" ; \ + echo "#define OPENBIOS_VERSION_STR \"$(VERSION)\"" ; \ + echo "#define OPENBIOS_RELEASE \"$(VERSION)\"" ; ) \ + > $(dir $@)/openbios-version.h +]]></pre> + + <!-- host compiler build rules --> + +<rule target="host" entity="executable"> + $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ +</rule> + +<rule target="host" entity="object"> + $(HOSTCC) $(HOSTCFLAGS) $(HOSTINCLUDES) -c -o $@ $^ +</rule> + +<rule target="host" entity="library"> + $(AR) cru $@ $^; $(RANLIB) $@ +</rule> + + <!-- target/cross compiler build rules --> + +<rule target="target" entity="executable"> + $(CC) $(CFLAGS) -o $@ $^ +</rule> + +<rule target="target" entity="object"> + $(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ $^ +</rule> + +<rule target="target" entity="library"> + $(AR) cru $@ $^; $(RANLIB) $@ +</rule> + +</rules>
Added: openbios-devel/include/sparc64/elf.h =================================================================== --- openbios-devel/include/sparc64/elf.h (rev 0) +++ openbios-devel/include/sparc64/elf.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,5 @@ +#define ARCH_ELF_CLASS ELFCLASS64 +#define ARCH_ELF_DATA ELFDATA2MSB +#define ARCH_ELF_MACHINE_OK(x) ((x)==EM_SPARCV9) +typedef Elf64_Ehdr Elf_ehdr; +typedef Elf64_Phdr Elf_phdr;
Added: openbios-devel/include/sparc64/io.h =================================================================== --- openbios-devel/include/sparc64/io.h (rev 0) +++ openbios-devel/include/sparc64/io.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,203 @@ +#ifndef _ASM_IO_H +#define _ASM_IO_H + +#include "asm/types.h" + +extern unsigned long va_shift; // Set in entry.S +extern char _start, _data, _heap, _eheap, _stack, _estack, _end, + _vmem, _evmem,_iomem; // Defined in ldscript + +static inline unsigned long +va2pa(unsigned long va) +{ + if ((va >= (unsigned long)&_data) && + (va < (unsigned long)&_end)) + return va - va_shift; + else + return va; +} + +static inline unsigned long +pa2va(unsigned long pa) +{ + if ((pa + va_shift >= (unsigned long)&_data) && + (pa + va_shift< (unsigned long)&_end)) + return pa + va_shift; + else + return pa; +} + +// XXX check use and merge +#define phys_to_virt(phys) ((void *) ((unsigned long) (phys))) +#define virt_to_phys(virt) ((unsigned long) (virt)) + +#ifndef BOOTSTRAP + +#ifndef _IO_BASE +#define _IO_BASE 0x1fe02000000ULL +#endif + +/* + * The insw/outsw/insl/outsl macros don't do byte-swapping. + * They are only used in practice for transferring buffers which + * are arrays of bytes, and byte-swapping is not appropriate in + * that case. - paulus + */ +#define insw(port, buf, ns) _insw_ns((uint16_t *)((port)+_IO_BASE), (buf), (ns)) +#define outsw(port, buf, ns) _outsw_ns((uint16_t *)((port)+_IO_BASE), (buf), (ns)) + +#define inb(port) in_8((uint8_t *)((port)+_IO_BASE)) +#define outb(val, port) out_8((uint8_t *)((port)+_IO_BASE), (val)) +#define inw(port) in_le16((uint16_t *)((port)+_IO_BASE)) +#define outw(val, port) out_le16((uint16_t *)((port)+_IO_BASE), (val)) +#define inl(port) in_le32((uint32_t *)((port)+_IO_BASE)) +#define outl(val, port) out_le32((uint32_t *)((port)+_IO_BASE), (val)) + +/* + * 8, 16 and 32 bit, big and little endian I/O operations, with barrier. + */ +static inline int in_8(volatile unsigned char *addr) +{ + int ret; + + __asm__ __volatile__("lduba [%1] 0x15, %0\n\t" + :"=r"(ret):"r"(addr):"memory"); + + return ret; +} + +static inline void out_8(volatile unsigned char *addr, int val) +{ + __asm__ __volatile__("stba %0, [%1] 0x15\n\t" + : : "r"(val), "r"(addr):"memory"); +} + +static inline int in_le16(volatile unsigned short *addr) +{ + int ret; + + // XXX + __asm__ __volatile__("lduha [%1] 0x15, %0\n\t" + :"=r"(ret):"r"(addr):"memory"); + + return ret; +} + +static inline int in_be16(volatile unsigned short *addr) +{ + int ret; + + __asm__ __volatile__("lduha [%1] 0x15, %0\n\t" + :"=r"(ret):"r"(addr):"memory"); + + return ret; +} + +static inline void out_le16(volatile unsigned short *addr, int val) +{ + // XXX + __asm__ __volatile__("stha %0, [%1] 0x15\n\t" + : : "r"(val), "r"(addr):"memory"); +} + +static inline void out_be16(volatile unsigned short *addr, int val) +{ + __asm__ __volatile__("stha %0, [%1] 0x15\n\t" + : : "r"(val), "r"(addr):"memory"); +} + +static inline unsigned in_le32(volatile unsigned *addr) +{ + unsigned ret; + + // XXX + __asm__ __volatile__("lduwa [%1] 0x15, %0\n\t" + :"=r"(ret):"r"(addr):"memory"); + + return ret; +} + +static inline unsigned in_be32(volatile unsigned *addr) +{ + unsigned ret; + + __asm__ __volatile__("lduwa [%1] 0x15, %0\n\t" + :"=r"(ret):"r"(addr):"memory"); + + return ret; +} + +static inline void out_le32(volatile unsigned *addr, int val) +{ + // XXX + __asm__ __volatile__("stwa %0, [%1] 0x15\n\t" + : : "r"(val), "r"(addr):"memory"); +} + +static inline void out_be32(volatile unsigned *addr, int val) +{ + __asm__ __volatile__("stwa %0, [%1] 0x15\n\t" + : : "r"(val), "r"(addr):"memory"); +} + +static inline void _insw_ns(volatile uint16_t * port, void *buf, int ns) +{ + uint16_t *b = (uint16_t *) buf; + + while (ns > 0) { + *b++ = in_le16(port); + ns--; + } +} + +static inline void _outsw_ns(volatile uint16_t * port, const void *buf, + int ns) +{ + uint16_t *b = (uint16_t *) buf; + + while (ns > 0) { + out_le16(port, *b++); + ns--; + } +} + +static inline void _insw(volatile uint16_t * port, void *buf, int ns) +{ + uint16_t *b = (uint16_t *) buf; + + while (ns > 0) { + *b++ = in_be16(port); + ns--; + } +} + +static inline void _outsw(volatile uint16_t * port, const void *buf, + int ns) +{ + uint16_t *b = (uint16_t *) buf; + + while (ns > 0) { + out_be16(port, *b++); + ns--; + } +} +#else /* BOOTSTRAP */ +#ifdef FCOMPILER +#define inb(reg) ((u8)0xff) +#define inw(reg) ((u16)0xffff) +#define inl(reg) ((u32)0xffffffff) +#define outb(reg, val) do{} while(0) +#define outw(reg, val) do{} while(0) +#define outl(reg, val) do{} while(0) +#else +extern u8 inb(u32 reg); +extern u16 inw(u32 reg); +extern u32 inl(u32 reg); +extern void insw(u32 reg, void *addr, unsigned long count); +extern void outb(u32 reg, u8 val); +extern void outw(u32 reg, u16 val); +extern void outl(u32 reg, u32 val); +extern void outsw(u32 reg, const void *addr, unsigned long count); +#endif +#endif +#endif /* _ASM_IO_H */
Added: openbios-devel/include/sparc64/types.h =================================================================== --- openbios-devel/include/sparc64/types.h (rev 0) +++ openbios-devel/include/sparc64/types.h 2006-06-10 01:37:53 UTC (rev 58) @@ -0,0 +1,39 @@ +/* tag: data types for forth engine + * + * Copyright (C) 2003-2005 Patrick Mauritz, Stefan Reinauer + * + * See the file "COPYING" for further information about + * the copyright and warranty status of this work. + */ + +#ifndef __TYPES_H +#define __TYPES_H + +#include "mconfig.h" + +#include <stdint.h> + +/* cell based types */ +typedef int64_t cell; +typedef uint64_t ucell; +typedef long long dcell; +typedef unsigned long long ducell; + +#define bitspercell (sizeof(cell)<<3) +#define bitsperdcell (sizeof(dcell)<<3) + +#define BITS 64 + +/* size named types */ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long u64; + +typedef signed char s8; +typedef short s16; +typedef int s32; +typedef long s64; + +#endif