Skip to content
Open
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
61 changes: 61 additions & 0 deletions apps/uefi/vendor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Vendor INF Files

Vendor-specific INF files that extend public sysarch-acs with vendor tests.

## Architecture

```
apps/uefi/
├── Bsa.inf # Public BSA
├── Sbsa.inf # Public SBSA
├── xbsa_acpi.inf # Public xBSA ACPI
└── vendor/
├── verify_vendor_inf.sh # Sync verification script
└── nvidia/
├── BsaNvidia.inf # BSA + NVIDIA tests
├── SbsaNvidia.inf # SBSA + NVIDIA tests
└── XbsaAcpiNvidia.inf # xBSA ACPI + NVIDIA tests
```

## Build Commands

```bash
# Public builds (no vendor argument)
source acsbuild.sh bsa
source acsbuild.sh sbsa
source acsbuild.sh xbsa_acpi

# Vendor builds (add vendor name as second argument)
source acsbuild.sh bsa nvidia
source acsbuild.sh sbsa nvidia
source acsbuild.sh xbsa_acpi nvidia
```

## Build-Time Sync Check

Vendor builds automatically verify that vendor INFs include all upstream tests.
If sync is broken, the build fails and shows missing tests.

Manual verification:
```bash
./apps/uefi/vendor/verify_vendor_inf.sh nvidia
```

## Adding a New Vendor

1. Create directory: `apps/uefi/vendor/<vendor>/`

2. Create vendor INFs (copy from nvidia/ and modify):
- Change `BASE_NAME` and `FILE_GUID`
- Capitalize vendor name in INF filename (e.g., `BsaQualcomm.inf`)
- Update paths and vendor test sources

3. The build script auto-detects vendor INFs by naming convention:
- `<AcsType><Vendor>.inf` (e.g., `BsaNvidia.inf`, `XbsaAcpiQualcomm.inf`)

## Syncing with Upstream

When upstream adds/removes tests:
1. Run `./verify_vendor_inf.sh <vendor>` to find missing tests
2. Update vendor INFs accordingly
3. Re-verify before building
158 changes: 158 additions & 0 deletions apps/uefi/vendor/verify_vendor_inf.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/bin/bash
## @file
# Verify vendor INF files include all upstream tests
#
# Copyright (c) 2025, Arm Limited or its affiliates. All rights reserved.
# SPDX-License-Identifier : Apache-2.0
#
# Usage: ./verify_vendor_inf.sh [vendor_name]
# ./verify_vendor_inf.sh nvidia
# ./verify_vendor_inf.sh # verifies all vendors
##

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APPS_DIR="$(dirname "$SCRIPT_DIR")"

# Extract test sources from an INF file (excluding vendor tests and app sources)
extract_test_sources() {
local inf_file="$1"
grep -E '^\s*(\.\./)*test_pool/' "$inf_file" | \
grep -v 'vendor/' | \
sed 's|.*test_pool/|test_pool/|' | \
sed 's|\.c.*|.c|' | \
sort -u
}

# Compare upstream and vendor INF
verify_inf_pair() {
local upstream_inf="$1"
local vendor_inf="$2"
local upstream_name=$(basename "$upstream_inf" .inf)
local vendor_name=$(basename "$vendor_inf" .inf)

if [ ! -f "$upstream_inf" ]; then
echo "ERROR: Upstream INF not found: $upstream_inf"
return 1
fi

if [ ! -f "$vendor_inf" ]; then
echo "ERROR: Vendor INF not found: $vendor_inf"
return 1
fi

echo "Checking: $upstream_name -> $vendor_name"

# Extract sources
local upstream_sources=$(extract_test_sources "$upstream_inf")
local vendor_sources=$(extract_test_sources "$vendor_inf")

# Find missing sources
local missing=""
for src in $upstream_sources; do
if ! echo "$vendor_sources" | grep -q "^${src}$"; then
missing="$missing - $src\n"
fi
done

if [ -n "$missing" ]; then
echo " FAIL: Missing tests in $vendor_name:"
echo -e "$missing"
return 1
else
echo " PASS: All upstream tests present"
return 0
fi
}

