From 18cd147df3d4c84c054a23f02af8235e2b836822 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Tue, 23 Dec 2008 11:57:36 +0000 Subject: [PATCH] Get machine ID, boot device, preloaded kernel parameters and UUID from Qemu configuration device and NVRAM. git-svn-id: svn://coreboot.org/openbios/openbios-devel@315 f158a5a8-5612-0410-a976-696ce0be7e32 --- arch/ppc/qemu/init.c | 69 +++++++++++++++++++++++++++++++++++++++++++- arch/ppc/qemu/main.c | 52 +++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index c5c35fd..b317976 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -27,6 +27,13 @@ #include "qemu/qemu.h" #include "ofmem.h" #include "openbios-version.h" +#include "libc/byteorder.h" +#define NO_QEMU_PROTOS +#include "openbios/fw_cfg.h" + +#define CFG_ADDR 0xf0000510 + +#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" extern void unexpected_excep( int vector ); extern void ob_pci_init( void ); @@ -62,10 +69,49 @@ static const pci_arch_t known_arch[] = { }; uint32_t isa_io_base; +static volatile uint16_t *fw_cfg_cmd = (void *)CFG_ADDR; +static volatile uint8_t *fw_cfg_data = (void *)(CFG_ADDR + 2); + +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); +} + void entry( void ) { - arch = &known_arch[ARCH_HEATHROW]; + uint32_t temp; + uint16_t machine_id; + char buf[5], qemu_uuid[16]; + + machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID); + + arch = &known_arch[machine_id]; isa_io_base = arch->io_base; serial_init(); @@ -74,6 +120,27 @@ entry( void ) printk("=============================================================\n"); printk("OpenBIOS %s [%s]\n", OPENBIOS_RELEASE, OPENBIOS_BUILD_DATE ); + fw_cfg_read(FW_CFG_SIGNATURE, buf, 4); + buf[4] = '\0'; + + printk("Configuration device id %s", buf); + + temp = fw_cfg_read_i32(FW_CFG_ID); + + printk(" version %d machine id %d\n", temp, machine_id); + + temp = fw_cfg_read_i32(FW_CFG_NB_CPUS); + + printk("CPUs: %x\n", temp); + + fw_cfg_read(FW_CFG_UUID, 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], + 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]); + ofmem_init(); initialize_forth(); /* won't return */ diff --git a/arch/ppc/qemu/main.c b/arch/ppc/qemu/main.c index 3e43c10..ff338c9 100644 --- a/arch/ppc/qemu/main.c +++ b/arch/ppc/qemu/main.c @@ -33,6 +33,10 @@ do { printk("ELF - %s: " fmt, __func__ , ##args); } while (0) #define ELF_DPRINTF(fmt, args...) do { } while (0) #endif +#define NVRAM_ADDR_LO 0x74 +#define NVRAM_ADDR_HI 0x75 +#define NVRAM_DATA 0x77 + static void transfer_control_to_elf( ulong elf_entry ) { @@ -206,6 +210,24 @@ try_bootinfo(const char *path) close_io( fd ); } +static uint8_t nvram_read(uint16_t offset) +{ + outb(offset & 0xff, NVRAM_ADDR_LO); + outb(offset >> 8, NVRAM_ADDR_HI); + return inb(NVRAM_DATA); +} + +static uint32_t nvram_read_be32(uint16_t offset) +{ + uint32_t ret; + + ret = nvram_read(offset) << 24; + ret |= nvram_read(offset + 1) << 16; + ret |= nvram_read(offset + 2) << 8; + ret |= nvram_read(offset + 3); + return ret; +} + static void yaboot_startup( void ) { @@ -238,6 +260,19 @@ yaboot_startup( void ) } try_bootinfo(path); try_path(path, param); + } else { + char boot_device = nvram_read(0x34); + + switch (boot_device) { + case 'c': + path = strdup("hd:0"); + break; + default: + case 'd': + path = strdup("cdrom:0"); + break; + } + try_bootinfo(path); } } else { ELF_DPRINTF("Entering boot, path %s\n", path); @@ -250,6 +285,22 @@ yaboot_startup( void ) printk("*** Boot failure! No secondary bootloader specified ***\n"); } +static void check_preloaded_kernel(void) +{ + unsigned long kernel_image, kernel_size, cmdline; + unsigned long initrd_image, initrd_size; + + kernel_size = nvram_read_be32(0x3c); + if (kernel_size) { + kernel_image = nvram_read_be32(0x38); + cmdline = nvram_read_be32(0x40); + initrd_image = nvram_read_be32(0x48); + initrd_size = nvram_read_be32(0x4c); + printk("[ppc] Kernel already loaded (0x%8.8lx + 0x%8.8lx)\n", + kernel_image, kernel_size); + call_elf(kernel_image); + } +} /************************************************************************/ /* entry */ @@ -259,5 +310,6 @@ void boot( void ) { fword("update-chosen"); + check_preloaded_kernel(); yaboot_startup(); }