Skip to content

Commit 363483e

Browse files
committed
nai_68int6: add wolfBoot target for the NAI 68INT6 (Intel Tiger Lake UP3) OpenVPX SBC
1 parent aa6fdb8 commit 363483e

21 files changed

Lines changed: 1771 additions & 130 deletions

‎arch.mk‎

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,13 +2207,13 @@ ifeq ($(USE_GCC),1)
22072207
endif
22082208
OUTPUT_FLAG?=-o
22092209

2210-
ifeq ($(filter $(TARGET),x86_fsp_qemu kontron_vx3060_s2),$(TARGET))
2210+
ifeq ($(filter $(TARGET),x86_fsp_qemu kontron_vx3060_s2 nai_68int6),$(TARGET))
22112211
FSP=1
22122212
CFLAGS+=-ffunction-sections -fdata-sections -ffreestanding -nostdlib -static
22132213
# some std libc have headers that bring in extra symbols used in
22142214
# FORTIFY_SOURCE realated checks. Use -U_FORTIFY_SOURCE to avoid that.
22152215
CFLAGS+=-U_FORTIFY_SOURCE
2216-
ifeq ($(TARGET), kontron_vx3060_s2)
2216+
ifeq ($(filter $(TARGET),kontron_vx3060_s2 nai_68int6),$(TARGET))
22172217
FSP_TGL=1
22182218
CFLAGS+=-DWOLFBOOT_TGL=1
22192219
endif
@@ -2263,23 +2263,20 @@ ifeq ("${FSP}", "1")
22632263
OBJS += src/image.o
22642264
OBJS += src/keystore.o
22652265
OBJS += src/sig_wolfboot_raw.o
2266-
ifeq ($(TARGET), kontron_vx3060_s2)
2267-
OBJS += hal/kontron_vx3060_s2_loader.o
2268-
endif
22692266
OBJS += $(WOLFCRYPT_OBJS)
22702267
CFLAGS+=-DSTAGE1_AUTH
22712268
endif
22722269

2270+
# Generic stage1 loader HAL (stubs); shared by all x86 FSP targets.
2271+
OBJS += hal/stub_loader.o
2272+
22732273
CFLAGS += -fno-stack-protector -m32 -fno-PIC -fno-pie -mno-mmx -mno-sse -DDEBUG_UART
22742274
CFLAGS += -DFSP_M_BASE=$(FSP_M_BASE)
22752275
ifeq ($(FSP_TGL), 1)
22762276
OBJS+=src/x86/tgl_fsp.o
22772277
OBJS+=src/ucode0.o
22782278
CFLAGS += -DUCODE0_ADDRESS=$(UCODE0_BASE)
22792279
endif
2280-
ifeq ($(TARGET),x86_fsp_qemu)
2281-
OBJS += hal/x86_fsp_qemu_loader.o
2282-
endif
22832280
else
22842281
# building wolfBoot
22852282
ifeq ($(FSP_TGL), 1)

