#ifndef _MACHINE_GHCB_H_
#define _MACHINE_GHCB_H_
#ifndef _LOCORE
#include <sys/systm.h>
#include <machine/frame.h>
#define GHCB_OFFSET(m) ((m) / 8)
#define GHCB_IDX(m) (GHCB_OFFSET((m)) / 8)
#define GHCB_BIT(m) (GHCB_OFFSET((m)) % 8)
#define GHCB_XSS 0x140
#define GHCB_RAX 0x1F8
#define GHCB_RBX 0x318
#define GHCB_RCX 0x308
#define GHCB_RDX 0x310
#define GHCB_SW_EXITCODE 0x390
#define GHCB_SW_EXITINFO1 0x398
#define GHCB_SW_EXITINFO2 0x3A0
#define GHCB_SW_SCRATCH 0x3A8
#define GHCB_XCR0 0x3E8
#define GHCB_MAX 0xFFF
struct ghcb_sa {
uint8_t v_pad0[0xcb];
uint8_t v_cpl;
uint8_t v_pad1[0x74];
uint64_t v_xss;
uint8_t v_pad2[0x18];
uint64_t v_dr7;
uint8_t v_pad3[0x10];
uint64_t v_rip;
uint8_t v_pad4[0x58];
uint64_t v_rsp;
uint8_t v_pad5[0x18];
uint64_t v_rax;
uint8_t v_pad6[0x108];
uint64_t v_rcx;
uint64_t v_rdx;
uint64_t v_rbx;
uint8_t v_pad7[0x8];
uint64_t v_rbp;
uint64_t v_rsi;
uint64_t v_rdi;
uint64_t v_r8;
uint64_t v_r9;
uint64_t v_r10;
uint64_t v_r11;
uint64_t v_r12;
uint64_t v_r13;
uint64_t v_r14;
uint64_t v_r15;
uint8_t v_pad8[0x10];
uint64_t v_sw_exitcode;
uint64_t v_sw_exitinfo1;
uint64_t v_sw_exitinfo2;
uint64_t v_sw_scratch;
uint8_t v_pad9[0x38];
uint64_t v_xcr0;
#define GHCB_VB_SZ 0x10
uint8_t valid_bitmap[GHCB_VB_SZ];
uint64_t v_x87_state_gpa;
uint8_t v_pad10[0x3f8];
uint8_t v_sharedbuf[0x7f0];
uint8_t v_pad11[0xa];
uint16_t v_ghcb_proto_version;
uint32_t v_ghcb_usage;
};
#define GHCB_SZ8 0
#define GHCB_SZ16 1
#define GHCB_SZ32 2
#define GHCB_SZ64 3
struct ghcb_sync {
uint8_t valid_bitmap[GHCB_VB_SZ];
int sz_a;
int sz_b;
int sz_c;
int sz_d;
};
#endif
#define MSR_PROTO_CPUID_REQ 0x4
#define MSR_PROTO_CPUID_RESP 0x5
#define MSR_PROTO_TERMINATE 0x100
#ifndef _LOCORE
extern vaddr_t ghcb_vaddr;
extern paddr_t ghcb_paddr;
struct ghcb_extra_regs {
uint64_t exitcode;
uint64_t exitinfo1;
uint64_t exitinfo2;
uint64_t scratch;
void *data;
size_t data_sz;
};
void ghcb_clear(struct ghcb_sa *);
int ghcb_valbm_set(uint8_t *, int);
int ghcb_valbm_isset(uint8_t *, int);
int ghcb_verify_bm(uint8_t *, uint8_t *);
int ghcb_valid(struct ghcb_sa *);
int ghcb_empty(struct ghcb_sa *);
void ghcb_sync_val(int, int, struct ghcb_sync *);
void ghcb_sync_out(struct trapframe *, const struct ghcb_extra_regs *,
struct ghcb_sa *, struct ghcb_sync *);
void ghcb_sync_in(struct trapframe *, struct ghcb_extra_regs *,
struct ghcb_sa *, struct ghcb_sync *);
void _ghcb_mem_rw(vaddr_t, int, void *, bool);
void _ghcb_io_rw(uint16_t, int, uint32_t *, bool);
static inline uint8_t
ghcb_mem_read_1(vaddr_t addr)
{
uint8_t val;
_ghcb_mem_rw(addr, GHCB_SZ8, &val, true);
return val;
}
static inline uint16_t
ghcb_mem_read_2(vaddr_t addr)
{
uint16_t val;
_ghcb_mem_rw(addr, GHCB_SZ16, &val, true);
return val;
}
static inline uint32_t
ghcb_mem_read_4(vaddr_t addr)
{
uint32_t val;
_ghcb_mem_rw(addr, GHCB_SZ32, &val, true);
return val;
}
static inline uint64_t
ghcb_mem_read_8(vaddr_t addr)
{
uint64_t val;
_ghcb_mem_rw(addr, GHCB_SZ64, &val, true);
return val;
}
static inline void
ghcb_mem_write_1(vaddr_t addr, uint8_t v)
{
_ghcb_mem_rw(addr, GHCB_SZ8, &v, false);
}
static inline void
ghcb_mem_write_2(vaddr_t addr, uint16_t v)
{
_ghcb_mem_rw(addr, GHCB_SZ16, &v, false);
}
static inline void
ghcb_mem_write_4(vaddr_t addr, uint32_t v)
{
_ghcb_mem_rw(addr, GHCB_SZ32, &v, false);
}
static inline void
ghcb_mem_write_8(vaddr_t addr, uint64_t v)
{
_ghcb_mem_rw(addr, GHCB_SZ64, &v, false);
}
static inline uint8_t
ghcb_io_read_1(uint16_t port)
{
uint32_t val;
_ghcb_io_rw(port, GHCB_SZ8, &val, true);
return val;
}
static inline uint16_t
ghcb_io_read_2(uint16_t port)
{
uint32_t val;
_ghcb_io_rw(port, GHCB_SZ16, &val, true);
return val;
}
static inline uint32_t
ghcb_io_read_4(uint16_t port)
{
uint32_t val;
_ghcb_io_rw(port, GHCB_SZ32, &val, true);
return val;
}
static inline void
ghcb_io_write_1(uint16_t port, uint8_t v)
{
uint32_t val = v;
_ghcb_io_rw(port, GHCB_SZ8, &val, false);
}
static inline void
ghcb_io_write_2(uint16_t port, uint16_t v)
{
uint32_t val = v;
_ghcb_io_rw(port, GHCB_SZ16, &val, false);
}
static inline void
ghcb_io_write_4(uint16_t port, uint32_t v)
{
_ghcb_io_rw(port, GHCB_SZ32, &v, false);
}
#endif
#endif