SS10 support by blueswirl

git-svn-id: svn://coreboot.org/openbios/openbios-devel@120 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Stefan Reinauer
2007-04-09 12:35:41 +00:00
parent 1ebb8a3b50
commit d06b24d10f
12 changed files with 584 additions and 119 deletions

View File

@@ -17,10 +17,10 @@
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
#define KBD_BASE 0x71000004 static unsigned long kbd_base, serial_base;
#define SERIAL_BASE 0x71100004
#define CTRL(port) (SERIAL_BASE + (port) * 2 + 0) #define CTRL(port) (serial_base + (port) * 2 + 0)
#define DATA(port) (SERIAL_BASE + (port) * 2 + 2) #define DATA(port) (serial_base + (port) * 2 + 2)
/* Conversion routines to/from brg time constants from/to bits /* Conversion routines to/from brg time constants from/to bits
* per second. * per second.
@@ -98,7 +98,8 @@ static void uart_init_line(int port, unsigned long baud)
int uart_init(int port, unsigned long speed) 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; return -1;
} }
@@ -177,6 +178,11 @@ void tcx_init(unsigned long base)
console_init(); console_init();
} }
void kbd_init(unsigned long base)
{
kbd_base = base + 4;
}
static const unsigned char sunkbd_keycode[128] = { 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, 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 @@ static int shiftstate;
int int
keyboard_dataready(void) keyboard_dataready(void)
{ {
return ((inb(KBD_BASE) & 1) == 1); return ((inb(kbd_base) & 1) == 1);
} }
unsigned char unsigned char
@@ -221,7 +227,7 @@ keyboard_readdata(void)
while (!keyboard_dataready()) { } while (!keyboard_dataready()) { }
do { do {
ch = inb(KBD_BASE + 2) & 0xff; ch = inb(kbd_base + 2) & 0xff;
if (ch == 99) if (ch == 99)
shiftstate |= 1; shiftstate |= 1;
else if (ch == 110) else if (ch == 110)

View File

@@ -14,6 +14,9 @@
#define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */ #define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */
#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */ #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 */ #define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
.globl entry, _entry .globl entry, _entry
@@ -31,9 +34,30 @@ entry:
* Main context is statically defined in C. * 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 ! Check if this not the first SMP CPU, if so, bypass PROM entirely
set PHYS_JJ_EEPROM + 0x2E, %g1 set PHYS_JJ_EEPROM + 0x2E, %g1
lduba [%g1] ASI_M_BYPASS, %g2 lduba [%g1] ASI_M_BYPASS, %g2
set PHYS_JJ_EEPROM + 0x30, %g1
tst %g2 tst %g2
bz first_cpu bz first_cpu
nop nop
@@ -58,11 +82,64 @@ entry:
set 1, %g1 set 1, %g1
jmp %g2 ! jump to kernel jmp %g2 ! jump to kernel
sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu 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: first_cpu:
/* Create temporary page tables and map the ROM area to end of /* Create temporary page tables and map the ROM area to end of
RAM. This will be done properly in iommu.c later. */ RAM. This will be done properly in iommu.c later. */
set PHYS_JJ_EEPROM + 0x30, %g1
lda [%g1] ASI_M_BYPASS, %g1 lda [%g1] ASI_M_BYPASS, %g1
set _end, %g3 set _end, %g3
set 0xfff, %g2 set 0xfff, %g2
@@ -213,6 +290,10 @@ first_cpu:
sub %g1, %g7, %g7 sub %g1, %g7, %g7
set va_shift, %g1 set va_shift, %g1
st %g7, [%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. */ /* Finally, turn on traps so that we can call c-code. */
rd %psr, %g3 rd %psr, %g3

View File

@@ -19,12 +19,60 @@
void boot(void); void boot(void);
void ob_ide_init(void); void ob_ide_init(void);
void tcx_init(unsigned long base); void tcx_init(unsigned long base);
void kbd_init(unsigned long base);
#define IOMMU_BASE 0x10000000 /* First page of sun4m IOMMU */ int qemu_machine_type;
#define SBUS_BASE 0x10001000
#define SLAVIO_BASE 0x71000000
#define TCX_BASE 0x50000000
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 unsigned char intdict[256 * 1024];
static void init_memory(void) static void init_memory(void)
@@ -48,15 +96,16 @@ arch_init( void )
modules_init(); modules_init();
#ifdef CONFIG_DRIVER_SBUS #ifdef CONFIG_DRIVER_SBUS
ob_init_mmu(IOMMU_BASE); ob_init_mmu(hwdef->iommu_high, hwdef->iommu_base);
ob_sbus_init(SBUS_BASE); ob_sbus_init(hwdef->iommu_high, hwdef->iommu_base + 0x1000, hwdef->machine_id);
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO #ifdef CONFIG_DEBUG_CONSOLE_VIDEO
init_video(); init_video();
#endif #endif
#endif #endif
#ifdef CONFIG_DRIVER_OBIO #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(); nvram_init();
#endif #endif
device_end(); device_end();
@@ -68,17 +117,29 @@ int openbios(void)
{ {
extern struct sys_info sys_info; extern struct sys_info sys_info;
extern struct mem cmem; 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); mem_init(&cmem, (char *) &_vmem, (char *)&_evmem);
#ifdef CONFIG_DRIVER_SBUS #ifdef CONFIG_DRIVER_SBUS
init_mmu_swift(IOMMU_BASE); init_mmu_swift(hwdef->iommu_base);
#endif #endif
#ifdef CONFIG_DEBUG_CONSOLE #ifdef CONFIG_DEBUG_CONSOLE
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL #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 #endif
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO #ifdef CONFIG_DEBUG_CONSOLE_VIDEO
tcx_init(TCX_BASE); tcx_init(hwdef->tcx_base);
kbd_init(hwdef->ms_kb_base);
#endif #endif
/* Clear the screen. */ /* Clear the screen. */
cls(); cls();

View File

@@ -3,10 +3,7 @@
2 encode-int " #address-cells" property 2 encode-int " #address-cells" property
1 encode-int " #size-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 " sun4m" encode-string " compatible" property
" SUNW,501-3059" encode-string " model" property
h# 0a21fe80 encode-int " clock-frequency" property h# 0a21fe80 encode-int " clock-frequency" property
: encode-unit encode-unit-sbus ; : encode-unit encode-unit-sbus ;
@@ -36,8 +33,6 @@ new-device
1 encode-int " #size-cells" property 1 encode-int " #size-cells" property
h# 1000 encode-int " page-size" property h# 1000 encode-int " page-size" property
0 encode-int " cache-coherence?" 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 external
: open ( cr ." opening iommu" cr) true ; : open ( cr ." opening iommu" cr) true ;
: close ; : close ;
@@ -54,12 +49,6 @@ new-device
h# 01443fd0 encode-int " clock-frequency" property h# 01443fd0 encode-int " clock-frequency" property
h# 1c encode-int " slot-address-bits" property h# 1c encode-int " slot-address-bits" property
h# 3f encode-int " burst-sizes" 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 external
: open ( cr ." opening SBus" cr) true ; : open ( cr ." opening SBus" cr) true ;
: close ; : close ;
@@ -103,20 +92,6 @@ new-device
" no" encode-string " tcx-8-bit" property " no" encode-string " tcx-8-bit" property
5 encode-int 0 encode-int encode+ " intr" property 5 encode-int 0 encode-int encode+ " intr" property
5 encode-int " interrupts" 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 finish-device
" /iommu/sbus" find-device " /iommu/sbus" find-device
@@ -130,7 +105,6 @@ finish-device
" /iommu/sbus" find-device " /iommu/sbus" find-device
new-device new-device
" ledma" device-name " 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 h# 3f encode-int " burst-sizes" property
external external
: encode-unit encode-unit-sbus ; : encode-unit encode-unit-sbus ;
@@ -141,7 +115,6 @@ finish-device
new-device new-device
" le" device-name " le" device-name
" network" device-type " 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# 7 encode-int " busmaster-regval" property
h# 26 encode-int 0 encode-int encode+ " intr" property h# 26 encode-int 0 encode-int encode+ " intr" property
finish-device finish-device
@@ -160,8 +133,6 @@ new-device
" hierarchical" device-type " hierarchical" device-type
2 encode-int " #address-cells" property 2 encode-int " #address-cells" property
1 encode-int " #size-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 external
: open ( cr ." opening obio" cr) true ; : open ( cr ." opening obio" cr) true ;
: close ; : close ;

View File

@@ -9,7 +9,8 @@ case "$1" in
ppc|powerpc|mpc107|osx|darwin) ARCH=ppc ;; ppc|powerpc|mpc107|osx|darwin) ARCH=ppc ;;
esac 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/arm.*/arm/ -e s/sa110/arm/ -e s/x86_64/amd64/ \
-e "s/Power Macintosh/ppc/"` -e "s/Power Macintosh/ppc/"`

