Author: blueswirl
Date: 2008-09-18 20:41:26 +0200 (Thu, 18 Sep 2008)
New Revision: 237
Added:
openbios-devel/include/openbios/fw_cfg.h
Modified:
openbios-devel/arch/sparc32/entry.S
openbios-devel/arch/sparc32/openbios.c
openbios-devel/arch/sparc64/entry.S
openbios-devel/arch/sparc64/openbios.c
openbios-devel/drivers/obio.c
openbios-devel/drivers/obio.h
openbios-devel/drivers/sbus.c
Log:
Use the firmware device introduced in Qemu SVN r5256
Modified: openbios-devel/arch/sparc32/entry.S
===================================================================
--- openbios-devel/arch/sparc32/entry.S 2008-09-11 19:33:02 UTC (rev 236)
+++ openbios-devel/arch/sparc32/entry.S 2008-09-18 18:41:26 UTC (rev 237)
@@ -12,7 +12,12 @@
#include "asm/crs.h"
#define __ASSEMBLY__
#include "openbios/firmware_abi.h"
+#define NO_QEMU_PROTOS
+#include "openbios/fw_cfg.h"
+#define CFG_ADDR 0x00000510
+#define CFG_ASI 0x2d
+
#define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */
#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */
@@ -44,41 +49,84 @@
* 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
+ ! Check signature "QEMU"
+ set CFG_ADDR, %g5
+ mov FW_CFG_SIGNATURE, %g2
+ stha %g2, [%g5] CFG_ASI
+ add %g5, 2, %g5
+ lduba [%g5] CFG_ASI, %g2
cmp %g2, 'Q'
- bne ss10
- inc %g1
- lduba [%g1] ASI_M_BYPASS, %g2
+ bne bad_conf
+ nop
+ lduba [%g5] CFG_ASI, %g2
cmp %g2, 'E'
- bne ss10
- inc %g1
- lduba [%g1] ASI_M_BYPASS, %g2
+ bne bad_conf
+ nop
+ lduba [%g5] CFG_ASI, %g2
cmp %g2, 'M'
- bne ss10
- inc %g1
- lduba [%g1] ASI_M_BYPASS, %g2
+ bne bad_conf
+ nop
+ lduba [%g5] CFG_ASI, %g2
cmp %g2, 'U'
- bne ss10
+ bne bad_conf
+ nop
+ ! Get memory size from configuration device
+ ! NB: little endian format
+ mov FW_CFG_RAM_SIZE, %g2
+ sub %g5, 2, %g5
+ stha %g2, [%g5] CFG_ASI
+ add %g5, 2, %g5
+ lduba [%g5] CFG_ASI, %g4
+
+ lduba [%g5] CFG_ASI, %g3
+ sll %g3, 8, %g3
+ or %g3, %g4, %g4
+
+ lduba [%g5] CFG_ASI, %g3
+ sll %g3, 16, %g3
+ or %g3, %g4, %g4
+
+ lduba [%g5] CFG_ASI, %g3
+ sll %g3, 24, %g3
+ or %g3, %g4, %g1
+ ! %g1 contains end of memory
+
+ ! Get machine ID from configuration device
+ mov FW_CFG_MACHINE_ID, %g2
+ sub %g5, 2, %g5
+ stha %g2, [%g5] CFG_ASI
+ add %g5, 2, %g5
+ lduba [%g5] CFG_ASI, %g4
+
+ lduba [%g5] CFG_ASI, %g3
+ sll %g3, 8, %g3
+ or %g3, %g4, %g4
+ mov %g4, %y
+
+ cmp %g4, 96
+ bgeu ss1000
+ cmp %g4, 64
+ bgeu ss10
+ cmp %g4, 32
+ blu ss2
+ nop
+
! Ok, this is SS-5
- mov 0x80, %y
! Find architecture specific part
- set PHYS_JJ_EEPROM + OHW_ARCH_PTR, %g1
- lduha [%g1] ASI_M_BYPASS, %g2
- set PHYS_JJ_EEPROM, %g1
- add %g1, %g2, %g3
+ set PHYS_JJ_EEPROM + OHW_ARCH_PTR, %g5
+ lduha [%g5] ASI_M_BYPASS, %g2
+ set PHYS_JJ_EEPROM, %g5
+ add %g5, %g2, %g3
! Check if this not the first SMP CPU, if so, bypass PROM entirely
- add %g3, SPARC_SMP_VALID, %g1
- lduba [%g1] ASI_M_BYPASS, %g2
- stba %g0, [%g1] ASI_M_BYPASS
- set PHYS_JJ_EEPROM + OHW_RAM_SIZE, %g1
- ldda [%g1] ASI_M_BYPASS, %g0
+ add %g3, SPARC_SMP_VALID, %g5
+ lduba [%g5] ASI_M_BYPASS, %g2
+ stba %g0, [%g5] ASI_M_BYPASS
tst %g2
bz first_cpu
nop
+ ! SMP init, jump to user specified address
set PHYS_JJ_INTR0 + 0x04, %g1
sll %g2, 12, %g2
add %g1, %g2, %g2
@@ -104,41 +152,21 @@
sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
ss10:
- set PHYS_SS10_EEPROM, %g1
- lduba [%g1] ASI_M_CTL, %g2
- cmp %g2, 'Q'
- bne ss2
- inc %g1
- lduba [%g1] ASI_M_CTL, %g2
- cmp %g2, 'E'
- bne ss2
- inc %g1
- lduba [%g1] ASI_M_CTL, %g2
- cmp %g2, 'M'
- bne ss2
- inc %g1
- lduba [%g1] ASI_M_CTL, %g2
- cmp %g2, 'U'
- bne ss2
-
! Ok, this is SS-10 or SS-600MP
- set PHYS_SS10_EEPROM + SPARC_MACHINE_ID, %g1
- lduba [%g1] ASI_M_CTL, %g2
- mov %g2, %y
! Find architecture specific part
- set PHYS_SS10_EEPROM + OHW_ARCH_PTR, %g1
- lduha [%g1] ASI_M_CTL, %g2
- set PHYS_SS10_EEPROM, %g1
- add %g1, %g2, %g3
+ set PHYS_SS10_EEPROM + OHW_ARCH_PTR, %g5
+ lduha [%g5] ASI_M_CTL, %g2
+ set PHYS_SS10_EEPROM, %g5
+ add %g5, %g2, %g3
! Check if this not the first SMP CPU, if so, bypass PROM entirely
- add %g3, SPARC_SMP_VALID, %g1
- lduba [%g1] ASI_M_CTL, %g2
- stba %g0, [%g1] ASI_M_CTL
- set PHYS_SS10_EEPROM + OHW_RAM_SIZE, %g1
- ldda [%g1] ASI_M_CTL, %g0
+ add %g3, SPARC_SMP_VALID, %g5
+ lduba [%g5] ASI_M_CTL, %g2
+ stba %g0, [%g5] ASI_M_CTL
tst %g2
bz first_cpu
nop
+
+ ! SMP init, jump to user specified address
set PHYS_SS10_INTR0 + 0x04, %g1
sll %g2, 12, %g2
add %g1, %g2, %g2
@@ -164,46 +192,12 @@
sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
ss2:
- set PHYS_SS2_EEPROM, %g1
- lduba [%g1] ASI_M_BYPASS, %g2
- cmp %g2, 'Q'
- bne ss1000
- inc %g1
- lduba [%g1] ASI_M_BYPASS, %g2
- cmp %g2, 'E'
- bne ss1000
- inc %g1
- lduba [%g1] ASI_M_BYPASS, %g2
- cmp %g2, 'M'
- bne ss1000
- inc %g1
- lduba [%g1] ASI_M_BYPASS, %g2
- cmp %g2, 'U'
- bne ss1000
-
! Ok, this is SS-2
set ss2_error, %o2
b ss2_ss1000_halt
nop
ss1000:
- set PHYS_SS1000_EEPROM, %g1
- lduba [%g1] ASI_M_CTL, %g2
- cmp %g2, 'Q'
- bne bad_nvram
- inc %g1
- lduba [%g1] ASI_M_CTL, %g2
- cmp %g2, 'E'
- bne bad_nvram
- inc %g1
- lduba [%g1] ASI_M_CTL, %g2
- cmp %g2, 'M'
- bne bad_nvram
- inc %g1
- lduba [%g1] ASI_M_CTL, %g2
- cmp %g2, 'U'
- bne bad_nvram
-
! Ok, this is SS-1000 or SS-2000
set ss1000_error, %o2
b ss2_ss1000_halt
@@ -408,7 +402,7 @@
stba %o3, [%o1] ASI_M_CTL
b 1b
inc %o2
-bad_nvram:
+bad_conf:
2: b 2b
nop
Modified: openbios-devel/arch/sparc32/openbios.c
===================================================================
--- openbios-devel/arch/sparc32/openbios.c 2008-09-11 19:33:02 UTC (rev 236)
+++ openbios-devel/arch/sparc32/openbios.c 2008-09-18 18:41:26 UTC (rev 237)
@@ -27,7 +27,7 @@
unsigned long aux1_offset, aux2_offset;
uint64_t dma_base, esp_base, le_base;
uint64_t tcx_base;
- int machine_id;
+ int machine_id_low, machine_id_high;
};
static const struct hwdef hwdefs[] = {
@@ -47,7 +47,8 @@
.dma_base = 0x78400000,
.esp_base = 0x78800000,
.le_base = 0x78c00000,
- .machine_id = 0x80,
+ .machine_id_low = 32,
+ .machine_id_high = 63,
},
/* SS-10 */
{
@@ -65,7 +66,8 @@
.dma_base = 0xef0400000ULL,
.esp_base = 0xef0800000ULL,
.le_base = 0xef0c00000ULL,
- .machine_id = 0x72,
+ .machine_id_low = 64,
+ .machine_id_high = 65,
},
/* SS-600MP */
{
@@ -83,7 +85,8 @@
.dma_base = 0xef0081000ULL,
.esp_base = 0xef0080000ULL,
.le_base = 0xef0060000ULL,
- .machine_id = 0x71,
+ .machine_id_low = 66,
+ .machine_id_high = 66,
},
};
@@ -121,7 +124,7 @@
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO
init_video();
#endif
- ob_sbus_init(hwdef->iommu_base + 0x1000ULL, hwdef->machine_id);
+ ob_sbus_init(hwdef->iommu_base + 0x1000ULL, qemu_machine_type);
#endif
device_end();
@@ -133,7 +136,8 @@
unsigned int i;
for (i = 0; i < sizeof(hwdefs) / sizeof(struct hwdef); i++) {
- if (hwdefs[i].machine_id == qemu_machine_type) {
+ if (hwdefs[i].machine_id_low <= qemu_machine_type &&
+ hwdefs[i].machine_id_high >= qemu_machine_type) {
hwdef = &hwdefs[i];
break;
}
Modified: openbios-devel/arch/sparc64/entry.S
===================================================================
--- openbios-devel/arch/sparc64/entry.S 2008-09-11 19:33:02 UTC (rev 236)
+++ openbios-devel/arch/sparc64/entry.S 2008-09-18 18:41:26 UTC (rev 237)
@@ -11,10 +11,11 @@
#include "asi.h"
#include "pstate.h"
#include "lsu.h"
-#define __ASSEMBLY__
-#include "openbios/firmware_abi.h"
+#define NO_QEMU_PROTOS
+#include "openbios/fw_cfg.h"
#define PROM_ADDR 0x1fff0000000
+#define CFG_ADDR 0x1fe02000510
.globl entry, _entry
@@ -52,59 +53,65 @@
! Disable I/D MMUs and caches
stxa %g0, [%g0] ASI_LSU_CONTROL
- ! Get memory size from NVRAM
- setx 0x1fe02000074, %g2, %g5
- mov OHW_RAM_SIZE, %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
+ ! Check signature "QEMU"
+ setx CFG_ADDR, %g2, %g5
+ mov FW_CFG_SIGNATURE, %g2
+ stha %g2, [%g5] ASI_PHYS_BYPASS_EC_E
+ inc %g5
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2
+ cmp %g2, 'Q'
+ bne bad_conf
+ nop
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2
+ cmp %g2, 'E'
+ bne bad_conf
+ nop
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2
+ cmp %g2, 'M'
+ bne bad_conf
+ nop
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2
+ cmp %g2, 'U'
+ bne bad_conf
+ nop
- sll %g4, 8, %g4
- inc %g2
- stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E
- lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3
+ ! Get memory size from configuration device
+ ! NB: little endian format
+ mov FW_CFG_RAM_SIZE, %g2
+ dec %g5
+ stha %g2, [%g5] ASI_PHYS_BYPASS_EC_E
+ inc %g5
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g4
+
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+ sllx %g3, 8, %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
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+ sllx %g3, 16, %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
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+ sllx %g3, 24, %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
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+ sllx %g3, 32, %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
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+ sllx %g3, 40, %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
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+ sllx %g3, 48, %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
+ lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+ sllx %g3, 56, %g3
or %g3, %g4, %g1
- ! %g1 contains end of memory
+ ! %g1 contains end of memory
-
setx _end, %g7, %g3
set 0xffff, %g2
add %g3, %g2, %g3
@@ -301,8 +308,7 @@
/* We get here when the main context switches back to
* the boot context.
- * Return to previous bootloader.
*/
- ret
+bad_conf:
+ b bad_conf
nop
-
Modified: openbios-devel/arch/sparc64/openbios.c
===================================================================
--- openbios-devel/arch/sparc64/openbios.c 2008-09-11 19:33:02 UTC (rev 236)
+++ openbios-devel/arch/sparc64/openbios.c 2008-09-18 18:41:26 UTC (rev 237)
@@ -24,7 +24,12 @@
#include "asi.h"
#include "spitfire.h"
#include "libc/vsprintf.h"
+#define NO_QEMU_PROTOS
+#include "openbios/fw_cfg.h"
+#define BIOS_CFG_CMD 0x510
+#define BIOS_CFG_DATA 0x511
+
#define REGISTER_NAMED_NODE( name, path ) do { \
bind_new_node( name##_flags_, name##_size_, \
path, name##_m, sizeof(name##_m)/sizeof(method_t)); \
@@ -67,6 +72,8 @@
#define PAGE_MASK_64K (64 * 1024 - 1)
#define PAGE_MASK_8K (8 * 1024 - 1)
+#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+
static void
mmu_open(void)
{
@@ -474,6 +481,8 @@
for (;;);
}
+static uint8_t qemu_uuid[16];
+
void arch_nvram_get(char *data)
{
unsigned short i;
@@ -481,6 +490,9 @@
uint32_t size;
const struct cpudef *cpu;
const char *bootpath;
+ char buf[256];
+ uint32_t temp;
+ uint64_t ram_size;
for (i = 0; i < sizeof(ohwcfg_v3_t); i++) {
outb(i & 0xff, 0x74);
@@ -488,15 +500,21 @@
*nvptr++ = inb(0x77);
}
- printk("Nvram id %s, version %d\n", nv_info.struct_ident,
- nv_info.struct_version);
- if (strcmp(nv_info.struct_ident, "QEMU_BIOS") ||
- nv_info.struct_version != 3 ||
- OHW_compute_crc(&nv_info, 0x00, 0xF8) != nv_info.crc) {
- printk("Unknown nvram, freezing!\n");
- for (;;);
- }
+ outw(__cpu_to_le16(FW_CFG_SIGNATURE), BIOS_CFG_CMD);
+ for (i = 0; i < 4; i++)
+ buf[i] = inb(BIOS_CFG_DATA);
+ buf[4] = '\0';
+
+ printk("Configuration device id %s", buf);
+
+ outw(__cpu_to_le16(FW_CFG_ID), BIOS_CFG_CMD);
+ for (i = 0; i < 4; i++)
+ buf[i] = inb(BIOS_CFG_DATA);
+
+ temp = __le32_to_cpu(*(uint32_t *)buf);
+ printk(" version %d\n", temp);
+
kernel_image = nv_info.kernel_image;
kernel_size = nv_info.kernel_size;
size = nv_info.cmdline_size;
@@ -518,16 +536,40 @@
data[i] = inb(0x77);
}
- printk("CPUs: %x", nv_info.nb_cpus);
+ outw(__cpu_to_le16(FW_CFG_NB_CPUS), BIOS_CFG_CMD);
+ for (i = 0; i < 4; i++)
+ buf[i] = inb(BIOS_CFG_DATA);
+
+ temp = __le32_to_cpu(*(uint32_t *)buf);
+
+ printk("CPUs: %x", temp);
+
cpu = id_cpu();
//cpu->initfn();
cpu_generic_init(cpu);
printk(" x %s\n", cpu->name);
- // Add /idprom
+ // Add /uuid
+ outw(__cpu_to_le16(FW_CFG_UUID), BIOS_CFG_CMD);
+ for (i = 0; i < 16; i++)
+ qemu_uuid[i] = inb(BIOS_CFG_DATA);
+
+ printk("UUID: " UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], qemu_uuid[2],
+ qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], qemu_uuid[6],
+ qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], qemu_uuid[10],
+ qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], qemu_uuid[14],
+ qemu_uuid[15]);
+
push_str("/");
fword("find-device");
+ PUSH((long)&qemu_uuid);
+ PUSH(16);
+ fword("encode-bytes");
+ push_str("uuid");
+ fword("property");
+
+ // Add /idprom
for (i = 0; i < 32; i++) {
outb((i + 0x1fd8) & 0xff, 0x74);
outb((i + 0x1fd8) >> 8, 0x75);
@@ -548,16 +590,22 @@
push_str("/memory");
fword("find-device");
+ outw(__cpu_to_le16(FW_CFG_RAM_SIZE), BIOS_CFG_CMD);
+ for (i = 0; i < 8; i++)
+ buf[i] = inb(BIOS_CFG_DATA);
+
+ ram_size = __le64_to_cpu(*(uint64_t *)buf);
+
// All memory: 0 to RAM_size
PUSH(0);
fword("encode-int");
PUSH(0);
fword("encode-int");
fword("encode+");
- PUSH((int)(nv_info.RAM0_size >> 32));
+ PUSH((int)(ram_size >> 32));
fword("encode-int");
fword("encode+");
- PUSH((int)(nv_info.RAM0_size & 0xffffffff));
+ PUSH((int)(ram_size & 0xffffffff));
fword("encode-int");
fword("encode+");
push_str("reg");
Modified: openbios-devel/drivers/obio.c
===================================================================
--- openbios-devel/drivers/obio.c 2008-09-11 19:33:02 UTC (rev 236)
+++ openbios-devel/drivers/obio.c 2008-09-18 18:41:26 UTC (rev 237)
@@ -21,6 +21,8 @@
#include "obio.h"
#define cpu_to_be16(x) __cpu_to_be16(x)
#include "openbios/firmware_abi.h"
+#define NO_QEMU_PROTOS
+#include "openbios/fw_cfg.h"
#define REGISTER_NAMED_NODE( name, path ) do { \
bind_new_node( name##_flags_, name##_size_, \
@@ -294,7 +296,7 @@
}
}
-static uint32_t
+static void
ob_eccmemctl_init(void)
{
uint32_t version, *regs;
@@ -333,8 +335,6 @@
fword("property");
fword("finish-device");
-
- return version;
}
static unsigned char *nvram;
@@ -716,6 +716,67 @@
for (;;);
}
+static void dummy_mach_init(void)
+{
+}
+
+struct machdef {
+ uint16_t machine_id;
+ const char *banner_name;
+ const char *model;
+ const char *name;
+ int mid_offset;
+ void (*initfn)(void);
+};
+
+static const struct machdef sun4m_defs[] = {
+ {
+ .machine_id = 32,
+ .banner_name = "SPARCstation 5",
+ .model = "SUNW,501-3059",
+ .name = "SUNW,SPARCstation-5",
+ .mid_offset = 0,
+ .initfn = dummy_mach_init,
+ },
+ {
+ .machine_id = 64,
+ .banner_name = "SPARCstation 10 (1 X 390Z55)",
+ .model = "SUNW,S10,501-2365",
+ .name = "SUNW,SPARCstation-10",
+ .mid_offset = 8,
+ .initfn = ob_eccmemctl_init,
+ },
+ {
+ .machine_id = 65,
+ .banner_name = "SPARCstation 20 (1 X 390Z55)",
+ .model = "SUNW,S20,501-2324",
+ .name = "SUNW,SPARCstation-20",
+ .mid_offset = 8,
+ .initfn = ob_eccmemctl_init,
+ },
+ {
+ .machine_id = 66,
+ .banner_name = "SPARCsystem 600(1 X 390Z55)",
+ .model = NULL,
+ .name = "SUNW,SPARCsystem-600",
+ .mid_offset = 8,
+ .initfn = ob_eccmemctl_init,
+ },
+};
+
+static const struct machdef *
+id_machine(uint16_t machine_id)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(sun4m_defs)/sizeof(struct machdef); i++) {
+ if (machine_id == sun4m_defs[i].machine_id)
+ return &sun4m_defs[i];
+ }
+ printk("Unknown machine (ID %d), freezing!\n", machine_id);
+ for (;;);
+}
+
static void
ob_nvram_init(uint64_t base, uint64_t offset)
{
@@ -732,9 +793,14 @@
unsigned int i;
char nographic;
uint32_t size;
- unsigned int machine_id;
+ uint16_t machine_id;
const struct cpudef *cpu;
+ const struct machdef *mach;
ohwcfg_v3_t *header;
+ volatile uint8_t *fw_cfg_data;
+ volatile uint16_t *fw_cfg_cmd;
+ char buf[256];
+ uint32_t temp;
ob_new_obio_device("eeprom", NULL);
@@ -745,17 +811,30 @@
push_str("address");
fword("property");
+ fw_cfg_cmd = map_io(CFG_ADDR, CFG_SIZE);
+ fw_cfg_data = (uint8_t *)fw_cfg_cmd + 2;
+
+ *fw_cfg_cmd = FW_CFG_SIGNATURE;
+ for (i = 0; i < 4; i++)
+ buf[i] = *fw_cfg_data;
+ buf[4] = '\0';
+ printk("Configuration device id %s", buf);
+
+ *fw_cfg_cmd = FW_CFG_ID;
+ for (i = 0; i < 4; i++)
+ buf[i] = *fw_cfg_data;
+
+ temp = __le32_to_cpu(*(uint32_t *)buf);
+ printk(" version %d", temp);
+
+ *fw_cfg_cmd = FW_CFG_MACHINE_ID;
+ for (i = 0; i < 2; i++)
+ buf[i] = *fw_cfg_data;
+
+ machine_id = __le16_to_cpu(*(uint16_t *)buf);
+ printk(" machine id %d\n", machine_id);
+
memcpy(&nv_info, nvram, sizeof(nv_info));
- machine_id = (unsigned int)nvram[0x1fd9] & 0xff;
- printk("Nvram id %s, version %d, machine id 0x%2.2x\n",
- nv_info.struct_ident, nv_info.struct_version, machine_id);
- if (strcmp(nv_info.struct_ident, "QEMU_BIOS") ||
- nv_info.struct_version != 3 ||
- OHW_compute_crc(&nv_info, 0x00, 0xF8) != nv_info.crc) {
- printk("Unknown nvram, freezing!\n");
- for (;;);
- }
-
kernel_image = nv_info.kernel_image;
kernel_size = nv_info.kernel_size;
size = nv_info.cmdline_size;
@@ -772,8 +851,10 @@
header->crc = OHW_compute_crc(header, 0x00, 0xF8);
boot_device = nv_info.boot_devices[0];
- nographic = nv_info.graphic_flags & OHW_GF_NOGRAPHICS;
- graphic_depth = nv_info.depth;
+ *fw_cfg_cmd = FW_CFG_NOGRAPHIC;
+ nographic = *fw_cfg_data;
+ *fw_cfg_cmd = FW_CFG_SUN4M_DEPTH;
+ graphic_depth = *fw_cfg_data;
push_str("mk48t08");
fword("model");
@@ -790,74 +871,37 @@
push_str("idprom");
fword("property");
- switch (machine_id) {
- case 0x71:
- push_str("SPARCsystem 600(1 X 390Z55)");
+ mach = id_machine(machine_id);
+
+ mach->initfn();
+
+ push_str(mach->banner_name);
+ fword("encode-string");
+ push_str("banner-name");
+ fword("property");
+
+ if (mach->model) {
+ push_str(mach->model);
fword("encode-string");
- push_str("banner-name");
- fword("property");
- push_str("SUNW,SPARCsystem-600");
- fword("encode-string");
- push_str("name");
- fword("property");
- ob_eccmemctl_init();
- break;
- case 0x72:
- switch (ob_eccmemctl_init()) {
- default:
- case 0x10000000:
- push_str("SPARCstation 10 (1 X 390Z55)");
- fword("encode-string");
- push_str("banner-name");
- fword("property");
- push_str("SUNW,S10,501-2365");
- fword("encode-string");
- push_str("model");
- fword("property");
- push_str("SUNW,SPARCstation-10");
- fword("encode-string");
- push_str("name");
- fword("property");
- break;
- case 0x20000000:
- push_str("SPARCstation 20 (1 X 390Z55)");
- fword("encode-string");
- push_str("banner-name");
- fword("property");
- push_str("SUNW,S20,501-2324");
- fword("encode-string");
- push_str("model");
- fword("property");
- push_str("SUNW,SPARCstation-20");
- fword("encode-string");
- push_str("name");
- fword("property");
- break;
- }
- break;
- case 0x80:
- push_str("SPARCstation 5");
- fword("encode-string");
- push_str("banner-name");
- fword("property");
- push_str("SUNW,501-3059");
- fword("encode-string");
push_str("model");
fword("property");
- push_str("SUNW,SPARCstation-5");
- fword("encode-string");
- push_str("name");
- fword("property");
- break;
- default:
- printk("Unknown machine, freezing!\n");
- for (;;);
}
+ push_str(mach->name);
+ fword("encode-string");
+ push_str("name");
+ fword("property");
+
// Add cpus
- printk("CPUs: %x", nv_info.nb_cpus);
+ *fw_cfg_cmd = FW_CFG_NB_CPUS;
+ for (i = 0; i < 4; i++)
+ buf[i] = *fw_cfg_data;
+
+ temp = __le32_to_cpu(*(uint32_t *)buf);
+
+ printk("CPUs: %x", temp);
cpu = id_cpu();
printk(" x %s\n", cpu->name);
- for (i = 0; i < (unsigned int)nv_info.nb_cpus; i++) {
+ for (i = 0; i < temp; i++) {
push_str("/");
fword("find-device");
@@ -959,15 +1003,7 @@
push_str("cache-coherence?");
fword("property");
- switch (machine_id) {
- case 0x71:
- case 0x72:
- PUSH(i + 8);
- break;
- case 0x80:
- PUSH(i);
- break;
- }
+ PUSH(i + mach->mid_offset);
fword("encode-int");
push_str("mid");
fword("property");
Modified: openbios-devel/drivers/obio.h
===================================================================
--- openbios-devel/drivers/obio.h 2008-09-11 19:33:02 UTC (rev 236)
+++ openbios-devel/drivers/obio.h 2008-09-18 18:41:26 UTC (rev 237)
@@ -38,6 +38,10 @@
#define SUN4M_NCPUS 16
#define PAGE_SIZE 4096
+#define CFG_ADDR 0xd00000510ULL
+#define CFG_SIZE 3
+#define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
+
/* linux/include/asm-sparc/timer.h */
/* A sun4m has two blocks of registers which are probably of the same
Modified: openbios-devel/drivers/sbus.c
===================================================================
--- openbios-devel/drivers/sbus.c 2008-09-11 19:33:02 UTC (rev 236)
+++ openbios-devel/drivers/sbus.c 2008-09-18 18:41:26 UTC (rev 237)
@@ -571,11 +571,11 @@
ob_sbus_node_init(base);
switch (machine_id) {
- case 0x71:
+ case 66:
return ob_sbus_init_ss600mp();
- case 0x72:
+ case 64 ... 65:
return ob_sbus_init_ss10();
- case 0x80:
+ case 32 ... 63:
return ob_sbus_init_ss5();
default:
return -1;
Added: openbios-devel/include/openbios/fw_cfg.h
===================================================================
--- openbios-devel/include/openbios/fw_cfg.h (rev 0)
+++ openbios-devel/include/openbios/fw_cfg.h 2008-09-18 18:41:26 UTC (rev 237)
@@ -0,0 +1,33 @@
+#ifndef FW_CFG_H
+#define FW_CFG_H
+
+#define FW_CFG_SIGNATURE 0x00
+#define FW_CFG_ID 0x01
+#define FW_CFG_UUID 0x02
+#define FW_CFG_RAM_SIZE 0x03
+#define FW_CFG_NOGRAPHIC 0x04
+#define FW_CFG_NB_CPUS 0x05
+#define FW_CFG_MACHINE_ID 0x06
+#define FW_CFG_MAX_ENTRY 0x10
+
+#define FW_CFG_WRITE_CHANNEL 0x4000
+#define FW_CFG_ARCH_LOCAL 0x8000
+#define FW_CFG_ENTRY_MASK ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)
+
+#define FW_CFG_INVALID 0xffff
+
+#ifndef NO_QEMU_PROTOS
+typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
+
+int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint16_t len);
+int fw_cfg_add_i16(void *opaque, uint16_t key, uint16_t value);
+int fw_cfg_add_i32(void *opaque, uint16_t key, uint32_t value);
+int fw_cfg_add_i64(void *opaque, uint16_t key, uint64_t value);
+int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback,
+ void *callback_opaque, uint8_t *data, size_t len);
+void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
+ target_phys_addr_t crl_addr, target_phys_addr_t data_addr);
+
+#endif /* NO_QEMU_PROTOS */
+
+#endif