‎config/examples/nai_68int6.config‎

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# NAI 68INT6 3U OpenVPX SBC (Tiger Lake UP3); needs the board's own FSP
2+
# (nai_extract_fsp.sh). See the NAI 68INT6 section of docs/Targets.md.
3+
4+
ARCH=x86_64
5+
TARGET=nai_68int6
6+
WOLFBOOT_SMALL_STACK=0
7+
8+
# ECC P-384 signature, SHA-384 digest (measured boot uses SHA-256 on an
9+
# SLB9670). See the integrity-algorithm table in docs/Targets.md.
10+
SIGN=ECC384
11+
HASH=SHA384
12+
13+
DEBUG=1
14+
# FSP-M UPD dump on the console before FspMemInit (bring-up aid).
15+
DUMP_FSP_UPD=0
16+
SPMATH=1
17+
ENCRYPTION=0
18+
WOLFBOOT_NO_PARTITIONS=1
19+
# Disk boot: signed kernels in GPT partitions 3/4, Ubuntu root in partition 2.
20+
# The A/B boot-partition indices are set per target in src/update_disk.c.
21+
WOLFBOOT_BOOT_DISK=0
22+
FORCE_32BIT=1
23+
24+
########## Flash layout (measured from the factory descriptor, 32 MB) ##########
25+
WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff400000
26+
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0
27+
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0
28+
WOLFBOOT_LOAD_BASE=0x58000200
29+
WOLFBOOT_SECTOR_SIZE?=0x1000
30+
WOLFBOOT_DATA_ADDRESS=0x1000000
31+
32+
FSP_CONFIG_BASE=0xffe9f800
33+
FSP_T_BASE=0xfff59000
34+
FSP_M_BASE=0xfff60000
35+
36+
WOLFBOOT_ORIGIN=0xfff00000
37+
BOOTLOADER_PARTITION_SIZE=0x600000
38+
# Inert (the flash descriptor is used); kept for config parity.
39+
BIOS_REGION_SIZE=0xc00000
40+
41+
UCODE0_BASE=0xffd90000
42+
UCODE0_BIN=src/x86/ucode0.bin
43+
44+
FSP_T_BIN=./src/x86/fsp_t.bin
45+
FSP_M_BIN=./src/x86/fsp_m.bin
46+
FSP_S_BIN=./src/x86/fsp_s.bin
47+
FSP_S_UPD_DATA_BIN=./src/x86/fsp_s_upd_data.bin
48+
# Boot Guard is left to the board owner: supply an ACM and key here to build a
49+
# Boot-Guard image. Unset, wolfBoot builds and boots without it.
50+
ACM_BIN=
51+
FSP_S_LOAD_BASE=0x0FED5F00
52+
53+
POLICY_BASE=0xffaa4000
54+
KEYSTORE_OFFSET=0x3FE00
55+
KEYSTORE_STAGE1_OFFSET=0x400
56+
57+
########## Console: LPSS UART2 (PCI 00:19.2), verified on hardware ##########
58+
X86_UART_NUMBER=2
59+
X86_UART_BASE=0xFE032000
60+
X86_UART_REG_WIDTH=4
61+
X86_UART_MMIO=1
62+
63+
########## PCH / PCI ##########
64+
PCH_PCR_BASE=0xFD000000
65+
PCI_ECAM_BASE=0xC0000000
66+
PCI_USE_ECAM=1
67+
PCH_HAS_PCR=1
68+
# Generate ACPI tables so Linux gets the interrupt model and PCI routing.
69+
ACPI=1
70+
71+
########## Payload: signed 64-bit Linux bzImage ##########
72+
64BIT=1
73+
ELF=1
74+
DEBUG_ELF=0
75+
MULTIBOOT2=1
76+
LINUX_PAYLOAD=1
77+
78+
########## Security ##########
79+
STAGE1_AUTH=1
80+
WOLFTPM=1
81+
MEASURED_BOOT=1
82+
MEASURED_PCR_A=0
83+
# Measure the verified OS image into PCR4, alongside the firmware in PCR0.
84+
MEASURED_PCR_OS=4
85+
WOLFBOOT_UNIVERSAL_KEYSTORE=1
86+
WOLFBOOT_SKIP_AUTH_CHECK=0
87+
ENABLE_DEBUG_CONSENT=0
88+
89+
# Deferred: TPM sealing and ATA disk lock/erase.
90+
WOLFBOOT_TPM_SEAL=0
91+
DISK_LOCK=0
92+
DISK_ERASE=0
93+
94+
# Anti-rollback: persistent version floor + audit counters in TPM NV
95+
# (trust-on-first-use; provision before first boot where that matters).
96+
ANTI_ROLLBACK=1