# Verify a vendor
verify_vendor() {
local vendor="$1"
local vendor_dir="$SCRIPT_DIR/$vendor"
local errors=0
local found_infs=0

echo "========================================"
echo "Verifying vendor: $vendor"
echo "========================================"

# Check if vendor directory exists
if [ ! -d "$vendor_dir" ]; then
echo "WARNING: Vendor directory not found: $vendor_dir"
echo " No vendor INFs to verify (this is OK if vendor tests not yet added)"
return 0
fi

# Check each INF file in vendor directory
# Look for pattern: <AcsType><Vendor>.inf (e.g., BsaNvidia.inf, XbsaAcpiNvidia.inf)
for vendor_inf in "$vendor_dir"/*.inf; do
[ -f "$vendor_inf" ] || continue

local inf_basename=$(basename "$vendor_inf" .inf)

# Skip if doesn't match vendor naming pattern
# Extract the ACS type by removing vendor name suffix (case insensitive)
local vendor_upper="${vendor^}" # Capitalize first letter
local acs_type=$(echo "$inf_basename" | sed "s/${vendor_upper}$//i")

# Skip if no ACS type extracted (means it's not a vendor INF)
[ -z "$acs_type" ] && continue
[ "$acs_type" == "$inf_basename" ] && continue

((found_infs++))

# Determine upstream INF name
local upstream_inf="$APPS_DIR/${acs_type}.inf"

if [ -f "$upstream_inf" ]; then
verify_inf_pair "$upstream_inf" "$vendor_inf" || ((errors++))
else
echo "WARNING: No upstream INF found for $vendor_inf (expected: $upstream_inf)"
fi
done

if [ $found_infs -eq 0 ]; then
echo " No vendor INF files found (this is OK if vendor tests not yet added)"
return 0
fi

return $errors
}

# Main
main() {
local total_errors=0
local vendors_checked=0

if [ -n "$1" ]; then
# Verify specific vendor
verify_vendor "$1"
total_errors=$?
vendors_checked=1
else
# Verify all vendors
for vendor_dir in "$SCRIPT_DIR"/*/; do
[ -d "$vendor_dir" ] || continue
vendor=$(basename "$vendor_dir")
[ "$vendor" = "." ] && continue
[ "$vendor" = "template" ] && continue # Skip template directory
verify_vendor "$vendor"
[ $? -ne 0 ] && ((total_errors++))
((vendors_checked++))
done
fi

echo ""
if [ $vendors_checked -eq 0 ]; then
echo "No vendor directories found. Vendor infrastructure ready for use."
exit 0
elif [ $total_errors -eq 0 ]; then
echo "All vendor INF files are in sync with upstream."
exit 0
else
echo "ERROR: $total_errors vendor(s) have sync issues."
echo "Please update vendor INF files to match upstream."
exit 1
fi
}

main "$@"
163 changes: 163 additions & 0 deletions test_pool/vendor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Vendor Test Pool

This directory contains vendor-specific tests that extend the standard BSA/SBSA test suites.

## Directory Structure

```
vendor/
├── README.md # This file
├── nvidia/ # NVIDIA-specific tests
│ ├── README.md # NVIDIA vendor test documentation
│ └── timer/ # Timer-related vendor tests
│ ├── vt001.c # Vendor timer test 001
│ └── ...
├── <vendor>/ # Other vendor directories
│ └── ...
└── template/ # Template for new vendor tests
└── vtest_template.c
```

## Adding Vendor Tests

### 1. Create Vendor Directory

Create a new directory under `vendor/` with your vendor name (lowercase):

```bash
mkdir -p test_pool/vendor/<vendor_name>/timer
```

### 2. Test Numbering Convention

Vendor tests use a separate numbering space to avoid conflicts with standard tests:

