Skip to content

Commit

Permalink
add a case-gen script for tdx-compliance-tests.
Browse files Browse the repository at this point in the history
Signed-off-by: DCyan_Elite <[email protected]>
  • Loading branch information
CrescentLove committed Oct 19, 2023
1 parent 8b159cd commit 8ba3543
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 0 deletions.
151 changes: 151 additions & 0 deletions tdx-compliance/auto_gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@


# related filepath
import csv
import sys

import pandas
import math
import json
version = "1.5"
class GetPath:
def __init__(self, config_path):
# 初始化成员变量
self.config_path = config_path
self.csv_path = None
self.header_path = None
self.vdetail = None
self.vtype = None
self.bias = 0

def read_config_csv(self, ptype):
try:
with open(self.config_path, 'r') as config_file:
config_data = json.load(config_file)
self.csv_path = config_data.get(ptype, {}).get('csv_path', None)
self.header_path = config_data.get(ptype, {}).get('header_path', None)
self.vdetail = config_data.get(ptype, {}).get('vdetail', None)
self.vtype = config_data.get(ptype, {}).get('vtype', None)
self.bias = config_data.get(ptype, {}).get('bias', 0)
return 0
except:
return -1

class CsvData:
def __init__(self, bias=0, vdetail='Virtualization Details', vtype='Bit or Field Virtualization Type'):
# 初始化成员变量,ans 为一个空数组
self.ans = []
self.bias = bias
self.vdetail=vdetail
self.vtype=vtype
self.body = []

def parse_csv(self, csv_path):
self.ans = []
try:
df = pandas.read_csv(csv_path, skiprows=range(int(self.bias)))
columns = df.columns.tolist()
column_indices = {column: index for index, column in enumerate(columns)}
except:
return -1

for index, row in df.iterrows():
virtualization_type = row[columns[column_indices[self.vtype]]]

# if "Bit or Field Virtualization Type"="Fixed"
if virtualization_type == 'Fixed':
entry = []
leaf = row[columns[column_indices['Leaf']]]
sl_from = row[columns[column_indices['Sub-Leaf From']]]
sl_to = row[columns[column_indices['Sub-Leaf To']]]
if isinstance(sl_from, float) and math.isnan(sl_from):
sl_from = 0x0
sl_to = 0x0
else:
sl_from = int(sl_from, 16)
sl_to = int(sl_to, 16)
reg = row[columns[column_indices['Reg.']]]
msb = int(row[columns[column_indices['MSB']]])
lsb = int(row[columns[column_indices['LSB']]])
field_size = int(row[columns[column_indices['Field Size']]])
virtualization_details = str(row[columns[column_indices[self.vdetail]]])
field_name = row[columns[column_indices['Field Name']]]

for i in range(sl_from, sl_to + 1):
subleaf = str(hex(i))
entry = [leaf, subleaf, reg, msb, lsb, field_size, field_name, virtualization_details]
self.ans.append(entry)
return 0

def get_body(self):
self.body = []
for entry in self.ans:
leaf = entry[0]
subleaf = entry[1]
reg = entry[2]
msb = entry[3]
lsb = entry[4]
size = entry[5]
name = entry[6]
val = entry[7]
if entry[5] == 32:
self.body.append("EXP_CPUID_BYTE(%s, %s, %s, %s, %s);\t//%s" % ( \
leaf, subleaf, reg, val, version, name))

elif entry[5] == 1:
self.body.append("EXP_CPUID_BIT(%s, %s, %s, %s, %s, %s);\t//%s" % ( \
leaf, subleaf, reg, msb, val, version, name))
else:
self.body.append("EXP_CPUID_RES_BITS(%s, %s, %s, %s, %s, %s);\t//%s" % ( \
leaf, subleaf, reg, lsb, msb, version, name))

def write2header(path, list, ptype, funcName="initial_cpuid"):
"""
gen a header file
:param path:
:param list: stores the generated statements for all cases.
:param funcName: the initial-func name defined in header file.
:return: if -1 is returned, it means the write failed
"""
function_name = f"void {funcName}(void)"
ptype = ptype.upper()
try:
with open(path, 'w') as header_file:
header_file.write(f"#define AUTOGEN_{ptype}\n\n")
header_file.write(f"{function_name} {{\n")

for line in list:
header_file.write('\t' + line + '\n')
header_file.write("}\n")
return 0
except:
return -1

if __name__ == '__main__':

# init all params
config_path = 'config.json'
ptype = "cpuid"
path_info = GetPath(config_path)
if path_info.read_config_csv(ptype) == -1:
print("Failed to read config. Exiting program.")
sys.exit(1)


# parse to a list
get_csv = CsvData(path_info.bias)
get_csv.parse_csv(path_info.csv_path)
if get_csv.ans == []:
print("Failed to parse csv. Exiting program.")
sys.exit(1)
#assert get_csv.ans, "ans is empty. Exiting program."
get_csv.get_body()

#gen a header file
write2header(path_info.header_path, get_csv.body, ptype)






23 changes: 23 additions & 0 deletions tdx-compliance/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"cpuid":{
"csv_path": "aa.csv",
"header_path": "cpuid_case.h",
"vdetail": "",
"vtype": "",
"bias": "2"
},
"cr":{
"csv_path": "",
"header_path": "",
"vdetail": "",
"vtype": "",
"bias": "2"
},
"msr":{
"csv_path": "",
"header_path": "msr_case.h",
"vdetail": "",
"vtype": "",
"bias": "2"
}
}
4 changes: 4 additions & 0 deletions tdx-compliance/tdx-compliance-cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
list_add_tail(&t->list, &cpuid_list); \
} while (0)

#ifdef AUTOGEN_CPUID
extern void initial_cpuid(void);
#else
void initial_cpuid(void)
{
/* CPUID(0x0) */
Expand Down Expand Up @@ -540,3 +543,4 @@ void initial_cpuid(void)
/* CPUID(0x80000008).EDX */
EXP_CPUID_RES_BITS(0x80000008, 0x0, edx, 0, 31, VER1_0); //Reserved
}
#endif

0 comments on commit 8ba3543

Please sign in to comment.