Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add instruction check tests #247

Merged
merged 2 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions BM/instruction-check/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Instruction Check

This README provides information about the `instruction-check` project, which focuses on the CPUID instruction in computer processors. The CPUID instruction allows software programs to query and retrieve detailed information about the processor, including the manufacturer, model, features, and other characteristics.

## CPUID Check Tool

In the `LKVS/tools` directory, you can find a pre-existing tool for checking CPUID information. This tool supports six parameters, for example: `cpuid_check 1 0 0 0 c 25`. The first four parameters represent the input values for the EAX, EBX, ECX, and EDX registers, while `c` indicates checking the output of the ECX register, and `25` represents checking the 25th bit.

## Preparation

### 1. Install the Avocado Test Framework
The Instruction Check project utilizes the Avocado Test Framework, so it needs to be installed first. You can install the Avocado test framework using either of the following methods:

1. Source code installation:
```
git clone git://github.com/avocado-framework/avocado.git
cd avocado
pip install .
```
2. Installation via pip:
```
pip3 install --user avocado-framework
```

### 2. Install the HTML plugin
After installing the framework, you also need to install the HTML plugin for generating test results in HTML format. You can do this by running the following command:
``pip install avocado-framework-plugin-result-html``

## Usage 1

### 1. Compile the cpuid_check tool
Run the command:
``./setup.sh``

### 2. Execute instruction_check.py
Run the command:
``./instruction_check.py`` or ``python instruction_check.py``

## Usage 2
Usage 1 assembles each test into an Avocado job, so it can be executed directly by calling the Python interpreter. We also provide another method, which generates Avocado test classes based on the information in feature_list.py and writes them into the file cpuid_test.py.

### 1. Compile the cpuid_check tool
Run the command:
``./setup.sh``

### 2. Generate Avocado tests
Run the command:
``./auto_gen_test.py`` or ``python auto_gen_test.py``

### 3. Use Avocado to run tests
Run the command:
``avocado run cpuid_test.py``
36 changes: 36 additions & 0 deletions BM/instruction-check/auto_gen_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/python
import os
from feature_list import cpuid_info

# Template string, used to generate code for each test class
class_template = """
class {class_name}(Test):
def test(self):
cmd = os.path.join(source_dir, file_name + ' ' + ' '.join({args}))
cmd_result = process.run(cmd, ignore_status=True)
self.assertEqual(cmd_result.exit_status, expected_result)
"""

def generate_cpuid_tests():
with open('cpuid_test.py', 'w') as f:
script_dir = os.path.dirname(__file__)
parent_dir = os.path.dirname(script_dir)
grandparent_dir = os.path.dirname(parent_dir)
source_dir = f"{grandparent_dir}/tools/cpuid_check"
# Write the necessary imports and variable definitions
f.write(f'''#!/usr/bin/python

import os
from avocado import Test
from avocado.utils import process

source_dir = "{source_dir}"
file_name = "cpuid_check"
expected_result = 0
''')
# For each feature in feature_list.py generates a test class
for feature, args in cpuid_info.items():
class_code = class_template.format(class_name=feature, args=args)
f.write(class_code)

generate_cpuid_tests()
49 changes: 49 additions & 0 deletions BM/instruction-check/feature_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
cpuid_info = {
"AESNI": ['1', '0', '0', '0', 'c', '25'],
"XSAVE": ['1', '0', '0', '0', 'c', '26'],
"FSGSBASE": ['7', '0', '0', '0', 'b', '0'],
"SMEP": ['7', '0', '0', '0', 'b', '7'],
"RDT_A": ['7', '0', '0', '0', 'b', '15'],
"AVX512_IFMA": ['7', '0', '0', '0', 'b', '21'],
"SHA_NI": ['7', '0', '0', '0', 'b', '29'],
"AVX512_VBMI": ['7', '0', '0', '0', 'c', '1'],
"UMIP": ['7', '0', '0', '0', 'c', '2'],
"WAITPKG": ['7', '0', '0', '0', 'c', '5'],
"AVX512_VBMI2": ['7', '0', '0', '0', 'c', '6'],
"CET_SS": ['7', '0', '0', '0', 'c', '7'],
"GFNI": ['7', '0', '0', '0', 'c', '8'],
"VAES": ['7', '0', '0', '0', 'c', '9'],
"AVX512_VNNI": ['7', '0', '0', '0', 'c', '11'],
"AVX512_BITALG": ['7', '0', '0', '0', 'c', '12'],
"RDPID": ['7', '0', '0', '0', 'c', '22'],
"KL": ['7', '0', '0', '0', 'c', '23'],
"CLDEMOTE": ['7', '0', '0', '0', 'c', '25'],
"MOVDIRI": ['7', '0', '0', '0', 'c', '27'],
"MOVDIR64B": ['7', '0', '0', '0', 'c', '28'],
"PKS": ['7', '0', '0', '0', 'c', '31'],
"UINTR": ['7', '0', '0', '0', 'd', '5'],
"AVX512_VP2INTERSECT": ['7', '0', '0', '0', 'd', '8'],
"SERIALIZE": ['7', '0', '0', '0', 'd', '14'],
"TSXLDTRK": ['7', '0', '0', '0', 'd', '16'],
"CET_IBT": ['7', '0', '0', '0', 'd', '20'],
"AMX_BF16": ['7', '0', '0', '0', 'd', '22'],
"AVX512_FP16": ['7', '0', '0', '0', 'd', '23'],
"AMX_TILE": ['7', '0', '0', '0', 'd', '24'],
"AMX_INT8": ['7', '0', '0', '0', 'd', '25'],
"AVX_VNNI": ['7', '0', '1', '0', 'a', '4'],
"FRED": ['7', '0', '1', '0', 'a', '17'],
"WRMSRNS": ['7', '0', '1', '0', 'a', '19'],
"AMX_FP16": ['7', '0', '1', '0', 'a', '21'],
"AVX_IFMA": ['7', '0', '1', '0', 'a', '23'],
"AVX_VNNI_INT8": ['7', '0', '1', '0', 'd', '4'],
"AVX_NE_CONVERT": ['7', '0', '1', '0', 'd', '5'],
"XFD": ['d', '0', '1', '0', 'a', '4'],
"KL_BITMAP0": ['19', '0', '0', '0', 'a', '0'],
"KL_BITMAP1": ['19', '0', '0', '0', 'a', '1'],
"KL_BITMAP2": ['19', '0', '0', '0', 'a', '2'],
"AESKLE": ['19', '0', '0', '0', 'b', '0'],
"AES_WIDE": ['19', '0', '0', '0', 'b', '2'],
"KL_IWKEYBACKUP": ['19', '0', '0', '0', 'b', '4'],
"KL_RANDOM_IWKEY": ['19', '0', '0', '0', 'c', '1']
# Add more cpuid_info here
}
25 changes: 25 additions & 0 deletions BM/instruction-check/instruction_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/python

import sys
from avocado.core.job import Job
from avocado.core.nrunner.runnable import Runnable
from avocado.core.suite import TestSuite
from feature_list import cpuid_info

def main():
feature_name_list = cpuid_info.keys()

suites = []

for feature_name in feature_name_list:
args = cpuid_info[feature_name]
runnable = Runnable("exec-test", "../tools/cpuid_check/cpuid_check", *args)
suite = TestSuite(name=feature_name, tests=[runnable])
suites.append(suite)

# Run the test suites
with Job(test_suites=suites) as j:
sys.exit(j.run())

if __name__=="__main__":
main()
5 changes: 5 additions & 0 deletions BM/instruction-check/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
PARENT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PARENT_DIR/tools" || exit 1
make
Loading