‎docs/Targets.md‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This README describes configuration of supported targets.
1414
* [Infineon AURIX TC4xx](#infineon-aurix-tc4xx)
1515
* [Intel x86-64 Intel FSP](#intel-x86_64-with-intel-fsp-support)
1616
* [Kontron VX3060-S2](#kontron-vx3060-s2)
17+
* [NAI 68INT6 (Intel Tiger Lake)](#nai-68int6-intel-tiger-lake)
1718
* [Microchip PIC32CK](#microchip-pic32ck)
1819
* [Microchip PIC32CZ](#microchip-pic32cz)
1920
* [Microchip PolarFire SoC](#microchip-polarfire-soc)
@@ -9609,6 +9610,74 @@ Attempting boot from partition A
96099610
```
96109611
At this point, the kernel image in partition "A" is verified and staged and you should be seeing the log messages of your OS booting.
96119612

9613+
## NAI 68INT6 (Intel Tiger Lake)
9614+
9615+
wolfBoot target `nai_68int6` for the North Atlantic Industries 68INT6, a 3U OpenVPX SOSA-aligned single board computer (Intel Core i7-1185GRE, Tiger Lake UP3). It uses the Intel FSP support described [above](#intel-x86_64-with-intel-fsp-support) and shares the Tiger Lake path with the Kontron target. wolfBoot boots a signed 64-bit Linux from the SATA disk with A/B update, measured boot and TPM anti-rollback, verified on a Rev D5 bench board. The public Tiger Lake FSP does not train this board's memory, so the FSP is extracted from a 68INT6 BIOS image.
9616+
9617+
| | |
9618+
|---|---|
9619+
| CPU | i7-1185GRE (`06-8C-01`), Tiger Lake UP3, PCH-LP |
9620+
| Memory | 2 x 32 GB DDR4-3200 SODIMM, non-ECC |
9621+
| BIOS flash | Rev C/D5: 2 x W25R256JV (32 MB), selected by JP36. Next revision: one 64 MB device |
9622+
| TPM | SLB9670 (SHA-1/256), or SLB9672, which adds a SHA-384 bank |
9623+
| Storage | Onboard SATA SSD, AHCI at `00:17.0` |
9624+
| Console | LPSS UART2, PCI `00:19.2`, RS-232; `X86_UART_NUMBER=2` |
9625+
9626+
### Building
9627+
9628+
```
9629+
cp config/examples/nai_68int6.config .config
9630+
./tools/scripts/x86_fsp/tgl/tgl_download_fsp.sh # FSP UPD headers, first time only
9631+
./tools/scripts/x86_fsp/tgl/nai_extract_fsp.sh <68INT6.bin> # board's own FSP blobs
9632+
./tools/scripts/x86_fsp/tgl/assemble_image.sh -k # generate signing keys
9633+
make
9634+
./tools/scripts/x86_fsp/tgl/assemble_image.sh -n <68INT6.bin>
9635+
```
9636+
9637+
`nai_extract_fsp.sh` takes FSP-T/M/S and the microcode from a 68INT6 BIOS image. Without it the build uses the public FSP, which compiles but does not train memory. The `-n` stitch replaces the top 6 MB (`BOOTLOADER_PARTITION_SIZE`) of the 12 MB BIOS region and keeps the descriptor and CSME byte for byte. The board has no recovery region (recovery is the second flash device), so use `-n`, not `-m`. The result is `final_image.bin`.
9638+
9639+
### Integrity algorithms
9640+
9641+
ECC P-384 and SHA-384 match what Intel Boot Guard uses for the Initial Boot Block.
9642+
9643+
| Layer | Algorithm |
9644+
|---|---|
9645+
| Image signature | ECC P-384 (`SIGN=ECC384`) |
9646+
| Image digest | SHA-384 (`HASH=SHA384`) |
9647+
| Measured boot PCR | SHA-256 (the SLB9670 has only SHA-1 and SHA-256 banks) |
9648+
9649+
`wolfBoot_image_measure()` re-hashes the authenticated digest with the PCR bank's algorithm, so one image serves either TPM. `MEASURED_PCR_ALG=SHA384` needs an SLB9672 with its SHA-384 bank allocated (`TPM2_PCR_Allocate` under platform auth, a provisioning step).
9650+
9651+
### Configuration
9652+
9653+
Notable options in [config/examples/nai_68int6.config](../config/examples/nai_68int6.config):
9654+
9655+
| Option | Meaning |
9656+
|---|---|
9657+
| `X86_UART_NUMBER=2` | LPSS UART2 for all three FSP phases (Kontron uses 0) |
9658+
| `ACPI=1` | Required. Generates ACPI tables (RSDP/XSDT/FADT/MADT/MCFG and a minimal DSDT); the board's PCI interrupt routing is only in the DSDT `_PRT`, since the MP table is the Kontron one |
9659+
| `ANTI_ROLLBACK=1` | Persistent version floor and boot audit counters in TPM NV |
9660+
| `MEASURED_BOOT=1`, `MEASURED_PCR_OS=4` | Firmware into PCR 0, the verified OS image into PCR 4 |
9661+
| `WOLFBOOT_BOOT_DISK=0` | Boot from GPT partitions; the A/B indices (sda3/sda4) are set in `src/update_disk.c` |
9662+
9663+
### BIOS region lock
9664+
9665+
Before handoff, `hal_flash_protect()` in the shared Tiger Lake HAL (`hal/x86_fsp_tgl.c`, as on Kontron) sets SPI Flash Protected Range 0 over the BIOS region with read and write protection, then FLOCKDN. Both hold until the next platform reset, so the booted OS cannot read or reprogram the BIOS region; update it with an external programmer.
9666+
9667+
### Anti-rollback
9668+
9669+
`ANTI_ROLLBACK=1` keeps a version floor and boot audit counters in a TPM NV index; the backend is `src/boot_state_tpm.c` and the policy is `src/boot_state.c`. The floor is the highest version ever booted, set trust-on-first-use. A validly signed older image still boots and records a rollback event. Only an untrustworthy reference halts the boot; `ANTI_ROLLBACK_HALT_ON_FAILURE=1` also halts when the TPM is unreachable, a write fails or the platform hierarchy cannot be disabled.
9670+
9671+
TPM NV is used instead of the partition state trailer because the floor must survive a full reimage of the disk or flash. `DISK_BOOT_CONFIRM` still handles per-slot confirmation, and the backend can move to a root-of-trust device later without changing the policy.
9672+
9673+
`ALLOW_DOWNGRADE` is left unset, the secure default: if the higher-versioned slot fails to verify, wolfBoot halts (`Rollback to lower version not allowed`) rather than boot the lower one. Building with `ALLOW_DOWNGRADE=1` allows that fall-back and leaves the TPM floor as the only rollback guard.
9674+
9675+
The booted OS cannot lower the floor. The index is platform-created and writable only under platform auth (`TPMA_NV_PPWRITE`), and on every boot wolfBoot disables the platform hierarchy (`TPM2_HierarchyControl`) until the next TPM reset, as in section 10 of the TCG PC Client Platform specification. The OS can then neither write nor undefine the index. An index with any other write attributes is treated as corrupt. Platform-auth provisioning, such as `TPM2_PCR_Allocate`, must be done before wolfBoot is installed.
9676+
9677+
### Boot, programming and recovery
9678+
9679+
wolfBoot boots the highest-versioned signed 64-bit `bzImage` that verifies from the two GPT boot partitions. It falls back to the other slot only if that is not a downgrade (see Anti-rollback), and halts if neither boots. Program the flash with a Dediprog SF100 on JP4 while the board is off; the BIOS region lock blocks `flashrom` from the booted OS. JP36 selects which bank boots and which one the programmer sees; move it only with the board off.
9680+
96129681
## Infineon PSOC Control C3
96139682

96149683
The [PSOC Control C3](https://www.infineon.com/products/microcontroller/32-bit-psoc-arm-cortex/32-bit-psoc-control-arm-cortex-m33-mcu/psoc-control-c3-main-line) family (PSC3, CAT1B) is an Arm Cortex-M33 motor-control MCU. wolfBoot runs as the first application the BootROM launches, verifies the signed firmware in the BOOT partition and jumps to it.

‎hal/kontron_vx3060_s2.c‎

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -31,87 +31,6 @@
3131

3232
#ifdef __WOLFBOOT
3333

34-
#define SPI_PCI_DEV 31
35-
#define SPI_PCI_FUN 5
36-
#define SPI_BAR_OFF 0x10
37-
/* Tiger Lake SPI controller register offsets, memory-mapped at the
38-
* BAR0 base. FREG1 holds the BIOS flash region base/limit (region 0
39-
* is the flash descriptor); FPR0 is the protected range register
40-
* with the same base/limit layout. Offsets per the Intel PCH SPI
41-
* register map (see drivers/spi/spi-intel.c in the Linux kernel):
42-
* FDATA0-15 at 0x10-0x4C, FRACC at 0x50, FREG0-7 at 0x54-0x74,
43-
* FPR0-4 at 0x84-0x9C. */
44-
#define SPI_FREG1 0x58
45-
#define SPI_FREG_BASE_MASK (0x7fffU << 0)
46-
#define SPI_FREG_LIMIT_MASK (0x7fffU << 16)
47-
#define SPI_FREG_LIMIT_SHIFT (16)
48-
#define SPI_FREG_ADDR_SHIFT (12)
49-
#define SPI_FPR0 (0x84)
50-
#define SPI_FPR_WPE (1U << 31)
51-
#define SPI_FPR_RPE (1U << 15)
52-
#define SPI_BIOS_HSFSTS_CTL (0x4)
53-
#define SPI_FLOCKDN (1U << 15)
54-
55-
int tgl_lock_bios_region()
56-
{
57-
uint32_t spi_bar, spi_cmd;
58-
uint32_t reg;
59-
int ret = 0;
60-
61-
#if defined(DEBUG)
62-
uint32_t bios_reg_base, bios_reg_lim;
63-
#endif
64-
65-
spi_bar = pci_config_read32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_BAR0_OFFSET);
66-
spi_bar &= PCI_BAR_MASK;
67-
spi_cmd =
68-
pci_config_read32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET);
69-
pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET,
70-
spi_cmd | PCI_COMMAND_MEM_SPACE);
71-
72-
/* The Flash Protected Range register has the same base/limit
73-
* layout as the Flash Region register: take the BIOS region
74-
* (FREG1, flash region 1) and enable read and write protection
75-
* on it. The SPI registers live in the BAR's memory-mapped
76-
* space, not in PCI configuration space. */
77-
reg = mmio_read32(spi_bar + SPI_FREG1);
78-
#if defined(DEBUG)
79-
bios_reg_base = (reg & SPI_FREG_BASE_MASK) << SPI_FREG_ADDR_SHIFT;
80-
bios_reg_lim = ((reg & SPI_FREG_LIMIT_MASK) >> SPI_FREG_LIMIT_SHIFT)
81-
<< SPI_FREG_ADDR_SHIFT;
82-
wolfBoot_printf("Bios reg base: 0x%x lim: 0x%x\r\n", bios_reg_base,
83-
bios_reg_lim);
84-
#endif
85-
reg |= (SPI_FPR_RPE) | (SPI_FPR_WPE);
86-
mmio_write32(spi_bar + SPI_FPR0, reg);
87-
if ((mmio_read32(spi_bar + SPI_FPR0) &
88-
(SPI_FPR_RPE | SPI_FPR_WPE)) != (SPI_FPR_RPE | SPI_FPR_WPE)) {
89-
ret = -1;
90-
}
91-
92-
/* lock down BIOS register configuration */
93-
reg = mmio_read32(spi_bar + SPI_BIOS_HSFSTS_CTL);
94-
reg |= SPI_FLOCKDN;
95-
mmio_write32(spi_bar + SPI_BIOS_HSFSTS_CTL, reg);
96-
if ((mmio_read32(spi_bar + SPI_BIOS_HSFSTS_CTL) & SPI_FLOCKDN) == 0) {
97-
ret = -1;
98-
}
99-
100-
/* restore original cmd */
101-
pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET, spi_cmd);
102-
return ret;
103-
}
104-
105-
int hal_flash_protect(haladdr_t address, int len)
106-
{
107-
(void)address;
108-
(void)len;
109-
110-
/* The TGL BIOS region covers the bootloader partition, so the
111-
* hook's address/len are the same range FREG1 describes. */
112-
return tgl_lock_bios_region();
113-
}
114-
11534
void hal_init(void)
11635
{
11736
gdt_setup_table();

0 commit comments

Comments
 (0)