mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
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> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@853 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -518,6 +518,58 @@ go( void )
|
||||
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 @@ arch_of_init( void )
|
||||
stdout_path = "screen";
|
||||
}
|
||||
|
||||
kvm_of_init();
|
||||
|
||||
/* Setup nvram variables */
|
||||
push_str("/options");
|
||||
fword("find-device");
|
||||
|
||||
@@ -39,6 +39,11 @@ new-device
|
||||
: close ;
|
||||
finish-device
|
||||
|
||||
new-device
|
||||
" hypervisor" device-name
|
||||
" hypervisor" device-type
|
||||
finish-device
|
||||
|
||||
\ -------------------------------------------------------------
|
||||
\ /packages
|
||||
\ -------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user