1 /** @file
2   Guest-Hypervisor Communication Block (GHCB) Definition.
3 
4   Provides data types allowing an SEV-ES guest to interact with the hypervisor
5   using the GHCB protocol.
6 
7   Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
8   SPDX-License-Identifier: BSD-2-Clause-Patent
9 
10   @par Specification Reference:
11   SEV-ES Guest-Hypervisor Communication Block Standardization
12 
13 **/
14 
15 #ifndef __GHCB_H__
16 #define __GHCB_H__
17 
18 #include <Base.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
21 
22 #define UD_EXCEPTION  6
23 #define GP_EXCEPTION 13
24 #define VC_EXCEPTION 29
25 
26 #define GHCB_VERSION_MIN     1
27 #define GHCB_VERSION_MAX     1
28 
29 #define GHCB_STANDARD_USAGE  0
30 
31 //
32 // SVM Exit Codes
33 //
34 #define SVM_EXIT_DR7_READ       0x27ULL
35 #define SVM_EXIT_DR7_WRITE      0x37ULL
36 #define SVM_EXIT_RDTSC          0x6EULL
37 #define SVM_EXIT_RDPMC          0x6FULL
38 #define SVM_EXIT_CPUID          0x72ULL
39 #define SVM_EXIT_INVD           0x76ULL
40 #define SVM_EXIT_IOIO_PROT      0x7BULL
41 #define SVM_EXIT_MSR            0x7CULL
42 #define SVM_EXIT_VMMCALL        0x81ULL
43 #define SVM_EXIT_RDTSCP         0x87ULL
44 #define SVM_EXIT_WBINVD         0x89ULL
45 #define SVM_EXIT_MONITOR        0x8AULL
46 #define SVM_EXIT_MWAIT          0x8BULL
47 #define SVM_EXIT_NPF            0x400ULL
48 
49 //
50 // VMG Special Exit Codes
51 //
52 #define SVM_EXIT_MMIO_READ      0x80000001ULL
53 #define SVM_EXIT_MMIO_WRITE     0x80000002ULL
54 #define SVM_EXIT_NMI_COMPLETE   0x80000003ULL
55 #define SVM_EXIT_AP_RESET_HOLD  0x80000004ULL
56 #define SVM_EXIT_AP_JUMP_TABLE  0x80000005ULL
57 #define SVM_EXIT_UNSUPPORTED    0x8000FFFFULL
58 
59 //
60 // IOIO Exit Information
61 //
62 #define IOIO_TYPE_STR       BIT2
63 #define IOIO_TYPE_IN        1
64 #define IOIO_TYPE_INS       (IOIO_TYPE_IN | IOIO_TYPE_STR)
65 #define IOIO_TYPE_OUT       0
66 #define IOIO_TYPE_OUTS      (IOIO_TYPE_OUT | IOIO_TYPE_STR)
67 
68 #define IOIO_REP            BIT3
69 
70 #define IOIO_ADDR_64        BIT9
71 #define IOIO_ADDR_32        BIT8
72 #define IOIO_ADDR_16        BIT7
73 
74 #define IOIO_DATA_32        BIT6
75 #define IOIO_DATA_16        BIT5
76 #define IOIO_DATA_8         BIT4
77 #define IOIO_DATA_MASK      (BIT6 | BIT5 | BIT4)
78 #define IOIO_DATA_OFFSET    4
79 #define IOIO_DATA_BYTES(x)  (((x) & IOIO_DATA_MASK) >> IOIO_DATA_OFFSET)
80 
81 #define IOIO_SEG_ES         0
82 #define IOIO_SEG_DS         (BIT11 | BIT10)
83 
84 
85 typedef PACKED struct {
86   UINT8                  Reserved1[203];
87   UINT8                  Cpl;
88   UINT8                  Reserved8[300];
89   UINT64                 Rax;
90   UINT8                  Reserved4[264];
91   UINT64                 Rcx;
92   UINT64                 Rdx;
93   UINT64                 Rbx;
94   UINT8                  Reserved5[112];
95   UINT64                 SwExitCode;
96   UINT64                 SwExitInfo1;
97   UINT64                 SwExitInfo2;
98   UINT64                 SwScratch;
99   UINT8                  Reserved6[56];
100   UINT64                 XCr0;
101   UINT8                  ValidBitmap[16];
102   UINT64                 X87StateGpa;
103   UINT8                  Reserved7[1016];
104 } GHCB_SAVE_AREA;
105 
106 typedef PACKED struct {
107   GHCB_SAVE_AREA         SaveArea;
108   UINT8                  SharedBuffer[2032];
109   UINT8                  Reserved1[10];
110   UINT16                 ProtocolVersion;
111   UINT32                 GhcbUsage;
112 } GHCB;
113 
114 #define GHCB_SAVE_AREA_QWORD_OFFSET(RegisterField) \
115   (OFFSET_OF (GHCB, SaveArea.RegisterField) / sizeof (UINT64))
116 
117 typedef enum {
118   GhcbCpl          = GHCB_SAVE_AREA_QWORD_OFFSET (Cpl),
119   GhcbRax          = GHCB_SAVE_AREA_QWORD_OFFSET (Rax),
120   GhcbRbx          = GHCB_SAVE_AREA_QWORD_OFFSET (Rbx),
121   GhcbRcx          = GHCB_SAVE_AREA_QWORD_OFFSET (Rcx),
122   GhcbRdx          = GHCB_SAVE_AREA_QWORD_OFFSET (Rdx),
123   GhcbXCr0         = GHCB_SAVE_AREA_QWORD_OFFSET (XCr0),
124   GhcbSwExitCode   = GHCB_SAVE_AREA_QWORD_OFFSET (SwExitCode),
125   GhcbSwExitInfo1  = GHCB_SAVE_AREA_QWORD_OFFSET (SwExitInfo1),
126   GhcbSwExitInfo2  = GHCB_SAVE_AREA_QWORD_OFFSET (SwExitInfo2),
127   GhcbSwScratch    = GHCB_SAVE_AREA_QWORD_OFFSET (SwScratch),
128 } GHCB_REGISTER;
129 
130 typedef union {
131   struct {
132     UINT32  Lower32Bits;
133     UINT32  Upper32Bits;
134   } Elements;
135 
136   UINT64    Uint64;
137 } GHCB_EXIT_INFO;
138 
139 typedef union {
140   struct {
141     UINT32  Vector:8;
142     UINT32  Type:3;
143     UINT32  ErrorCodeValid:1;
144     UINT32  Rsvd:19;
145     UINT32  Valid:1;
146     UINT32  ErrorCode;
147   } Elements;
148 
149   UINT64    Uint64;
150 } GHCB_EVENT_INJECTION;
151 
152 #define GHCB_EVENT_INJECTION_TYPE_INT        0
153 #define GHCB_EVENT_INJECTION_TYPE_NMI        2
154 #define GHCB_EVENT_INJECTION_TYPE_EXCEPTION  3
155 #define GHCB_EVENT_INJECTION_TYPE_SOFT_INT   4
156 
157 #endif
158