```c
/* Standard test numbering (reserved 0-9999) */
#define ACS_TIMER_TEST_NUM_BASE 400

/* Vendor test numbering (10000+) */
#define ACS_VENDOR_TEST_NUM_BASE 10000

/* Per-vendor offsets (1000 tests per vendor) */
#define ACS_VENDOR_NVIDIA_BASE (ACS_VENDOR_TEST_NUM_BASE + 0)
#define ACS_VENDOR_QUALCOMM_BASE (ACS_VENDOR_TEST_NUM_BASE + 1000)
#define ACS_VENDOR_MEDIATEK_BASE (ACS_VENDOR_TEST_NUM_BASE + 2000)
/* Add more vendors as needed */

/* Module offsets within vendor space (100 tests per module) */
#define VENDOR_TIMER_OFFSET 0
#define VENDOR_PCIE_OFFSET 100
#define VENDOR_PE_OFFSET 200
/* ... */
```

### 3. Test File Naming

Vendor tests should be named with a `v` prefix:
- `vt001.c` - Vendor timer test 001
- `vp001.c` - Vendor PCIe test 001
- `vpe001.c` - Vendor PE test 001

### 4. Test Rule ID Convention

Use vendor-prefixed rule IDs:
```c
#define TEST_RULE "NVIDIA_TIME_01" /* Vendor-specific rule */
```

### 5. Creating a Test

Copy the template and modify:

```c
#include "val/include/acs_val.h"
#include "val/include/acs_timer.h"
#include "val/include/acs_pe.h"

/* Test identification */
#define TEST_NUM (ACS_VENDOR_NVIDIA_BASE + VENDOR_TIMER_OFFSET + 1)
#define TEST_DESC "NVIDIA: Custom timer validation"
#define TEST_RULE "NVIDIA_TIME_01"

static void payload(uint32_t num_pe)
{
uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid());

/* Your test logic here */

val_set_status(index, RESULT_PASS(TEST_NUM, 1));
}

uint32_t
vt001_entry(uint32_t num_pe)
{
uint32_t status = ACS_STATUS_FAIL;

status = val_initialize_test(TEST_NUM, TEST_DESC, val_pe_get_num());
if (status != ACS_STATUS_SKIP)
payload(num_pe);

status = val_check_for_error(TEST_NUM, 1, TEST_RULE);
val_report_status(0, ACS_END(TEST_NUM), TEST_RULE);

return status;
}
```

### 6. Registering Vendor Tests

Add your test entry point to the appropriate execute file or create a vendor-specific executor.

## Running Vendor Tests

### Run All Vendor Tests
```bash
xbsa_acpi.efi -m VENDOR -v 1
```

### Run Specific Vendor Tests
```bash
xbsa_acpi.efi -r NVIDIA_TIME_01 -v 1
```

### Run Standard + Vendor Tests
```bash
xbsa_acpi.efi -m BSA,VENDOR -v 1
```

## Build Architecture

```
apps/uefi/
├── xbsa_acpi.inf # Public INF (unchanged from upstream)
└── vendor/nvidia/
└── XbsaAcpiNvidia.inf # Public tests + NVIDIA vendor tests
```

Vendor INF files copy the public test list and add vendor tests at the end.
When upstream is updated, sync the test list in vendor INF files.

### DSC Integration

```ini
[Components]
# Public build
ShellPkg/Application/sysarch-acs/apps/uefi/xbsa_acpi.inf

# OR NVIDIA internal build
ShellPkg/Application/sysarch-acs/apps/uefi/vendor/nvidia/XbsaAcpiNvidia.inf
```

## Guidelines

1. **Isolation**: Vendor tests should not modify or depend on standard test behavior
2. **Documentation**: Each vendor directory must have a README.md
3. **Compatibility**: Use only public VAL/PAL APIs
4. **Naming**: Follow the naming conventions strictly
5. **Testing**: Ensure vendor tests pass on the target platform before submission

## Contact

For questions about adding vendor tests, contact the sysarch-acs maintainers.

Loading