[OpenBIOS] r315 - openbios-devel/arch/ppc/qemu
Laurent Vivier
laurent at lvivier.info
Tue Dec 23 13:35:41 CET 2008
Le 23 déc. 08 à 12:57, svn at openbios.org a écrit :
> 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.
This one hangs when it is used with a QEmu that doesn't present the FW
cfg interface to openbios.
>
>
> 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);
>
If qemu doesn't provide FW cfg interface machine_id is 0, which means
ARCH_PREPS.
> + 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();
> }
>
>
> --
> OpenBIOS http://openbios.org/
> Mailinglist: http://lists.openbios.org/mailman/listinfo
> Free your System - May the Forth be with you
----------------------- Laurent Vivier ----------------------
"The best way to predict the future is to invent it."
- Alan Kay
More information about the OpenBIOS
mailing list