View File

@@ -3,31 +3,33 @@
host=$1 host=$1
target=$2 target=$2
if test "$host" = "sparc"; then if test "$host" = "powerpc" -o "$host" = "mips" -o "$host" = "s390" \
host="sparc32" -o "$host" = "sparc32" -o "$host" = "sparc64" \
fi -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" hostbigendian="yes"
else else
hostbigendian="no" hostbigendian="no"
fi fi
# host long bits test # 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" hostlongbits="64"
else else
hostlongbits="32" hostlongbits="32"
fi 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" targetbigendian="yes"
else else
targetbigendian="no" targetbigendian="no"
fi fi
# target long bits test # 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" targetlongbits="64"
else else
targetlongbits="32" targetlongbits="32"

View File

@@ -25,8 +25,8 @@
#include "asm/dma.h" #include "asm/dma.h"
#include "esp.h" #include "esp.h"
#define MACIO_ESPDMA 0x08400000 /* ESP DMA controller */ #define MACIO_ESPDMA 0x00400000 /* ESP DMA controller */
#define MACIO_ESP 0x08800000 /* ESP SCSI */ #define MACIO_ESP 0x00800000 /* ESP SCSI */
#define BUFSIZE 4096 #define BUFSIZE 4096
@@ -321,9 +321,10 @@ NODE_METHODS(ob_sd) = {
static int 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) { if (espdma->regs == 0) {
DPRINTF("espdma_init: cannot map registers\n"); DPRINTF("espdma_init: cannot map registers\n");
@@ -369,9 +370,9 @@ espdma_init(unsigned long base, struct esp_dma *espdma)
fword("find-device"); fword("find-device");
/* set reg */ /* set reg */
PUSH(4); PUSH(slot);
fword("encode-int"); fword("encode-int");
PUSH(MACIO_ESPDMA); PUSH(offset + MACIO_ESPDMA);
fword("encode-int"); fword("encode-int");
fword("encode+"); fword("encode+");
PUSH(0x00000010); PUSH(0x00000010);
@@ -395,18 +396,6 @@ ob_esp_initialize(__attribute__((unused)) esp_private_t **esp)
push_str("scsi"); push_str("scsi");
fword("device-type"); 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); PUSH(0x24);
fword("encode-int"); fword("encode-int");
PUSH(0); PUSH(0);
@@ -448,7 +437,7 @@ add_alias(const char *device, const char *alias)
} }
int 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; int id, diskcount = 0, cdcount = 0, *counter_ptr;
char nodebuff[256], aliasbuff[256]; char nodebuff[256], aliasbuff[256];
@@ -464,11 +453,11 @@ ob_esp_init(unsigned long base)
global_esp = esp; global_esp = esp;
if (espdma_init(base, &esp->espdma) != 0) { if (espdma_init(slot, base, offset, &esp->espdma) != 0) {
return -1; return -1;
} }
/* Get the IO region */ /* 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) { if (esp->ll == 0) {
DPRINTF("Can't map ESP registers\n"); DPRINTF("Can't map ESP registers\n");
return -1; return -1;
@@ -501,6 +490,19 @@ ob_esp_init(unsigned long base)
REGISTER_NAMED_NODE(ob_esp, "/iommu/sbus/espdma/esp"); REGISTER_NAMED_NODE(ob_esp, "/iommu/sbus/espdma/esp");
device_end(); 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++) { for (id = 0; id < 8; id++) {
if (!esp->sd[id].present) if (!esp->sd[id].present)

View File

@@ -199,7 +199,7 @@ map_io(unsigned pa, int size)
} }
void void
ob_init_mmu(unsigned long base) ob_init_mmu(unsigned long bus, unsigned long base)
{ {
extern unsigned int qemu_mem_size; extern unsigned int qemu_mem_size;
@@ -231,7 +231,7 @@ ob_init_mmu(unsigned long base)
push_str("/virtual-memory"); push_str("/virtual-memory");
fword("find-device"); fword("find-device");
PUSH(0); PUSH(bus);
fword("encode-int"); fword("encode-int");
PUSH(base); PUSH(base);
fword("encode-int"); fword("encode-int");
@@ -269,6 +269,17 @@ ob_init_mmu(unsigned long base)
fword("encode-int"); fword("encode-int");
push_str("address"); push_str("address");
fword("property"); 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");
} }

View File

@@ -285,7 +285,7 @@ ob_zs_init(unsigned long base, unsigned long offset, int intr, int slave, int ke
} }
} }
static char *nvram; static unsigned char *nvram;
struct qemu_nvram_v1 nv_info; struct qemu_nvram_v1 nv_info;
void void
@@ -306,6 +306,39 @@ arch_nvram_size(void)
return NVRAM_SIZE; 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 static void
ob_nvram_init(unsigned long base, unsigned long offset) ob_nvram_init(unsigned long base, unsigned long offset)
{ {
@@ -317,10 +350,11 @@ ob_nvram_init(unsigned long base, unsigned long offset)
extern char obp_stdin, obp_stdout; extern char obp_stdin, obp_stdout;
extern const char *obp_stdin_path, *obp_stdout_path; extern const char *obp_stdin_path, *obp_stdout_path;
const char *stdin, *stdout; const char *stdin, *stdout, *cpuname;
unsigned int i; unsigned int i;
char nographic; char nographic;
uint32_t size; uint32_t size;
unsigned int machine_id;
ob_new_obio_device("eeprom", NULL); ob_new_obio_device("eeprom", NULL);
@@ -332,12 +366,14 @@ ob_nvram_init(unsigned long base, unsigned long offset)
fword("property"); fword("property");
memcpy(&nv_info, nvram, sizeof(nv_info)); memcpy(&nv_info, nvram, sizeof(nv_info));
machine_id = (unsigned int)nvram[0x1fd9] & 0xff;
printk("Nvram id %s, version %d\n", nv_info.id_string, nv_info.version); 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) { if (strcmp(nv_info.id_string, "QEMU_BIOS") || nv_info.version != 1) {
printk("Unknown nvram, freezing!\n"); printk("Unknown nvram, freezing!\n");
for (;;); for (;;);
} }
kernel_image = nv_info.kernel_image; kernel_image = nv_info.kernel_image;
kernel_size = nv_info.kernel_size; kernel_size = nv_info.kernel_size;
size = nv_info.cmdline_size; size = nv_info.cmdline_size;
@@ -366,6 +402,33 @@ ob_nvram_init(unsigned long base, unsigned long offset)
push_str("idprom"); push_str("idprom");
fword("property"); 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 // Add cpus
printk("CPUs: %x\n", nv_info.smp_cpus); printk("CPUs: %x\n", nv_info.smp_cpus);
for (i = 0; i < (unsigned int)nv_info.smp_cpus; i++) { for (i = 0; i < (unsigned int)nv_info.smp_cpus; i++) {
@@ -373,8 +436,9 @@ ob_nvram_init(unsigned long base, unsigned long offset)
fword("find-device"); fword("find-device");
fword("new-device"); fword("new-device");
push_str("FMI,MB86904"); cpuname = id_cpu();
push_str(cpuname);
fword("device-name"); fword("device-name");
push_str("cpu"); push_str("cpu");
@@ -713,7 +777,7 @@ ob_obio_initialize(__attribute__((unused))int *idx)
} }
static void static void
ob_set_obio_ranges(unsigned long base) ob_set_obio_ranges(unsigned long high, unsigned long base)
{ {
push_str("/obio"); push_str("/obio");
fword("find-device"); fword("find-device");
@@ -722,7 +786,7 @@ ob_set_obio_ranges(unsigned long base)
PUSH(0); PUSH(0);
fword("encode-int"); fword("encode-int");
fword("encode+"); fword("encode+");
PUSH(0); PUSH(high);
fword("encode-int"); fword("encode-int");
fword("encode+"); fword("encode+");
PUSH(base); PUSH(base);
@@ -758,7 +822,9 @@ NODE_METHODS(ob_obio) = {
int 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 // All devices were integrated to NCR89C105, see
@@ -768,8 +834,8 @@ ob_obio_init(unsigned long slavio_base)
#if 0 // XXX #if 0 // XXX
REGISTER_NAMED_NODE(ob_obio, "/obio"); REGISTER_NAMED_NODE(ob_obio, "/obio");
device_end(); device_end();
ob_set_obio_ranges(slavio_base);
#endif #endif
ob_set_obio_ranges(slavio_high, slavio_base);
// Zilog Z8530 serial ports, see http://www.zilog.com // Zilog Z8530 serial ports, see http://www.zilog.com
// Must be before zs@0,0 or Linux won't boot // Must be before zs@0,0 or Linux won't boot
@@ -781,7 +847,7 @@ ob_obio_init(unsigned long slavio_base)
ob_nvram_init(slavio_base, SLAVIO_NVRAM); ob_nvram_init(slavio_base, SLAVIO_NVRAM);
// 82078 FDC // 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); ob_sconfig_init(slavio_base, SLAVIO_SCONFIG);
@@ -789,9 +855,9 @@ ob_obio_init(unsigned long slavio_base)
ob_power_init(slavio_base, SLAVIO_POWER, POWER_INTR); 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; return 0;
} }

View File

@@ -19,17 +19,17 @@
#include "openbios/drivers.h" #include "openbios/drivers.h"
#define SBUS_REGS 0x28 #define SBUS_REGS 0x28
#define SBUS_SLOTS 5 #define SBUS_SLOTS 16
static void static void
ob_sbus_node_init(unsigned long base) ob_sbus_node_init(unsigned long bus, unsigned long base)
{ {
void *regs; void *regs;
push_str("/iommu/sbus"); push_str("/iommu/sbus");
fword("find-device"); fword("find-device");
PUSH(0); PUSH(bus);
fword("encode-int"); fword("encode-int");
PUSH(base); PUSH(base);
fword("encode-int"); fword("encode-int");
@@ -48,7 +48,176 @@ ob_sbus_node_init(unsigned long base)
} }
static void 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 // All devices were integrated to NCR89C100, see
// http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt // http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
@@ -56,11 +225,11 @@ ob_macio_init(unsigned int slot, unsigned long base)
// NCR 53c9x, aka ESP. See // NCR 53c9x, aka ESP. See
// http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt // http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
#ifdef CONFIG_DRIVER_ESP #ifdef CONFIG_DRIVER_ESP
ob_esp_init(base); ob_esp_init(slot, base, offset);
#endif #endif
// NCR 92C990, Am7990, Lance. See http://www.amd.com // NCR 92C990, Am7990, Lance. See http://www.amd.com
//ob_le_init(base); ob_le_init(slot, base, offset);
// Parallel port // Parallel port
//ob_bpp_init(base); //ob_bpp_init(base);
@@ -70,18 +239,34 @@ ob_macio_init(unsigned int slot, unsigned long base)
} }
static void 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 3: // SUNW,tcx
ob_tcx_init(slot, base);
break;
case 4: // SUNW,CS4231
//ob_cs4231_init(slot, base);
break;
case 5: // MACIO: le, esp, bpp, power-management
ob_macio_init(slot, base, 0x08000000);
break;
default:
break;
}
}
static void
sbus_probe_slot_ss10(unsigned int slot, unsigned long base)
{ {
// OpenBIOS and Qemu don't know how to do Sbus probing // OpenBIOS and Qemu don't know how to do Sbus probing
switch(slot) { switch(slot) {
case 2: // SUNW,tcx case 2: // SUNW,tcx
//ob_tcx_init(slot, base); ob_tcx_init(slot, base);
break; break;
case 3: // SUNW,CS4231 case 0xf: // le, esp, bpp, power-management
//ob_cs4231_init(slot, base); ob_macio_init(slot, base, 0);
break;
case 4: // MACIO: le, esp, bpp, power-management
ob_macio_init(slot, base);
break; break;
default: default:
break; break;
@@ -113,23 +298,100 @@ NODE_METHODS(ob_sbus_node) = {
{ "close", ob_sbus_close }, { "close", ob_sbus_close },
}; };
static const unsigned long sbus_offset[SBUS_SLOTS] = { static const unsigned long sbus_offsets_ss5[SBUS_SLOTS][5] = {
0x30000000, { 0, 0, 0x0, 0x20000000, 0x10000000,},
0x40000000, { 1, 0, 0x0, 0x30000000, 0x10000000,},
0x50000000, { 2, 0, 0x0, 0x40000000, 0x10000000,},
0x60000000, { 3, 0, 0x0, 0x50000000, 0x10000000,},
0x70000000, { 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; unsigned int slot;
int notfirst = 0;
ob_sbus_node_init(base);
for (slot = 0; slot < SBUS_SLOTS; slot++) { for (slot = 0; slot < SBUS_SLOTS; slot++) {
sbus_probe_slot(slot, sbus_offset[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++) {
if (sbus_offsets_ss5[slot][4] > 0)
sbus_probe_slot_ss5(slot, sbus_offsets_ss5[slot][3]);
} }
return 0; 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;
}
}

View File

@@ -15,15 +15,17 @@
int ob_pci_init(void); int ob_pci_init(void);
#endif #endif
#ifdef CONFIG_DRIVER_SBUS #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 #endif
#ifdef CONFIG_DRIVER_IDE #ifdef CONFIG_DRIVER_IDE
int ob_ide_init(void); int ob_ide_init(void);
#endif #endif
#ifdef CONFIG_DRIVER_ESP #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 #endif
#ifdef CONFIG_DRIVER_OBIO #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 #endif

View File

@@ -38,7 +38,7 @@ void *mem_alloc(struct mem *t, int size, int align);
void *mem_zalloc(struct mem *t, int size, int align); void *mem_zalloc(struct mem *t, int size, int align);
int map_page(unsigned long va, unsigned long epa, int type); int map_page(unsigned long va, unsigned long epa, int type);
void *map_io(unsigned pa, int size); 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 init_mmu_swift(unsigned long base);
void *dvma_alloc(int size, unsigned int *pphys); void *dvma_alloc(int size, unsigned int *pphys);