Author: agraf Date: Tue Aug 17 17:42:10 2010 New Revision: 853 URL: http://tracker.coreboot.org/trac/openbios/changeset/853
Log: Detect KVM hypervisor and set /hypervisor properties accordingly
The ePAPR spec requires us to have a /hypervisor node that tells the guest OS which hypervisor it's running on and which hypercall to use to call into it.
So let's fetch all that information from Qemu's fw_cfg interface and put it into place, making everyone happy.
Signed-off-by: Alexander Graf agraf@suse.de
Modified: trunk/openbios-devel/arch/ppc/qemu/init.c trunk/openbios-devel/arch/ppc/qemu/tree.fs trunk/openbios-devel/include/arch/common/fw_cfg.h
Modified: trunk/openbios-devel/arch/ppc/qemu/init.c ============================================================================== --- trunk/openbios-devel/arch/ppc/qemu/init.c Wed Aug 11 22:59:18 2010 (r852) +++ trunk/openbios-devel/arch/ppc/qemu/init.c Tue Aug 17 17:42:10 2010 (r853) @@ -518,6 +518,58 @@ call_elf( 0, 0, addr); }
+static void kvm_of_init(void) +{ + char hypercall[4 * 4]; + uint32_t *hc32; + + /* Don't expose /hypervisor when not in KVM */ + if (!fw_cfg_read_i32(FW_CFG_PPC_IS_KVM)) + return; + + push_str("/hypervisor"); + fword("find-device"); + + /* compatible */ + + push_str("linux,kvm"); + fword("encode-string"); + push_str("epapr,hypervisor-0.2"); + fword("encode-string"); + fword("encode+"); + push_str("compatible"); + fword("property"); + + /* Tell the guest about the hypercall instructions */ + fw_cfg_read(FW_CFG_PPC_KVM_HC, hypercall, 4 * 4); + hc32 = (uint32_t*)hypercall; + PUSH(hc32[0]); + fword("encode-int"); + PUSH(hc32[1]); + fword("encode-int"); + fword("encode+"); + PUSH(hc32[2]); + fword("encode-int"); + fword("encode+"); + PUSH(hc32[3]); + fword("encode-int"); + fword("encode+"); + push_str("hcall-instructions"); + fword("property"); + + /* ePAPR requires us to provide a unique guest id */ + PUSH(fw_cfg_read_i32(FW_CFG_PPC_KVM_PID)); + fword("encode-int"); + push_str("guest-id"); + fword("property"); + + /* ePAPR requires us to provide a guest name */ + push_str("KVM guest"); + fword("encode-string"); + push_str("guest-name"); + fword("property"); +} + void arch_of_init( void ) { @@ -714,6 +766,8 @@ stdout_path = "screen"; }
+ kvm_of_init(); + /* Setup nvram variables */ push_str("/options"); fword("find-device");
Modified: trunk/openbios-devel/arch/ppc/qemu/tree.fs ============================================================================== --- trunk/openbios-devel/arch/ppc/qemu/tree.fs Wed Aug 11 22:59:18 2010 (r852) +++ trunk/openbios-devel/arch/ppc/qemu/tree.fs Tue Aug 17 17:42:10 2010 (r853) @@ -39,6 +39,11 @@ : close ; finish-device
+new-device + " hypervisor" device-name + " hypervisor" device-type +finish-device + \ ------------------------------------------------------------- \ /packages \ -------------------------------------------------------------
Modified: trunk/openbios-devel/include/arch/common/fw_cfg.h ============================================================================== --- trunk/openbios-devel/include/arch/common/fw_cfg.h Wed Aug 11 22:59:18 2010 (r852) +++ trunk/openbios-devel/include/arch/common/fw_cfg.h Tue Aug 17 17:42:10 2010 (r853) @@ -41,6 +41,9 @@ #define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02) #define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03) #define FW_CFG_PPC_CPUFREQ (FW_CFG_ARCH_LOCAL + 0x04) +#define FW_CFG_PPC_IS_KVM (FW_CFG_ARCH_LOCAL + 0x05) +#define FW_CFG_PPC_KVM_HC (FW_CFG_ARCH_LOCAL + 0x06) +#define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07)
#define FW_CFG_INVALID 0xffff