mirror of https://github.com/wolfSSL/wolfBoot.git
nai_68int6: add wolfBoot target for the NAI 68INT6 (Intel Tiger Lake UP3) OpenVPX SBC
parent
aa6fdb8fa9
commit
363483ed54
13
arch.mk
13
arch.mk
|
|
@ -2207,13 +2207,13 @@ ifeq ($(USE_GCC),1)
|
|||
endif
|
||||
OUTPUT_FLAG?=-o
|
||||
|
||||
ifeq ($(filter $(TARGET),x86_fsp_qemu kontron_vx3060_s2),$(TARGET))
|
||||
ifeq ($(filter $(TARGET),x86_fsp_qemu kontron_vx3060_s2 nai_68int6),$(TARGET))
|
||||
FSP=1
|
||||
CFLAGS+=-ffunction-sections -fdata-sections -ffreestanding -nostdlib -static
|
||||
# some std libc have headers that bring in extra symbols used in
|
||||
# FORTIFY_SOURCE realated checks. Use -U_FORTIFY_SOURCE to avoid that.
|
||||
CFLAGS+=-U_FORTIFY_SOURCE
|
||||
ifeq ($(TARGET), kontron_vx3060_s2)
|
||||
ifeq ($(filter $(TARGET),kontron_vx3060_s2 nai_68int6),$(TARGET))
|
||||
FSP_TGL=1
|
||||
CFLAGS+=-DWOLFBOOT_TGL=1
|
||||
endif
|
||||
|
|
@ -2263,13 +2263,13 @@ ifeq ("${FSP}", "1")
|
|||
OBJS += src/image.o
|
||||
OBJS += src/keystore.o
|
||||
OBJS += src/sig_wolfboot_raw.o
|
||||
ifeq ($(TARGET), kontron_vx3060_s2)
|
||||
OBJS += hal/kontron_vx3060_s2_loader.o
|
||||
endif
|
||||
OBJS += $(WOLFCRYPT_OBJS)
|
||||
CFLAGS+=-DSTAGE1_AUTH
|
||||
endif
|
||||
|
||||
# Generic stage1 loader HAL (stubs); shared by all x86 FSP targets.
|
||||
OBJS += hal/stub_loader.o
|
||||
|
||||
CFLAGS += -fno-stack-protector -m32 -fno-PIC -fno-pie -mno-mmx -mno-sse -DDEBUG_UART
|
||||
CFLAGS += -DFSP_M_BASE=$(FSP_M_BASE)
|
||||
ifeq ($(FSP_TGL), 1)
|
||||
|
|
@ -2277,9 +2277,6 @@ ifeq ("${FSP}", "1")
|
|||
OBJS+=src/ucode0.o
|
||||
CFLAGS += -DUCODE0_ADDRESS=$(UCODE0_BASE)
|
||||
endif
|
||||
ifeq ($(TARGET),x86_fsp_qemu)
|
||||
OBJS += hal/x86_fsp_qemu_loader.o
|
||||
endif
|
||||
else
|
||||
# building wolfBoot
|
||||
ifeq ($(FSP_TGL), 1)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
# NAI 68INT6 3U OpenVPX SBC (Tiger Lake UP3); needs the board's own FSP
|
||||
# (nai_extract_fsp.sh). See the NAI 68INT6 section of docs/Targets.md.
|
||||
|
||||
ARCH=x86_64
|
||||
TARGET=nai_68int6
|
||||
WOLFBOOT_SMALL_STACK=0
|
||||
|
||||
# ECC P-384 signature, SHA-384 digest (measured boot uses SHA-256 on an
|
||||
# SLB9670). See the integrity-algorithm table in docs/Targets.md.
|
||||
SIGN=ECC384
|
||||
HASH=SHA384
|
||||
|
||||
DEBUG=1
|
||||
# FSP-M UPD dump on the console before FspMemInit (bring-up aid).
|
||||
DUMP_FSP_UPD=0
|
||||
SPMATH=1
|
||||
ENCRYPTION=0
|
||||
WOLFBOOT_NO_PARTITIONS=1
|
||||
# Disk boot: signed kernels in GPT partitions 3/4, Ubuntu root in partition 2.
|
||||
# The A/B boot-partition indices are set per target in src/update_disk.c.
|
||||
WOLFBOOT_BOOT_DISK=0
|
||||
FORCE_32BIT=1
|
||||
|
||||
########## Flash layout (measured from the factory descriptor, 32 MB) ##########
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff400000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0
|
||||
WOLFBOOT_LOAD_BASE=0x58000200
|
||||
WOLFBOOT_SECTOR_SIZE?=0x1000
|
||||
WOLFBOOT_DATA_ADDRESS=0x1000000
|
||||
|
||||
FSP_CONFIG_BASE=0xffe9f800
|
||||
FSP_T_BASE=0xfff59000
|
||||
FSP_M_BASE=0xfff60000
|
||||
|
||||
WOLFBOOT_ORIGIN=0xfff00000
|
||||
BOOTLOADER_PARTITION_SIZE=0x600000
|
||||
# Inert (the flash descriptor is used); kept for config parity.
|
||||
BIOS_REGION_SIZE=0xc00000
|
||||
|
||||
UCODE0_BASE=0xffd90000
|
||||
UCODE0_BIN=src/x86/ucode0.bin
|
||||
|
||||
FSP_T_BIN=./src/x86/fsp_t.bin
|
||||
FSP_M_BIN=./src/x86/fsp_m.bin
|
||||
FSP_S_BIN=./src/x86/fsp_s.bin
|
||||
FSP_S_UPD_DATA_BIN=./src/x86/fsp_s_upd_data.bin
|
||||
# Boot Guard is left to the board owner: supply an ACM and key here to build a
|
||||
# Boot-Guard image. Unset, wolfBoot builds and boots without it.
|
||||
ACM_BIN=
|
||||
FSP_S_LOAD_BASE=0x0FED5F00
|
||||
|
||||
POLICY_BASE=0xffaa4000
|
||||
KEYSTORE_OFFSET=0x3FE00
|
||||
KEYSTORE_STAGE1_OFFSET=0x400
|
||||
|
||||
########## Console: LPSS UART2 (PCI 00:19.2), verified on hardware ##########
|
||||
X86_UART_NUMBER=2
|
||||
X86_UART_BASE=0xFE032000
|
||||
X86_UART_REG_WIDTH=4
|
||||
X86_UART_MMIO=1
|
||||
|
||||
########## PCH / PCI ##########
|
||||
PCH_PCR_BASE=0xFD000000
|
||||
PCI_ECAM_BASE=0xC0000000
|
||||
PCI_USE_ECAM=1
|
||||
PCH_HAS_PCR=1
|
||||
# Generate ACPI tables so Linux gets the interrupt model and PCI routing.
|
||||
ACPI=1
|
||||
|
||||
########## Payload: signed 64-bit Linux bzImage ##########
|
||||
64BIT=1
|
||||
ELF=1
|
||||
DEBUG_ELF=0
|
||||
MULTIBOOT2=1
|
||||
LINUX_PAYLOAD=1
|
||||
|
||||
########## Security ##########
|
||||
STAGE1_AUTH=1
|
||||
WOLFTPM=1
|
||||
MEASURED_BOOT=1
|
||||
MEASURED_PCR_A=0
|
||||
# Measure the verified OS image into PCR4, alongside the firmware in PCR0.
|
||||
MEASURED_PCR_OS=4
|
||||
WOLFBOOT_UNIVERSAL_KEYSTORE=1
|
||||
WOLFBOOT_SKIP_AUTH_CHECK=0
|
||||
ENABLE_DEBUG_CONSENT=0
|
||||
|
||||
# Deferred: TPM sealing and ATA disk lock/erase.
|
||||
WOLFBOOT_TPM_SEAL=0
|
||||
DISK_LOCK=0
|
||||
DISK_ERASE=0
|
||||
|
||||
# Anti-rollback: persistent version floor + audit counters in TPM NV
|
||||
# (trust-on-first-use; provision before first boot where that matters).
|
||||
ANTI_ROLLBACK=1
|
||||
|
|
@ -14,6 +14,7 @@ This README describes configuration of supported targets.
|
|||
* [Infineon AURIX TC4xx](#infineon-aurix-tc4xx)
|
||||
* [Intel x86-64 Intel FSP](#intel-x86_64-with-intel-fsp-support)
|
||||
* [Kontron VX3060-S2](#kontron-vx3060-s2)
|
||||
* [NAI 68INT6 (Intel Tiger Lake)](#nai-68int6-intel-tiger-lake)
|
||||
* [Microchip PIC32CK](#microchip-pic32ck)
|
||||
* [Microchip PIC32CZ](#microchip-pic32cz)
|
||||
* [Microchip PolarFire SoC](#microchip-polarfire-soc)
|
||||
|
|
@ -9609,6 +9610,74 @@ Attempting boot from partition A
|
|||
```
|
||||
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.
|
||||
|
||||
## NAI 68INT6 (Intel Tiger Lake)
|
||||
|
||||
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.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| CPU | i7-1185GRE (`06-8C-01`), Tiger Lake UP3, PCH-LP |
|
||||
| Memory | 2 x 32 GB DDR4-3200 SODIMM, non-ECC |
|
||||
| BIOS flash | Rev C/D5: 2 x W25R256JV (32 MB), selected by JP36. Next revision: one 64 MB device |
|
||||
| TPM | SLB9670 (SHA-1/256), or SLB9672, which adds a SHA-384 bank |
|
||||
| Storage | Onboard SATA SSD, AHCI at `00:17.0` |
|
||||
| Console | LPSS UART2, PCI `00:19.2`, RS-232; `X86_UART_NUMBER=2` |
|
||||
|
||||
### Building
|
||||
|
||||
```
|
||||
cp config/examples/nai_68int6.config .config
|
||||
./tools/scripts/x86_fsp/tgl/tgl_download_fsp.sh # FSP UPD headers, first time only
|
||||
./tools/scripts/x86_fsp/tgl/nai_extract_fsp.sh <68INT6.bin> # board's own FSP blobs
|
||||
./tools/scripts/x86_fsp/tgl/assemble_image.sh -k # generate signing keys
|
||||
make
|
||||
./tools/scripts/x86_fsp/tgl/assemble_image.sh -n <68INT6.bin>
|
||||
```
|
||||
|
||||
`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`.
|
||||
|
||||
### Integrity algorithms
|
||||
|
||||
ECC P-384 and SHA-384 match what Intel Boot Guard uses for the Initial Boot Block.
|
||||
|
||||
| Layer | Algorithm |
|
||||
|---|---|
|
||||
| Image signature | ECC P-384 (`SIGN=ECC384`) |
|
||||
| Image digest | SHA-384 (`HASH=SHA384`) |
|
||||
| Measured boot PCR | SHA-256 (the SLB9670 has only SHA-1 and SHA-256 banks) |
|
||||
|
||||
`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).
|
||||
|
||||
### Configuration
|
||||
|
||||
Notable options in [config/examples/nai_68int6.config](../config/examples/nai_68int6.config):
|
||||
|
||||
| Option | Meaning |
|
||||
|---|---|
|
||||
| `X86_UART_NUMBER=2` | LPSS UART2 for all three FSP phases (Kontron uses 0) |
|
||||
| `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 |
|
||||
| `ANTI_ROLLBACK=1` | Persistent version floor and boot audit counters in TPM NV |
|
||||
| `MEASURED_BOOT=1`, `MEASURED_PCR_OS=4` | Firmware into PCR 0, the verified OS image into PCR 4 |
|
||||
| `WOLFBOOT_BOOT_DISK=0` | Boot from GPT partitions; the A/B indices (sda3/sda4) are set in `src/update_disk.c` |
|
||||
|
||||
### BIOS region lock
|
||||
|
||||
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.
|
||||
|
||||
### Anti-rollback
|
||||
|
||||
`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.
|
||||
|
||||
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.
|
||||
|
||||
`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.
|
||||
|
||||
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.
|
||||
|
||||
### Boot, programming and recovery
|
||||
|
||||
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.
|
||||
|
||||
## Infineon PSOC Control C3
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -31,87 +31,6 @@
|
|||
|
||||
#ifdef __WOLFBOOT
|
||||
|
||||
#define SPI_PCI_DEV 31
|
||||
#define SPI_PCI_FUN 5
|
||||
#define SPI_BAR_OFF 0x10
|
||||
/* Tiger Lake SPI controller register offsets, memory-mapped at the
|
||||
* BAR0 base. FREG1 holds the BIOS flash region base/limit (region 0
|
||||
* is the flash descriptor); FPR0 is the protected range register
|
||||
* with the same base/limit layout. Offsets per the Intel PCH SPI
|
||||
* register map (see drivers/spi/spi-intel.c in the Linux kernel):
|
||||
* FDATA0-15 at 0x10-0x4C, FRACC at 0x50, FREG0-7 at 0x54-0x74,
|
||||
* FPR0-4 at 0x84-0x9C. */
|
||||
#define SPI_FREG1 0x58
|
||||
#define SPI_FREG_BASE_MASK (0x7fffU << 0)
|
||||
#define SPI_FREG_LIMIT_MASK (0x7fffU << 16)
|
||||
#define SPI_FREG_LIMIT_SHIFT (16)
|
||||
#define SPI_FREG_ADDR_SHIFT (12)
|
||||
#define SPI_FPR0 (0x84)
|
||||
#define SPI_FPR_WPE (1U << 31)
|
||||
#define SPI_FPR_RPE (1U << 15)
|
||||
#define SPI_BIOS_HSFSTS_CTL (0x4)
|
||||
#define SPI_FLOCKDN (1U << 15)
|
||||
|
||||
int tgl_lock_bios_region()
|
||||
{
|
||||
uint32_t spi_bar, spi_cmd;
|
||||
uint32_t reg;
|
||||
int ret = 0;
|
||||
|
||||
#if defined(DEBUG)
|
||||
uint32_t bios_reg_base, bios_reg_lim;
|
||||
#endif
|
||||
|
||||
spi_bar = pci_config_read32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_BAR0_OFFSET);
|
||||
spi_bar &= PCI_BAR_MASK;
|
||||
spi_cmd =
|
||||
pci_config_read32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET);
|
||||
pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET,
|
||||
spi_cmd | PCI_COMMAND_MEM_SPACE);
|
||||
|
||||
/* The Flash Protected Range register has the same base/limit
|
||||
* layout as the Flash Region register: take the BIOS region
|
||||
* (FREG1, flash region 1) and enable read and write protection
|
||||
* on it. The SPI registers live in the BAR's memory-mapped
|
||||
* space, not in PCI configuration space. */
|
||||
reg = mmio_read32(spi_bar + SPI_FREG1);
|
||||
#if defined(DEBUG)
|
||||
bios_reg_base = (reg & SPI_FREG_BASE_MASK) << SPI_FREG_ADDR_SHIFT;
|
||||
bios_reg_lim = ((reg & SPI_FREG_LIMIT_MASK) >> SPI_FREG_LIMIT_SHIFT)
|
||||
<< SPI_FREG_ADDR_SHIFT;
|
||||
wolfBoot_printf("Bios reg base: 0x%x lim: 0x%x\r\n", bios_reg_base,
|
||||
bios_reg_lim);
|
||||
#endif
|
||||
reg |= (SPI_FPR_RPE) | (SPI_FPR_WPE);
|
||||
mmio_write32(spi_bar + SPI_FPR0, reg);
|
||||
if ((mmio_read32(spi_bar + SPI_FPR0) &
|
||||
(SPI_FPR_RPE | SPI_FPR_WPE)) != (SPI_FPR_RPE | SPI_FPR_WPE)) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* lock down BIOS register configuration */
|
||||
reg = mmio_read32(spi_bar + SPI_BIOS_HSFSTS_CTL);
|
||||
reg |= SPI_FLOCKDN;
|
||||
mmio_write32(spi_bar + SPI_BIOS_HSFSTS_CTL, reg);
|
||||
if ((mmio_read32(spi_bar + SPI_BIOS_HSFSTS_CTL) & SPI_FLOCKDN) == 0) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* restore original cmd */
|
||||
pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET, spi_cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hal_flash_protect(haladdr_t address, int len)
|
||||
{
|
||||
(void)address;
|
||||
(void)len;
|
||||
|
||||
/* The TGL BIOS region covers the bootloader partition, so the
|
||||
* hook's address/len are the same range FREG1 describes. */
|
||||
return tgl_lock_bios_region();
|
||||
}
|
||||
|
||||
void hal_init(void)
|
||||
{
|
||||
gdt_setup_table();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
/* kontron_vx3060_s2_loader.c
|
||||
/* nai_68int6.c
|
||||
*
|
||||
* HAL for the NAI 68INT6 3U OpenVPX SBC (Intel Tiger Lake UP3).
|
||||
*
|
||||
* Copyright (C) 2026 wolfSSL Inc.
|
||||
*
|
||||
|
|
@ -6,7 +8,7 @@
|
|||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot is distributed in the hope that it will be useful,
|
||||
|
|
@ -20,27 +22,41 @@
|
|||
*/
|
||||
|
||||
#include <wolfboot/wolfboot.h>
|
||||
#include <hal.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <uart_drv.h>
|
||||
#include <printf.h>
|
||||
#include <pci.h>
|
||||
#include <x86/gdt.h>
|
||||
#include <x86/fsp.h>
|
||||
#include <x86/common.h>
|
||||
|
||||
#ifdef __WOLFBOOT
|
||||
#include <printf.h>
|
||||
|
||||
|
||||
static void panic(void);
|
||||
|
||||
void hal_init(void)
|
||||
{
|
||||
gdt_setup_table();
|
||||
gdt_update_segments();
|
||||
fsp_init_silicon();
|
||||
}
|
||||
|
||||
void hal_prepare_boot(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif /* __WOLFBOOT */
|
||||
|
||||
int hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
||||
int hal_flash_write(uintptr_t address, const uint8_t *data, int len)
|
||||
{
|
||||
(void)address;
|
||||
(void)data;
|
||||
(void)len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hal_flash_erase(uintptr_t address, int len)
|
||||
{
|
||||
(void)address;
|
||||
(void)len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -52,15 +68,11 @@ void hal_flash_lock(void)
|
|||
{
|
||||
}
|
||||
|
||||
int hal_flash_erase(uint32_t address, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No automatic fallback: a verification failure is terminal on this
|
||||
* target rather than silently reverting. */
|
||||
int wolfBoot_fallback_is_possible(void)
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int wolfBoot_dualboot_candidate(void)
|
||||
|
|
@ -75,7 +87,7 @@ void* hal_get_primary_address(void)
|
|||
|
||||
void* hal_get_update_address(void)
|
||||
{
|
||||
return (void*)0;
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
void *hal_get_dts_address(void)
|
||||
|
|
@ -87,8 +99,3 @@ void *hal_get_dts_update_address(void)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void panic(void)
|
||||
{
|
||||
while(1) {}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
/* x86_fsp_qemu_loader.c
|
||||
/* stub_loader.c
|
||||
*
|
||||
* Generic stage1 loader HAL for x86 FSP targets.
|
||||
*
|
||||
* Copyright (C) 2026 wolfSSL Inc.
|
||||
*
|
||||
|
|
@ -6,7 +8,7 @@
|
|||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot is distributed in the hope that it will be useful,
|
||||
|
|
@ -19,10 +21,14 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
/* x86 FSP stage1 runs XIP before memory init and only authenticates stage2,
|
||||
* so every HAL entry point is a stub. */
|
||||
|
||||
#include <wolfboot/wolfboot.h>
|
||||
#include <hal.h>
|
||||
#include <uart_drv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <uart_drv.h>
|
||||
|
||||
#ifdef __WOLFBOOT
|
||||
#include <printf.h>
|
||||
|
|
@ -34,10 +40,13 @@ void hal_init(void)
|
|||
void hal_prepare_boot(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif /* __WOLFBOOT */
|
||||
|
||||
int hal_flash_write(uintptr_t address, const uint8_t *data, int len)
|
||||
int hal_flash_write(haladdr_t address, const uint8_t *data, int len)
|
||||
{
|
||||
(void)address;
|
||||
(void)data;
|
||||
(void)len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -49,15 +58,16 @@ void hal_flash_lock(void)
|
|||
{
|
||||
}
|
||||
|
||||
int hal_flash_erase(uintptr_t address, int len)
|
||||
int hal_flash_erase(haladdr_t address, int len)
|
||||
{
|
||||
(void)address;
|
||||
(void)len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wolfBoot_fallback_is_possible(void)
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int wolfBoot_dualboot_candidate(void)
|
||||
|
|
@ -72,7 +82,7 @@ void* hal_get_primary_address(void)
|
|||
|
||||
void* hal_get_update_address(void)
|
||||
{
|
||||
return (void*)0;
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
void *hal_get_dts_address(void)
|
||||
|
|
@ -84,4 +94,3 @@ void *hal_get_dts_update_address(void)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -27,6 +27,8 @@
|
|||
#include "uart_drv.h"
|
||||
#include "printf.h"
|
||||
#include "loader.h"
|
||||
#include "hal.h"
|
||||
#include "pci.h"
|
||||
|
||||
#ifdef WOLFBOOT_FSP
|
||||
#include "x86/ahci.h"
|
||||
|
|
@ -35,7 +37,7 @@
|
|||
#include "x86/tgl_fsp.h"
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_kontron_vx3060_s2)
|
||||
#if defined(TARGET_kontron_vx3060_s2) || defined(TARGET_nai_68int6)
|
||||
#define PCI_AHCI_BUS 0
|
||||
#define PCI_AHCI_DEV 0x17
|
||||
#define PCI_AHCI_FUN 0
|
||||
|
|
@ -106,5 +108,88 @@ int x86_fsp_tgl_init_sata(uint32_t *bar)
|
|||
*bar = sata_bar;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WOLFBOOT_TGL
|
||||
#define SPI_PCI_DEV 31
|
||||
#define SPI_PCI_FUN 5
|
||||
#define SPI_BAR_OFF 0x10
|
||||
/* Tiger Lake SPI controller register offsets, memory-mapped at the
|
||||
* BAR0 base. FREG1 holds the BIOS flash region base/limit (region 0
|
||||
* is the flash descriptor); FPR0 is the protected range register
|
||||
* with the same base/limit layout. Offsets per the Intel PCH SPI
|
||||
* register map (see drivers/spi/spi-intel.c in the Linux kernel):
|
||||
* FDATA0-15 at 0x10-0x4C, FRACC at 0x50, FREG0-7 at 0x54-0x74,
|
||||
* FPR0-4 at 0x84-0x9C. */
|
||||
#define SPI_FREG1 0x58
|
||||
#define SPI_FREG_BASE_MASK (0x7fffU << 0)
|
||||
#define SPI_FREG_LIMIT_MASK (0x7fffU << 16)
|
||||
#define SPI_FREG_LIMIT_SHIFT (16)
|
||||
#define SPI_FREG_ADDR_SHIFT (12)
|
||||
#define SPI_FPR0 (0x84)
|
||||
#define SPI_FPR_WPE (1U << 31)
|
||||
#define SPI_FPR_RPE (1U << 15)
|
||||
#define SPI_BIOS_HSFSTS_CTL (0x4)
|
||||
#define SPI_FLOCKDN (1U << 15)
|
||||
|
||||
int tgl_lock_bios_region(void)
|
||||
{
|
||||
uint32_t spi_bar, spi_cmd;
|
||||
uint32_t reg;
|
||||
int ret = 0;
|
||||
|
||||
#if defined(DEBUG)
|
||||
uint32_t bios_reg_base, bios_reg_lim;
|
||||
#endif
|
||||
|
||||
spi_bar = pci_config_read32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_BAR0_OFFSET);
|
||||
spi_bar &= PCI_BAR_MASK;
|
||||
spi_cmd =
|
||||
pci_config_read32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET);
|
||||
pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET,
|
||||
spi_cmd | PCI_COMMAND_MEM_SPACE);
|
||||
|
||||
/* The Flash Protected Range register has the same base/limit
|
||||
* layout as the Flash Region register: take the BIOS region
|
||||
* (FREG1, flash region 1) and enable read and write protection
|
||||
* on it. The SPI registers live in the BAR's memory-mapped
|
||||
* space, not in PCI configuration space. */
|
||||
reg = mmio_read32(spi_bar + SPI_FREG1);
|
||||
#if defined(DEBUG)
|
||||
bios_reg_base = (reg & SPI_FREG_BASE_MASK) << SPI_FREG_ADDR_SHIFT;
|
||||
bios_reg_lim = ((reg & SPI_FREG_LIMIT_MASK) >> SPI_FREG_LIMIT_SHIFT)
|
||||
<< SPI_FREG_ADDR_SHIFT;
|
||||
wolfBoot_printf("Bios reg base: 0x%x lim: 0x%x\r\n", bios_reg_base,
|
||||
bios_reg_lim);
|
||||
#endif
|
||||
reg |= (SPI_FPR_RPE) | (SPI_FPR_WPE);
|
||||
mmio_write32(spi_bar + SPI_FPR0, reg);
|
||||
if ((mmio_read32(spi_bar + SPI_FPR0) &
|
||||
(SPI_FPR_RPE | SPI_FPR_WPE)) != (SPI_FPR_RPE | SPI_FPR_WPE)) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* lock down BIOS register configuration */
|
||||
reg = mmio_read32(spi_bar + SPI_BIOS_HSFSTS_CTL);
|
||||
reg |= SPI_FLOCKDN;
|
||||
mmio_write32(spi_bar + SPI_BIOS_HSFSTS_CTL, reg);
|
||||
if ((mmio_read32(spi_bar + SPI_BIOS_HSFSTS_CTL) & SPI_FLOCKDN) == 0) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* restore original cmd */
|
||||
pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET, spi_cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hal_flash_protect(haladdr_t address, int len)
|
||||
{
|
||||
(void)address;
|
||||
(void)len;
|
||||
|
||||
/* The TGL BIOS region covers the bootloader partition, so the
|
||||
* hook's address/len are the same range FREG1 describes. */
|
||||
return tgl_lock_bios_region();
|
||||
}
|
||||
#endif /* WOLFBOOT_TGL */
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef FSP_CONFIG_H
|
||||
#define FSP_CONFIG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef FSP_HYPERTHREADING
|
||||
#define FSP_HYPERTHREADING 0
|
||||
#endif
|
||||
#if FSP_HYPERTHREADING
|
||||
/* The MADT and MP table list four single-thread cores (APIC IDs 0/2/4/6). */
|
||||
#error "FSP_HYPERTHREADING=1 needs sibling threads in the MADT and MP table"
|
||||
#endif
|
||||
|
||||
#ifndef FSP_INTEL_SPEED_STEP
|
||||
#define FSP_INTEL_SPEED_STEP 0
|
||||
#endif
|
||||
|
||||
#ifndef FSP_INTEL_SPEED_SHIFT
|
||||
#define FSP_INTEL_SPEED_SHIFT 0
|
||||
#endif
|
||||
|
||||
#define FSP_BOOT_FREQ_MAX_NO_TURBO 0x1
|
||||
#ifndef FSP_BOOT_PERFORMANCE_MODE
|
||||
#define FSP_BOOT_PERFORMANCE_MODE FSP_BOOT_FREQ_MAX_NO_TURBO
|
||||
#endif
|
||||
|
||||
#ifndef FSP_C_STATES
|
||||
#define FSP_C_STATES 0
|
||||
#endif
|
||||
|
||||
#ifndef FSP_TXT
|
||||
#define FSP_TXT 0
|
||||
#endif
|
||||
|
||||
#ifndef FSP_IN_BAND_ECC
|
||||
#define FSP_IN_BAND_ECC 1
|
||||
#endif
|
||||
|
||||
/* TM1/TM2 throttling at the thermal-control limit, the FSP default */
|
||||
#ifndef FSP_THERMAL_THROTTLING
|
||||
#define FSP_THERMAL_THROTTLING 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -150,7 +150,7 @@ enum mp_irq_source_types {
|
|||
#define MP_CPU_NUM_ENTRY 1
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
#if defined(TARGET_kontron_vx3060_s2) || defined(TARGET_nai_68int6)
|
||||
#define MP_IOAPIC_NUM_ENTRY 1
|
||||
#define MP_INTSRC_NUM_ENTRY 17
|
||||
#define MP_LINTSRC_NUM_ENTRY 0
|
||||
|
|
|
|||
|
|
@ -24,5 +24,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
int x86_fsp_tgl_init_sata(uint32_t *bar);
|
||||
int tgl_lock_bios_region(void);
|
||||
|
||||
#endif /* TGL_FSP_H */
|
||||
|
|
|
|||
|
|
@ -54,8 +54,16 @@ WOLFBOOT_TIME_TEST?=0
|
|||
# Generate a minimal ACPI table set (RSDP/XSDT/FADT/MADT/MCFG + DSDT) for the
|
||||
# x86 FSP Linux payload, so the OS gets the interrupt model and PCI routing.
|
||||
ifeq ($(ACPI),1)
|
||||
ifneq ($(TARGET),nai_68int6)
|
||||
$(error ACPI=1 tables (CPU list, DSDT routing) are specific to nai_68int6)
|
||||
endif
|
||||
CFLAGS+=-D"WOLFBOOT_ACPI"
|
||||
endif
|
||||
ifeq ($(TARGET),nai_68int6)
|
||||
ifneq ($(ACPI),1)
|
||||
$(error nai_68int6 needs ACPI=1: its PCI interrupt routing is only in the DSDT)
|
||||
endif
|
||||
endif
|
||||
|
||||
# TPM NV version floor and boot audit counters (see docs/Targets.md).
|
||||
# HALT_ON_FAILURE also halts when the TPM state cannot be read or locked.
|
||||
|
|
@ -1601,6 +1609,7 @@ ifeq ($(FSP), 1)
|
|||
X86_UART_BASE \
|
||||
X86_UART_REG_WIDTH \
|
||||
X86_UART_MMIO \
|
||||
X86_UART_NUMBER \
|
||||
PCH_HAS_PCR \
|
||||
PCI_USE_ECAM \
|
||||
PCH_PCR_BASE \
|
||||
|
|
|
|||
|
|
@ -64,6 +64,15 @@ uint8_t mb2_boot_info[MAX_MB2_BOOT_INFO_SIZE];
|
|||
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
static char *cmdline = "apic=verbose acpi=no pci=debug console=ttyS0,115200 debug";
|
||||
#elif defined(TARGET_nai_68int6)
|
||||
#define CMDLINE_STR_(x) #x
|
||||
#define CMDLINE_STR(x) CMDLINE_STR_(x)
|
||||
/* earlycon covers LPSS UART2 at its FSP-assigned base until the 8250 driver
|
||||
* binds it as ttyS4 */
|
||||
static char *cmdline =
|
||||
"earlycon=uart8250,mmio32," CMDLINE_STR(X86_UART_BASE) ",115200n8 "
|
||||
"console=ttyS4,115200 console=tty0 "
|
||||
"root=/dev/sda2 rw rootwait";
|
||||
#elif TARGET_x86_fsp_qemu
|
||||
static char *cmdline = "console=ttyS0,115200 pci=earlydump debug";
|
||||
#else
|
||||
|
|
|
|||
14
src/pci.c
14
src/pci.c
|
|
@ -390,10 +390,18 @@ static int pci_pre_enum_cb(uint8_t bus, uint8_t dev, uint8_t fun)
|
|||
#ifdef WOLFBOOT_TGL
|
||||
if (bus != 0)
|
||||
return 0;
|
||||
/* don't change UART mapping */
|
||||
if (dev == 0x1e && (fun == 0 || fun == 1)) {
|
||||
/* Leave the console UART BAR at X86_UART_BASE. LPSS UART0/1 are
|
||||
* 00:1e.0/1, UART2 is 00:19.2. */
|
||||
#if defined(X86_UART_NUMBER) && (X86_UART_NUMBER == 2)
|
||||
if (dev == 0x19 && fun == 2)
|
||||
return 1;
|
||||
}
|
||||
#elif defined(X86_UART_NUMBER) && (X86_UART_NUMBER == 1)
|
||||
if (dev == 0x1e && fun == 1)
|
||||
return 1;
|
||||
#else
|
||||
if (dev == 0x1e && fun == 0)
|
||||
return 1;
|
||||
#endif
|
||||
/* PMC BARs shouldn't be programmed as per FSP integration guide */
|
||||
if (dev == 31 && fun == 2)
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -477,7 +477,7 @@ int wolfBoot_tpm2_extend(uint8_t pcrIndex, uint8_t* hash, int line)
|
|||
int rc;
|
||||
#ifdef WOLFBOOT_DEBUG_TPM
|
||||
uint8_t digest[WOLFBOOT_TPM_PCR_DIG_SZ];
|
||||
int digestSz = 0;
|
||||
int digestSz = (int)sizeof(digest);
|
||||
#endif
|
||||
|
||||
/* clear auth session for PCR */
|
||||
|
|
@ -502,7 +502,8 @@ int wolfBoot_tpm2_extend(uint8_t pcrIndex, uint8_t* hash, int line)
|
|||
|
||||
wolfBoot_printf("PCR %d: Res %d, Digest Sz %d\n",
|
||||
pcrIndex, read_rc, digestSz);
|
||||
wolfBoot_print_bin(digest, digestSz);
|
||||
if (read_rc == 0)
|
||||
wolfBoot_print_bin(digest, digestSz);
|
||||
}
|
||||
else {
|
||||
wolfBoot_printf("Measure boot failed! Index %d, %x (%s)\n",
|
||||
|
|
|
|||
|
|
@ -91,6 +91,11 @@ static uint8_t disk_encrypt_nonce[ENCRYPT_NONCE_SIZE];
|
|||
#define BOOT_PART_A 5
|
||||
#define BOOT_PART_B 6
|
||||
#endif
|
||||
#ifdef TARGET_nai_68int6
|
||||
/* Signed kernels live in the 3rd and 4th GPT partitions (sda3/sda4). */
|
||||
#define BOOT_PART_A 2
|
||||
#define BOOT_PART_B 3
|
||||
#endif
|
||||
#endif /* WOLFBOOT_FSP */
|
||||
|
||||
/* Default values for BOOT_DISK, BOOT_PART_A and BOOT_PART_B */
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#define LOCAL_APIC_ID 0xfee00020
|
||||
#define LOCAL_APIC_VER 0xfee00030
|
||||
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
#if defined(TARGET_kontron_vx3060_s2) || defined(TARGET_nai_68int6)
|
||||
#define ISA_BUS 0x4
|
||||
|
||||
/* TGL mptable */
|
||||
|
|
@ -518,7 +518,7 @@ void mptable_setup(void)
|
|||
_mp->mpce_processor[0]._res[0] = _mp->mpce_processor[0]._res[1] = 0;
|
||||
|
||||
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
#if defined(TARGET_kontron_vx3060_s2) || defined(TARGET_nai_68int6)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < 4; ++i) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@
|
|||
#include <x86/fsp/FspsUpd.h>
|
||||
#include <x86/ahci.h>
|
||||
#include <stage2_params.h>
|
||||
#ifdef TARGET_nai_68int6
|
||||
#include <x86/fsp_config.h>
|
||||
#endif
|
||||
|
||||
#define PCR_DMI_PORT_ID 0x88
|
||||
#define PCR_DMI_LPCLGIR1 0x2730
|
||||
|
|
@ -238,6 +241,9 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp)
|
|||
FSP_M_CONFIG *mem_cfg;
|
||||
|
||||
mem_cfg = &udp->FspmConfig;
|
||||
/* Kontron VX3060-S2 DQ maps and DDR tuning; other boards keep the FSP-M
|
||||
* defaults. */
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->PlatformMemorySize = 93806592;
|
||||
mem_cfg->DqMapCpu2DramMc0Ch0[0] = 13;
|
||||
mem_cfg->DqMapCpu2DramMc0Ch0[1] = 12;
|
||||
|
|
@ -367,6 +373,7 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp)
|
|||
mem_cfg->DqMapCpu2DramMc1Ch3[13] = 9;
|
||||
mem_cfg->DqMapCpu2DramMc1Ch3[14] = 8;
|
||||
mem_cfg->DqMapCpu2DramMc1Ch3[15] = 13;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
mem_cfg->TsegSize = 8388608;
|
||||
mem_cfg->SpdAddressTable[0] = 160;
|
||||
mem_cfg->SpdAddressTable[1] = 0;
|
||||
|
|
@ -394,8 +401,10 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp)
|
|||
mem_cfg->VtdBaseAddress[7] = 0;
|
||||
mem_cfg->VtdBaseAddress[8] = 0;
|
||||
mem_cfg->UserBd = 5;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->RMT = 1;
|
||||
mem_cfg->NModeSupport = 2;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
mem_cfg->PchHdaEnable = 0;
|
||||
mem_cfg->GttMmAdr = 2147483648;
|
||||
mem_cfg->DdiPort2Hpd = 1;
|
||||
|
|
@ -404,14 +413,22 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp)
|
|||
mem_cfg->DdiPort4Ddc = 1;
|
||||
mem_cfg->EnableC6Dram = 0;
|
||||
mem_cfg->HyperThreading = 0;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->CpuRatio = 0;
|
||||
mem_cfg->FClkFrequency = 1;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
#ifdef TARGET_nai_68int6
|
||||
mem_cfg->VmxEnable = 1;
|
||||
#else
|
||||
mem_cfg->VmxEnable = 0;
|
||||
#endif
|
||||
mem_cfg->BiosGuard = 0;
|
||||
mem_cfg->EnableSgx = 0;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->TxtDprMemorySize = 4194304;
|
||||
mem_cfg->BiosAcmBase = 4285267968;
|
||||
mem_cfg->ConfigTdpLevel = 2;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
mem_cfg->PcieClkSrcUsage[0] = 128;
|
||||
mem_cfg->PcieClkSrcUsage[1] = 128;
|
||||
mem_cfg->PcieClkSrcUsage[2] = 128;
|
||||
|
|
@ -434,7 +451,9 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp)
|
|||
* set from X86_UART_NUMBER or the console changes between phases - output
|
||||
* appears for part of the boot and then stops, reading as a hang. */
|
||||
mem_cfg->SerialIoUartDebugControllerNumber = X86_UART_NUMBER;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->MrcSafeConfig = 1;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
mem_cfg->TcssItbtPcie0En = 0;
|
||||
mem_cfg->TcssItbtPcie1En = 0;
|
||||
mem_cfg->TcssItbtPcie2En = 0;
|
||||
|
|
@ -442,9 +461,12 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp)
|
|||
mem_cfg->TcssXdciEn = 1;
|
||||
mem_cfg->TcssDma0En = 0;
|
||||
mem_cfg->TcssDma1En = 0;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->RMC = 0;
|
||||
mem_cfg->EccSupport = 0;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
mem_cfg->Ibecc = 1;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->IbeccParity = 1;
|
||||
mem_cfg->RankInterleave = 0;
|
||||
mem_cfg->EnhancedInterleave = 0;
|
||||
|
|
@ -452,9 +474,12 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp)
|
|||
mem_cfg->ChHashMask = 12492;
|
||||
mem_cfg->PowerDownMode = 0;
|
||||
mem_cfg->SafeMode = 1;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
mem_cfg->UsbTcPortEnPreMem = 15;
|
||||
mem_cfg->WrcFeatureEnable = 0;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->McParity = 1;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
mem_cfg->PchHdaSdiEnable[0] = 1;
|
||||
mem_cfg->PchHdaSdiEnable[1] = 1;
|
||||
mem_cfg->PchHdaAudioLinkDmicEnable[0] = 0;
|
||||
|
|
@ -470,7 +495,9 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp)
|
|||
mem_cfg->PchHdaAudioLinkSndwEnable[1] = 1;
|
||||
mem_cfg->PchHdaAudioLinkSndwEnable[2] = 0;
|
||||
mem_cfg->PchHdaAudioLinkSndwEnable[3] = 0;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
mem_cfg->SkipCpuReplacementCheck = 1;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
mem_cfg->SerialIoUartDebugMode = 4;
|
||||
mem_cfg->PcieRefPllSsc = 0;
|
||||
return 0;
|
||||
|
|
@ -497,7 +524,9 @@ static void fsp_set_silicon_cfg(FSPS_UPD *fsps)
|
|||
{
|
||||
FSP_S_CONFIG *upd = &fsps->FspsConfig;
|
||||
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
upd->GraphicsConfigPtr = 2024131364;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
|
||||
upd->SataPortsEnable[0] = 1;
|
||||
upd->SataPortsEnable[1] = 1;
|
||||
|
|
@ -661,18 +690,33 @@ static void fsp_set_silicon_cfg(FSPS_UPD *fsps)
|
|||
upd->IomTypeCPortPadCfg[7] = 0;
|
||||
upd->UsbTcPortEn = 15;
|
||||
upd->AesEnable = 0;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
upd->PchWriteProtectionEnable[0] = 1;
|
||||
upd->PchWriteProtectionEnable[1] = 1;
|
||||
#else
|
||||
upd->PchWriteProtectionEnable[0] = 0;
|
||||
upd->PchWriteProtectionEnable[1] = 0;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
upd->PchWriteProtectionEnable[2] = 0;
|
||||
upd->PchWriteProtectionEnable[3] = 0;
|
||||
upd->PchWriteProtectionEnable[4] = 0;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
upd->PchProtectedRangeLimit[0] = 13679;
|
||||
upd->PchProtectedRangeLimit[1] = 16383;
|
||||
#else
|
||||
upd->PchProtectedRangeLimit[0] = 0;
|
||||
upd->PchProtectedRangeLimit[1] = 0;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
upd->PchProtectedRangeLimit[2] = 0;
|
||||
upd->PchProtectedRangeLimit[3] = 0;
|
||||
upd->PchProtectedRangeLimit[4] = 0;
|
||||
#ifdef TARGET_kontron_vx3060_s2
|
||||
upd->PchProtectedRangeBase[0] = 13312;
|
||||
upd->PchProtectedRangeBase[1] = 13744;
|
||||
#else
|
||||
upd->PchProtectedRangeBase[0] = 0;
|
||||
upd->PchProtectedRangeBase[1] = 0;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
upd->PchProtectedRangeBase[2] = 0;
|
||||
upd->PchProtectedRangeBase[3] = 0;
|
||||
upd->PchProtectedRangeBase[4] = 0;
|
||||
|
|
@ -953,9 +997,16 @@ int fsp_machine_update_s_parameters(uint8_t *default_s_params)
|
|||
|
||||
upd->MicrocodeRegionBase = 0x0;
|
||||
upd->MicrocodeRegionSize = 0x0;
|
||||
#ifdef TARGET_nai_68int6
|
||||
/* No table: the FSP's built-in PCH interrupt routing matches the DSDT
|
||||
* _PRT; a partial table leaves other devices' INTx unrouted. */
|
||||
upd->DevIntConfigPtr = 0;
|
||||
upd->NumOfDevIntConfig = 0;
|
||||
#else
|
||||
/* we can assume that is under 4gb */
|
||||
upd->DevIntConfigPtr = (uint32_t)(uintptr_t)mPchHDevIntConfig;
|
||||
upd->NumOfDevIntConfig = sizeof(mPchHDevIntConfig)/sizeof(mPchHDevIntConfig[0]);
|
||||
#endif
|
||||
upd->SataEnable = 1;
|
||||
upd->SataMode = 0;
|
||||
upd->SataSalpSupport = 0;
|
||||
|
|
@ -978,6 +1029,13 @@ int fsp_machine_update_s_parameters(uint8_t *default_s_params)
|
|||
|
||||
memset(upd->PcieRpHotPlug, 0, sizeof(upd->PcieRpHotPlug));
|
||||
memset(upd->CpuPcieRpHotPlug, 0, sizeof(upd->CpuPcieRpHotPlug));
|
||||
#ifdef TARGET_nai_68int6
|
||||
upd->Eist = FSP_INTEL_SPEED_STEP;
|
||||
upd->Hwp = FSP_INTEL_SPEED_SHIFT;
|
||||
upd->Cx = FSP_C_STATES;
|
||||
upd->TxtEnable = FSP_TXT;
|
||||
upd->ThermalMonitor = FSP_THERMAL_THROTTLING;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
|
|
@ -1470,6 +1528,8 @@ static const struct tgl_gpio_conf gpio_table_presilicon[] = {
|
|||
.gpio_term = GPIO_TERM_NONE},
|
||||
|
||||
};
|
||||
#elif defined(TARGET_nai_68int6)
|
||||
#include <x86/gpio_config.h>
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
/**
|
||||
* @brief Configure GPIO settings for a specific device.
|
||||
|
|
@ -1655,6 +1715,16 @@ int post_temp_ram_init_cb(void)
|
|||
|
||||
|
||||
kontron_ask_for_recovery();
|
||||
#elif defined(TARGET_nai_68int6)
|
||||
unsigned int i;
|
||||
unsigned int n;
|
||||
|
||||
/* No CPLD or SuperIO: the LTC2870 transceiver resets to RS-232, so only
|
||||
* the console pads need setting up. */
|
||||
n = sizeof(gpio_table_tempram)/sizeof(gpio_table_tempram[0]);
|
||||
for (i = 0; i < n; i++) {
|
||||
tgl_gpio_configure(&gpio_table_tempram[i]);
|
||||
}
|
||||
#else
|
||||
(void)tgl_gpio_configure;
|
||||
#endif /* TARGET_kontron_vx3060_s2 */
|
||||
|
|
@ -1691,6 +1761,11 @@ int fsp_machine_update_m_parameters(uint8_t *default_m_params,
|
|||
new_udp->FspmArchUpd.NvsBufferPtr = 0;
|
||||
new_udp->FspmArchUpd.StackBase = mem_base;
|
||||
new_udp->FspmArchUpd.StackSize = mem_size;
|
||||
#ifdef TARGET_nai_68int6
|
||||
new_udp->FspmConfig.HyperThreading = FSP_HYPERTHREADING;
|
||||
new_udp->FspmConfig.BootFrequency = FSP_BOOT_PERFORMANCE_MODE;
|
||||
new_udp->FspmConfig.Ibecc = FSP_IN_BAND_ECC;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1698,8 +1773,12 @@ int fsp_machine_update_m_parameters(uint8_t *default_m_params,
|
|||
int fsp_pre_mem_init_cb(void)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int n;
|
||||
|
||||
for (i = 0; i < sizeof(gpio_table_premem)/sizeof(gpio_table_premem[0]); i++) {
|
||||
/* via a variable: the table is empty on some targets, and comparing
|
||||
* against the literal 0 that sizeof folds to trips -Wtype-limits. */
|
||||
n = sizeof(gpio_table_premem)/sizeof(gpio_table_premem[0]);
|
||||
for (i = 0; i < n; i++) {
|
||||
tgl_gpio_configure(&gpio_table_premem[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Switch the in-tree FSP set (UPD headers and FSP binaries) between QEMU,
|
||||
# Tiger Lake and NAI; their generators all write the same paths.
|
||||
#
|
||||
# Usage:
|
||||
# select_fsp.sh save {tgl|qemu|nai} snapshot the current in-tree set
|
||||
# select_fsp.sh use {tgl|qemu|nai} restore a snapshotted set into the tree
|
||||
# select_fsp.sh show report what is cached and what is in-tree
|
||||
#
|
||||
set -e
|
||||
|
||||
CACHE="${WOLFBOOT_FSP_CACHE:-$HOME/.cache/wolfboot-fsp}"
|
||||
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||
HDRS="FspUpd.h FspmUpd.h FspsUpd.h FsptUpd.h"
|
||||
# Headers only some generators emit; each set restores only its own, so one
|
||||
# cannot leak into another.
|
||||
HDRS_OPT_ALL="MemInfoHob.h"
|
||||
HDRS_OPT_tgl="MemInfoHob.h"
|
||||
HDRS_OPT_nai="MemInfoHob.h"
|
||||
BINS="fsp_t.bin fsp_m.bin fsp_s.bin"
|
||||
# ucode0.bin is only produced by the TGL flow
|
||||
EXTRA_tgl="ucode0.bin"
|
||||
# NAI: the TGL flow with NAI's own FSP and microcode (nai_extract_fsp.sh)
|
||||
EXTRA_nai="ucode0.bin"
|
||||
|
||||
usage() { sed -n '3,9p' "$0" | sed 's/^# \{0,1\}//'; exit 1; }
|
||||
|
||||
check_set() {
|
||||
case "$1" in
|
||||
tgl|qemu|nai) ;;
|
||||
*) echo "error: set must be 'tgl', 'qemu' or 'nai'" >&2; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
do_save() {
|
||||
local s="$1" extra opt n=0
|
||||
eval "extra=\${EXTRA_$s:-}"
|
||||
eval "opt=\${HDRS_OPT_$s:-}"
|
||||
mkdir -p "$CACHE/$s"
|
||||
for f in $HDRS; do
|
||||
[ -f "$ROOT/include/x86/fsp/$f" ] || { echo "error: missing include/x86/fsp/$f" >&2; exit 1; }
|
||||
cp "$ROOT/include/x86/fsp/$f" "$CACHE/$s/"; n=$((n+1))
|
||||
done
|
||||
for f in $HDRS_OPT_ALL; do
|
||||
rm -f "$CACHE/$s/$f"
|
||||
done
|
||||
for f in $opt; do
|
||||
[ -f "$ROOT/include/x86/fsp/$f" ] && { cp "$ROOT/include/x86/fsp/$f" "$CACHE/$s/"; n=$((n+1)); }
|
||||
done
|
||||
for f in $BINS $extra; do
|
||||
[ -f "$ROOT/src/x86/$f" ] || { echo "error: missing src/x86/$f" >&2; exit 1; }
|
||||
cp "$ROOT/src/x86/$f" "$CACHE/$s/"; n=$((n+1))
|
||||
done
|
||||
echo "saved $n files to $CACHE/$s"
|
||||
}
|
||||
|
||||
do_use() {
|
||||
local s="$1" extra opt n=0
|
||||
eval "extra=\${EXTRA_$s:-}"
|
||||
eval "opt=\${HDRS_OPT_$s:-}"
|
||||
[ -d "$CACHE/$s" ] || { echo "error: no snapshot for '$s'. Run the generator then 'select_fsp.sh save $s'." >&2; exit 1; }
|
||||
# Check every required file before copying any, so a partial cache fails
|
||||
# here rather than leaving a half-updated tree.
|
||||
for f in $HDRS $BINS $extra; do
|
||||
[ -f "$CACHE/$s/$f" ] || { echo "error: cached '$s' set is missing $f; re-run the generator then 'select_fsp.sh save $s'" >&2; exit 1; }
|
||||
done
|
||||
for f in $HDRS; do
|
||||
cp "$CACHE/$s/$f" "$ROOT/include/x86/fsp/"; n=$((n+1))
|
||||
done
|
||||
for f in $HDRS_OPT_ALL; do
|
||||
rm -f "$ROOT/include/x86/fsp/$f"
|
||||
done
|
||||
for f in $opt; do
|
||||
[ -f "$CACHE/$s/$f" ] && { cp "$CACHE/$s/$f" "$ROOT/include/x86/fsp/"; n=$((n+1)); }
|
||||
done
|
||||
for f in $BINS $extra; do
|
||||
cp "$CACHE/$s/$f" "$ROOT/src/x86/"; n=$((n+1))
|
||||
done
|
||||
echo "restored $n files of the '$s' FSP set"
|
||||
}
|
||||
|
||||
do_show() {
|
||||
echo "cache: $CACHE"
|
||||
for s in tgl qemu nai; do
|
||||
if [ -d "$CACHE/$s" ]; then
|
||||
echo " $s: $(ls "$CACHE/$s" | wc -l) files"
|
||||
else
|
||||
echo " $s: (not snapshotted)"
|
||||
fi
|
||||
done
|
||||
echo "in-tree include/x86/fsp/FspmUpd.h:"
|
||||
if [ -f "$ROOT/include/x86/fsp/FspmUpd.h" ]; then
|
||||
# the TGL header is thousands of lines; the QEMU one is a small stub
|
||||
printf " %s lines -> looks like %s\n" \
|
||||
"$(wc -l < "$ROOT/include/x86/fsp/FspmUpd.h")" \
|
||||
"$([ "$(wc -l < "$ROOT/include/x86/fsp/FspmUpd.h")" -gt 1000 ] && echo TGL || echo QEMU)"
|
||||
else
|
||||
echo " (absent)"
|
||||
fi
|
||||
}
|
||||
|
||||
[ $# -ge 1 ] || usage
|
||||
case "$1" in
|
||||
save) [ $# -eq 2 ] || usage; check_set "$2"; do_save "$2" ;;
|
||||
use) [ $# -eq 2 ] || usage; check_set "$2"; do_use "$2" ;;
|
||||
show) do_show ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Extract FSP-T/M/S and microcode from a 68INT6 BIOS image and rebase them
|
||||
# to the .config addresses (the public TGL_IOT FSP does not train this board).
|
||||
#
|
||||
# Usage: tools/scripts/x86_fsp/tgl/nai_extract_fsp.sh <68INT6_bios_image.bin>
|
||||
|
||||
set -eu
|
||||
|
||||
IMG=${1:?usage: $0 <nai_bios_image.bin>}
|
||||
WORK_DIR=/tmp/tgl_fsp
|
||||
EDK2_COMMIT_ID=df25a5457f04ec465dce97428cfee96f462676e7
|
||||
FSP_TOOL_URL=https://github.com/tianocore/edk2/raw/${EDK2_COMMIT_ID}/IntelFsp2Pkg/Tools/SplitFspBin.py
|
||||
SCRIPT_DIR=$(readlink -f "$(dirname "$0")")
|
||||
WOLFBOOT_DIR="${SCRIPT_DIR}/../../../.."
|
||||
CFG="${WOLFBOOT_DIR}/.config"
|
||||
|
||||
[ -f "$IMG" ] || { echo "error: image not found: $IMG" >&2; exit 1; }
|
||||
[ -f "$CFG" ] || { echo "error: no .config in ${WOLFBOOT_DIR}; copy config/examples/nai_68int6.config there first" >&2; exit 1; }
|
||||
|
||||
cfgval() { grep -E "^$1=" "$CFG" | tail -1 | cut -d= -f2 | tr -d ' '; }
|
||||
FSP_T_BASE=$(cfgval FSP_T_BASE)
|
||||
FSP_M_BASE=$(cfgval FSP_M_BASE)
|
||||
FSP_S_LOAD_BASE=$(cfgval FSP_S_LOAD_BASE)
|
||||
for v in FSP_T_BASE FSP_M_BASE FSP_S_LOAD_BASE; do
|
||||
[ -n "${!v}" ] || { echo "error: $v not set in .config" >&2; exit 1; }
|
||||
done
|
||||
|
||||
mkdir -p "$WORK_DIR"
|
||||
if [ ! -f "$WORK_DIR/SplitFspBin.py" ]; then
|
||||
echo "fetching SplitFspBin.py (edk2 ${EDK2_COMMIT_ID:0:12})"
|
||||
curl -sL -o "$WORK_DIR/SplitFspBin.py" "$FSP_TOOL_URL"
|
||||
fi
|
||||
|
||||
# Locate FSP-T/M/S by their FSP_INFO_HEADER (type = ComponentAttribute bits
|
||||
# 15:12; the FV starts 0x94 before the header, inner FV for FSP-S).
|
||||
python3 - "$IMG" "$WORK_DIR" <<'PY'
|
||||
import struct, sys
|
||||
img = open(sys.argv[1], 'rb').read()
|
||||
work = sys.argv[2]
|
||||
names = {1: 'T', 2: 'M', 3: 'S'}
|
||||
found = {}
|
||||
i = 0
|
||||
while True:
|
||||
i = img.find(b'FSPH', i)
|
||||
if i < 0:
|
||||
break
|
||||
hlen = struct.unpack_from('<I', img, i + 4)[0]
|
||||
if hlen in (0x48, 0x4C, 0x50):
|
||||
imgrev, imgid, imgsize, imgbase, attr, cattr = struct.unpack_from('<I8sIIHH', img, i + 0x0C)
|
||||
kind = names.get((cattr >> 12) & 0xF)
|
||||
if kind and imgid.strip(b'\0') and 0 < imgsize < 0x200000:
|
||||
fv = i - 0x94
|
||||
found.setdefault(kind, (fv, imgsize, imgid, imgbase, imgrev))
|
||||
i += 4
|
||||
for k in 'TMS':
|
||||
if k not in found:
|
||||
print("error: FSP-%s not found in image" % k); sys.exit(1)
|
||||
fv, size, imgid, base, rev = found[k]
|
||||
open("%s/NAI_FSP_%s.fd" % (work, k), 'wb').write(img[fv:fv + size])
|
||||
print(" FSP-%s %-9r rev %X.%X.%X.%X at 0x%08X size 0x%06X linked at 0x%08X"
|
||||
% (k, imgid, (rev >> 24) & 0xFF, (rev >> 16) & 0xFF, (rev >> 8) & 0xFF, rev & 0xFF, fv, size, base))
|
||||
|
||||
# Newest microcode for this CPU from the same image.
|
||||
best = None
|
||||
for off in range(0, len(img) - 48, 16):
|
||||
if struct.unpack_from('<I', img, off)[0] != 1:
|
||||
continue
|
||||
hv, urev, date, sig, cks, ldr, pf, dsz, tsz = struct.unpack_from('<9I', img, off)
|
||||
if ldr != 1 or sig != 0x000806C1 or tsz == 0 or tsz > 0x40000 or off + tsz > len(img):
|
||||
continue
|
||||
blob = img[off:off + tsz]
|
||||
if sum(struct.unpack_from('<%dI' % (tsz // 4), blob)) & 0xFFFFFFFF:
|
||||
continue
|
||||
if best is None or urev > best[0]:
|
||||
best = (urev, date, blob)
|
||||
if best is None:
|
||||
print("error: no valid 06-8c-01 microcode found in image"); sys.exit(1)
|
||||
urev, date, blob = best
|
||||
open("%s/NAI_ucode0.bin" % work, 'wb').write(blob)
|
||||
print(" ucode 06-8c-01 rev 0x%02X date %08X %d bytes" % (urev, date, len(blob)))
|
||||
PY
|
||||
|
||||
rebase() {
|
||||
local c=$1 base=$2
|
||||
(cd "$WORK_DIR" && python3 SplitFspBin.py rebase -f "NAI_FSP_${c}.fd" -b "$base" \
|
||||
-c "${c,,}" -o . -n "NAI_FSP_${c}_rebased.fd" >/dev/null)
|
||||
cp "$WORK_DIR/NAI_FSP_${c}_rebased.fd" "${WOLFBOOT_DIR}/src/x86/fsp_${c,,}.bin"
|
||||
echo " FSP-$c rebased to $base -> src/x86/fsp_${c,,}.bin"
|
||||
}
|
||||
rebase T "$FSP_T_BASE"
|
||||
rebase M "$FSP_M_BASE"
|
||||
rebase S "$FSP_S_LOAD_BASE"
|
||||
cp "$WORK_DIR/NAI_ucode0.bin" "${WOLFBOOT_DIR}/src/x86/ucode0.bin"
|
||||
echo " microcode -> src/x86/ucode0.bin"
|
||||
echo
|
||||
echo "Done. Snapshot it: tools/scripts/x86_fsp/select_fsp.sh save nai"
|
||||
|
|
@ -39,7 +39,7 @@ typedef uintptr_t haladdr_t;
|
|||
#define MMIO_BASE 0xFED40000UL
|
||||
|
||||
/* SPI PCI device constants + register offsets from
|
||||
* hal/kontron_vx3060_s2.c (extracted by the Makefile). */
|
||||
* hal/x86_fsp_tgl.c (extracted by the Makefile). */
|
||||
#include "kontron_spi_extract.h"
|
||||
|
||||
/* TGL register offsets used by the model. */
|
||||
|
|
@ -122,7 +122,7 @@ static uint32_t mmio_read32(uintptr_t address)
|
|||
}
|
||||
|
||||
/* The real tgl_lock_bios_region() + hal_flash_protect() from
|
||||
* hal/kontron_vx3060_s2.c (extracted). */
|
||||
* hal/x86_fsp_tgl.c (extracted). */
|
||||
#include "kontron_spi_fn_extract.h"
|
||||
|
||||
/* The lock must land in the MMIO space: FPR0 carries the FREG1
|
||||
|
|
|
|||
Loading…
Reference in New Issue