Author: stepan Date: 2007-04-09 14:35:41 +0200 (Mon, 09 Apr 2007) New Revision: 120
Modified: openbios-devel/arch/sparc32/console.c openbios-devel/arch/sparc32/entry.S openbios-devel/arch/sparc32/openbios.c openbios-devel/arch/sparc32/tree.fs openbios-devel/config/scripts/archname openbios-devel/config/scripts/crosscflags openbios-devel/drivers/esp.c openbios-devel/drivers/iommu.c openbios-devel/drivers/obio.c openbios-devel/drivers/sbus.c openbios-devel/include/openbios/drivers.h openbios-devel/include/sparc32/io.h Log: SS10 support by blueswirl
Modified: openbios-devel/arch/sparc32/console.c =================================================================== --- openbios-devel/arch/sparc32/console.c 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/arch/sparc32/console.c 2007-04-09 12:35:41 UTC (rev 120) @@ -17,11 +17,11 @@
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
-#define KBD_BASE 0x71000004 -#define SERIAL_BASE 0x71100004 -#define CTRL(port) (SERIAL_BASE + (port) * 2 + 0) -#define DATA(port) (SERIAL_BASE + (port) * 2 + 2) +static unsigned long kbd_base, serial_base;
+#define CTRL(port) (serial_base + (port) * 2 + 0) +#define DATA(port) (serial_base + (port) * 2 + 2) + /* Conversion routines to/from brg time constants from/to bits * per second. */ @@ -98,7 +98,8 @@
int uart_init(int port, unsigned long speed) { - uart_init_line(port, speed); + serial_base = ((unsigned long)port) & ~3; + uart_init_line(port & 3, speed); return -1; }
@@ -177,6 +178,11 @@ console_init(); }
+void kbd_init(unsigned long base) +{ + kbd_base = base + 4; +} + static const unsigned char sunkbd_keycode[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -210,7 +216,7 @@ int keyboard_dataready(void) { - return ((inb(KBD_BASE) & 1) == 1); + return ((inb(kbd_base) & 1) == 1); }
unsigned char @@ -221,7 +227,7 @@ while (!keyboard_dataready()) { }
do { - ch = inb(KBD_BASE + 2) & 0xff; + ch = inb(kbd_base + 2) & 0xff; if (ch == 99) shiftstate |= 1; else if (ch == 110)
Modified: openbios-devel/arch/sparc32/entry.S =================================================================== --- openbios-devel/arch/sparc32/entry.S 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/arch/sparc32/entry.S 2007-04-09 12:35:41 UTC (rev 120) @@ -14,6 +14,9 @@ #define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */ #define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */
+#define PHYS_SS10_EEPROM 0xf1200000 /* XXX Actually at 0xff1200000ULL (36 bits)*/ +#define PHYS_SS10_INTR0 0xf1400000 /* 0xff1400000ULL */ + #define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
.globl entry, _entry @@ -31,9 +34,30 @@ * Main context is statically defined in C. */
+ ! Check if this is QEMU for SS-5 + set PHYS_JJ_EEPROM, %g1 + lduba [%g1] ASI_M_BYPASS, %g2 + cmp %g2, 'Q' + bne ss10 + inc %g1 + lduba [%g1] ASI_M_BYPASS, %g2 + cmp %g2, 'E' + bne ss10 + inc %g1 + lduba [%g1] ASI_M_BYPASS, %g2 + cmp %g2, 'M' + bne ss10 + inc %g1 + lduba [%g1] ASI_M_BYPASS, %g2 + cmp %g2, 'U' + bne ss10 + + ! Ok, this is SS-5 + mov 0x80, %y ! Check if this not the first SMP CPU, if so, bypass PROM entirely set PHYS_JJ_EEPROM + 0x2E, %g1 lduba [%g1] ASI_M_BYPASS, %g2 + set PHYS_JJ_EEPROM + 0x30, %g1 tst %g2 bz first_cpu nop @@ -58,11 +82,64 @@ set 1, %g1 jmp %g2 ! jump to kernel sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu + +bad_nvram: + ! Unknown machine, freeze + b bad_nvram + nop +ss10: + set PHYS_SS10_EEPROM, %g1 + ! XXX use full 36 bits access + lduba [%g1] ASI_M_BYPASS, %g2 + cmp %g2, 'Q' + bne bad_nvram + inc %g1 + lduba [%g1] ASI_M_BYPASS, %g2 + cmp %g2, 'E' + bne bad_nvram + inc %g1 + lduba [%g1] ASI_M_BYPASS, %g2 + cmp %g2, 'M' + bne bad_nvram + inc %g1 + lduba [%g1] ASI_M_BYPASS, %g2 + cmp %g2, 'U' + bne bad_nvram
+ ! Ok, this is SS-10 + mov 0x72, %y + ! Check if this not the first SMP CPU, if so, bypass PROM entirely + ! XXX use full 36 bits access + set PHYS_SS10_EEPROM + 0x2E, %g1 + lduba [%g1] ASI_M_BYPASS, %g2 + set PHYS_SS10_EEPROM + 0x30, %g1 + tst %g2 + bz first_cpu + nop + set PHYS_SS10_INTR0 + 0x04, %g1 + sll %g2, 12, %g2 + add %g1, %g2, %g2 + set 0xffffffff, %g1 + sta %g1, [%g2] ASI_M_BYPASS ! clear softints + add %g2, 4, %g2 + sta %g0, [%g2] ASI_M_BYPASS ! clear softints + set PHYS_SS10_EEPROM + 0x3C, %g1 + lda [%g1] ASI_M_BYPASS, %g1 + set AC_M_CTPR, %g2 + sta %g1, [%g2] ASI_M_MMUREGS ! set ctx table ptr + set PHYS_JJ_EEPROM + 0x40, %g1 + lda [%g1] ASI_M_BYPASS, %g1 + set AC_M_CXR, %g2 + sta %g1, [%g2] ASI_M_MMUREGS ! set context + set PHYS_SS10_EEPROM + 0x38, %g1 + lda [%g1] ASI_M_BYPASS, %g2 + set 1, %g1 + jmp %g2 ! jump to kernel + sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu + first_cpu: /* Create temporary page tables and map the ROM area to end of RAM. This will be done properly in iommu.c later. */ - set PHYS_JJ_EEPROM + 0x30, %g1 lda [%g1] ASI_M_BYPASS, %g1 set _end, %g3 set 0xfff, %g2 @@ -213,6 +290,10 @@ sub %g1, %g7, %g7 set va_shift, %g1 st %g7, [%g1] + + set qemu_machine_type, %g1 + mov %y, %g2 + st %g2, [%g1]
/* Finally, turn on traps so that we can call c-code. */ rd %psr, %g3
Modified: openbios-devel/arch/sparc32/openbios.c =================================================================== --- openbios-devel/arch/sparc32/openbios.c 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/arch/sparc32/openbios.c 2007-04-09 12:35:41 UTC (rev 120) @@ -19,12 +19,60 @@ void boot(void); void ob_ide_init(void); void tcx_init(unsigned long base); +void kbd_init(unsigned long base);
-#define IOMMU_BASE 0x10000000 /* First page of sun4m IOMMU */ -#define SBUS_BASE 0x10001000 -#define SLAVIO_BASE 0x71000000 -#define TCX_BASE 0x50000000 +int qemu_machine_type;
+struct hwdef { + unsigned long iommu_high, iommu_base; + unsigned long slavio_high, slavio_base; + unsigned long intctl_base, counter_base, nvram_base, ms_kb_base, serial_base; + unsigned long fd_offset, counter_offset, intr_offset; + unsigned long dma_base, esp_base, le_base; + unsigned long tcx_base; + int machine_id; +}; + +static const struct hwdef hwdefs[] = { + /* SS-5 */ + { + .iommu_high = 0x0, + .iommu_base = 0x10000000, + .tcx_base = 0x50000000, + .slavio_high = 0x0, + .slavio_base = 0x71000000, + .ms_kb_base = 0x71000000, + .serial_base = 0x71100000, + .nvram_base = 0x71200000, + .fd_offset = 0x00400000, + .counter_offset = 0x00d00000, + .intr_offset = 0x00e00000, + .dma_base = 0x78400000, + .esp_base = 0x78800000, + .le_base = 0x78c00000, + .machine_id = 0x80, + }, + /* SS-10 */ + { + .iommu_high = 0xf, + .iommu_base = 0xe0000000, // XXX Actually at 0xfe0000000ULL (36 bits) + .tcx_base = 0x20000000, // 0xe20000000ULL, + .slavio_high = 0xf, + .slavio_base = 0xf1000000, // 0xff1000000ULL, + .ms_kb_base = 0xf1000000, // 0xff1000000ULL, + .serial_base = 0xf1100000, // 0xff1100000ULL, + .nvram_base = 0xf1200000, // 0xff1200000ULL, + .fd_offset = 0x00700000, // 0xff1700000ULL, + .counter_offset = 0x00300000, // 0xff1300000ULL, + .intr_offset = 0x00400000, // 0xff1400000ULL, + .dma_base = 0xf0400000, // 0xef0400000ULL, + .esp_base = 0xf0800000, // 0xef0800000ULL, + .le_base = 0xf0c00000, // 0xef0c00000ULL, + .machine_id = 0x72, + }, +}; + +static const struct hwdef *hwdef; static unsigned char intdict[256 * 1024];
static void init_memory(void) @@ -48,15 +96,16 @@
modules_init(); #ifdef CONFIG_DRIVER_SBUS - ob_init_mmu(IOMMU_BASE); - ob_sbus_init(SBUS_BASE); + ob_init_mmu(hwdef->iommu_high, hwdef->iommu_base); + ob_sbus_init(hwdef->iommu_high, hwdef->iommu_base + 0x1000, hwdef->machine_id);
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO init_video(); #endif #endif #ifdef CONFIG_DRIVER_OBIO - ob_obio_init(SLAVIO_BASE); + ob_obio_init(hwdef->slavio_high, hwdef->slavio_base, hwdef->fd_offset, + hwdef->counter_offset, hwdef->intr_offset); nvram_init(); #endif device_end(); @@ -68,17 +117,29 @@ { extern struct sys_info sys_info; extern struct mem cmem; + unsigned int i;
+ for (i = 0; i < sizeof(hwdefs) / sizeof(struct hwdef); i++) { + if (hwdefs[i].machine_id == qemu_machine_type) { + hwdef = &hwdefs[i]; + break; + } + } + if (!hwdef) + for(;;); // Internal inconsistency, hang + mem_init(&cmem, (char *) &_vmem, (char *)&_evmem); #ifdef CONFIG_DRIVER_SBUS - init_mmu_swift(IOMMU_BASE); + init_mmu_swift(hwdef->iommu_base); #endif #ifdef CONFIG_DEBUG_CONSOLE #ifdef CONFIG_DEBUG_CONSOLE_SERIAL - uart_init(CONFIG_SERIAL_PORT, CONFIG_SERIAL_SPEED); + uart_init(hwdef->serial_base | (CONFIG_SERIAL_PORT? 0: 4), + CONFIG_SERIAL_SPEED); #endif #ifdef CONFIG_DEBUG_CONSOLE_VIDEO - tcx_init(TCX_BASE); + tcx_init(hwdef->tcx_base); + kbd_init(hwdef->ms_kb_base); #endif /* Clear the screen. */ cls();
Modified: openbios-devel/arch/sparc32/tree.fs =================================================================== --- openbios-devel/arch/sparc32/tree.fs 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/arch/sparc32/tree.fs 2007-04-09 12:35:41 UTC (rev 120) @@ -3,10 +3,7 @@ 2 encode-int " #address-cells" property 1 encode-int " #size-cells" property
- " SUNW,SPARCstation-5" encode-string " name" property - " SPARCstation 5" encode-string " banner-name" property " sun4m" encode-string " compatible" property - " SUNW,501-3059" encode-string " model" property h# 0a21fe80 encode-int " clock-frequency" property
: encode-unit encode-unit-sbus ; @@ -36,8 +33,6 @@ 1 encode-int " #size-cells" property h# 1000 encode-int " page-size" property 0 encode-int " cache-coherence?" property - h# ffee8000 encode-int " address" property - h# 0 encode-int h# 10000000 encode-int encode+ h# 00000300 encode-int encode+ " reg" property external : open ( cr ." opening iommu" cr) true ; : close ; @@ -54,12 +49,6 @@ h# 01443fd0 encode-int " clock-frequency" property h# 1c encode-int " slot-address-bits" property h# 3f encode-int " burst-sizes" property - h# 0 encode-int h# 0 encode-int encode+ h# 0 encode-int encode+ h# 30000000 encode-int encode+ h# 10000000 encode-int encode+ - h# 1 encode-int encode+ h# 0 encode-int encode+ h# 0 encode-int encode+ h# 40000000 encode-int encode+ h# 10000000 encode-int encode+ - h# 2 encode-int encode+ h# 0 encode-int encode+ h# 0 encode-int encode+ h# 50000000 encode-int encode+ h# 10000000 encode-int encode+ - h# 3 encode-int encode+ h# 0 encode-int encode+ h# 0 encode-int encode+ h# 60000000 encode-int encode+ h# 10000000 encode-int encode+ - h# 4 encode-int encode+ h# 0 encode-int encode+ h# 0 encode-int encode+ h# 70000000 encode-int encode+ h# 10000000 encode-int encode+ - " ranges" property external : open ( cr ." opening SBus" cr) true ; : close ; @@ -103,20 +92,6 @@ " no" encode-string " tcx-8-bit" property 5 encode-int 0 encode-int encode+ " intr" property 5 encode-int " interrupts" property - 2 encode-int h# 00800000 encode-int encode+ h# 00100000 encode-int encode+ - 2 encode-int encode+ h# 02000000 encode-int encode+ h# 00000001 encode-int encode+ - 2 encode-int encode+ h# 04000000 encode-int encode+ h# 00800000 encode-int encode+ - 2 encode-int encode+ h# 06000000 encode-int encode+ h# 00800000 encode-int encode+ - 2 encode-int encode+ h# 0a000000 encode-int encode+ h# 00000001 encode-int encode+ - 2 encode-int encode+ h# 0c000000 encode-int encode+ h# 00000001 encode-int encode+ - 2 encode-int encode+ h# 0e000000 encode-int encode+ h# 00000001 encode-int encode+ - 2 encode-int encode+ h# 00700000 encode-int encode+ h# 00001000 encode-int encode+ - 2 encode-int encode+ h# 00200000 encode-int encode+ h# 00000004 encode-int encode+ - 2 encode-int encode+ h# 00300000 encode-int encode+ h# 0000081c encode-int encode+ - 2 encode-int encode+ h# 00000000 encode-int encode+ h# 00010000 encode-int encode+ - 2 encode-int encode+ h# 00240000 encode-int encode+ h# 00000004 encode-int encode+ - 2 encode-int encode+ h# 00280000 encode-int encode+ h# 00000001 encode-int encode+ - " reg" property finish-device
" /iommu/sbus" find-device @@ -130,7 +105,6 @@ " /iommu/sbus" find-device new-device " ledma" device-name - h# 4 encode-int h# 08400010 encode-int encode+ h# 00000020 encode-int encode+ " reg" property h# 3f encode-int " burst-sizes" property external : encode-unit encode-unit-sbus ; @@ -141,7 +115,6 @@ new-device " le" device-name " network" device-type - h# 4 encode-int h# 08c00000 encode-int encode+ h# 00000004 encode-int encode+ " reg" property h# 7 encode-int " busmaster-regval" property h# 26 encode-int 0 encode-int encode+ " intr" property finish-device @@ -160,8 +133,6 @@ " hierarchical" device-type 2 encode-int " #address-cells" property 1 encode-int " #size-cells" property - h# 0 encode-int h# 0 encode-int encode+ h# 0 encode-int encode+ h# 71000000 encode-int encode+ h# 01000000 encode-int encode+ - " ranges" property external : open ( cr ." opening obio" cr) true ; : close ;
Modified: openbios-devel/config/scripts/archname =================================================================== --- openbios-devel/config/scripts/archname 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/config/scripts/archname 2007-04-09 12:35:41 UTC (rev 120) @@ -9,7 +9,8 @@ ppc|powerpc|mpc107|osx|darwin) ARCH=ppc ;; esac
-test "$ARCH" || ARCH=`uname -m | sed -e s/i.86/x86/ -e s/i86pc/x86/ -e s/sun4u/sparc64/ \ +test "$ARCH" || ARCH=`uname -m | sed -e s/i.86/x86/ -e s/i86pc/x86/ \ + -e s/sun4u/sparc64/ -e s/sparc$/sparc32/ \ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/x86_64/amd64/ \ -e "s/Power Macintosh/ppc/"`
Modified: openbios-devel/config/scripts/crosscflags =================================================================== --- openbios-devel/config/scripts/crosscflags 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/config/scripts/crosscflags 2007-04-09 12:35:41 UTC (rev 120) @@ -3,31 +3,33 @@ host=$1 target=$2
-if test "$host" = "sparc"; then - host="sparc32" -fi - -if test "$host" = "powerpc" -o "$host" = "mips" -o "$host" = "s390" -o "$host" = "sparc32" -o "$host" = "sparc64" -o "$host" = "m68k" -o "$host" = "armv4b"; then +if test "$host" = "powerpc" -o "$host" = "mips" -o "$host" = "s390" \ + -o "$host" = "sparc32" -o "$host" = "sparc64" \ + -o "$host" = "m68k" -o "$host" = "armv4b"; then hostbigendian="yes" else hostbigendian="no" fi
# host long bits test -if test "$host" = "sparc64" -o "$host" = "ia64" -o "$host" = "amd64" -o "$host" = "alpha"; then +if test "$host" = "sparc64" -o "$host" = "ia64" \ + -o "$host" = "amd64" -o "$host" = "alpha"; then hostlongbits="64" else hostlongbits="32" fi
-if test "$target" = "powerpc" -o "$target" = "mips" -o "$target" = "s390" -o "$target" = "sparc32" -o "$target" = "sparc64" -o "$target" = "m68k" -o "$target" = "armv4b"; then +if test "$target" = "powerpc" -o "$target" = "mips" -o "$target" = "s390" \ + -o "$target" = "sparc32" -o "$target" = "sparc64" \ + -o "$target" = "m68k" -o "$target" = "armv4b"; then targetbigendian="yes" else targetbigendian="no" fi
# target long bits test -if test "$target" = "sparc64" -o "$target" = "ia64" -o "$target" = "amd64" -o "$target" = "alpha"; then +if test "$target" = "sparc64" -o "$target" = "ia64" \ + -o "$target" = "amd64" -o "$target" = "alpha"; then targetlongbits="64" else targetlongbits="32"
Modified: openbios-devel/drivers/esp.c =================================================================== --- openbios-devel/drivers/esp.c 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/drivers/esp.c 2007-04-09 12:35:41 UTC (rev 120) @@ -25,8 +25,8 @@ #include "asm/dma.h" #include "esp.h"
-#define MACIO_ESPDMA 0x08400000 /* ESP DMA controller */ -#define MACIO_ESP 0x08800000 /* ESP SCSI */ +#define MACIO_ESPDMA 0x00400000 /* ESP DMA controller */ +#define MACIO_ESP 0x00800000 /* ESP SCSI */
#define BUFSIZE 4096
@@ -321,9 +321,10 @@
static int -espdma_init(unsigned long base, struct esp_dma *espdma) +espdma_init(unsigned int slot, unsigned long base, unsigned long offset, + struct esp_dma *espdma) { - espdma->regs = (void *)map_io(base + MACIO_ESPDMA, 0x10); + espdma->regs = (void *)map_io(base + offset + MACIO_ESPDMA, 0x10);
if (espdma->regs == 0) { DPRINTF("espdma_init: cannot map registers\n"); @@ -369,9 +370,9 @@ fword("find-device");
/* set reg */ - PUSH(4); + PUSH(slot); fword("encode-int"); - PUSH(MACIO_ESPDMA); + PUSH(offset + MACIO_ESPDMA); fword("encode-int"); fword("encode+"); PUSH(0x00000010); @@ -395,18 +396,6 @@ push_str("scsi"); fword("device-type");
- /* set reg */ - PUSH(4); - fword("encode-int"); - PUSH(MACIO_ESP); - fword("encode-int"); - fword("encode+"); - PUSH(0x00000010); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - PUSH(0x24); fword("encode-int"); PUSH(0); @@ -448,7 +437,7 @@ }
int -ob_esp_init(unsigned long base) +ob_esp_init(unsigned int slot, unsigned long base, unsigned long offset) { int id, diskcount = 0, cdcount = 0, *counter_ptr; char nodebuff[256], aliasbuff[256]; @@ -464,11 +453,11 @@
global_esp = esp;
- if (espdma_init(base, &esp->espdma) != 0) { + if (espdma_init(slot, base, offset, &esp->espdma) != 0) { return -1; } /* Get the IO region */ - esp->ll = (void *)map_io(base + MACIO_ESP, sizeof(struct esp_regs)); + esp->ll = (void *)map_io(base + offset + MACIO_ESP, sizeof(struct esp_regs)); if (esp->ll == 0) { DPRINTF("Can't map ESP registers\n"); return -1; @@ -501,6 +490,19 @@
REGISTER_NAMED_NODE(ob_esp, "/iommu/sbus/espdma/esp"); device_end(); + /* set reg */ + push_str("/iommu/sbus/espdma/esp"); + fword("find-device"); + PUSH(slot); + fword("encode-int"); + PUSH(offset + MACIO_ESP); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000010); + fword("encode-int"); + fword("encode+"); + push_str("reg"); + fword("property");
for (id = 0; id < 8; id++) { if (!esp->sd[id].present)
Modified: openbios-devel/drivers/iommu.c =================================================================== --- openbios-devel/drivers/iommu.c 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/drivers/iommu.c 2007-04-09 12:35:41 UTC (rev 120) @@ -199,7 +199,7 @@ }
void -ob_init_mmu(unsigned long base) +ob_init_mmu(unsigned long bus, unsigned long base) { extern unsigned int qemu_mem_size;
@@ -231,7 +231,7 @@ push_str("/virtual-memory"); fword("find-device");
- PUSH(0); + PUSH(bus); fword("encode-int"); PUSH(base); fword("encode-int"); @@ -269,6 +269,17 @@ fword("encode-int"); push_str("address"); fword("property"); + + PUSH(bus); + fword("encode-int"); + PUSH(base); + fword("encode-int"); + fword("encode+"); + PUSH(IOMMU_REGS); + fword("encode-int"); + fword("encode+"); + push_str("reg"); + fword("property"); }
Modified: openbios-devel/drivers/obio.c =================================================================== --- openbios-devel/drivers/obio.c 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/drivers/obio.c 2007-04-09 12:35:41 UTC (rev 120) @@ -285,7 +285,7 @@ } }
-static char *nvram; +static unsigned char *nvram; struct qemu_nvram_v1 nv_info;
void @@ -306,6 +306,39 @@ return NVRAM_SIZE; }
+struct cpudef { + const unsigned char *name; + unsigned long iu_version; +}; + +static const struct cpudef sparc_defs[] = { + { + .name = "FMI,MB86904", + .iu_version = 0x04 << 24, /* Impl 0, ver 4 */ + }, + { + .name = "TI,TMS390Z55", + .iu_version = 0x40000000, + }, +}; + +static const char * +id_cpu(void) +{ + unsigned long iu_version; + unsigned int i; + + asm("rd %%psr, %0\n" + : "=r"(iu_version) :); + iu_version &= 0xff000000; + + for (i = 0; i < sizeof(sparc_defs)/sizeof(struct cpudef); i++) { + if (iu_version == sparc_defs[i].iu_version) + return sparc_defs[i].name; + } + return "CPU,Unknown"; +} + static void ob_nvram_init(unsigned long base, unsigned long offset) { @@ -317,10 +350,11 @@ extern char obp_stdin, obp_stdout; extern const char *obp_stdin_path, *obp_stdout_path;
- const char *stdin, *stdout; + const char *stdin, *stdout, *cpuname; unsigned int i; char nographic; uint32_t size; + unsigned int machine_id;
ob_new_obio_device("eeprom", NULL);
@@ -332,12 +366,14 @@ fword("property");
memcpy(&nv_info, nvram, sizeof(nv_info)); - - printk("Nvram id %s, version %d\n", nv_info.id_string, nv_info.version); + machine_id = (unsigned int)nvram[0x1fd9] & 0xff; + printk("Nvram id %s, version %d, machine id 0x%2.2x\n", nv_info.id_string, + nv_info.version, machine_id); if (strcmp(nv_info.id_string, "QEMU_BIOS") || nv_info.version != 1) { printk("Unknown nvram, freezing!\n"); for (;;); } + kernel_image = nv_info.kernel_image; kernel_size = nv_info.kernel_size; size = nv_info.cmdline_size; @@ -366,6 +402,33 @@ push_str("idprom"); fword("property");
+ switch (machine_id) { + case 0x72: + push_str("SPARCstation 10 (1 X 390Z55)"); + push_str("banner-name"); + fword("property"); + push_str("SUNW,S10,501-2365"); + push_str("model"); + fword("property"); + push_str("SUNW,SPARCstation-10"); + push_str("name"); + fword("property"); + break; + case 0x80: + push_str("SPARCstation 5"); + push_str("name"); + fword("property"); + push_str("SUNW,501-3059"); + push_str("model"); + fword("property"); + push_str("SUNW,SPARCstation-5"); + push_str("name"); + fword("property"); + break; + default: + printk("Unknown machine, freezing!\n"); + for (;;); + } // Add cpus printk("CPUs: %x\n", nv_info.smp_cpus); for (i = 0; i < (unsigned int)nv_info.smp_cpus; i++) { @@ -373,8 +436,9 @@ fword("find-device");
fword("new-device"); - - push_str("FMI,MB86904"); + + cpuname = id_cpu(); + push_str(cpuname); fword("device-name");
push_str("cpu"); @@ -713,7 +777,7 @@ }
static void -ob_set_obio_ranges(unsigned long base) +ob_set_obio_ranges(unsigned long high, unsigned long base) { push_str("/obio"); fword("find-device"); @@ -722,7 +786,7 @@ PUSH(0); fword("encode-int"); fword("encode+"); - PUSH(0); + PUSH(high); fword("encode-int"); fword("encode+"); PUSH(base); @@ -758,7 +822,9 @@
int -ob_obio_init(unsigned long slavio_base) +ob_obio_init(unsigned long slavio_high, unsigned long slavio_base, + unsigned long fd_offset, unsigned long counter_offset, + unsigned long intr_offset) {
// All devices were integrated to NCR89C105, see @@ -768,8 +834,8 @@ #if 0 // XXX REGISTER_NAMED_NODE(ob_obio, "/obio"); device_end(); - ob_set_obio_ranges(slavio_base); #endif + ob_set_obio_ranges(slavio_high, slavio_base);
// Zilog Z8530 serial ports, see http://www.zilog.com // Must be before zs@0,0 or Linux won't boot @@ -781,7 +847,7 @@ ob_nvram_init(slavio_base, SLAVIO_NVRAM);
// 82078 FDC - ob_fd_init(slavio_base, SLAVIO_FD, FD_INTR); + ob_fd_init(slavio_base, fd_offset, FD_INTR);
ob_sconfig_init(slavio_base, SLAVIO_SCONFIG);
@@ -789,9 +855,9 @@
ob_power_init(slavio_base, SLAVIO_POWER, POWER_INTR);
- ob_counter_init(slavio_base, SLAVIO_COUNTER); + ob_counter_init(slavio_base, counter_offset);
- ob_interrupt_init(slavio_base, SLAVIO_INTERRUPT); + ob_interrupt_init(slavio_base, intr_offset);
return 0; }
Modified: openbios-devel/drivers/sbus.c =================================================================== --- openbios-devel/drivers/sbus.c 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/drivers/sbus.c 2007-04-09 12:35:41 UTC (rev 120) @@ -19,17 +19,17 @@ #include "openbios/drivers.h"
#define SBUS_REGS 0x28 -#define SBUS_SLOTS 5 +#define SBUS_SLOTS 16
static void -ob_sbus_node_init(unsigned long base) +ob_sbus_node_init(unsigned long bus, unsigned long base) { void *regs;
push_str("/iommu/sbus"); fword("find-device");
- PUSH(0); + PUSH(bus); fword("encode-int"); PUSH(base); fword("encode-int"); @@ -48,19 +48,188 @@ }
static void -ob_macio_init(unsigned int slot, unsigned long base) +ob_le_init(unsigned int slot, unsigned long base, unsigned long offset) { + push_str("/iommu/sbus/ledma"); + fword("find-device"); + PUSH(slot); + fword("encode-int"); + PUSH(offset + 0x00400010); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000020); + fword("encode-int"); + fword("encode+"); + push_str("reg"); + fword("property"); + + push_str("/iommu/sbus/ledma/le"); + fword("find-device"); + PUSH(slot); + fword("encode-int"); + PUSH(offset + 0x00c00000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000004); + fword("encode-int"); + fword("encode+"); + push_str("reg"); + fword("property"); +} + +static void +ob_tcx_init(unsigned int slot, unsigned long base) +{ + push_str("/iommu/sbus/SUNW,tcx"); + fword("find-device"); + + PUSH(slot); + fword("encode-int"); + PUSH(0x00800000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00100000); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x02000000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000001); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x04000000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000001); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x06000000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00800000); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x0a000000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000001); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x0c000000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000001); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x0e000000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000001); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x00700000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00001000); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x00200000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000004); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x00300000); + fword("encode-int"); + fword("encode+"); + PUSH(0x0000081c); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00010000); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x00240000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000004); + fword("encode-int"); + fword("encode+"); + + PUSH(slot); + fword("encode-int"); + fword("encode+"); + PUSH(0x00280000); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000001); + fword("encode-int"); + fword("encode+"); + + push_str("reg"); + fword("property"); +} + +static void +ob_macio_init(unsigned int slot, unsigned long base, unsigned long offset) +{ // All devices were integrated to NCR89C100, see // http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.tx...
// NCR 53c9x, aka ESP. See // http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt #ifdef CONFIG_DRIVER_ESP - ob_esp_init(base); + ob_esp_init(slot, base, offset); #endif
// NCR 92C990, Am7990, Lance. See http://www.amd.com - //ob_le_init(base); + ob_le_init(slot, base, offset);
// Parallel port //ob_bpp_init(base); @@ -70,18 +239,18 @@ }
static void -sbus_probe_slot(unsigned int slot, unsigned long base) +sbus_probe_slot_ss5(unsigned int slot, unsigned long base) { // OpenBIOS and Qemu don't know how to do Sbus probing switch(slot) { - case 2: // SUNW,tcx - //ob_tcx_init(slot, base); + case 3: // SUNW,tcx + ob_tcx_init(slot, base); break; - case 3: // SUNW,CS4231 + case 4: // SUNW,CS4231 //ob_cs4231_init(slot, base); break; - case 4: // MACIO: le, esp, bpp, power-management - ob_macio_init(slot, base); + case 5: // MACIO: le, esp, bpp, power-management + ob_macio_init(slot, base, 0x08000000); break; default: break; @@ -89,6 +258,22 @@ }
static void +sbus_probe_slot_ss10(unsigned int slot, unsigned long base) +{ + // OpenBIOS and Qemu don't know how to do Sbus probing + switch(slot) { + case 2: // SUNW,tcx + ob_tcx_init(slot, base); + break; + case 0xf: // le, esp, bpp, power-management + ob_macio_init(slot, base, 0); + break; + default: + break; + } +} + +static void ob_sbus_open(int *idx) { int ret=1; @@ -113,23 +298,100 @@ { "close", ob_sbus_close }, };
-static const unsigned long sbus_offset[SBUS_SLOTS] = { - 0x30000000, - 0x40000000, - 0x50000000, - 0x60000000, - 0x70000000, +static const unsigned long sbus_offsets_ss5[SBUS_SLOTS][5] = { + { 0, 0, 0x0, 0x20000000, 0x10000000,}, + { 1, 0, 0x0, 0x30000000, 0x10000000,}, + { 2, 0, 0x0, 0x40000000, 0x10000000,}, + { 3, 0, 0x0, 0x50000000, 0x10000000,}, + { 4, 0, 0x0, 0x60000000, 0x10000000,}, + { 5, 0, 0x0, 0x70000000, 0x10000000,}, };
-int ob_sbus_init(unsigned long base) +static const unsigned long sbus_offsets_ss10[SBUS_SLOTS][5] = { + { 0, 0, 0xe, 0x00000000, 0x10000000,}, + { 1, 0, 0xe, 0x10000000, 0x10000000,}, + { 2, 0, 0xe, 0x20000000, 0x10000000,}, + { 3, 0, 0xe, 0x30000000, 0x10000000,}, + [0xf] = { 0xf, 0, 0xe, 0xf0000000, 0x10000000,}, +}; + +static void +ob_add_sbus_range(const unsigned long *range, int notfirst) { + if (!notfirst) { + push_str("/iommu/sbus"); + fword("find-device"); + } + PUSH(range[0]); + fword("encode-int"); + if (notfirst) + fword("encode+"); + PUSH(range[1]); + fword("encode-int"); + fword("encode+"); + PUSH(range[2]); + fword("encode-int"); + fword("encode+"); + PUSH(range[3]); + fword("encode-int"); + fword("encode+"); + PUSH(range[4]); + fword("encode-int"); + fword("encode+"); +} + +static int +ob_sbus_init_ss5(unsigned long bus, unsigned long base) +{ unsigned int slot; + int notfirst = 0;
- ob_sbus_node_init(base); + for (slot = 0; slot < SBUS_SLOTS; slot++) { + if (sbus_offsets_ss5[slot][4] > 0) + ob_add_sbus_range(sbus_offsets_ss5[slot], notfirst++); + } + push_str("ranges"); + fword("property");
for (slot = 0; slot < SBUS_SLOTS; slot++) { - sbus_probe_slot(slot, sbus_offset[slot]); + if (sbus_offsets_ss5[slot][4] > 0) + sbus_probe_slot_ss5(slot, sbus_offsets_ss5[slot][3]); }
return 0; } + +static int +ob_sbus_init_ss10(unsigned long bus, unsigned long base) +{ + unsigned int slot; + int notfirst = 0; + + for (slot = 0; slot < SBUS_SLOTS; slot++) { + if (sbus_offsets_ss10[slot][4] > 0) + ob_add_sbus_range(sbus_offsets_ss10[slot], notfirst++); + } + push_str("ranges"); + fword("property"); + + for (slot = 0; slot < SBUS_SLOTS; slot++) { + if (sbus_offsets_ss10[slot][4] > 0) + sbus_probe_slot_ss10(slot, sbus_offsets_ss10[slot][3]); + } + + return 0; +} + +int ob_sbus_init(unsigned long bus, unsigned long base, int machine_id) +{ + ob_sbus_node_init(bus, base); + + switch (machine_id) { + case 0x72: + return ob_sbus_init_ss10(bus, base); + case 0x80: + return ob_sbus_init_ss5(bus, base); + default: + return -1; + } +}
Modified: openbios-devel/include/openbios/drivers.h =================================================================== --- openbios-devel/include/openbios/drivers.h 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/include/openbios/drivers.h 2007-04-09 12:35:41 UTC (rev 120) @@ -15,15 +15,17 @@ int ob_pci_init(void); #endif #ifdef CONFIG_DRIVER_SBUS -int ob_sbus_init(unsigned long base); +int ob_sbus_init(unsigned long bus, unsigned long base, int machine_id); #endif #ifdef CONFIG_DRIVER_IDE int ob_ide_init(void); #endif #ifdef CONFIG_DRIVER_ESP -int ob_esp_init(unsigned long base); +int ob_esp_init(unsigned int slot, unsigned long base, unsigned long offset); #endif #ifdef CONFIG_DRIVER_OBIO -int ob_obio_init(unsigned long slavio_base); +int ob_obio_init(unsigned long slavio_high, unsigned long slavio_base, + unsigned long fd_offset, unsigned long counter_offset, + unsigned long intr_offset); #endif
Modified: openbios-devel/include/sparc32/io.h =================================================================== --- openbios-devel/include/sparc32/io.h 2007-04-09 12:19:41 UTC (rev 119) +++ openbios-devel/include/sparc32/io.h 2007-04-09 12:35:41 UTC (rev 120) @@ -38,7 +38,7 @@ void *mem_zalloc(struct mem *t, int size, int align); int map_page(unsigned long va, unsigned long epa, int type); void *map_io(unsigned pa, int size); -void ob_init_mmu(unsigned long base); +void ob_init_mmu(unsigned long bus, unsigned long base); void init_mmu_swift(unsigned long base); void *dvma_alloc(int size, unsigned int *pphys);