#ifndef __VMCB_H
#define __VMCB_H
+#include <geekos/ktypes.h>
#define VMCB_CTRL_AREA_OFFSET 0x0
#define VMCB_STATE_SAVE_AREA_OFFSET 0x400
-#define GET_VMCB_CTRL_AREA(page) (page + VMCB_CONTROL_AREA_OFFSET)
+#define GET_VMCB_CTRL_AREA(page) (page + VMCB_CTRL_AREA_OFFSET)
#define GET_VMCB_SAVE_STATE_AREA(page) (page + VMCB_STATE_SAVE_AREA_OFFSET)
#define PACKED __attribute__((packed))
#endif
+
+typedef void vmcb_t;
+
+
union Ctrl_Registers {
ushort_t bitmap PACKED;
struct {
union Exception_Vectors {
uint_t bitmap PACKED;
struct {
- uint_t ex0 : 1 PACKED;
- uint_t ex1 : 1 PACKED;
+ uint_t ex0 : 1 PACKED;
+ uint_t ex1 : 1 PACKED;
uint_t ex2 : 1 PACKED;
uint_t ex3 : 1 PACKED;
uint_t ex4 : 1 PACKED;
uint_t ex29 : 1 PACKED;
uint_t ex30 : 1 PACKED;
uint_t ex31 : 1 PACKED;
- } exceptions;
+ } ex_numbers;
+ struct {
+ uint_t de : 1 PACKED; // divide by zero
+ uint_t db : 1 PACKED; // Debug
+ uint_t nmi : 1 PACKED; // Non-maskable interrupt
+ uint_t bp : 1 PACKED; // Breakpoint
+ uint_t of : 1 PACKED; // Overflow
+ uint_t br : 1 PACKED; // Bound-Range
+ uint_t ud : 1 PACKED; // Invalid-Opcode
+ uint_t nm : 1 PACKED; // Device-not-available
+ uint_t df : 1 PACKED; // Double Fault
+ uint_t ex9 : 1 PACKED;
+ uint_t ts : 1 PACKED; // Invalid TSS
+ uint_t np : 1 PACKED; // Segment-not-present
+ uint_t ss : 1 PACKED; // Stack
+ uint_t gp : 1 PACKED; // General Protection Fault
+ uint_t pf : 1 PACKED; // Page fault
+ uint_t ex15 : 1 PACKED;
+ uint_t mf : 1 PACKED; // Floating point exception
+ uint_t ac : 1 PACKED; // Alignment-check
+ uint_t mc : 1 PACKED; // Machine Check
+ uint_t xf : 1 PACKED; // SIMD floating-point
+ uint_t ex20 : 1 PACKED;
+ uint_t ex21 : 1 PACKED;
+ uint_t ex22 : 1 PACKED;
+ uint_t ex23 : 1 PACKED;
+ uint_t ex24 : 1 PACKED;
+ uint_t ex25 : 1 PACKED;
+ uint_t ex26 : 1 PACKED;
+ uint_t ex27 : 1 PACKED;
+ uint_t ex28 : 1 PACKED;
+ uint_t ex29 : 1 PACKED;
+ uint_t sx : 1 PACKED; // Security Exception
+ uint_t ex31 : 1 PACKED;
+ } ex_names;
};
union Instr_Intercepts instrs PACKED;
union SVM_Instr_Intercepts svm_instrs PACKED;
- uchar_t rsvd1[43] PACKED; // Should be 0
+ uchar_t rsvd1[44] PACKED; // Should be 0
// offset 0x040
ullong_t IOPM_BASE_PA PACKED;
ullong_t exit_int_info : 63 PACKED;
/* ** */
- uint_t NP_ENABLE : 1 PACKED;
- ullong_t rsvd6 : 63 PACKED; // Should be 0
+ // uint_t NP_ENABLE : 1 PACKED;
+ //ullong_t rsvd6 : 63 PACKED; // Should be 0
+ ullong_t NP_ENABLE PACKED;
- uchar_t rsvd7[15] PACKED; // Should be 0
+ uchar_t rsvd7[16] PACKED; // Should be 0
// Offset 0xA8
ullong_t EVENTINJ PACKED;
* But it does say that the EXITINTINFO field is in bits 63-1
* ALL other occurances mention a 1 bit reserved field
*/
- uint_t rsvd8 : 1 PACKED;
- ullong_t N_CR3 : 63 PACKED;
+ // uint_t rsvd8 : 1 PACKED;
+ //ullong_t N_CR3 : 63 PACKED;
+ ullong_t N_CR3 PACKED;
/* ** */
+
uint_t LBR_VIRTUALIZATION_ENABLE : 1 PACKED;
ullong_t rsvd9 : 63 PACKED; // Should be 0
struct vmcb_selector {
ushort_t selector PACKED;
- ushort_t attrib PACKED;
+
+ /* These attributes are basically a direct map of the attribute fields of a segment desc.
+ * The segment limit in the middle is removed and the fields are fused together
+ * There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1, pg 78
+ */
+ union {
+ ushort_t raw PACKED;
+ struct {
+ uint_t type : 4 PACKED; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
+ uint_t S : 1 PACKED; // System=0, code/data=1
+ uint_t dpl : 2 PACKED; // priviledge level, corresonds to protection ring
+ uint_t P : 1 PACKED; // present flag
+ uint_t avl : 1 PACKED; // available for use by system software
+ uint_t L : 1 PACKED; // long mode (64 bit?)
+ uint_t db : 1 PACKED; // default op size (0=16 bit seg, 1=32 bit seg)
+ uint_t G : 1 PACKED; // Granularity, (0=bytes, 1=4k)
+ } fields;
+ } attrib;
uint_t limit PACKED;
ullong_t base PACKED;
-}
+};
typedef struct VMCB_State_Save_Area {
struct vmcb_selector idtr PACKED; // selector+attrib are reserved, only lower 16 bits of limit are implemented
struct vmcb_selector tr PACKED;
- uchar_t rsvd1[42] PACKED;
+ uchar_t rsvd1[43] PACKED;
//offset 0x0cb
uchar_t cpl PACKED; // if the guest is real-mode then the CPL is forced to 0
// offset 0x0d0
ullong_t efer PACKED;
- uchar_t rsvd3[111] PACKED;
+ uchar_t rsvd3[112] PACKED;
//offset 0x148
ullong_t cr4 PACKED;
ullong_t rflags PACKED;
ullong_t rip PACKED;
- uchar_t rsvd4[87] PACKED;
+ uchar_t rsvd4[88] PACKED;
//offset 0x1d8
ullong_t rsp PACKED;
- uchar_t rsvd5[23] PACKED;
+ uchar_t rsvd5[24] PACKED;
//offset 0x1f8
ullong_t rax PACKED;
ullong_t cr2 PACKED;
- uchar_t rsvd6[31] PACKED;
+ uchar_t rsvd6[32] PACKED;
//offset 0x268
ullong_t g_pat PACKED; // Guest PAT
} vmcb_saved_state_t;
+void PrintDebugVMCB(vmcb_t * vmcb);
+
#endif