diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c index 4768f69..7caafa5 100644 --- a/arch/sparc64/openbios.c +++ b/arch/sparc64/openbios.c @@ -32,6 +32,10 @@ #define BIOS_CFG_CMD 0x510 #define BIOS_CFG_DATA 0x511 +#define NVRAM_ADDR_LO 0x74 +#define NVRAM_ADDR_HI 0x75 +#define NVRAM_DATA 0x77 + #define APB_SPECIAL_BASE 0x1fe00000000ULL #define PCI_CONFIG (APB_SPECIAL_BASE + 0x1000000ULL) #define APB_MEM_BASE 0x1ff00000000ULL @@ -40,20 +44,21 @@ static unsigned char intdict[256 * 1024]; // XXX #define NVRAM_SIZE 0x2000 -#define NVRAM_IDPROM 0x1fd0 +#define NVRAM_IDPROM 0x1fd8 +#define NVRAM_IDPROM_SIZE 32 #define NVRAM_OB_START (sizeof(ohwcfg_v3_t) + sizeof(struct sparc_arch_cfg)) -#define NVRAM_OB_SIZE ((NVRAM_IDPROM - NVRAM_OB_START) & ~15) +#define NVRAM_OB_SIZE ((0x1fd0 - NVRAM_OB_START) & ~15) static ohwcfg_v3_t nv_info; #define OBIO_CMDLINE_MAX 256 static char obio_cmdline[OBIO_CMDLINE_MAX]; -static uint8_t idprom[32]; +static uint8_t idprom[NVRAM_IDPROM_SIZE]; struct hwdef { pci_arch_t pci; - uint8_t machine_id_low, machine_id_high; + uint16_t machine_id_low, machine_id_high; }; static const struct hwdef hwdefs[] = { @@ -556,12 +561,80 @@ id_cpu(void) for (;;); } +static void +fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) +{ + unsigned int i; + + outw(__cpu_to_le16(cmd), BIOS_CFG_CMD); + for (i = 0; i < nbytes; i++) + buf[i] = inb(BIOS_CFG_DATA); +} + +static uint64_t +fw_cfg_read_i64(uint16_t cmd) +{ + char buf[sizeof(uint64_t)]; + + fw_cfg_read(cmd, buf, sizeof(uint64_t)); + + return __le64_to_cpu(*(uint64_t *)buf); +} + +static uint32_t +fw_cfg_read_i32(uint16_t cmd) +{ + char buf[sizeof(uint32_t)]; + + fw_cfg_read(cmd, buf, sizeof(uint32_t)); + + return __le32_to_cpu(*(uint32_t *)buf); +} + +static uint16_t +fw_cfg_read_i16(uint16_t cmd) +{ + char buf[sizeof(uint16_t)]; + + fw_cfg_read(cmd, buf, sizeof(uint16_t)); + + return __le16_to_cpu(*(uint16_t *)buf); +} + +static uint8_t nvram_read_byte(uint16_t offset) +{ + outb(offset & 0xff, NVRAM_ADDR_LO); + outb(offset >> 8, NVRAM_ADDR_HI); + return inb(NVRAM_DATA); +} + +static void nvram_read(uint16_t offset, char *buf, unsigned int nbytes) +{ + unsigned int i; + + for (i = 0; i < nbytes; i++) + buf[i] = nvram_read_byte(offset + i); +} + +static void nvram_write_byte(uint16_t offset, uint8_t val) +{ + outb(offset & 0xff, NVRAM_ADDR_LO); + outb(offset >> 8, NVRAM_ADDR_HI); + outb(val, NVRAM_DATA); +} + +static void nvram_write(uint16_t offset, const char *buf, unsigned int nbytes) +{ + unsigned int i; + + for (i = 0; i < nbytes; i++) + nvram_write_byte(offset + i, buf[i]); +} + static uint8_t qemu_uuid[16]; void arch_nvram_get(char *data) { - unsigned short i; - unsigned char *nvptr = (unsigned char *)&nv_info; uint32_t size; const struct cpudef *cpu; const char *bootpath; @@ -569,27 +642,19 @@ void arch_nvram_get(char *data) uint32_t temp; uint64_t ram_size; uint32_t clock_frequency; + uint16_t machine_id; - for (i = 0; i < sizeof(ohwcfg_v3_t); i++) { - outb(i & 0xff, 0x74); - outb(i >> 8, 0x75); - *nvptr++ = inb(0x77); - } - - outw(__cpu_to_le16(FW_CFG_SIGNATURE), BIOS_CFG_CMD); - for (i = 0; i < 4; i++) - buf[i] = inb(BIOS_CFG_DATA); + nvram_read(0, (char *)&nv_info, sizeof(ohwcfg_v3_t)); + fw_cfg_read(FW_CFG_SIGNATURE, buf, 4); 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 = fw_cfg_read_i32(FW_CFG_ID); + machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID); - temp = __le32_to_cpu(*(uint32_t *)buf); - printk(" version %d\n", temp); + printk(" version %d machine id %d\n", temp, machine_id); kernel_image = nv_info.kernel_image; kernel_size = nv_info.kernel_size; @@ -606,17 +671,9 @@ void arch_nvram_get(char *data) if (size) printk("kernel cmdline %s\n", obio_cmdline); - for (i = 0; i < NVRAM_OB_SIZE; i++) { - outb((i + NVRAM_OB_START) & 0xff, 0x74); - outb((i + NVRAM_OB_START) >> 8, 0x75); - data[i] = inb(0x77); - } + nvram_read(NVRAM_OB_START, data, NVRAM_OB_SIZE); - 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); + temp = fw_cfg_read_i32(FW_CFG_NB_CPUS); printk("CPUs: %x", temp); @@ -628,9 +685,7 @@ void arch_nvram_get(char *data) printk(" x %s\n", cpu->name); // 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); + fw_cfg_read(FW_CFG_UUID, (char *)qemu_uuid, 16); 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], @@ -648,11 +703,7 @@ void arch_nvram_get(char *data) fword("property"); // Add /idprom - for (i = 0; i < 32; i++) { - outb((i + 0x1fd8) & 0xff, 0x74); - outb((i + 0x1fd8) >> 8, 0x75); - idprom[i] = inb(0x77); - } + nvram_read(NVRAM_IDPROM, (char *)idprom, NVRAM_IDPROM_SIZE); PUSH((long)&idprom); PUSH(32); @@ -668,11 +719,7 @@ void arch_nvram_get(char *data) 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); + ram_size = fw_cfg_read_i64(FW_CFG_RAM_SIZE); // All memory: 0 to RAM_size PUSH(0); @@ -811,13 +858,7 @@ void arch_nvram_get(char *data) void arch_nvram_put(char *data) { - unsigned short i; - - for (i = 0; i < NVRAM_OB_SIZE; i++) { - outb((i + NVRAM_OB_START) & 0xff, 0x74); - outb((i + NVRAM_OB_START) >> 8, 0x75); - outb(data[i], 0x77); - } + nvram_write(0, data, NVRAM_OB_SIZE); } int arch_nvram_size(void) @@ -851,15 +892,14 @@ static void arch_init( void ) { unsigned int i; - uint8_t qemu_machine_type; - const struct hwdef *hwdef; + uint16_t machine_id; + const struct hwdef *hwdef = NULL; - outw(__cpu_to_le16(FW_CFG_MACHINE_ID), BIOS_CFG_CMD); - qemu_machine_type = inb(BIOS_CFG_DATA); + machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID); for (i = 0; i < sizeof(hwdefs) / sizeof(struct hwdef); i++) { - if (hwdefs[i].machine_id_low <= qemu_machine_type && - hwdefs[i].machine_id_high >= qemu_machine_type) { + if (hwdefs[i].machine_id_low <= machine_id && + hwdefs[i].machine_id_high >= machine_id) { hwdef = &hwdefs[i]; break; } diff --git a/drivers/obio.c b/drivers/obio.c index f8cc812..985fba7 100644 --- a/drivers/obio.c +++ b/drivers/obio.c @@ -24,6 +24,8 @@ #define NO_QEMU_PROTOS #include "openbios/fw_cfg.h" +#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" + #define PROMDEV_KBD 0 /* input from keyboard */ #define PROMDEV_SCREEN 0 /* output to screen */ #define PROMDEV_TTYA 1 /* in/out to ttya */ @@ -964,6 +966,41 @@ id_machine(uint16_t machine_id) for (;;); } +static volatile uint16_t *fw_cfg_cmd; +static volatile uint8_t *fw_cfg_data; + +static void +fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) +{ + unsigned int i; + + *fw_cfg_cmd = cmd; + for (i = 0; i < nbytes; i++) + buf[i] = *fw_cfg_data; +} + +static uint32_t +fw_cfg_read_i32(uint16_t cmd) +{ + char buf[sizeof(uint32_t)]; + + fw_cfg_read(cmd, buf, sizeof(uint32_t)); + + return __le32_to_cpu(*(uint32_t *)buf); +} + +static uint16_t +fw_cfg_read_i16(uint16_t cmd) +{ + char buf[sizeof(uint16_t)]; + + fw_cfg_read(cmd, buf, sizeof(uint16_t)); + + return __le16_to_cpu(*(uint16_t *)buf); +} + +static uint8_t qemu_uuid[16]; + static void ob_nvram_init(uint64_t base, uint64_t offset) { @@ -975,8 +1012,6 @@ ob_nvram_init(uint64_t base, uint64_t offset) 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; @@ -989,28 +1024,23 @@ ob_nvram_init(uint64_t base, uint64_t offset) push_str("address"); fword("property"); + push_str("mk48t08"); + fword("model"); + + fword("finish-device"); + 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; + fw_cfg_read(FW_CFG_SIGNATURE, buf, 4); 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 = fw_cfg_read_i32(FW_CFG_ID); + machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID); - 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); + printk(" version %d machine id %d\n", temp, machine_id); memcpy(&nv_info, nvram, sizeof(nv_info)); kernel_image = nv_info.kernel_image; @@ -1029,15 +1059,26 @@ ob_nvram_init(uint64_t base, uint64_t offset) header->crc = OHW_compute_crc(header, 0x00, 0xF8); boot_device = nv_info.boot_devices[0]; - *fw_cfg_cmd = FW_CFG_NOGRAPHIC; - nographic = *fw_cfg_data; - *fw_cfg_cmd = FW_CFG_SUN4M_DEPTH; - graphic_depth = *fw_cfg_data; + fw_cfg_read(FW_CFG_NOGRAPHIC, &nographic, 1); + graphic_depth = fw_cfg_read_i16(FW_CFG_SUN4M_DEPTH); - push_str("mk48t08"); - fword("model"); + // Add /uuid + fw_cfg_read(FW_CFG_UUID, (char *)qemu_uuid, 16); - fword("finish-device"); + 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 push_str("/"); @@ -1070,11 +1111,7 @@ ob_nvram_init(uint64_t base, uint64_t offset) fword("property"); // Add 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); + temp = fw_cfg_read_i32(FW_CFG_NB_CPUS); printk("CPUs: %x", temp); cpu = id_cpu();