Author: blueswirl Date: 2008-12-23 12:57:36 +0100 (Tue, 23 Dec 2008) New Revision: 315
Modified: openbios-devel/arch/ppc/qemu/init.c openbios-devel/arch/ppc/qemu/main.c Log: Get machine ID, boot device, preloaded kernel parameters and UUID from Qemu configuration device and NVRAM.
Modified: openbios-devel/arch/ppc/qemu/init.c =================================================================== --- openbios-devel/arch/ppc/qemu/init.c 2008-12-23 11:54:25 UTC (rev 314) +++ openbios-devel/arch/ppc/qemu/init.c 2008-12-23 11:57:36 UTC (rev 315) @@ -27,7 +27,14 @@ #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 ); extern void setup_timers( void ); @@ -62,10 +69,49 @@ }; 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 @@ 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 */
Modified: openbios-devel/arch/ppc/qemu/main.c =================================================================== --- openbios-devel/arch/ppc/qemu/main.c 2008-12-23 11:54:25 UTC (rev 314) +++ openbios-devel/arch/ppc/qemu/main.c 2008-12-23 11:57:36 UTC (rev 315) @@ -33,6 +33,10 @@ #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 @@ 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 @@ } 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,7 +285,23 @@ 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 @@ boot( void ) { fword("update-chosen"); + check_preloaded_kernel(); yaboot_startup(); }