diff --git a/.github/workflows/test-x86-fsp-qemu.yml b/.github/workflows/test-x86-fsp-qemu.yml new file mode 100644 index 00000000..afd2edc0 --- /dev/null +++ b/.github/workflows/test-x86-fsp-qemu.yml @@ -0,0 +1,23 @@ +name: X86 FSP QEMU test + +on: + pull_request: + branches: [ '*' ] +jobs: + fsp_qemu_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: install req + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends -y -q nasm gcc-multilib qemu-system-x86 swtpm + - name: setup git + run: | + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + - name: run test + run: | + ./tools/scripts/x86_fsp/qemu/test_qemu.sh diff --git a/.gitignore b/.gitignore index 146bda1d..d2ea2036 100644 --- a/.gitignore +++ b/.gitignore @@ -132,6 +132,8 @@ CMakeCache.txt # Stage 1 stage1/loader_stage1.ld +hal/x86_fsp_tgl_stage1.ld +hal/x86_fsp_qemu_stage1.ld debug/lauterbach @@ -177,3 +179,12 @@ IDE/Renesas/e2studio/RZN2L/wolfboot/.secure_azone IDE/Renesas/e2studio/RZN2L/wolfboot/.secure_xml IDE/Renesas/e2studio/RZN2L/wolfboot/configuration.xml + +tpm_seal_key.key + +# FSP downloaded headers +include/x86/fsp/FspUpd.h +include/x86/fsp/FspmUpd.h +include/x86/fsp/FspsUpd.h +include/x86/fsp/FsptUpd.h +include/x86/fsp/MemInfoHob.h diff --git a/arch.mk b/arch.mk index 740da492..8278aa9e 100644 --- a/arch.mk +++ b/arch.mk @@ -671,6 +671,7 @@ endif ifeq ($(filter $(TARGET),x86_fsp_qemu kontron_vx3060_s2),$(TARGET)) FSP=1 CFLAGS+=-DWOLFBOOT_FSP=1 + CFLAGS+=-ffunction-sections -fdata-sections ifeq ($(TARGET), kontron_vx3060_s2) FSP_TGL=1 CFLAGS+=-DWOLFBOOT_TGL=1 @@ -697,11 +698,11 @@ ifeq ("${FSP}", "1") LSCRIPT_IN = ../hal/$(TARGET)_stage1.ld endif # using ../wolfboot.map as stage1 is built from stage1 sub-directory - LDFLAGS = --defsym main=`grep main ../wolfboot.map | awk '{print $$1}'` \ - --defsym wb_start_bss=`grep _start_bss ../wolfboot.map | awk '{print $$1}'` \ - --defsym wb_end_bss=`grep _end_bss ../wolfboot.map | awk '{print $$1}'` \ - --defsym _stage2_params=`grep _stage2_params ../wolfboot.map | awk '{print $$1}'` - LDFLAGS += --no-gc-sections --print-gc-sections -T $(LSCRIPT) -m elf_i386 -Map=loader_stage1.map + LDFLAGS = --defsym main=0x`nm ../wolfboot.elf | grep -w main | awk '{print $$1}'` \ + --defsym wb_start_bss=0x`nm ../wolfboot.elf | grep -w _start_bss | awk '{print $$1}'` \ + --defsym wb_end_bss=0x`nm ../wolfboot.elf | grep -w _end_bss | awk '{print $$1}'` \ + --defsym _stage2_params=0x`nm ../wolfboot.elf | grep -w _stage2_params | awk '{print $$1}'` + LDFLAGS += --gc-sections --entry=reset_vector -T $(LSCRIPT) -m elf_i386 -Map=loader_stage1.map OBJS += src/boot_x86_fsp.o OBJS += src/boot_x86_fsp_start.o OBJS += src/fsp_m.o @@ -713,6 +714,7 @@ ifeq ("${FSP}", "1") OBJS += src/pci.o OBJS += hal/x86_uart.o OBJS += src/string.o + OBJS += src/stage2_params.o ifeq ($(filter-out $(STAGE1_AUTH),1),) OBJS += src/libwolfboot.o OBJS += src/image.o @@ -729,7 +731,6 @@ ifeq ("${FSP}", "1") CFLAGS += -fno-stack-protector -m32 -fno-PIC -fno-pie -mno-mmx -mno-sse -DDEBUG_UART ifeq ($(FSP_TGL), 1) OBJS+=src/x86/tgl_fsp.o - OBJS+=src/fsp_tgl_s_upd.o OBJS+=src/ucode0.o CFLAGS += -DUCODE0_ADDRESS=$(UCODE0_BASE) endif @@ -743,7 +744,7 @@ ifeq ("${FSP}", "1") else LSCRIPT_IN = hal/$(TARGET).ld.in endif - LDFLAGS = --no-gc-sections --print-gc-sections -T $(LSCRIPT) -Map=wolfboot.map + LDFLAGS = --gc-sections --entry=main -T $(LSCRIPT) -Map=wolfboot.map CFLAGS += -fno-stack-protector -fno-PIC -fno-pie -mno-mmx -mno-sse -Os -DDEBUG_UART OBJS += hal/x86_fsp_tgl.o OBJS += hal/x86_uart.o @@ -755,6 +756,8 @@ ifeq ("${FSP}", "1") OBJS += src/x86/ata.o OBJS += src/x86/gpt.o OBJS += src/x86/mptable.o + OBJS += src/stage2_params.o + OBJS += src/x86/exceptions.o UPDATE_OBJS := src/update_disk.o ifeq ($(64BIT),1) LDFLAGS += -m elf_x86_64 --oformat elf64-x86-64 diff --git a/config/examples/kontron_vx3060_s2.config b/config/examples/kontron_vx3060_s2.config index 08157d75..cee530f5 100644 --- a/config/examples/kontron_vx3060_s2.config +++ b/config/examples/kontron_vx3060_s2.config @@ -1,7 +1,7 @@ ARCH=x86_64 TARGET=kontron_vx3060_s2 WOLFBOOT_SMALL_STACK=0 -SIGN=ECC256 +SIGN=ECC384 HASH=SHA256 DEBUG=1 SPMATH=1 @@ -14,9 +14,8 @@ WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff400000 WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0 WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0 -# 128mb -WOLFBOOT_LOAD_BASE=0x8000000 -WOLFBOOT_LOAD_ADDRESS=0x1000000 +# 1408mb + 0x200 (For the header) +WOLFBOOT_LOAD_BASE=0x58000200 # required for keytools WOLFBOOT_SECTOR_SIZE?=0x1000 @@ -24,7 +23,6 @@ WOLFBOOT_DATA_ADDRESS=0x1000000 FSP_S_BASE=0xffea0000 -FSP_S_UPD_DATA_BASE=0xffd00000 FSP_T_BASE=0xfff59000 FSP_M_BASE=0xfff60000 @@ -59,8 +57,10 @@ MULTIBOOT2=1 FSP_S_LOAD_BASE=0x0FED5F00 STAGE1_AUTH=1 -# MEASURED_BOOT=1 -# MEASURED_PCR_A=0 -# DISK_LOCK=1 -# WOLFTPM=1 -# WOLFBOOT_TPM_SEAL=1 +MEASURED_BOOT=1 +MEASURED_PCR_A=0 +DISK_LOCK=0 +WOLFTPM=1 +WOLFBOOT_TPM_SEAL=1 +WOLFBOOT_TPM_SEAL_KEY_ID=1 +WOLFBOOT_UNIVERSAL_KEYSTORE=1 \ No newline at end of file diff --git a/config/examples/x86_fsp_qemu.config b/config/examples/x86_fsp_qemu.config index 76734003..cfa3152b 100644 --- a/config/examples/x86_fsp_qemu.config +++ b/config/examples/x86_fsp_qemu.config @@ -1,8 +1,8 @@ ARCH=x86_64 TARGET=x86_fsp_qemu WOLFBOOT_SMALL_STACK=1 -SIGN?=ECC384 -HASH?=SHA384 +SIGN=ECC256 +HASH=SHA256 DEBUG=1 SPMATH=1 FORCE_32BIT=1 @@ -16,9 +16,6 @@ WOLFTPM=0 #WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201 # 4gb - 8mb -WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff800000 -WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0 -WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0 WOLFBOOT_LOAD_BASE=0x2000000 WOLFBOOT_LOAD_ADDRESS=0x1000000 @@ -30,13 +27,15 @@ FSP_M_BASE=0xffe30000 FSP_S_BASE=0xffed6000 FSP_T_BASE=0xfffe0000 FSP_S_LOAD_BASE=0x0FED5F00 -WOLFBOOT_ORIGIN=0xfffa0000 -LINUX_PAYLOAD=1 +WOLFBOOT_ORIGIN=0xfff80000 -BOOTLOADER_PARTITION_SIZE=0xa0000 +BOOTLOADER_PARTITION_SIZE=0xe0000 BIOS_REGION_SIZE=0x800000 MACHINE_OBJ=src/x86/qemu_fsp.o FSP_T_BIN=./src/x86/fsp_t.bin FSP_M_BIN=./src/x86/fsp_m.bin FSP_S_BIN=./src/x86/fsp_s.bin STAGE1_AUTH=1 +64BIT=1 +ELF=1 +MULTIBOOT2=1 diff --git a/config/examples/x86_fsp_qemu_tpm.config b/config/examples/x86_fsp_qemu_seal.config similarity index 75% rename from config/examples/x86_fsp_qemu_tpm.config rename to config/examples/x86_fsp_qemu_seal.config index 3926227d..8ac8ff8c 100644 --- a/config/examples/x86_fsp_qemu_tpm.config +++ b/config/examples/x86_fsp_qemu_seal.config @@ -1,20 +1,14 @@ ARCH=x86_64 TARGET=x86_fsp_qemu WOLFBOOT_SMALL_STACK=0 -SIGN?=ECC256 -HASH?=SHA256 +SIGN=ECC384 +HASH=SHA256 DEBUG=1 SPMATH=1 FORCE_32BIT=1 ENCRYPTION=0 WOLFBOOT_NO_PARTITIONS=1 -WOLFTPM=1 -# Measured boot -MEASURED_BOOT=1 -MEASURED_PCR_A=0 -WOLFBOOT_TPM_SEAL=1 -DISK_LOCK=1 # TPM Keystore options #WOLFBOOT_TPM_KEYSTORE?=1 @@ -22,9 +16,6 @@ DISK_LOCK=1 #WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201 # 4gb - 8mb -WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff800000 -WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0 -WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0 WOLFBOOT_LOAD_BASE=0x2000000 WOLFBOOT_LOAD_ADDRESS=0x1000000 @@ -36,13 +27,22 @@ FSP_M_BASE=0xffe30000 FSP_S_BASE=0xffed6000 FSP_T_BASE=0xfffe0000 FSP_S_LOAD_BASE=0x0FED5F00 -WOLFBOOT_ORIGIN=0xfff90000 -LINUX_PAYLOAD=1 +WOLFBOOT_ORIGIN=0xfff80000 -BOOTLOADER_PARTITION_SIZE=0xb0000 +BOOTLOADER_PARTITION_SIZE=0xe0000 BIOS_REGION_SIZE=0x800000 MACHINE_OBJ=src/x86/qemu_fsp.o FSP_T_BIN=./src/x86/fsp_t.bin FSP_M_BIN=./src/x86/fsp_m.bin FSP_S_BIN=./src/x86/fsp_s.bin + STAGE1_AUTH=1 +64BIT=1 +ELF=1 +MULTIBOOT2=1 +MEASURED_BOOT=1 +MEASURED_PCR_A=0 +WOLFBOOT_TPM_SEAL=1 +WOLFBOOT_TPM_SEAL_KEY_ID=1 +DISK_LOCK=1 +WOLFBOOT_UNIVERSAL_KEYSTORE=1 \ No newline at end of file diff --git a/config/examples/x86_fsp_qemu_stage1_auth.config b/config/examples/x86_fsp_qemu_stage1_auth.config deleted file mode 100644 index ec209d2f..00000000 --- a/config/examples/x86_fsp_qemu_stage1_auth.config +++ /dev/null @@ -1,42 +0,0 @@ -ARCH=x86_64 -TARGET=x86_fsp_qemu -WOLFBOOT_SMALL_STACK=1 -SIGN?=ECC256 -HASH?=SHA256 -DEBUG=1 -SPMATH=1 -FORCE_32BIT=1 -ENCRYPTION=0 -WOLFBOOT_NO_PARTITIONS=1 -WOLFTPM=0 - -# TPM Keystore options -#WOLFBOOT_TPM_KEYSTORE?=1 -#WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01800200 -#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201 - -# 4gb - 8mb -WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff800000 -WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0 -WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0 -WOLFBOOT_LOAD_BASE=0x2000000 -WOLFBOOT_LOAD_ADDRESS=0x1000000 - -# required for keytools -WOLFBOOT_SECTOR_SIZE?=0x1000 -WOLFBOOT_DATA_ADDRESS=0x1000000 - -FSP_M_BASE=0xffe30000 -FSP_S_BASE=0xffed6000 -FSP_T_BASE=0xfffe0000 -FSP_S_LOAD_BASE=0x0FED5F00 -WOLFBOOT_ORIGIN=0xfffa0000 -LINUX_PAYLOAD=1 - -BOOTLOADER_PARTITION_SIZE=0xa0000 -BIOS_REGION_SIZE=0x800000 -MACHINE_OBJ=src/x86/qemu_fsp.o -FSP_T_BIN=./src/x86/fsp_t.bin -FSP_M_BIN=./src/x86/fsp_m.bin -FSP_S_BIN=./src/x86/fsp_s.bin -STAGE1_AUTH=1 diff --git a/config/examples/x86_fsp_qemu_tpm_keystore.config b/config/examples/x86_fsp_qemu_tpm_keystore.config deleted file mode 100644 index 9b8c1111..00000000 --- a/config/examples/x86_fsp_qemu_tpm_keystore.config +++ /dev/null @@ -1,40 +0,0 @@ -ARCH=x86_64 -TARGET=x86_fsp_qemu -WOLFBOOT_SMALL_STACK=1 -SIGN?=ECC256 -HASH?=SHA256 -DEBUG=1 -SPMATH=1 -FORCE_32BIT=1 -ENCRYPTION=0 -WOLFBOOT_NO_PARTITIONS=1 -WOLFTPM=1 - -# TPM Keystore options -WOLFBOOT_TPM_KEYSTORE?=1 -WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01800200 -WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201 - -# 4gb - 8mb -WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff800000 -WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0 -WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0 -WOLFBOOT_LOAD_BASE=0x2000000 -WOLFBOOT_LOAD_ADDRESS=0x1000000 - -# required for keytools -WOLFBOOT_SECTOR_SIZE?=0x1000 -WOLFBOOT_DATA_ADDRESS=0x1000000 - -FSP_M_BASE=0xffe30000 -FSP_S_BASE=0xffed6000 -FSP_T_BASE=0xfffe0000 -BOOTLOADER_START=0xffff0000 -LINUX_PAYLOAD=1 - -BOOTLOADER_PARTITION_SIZE=0xa0000 -BIOS_REGION_SIZE=0x800000 -MACHINE_OBJ=src/x86/qemu_fsp.o -FSP_T_BIN=./src/x86/fsp_t.bin -FSP_M_BIN=./src/x86/fsp_m.bin -FSP_S_BIN=./src/x86/fsp_s.bin diff --git a/docs/Targets.md b/docs/Targets.md index 5edc710c..d26eaa52 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -2198,56 +2198,60 @@ The following variables must be set in your `.config` file when using this featu - `WOLFBOOT_LOAD_BASE`: the address where wolfboot will be loaded in RAM after the first initialization phase While Intel FSP aims to abstract away specific machine details, you still need -some machine-specific code. In the next section we show how to retrieve the -target-specific code for qemu. Refer to the Intel Integration Guide of the selected -silicon for more information. +some machine-specific code. Current supported targets are QEMU and the TigerLake based Kontron VX3060-S2 board. +Refer to the Intel Integration Guide of the selected silicon for more information. Note: - This feature requires `NASM` to be installed on the machine building wolfBoot. -### Running on 64-bit Qemu +### Running on 64-bit QEMU -An example configuration file is available in `config/examples/x86_fsp_qemu.config`. +Two example configuration files are available: `config/examples/x86_fsp_qemu.config` and `config/examples/x86_fsp_qemu_seal.config`. +Both will try to load a 64bit ELF/Multiboot2 payload from the emulated sata drive. +The second one is an example of configuration that also do measure boot and seal/unseal secrets using a TPM. + +A test ELF/Multiboot2 image is provided as well. To test `config/examples/x86_fsp_qemu.config` use the following steps: -Assuming that you have compiled a linux kernel that can boot on qemu, you can verify -and stage it by running the following commands: ``` # Copy the example configuration for this target cp config/examples/x86_fsp_qemu.config .config # Create necessary Intel FSP binaries from edk2 repo -tools/x86_fsp/qemu/qemu_build_fsp.sh +./tools/scripts/x86_fsp/qemu/qemu_build_fsp.sh # build wolfboot make -# The next script needs to be run from wolboot root folder and assumes your -# kernel is in th root folder, named bzImage -# If this is not the case, change the path in the script accordingly -tools/x86_fsp/qemu/make_hd.sh +# make test-app +make test-app/image.elf -# Run wolfBoot + Linux in qemu -tools/scripts/qemu64/qemu64.sh +# make_hd.sh sign the image, creates a file-based hard disk image with GPT table and raw partitions and then copies the signed images into the partitions. +IMAGE=test-app/image.elf tools/scripts/x86_fsp/qemu/make_hd.sh +# run wolfBoot + test-image +./tools/scripts/x86_fsp/qemu/qemu.sh ``` -#### Sample boot output +#### Sample boot output using config/examples/x86_fsp_qemu.config ``` Cache-as-RAM initialized +FSP-T:0.0.10 build 0 +FSP-M:0.0.10 build 0 +no microcode for QEMU target calling FspMemInit... ============= FSP Spec v2.0 Header Revision v3 ($QEMFSP$ v0.0.10.0) ============= Fsp BootFirmwareVolumeBase - 0xFFE30000 Fsp BootFirmwareVolumeSize - 0x22000 Fsp TemporaryRamBase - 0x4 -Fsp TemporaryRamSize - 0x20000 +Fsp TemporaryRamSize - 0x50000 Fsp PeiTemporaryRamBase - 0x4 -Fsp PeiTemporaryRamSize - 0x14CCC -Fsp StackBase - 0x14CD0 -Fsp StackSize - 0xB334 +Fsp PeiTemporaryRamSize - 0x34000 +Fsp StackBase - 0x34004 +Fsp StackSize - 0x1C000 Register PPI Notify: DCD0BE23-9586-40F4-B643-06522CED4EDE Install PPI: 8C8CE578-8A3D-4F1C-9935-896185C32DD3 Install PPI: 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A @@ -2273,15 +2277,15 @@ Install PPI: 7408D748-FC8C-4EE6-9288-C4BEC092A410 Register PPI Notify: F894643D-C449-42D1-8EA8-85BDD8C65BDE PeiInstallPeiMemory MemoryBegin 0x3EF00000, MemoryLength 0x100000 FspmInitPoint() - End -Temp Stack : BaseAddress=0x14CD0 Length=0xB334 -Temp Heap : BaseAddress=0x4 Length=0x14CCC -Total temporary memory: 131072 bytes. +Temp Stack : BaseAddress=0x34004 Length=0x1C000 +Temp Heap : BaseAddress=0x4 Length=0x34000 +Total temporary memory: 327680 bytes. temporary memory stack ever used: 3360 bytes. temporary memory heap used for HobList: 2104 bytes. temporary memory heap occupied by memory pages: 0 bytes. -Old Stack size 45876, New stack size 131072 +Old Stack size 114688, New stack size 131072 Stack Hob: BaseAddress=0x3EF00000 Length=0x20000 -Heap Offset = 0x3EF1FFFC Stack Offset = 0x3EEFFFFC +Heap Offset = 0x3EF1FFFC Stack Offset = 0x3EECFFFC Loading PEIM 52C05B14-0B98-496C-BC3B-04B50211D680 Loading PEIM at 0x0003EFF5150 EntryPoint=0x0003EFFBBC6 PeiCore.efi Reinstall PPI: 8C8CE578-8A3D-4F1C-9935-896185C32DD3 @@ -2291,19 +2295,34 @@ Install PPI: F894643D-C449-42D1-8EA8-85BDD8C65BDE Notify: PPI Guid: F894643D-C449-42D1-8EA8-85BDD8C65BDE, Peim notify entry point: FFE40AB2 Memory Discovered Notify invoked ... FSP TOLM = 0x3F000000 -Migrate FSP-M UPD from 7F548 to 3EFF4000 +Migrate FSP-M UPD from 7F540 to 3EFF4000 FspMemoryInitApi() - [Status: 0x00000000] - End success top reserved 0_3EF00000h +mem: [ 0x3EEF0000, 0x3EF00000 ] - stack (0x10000) +mem: [ 0x3EEEFFF4, 0x3EEF0000 ] - stage2 parameter (0xC) hoblist@0x3EF20000 +mem: [ 0x3EEE8000, 0x3EEEFFF4 ] - page tables (0x7FF4) +page table @ 0x3EEE8000 [length: 7000] +mem: [ 0x3EEE7FF8, 0x3EEE8000 ] - stage2 ptr holder (0x8) +TOLUM: 0x3EEE7FF8 TempRamExitApi() - Begin Memory Discovered Notify completed ... TempRamExitApi() - [Status: 0x00000000] - End +mem: [ 0x800000, 0x800084 ] - stage1 .data (0x84) +mem: [ 0x8000A0, 0x801A80 ] - stage1 .bss (0x19E0) +mem: [ 0xFED5E00, 0xFEEAF00 ] - FSPS (0x15100) +Authenticating FSP_S at FED5E00... +Image size 86016 +verify_payload: image open successfully. +verify_payload: integrity OK. Checking signature. +FSP_S: verified OK. +FSP-S:0.0.10 build 0 call silicon... SiliconInitApi() - Begin Install PPI: 49EDB1C1-BF21-4761-BB12-EB0031AABB39 Notify: PPI Guid: 49EDB1C1-BF21-4761-BB12-EB0031AABB39, Peim notify entry point: FFE370A2 -The 1th FV start address is 0x000FFED6000, size is 0x00015000, handle is 0xFFED6000 +The 1th FV start address is 0x0000FED5F00, size is 0x00015000, handle is 0xFED5F00 DiscoverPeimsAndOrderWithApriori(): Found 0x4 PEI FFS files in the 1th FV Loading PEIM 86D70125-BAA3-4296-A62F-602BEBBB9081 Loading PEIM at 0x0003EFEE150 EntryPoint=0x0003EFF15B9 DxeIpl.efi @@ -2335,6 +2354,11 @@ FspInitEndOfPeiCallback-- FSP is waiting for NOTIFY FspSiliconInitApi() - [Status: 0x00000000] - End success +pcie retraining failed FFFFFFFF +cap a 0 +ddt disabled 0 +device enable: 0 +device enable: 128 NotifyPhaseApi() - Begin [Phase: 00000020] FSP Post PCI Enumeration ... Install PPI: 30CFE3E7-3DE1-4586-BE20-DEABA1B3B793 @@ -2357,8 +2381,15 @@ FspEndOfFirmwareCallback++ FspEndOfFirmwareCallback-- NotifyPhaseApi() - End [Status: 0x00000000] CPUID(0):D 68747541 444D4163 -loading wolfboot at 2000000... +mem: [ 0x1FFFF00, 0x200CC70 ] - wolfboot (0xCD70) +mem: [ 0x200CC70, 0x222FA00 ] - wolfboot .bss (0x222D90) load wolfboot end +Authenticating wolfboot at 2000000... +Image size 52336 +verify_payload: image open successfully. +verify_payload: integrity OK. Checking signature. +wolfBoot: verified OK. +starting wolfboot 64bit AHCI port 0: No disk detected AHCI port 1: No disk detected AHCI port 2: No disk detected @@ -2381,46 +2412,95 @@ Total partitions on disk0: 2 Checking primary OS image in 0,0... Checking secondary OS image in 0,1... Versions, A:1 B:2 +Load address 0x222FA00 Attempting boot from partition B -Image size 11982512 -Firmware Valid -Booting at 5000100 -linux payload +mem: [ 0x222FA00, 0x2241DC8 ] - ELF (0x123C8) +Loading image from disk...done. +Image size 74696 +Checking image integrity...done. +Verifying image signature...done. +Firmware Valid. +Booting at 222FB00 +mem: [ 0x100, 0x1E0 ] - MPTABLE (0xE0) +Loading elf at 0x222FB00 +Found valid elf64 (little endian) +Program Headers 7 (size 56) +Load 504 bytes (offset 0x0) to 0x400000 (p 0x400000) +Load 3999 bytes (offset 0x1000) to 0x401000 (p 0x401000) +Load 1952 bytes (offset 0x2000) to 0x402000 (p 0x402000) +Load 32 bytes (offset 0x3000) to 0x403000 (p 0x403000) +Entry point 0x401000 +Elf loaded (ret 0), entry 0x0_401000 +mb2 header found at 2232B00 booting... -Linux version 5.17.15 (arch@wb-hg-2) (x86_64-linux-gcc.br_real (Buildroot toolchains.bootlin.com-2021.11-5) 11.2.0, GNU ld (GNU Binutils) 2.37) #24 PREEMPT Wed May 17 13:47:24 UTC 2023 +wolfBoot QEMU x86 FSP test app ``` -### Running on 64-bit Qemu with swtpm (TPM emulator) +### Running on QEMU with swtpm (TPM emulator) -The example configuration for this setup can be found in -`config/examples/x86_fsp_qemu_tpm.config`. +First step: [clone and install swtpm](https://github.com/stefanberger/swtpm), a +TPM emulator that can be connected to qemu guest VMs. This TPM emulator will +create a memory-mapped I/O device. -First step: [clone and install swtpm](https://github.com/stefanberger/swtpm), a TPM emulator that can be connected to qemu -guest VMs. This TPM emulator will create a memory-mapped I/O device. - -The other steps to follow are: +A small note is that `config/examples/x86_fsp_qemu_seal.config` showcases two +different key ecc size of 384 and 256 of authentication for image verification +and TPM sealing respectively. +The correct steps to run the example: ``` -# Copy the example configuration for this target -cp config/examples/x86_fsp_qemu_tpm.config .config +# copy the example configuration for this target +cp config/examples/x86_fsp_qemu_seal.config .config -# Create necessary Intel FSP binaries from edk2 repo -tools/x86_fsp/qemu/qemu_build_fsp.sh +# create necessary Intel FSP binaries from edk2 repo +tools/scripts/x86_fsp/qemu/qemu_build_fsp.sh -# Compile wolfBoot and assemble the loader image -make +# make keytools and tpmtools +make keytools +make tpmtools -# The next script needs to be run from wolboot root folder and assumes your -# kernel is in wolfBoot's root folder. The file should be named `bzImage`. -# If this is not the case, change the path in the script accordingly +# create two keys, one for signing the images (ecc384) and one to seal/unseal secret into the TPM (ecc256) +./tools/keytools/keygen --force --ecc384 -g wolfboot_signing_private_key.der --ecc256 -g tpm_seal_key.key -tools/x86_fsp/qemu/make_hd.sh +# build wolfboot, manually add ECC256 for TPM +make CFLAGS_EXTRA="-DHAVE_ECC256" -# Run wolfBoot + linux in qemu, with swTPM connected to the guest machine. -# The script will start the TPM emulator before launching the VM. -tools/scripts/qemu64/qemu64-tpm.sh +# compute the value of PCR0 to sign with TPM key +PCR0=$(python ./tools/scripts/x86_fsp/compute_pcr.py --target qemu wolfboot_stage1.bin | tail -n 1) + +# sign the policy +./tools/tpm/policy_sign -ecc256 -key=tpm_seal_key.key -pcr=0 -pcrdigest=$PCR0 + +# install the policy +./tools/scripts/x86_fsp/tpm_install_policy.sh policy.bin.sig + +# make test-app +make test-app/image.elf + +# make_hd.sh sign the image, creates a file-based hard disk image with GPT table and raw partitions and then copy the signed images into the partitions. +IMAGE=test-app/image.elf SIGN=--ecc384 tools/scripts/x86_fsp/qemu/make_hd.sh + +# run wolfBoot + test-image, use -t to emulate a TPM (requires swtpm) +./tools/scripts/x86_fsp/qemu/qemu.sh -t ``` For more advanced uses of TPM, please check [TPM.md](TPM.md) to configure wolfBoot according to your secure boot strategy. +### Running on Kontron VX3060-S2 + +A reference configuration and helper scripts are provided to run wolfBoot on +Kontron VX3060-S2 board. +A flash dump of the original Flash BIOS is needed. +To compile a flashable image run the following steps: + +``` +cp config/examples/kontron_vx3060_s2.config .config +./tools/scripts/x86_fsp/tgl/tgl_download_fsp.sh +make tpmtools +./tools/scripts/x86_fsp/tgl/assemble_image.sh -k +make CFLAGS_EXTRA="-DHAVE_ECC256" +./tools/scripts/x86_fsp/tgl/assemble_image.sh -n /path/to/original/flash/dump +``` + +they produce a file named `final_image.bin` inside the root folder of the +repository that can be directly flashed into the BIOS flash of the board. diff --git a/docs/ata_security.md b/docs/ata_security.md new file mode 100644 index 00000000..4f354c9d --- /dev/null +++ b/docs/ata_security.md @@ -0,0 +1,44 @@ +# ATA Security + +## Introduction +This document provides an overview of how wolfBoot can leaverage the ATA security features to lock or unlock ATA drive. +The ATA drive may be locked either by using a hardcoded password or by using a secret that is sealed in the TPM. + +## Table of Contents +- [ATA Security](#ata-security) + - [Introduction](#introduction) + - [Table of Contents](#table-of-contents) + - [Unlocking the Disk with a Hardcoded Password](#unlocking-the-disk-with-a-hardcoded-password) + - [Unlocking the Disk with a TPM-Sealed Secret](#unlocking-the-disk-with-a-tpm-sealed-secret) + - [Disabling the password](#disabling-the-password) + +## Unlocking the Disk with a Hardcoded Password +To unlock the disk using a hardcoded password, use the following options in your .config file: +``` +DISK_LOCK=1 +DISK_LOCK_PASSWORD=hardcoded_password +``` +If the ATA disk has no password set, the disk will be locked with the password provided at the first boot. + +## Unlocking the Disk with a TPM-Sealed Secret +wolfBoot allows to seal secret safely in the TPM in a way that it can be unsealed only under specific conditions. Please refer to files TPM.md and measured_boot.md for more information. +If the options `WOLFBOOT_TPM_SEAL` and `DISK_LOCK` are enabled, wolfBoot will use a TPM sealed secret as the password to unlock the disk. The following options controls the sealing and unsealing of the secret: + +| Option | Description | +|--------|-------------| +| WOLFBOOT_TPM_SEAL_KEY_ID| The key ID to use for sign the policy | +| ATA_UNLOCK_DISK_KEY_NV_INDEX | The NV index to store the sealed secret. | +| WOLFBOOT_DEBUG_REMOVE_SEALED_ON_ERROR| In case of error, delete the secret and panic() | + +In case there are no secret sealed at `ATA_UNLOCK_DISK_KEY_NV_INDEX`, a new random secret will be created and sealed at that index. +In case the ATA drive is not locked, it will be locked at the first boot with the secret sealed in the TPM. + +## Disabling the password + +If you need to disable the password, a master password should be already set on the device. Then you can use the following options to compile wolfBoot so that it will disable the password from the drive and panic: + +``` +WOLFBOOT_ATA_DISABLE_USER_PASSWORD=1 +ATA_MASTER_PASSWORD=the_master_password +``` + diff --git a/hal/kontron_vx3060_s2.c b/hal/kontron_vx3060_s2.c index e516593c..b642cad6 100644 --- a/hal/kontron_vx3060_s2.c +++ b/hal/kontron_vx3060_s2.c @@ -23,10 +23,66 @@ #include #include #include -#include +#include +#include #ifdef __WOLFBOOT +#define SPI_PCI_DEV 31 +#define SPI_PCI_FUN 5 +#define SPI_BAR_OFF 0x10 +#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 (0x48) +#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; + +#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); + + 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 + /* Flash Protected Range register has very similar layout of the Flash + * Region Register, so we can reuse it and just enable read and write + * protection + */ + reg |= (SPI_FPR_RPE) | (SPI_FPR_WPE); + pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, SPI_FPR0, reg); + + /* lock down BIOS register configuration */ + reg = pci_config_read32(0, SPI_PCI_DEV, SPI_PCI_FUN, SPI_BIOS_HSFSTS_CTL); + reg |= SPI_FLOCKDN; + pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, SPI_BIOS_HSFSTS_CTL, reg); + + /* restore original cmd */ + pci_config_write32(0, SPI_PCI_DEV, SPI_PCI_FUN, PCI_COMMAND_OFFSET, spi_cmd); + return 0; +} + void hal_init(void) { } diff --git a/hal/x86_fsp_qemu_stage1.ld.in b/hal/x86_fsp_qemu_stage1.ld.in index 566b6fd5..c0e0e6a5 100644 --- a/hal/x86_fsp_qemu_stage1.ld.in +++ b/hal/x86_fsp_qemu_stage1.ld.in @@ -24,7 +24,7 @@ SECTIONS { _wolfboot_flash_start = .; KEEP(*(.sig_wolfboot_raw*)) - *(.wolfboot) + KEEP(*(.wolfboot)) _wolfboot_flash_end = .; } > FLASH @@ -41,7 +41,7 @@ SECTIONS .keystore KEYSTORE_START : { _start_keystore = .; - *(.keystore*) + KEEP(*(.keystore*)) } > FLASH .jmpto32 BOOTLOADER_JUMP32_START : @@ -60,7 +60,6 @@ SECTIONS KEEP(*(.boot*)) *(.text*) *(.rodata*) - *(.eh_frame*) . = ALIGN(256); } > FLASH @@ -90,7 +89,7 @@ SECTIONS AT(FSP_T_ORIGIN) { _start_fsp_t = .; - *(.fsp_t) + KEEP(*(.fsp_t)) } .fsp_s FSP_S_ORIGIN : @@ -98,14 +97,14 @@ SECTIONS _fsp_s_hdr = .; KEEP(*(.sig_fsp_s*)) _start_fsp_s = .; - *(.fsp_s) + KEEP(*(.fsp_s)) _end_fsp_s = .; } .fsp_m FSP_M_ORIGIN : { _start_fsp_m = .; - *(.fsp_m) + KEEP(*(.fsp_m)) _end_fsp_m = .; } } diff --git a/hal/x86_fsp_tgl_stage1.ld.in b/hal/x86_fsp_tgl_stage1.ld.in index c1d6ba59..0d9b6f31 100644 --- a/hal/x86_fsp_tgl_stage1.ld.in +++ b/hal/x86_fsp_tgl_stage1.ld.in @@ -1,6 +1,5 @@ FLASH_SIZE = @BOOTLOADER_PARTITION_SIZE@; FLASH_START = 0x100000000 - @BOOTLOADER_PARTITION_SIZE@; -FSP_S_UPD_DATA_BASE = @FSP_S_UPD_DATA_BASE@; UCODE0_BASE = @UCODE0_BASE@; FIT_TABLE = 0xffe00000; FSP_S_ORIGIN = @FSP_S_BASE@; @@ -28,7 +27,7 @@ SECTIONS { _wolfboot_flash_start = .; KEEP(*(.sig_wolfboot_raw*)) - *(.wolfboot) + KEEP(*(.wolfboot)) _wolfboot_flash_end = .; } > FLASH @@ -38,18 +37,13 @@ SECTIONS _policy_size_u32 = .; . += 4; _start_policy = .; - . += MAX_POLICY_SIZE; + . += MAX_POLICY_SIZE; _end_policy = .; } > FLASH - .fsps_upd FSP_S_UPD_DATA_BASE : - { - KEEP(./fsp_tgl_s_upd.o(.fsps_upd)) - } > FLASH - .ucode_update0 UCODE0_BASE : { - *(.ucode0) + KEEP(*(.ucode0)) } > FLASH .fit_table FIT_TABLE : @@ -63,19 +57,18 @@ SECTIONS _fsp_s_hdr = .; KEEP(*(.sig_fsp_s*)) _start_fsp_s = .; - *(.fsp_s) + KEEP(*(.fsp_s)) _end_fsp_s = .; } > FLASH .bootloader WOLFBOOT_ORIGIN : { KEEP(./tgl_fsp.o(.boot)) - *(.boot*) + KEEP(*(.boot*)) KEYSTORE_START = .; - *(.keystore*) + KEEP(*(.keystore*)) *(.text*) *(.rodata*) - *(.eh_frame*) . = ALIGN(256); } > FLASH @@ -106,13 +99,13 @@ SECTIONS AT(FSP_T_ORIGIN) { _start_fsp_t = .; - *(.fsp_t) + KEEP(*(.fsp_t)) } > FLASH .fsp_m FSP_M_ORIGIN : { _start_fsp_m = .; - *(.fsp_m) + KEEP(*(.fsp_m)) _end_fsp_m = .; } > FLASH diff --git a/include/pci.h b/include/pci.h index 4f9eae63..c3fd99ba 100644 --- a/include/pci.h +++ b/include/pci.h @@ -25,7 +25,9 @@ #define PCI_VENDOR_ID_OFFSET 0x00 #define PCI_DEVICE_ID_OFFSET 0x02 -#define PCI_COMMAND_OFFSET 0x04 +#define PCI_COMMAND_OFFSET 0x04 +#define PCI_STATUS_OFFSET 0x06 +#define PCI_CAP_OFFSET 0x34 /* Programming interface, Rev. ID and class code */ #define PCI_RID_CC_OFFSET 0x08 #define PCI_HEADER_TYPE_OFFSET 0x0E @@ -69,9 +71,17 @@ #define PCI_COMMAND_SPECIAL_CYCLE (1 << 3) #define PCI_COMMAND_BUS_MASTER (1 << 2) #define PCI_COMMAND_MEM_SPACE (1 << 1) -#define PCI_COMMAND_IO_SPACE (1 << 0) +#define PCI_COMMAND_IO_SPACE (1 << 0) -typedef struct { +/* STATUS bits */ +#define PCI_STATUS_CAP_LIST (1 << 4) + +#define PCI_PCIE_CAP_ID (0x10) +#define PCIE_LINK_STATUS_OFF (0x12) +#define PCIE_LINK_CONTROL_OFF (0x10) +#define PCIE_LINK_STATUS_TRAINING (1 << 11) +#define PCIE_LINK_CONTROL_RETRAINING (1 << 5) +typedef struct { int bus; int device; int function; @@ -113,6 +123,7 @@ uint32_t pci_enum_bus(uint8_t bus, struct pci_enum_info *info); int pci_enum_do(void); int pci_pre_enum(void); +void pci_dump_config_space(void); #ifdef __cplusplus } diff --git a/include/stage1.h b/include/stage2_params.h similarity index 76% rename from include/stage1.h rename to include/stage2_params.h index ed4aa74e..12972e73 100644 --- a/include/stage1.h +++ b/include/stage2_params.h @@ -1,4 +1,4 @@ -/* stage1.h +/* stage2_params.h * * Copyright (C) 2023 wolfSSL Inc. * @@ -35,8 +35,15 @@ struct stage2_parameter { #endif } __attribute__((packed)); -/* implemented in src/boot_x86_fsp_payload.c */ -struct stage2_parameter *stage2_get_parameters(); +#define DUMMY_IDT_DESC_SIZE 4 +struct stage2_ptr_holder { + struct stage2_parameter *ptr; + uint8_t dummy_idt[DUMMY_IDT_DESC_SIZE]; +} __attribute__((packed)); + +struct stage2_parameter *stage2_get_parameters(void); +void stage2_set_parameters(struct stage2_parameter *p, struct stage2_ptr_holder *holder); +void stage2_copy_parameter(struct stage2_parameter *p); #if defined(WOLFBOOT_TPM_SEAL) int stage2_get_tpm_policy(const uint8_t **policy, uint16_t *policy_size); diff --git a/include/tpm.h b/include/tpm.h index d0043725..832fe813 100644 --- a/include/tpm.h +++ b/include/tpm.h @@ -106,6 +106,8 @@ int wolfBoot_tpm2_extend(uint8_t pcrIndex, uint8_t* hash, int line); wolfBoot_tpm2_extend(WOLFBOOT_MEASURED_PCR_A, (hash), __LINE__) #endif /* WOLFBOOT_MEASURED_BOOT */ +int wolfBoot_tpm_self_test(void); + /* debugging */ void wolfBoot_print_hexstr(const unsigned char* bin, unsigned long sz, unsigned long maxLine); diff --git a/include/user_settings.h b/include/user_settings.h index 2ec00965..0eff5fc7 100644 --- a/include/user_settings.h +++ b/include/user_settings.h @@ -132,31 +132,36 @@ extern int tolower(int c); /* Curve */ # ifdef WOLFBOOT_SIGN_ECC256 # define HAVE_ECC256 -# define FP_MAX_BITS (256 + 32) -# if !defined(USE_FAST_MATH) && !defined(WOLFSSL_SP_MATH_ALL) -# define WOLFSSL_SP_NO_384 -# define WOLFSSL_SP_NO_521 -# endif # elif defined(WOLFBOOT_SIGN_ECC384) # define HAVE_ECC384 -# define FP_MAX_BITS (384 * 2) -# if !defined(USE_FAST_MATH) && !defined(WOLFSSL_SP_MATH_ALL) -# define WOLFSSL_SP_384 -# define WOLFSSL_SP_NO_256 -# endif -# if !defined(WOLFBOOT_TPM_PARMENC) -# define NO_ECC256 -# endif +# define WOLFSSL_SP_384 # elif defined(WOLFBOOT_SIGN_ECC521) # define HAVE_ECC521 -# define FP_MAX_BITS (528 * 2) -# if !defined(USE_FAST_MATH) && !defined(WOLFSSL_SP_MATH_ALL) -# define WOLFSSL_SP_521 -# define WOLFSSL_SP_NO_256 -# endif -# if !defined(WOLFBOOT_TPM_PARMENC) -# define NO_ECC256 -# endif +# define WOLFSSL_SP_521 +# endif + /* FP MAX BITS */ +# if defined(HAVE_ECC521) +# define FP_MAX_BITS ((528 * 2)) +# elif defined(HAVE_ECC384) +# define FP_MAX_BITS ((384 * 2)) +# elif defined(HAVE_ECC256) +# define FP_MAX_BITS ((256 + 32)) +# endif + +# if !defined(HAVE_ECC256) && !defined(WOLFBOOT_TPM_PARMENC) +# define NO_ECC256 +# endif + +# if !defined(USE_FAST_MATH) && !defined(WOLFSSL_SP_MATH_ALL) +# if !defined(HAVE_ECC521) +# define WOLFSSL_SP_NO_521 +# endif +# if !defined(HAVE_ECC384) +# define WOLFSSL_SP_NO_384 +# endif +# if !defined(HAVE_ECC256) +# define WOLFSSL_SP_NO_256 +# endif # endif #endif /* WOLFBOOT_SIGN_ECC521 || WOLFBOOT_SIGN_ECC384 || WOLFBOOT_SIGN_ECC256 */ diff --git a/include/x86/ahci.h b/include/x86/ahci.h index 37f97584..2b96ef72 100644 --- a/include/x86/ahci.h +++ b/include/x86/ahci.h @@ -174,5 +174,6 @@ struct ahci_received_fis { uint32_t ahci_enable(uint32_t bus, uint32_t dev, uint32_t fun); void sata_enable(uint32_t base); void sata_disable(uint32_t base); +int sata_unlock_disk(int drv, int freeze); #endif /* AHCI_H */ diff --git a/include/x86/ata.h b/include/x86/ata.h index 3f7ae552..a283d3a8 100644 --- a/include/x86/ata.h +++ b/include/x86/ata.h @@ -41,10 +41,15 @@ int ata_drive_read(int drv, uint64_t start, uint32_t count, uint8_t *buf); int ata_drive_write(int drv, uint64_t start, uint32_t count, const uint8_t *buf); int ata_identify_device(int drv); +int ata_security_erase_prepare(int drv); +int ata_security_erase_unit(int drv, const char *passphrase, int master); +int ata_security_set_password(int drv, int master, const char *passphrase); +int ata_security_disable_password(int drv, const char *passphrase, int master); int ata_device_config_identify(int drv); int ata_security_freeze_lock(int drv); -int ata_security_unlock_device(int drv, const char *passphrase); +int ata_security_unlock_device(int drv, const char *passphrase, int master); +int ata_cmd_complete_async(); /* @brief Enum with the possible state for each drive. * See ATA/ATAPI Command Set (ATA8-ACS) section 4.7.4 @@ -101,5 +106,7 @@ enum ata_security_state ata_security_get_state(int); /* Constants for security set commands */ #define ATA_SECURITY_COMMAND_LEN (256 * 2) #define ATA_SECURITY_PASSWORD_OFFSET (1 * 2) - +#define ATA_ERR_BUSY -2 +#define ATA_ERR_OP_IN_PROGRESS -3 +#define ATA_ERR_OP_NOT_IN_PROGRESS -4 #endif diff --git a/include/x86/common.h b/include/x86/common.h index ba5aa3fd..78ed9159 100644 --- a/include/x86/common.h +++ b/include/x86/common.h @@ -67,4 +67,5 @@ void cpuid(uint32_t eax_param, int cpuid_is_1gb_page_supported(); void switch_to_long_mode(uint64_t *entry, uint32_t page_table); void x86_log_memory_load(uint32_t start, uint32_t end, const char *name); +void hlt(); #endif /* COMMON_H */ diff --git a/include/x86/exceptions.h b/include/x86/exceptions.h new file mode 100644 index 00000000..71f4e7f0 --- /dev/null +++ b/include/x86/exceptions.h @@ -0,0 +1,32 @@ +/* exceptions.h + * + * Copyright (C) 2023 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef EXCEPTIONS_H +#define EXCEPTIONS_H + +#include + +int setup_interrupt_gate(int vnum, uintptr_t handler); +int setup_interrupts(); +void deinit_interrupts(); +void wfi(); + +#endif /* EXCEPTIONS_H */ diff --git a/include/x86/gpt.h b/include/x86/gpt.h index 466bb205..7656bef9 100644 --- a/include/x86/gpt.h +++ b/include/x86/gpt.h @@ -24,4 +24,5 @@ int disk_open(int drv); int disk_read(int drv, int part, uint64_t off, uint64_t sz, uint8_t *buf); int disk_write(int drv, int part, uint64_t off, uint64_t sz, const uint8_t *buf); +int disk_find_partion_by_label(int drv, const char *label); #endif diff --git a/options.mk b/options.mk index fa4dfe39..d0361559 100644 --- a/options.mk +++ b/options.mk @@ -34,7 +34,9 @@ ifeq ($(WOLFBOOT_TPM_SEAL),1) ifneq ($(WOLFBOOT_TPM_SEAL_NV_BASE),) CFLAGS+=-D"WOLFBOOT_TPM_SEAL_NV_BASE=$(WOLFBOOT_TPM_SEAL_NV_BASE)" endif - + ifneq ($(WOLFBOOT_TPM_SEAL_KEY_ID),) + CFLAGS+=-D"WOLFBOOT_TPM_SEAL_KEY_ID=$(WOLFBOOT_TPM_SEAL_KEY_ID)" + endif ifneq ($(POLICY_FILE),) SIGN_OPTIONS+=--policy $(POLICY_FILE) endif @@ -779,7 +781,6 @@ ifeq ($(FSP), 1) PCI_USE_ECAM \ PCH_PCR_BASE \ PCI_ECAM_BASE \ - FSP_S_UPD_DATA_BASE \ WOLFBOOT_LOAD_BASE \ FSP_S_LOAD_BASE diff --git a/src/boot_x86_fsp.c b/src/boot_x86_fsp.c index c503d601..2c84a875 100644 --- a/src/boot_x86_fsp.c +++ b/src/boot_x86_fsp.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "wolfboot/wolfboot.h" #include "image.h" @@ -74,7 +74,7 @@ const uint8_t __attribute__((section(".sig_wolfboot_raw"))) /* Amount of car memory to provide to FSP-M, machine dependent, find the value * in the integration guide */ #ifndef FSP_M_CAR_MEM_SIZE -#define FSP_M_CAR_MEM_SIZE 0x20000 +#define FSP_M_CAR_MEM_SIZE 0x50000 #endif /* offset of the header from the base image */ @@ -85,6 +85,9 @@ const uint8_t __attribute__((section(".sig_wolfboot_raw"))) #define MEMORY_4GB (4ULL * 1024 * 1024 * 1024) #define ENDLINE "\r\n" +#define PCI_DEVICE_CONTROLLER_TO_PEX 0x6 +#define PCIE_TRAINING_TIMEOUT_MS (100) + typedef uint32_t (*memory_init_cb)(void *udp, struct efi_hob **HobList); typedef uint32_t (*temp_ram_exit_cb)(void *udp); typedef uint32_t (*silicon_init_cb)(void *udp); @@ -95,8 +98,11 @@ int fsp_machine_update_m_parameters(uint8_t *default_m_params, uint32_t mem_base, uint32_t mem_size); int fsp_machine_update_s_parameters(uint8_t *default_s_params); int post_temp_ram_init_cb(void); +int fsp_pre_mem_init_cb(void); +int fsp_pre_silicon_init_cb(void); /* from the linker */ +extern uint8_t _start_fsp_t[]; extern uint8_t _start_fsp_m[]; extern uint8_t _fsp_s_hdr[]; extern uint8_t _end_fsp_m[]; @@ -110,10 +116,8 @@ extern const uint8_t _start_policy[], _end_policy[]; extern const uint32_t _policy_size_u32[]; extern const uint8_t _start_keystore[]; -/* wolfboot symbols */ +/* wolfboot symbol */ extern int main(void); -extern uint8_t _stage2_params[]; - /*! * \brief Get the top address from the EFI HOB (Hand-Off Block) list. @@ -150,15 +154,13 @@ static int get_top_address(uint64_t *top, struct efi_hob *hoblist) * \param ptr Pointer to the parameter to be passed to the invoked function. */ static void change_stack_and_invoke(uint32_t new_stack, - void (*other_func)(void *), void *ptr) + void (*other_func)(void)) { __asm__ volatile("movl %0, %%eax\n" - "subl $4, %%eax\n" - "movl %1, (%%eax)\n" "mov %%eax, %%esp\n" - "call *%2\n" + "call *%1\n" : - : "r"(new_stack), "r"(ptr), "r"(other_func) + : "r"(new_stack), "r"(other_func) : "%eax"); } static int range_overlaps(uint32_t start1, uint32_t end1, uint32_t start2, @@ -230,19 +232,6 @@ static void load_fsp_s_to_ram(void) memcpy((uint8_t*)fsp_start, _fsp_s_hdr, fsp_s_size); } -/*! - * \brief Set the stage 2 parameter for the WolfBoot bootloader. - * - * This static function sets the stage 2 parameter for the WolfBoot bootloader, - * which will be used by the bootloader during its execution. - * - * \param p Pointer to the stage 2 parameter structure. - */ -static void set_stage2_parameter(struct stage2_parameter *p) -{ - memcpy((uint8_t*)_stage2_params, (uint8_t*)p, sizeof(*p)); -} - #ifdef WOLFBOOT_64BIT /*! * \brief Jump into the WolfBoot bootloader. @@ -252,25 +241,28 @@ static void set_stage2_parameter(struct stage2_parameter *p) */ static void jump_into_wolfboot(void) { - struct stage2_parameter *params = (struct stage2_parameter*)_stage2_params; + struct stage2_parameter *params; uint32_t cr3; int ret; - x86_log_memory_load((uint32_t)(uintptr_t)params->page_table,params->page_table + x86_paging_get_page_table_size(), - "IdentityPageTablePage"); + params = stage2_get_parameters(); ret = x86_paging_build_identity_mapping(MEMORY_4GB, (uint8_t*)(uintptr_t)params->page_table); if (ret != 0) { wolfBoot_printf("can't build identity mapping\r\n"); panic(); } + + stage2_copy_parameter(params); wolfBoot_printf("starting wolfboot 64bit\r\n"); switch_to_long_mode((uint64_t*)&main, params->page_table); panic(); } #else -static void jump_into_wolfboot() +static void jump_into_wolfboot(void) { + struct stage2_parameter *params = stage2_get_parameters(); + stage2_copy_parameter(params); main(); } #endif /* WOLFBOOT_64BIT */ @@ -350,6 +342,133 @@ static inline void memory_init_data_bss(void) memset(_start_bss, 0, (_end_bss - _start_bss)); } +/*! + * \brief Check if the FSP info header is valid. + * + * This static function checks if the given FSP info header is valid by verifying + * its signature. + * + * \param hdr Pointer to the FSP info header structure. + * \return 1 if the FSP info header is valid, 0 otherwise. + */ +static int fsp_info_header_is_ok(struct fsp_info_header *hdr) +{ + uint8_t *raw_signature; + + raw_signature = (uint8_t *)&hdr->Signature; + if (raw_signature[0] != 'F' || raw_signature[1] != 'S' || + raw_signature[2] != 'P' || raw_signature[3] != 'H') { + return 0; + } + return 1; +} + +static int fsp_get_image_revision(struct fsp_info_header *h, int *build, + int *rev, int *maj, int *min) +{ + uint16_t ext_revision; + uint32_t revision; + + if (!fsp_info_header_is_ok(h)) { + wolfBoot_printf("Wrong FSP Header\r\n"); + return -1; + } + + revision = h->ImageRevision; + + *build = revision & 0xff; + *rev = (revision >> 8) & 0xff; + *min = (revision >> 16) & 0xff; + *maj = (revision >> 24) & 0xff; + + if (h->HeaderRevision >= 6) { + *build = *build | ((h->ExtendedImageRevision & 0xff) << 8); + *rev = *rev | (h->ExtendedImageRevision & 0xff00); + } + + return 0; +} + +static void print_fsp_image_revision(struct fsp_info_header *h) +{ + int build, rev, maj, min; + int r; + r = fsp_get_image_revision(h, &build, &rev, &maj, &min); + if (r != 0) { + wolfBoot_printf("failed to get fsp image revision\r\n"); + return; + } + wolfBoot_printf("%x.%x.%x build %x\r\n", maj, min, rev, build); +} + +static int pci_get_capability(uint8_t bus, uint8_t dev, uint8_t fun, + uint8_t cap_id, uint8_t *cap_off) +{ + uint8_t r8, id; + uint32_t r32; + + r32 = pci_config_read16(bus, dev, fun, PCI_STATUS_OFFSET); + if (!(r32 & PCI_STATUS_CAP_LIST)) + return -1; + r8 = pci_config_read8(bus, dev, fun, PCI_CAP_OFFSET); + while (r8 != 0) { + id = pci_config_read8(bus, dev, fun, r8); + if (id == cap_id) { + *cap_off = r8; + return 0; + } + r8 = pci_config_read8(bus, dev, fun, r8 + 1); + } + return -1; +} + +int pcie_retraining_link(uint8_t bus, uint8_t dev, uint8_t fun) +{ + uint16_t link_status, link_control, vid; + uint8_t pcie_cap_off; + int ret, tries; + + vid = pci_config_read16(bus, dev, 0, PCI_VENDOR_ID_OFFSET); + if (vid == 0xffff) { + return -1; + } + + ret = pci_get_capability(bus, dev, fun, PCI_PCIE_CAP_ID, &pcie_cap_off); + if (ret != 0) { + return -1; + } + + link_status = pci_config_read16(bus, dev, fun, + pcie_cap_off + PCIE_LINK_STATUS_OFF); + if (link_status & PCIE_LINK_STATUS_TRAINING) { + delay(PCIE_TRAINING_TIMEOUT_MS); + link_status = pci_config_read16(bus, dev, fun, + pcie_cap_off + PCIE_LINK_STATUS_OFF); + if (link_status & PCIE_LINK_STATUS_TRAINING) { + return -1; + } + } + + link_control = pci_config_read16(bus, dev, fun, + pcie_cap_off + PCIE_LINK_CONTROL_OFF); + link_control |= PCIE_LINK_CONTROL_RETRAINING; + pci_config_write16(bus, dev, fun, pcie_cap_off + PCIE_LINK_CONTROL_OFF, + link_control); + tries = PCIE_TRAINING_TIMEOUT_MS / 10; + do { + link_status = pci_config_read16(bus, dev, fun, + pcie_cap_off + PCIE_LINK_STATUS_OFF); + if (!(link_status & PCIE_LINK_STATUS_TRAINING)) + break; + delay(10); + } while(tries--); + + if ((link_status & PCIE_LINK_STATUS_TRAINING)) { + return -1; + } + + return 0; +} /*! * \brief Staging of FSP_S after verification @@ -373,9 +492,17 @@ static int fsp_silicon_init(struct fsp_info_header *fsp_info, uint8_t *fsp_s_bas memcpy(silicon_init_parameter, fsp_s_base + fsp_info->CfgRegionOffset, FSP_S_PARAM_SIZE); status = fsp_machine_update_s_parameters(silicon_init_parameter); - fsp_info = (struct fsp_info_header *)(fsp_s_base + FSP_INFO_HEADER_OFFSET); SiliconInit = (silicon_init_cb)(fsp_s_base + fsp_info->FspSiliconInitEntryOffset); +#if defined(WOLFBOOT_DUMP_FSP_UPD) + wolfBoot_printf("Dumping fsps upd (%d bytes)" ENDLINE, (int)fsp_info->CfgRegionSize); + wolfBoot_print_hexstr(silicon_init_parameter, fsp_info->CfgRegionSize, 16); +#endif + status = fsp_pre_silicon_init_cb(); + if (status != 0) { + wolfBoot_printf("pre silicon init cb returns %d", status); + panic(); + } wolfBoot_printf("call silicon..." ENDLINE); status = SiliconInit(silicon_init_parameter); if (status != EFI_SUCCESS) { @@ -383,7 +510,12 @@ static int fsp_silicon_init(struct fsp_info_header *fsp_info, uint8_t *fsp_s_bas return -1; } wolfBoot_printf("success" ENDLINE); + status = pcie_retraining_link(0, PCI_DEVICE_CONTROLLER_TO_PEX, 0); + if (status != 0) + wolfBoot_printf("pcie retraining failed %x\n", status); + pci_enum_do(); + pci_dump_config_space(); notifyPhase = (notify_phase_cb)(fsp_s_base + fsp_info->NotifyPhaseEntryOffset); param.Phase = EnumInitPhaseAfterPciEnumeration; @@ -451,11 +583,9 @@ static int self_extend_pcr(void) * This static function serves as the entry point for further execution after the * memory initialization is completed and the stack has been remapped. * - * \param ptr Pointer to a parameter structure. */ -static void memory_ready_entry(void *ptr) +static void memory_ready_entry(void) { - struct stage2_parameter *stage2_params = (struct stage2_parameter *)ptr; struct fsp_info_header *fsp_info; temp_ram_exit_cb TempRamExit; uint8_t *fsp_s_base; @@ -463,6 +593,7 @@ static void memory_ready_entry(void *ptr) uint32_t cpu_info[4]; uint32_t status; int ret; + /* FSP_M is located in flash */ fsp_m_base = _start_fsp_m; /* fsp_s is loaded to RAM for validation */ @@ -483,14 +614,20 @@ static void memory_ready_entry(void *ptr) */ memory_init_data_bss(); -#if (defined(TARGET_x86_fsp_qemu) && defined(WOLFBOOT_MEASURED_BOOT)) || \ - (defined(STAGE1_AUTH) && defined (WOLFBOOT_TPM)) +#if (defined(WOLFBOOT_MEASURED_BOOT)) || \ + (defined(STAGE1_AUTH) && defined (WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY)) wolfBoot_printf("Initializing WOLFBOOT_TPM" ENDLINE); ret = wolfBoot_tpm2_init(); if (ret != 0) { wolfBoot_printf("tpm init failed" ENDLINE); panic(); } + + ret = wolfBoot_tpm_self_test(); + if (ret != 0) { + wolfBoot_printf("tpm self test failed" ENDLINE); + panic(); + } #endif #if (defined(TARGET_x86_fsp_qemu) && defined(WOLFBOOT_MEASURED_BOOT)) @@ -522,6 +659,10 @@ static void memory_ready_entry(void *ptr) #endif /* WOLFBOOT_MEASURED_BOOT */ /* Call FSP_S initialization */ + fsp_info = + (struct fsp_info_header *)(fsp_s_base + FSP_INFO_HEADER_OFFSET); + wolfBoot_printf("FSP-S:"); + print_fsp_image_revision((struct fsp_info_header *)fsp_info); if (fsp_silicon_init(fsp_info, fsp_s_base) != EFI_SUCCESS) panic(); /* Get CPUID */ @@ -549,36 +690,36 @@ static void memory_ready_entry(void *ptr) } #endif /* WOLFBOOT_MEASURED_BOOT */ -#if (defined(TARGET_x86_fsp_qemu) && defined(WOLFBOOT_MEASURED_BOOT)) || \ - (defined(STAGE1_AUTH) && defined (WOLFBOOT_TPM)) +#if (defined(WOLFBOOT_MEASURED_BOOT)) || \ + (defined(STAGE1_AUTH) && defined (WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY)) wolfBoot_tpm2_deinit(); #endif /* Finalize staging to stage2 */ - set_stage2_parameter(stage2_params); jump_into_wolfboot(); } -/*! - * \brief Check if the FSP info header is valid. - * - * This static function checks if the given FSP info header is valid by verifying - * its signature. - * - * \param hdr Pointer to the FSP info header structure. - * \return 1 if the FSP info header is valid, 0 otherwise. - */ -static int fsp_info_header_is_ok(struct fsp_info_header *hdr) +static void print_ucode_revision(void) { - uint8_t *raw_signature; +#if !defined(TARGET_x86_fsp_qemu) + /* incomplete */ + struct ucode_header { + uint32_t header_version; + uint32_t update_revision; + uint32_t date; + /* other fields not needed */ + } __attribute__((packed)); + struct ucode_header *h; - raw_signature = (uint8_t *)&hdr->Signature; - if (raw_signature[0] != 'F' || raw_signature[1] != 'S' || - raw_signature[2] != 'P' || raw_signature[3] != 'H') { - return 0; - } - return 1; + h = (struct ucode_header *)UCODE0_ADDRESS; + wolfBoot_printf("microcode revision: %x, date: %x-%x-%x\r\n", + (int)h->update_revision, + (int)((h->date >> 24) & 0xff), /* month */ + (int)((h->date >> 16) & 0xff), /* day */ + (int)(h->date & 0xffff)); /* year */ +#else + wolfBoot_printf("no microcode for QEMU target\r\n"); +#endif } - /*! * \brief Entry point for the FSP-M (Firmware Support Package - Memory) module. * @@ -595,8 +736,11 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, uint32_t bist) { uint8_t udp_m_parameter[FSP_M_UDP_MAX_SIZE], *udp_m_default; + struct stage2_ptr_holder *mem_stage2_holder; struct fsp_info_header *fsp_m_info_header; struct stage2_parameter *stage2_params; + struct stage2_ptr_holder stage2_holder; + struct stage2_parameter temp_params; uint8_t *fsp_m_base, done = 0; struct efi_hob *hobList, *it; memory_init_cb MemoryInit; @@ -621,8 +765,20 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, wolfBoot_printf("post temp ram init cb failed" ENDLINE); panic(); } + memset(&temp_params, 0, sizeof(temp_params)); + + stage2_set_parameters(&temp_params, &stage2_holder); wolfBoot_printf("Cache-as-RAM initialized" ENDLINE); + wolfBoot_printf("FSP-T:"); + print_fsp_image_revision((struct fsp_info_header *) + (_start_fsp_t + FSP_INFO_HEADER_OFFSET)); + wolfBoot_printf("FSP-M:"); + print_fsp_image_revision((struct fsp_info_header *) + (_start_fsp_m + FSP_INFO_HEADER_OFFSET)); + + print_ucode_revision(); + fsp_m_info_header = (struct fsp_info_header *)(fsp_m_base + FSP_INFO_HEADER_OFFSET); udp_m_default = fsp_m_base + fsp_m_info_header->CfgRegionOffset; @@ -643,6 +799,16 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, panic(); } +#if defined(WOLFBOOT_DUMP_FSP_UPD) + wolfBoot_printf("Dumping fspm udp (%d bytes)" ENDLINE, (int)fsp_m_info_header->CfgRegionSize); + wolfBoot_print_hexstr(udp_m_parameter, fsp_m_info_header->CfgRegionSize, 16); +#endif + status = fsp_pre_mem_init_cb(); + if (status != 0) { + wolfBoot_printf("pre mem init cb returns %d", status); + panic(); + } + wolfBoot_printf("calling FspMemInit..." ENDLINE); MemoryInit = (memory_init_cb)(fsp_m_base + fsp_m_info_header->FspMemoryInitEntryOffset); @@ -675,10 +841,13 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, } new_stack = top_address; + x86_log_memory_load(new_stack - WOLFBOOT_X86_STACK_SIZE, new_stack, "stack"); + x86_log_memory_load(new_stack - WOLFBOOT_X86_STACK_SIZE - sizeof(struct stage2_parameter), + new_stack - WOLFBOOT_X86_STACK_SIZE, "stage2 parameter"); top_address = new_stack - WOLFBOOT_X86_STACK_SIZE - sizeof(struct stage2_parameter); stage2_params = (struct stage2_parameter *)(uint32_t)top_address; - memset((uint8_t *)stage2_params, 0, sizeof(struct stage2_parameter)); + memcpy((uint8_t *)stage2_params, (uint8_t*)&temp_params, sizeof(struct stage2_parameter)); wolfBoot_printf("hoblist@0x%x" ENDLINE, (uint32_t)hobList); stage2_params->hobList = (uint32_t)hobList; @@ -686,10 +855,14 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, stage2_params->page_table = ((uint32_t)(top_address) - x86_paging_get_page_table_size()); stage2_params->page_table = (((uint32_t)stage2_params->page_table) & ~((1 << 12) - 1)); + x86_log_memory_load(stage2_params->page_table, top_address, "page tables"); memset((uint8_t*)stage2_params->page_table, 0, x86_paging_get_page_table_size()); wolfBoot_printf("page table @ 0x%x [length: %x]" ENDLINE, (uint32_t)stage2_params->page_table, x86_paging_get_page_table_size()); top_address = stage2_params->page_table; #endif /* WOLFBOOT_64BIT */ + x86_log_memory_load(top_address - sizeof(struct stage2_ptr_holder), top_address, "stage2 ptr holder"); + top_address = top_address - sizeof(struct stage2_ptr_holder); + mem_stage2_holder = (struct stage2_ptr_holder*)(uintptr_t)top_address; stage2_params->tolum = top_address; @@ -704,14 +877,14 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, stage2_params->tpm_policy_size); #endif + stage2_set_parameters(stage2_params, mem_stage2_holder); wolfBoot_printf("TOLUM: 0x%x\r\n", stage2_params->tolum); /* change_stack_and_invoke() never returns. * * Execution here is eventually transferred to memory_ready_entry * after the stack has been remapped. */ - change_stack_and_invoke(new_stack, memory_ready_entry, - (void*)stage2_params); + change_stack_and_invoke(new_stack, memory_ready_entry); /* Returning from change_stack_and_invoke() implies a fatal error * while attempting to remap the stack. diff --git a/src/boot_x86_fsp_payload.c b/src/boot_x86_fsp_payload.c index 0e81dcaf..81abd55b 100644 --- a/src/boot_x86_fsp_payload.c +++ b/src/boot_x86_fsp_payload.c @@ -34,7 +34,7 @@ #include #include -#include +#include #include #if defined(WOLFBOOT_LINUX_PAYLOAD) @@ -70,10 +70,6 @@ static char *cmdline = "console=ttyS0,115200 pci=earlydump debug"; static char *cmdline = "auto"; #endif /* TARGET_kontron_vx3060_s2 */ -/* must be global so the linker will export the symbol. It's used from loader 1 - * to fill the parameters */ -struct stage2_parameter _stage2_params; - /** * @brief Jump to the specified entry point. * @@ -89,26 +85,6 @@ void jump(uintptr_t entry) : "g"(entry)); } -struct stage2_parameter *stage2_get_parameters() -{ - return &_stage2_params; -} - -#if defined(WOLFBOOT_TPM_SEAL) -int stage2_get_tpm_policy(const uint8_t **policy, uint16_t *policy_sz) -{ -#if defined(WOLFBOOT_FSP) && !defined(BUILD_LOADER_STAGE1) - struct stage2_parameter *p; - p = stage2_get_parameters(); - *policy = (const uint8_t*)(uintptr_t)p->tpm_policy; - *policy_sz = p->tpm_policy_size; - return 0; -#else -#error "wolfBoot_get_tpm_policy is not implemented" -#endif -} -#endif /* WOLFBOOT_TPM_SEAL */ - /** * @brief Perform the boot process for the given application. * @@ -144,7 +120,7 @@ void do_boot(const uint32_t *app) mptable_setup(); x86_paging_dump_info(); r = elf_load_image_mmu((uint8_t *)app, &e, mmu_cb); - wolfBoot_printf("Elf loaded (ret %d), entry 0x%x_%x\r\n", 0, + wolfBoot_printf("Elf loaded (ret %d), entry 0x%x_%x\r\n", r, (uint32_t)(e >> 32), (uint32_t)(e)); x86_paging_dump_info(); diff --git a/src/boot_x86_fsp_start.S b/src/boot_x86_fsp_start.S index 61ea65b6..32ad2503 100644 --- a/src/boot_x86_fsp_start.S +++ b/src/boot_x86_fsp_start.S @@ -151,6 +151,7 @@ TempRamInitSuccess: [section .reset_vector] BITS 16 ALIGN 16 +global reset_vector reset_vector: nop nop diff --git a/src/elf.c b/src/elf.c index b9d2dbf5..59d207d8 100644 --- a/src/elf.c +++ b/src/elf.c @@ -77,7 +77,7 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) int is_elf32, is_le, i; #ifdef DEBUG_ELF - wolfBoot_printf("Loading elf at %p\n", (void*)image); + wolfBoot_printf("Loading elf at %p\r\n", (void*)image); #endif /* Verify ELF header */ @@ -95,7 +95,7 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) } #ifdef DEBUG_ELF - wolfBoot_printf("Found valid elf%d (%s endian)\n", + wolfBoot_printf("Found valid elf%d (%s endian)\r\n", is_elf32 ? 32 : 64, is_le ? "little" : "big"); #endif @@ -104,7 +104,7 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) entry_size = GET_H16(ph_entry_size); entry_count = GET_H16(ph_entry_count); #ifdef DEBUG_ELF - wolfBoot_printf("Program Headers %d (size %d)\n", entry_count, entry_size); + wolfBoot_printf("Program Headers %d (size %d)\r\n", entry_count, entry_size); #endif for (i = 0; i < entry_count; i++) { uint8_t *ptr = ((uint8_t*)entry_off) + (i * entry_size); @@ -124,12 +124,12 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) #ifdef DEBUG_ELF if (file_size > 0) { wolfBoot_printf( - "\tLoad %u bytes (offset %p) to %p (p %p)\n", + "Load %u bytes (offset %p) to %p (p %p)\r\n", (uint32_t)mem_size, (void*)offset, (void*)vaddr, (void*)paddr); } if (mem_size > file_size) { wolfBoot_printf( - "\tClear %u bytes at %p (p %p)\n", + "Clear %u bytes at %p (p %p)\r\n", (uint32_t)(mem_size - file_size), (void*)vaddr, (void*)paddr); } #endif @@ -139,7 +139,7 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) if (mmu_cb(vaddr, paddr, mem_size) != 0) { #ifdef DEBUG_ELF wolfBoot_printf( - "\tFail to map %u bytes to %p (p %p)\n", + "Fail to map %u bytes to %p (p %p)\r\n", (uint32_t)mem_size, (void*)vaddr, (void*)paddr); #endif continue; @@ -159,7 +159,7 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) *entry = GET_H64(entry); #ifdef DEBUG_ELF - wolfBoot_printf("Entry point %p\n", (void*)*entry); + wolfBoot_printf("Entry point %p\r\n", (void*)*entry); #endif return 0; diff --git a/src/multiboot.c b/src/multiboot.c index 79844699..6a1c1cd2 100644 --- a/src/multiboot.c +++ b/src/multiboot.c @@ -28,7 +28,7 @@ #include #ifdef WOLFBOOT_FSP -#include +#include #endif #define MB2_HEADER_MAX_OFF (32768 - 4) diff --git a/src/pci.c b/src/pci.c index ce2395d6..5fc4d20b 100644 --- a/src/pci.c +++ b/src/pci.c @@ -794,6 +794,102 @@ int pci_pre_enum(void) return 0; } +#if defined(DEBUG_PCI) +/** + * @brief Dump PCI configuration space + * + * @param bus PCI bus number + * @param dev PCI device number + * @param fun PCI function number +*/ +void pci_dump(uint8_t bus, uint8_t dev, uint8_t fun) +{ + uint32_t reg[256/4]; + uint8_t *ptr; + int i; + + for (i = 0; i < 256 / 4; i++) { + reg[i] = pci_config_read32(bus, dev, fun, i * 4); + } + + ptr = (uint8_t*)reg; + for (i = 0; i < 256; i++) { + if (i % 0x10 == 0x0) { + if (i < 0x10) { + wolfBoot_printf("0"); + } + wolfBoot_printf("%x: ", (int)i); + } + wolfBoot_printf("%s%x%s", (ptr[i] < 0x10 ? "0" :""), (int)ptr[i], + (i % 0x10 == 0xf ? "\r\n":" ")); + } +} + +/** + * @brief Dump PCI configuration space for all devices in the bus + * + * This function will dump the PCI configuration space for all devices in the + * bus, it will recursively dump buses behind bridges. + * + * @param bus PCI bus number +*/ +static void pci_dump_bus(uint8_t bus) +{ + uint16_t vendor_id, device_id, header_type; + uint8_t dev, fun, sec_bus; + uint32_t vd_code, reg; + int ret; + + for (dev = 0; dev < PCI_ENUM_MAX_DEV; dev++) { + vd_code = pci_config_read32(bus, dev, 0, PCI_VENDOR_ID_OFFSET); + if (vd_code == 0xFFFFFFFF) { + /* No device here. */ + continue; + } + + for (fun = 0; fun < PCI_ENUM_MAX_FUN; fun++) { + vd_code = pci_config_read32(bus, dev, fun, PCI_VENDOR_ID_OFFSET); + if (vd_code == 0xFFFFFFFF) { + /* No device here. */ + continue; + } + + if (bus < 0x10) + wolfBoot_printf("0"); + wolfBoot_printf("%x:", bus); + if (dev < 0x10) + wolfBoot_printf("0"); + wolfBoot_printf("%x.", dev); + wolfBoot_printf("%d \r\n", fun); + pci_dump(bus, dev, fun); + header_type = pci_config_read16(bus, dev, fun, + PCI_HEADER_TYPE_OFFSET); + + if ((header_type & PCI_HEADER_TYPE_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) { + sec_bus = pci_config_read8(bus, dev, fun, PCI_SECONDARY_BUS); + if (sec_bus != 0) + pci_dump_bus(sec_bus); + } + + /* just one function */ + if ((fun == 0) && !(header_type & PCI_HEADER_TYPE_MULTIFUNC_MASK)) { + break; + } + } + } +} + +/** + * @brief Dump full PCI configuration space +*/ +void pci_dump_config_space(void) +{ + return pci_dump_bus(0); +} +#else +void pci_dump_config_space(void) {}; +#endif + int pci_enum_do(void) { struct pci_enum_info enum_info; diff --git a/src/stage2_params.c b/src/stage2_params.c new file mode 100644 index 00000000..bc0b08e5 --- /dev/null +++ b/src/stage2_params.c @@ -0,0 +1,132 @@ +/* stage2_params.c + * + * Copyright (C) 2023 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +#include +#include + +/* +* The storage of the stage2_params variable during memory initialization +* involves several changes of locations. Initially, before memory becomes +* available, it is stored inside the Cache-As-RAM, more precisely as the stack +* variable `temp_params` in `boot_x86_fsp.c:start()`. Once memory initialization +* occurs in stage1, the stage2_params is copied into memory. In stage2, when +* writable data sections are available, stage2_params resides in the .data +* section. +* +* The function `stage2_get_parameters()` is utilized throughout the code to +* obtain the correct address of stage2_params. It's important to note that +* whenever the location changes, the structure is copied verbatim. References to +* the struct must be updated manually. Additionally, during the transition to +* stage2, all references to function pointers will not be valid anymore. +* +* Internals: +* During stage1, the pointer to the parameter is stored just before the IDT +* (Interrupt Descriptor Table) table, and it can be recovered using the sidt +* instruction. This necessitates the presence of a dummy table with a single +* NULL descriptor. In stage2, stage2_get_parameter() serves as a wrapper +* function that simply returns the address of the _stage2_parameter global +* variable. +*/ + +#if defined(WOLFBOOT_TPM_SEAL) +int stage2_get_tpm_policy(const uint8_t **policy, uint16_t *policy_sz) +{ +#if defined(WOLFBOOT_FSP) + struct stage2_parameter *p; + p = stage2_get_parameters(); + *policy = (const uint8_t*)(uintptr_t)p->tpm_policy; + *policy_sz = p->tpm_policy_size; + return 0; +#else +#error "wolfBoot_get_tpm_policy is not implemented" +#endif +} +#endif /* WOLFBOOT_TPM_SEAL */ +#if defined(BUILD_LOADER_STAGE1) +extern uint8_t _stage2_params[]; + +struct idt_descriptor { + uint16_t limit; + uint32_t base; +} __attribute__ ((packed)); + +/** + * @brief Set the stage 2 parameter pointer during stage 1. + * + * @param p Pointer to the stage 2 parameter structure. + * @param holder Pointer to the stage 2 parameter holder structure. + * + * This function sets the stage 2 parameter pointer during stage 1. The pointer + * is stored just before a dummy IDTR table, that is defined inside the holder + * struct. +*/ +void stage2_set_parameters(struct stage2_parameter *p, struct stage2_ptr_holder *holder) +{ + struct idt_descriptor idt; + + idt.limit = sizeof(holder->dummy_idt) - 1; + idt.base = (uint32_t)&holder->dummy_idt; + memset(holder->dummy_idt, 0, sizeof(holder->dummy_idt)); + holder->ptr = p; + + asm ("lidt %0\r\n" : : "m"(idt)); +} + +/** + * @brief Get the stage 2 parameter pointer during stage 1. + * + * This function gets the stage 2 parameter pointer during stage 1. The pointer + * is stored just before a dummy IDTR table, stored in the IDT register. + * + * @return Pointer to the stage 2 parameter structure. + */ +struct stage2_parameter *stage2_get_parameters(void) +{ + struct stage2_parameter **ptr; + struct idt_descriptor idt; + + asm ("sidt %0\r\n" : "=m"(idt) : ); + + ptr = (struct stage2_parameter**)(uintptr_t)(idt.base - sizeof(struct stage2_parameter*)); + return *ptr; +} + +/*! + * \brief Set the stage 2 parameter for the WolfBoot bootloader. + * + * This static function sets the stage 2 parameter for the WolfBoot bootloader, + * which will be used by the bootloader during its execution. + * + * \param p Pointer to the stage 2 parameter structure. + */ +void stage2_copy_parameter(struct stage2_parameter *p) +{ + memcpy((uint8_t*)&_stage2_params, (uint8_t*)p, sizeof(*p)); +} +#else +/* must be global so the linker will export the symbol. It's used from loader 1 + * to fill the parameters */ +struct stage2_parameter _stage2_params; + +struct stage2_parameter *stage2_get_parameters(void) +{ + return &_stage2_params; +} +#endif diff --git a/src/tpm.c b/src/tpm.c index c5c90bfb..ceb95c4a 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -851,10 +851,15 @@ int wolfBoot_seal_auth(const uint8_t* pubkey_hint, WOLFTPM2_KEYBLOB seal_blob; word32 nvAttributes; + if (auth == NULL && authSz > 0) + return BAD_FUNC_ARG; + memset(&seal_blob, 0, sizeof(seal_blob)); seal_blob.handle.auth.size = authSz; - XMEMCPY(seal_blob.handle.auth.buffer, auth, authSz); + + if (auth != NULL) + XMEMCPY(seal_blob.handle.auth.buffer, auth, authSz); /* creates a sealed keyed hash object (not loaded to TPM) */ rc = wolfBoot_seal_blob(pubkey_hint, policy, policySz, &seal_blob, @@ -1320,5 +1325,17 @@ int wolfBoot_check_rot(int key_slot, uint8_t* pubkey_hint) return rc; } #endif +/** + * @brief Perform TPM2 self test. + * + * This function performs the TPM2 self test. + * + * @return TPM_RC_SUCCESS in case of success + * +*/ +int wolfBoot_tpm_self_test(void) +{ + return wolfTPM2_SelfTest(&wolftpm_dev); +} #endif /* WOLFBOOT_TPM */ diff --git a/src/update_disk.c b/src/update_disk.c index 57477096..62d7afd6 100644 --- a/src/update_disk.c +++ b/src/update_disk.c @@ -41,7 +41,7 @@ #include "hal.h" #include "spi_flash.h" #include "printf.h" -#include "stage1.h" +#include "stage2_params.h" #include "wolfboot/wolfboot.h" #include #include @@ -96,7 +96,12 @@ void RAMFUNCTION wolfBoot_start(void) ret = x86_fsp_tgl_init_sata(&sata_bar); if (ret != 0) panic(); -#endif +#if defined(WOLFBOOT_ATA_DISK_LOCK) + ret = sata_unlock_disk(BOOT_DISK, 1); + if (ret != 0) + panic(); +#endif /* WOLFBOOT_ATA_DISK_LOCK */ +#endif /* WOLFBOOT_FSP */ if (disk_open(BOOT_DISK) < 0) panic(); @@ -218,6 +223,5 @@ void RAMFUNCTION wolfBoot_start(void) wolfBoot_printf("Booting at %08lx\r\n", os_image.fw_base); hal_prepare_boot(); do_boot((uint32_t*)os_image.fw_base); - } #endif /* UPDATE_DISK_H_ */ diff --git a/src/x86/ahci.c b/src/x86/ahci.c index 23729dd6..6db07b76 100644 --- a/src/x86/ahci.c +++ b/src/x86/ahci.c @@ -45,7 +45,7 @@ #include #if defined(WOLFBOOT_FSP) -#include +#include #endif #include @@ -63,6 +63,9 @@ #ifndef ATA_UNLOCK_DISK_KEY_SZ #define ATA_UNLOCK_DISK_KEY_SZ 32 #endif +#ifndef WOLFBOOT_TPM_SEAL_KEY_ID +#define WOLFBOOT_TPM_SEAL_KEY_ID (0) +#endif #endif /* defined(WOLFBOOT_ATA_DISK_LOCK_PASSWORD) || defined(WOLFBOOT_TPM_SEAL) */ #if defined(WOLFBOOT_ATA_DISK_LOCK_PASSWORD) && defined(WOLFBOOT_TPM_SEAL) @@ -223,7 +226,10 @@ static int sata_get_unlock_secret(uint8_t *secret, int *secret_size) { int password_len; - *secret_size = strlen(WOLFBOOT_ATA_DISK_LOCK_PASSWORD); + password_len = strlen(WOLFBOOT_ATA_DISK_LOCK_PASSWORD); + if (*secret_size < password_len) + return -1; + *secret_size = password_len; memcpy(secret, (uint8_t*)WOLFBOOT_ATA_DISK_LOCK_PASSWORD, *secret_size); return 0; } @@ -236,8 +242,9 @@ static int sata_get_unlock_secret(uint8_t *secret, int *secret_size) * * @param key_slot The key slot ID to calculate the hash for. * @param hash A pointer to store the resulting SHA256 hash. + * @return 0 on success, -1 on failure */ -static void get_key_sha256(uint8_t key_slot, uint8_t *hash) +static int get_key_sha256(uint8_t key_slot, uint8_t *hash) { int blksz; unsigned int i = 0; @@ -246,7 +253,7 @@ static void get_key_sha256(uint8_t key_slot, uint8_t *hash) wc_Sha256 sha256_ctx; if (!pubkey || (pubkey_sz < 0)) - return; + return -1; wc_InitSha256(&sha256_ctx); while (i < (uint32_t)pubkey_sz) { @@ -257,25 +264,31 @@ static void get_key_sha256(uint8_t key_slot, uint8_t *hash) i += blksz; } wc_Sha256Final(&sha256_ctx, hash); + return 0; } static int sata_get_random_base64(uint8_t *out, int *out_size) { uint8_t rand[ATA_SECRET_RANDOM_BYTES]; - word32 _out_size; + word32 base_64_len; int ret; ret = wolfBoot_get_random(rand, ATA_SECRET_RANDOM_BYTES); if (ret != 0) return ret; - _out_size = *out_size; - ret = Base64_Encode(rand, ATA_SECRET_RANDOM_BYTES, out, &_out_size); + base_64_len = *out_size; + ret = Base64_Encode_NoNl(rand, ATA_SECRET_RANDOM_BYTES, out, &base_64_len); if (ret != 0) return ret; /* double check we have a NULL-terminated string */ - *out_size = (int)_out_size; - out[*out_size] = '\0'; + if ((int)base_64_len < *out_size) { + out[base_64_len] = '\0'; + base_64_len += 1; + } else { + out[base_64_len-1] = '\0'; + } + *out_size = (int)base_64_len; return 0; } @@ -296,12 +309,13 @@ static int sata_create_and_seal_unlock_secret(const uint8_t *pubkey_hint, if (ret == 0) { wolfBoot_printf("Creating new secret (%d bytes)\r\n", *secret_size); wolfBoot_printf("%s\r\n", secret); - /* seal new secret */ + + /* seal new secret */ ret = wolfBoot_seal(pubkey_hint, policy, policy_size, ATA_UNLOCK_DISK_KEY_NV_INDEX, secret, *secret_size); } - + if (ret == 0) { /* unseal again to make sure it works */ memset(secret_check, 0, sizeof(secret_check)); @@ -352,7 +366,11 @@ static int sata_get_unlock_secret(uint8_t *secret, int *secret_size) return -1; memcpy(policy, pol, policy_size); - get_key_sha256(0, pubkey_hint); + ret = get_key_sha256(WOLFBOOT_TPM_SEAL_KEY_ID, pubkey_hint); + if (ret != 0) { + wolfBoot_printf("failed to find key id %d\r\n", WOLFBOOT_TPM_SEAL_KEY_ID); + return ret; + } ret = wolfBoot_unseal(pubkey_hint, policy, policy_size, ATA_UNLOCK_DISK_KEY_NV_INDEX, secret, secret_size); @@ -361,6 +379,13 @@ static int sata_get_unlock_secret(uint8_t *secret, int *secret_size) ret = sata_create_and_seal_unlock_secret(pubkey_hint, policy, policy_size, secret, secret_size); } +#if defined(WOLFBOOT_DEBUG_REMOVE_SEALED_ON_ERROR) + if (ret != 0) { + wolfBoot_printf("deleting secret and panic!\r\n"); + wolfBoot_delete_seal(ATA_UNLOCK_DISK_KEY_NV_INDEX); + panic(); + } +#endif if (ret != 0) { wolfBoot_printf("get sealed unlock secret failed! %d (%s)\n", ret, wolfTPM2_GetRCString(ret)); @@ -370,52 +395,108 @@ static int sata_get_unlock_secret(uint8_t *secret, int *secret_size) } #endif /* WOLFBOOT_TPM_SEAL */ -static int sata_unlock_disk(int drv) +#ifdef WOLFBOOT_ATA_DISABLE_USER_PASSWORD +static int sata_disable_password(int drv) +{ + enum ata_security_state ata_st; + int r; + wolfBoot_printf("DISK DISABLE PASSWORD\r\n"); + ata_st = ata_security_get_state(drv); + wolfBoot_printf("ATA: State SEC%d\r\n", ata_st); + if (ata_st == ATA_SEC4) { + r = ata_security_unlock_device(drv, ATA_MASTER_PASSWORD, 1); + wolfBoot_printf("ATA device unlock: returned %d\r\n", r); + if (r == 0) { + r = ata_security_disable_password(drv, ATA_MASTER_PASSWORD, 1); + wolfBoot_printf("ATA disable password: returned %d\r\n", r); + } + } + panic(); + return 0; +} +#endif + +/** + * @brief Unlocks a SATA disk for a given drive. + * + * This function unlocks a SATA disk identified by the specified drive number. + * If the SATA disk has no user password set, this function locks the disk. + * + * @param drv The drive number of the SATA disk to be unlocked. + * @return An integer indicating the success or failure of the unlocking + * operation. + * - 0: Success (disk unlocked). + * - -1: Failure (unable to unlock the disk). + */ +int sata_unlock_disk(int drv, int freeze) { int secret_size = ATA_UNLOCK_DISK_KEY_SZ; uint8_t secret[ATA_UNLOCK_DISK_KEY_SZ]; enum ata_security_state ata_st; int r; +#ifdef WOLFBOOT_ATA_DISABLE_USER_PASSWORD + sata_disable_password(0); +#endif r = sata_get_unlock_secret(secret, &secret_size); if (r != 0) return r; #ifdef TARGET_x86_fsp_qemu wolfBoot_printf("DISK LOCK SECRET: %s\r\n", secret); #endif - ata_st = ata_security_get_state(drv); wolfBoot_printf("ATA: Security state SEC%d\r\n", ata_st); +#if defined(TARGET_x86_fsp_qemu) + if (ata_st == ATA_SEC0) + return 0; +#endif if (ata_st == ATA_SEC1) { - AHCI_DEBUG_PRINTF("ATA identify: calling freeze lock\r\n", r); - r = ata_security_freeze_lock(drv); - AHCI_DEBUG_PRINTF("ATA security freeze lock: returned %d\r\n", r); + AHCI_DEBUG_PRINTF("ATA: calling set passphrase\r\n", r); + r = ata_security_set_password(drv, 0, (char*)secret); + if (r != 0) + return -1; + AHCI_DEBUG_PRINTF("ATA: calling freeze lock\r\n", r); + if (freeze) { + r = ata_security_freeze_lock(drv); + AHCI_DEBUG_PRINTF("ATA security freeze lock: returned %d\r\n", r); + if (r != 0) + return -1; + } r = ata_identify_device(drv); AHCI_DEBUG_PRINTF("ATA identify: returned %d\r\n", r); ata_st = ata_security_get_state(drv); - wolfBoot_printf("ATA: Security disabled. State SEC%d\r\n", ata_st); + wolfBoot_printf("ATA: State SEC%d\r\n", ata_st); } else if (ata_st == ATA_SEC4) { AHCI_DEBUG_PRINTF("ATA identify: calling device unlock\r\n", r); - r = ata_security_unlock_device(drv, (char*)secret); + r = ata_security_unlock_device(drv, (char*)secret, 0); AHCI_DEBUG_PRINTF("ATA device unlock: returned %d\r\n", r); r = ata_identify_device(drv); AHCI_DEBUG_PRINTF("ATA identify: returned %d\r\n", r); ata_st = ata_security_get_state(drv); if (ata_st == ATA_SEC5) { - AHCI_DEBUG_PRINTF("ATA identify: calling device freeze\r\n", r); - r = ata_security_freeze_lock(drv); - AHCI_DEBUG_PRINTF("ATA device freeze: returned %d\r\n", r); + if (freeze) { + AHCI_DEBUG_PRINTF("ATA identify: calling freeze lock\r\n", r); + r = ata_security_freeze_lock(drv); + AHCI_DEBUG_PRINTF("ATA security freeze lock: returned %d\r\n", + r); + if (r != 0) + return -1; + } else { + AHCI_DEBUG_PRINTF("ATA security freeze skipped\r\n"); + } r = ata_identify_device(drv); AHCI_DEBUG_PRINTF("ATA identify: returned %d\r\n", r); } - ata_st = ata_security_get_state(drv); - if (ata_st != ATA_SEC6) { - panic(); - } - ata_st = ata_security_get_state(drv); - wolfBoot_printf("ATA: Security enabled. State SEC%d\r\n", ata_st); } + ata_st = ata_security_get_state(drv); + if ((freeze && ata_st != ATA_SEC6) || (!freeze && ata_st != ATA_SEC5)) { + AHCI_DEBUG_PRINTF("ATA: Security is not enabled/locked (State SEC%d)\r\n", + ata_st); + panic(); + } + AHCI_DEBUG_PRINTF("ATA: Security enabled. State SEC%d\r\n", ata_st); + return 0; } #endif /* WOLFBOOT_ATA_DISK_LOCK */ @@ -656,10 +737,6 @@ void sata_enable(uint32_t base) drv, i); r = ata_identify_device(drv); AHCI_DEBUG_PRINTF("ATA identify: returned %d\r\n", r); -#ifdef WOLFBOOT_ATA_DISK_LOCK - if (r == 0) - r = sata_unlock_disk(drv); -#endif /* WOLFBOOT_ATA_DISK_LOCK */ } } else { AHCI_DEBUG_PRINTF("AHCI port %d: device with signature %08x is not supported\r\n", diff --git a/src/x86/ata.c b/src/x86/ata.c index c4799512..954443d7 100644 --- a/src/x86/ata.c +++ b/src/x86/ata.c @@ -57,7 +57,13 @@ static int ata_drive_count = -1; +struct ata_async_info{ + int in_progress; + int drv; + int slot; +}; +static struct ata_async_info ata_async_info; /** * @brief This structure holds the necessary information for an ATA drive, * including AHCI base address, AHCI port number, and sector cache. @@ -264,6 +270,92 @@ static int prepare_cmd_h2d_slot(int drv, const uint8_t *buf, int sz, int w) return slot; } +/** + * @brief Check the completion status of an asynchronous ATA command. + * + * This function checks the completion status of an asynchronous ATA command + * that was previously initiated. + * + * @return + * - 0: Asynchronous ATA command completed successfully. + * - ATA_ERR_OP_NOT_IN_PROGRESS: No asynchronous operation in progress. + * - ATA_ERR_BUSY: The ATA operation is still in progress. + * - -1: ATA Task File error. + */ +int ata_cmd_complete_async() +{ + struct ata_drive *ata; + int slot; + + if (!ata_async_info.in_progress) + return ATA_ERR_OP_NOT_IN_PROGRESS; + ata = &ATA_Drv[ata_async_info.drv]; + if (mmio_read32(AHCI_PxIS(ata->ahci_base, ata->ahci_port)) & AHCI_PORT_IS_TFES) { + ata_async_info.in_progress = 0; + return -1; + } + + slot = ata_async_info.slot; + if ((mmio_read32(AHCI_PxCI(ata->ahci_base, ata->ahci_port)) & (1 << slot)) != 0) + return ATA_ERR_BUSY; + + ata_async_info.in_progress = 0; + return 0; +} + +/** + * @brief This static function executes the command in the specified command + * slot for the ATA drive, if async = 0 waits for the command to complete + * otherwise it immediately returns ATA_ERR_BUSY. Software must call + * `ata_cmd_complete_async()` to check for operation completion. Only one + * operation can run at a time, so this function returns ATA_OP_IN_PROGRESS if + * another async operation is already in progress. Software must invoke + * ata_cmd_complete_async() until it returns 0 or -1. Please note that the + * function is NOT thread safe and is NOT safe if ATA functions are supposed to + * interrupt the normal execution flow. + * + * @param[in] drv The index of the ATA drive in the ATA_Drv array. + * @param[in] slot The index of the command slot to execute. + * @param[in] async Flag indicating whether the operation should be asynchronous (1) or synchronous (0). + + * @return: + * - -1: if an error occurs during command execution. + * - ATA_ERR_OP_IN_PROGRESS: if async = 1 and another asynchronous operation is already in progress. + * - ATA_ERR_BUSY: If async = 1. To get cmd status invoke `ata_cmd_complete_async()`. + * - 0: success. + */ +static int exec_cmd_slot_ex(int drv, int slot, int async) +{ + struct ata_drive *ata = &ATA_Drv[drv]; + uint32_t reg; + + if (ata_async_info.in_progress) + return ATA_ERR_OP_IN_PROGRESS; + + /* Clear IS */ + reg = mmio_read32(AHCI_PxIS(ata->ahci_base, ata->ahci_port)); + mmio_write32(AHCI_PxIS(ata->ahci_base, ata->ahci_port), reg); + + /* Wait until port not busy */ + while (mmio_read32(AHCI_PxTFD(ata->ahci_base, ata->ahci_port)) & (ATA_DEV_BUSY | ATA_DEV_DRQ)) + ; + + mmio_write32((AHCI_PxCI(ata->ahci_base, ata->ahci_port)), 1 << slot); + if (async) { + ata_async_info.in_progress = 1; + ata_async_info.drv = drv; + ata_async_info.slot = slot; + return ATA_ERR_BUSY; + } + + while ((mmio_read32(AHCI_PxCI(ata->ahci_base, ata->ahci_port)) & (1 << slot)) != 0) { + if (mmio_read32(AHCI_PxIS(ata->ahci_base, ata->ahci_port)) & AHCI_PORT_IS_TFES) { + wolfBoot_printf("ATA: port error\r\n"); + return -1; + } + } + return 0; +} /** * @brief This static function executes the command in the specified command @@ -276,28 +368,9 @@ static int prepare_cmd_h2d_slot(int drv, const uint8_t *buf, int sz, int w) */ static int exec_cmd_slot(int drv, int slot) { - struct ata_drive *ata = &ATA_Drv[drv]; - uint32_t reg; - /* Clear IS */ - reg = mmio_read32(AHCI_PxIS(ata->ahci_base, ata->ahci_port)); - mmio_write32(AHCI_PxIS(ata->ahci_base, ata->ahci_port), reg); - - /* Wait until port not busy */ - while (mmio_read32(AHCI_PxTFD(ata->ahci_base, ata->ahci_port)) & (ATA_DEV_BUSY | ATA_DEV_DRQ)) - ; - - mmio_write32((AHCI_PxCI(ata->ahci_base, ata->ahci_port)), 1 << slot); - - while ((mmio_read32(AHCI_PxCI(ata->ahci_base, ata->ahci_port)) & (1 << slot)) != 0) { - if (mmio_read32(AHCI_PxIS(ata->ahci_base, ata->ahci_port)) & AHCI_PORT_IS_TFES) { - wolfBoot_printf("ATA: port error\r\n"); - return -1; - } - } - return 0; + return exec_cmd_slot_ex(drv, slot, 0); } - static void invert_buf(uint8_t *src, uint8_t *dst, unsigned len) { unsigned i; @@ -375,13 +448,15 @@ static int security_command(int drv, uint8_t ata_cmd) * @param[in] ata_cmd The ATA command to execute from the ATA security set. * @param[in] passphrase The passphrase to transmit as argument in the buffer * entry. - * - * @return 0 on success, or -1 if an error occurs while preparing or executing - * the ATA command. - * + * @param[in] async if the command will be executed in asynchronous mode + * @param[in] master if the passphrase should compare with master + * @return + * - 0: ATA command completed successfully. + * - ATA_ERR_OP_NOT_IN_PROGRESS: If async = 1 but no asynchronous operation in progress. + * - ATA_ERR_BUSY: If async = 1. To get cmd status invoke `ata_cmd_complete_async()`. */ static int security_command_passphrase(int drv, uint8_t ata_cmd, - const char *passphrase) + const char *passphrase, int async, int master) { struct hba_cmd_header *cmd; struct hba_cmd_table *tbl; @@ -391,6 +466,8 @@ static int security_command_passphrase(int drv, uint8_t ata_cmd, int slot = prepare_cmd_h2d_slot(drv, buffer, ATA_SECURITY_COMMAND_LEN, 1); memset(buffer, 0, ATA_SECURITY_COMMAND_LEN); + if (master) + buffer[0] = 0x1; memcpy(buffer + ATA_SECURITY_PASSWORD_OFFSET, passphrase, strlen(passphrase)); if (slot < 0) { return slot; @@ -403,7 +480,7 @@ static int security_command_passphrase(int drv, uint8_t ata_cmd, cmdfis->c = 1; cmdfis->command = ata_cmd; cmdfis->count = 1; - ret = exec_cmd_slot(drv, slot); + ret = exec_cmd_slot_ex(drv, slot, async); return ret; } @@ -439,13 +516,14 @@ int ata_security_erase_prepare(int drv) * command SECURITY UNLOCK, as defined in specs ATA8-ACS Sec. 7.49 * * @param[in] drv The index of the ATA drive in the ATA_Drv array. - * @param[in] passphrase The USER passphrase of the disk unit. + * @param[in] passphrase The passphrase of the disk unit. + * @param[in] master if true compare with MASTER otherwise USER * * @return 0 on success, or -1 if an error occurred. */ -int ata_security_unlock_device(int drv, const char *passphrase) +int ata_security_unlock_device(int drv, const char *passphrase, int master) { - return security_command_passphrase(drv, ATA_CMD_SECURITY_UNLOCK, passphrase); + return security_command_passphrase(drv, ATA_CMD_SECURITY_UNLOCK, passphrase, 0, master); } /** @@ -460,7 +538,7 @@ int ata_security_unlock_device(int drv, const char *passphrase) */ int ata_security_set_password(int drv, int master, const char *passphrase) { - return security_command_passphrase(drv, ATA_CMD_SECURITY_SET_PASSWORD, passphrase); + return security_command_passphrase(drv, ATA_CMD_SECURITY_SET_PASSWORD, passphrase, 0, master); } /** @@ -470,12 +548,13 @@ int ata_security_set_password(int drv, int master, const char *passphrase) * * @param[in] drv The index of the ATA drive in the ATA_Drv array. * @param[in] passphrase The old USER passphrase for the disk unit to reset. + * @param[in] master if true compare with MASTER otherwise USER * * @return 0 on success, or -1 if an error occurred. */ -int ata_security_disable_password(int drv, const char *passphrase) +int ata_security_disable_password(int drv, const char *passphrase, int master) { - return security_command_passphrase(drv, ATA_CMD_SECURITY_DISABLE_PASSWORD, passphrase); + return security_command_passphrase(drv, ATA_CMD_SECURITY_DISABLE_PASSWORD, passphrase, 0, master); } /** @@ -483,13 +562,16 @@ int ata_security_disable_password(int drv, const char *passphrase) * in specs ATA8-ACS Sec. 7.46 * * @param[in] drv The index of the ATA drive in the ATA_Drv array. - * @param[in] passphrase The USER passphrase for the disk unit to erase. + * @param[in] passphrase The USER/MASTER passphrase for the disk unit to erase. + * @param[in] master if 1 compare againts the MASTER password instead of USER + * password * * @return 0 on success, or -1 if an error occurred. */ -int ata_security_erase_unit(int drv, const char *passphrase) +int ata_security_erase_unit(int drv, const char *passphrase, int master) { - return security_command_passphrase(drv, ATA_CMD_SECURITY_ERASE_UNIT, passphrase); + return security_command_passphrase(drv, ATA_CMD_SECURITY_ERASE_UNIT, + passphrase, 1, master); } #endif /* WOLFBOOT_SATA_DISK_LOCK */ @@ -712,6 +794,9 @@ int ata_drive_read(int drv, uint64_t start, uint32_t size, uint8_t *buf) sect_start = start >> ata->sector_size_shift; sect_off = start - (sect_start << ata->sector_size_shift); + if (drv > ata_drive_count) + return -1; + if (sect_off > 0) { uint32_t len = MAX_SECTOR_SIZE - sect_off; if (len > size) diff --git a/src/x86/common.c b/src/x86/common.c index 8de0112e..9ce09de0 100644 --- a/src/x86/common.c +++ b/src/x86/common.c @@ -51,6 +51,11 @@ #define NULL 0 #endif +void hlt() +{ + __asm__ ("hlt"); +} + /** * @brief Memory-mapped write access to a 32-bit register. * @@ -265,9 +270,7 @@ void delay(int msec) */ void panic() { - while (1) { - delay(1); - } + hlt(); } /** diff --git a/src/x86/exceptions.c b/src/x86/exceptions.c new file mode 100644 index 00000000..603e4fdb --- /dev/null +++ b/src/x86/exceptions.c @@ -0,0 +1,216 @@ +/* exceptions.c + * + * Copyright (C) 2023 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + * + */ + +#include +#include +#include + +#define EXCEPTION_NUM 35 +#define INTERRUPT_GATE_TYPE (0xe) +#define SEGMENT_SELECTOR (0x18) +#define TYPE_FLAG (INTERRUPT_GATE_TYPE << 8 | 1 << 15) + +#define LAPIC_DIV_CONF_REG 0xfee003e0 +#define LAPIC_INITIAL_CNT 0xfee00380 +#define LAPIC_CURRENT_CNT 0xfee00390 +#define LAPIC_LVT_TIMER_REG 0xfee00320 +#define LAPIC_EOI 0xfee000b0 +#define LAPIC_SVR 0xfee000f0 +#define LAPIC_SVR_ENABLE (1 << 8) +#define LAPIC_DIV_CONF_128 (1 << 1 | 1 << 3) +#define TIMER_SPURIOUS_NUMBER (33) +#define TIMER_VECTOR_NUMBER (34) +#define TIMER_CNT 0xffffff +#define IA32_APIC_BASE_MSR (0x1b) +#define IA32_APIC_BASE_MSR_ENABLE (0x800) + +#define DEBUG_EXCEPTIONS +#if defined(DEBUG_EXCEPTIONS) +#include +#define EXCEPTIONS_DEBUG_PRINTF(...) wolfBoot_printf(__VA_ARGS__) +#else +#define EXCEPTIONS_DEBUG_PRINTF(...) do {} while(0) +#endif + +struct interrupt_gate { + uint16_t offset_0_15; + uint16_t seg_sel; + uint16_t type_flags; + uint16_t offset_31_16; + uint32_t offset_63_32; + uint32_t reserved; +} __attribute__((packed)); + +struct idt_descriptor { + uint16_t limit; + uint64_t base; +} __attribute__((packed)); + +static struct interrupt_gate idt_table[EXCEPTION_NUM]; +static struct idt_descriptor idt_descriptor; + +#define EXCEPTION_TRAMPOLINE(X) \ + __attribute__((naked)) void exception_trampoline_##X() { \ + asm volatile("cli\r\n" \ + "mov %0, %%rdi\r\n" \ + "sti\r\n" \ + "call common_exception_handler\r\n" \ + "iretq\r\n" \ + : \ + : ""(X)); \ + } + +static void common_exception_handler(uint64_t vector_number) +{ + EXCEPTIONS_DEBUG_PRINTF("CPU exception: %d\r\n", (int)vector_number); +} + +EXCEPTION_TRAMPOLINE(0); +EXCEPTION_TRAMPOLINE(1); +EXCEPTION_TRAMPOLINE(2); +EXCEPTION_TRAMPOLINE(3); +EXCEPTION_TRAMPOLINE(4); +EXCEPTION_TRAMPOLINE(5); +EXCEPTION_TRAMPOLINE(6); +EXCEPTION_TRAMPOLINE(7); +EXCEPTION_TRAMPOLINE(8); +EXCEPTION_TRAMPOLINE(9); +EXCEPTION_TRAMPOLINE(10); +EXCEPTION_TRAMPOLINE(11); +EXCEPTION_TRAMPOLINE(12) +EXCEPTION_TRAMPOLINE(13); +EXCEPTION_TRAMPOLINE(14); +EXCEPTION_TRAMPOLINE(15); +EXCEPTION_TRAMPOLINE(16); +EXCEPTION_TRAMPOLINE(17); +EXCEPTION_TRAMPOLINE(18); +EXCEPTION_TRAMPOLINE(19); +EXCEPTION_TRAMPOLINE(20); +EXCEPTION_TRAMPOLINE(21); +EXCEPTION_TRAMPOLINE(22); +EXCEPTION_TRAMPOLINE(23); +EXCEPTION_TRAMPOLINE(24); +EXCEPTION_TRAMPOLINE(25); +EXCEPTION_TRAMPOLINE(26); +EXCEPTION_TRAMPOLINE(27); +EXCEPTION_TRAMPOLINE(28); +EXCEPTION_TRAMPOLINE(29); +EXCEPTION_TRAMPOLINE(30); +EXCEPTION_TRAMPOLINE(31); +EXCEPTION_TRAMPOLINE(32); +/* lapic spurious vector */ +EXCEPTION_TRAMPOLINE(33); + +int setup_interrupt_gate(int vnum, uintptr_t handler) +{ + struct interrupt_gate *ig; + + ig = &idt_table[vnum]; + ig->offset_0_15 = (uint16_t)(handler & 0xffff); + ig->offset_31_16 = (uint16_t)((handler >> 16) & 0xffff); + ig->offset_63_32 = (uint32_t)((handler) >> 32); + ig->type_flags = TYPE_FLAG; + ig->seg_sel = SEGMENT_SELECTOR; + ig->reserved = 0x0; +} + +static void _timer_handler() +{ + EXCEPTIONS_DEBUG_PRINTF("In the timer handler\r\n"); +} + +static void __attribute__((__naked__)) timer_handler() { + asm volatile("cli\r\n" + "call _timer_handler\r\n" + "sti\r\n" + "mov %0, %%eax\r\n" + "movl $0, (%%eax)\r\n" + "iretq\r\n"::""(LAPIC_EOI)); +} + +static void setup_apic_timer() +{ + mmio_write32(LAPIC_SVR, (LAPIC_SVR_ENABLE)); + mmio_write32(LAPIC_DIV_CONF_REG, LAPIC_DIV_CONF_128); + setup_interrupt_gate(TIMER_VECTOR_NUMBER, (uintptr_t)timer_handler); + mmio_write32(LAPIC_LVT_TIMER_REG, TIMER_VECTOR_NUMBER); +} + +int setup_interrupts() +{ + setup_interrupt_gate(0,(uintptr_t) exception_trampoline_0); + setup_interrupt_gate(1,(uintptr_t) exception_trampoline_1); + setup_interrupt_gate(2,(uintptr_t) exception_trampoline_2); + setup_interrupt_gate(3,(uintptr_t) exception_trampoline_3); + setup_interrupt_gate(4,(uintptr_t) exception_trampoline_4); + setup_interrupt_gate(5,(uintptr_t) exception_trampoline_5); + setup_interrupt_gate(6,(uintptr_t) exception_trampoline_6); + setup_interrupt_gate(7,(uintptr_t) exception_trampoline_7); + setup_interrupt_gate(8,(uintptr_t) exception_trampoline_8); + setup_interrupt_gate(9,(uintptr_t) exception_trampoline_9); + setup_interrupt_gate(10,(uintptr_t) exception_trampoline_10); + setup_interrupt_gate(11,(uintptr_t) exception_trampoline_11); + setup_interrupt_gate(12,(uintptr_t) exception_trampoline_12); + setup_interrupt_gate(13,(uintptr_t) exception_trampoline_13); + setup_interrupt_gate(14,(uintptr_t) exception_trampoline_14); + setup_interrupt_gate(15,(uintptr_t) exception_trampoline_15); + setup_interrupt_gate(16,(uintptr_t) exception_trampoline_16); + setup_interrupt_gate(17,(uintptr_t) exception_trampoline_17); + setup_interrupt_gate(18,(uintptr_t) exception_trampoline_18); + setup_interrupt_gate(19,(uintptr_t) exception_trampoline_19); + setup_interrupt_gate(20,(uintptr_t) exception_trampoline_20); + setup_interrupt_gate(21,(uintptr_t) exception_trampoline_21); + setup_interrupt_gate(22,(uintptr_t) exception_trampoline_22); + setup_interrupt_gate(23,(uintptr_t) exception_trampoline_23); + setup_interrupt_gate(24,(uintptr_t) exception_trampoline_24); + setup_interrupt_gate(25,(uintptr_t) exception_trampoline_25); + setup_interrupt_gate(26,(uintptr_t) exception_trampoline_26); + setup_interrupt_gate(27,(uintptr_t) exception_trampoline_27); + setup_interrupt_gate(28,(uintptr_t) exception_trampoline_28); + setup_interrupt_gate(29,(uintptr_t) exception_trampoline_29); + setup_interrupt_gate(30,(uintptr_t) exception_trampoline_30); + setup_interrupt_gate(31,(uintptr_t) exception_trampoline_31); + + setup_apic_timer(); + idt_descriptor.base = (uintptr_t)&idt_table; + idt_descriptor.limit = sizeof(idt_table) -1; + + asm ("lidt %0\r\n" : : "m"(idt_descriptor)); + asm ("sti\r\n"); + + return 0; +} + +void deinit_interrupts() +{ + idt_descriptor.base = (uintptr_t)NULL; + idt_descriptor.limit = 0xffff; + asm ("cli\r\n"); + asm ("lidt %0\r\n" : : "m"(idt_descriptor)); +} + +void wfi() +{ + setup_apic_timer(); + mmio_write32(LAPIC_INITIAL_CNT, TIMER_CNT); + hlt(); +} diff --git a/src/x86/gpt.c b/src/x86/gpt.c index aaf5e5ec..0578ca39 100644 --- a/src/x86/gpt.c +++ b/src/x86/gpt.c @@ -29,6 +29,7 @@ */ #ifndef GPT_C #define GPT_C +#include #include #include #include @@ -45,6 +46,7 @@ #define PTYPE_GPT 0xEE #define P_ENTRY_START 0x01BE #define P_BOOTSIG_OFFSET 0x01FE +#define GPT_PART_NAME_SIZE (36) /** * @brief This packed structure defines the layout of an MBR partition table entry @@ -92,7 +94,7 @@ struct __attribute__((packed)) guid_part_array uint64_t first; uint64_t last; uint64_t flags; - int16_t name[72]; + uint16_t name[GPT_PART_NAME_SIZE]; }; /** @@ -105,6 +107,7 @@ struct disk_partition int part_no; uint64_t start; uint64_t end; + uint16_t name[GPT_PART_NAME_SIZE]; }; /** @@ -125,6 +128,30 @@ struct disk_drive { */ static struct disk_drive Drives[MAX_DISKS] = {0}; +static int disk_u16_ascii_eq(const uint16_t *utf16, const char *ascii) +{ + unsigned int utf16_idx; + unsigned int i; + + if (strlen(ascii) > GPT_PART_NAME_SIZE) + return 0; + + utf16_idx = 0; + /* skip BOM if present */ + if (utf16[utf16_idx] == 0xfeff) + utf16_idx = 1; + for (i = 0; i < strlen(ascii); i++, utf16_idx++) { + /* non-ascii character*/ + if (utf16[utf16_idx] != (uint16_t)ascii[i]) + return 0; + } + + if (utf16_idx < GPT_PART_NAME_SIZE && utf16[utf16_idx] != 0x0) + return 0; + + return 1; +} + /** * @brief Opens a disk drive and initializes its partitions. * @@ -220,6 +247,7 @@ int disk_open(int drv) Drives[drv].part[part_count].drv = drv; Drives[drv].part[part_count].start = pa.first * SECTOR_SIZE; Drives[drv].part[part_count].end = (pa.last * SECTOR_SIZE - 1); + memcpy(&Drives[drv].part[part_count].name, (uint8_t*)&pa.name, sizeof(pa.name)); wolfBoot_printf("disk%d.p%u ", drv, part_count); wolfBoot_printf("(%x_%xh", (uint32_t)(size>>32), (uint32_t)size); wolfBoot_printf("@ %x_%x)\r\n", (uint32_t)((pa.first * SECTOR_SIZE) >> 32), @@ -327,4 +355,23 @@ int disk_write(int drv, int part, uint64_t off, uint64_t sz, const uint8_t *buf) ret = ata_drive_write(drv, p->start + off, len, buf); return ret; } + +int disk_find_partion_by_label(int drv, const char *label) +{ + struct disk_partition *p; + int i; + + if ((drv < 0) || (drv > MAX_DISKS)) + return -1; + + if (Drives[drv].is_open == 0) + return -1; + + for (i = 0; i < Drives[drv].n_parts; i++) { + p = open_part(drv, i); + if (disk_u16_ascii_eq(p->name, label) == 1) + return i; + } + return -1; +} #endif /* GPT_C */ diff --git a/src/x86/linux_loader.c b/src/x86/linux_loader.c index 77213167..f5f6d907 100644 --- a/src/x86/linux_loader.c +++ b/src/x86/linux_loader.c @@ -30,7 +30,7 @@ #ifdef WOLFBOOT_FSP #include -#include +#include #endif /* WOLFBOOT_FSP */ #define ENDLINE "\r\n" diff --git a/src/x86/paging.c b/src/x86/paging.c index f02d27f5..765f8dda 100644 --- a/src/x86/paging.c +++ b/src/x86/paging.c @@ -25,7 +25,7 @@ #define PAGE_TABLE_PAGE_SIZE (0x1000) #ifndef PAGE_TABLE_PAGE_NUM -/* 7 pages are enough to identity map al 4GB */ +/* 7 pages are enough to identity map all 4GB */ #define PAGE_TABLE_PAGE_NUM 7 #endif /* PAGE_TABLE_PAGE_NUM */ @@ -42,7 +42,7 @@ #define PAGE_2MB_SHIFT 21 #if !defined(BUILD_LOADER_STAGE1) -#define WOLFBOOT_PTP_NUM 128 +#define WOLFBOOT_PTP_NUM 512 static uint8_t page_table_pages[WOLFBOOT_PTP_NUM * PAGE_TABLE_PAGE_SIZE] __attribute__((aligned(PAGE_TABLE_PAGE_SIZE))); static int page_table_page_used; @@ -220,12 +220,6 @@ void x86_paging_dump_info() (uint32_t)((uintptr_t)page_table_pages >> 32), (uint32_t)(uintptr_t)page_table_pages); wolfBoot_printf("page_table_pages used: %d\r\n", page_table_page_used); - wolfBoot_printf("mem start @ %x %xh\r\n", - (uint32_t)((uintptr_t)_mem >> 32), - (uint32_t)(uintptr_t)_mem); - wolfBoot_printf("mem curr @ %x %xh\r\n", - (uint32_t)((uintptr_t)mem >> 32), - (uint32_t)(uintptr_t)mem); } #else void x86_paging_dump_info() {} diff --git a/src/x86/qemu_fsp.c b/src/x86/qemu_fsp.c index 14fbe27e..24314087 100644 --- a/src/x86/qemu_fsp.c +++ b/src/x86/qemu_fsp.c @@ -25,6 +25,7 @@ #include #include #include +#include #define FSPM_UPD_SIGNATURE 0x4D5F4450554D4551 /* 'QEMUPD_M' */ #define FSPT_UPD_SIGNATURE 0x545F4450554D4551 /* 'QEMUPD_T' */ @@ -115,6 +116,7 @@ int fsp_machine_update_m_parameters(uint8_t *default_m_params, uint32_t mem_base, uint32_t mem_size) { + struct stage2_parameter *params; struct fspm_upd *new_udp; new_udp = (struct fspm_upd*)default_m_params; @@ -128,3 +130,13 @@ int fsp_machine_update_m_parameters(uint8_t *default_m_params, return 0; } + +int fsp_pre_mem_init_cb(void) +{ + return 0; +} + +int fsp_pre_silicon_init_cb(void) +{ + return 0; +} diff --git a/src/x86/tgl_fsp.c b/src/x86/tgl_fsp.c index 886b39cf..27dfdea1 100644 --- a/src/x86/tgl_fsp.c +++ b/src/x86/tgl_fsp.c @@ -45,8 +45,8 @@ #include #include #include - #include +#include #define PCR_DMI_PORT_ID 0x88 #define PCR_DMI_LPCLGIR1 0x2730 @@ -80,19 +80,80 @@ #define CPLD_SERIAL_LINES_CTL 0x07 #define CPLD_SERIAL1_TXEN (1<<2) #define GPIO_COMM_4_PORT_ID 0x6a -#define GPIO_PAD_CONF_OFF 0x700 -#define GPIO_C_8_OFF 0x8 -#define GPIO_C_9_OFF 0x9 -#define GPIO_C_10_OFF 0x10 -#define GPIO_C_11_OFF 0x11 +#define GPIO_COMM_0_PORT_ID (0x6e) +#define GPIO_COMM_1_PORT_ID (0x6d) +#define GPIO_COMM_5_PORT_ID (0x69) #define GPIO_MODE_NATIVE_1 0x01 +#define GPIO_MODE_GPIO (0x0) #define GPIO_RESET_PLTRST 0x02 -#define GPIO_MODE_MASK (0x7) << 10 +#define GPIO_RESET_HOSTDEEPRESET (0x01) +#define GPIO_DIR_INPUT (0x1) +#define GPIO_DIR_OUTPUT (0x2) +#define GPIO_INTERRUPT_DISABLE (0x0) +#define GPIO_INTERRUPT_SCI (1 << 2) +#define GPIO_TERM_NONE (0x0) +#define GPIO_RXEVCONF_LEVEL (0) #define GPIO_MODE_SHIFT 10 -#define GPIO_RESET_MASK (0x3) << 30 +#define GPIO_MODE_MASK (0x7) << GPIO_MODE_SHIFT #define GPIO_RESET_SHIFT 30 +#define GPIO_RESET_MASK (0x3) << GPIO_RESET_SHIFT +#define GPIO_DIR_SHIFT (0x8) +#define GPIO_DIR_MASK (0x3) << GPIO_DIR_SHIFT +#define GPIO_RXINV_SHIFT (23) +#define GPIO_RXINV_MASK (0x1) << 23 +#define GPIO_INTERRUPT_SHIFT (17) +#define GPIO_INTERRUPT_MASK (0xf) << GPIO_INTERRUPT_SHIFT +#define GPIO_TERM_SHIFT (10) +#define GPIO_TERM_MASK (0xf) << GPIO_TERM_SHIFT +#define GPIO_RXEVCONF_SHIFT (25) +#define GPIO_RXEVCONF_MASK (0x3) << GPIO_RXEVCONF_SHIFT +#define PCR_INTERRUPT_PORT_ID (0xc4) +#define GIC_OFFSET (0x31FC) +#define GIC_SHUTDOWN_STATUS_BIT (1 << 0) +#define GPIO_GPPC_B9_CFG_OFF (0x790) +#define GPIO_GPPC_B10_CFG_OFF (0x7a0) +#define GPIO_GPPC_C6_CFG_OFF (0x760) +#define GPIO_GPPC_C7_CFG_OFF (0x770) +#define GPIO_GPPC_C8_CFG_OFF (0x780) +#define GPIO_GPPC_C9_CFG_OFF (0x790) +#define GPIO_GPPC_C10_CFG_OFF (0x7a0) +#define GPIO_GPPC_C11_CFG_OFF (0x7b0) +#define GPIO_GPPC_C12_CFG_OFF (0x7c0) +#define GPIO_GPPC_C13_CFG_OFF (0x7d0) +#define GPIO_GPPC_C14_CFG_OFF (0x7e0) +#define GPIO_GPPC_C15_CFG_OFF (0x7f0) +#define GPIO_GPPC_C20_CFG_OFF (0x840) +#define GPIO_GPPC_C21_CFG_OFF (0x850) +#define GPIO_GPPC_C22_CFG_OFF (0x860) +#define GPIO_GPPC_D0_CFG_OFF (0x900) +#define GPIO_GPPC_D1_CFG_OFF (0x910) +#define GPIO_GPPC_D2_CFG_OFF (0x920) +#define GPIO_GPP_R0_CFG_OFF (0x700) +#define GPIO_GPP_R1_CFG_OFF (0x710) +#define GPIO_GPP_R2_CFG_OFF (0x720) +#define GPIO_GPP_R3_CFG_OFF (0x730) +#define GPIO_GPP_R4_CFG_OFF (0x740) +#define GPIO_GPP_R5_CFG_OFF (0x750) +#define GPIO_GPPC_A8_CFG_OFF (0xa20) +#define GPIO_GPPC_E12_CFG_OFF (0xb30) +#define GPIO_GPPC_E15_CFG_OFF (0xb60) +#define GPIO_GPPC_E16_CFG_OFF (0xb70) +#define GPIO_GPPC_F2_CFG_OFF (0xba0) +#define GPIO_GPPC_F4_CFG_OFF (0xbc0) +#define GPIO_GPPC_F5_CFG_OFF (0xbd0) +#define GPIO_GPPC_F9_CFG_OFF (0x910) +#define GPIO_GPPC_A9_CFG_OFF (0xa30) +#define GPIO_GPPC_T2_CFG_OFF (0x8c0) +#define GPIO_GPPC_T3_CFG_OFF (0x8d0) + +#ifdef DEBUG_GPIO +#define GPIO_DEBUG_PRINTF(...) wolfBoot_printf(__VA_ARGS__) +#else +#define GPIO_DEBUG_PRINTF(...) do {} while(0) +#endif /* DEBUG_GPIO */ + SI_PCH_DEVICE_INTERRUPT_CONFIG mPchHDevIntConfig[] = { {30, 0, SiPchIntA, 16}, }; @@ -324,7 +385,9 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp) mem_cfg->VtdBaseAddress[8] = 0; mem_cfg->UserBd = 5; mem_cfg->RMT = 1; + mem_cfg->NModeSupport = 2; mem_cfg->PchHdaEnable = 0; + mem_cfg->GttMmAdr = 2147483648; mem_cfg->DdiPort2Hpd = 1; mem_cfg->DdiPort4Hpd = 1; mem_cfg->DdiPort2Ddc = 1; @@ -339,7 +402,6 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp) mem_cfg->TxtDprMemorySize = 4194304; mem_cfg->BiosAcmBase = 4285267968; mem_cfg->ConfigTdpLevel = 2; - mem_cfg->PchNumRsvdSmbusAddresses = 4; mem_cfg->PcieClkSrcUsage[0] = 128; mem_cfg->PcieClkSrcUsage[1] = 128; mem_cfg->PcieClkSrcUsage[2] = 128; @@ -356,7 +418,7 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp) mem_cfg->PcieClkSrcUsage[13] = 128; mem_cfg->PcieClkSrcUsage[14] = 128; mem_cfg->PcieClkSrcUsage[15] = 128; - mem_cfg->RsvdSmbusAddressTablePtr = 4277460020; + mem_cfg->PcieRpEnableMask = 1520787455; mem_cfg->PcdDebugInterfaceFlags = 16; mem_cfg->SerialIoUartDebugControllerNumber = 0; mem_cfg->MrcSafeConfig = 1; @@ -364,10 +426,11 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp) mem_cfg->TcssItbtPcie1En = 0; mem_cfg->TcssItbtPcie2En = 0; mem_cfg->TcssItbtPcie3En = 0; - mem_cfg->TcssXhciEn = 0; + mem_cfg->TcssXdciEn = 1; mem_cfg->TcssDma0En = 0; mem_cfg->TcssDma1En = 0; mem_cfg->RMC = 0; + mem_cfg->EccSupport = 0; mem_cfg->Ibecc = 1; mem_cfg->IbeccParity = 1; mem_cfg->RankInterleave = 0; @@ -397,7 +460,6 @@ static int fsp_set_memory_cfg(FSPM_UPD *udp) mem_cfg->SkipCpuReplacementCheck = 1; mem_cfg->SerialIoUartDebugMode = 4; mem_cfg->PcieRefPllSsc = 0; - return 0; } @@ -417,6 +479,442 @@ static int disable_watchdog_tco() return 0; } +static void fsp_set_silicon_cfg(FSPS_UPD *fsps) +{ + FSP_S_CONFIG *upd = &fsps->FspsConfig; + + upd->GraphicsConfigPtr = 2024131364; + + upd->SataPortsEnable[0] = 1; + upd->SataPortsEnable[1] = 1; + upd->SataPortsEnable[2] = 0; + upd->SataPortsEnable[3] = 0; + upd->SataPortsEnable[4] = 0; + upd->SataPortsEnable[5] = 0; + upd->SataPortsEnable[6] = 0; + upd->SataPortsEnable[7] = 0; + upd->PortUsb30Enable[0] = 1; + upd->PortUsb30Enable[1] = 1; + upd->PortUsb30Enable[2] = 1; + upd->PortUsb30Enable[3] = 1; + upd->PortUsb30Enable[4] = 0; + upd->PortUsb30Enable[5] = 0; + upd->PortUsb30Enable[6] = 0; + upd->PortUsb30Enable[7] = 0; + upd->PortUsb30Enable[8] = 0; + upd->PortUsb30Enable[9] = 0; + upd->XdciEnable = 1; + upd->DevIntConfigPtr = 2023910720; + upd->NumOfDevIntConfig = 52; + upd->SerialIoSpiMode[0] = 1; + upd->SerialIoSpiMode[1] = 0; + upd->SerialIoSpiMode[2] = 0; + upd->SerialIoSpiMode[3] = 0; + upd->SerialIoSpiMode[4] = 0; + upd->SerialIoSpiMode[5] = 0; + upd->SerialIoSpiMode[6] = 0; + upd->SerialIoUartMode[0] = 4; + upd->SerialIoUartMode[1] = 1; + upd->SerialIoUartMode[2] = 1; + upd->SerialIoUartMode[3] = 0; + upd->SerialIoUartMode[4] = 0; + upd->SerialIoUartMode[5] = 0; + upd->SerialIoUartMode[6] = 0; + upd->SerialIoUartAutoFlow[0] = 0; + upd->SerialIoUartAutoFlow[1] = 0; + upd->SerialIoUartAutoFlow[2] = 0; + upd->SerialIoUartAutoFlow[3] = 1; + upd->SerialIoUartAutoFlow[4] = 1; + upd->SerialIoUartAutoFlow[5] = 0; + upd->SerialIoUartAutoFlow[6] = 0; + upd->SerialIoUartRtsPinMuxPolicy[0] = 420160010; + upd->SerialIoUartRtsPinMuxPolicy[1] = 0; + upd->SerialIoUartRtsPinMuxPolicy[2] = 0; + upd->SerialIoUartRtsPinMuxPolicy[3] = 0; + upd->SerialIoUartRtsPinMuxPolicy[4] = 0; + upd->SerialIoUartRtsPinMuxPolicy[5] = 0; + upd->SerialIoUartRtsPinMuxPolicy[6] = 0; + upd->SerialIoUartCtsPinMuxPolicy[0] = 420164107; + upd->SerialIoUartCtsPinMuxPolicy[1] = 0; + upd->SerialIoUartCtsPinMuxPolicy[2] = 0; + upd->SerialIoUartCtsPinMuxPolicy[3] = 0; + upd->SerialIoUartCtsPinMuxPolicy[4] = 0; + upd->SerialIoUartCtsPinMuxPolicy[5] = 0; + upd->SerialIoUartCtsPinMuxPolicy[6] = 0; + upd->SerialIoUartRxPinMuxPolicy[0] = 420151816; + upd->SerialIoUartRxPinMuxPolicy[1] = 0; + upd->SerialIoUartRxPinMuxPolicy[2] = 0; + upd->SerialIoUartRxPinMuxPolicy[3] = 0; + upd->SerialIoUartRxPinMuxPolicy[4] = 0; + upd->SerialIoUartRxPinMuxPolicy[5] = 0; + upd->SerialIoUartRxPinMuxPolicy[6] = 0; + upd->SerialIoUartTxPinMuxPolicy[0] = 420155913; + upd->SerialIoUartTxPinMuxPolicy[1] = 0; + upd->SerialIoUartTxPinMuxPolicy[2] = 0; + upd->SerialIoUartTxPinMuxPolicy[3] = 0; + upd->SerialIoUartTxPinMuxPolicy[4] = 0; + upd->SerialIoUartTxPinMuxPolicy[5] = 0; + upd->SerialIoUartTxPinMuxPolicy[6] = 0; + upd->SerialIoDebugUartNumber = 0; + upd->SerialIoI2cMode[0] = 0; + upd->SerialIoI2cMode[1] = 0; + upd->SerialIoI2cMode[2] = 0; + upd->SerialIoI2cMode[3] = 0; + upd->SerialIoI2cMode[4] = 0; + upd->SerialIoI2cMode[5] = 0; + upd->SerialIoI2cMode[6] = 0; + upd->SerialIoI2cMode[7] = 0; + upd->Usb2PhyPetxiset[0] = 6; + upd->Usb2PhyPetxiset[1] = 6; + upd->Usb2PhyPetxiset[2] = 6; + upd->Usb2PhyPetxiset[3] = 6; + upd->Usb2PhyPetxiset[4] = 6; + upd->Usb2PhyPetxiset[5] = 6; + upd->Usb2PhyPetxiset[6] = 6; + upd->Usb2PhyPetxiset[7] = 6; + upd->Usb2PhyPetxiset[8] = 6; + upd->Usb2PhyPetxiset[9] = 6; + upd->Usb2PhyPetxiset[10] = 6; + upd->Usb2PhyPetxiset[11] = 6; + upd->Usb2PhyPetxiset[12] = 6; + upd->Usb2PhyPetxiset[13] = 6; + upd->Usb2PhyPetxiset[14] = 0; + upd->Usb2PhyPetxiset[15] = 0; + upd->Usb2PhyTxiset[0] = 0; + upd->Usb2PhyTxiset[1] = 0; + upd->Usb2PhyTxiset[2] = 0; + upd->Usb2PhyTxiset[3] = 0; + upd->Usb2PhyTxiset[4] = 0; + upd->Usb2PhyTxiset[5] = 0; + upd->Usb2PhyTxiset[6] = 0; + upd->Usb2PhyTxiset[7] = 0; + upd->Usb2PhyTxiset[8] = 0; + upd->Usb2PhyTxiset[9] = 0; + upd->Usb2PhyTxiset[10] = 0; + upd->Usb2PhyTxiset[11] = 0; + upd->Usb2PhyTxiset[12] = 0; + upd->Usb2PhyTxiset[13] = 0; + upd->Usb2PhyTxiset[14] = 0; + upd->Usb2PhyTxiset[15] = 0; + upd->Usb2PhyPredeemp[0] = 3; + upd->Usb2PhyPredeemp[1] = 3; + upd->Usb2PhyPredeemp[2] = 3; + upd->Usb2PhyPredeemp[3] = 3; + upd->Usb2PhyPredeemp[4] = 3; + upd->Usb2PhyPredeemp[5] = 3; + upd->Usb2PhyPredeemp[6] = 3; + upd->Usb2PhyPredeemp[7] = 3; + upd->Usb2PhyPredeemp[8] = 3; + upd->Usb2PhyPredeemp[9] = 3; + upd->Usb2PhyPredeemp[10] = 3; + upd->Usb2PhyPredeemp[11] = 3; + upd->Usb2PhyPredeemp[12] = 3; + upd->Usb2PhyPredeemp[13] = 3; + upd->Usb2PhyPredeemp[14] = 0; + upd->Usb2PhyPredeemp[15] = 0; + upd->Usb2PhyPehalfbit[0] = 0; + upd->Usb2PhyPehalfbit[1] = 0; + upd->Usb2PhyPehalfbit[2] = 0; + upd->Usb2PhyPehalfbit[3] = 0; + upd->Usb2PhyPehalfbit[4] = 0; + upd->Usb2PhyPehalfbit[5] = 0; + upd->Usb2PhyPehalfbit[6] = 0; + upd->Usb2PhyPehalfbit[7] = 0; + upd->Usb2PhyPehalfbit[8] = 0; + upd->Usb2PhyPehalfbit[9] = 0; + upd->Usb2PhyPehalfbit[10] = 0; + upd->Usb2PhyPehalfbit[11] = 0; + upd->Usb2PhyPehalfbit[12] = 0; + upd->Usb2PhyPehalfbit[13] = 0; + upd->Usb2PhyPehalfbit[14] = 0; + upd->Usb2PhyPehalfbit[15] = 0; + upd->PchTsnEnable[0] = 0; + upd->PchTsnEnable[1] = 0; + upd->CnviMode = 0; + upd->CnviBtCore = 0; + upd->SataLedEnable = 1; + upd->IomTypeCPortPadCfg[0] = 0; + upd->IomTypeCPortPadCfg[1] = 0; + upd->IomTypeCPortPadCfg[2] = 0; + upd->IomTypeCPortPadCfg[3] = 0; + upd->IomTypeCPortPadCfg[4] = 0; + upd->IomTypeCPortPadCfg[5] = 0; + upd->IomTypeCPortPadCfg[6] = 0; + upd->IomTypeCPortPadCfg[7] = 0; + upd->UsbTcPortEn = 15; + upd->AesEnable = 0; + upd->PchWriteProtectionEnable[0] = 1; + upd->PchWriteProtectionEnable[1] = 1; + upd->PchWriteProtectionEnable[2] = 0; + upd->PchWriteProtectionEnable[3] = 0; + upd->PchWriteProtectionEnable[4] = 0; + upd->PchProtectedRangeLimit[0] = 13679; + upd->PchProtectedRangeLimit[1] = 16383; + upd->PchProtectedRangeLimit[2] = 0; + upd->PchProtectedRangeLimit[3] = 0; + upd->PchProtectedRangeLimit[4] = 0; + upd->PchProtectedRangeBase[0] = 13312; + upd->PchProtectedRangeBase[1] = 13744; + upd->PchProtectedRangeBase[2] = 0; + upd->PchProtectedRangeBase[3] = 0; + upd->PchProtectedRangeBase[4] = 0; + upd->PcieRpClkReqDetect[0] = 1; + upd->PcieRpClkReqDetect[1] = 1; + upd->PcieRpClkReqDetect[2] = 1; + upd->PcieRpClkReqDetect[3] = 1; + upd->PcieRpClkReqDetect[4] = 1; + upd->PcieRpClkReqDetect[5] = 1; + upd->PcieRpClkReqDetect[6] = 1; + upd->PcieRpClkReqDetect[7] = 1; + upd->PcieRpClkReqDetect[8] = 1; + upd->PcieRpClkReqDetect[9] = 1; + upd->PcieRpClkReqDetect[10] = 1; + upd->PcieRpClkReqDetect[11] = 1; + upd->PcieRpClkReqDetect[12] = 0; + upd->PcieRpClkReqDetect[13] = 0; + upd->PcieRpClkReqDetect[14] = 0; + upd->PcieRpClkReqDetect[15] = 0; + upd->PcieRpClkReqDetect[16] = 0; + upd->PcieRpClkReqDetect[17] = 0; + upd->PcieRpClkReqDetect[18] = 0; + upd->PcieRpClkReqDetect[19] = 0; + upd->PcieRpClkReqDetect[20] = 0; + upd->PcieRpClkReqDetect[21] = 0; + upd->PcieRpClkReqDetect[22] = 0; + upd->PcieRpClkReqDetect[23] = 0; + upd->PcieRpAdvancedErrorReporting[0] = 1; + upd->PcieRpAdvancedErrorReporting[1] = 1; + upd->PcieRpAdvancedErrorReporting[2] = 1; + upd->PcieRpAdvancedErrorReporting[3] = 1; + upd->PcieRpAdvancedErrorReporting[4] = 1; + upd->PcieRpAdvancedErrorReporting[5] = 1; + upd->PcieRpAdvancedErrorReporting[6] = 1; + upd->PcieRpAdvancedErrorReporting[7] = 1; + upd->PcieRpAdvancedErrorReporting[8] = 1; + upd->PcieRpAdvancedErrorReporting[9] = 1; + upd->PcieRpAdvancedErrorReporting[10] = 1; + upd->PcieRpAdvancedErrorReporting[11] = 1; + upd->PcieRpAdvancedErrorReporting[12] = 0; + upd->PcieRpAdvancedErrorReporting[13] = 0; + upd->PcieRpAdvancedErrorReporting[14] = 0; + upd->PcieRpAdvancedErrorReporting[15] = 0; + upd->PcieRpAdvancedErrorReporting[16] = 0; + upd->PcieRpAdvancedErrorReporting[17] = 0; + upd->PcieRpAdvancedErrorReporting[18] = 0; + upd->PcieRpAdvancedErrorReporting[19] = 0; + upd->PcieRpAdvancedErrorReporting[20] = 0; + upd->PcieRpAdvancedErrorReporting[21] = 0; + upd->PcieRpAdvancedErrorReporting[22] = 0; + upd->PcieRpAdvancedErrorReporting[23] = 0; + upd->PcieRpMaxPayload[0] = 1; + upd->PcieRpMaxPayload[1] = 1; + upd->PcieRpMaxPayload[2] = 1; + upd->PcieRpMaxPayload[3] = 1; + upd->PcieRpMaxPayload[4] = 1; + upd->PcieRpMaxPayload[5] = 1; + upd->PcieRpMaxPayload[6] = 1; + upd->PcieRpMaxPayload[7] = 1; + upd->PcieRpMaxPayload[8] = 1; + upd->PcieRpMaxPayload[9] = 1; + upd->PcieRpMaxPayload[10] = 1; + upd->PcieRpMaxPayload[11] = 1; + upd->PcieRpMaxPayload[12] = 0; + upd->PcieRpMaxPayload[13] = 0; + upd->PcieRpMaxPayload[14] = 0; + upd->PcieRpMaxPayload[15] = 0; + upd->PcieRpMaxPayload[16] = 0; + upd->PcieRpMaxPayload[17] = 0; + upd->PcieRpMaxPayload[18] = 0; + upd->PcieRpMaxPayload[19] = 0; + upd->PcieRpMaxPayload[20] = 0; + upd->PcieRpMaxPayload[21] = 0; + upd->PcieRpMaxPayload[22] = 0; + upd->PcieRpMaxPayload[23] = 0; + upd->PcieRpAspm[0] = 0; + upd->PcieRpAspm[1] = 0; + upd->PcieRpAspm[2] = 0; + upd->PcieRpAspm[3] = 0; + upd->PcieRpAspm[4] = 0; + upd->PcieRpAspm[5] = 0; + upd->PcieRpAspm[6] = 0; + upd->PcieRpAspm[7] = 0; + upd->PcieRpAspm[8] = 0; + upd->PcieRpAspm[9] = 0; + upd->PcieRpAspm[10] = 0; + upd->PcieRpAspm[11] = 0; + upd->PcieRpAspm[12] = 4; + upd->PcieRpAspm[13] = 4; + upd->PcieRpAspm[14] = 4; + upd->PcieRpAspm[15] = 4; + upd->PcieRpAspm[16] = 4; + upd->PcieRpAspm[17] = 4; + upd->PcieRpAspm[18] = 4; + upd->PcieRpAspm[19] = 4; + upd->PcieRpAspm[20] = 4; + upd->PcieRpAspm[21] = 4; + upd->PcieRpAspm[22] = 4; + upd->PcieRpAspm[23] = 4; + upd->PcieRpL1Substates[0] = 0; + upd->PcieRpL1Substates[1] = 0; + upd->PcieRpL1Substates[2] = 0; + upd->PcieRpL1Substates[3] = 0; + upd->PcieRpL1Substates[4] = 0; + upd->PcieRpL1Substates[5] = 0; + upd->PcieRpL1Substates[6] = 0; + upd->PcieRpL1Substates[7] = 0; + upd->PcieRpL1Substates[8] = 0; + upd->PcieRpL1Substates[9] = 0; + upd->PcieRpL1Substates[10] = 0; + upd->PcieRpL1Substates[11] = 0; + upd->PcieRpL1Substates[12] = 3; + upd->PcieRpL1Substates[13] = 3; + upd->PcieRpL1Substates[14] = 3; + upd->PcieRpL1Substates[15] = 3; + upd->PcieRpL1Substates[16] = 3; + upd->PcieRpL1Substates[17] = 3; + upd->PcieRpL1Substates[18] = 3; + upd->PcieRpL1Substates[19] = 3; + upd->PcieRpL1Substates[20] = 3; + upd->PcieRpL1Substates[21] = 3; + upd->PcieRpL1Substates[22] = 3; + upd->PcieRpL1Substates[23] = 3; + upd->PcieRpLtrEnable[0] = 1; + upd->PcieRpLtrEnable[1] = 1; + upd->PcieRpLtrEnable[2] = 1; + upd->PcieRpLtrEnable[3] = 1; + upd->PcieRpLtrEnable[4] = 1; + upd->PcieRpLtrEnable[5] = 1; + upd->PcieRpLtrEnable[6] = 1; + upd->PcieRpLtrEnable[7] = 1; + upd->PcieRpLtrEnable[8] = 1; + upd->PcieRpLtrEnable[9] = 1; + upd->PcieRpLtrEnable[10] = 1; + upd->PcieRpLtrEnable[11] = 1; + upd->PcieRpLtrEnable[12] = 0; + upd->PcieRpLtrEnable[13] = 0; + upd->PcieRpLtrEnable[14] = 0; + upd->PcieRpLtrEnable[15] = 0; + upd->PcieRpLtrEnable[16] = 0; + upd->PcieRpLtrEnable[17] = 0; + upd->PcieRpLtrEnable[18] = 0; + upd->PcieRpLtrEnable[19] = 0; + upd->PcieRpLtrEnable[20] = 0; + upd->PcieRpLtrEnable[21] = 0; + upd->PcieRpLtrEnable[22] = 0; + upd->PcieRpLtrEnable[23] = 0; + upd->IehMode = 1; + upd->Usb2OverCurrentPin[0] = 255; + upd->Usb2OverCurrentPin[1] = 3; + upd->Usb2OverCurrentPin[2] = 255; + upd->Usb2OverCurrentPin[3] = 255; + upd->Usb2OverCurrentPin[4] = 255; + upd->Usb2OverCurrentPin[5] = 255; + upd->Usb2OverCurrentPin[6] = 3; + upd->Usb2OverCurrentPin[7] = 255; + upd->Usb2OverCurrentPin[8] = 1; + upd->Usb2OverCurrentPin[9] = 255; + upd->Usb2OverCurrentPin[10] = 5; + upd->Usb2OverCurrentPin[11] = 5; + upd->Usb2OverCurrentPin[12] = 6; + upd->Usb2OverCurrentPin[13] = 6; + upd->Usb2OverCurrentPin[14] = 7; + upd->Usb2OverCurrentPin[15] = 7; + upd->Usb3OverCurrentPin[0] = 2; + upd->Usb3OverCurrentPin[1] = 255; + upd->Usb3OverCurrentPin[2] = 255; + upd->Usb3OverCurrentPin[3] = 255; + upd->Usb3OverCurrentPin[4] = 2; + upd->Usb3OverCurrentPin[5] = 2; + upd->Usb3OverCurrentPin[6] = 3; + upd->Usb3OverCurrentPin[7] = 3; + upd->Usb3OverCurrentPin[8] = 4; + upd->Usb3OverCurrentPin[9] = 4; + upd->SgxEpoch0 = 6142344250440060711U; + upd->SgxEpoch1 = 15521488688214965697U; + upd->PchDmiAspmCtrl = 0; + upd->CpuPcieSetSecuredRegisterLock = 1; + upd->CpuPcieRpPmSci[0] = 1; + upd->CpuPcieRpPmSci[1] = 0; + upd->CpuPcieRpPmSci[2] = 0; + upd->CpuPcieRpPmSci[3] = 0; + upd->CpuPcieRpMaxPayload[0] = 1; + upd->CpuPcieRpMaxPayload[1] = 0; + upd->CpuPcieRpMaxPayload[2] = 0; + upd->CpuPcieRpMaxPayload[3] = 0; + upd->CpuPcieRpAspm[0] = 0; + upd->CpuPcieRpAspm[1] = 2; + upd->CpuPcieRpAspm[2] = 2; + upd->CpuPcieRpAspm[3] = 2; + upd->CpuPcieRpL1Substates[0] = 0; + upd->CpuPcieRpL1Substates[1] = 2; + upd->CpuPcieRpL1Substates[2] = 2; + upd->CpuPcieRpL1Substates[3] = 2; + upd->CpuPcieRpLtrEnable[0] = 1; + upd->CpuPcieRpLtrEnable[1] = 0; + upd->CpuPcieRpLtrEnable[2] = 0; + upd->CpuPcieRpLtrEnable[3] = 0; + upd->Eist = 0; + upd->ProcHotResponse = 0; + upd->ThermalMonitor = 0; + upd->Cx = 0; + upd->EnableItbm = 0; + upd->PcieRpLtrMaxSnoopLatency[0] = 4099; + upd->PcieRpLtrMaxSnoopLatency[1] = 4099; + upd->PcieRpLtrMaxSnoopLatency[2] = 4099; + upd->PcieRpLtrMaxSnoopLatency[3] = 4099; + upd->PcieRpLtrMaxSnoopLatency[4] = 4099; + upd->PcieRpLtrMaxSnoopLatency[5] = 4099; + upd->PcieRpLtrMaxSnoopLatency[6] = 4099; + upd->PcieRpLtrMaxSnoopLatency[7] = 4099; + upd->PcieRpLtrMaxSnoopLatency[8] = 4099; + upd->PcieRpLtrMaxSnoopLatency[9] = 4099; + upd->PcieRpLtrMaxSnoopLatency[10] = 4099; + upd->PcieRpLtrMaxSnoopLatency[11] = 4099; + upd->PcieRpLtrMaxSnoopLatency[12] = 0; + upd->PcieRpLtrMaxSnoopLatency[13] = 0; + upd->PcieRpLtrMaxSnoopLatency[14] = 0; + upd->PcieRpLtrMaxSnoopLatency[15] = 0; + upd->PcieRpLtrMaxSnoopLatency[16] = 0; + upd->PcieRpLtrMaxSnoopLatency[17] = 0; + upd->PcieRpLtrMaxSnoopLatency[18] = 0; + upd->PcieRpLtrMaxSnoopLatency[19] = 0; + upd->PcieRpLtrMaxSnoopLatency[20] = 0; + upd->PcieRpLtrMaxSnoopLatency[21] = 0; + upd->PcieRpLtrMaxSnoopLatency[22] = 0; + upd->PcieRpLtrMaxSnoopLatency[23] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[0] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[1] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[2] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[3] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[4] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[5] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[6] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[7] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[8] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[9] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[10] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[11] = 4099; + upd->PcieRpLtrMaxNoSnoopLatency[12] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[13] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[14] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[15] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[16] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[17] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[18] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[19] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[20] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[21] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[22] = 0; + upd->PcieRpLtrMaxNoSnoopLatency[23] = 0; + upd->CpuPcieRpLtrMaxSnoopLatency[0] = 4099; + upd->CpuPcieRpLtrMaxSnoopLatency[1] = 4111; + upd->CpuPcieRpLtrMaxSnoopLatency[2] = 4111; + upd->CpuPcieRpLtrMaxSnoopLatency[3] = 4111; + upd->CpuPcieRpLtrMaxNoSnoopLatency[0] = 4099; + upd->CpuPcieRpLtrMaxNoSnoopLatency[1] = 4111; + upd->CpuPcieRpLtrMaxNoSnoopLatency[2] = 4111; + upd->CpuPcieRpLtrMaxNoSnoopLatency[3] = 4111; +} /** * @brief Update S parameters in FSPS_UPD structure. * @@ -431,11 +929,10 @@ int fsp_machine_update_s_parameters(uint8_t *default_s_params) FSP_S_CONFIG *upd; unsigned int i; - (void)default_s_params; - - memcpy(default_s_params, (uint8_t*)FSP_S_UPD_DATA_BASE, 0xee0); + fsp_set_silicon_cfg((FSPS_UPD*)default_s_params); upd = &((FSPS_UPD*)default_s_params)->FspsConfig; + upd->MicrocodeRegionBase = 0x0; upd->MicrocodeRegionSize = 0x0; upd->DevIntConfigPtr = (uint32_t)mPchHDevIntConfig; @@ -445,22 +942,21 @@ int fsp_machine_update_s_parameters(uint8_t *default_s_params) upd->SataSalpSupport = 0; upd->EnableMultiPhaseSiliconInit = 0; upd->Enable8254ClockGating = 0; - memset(upd->SataPortsEnable, 1, sizeof(upd->SataPortsEnable)); -/* - upd->SataRstRaid0 = 1; - upd->SataRstRaid1 = 1; - upd->SataRstRaid10 = 1; - upd->SataRstRaid5 = 1; - */ - + memset(upd->SataPortsEnable, 0, sizeof(upd->SataPortsEnable)); + upd->SataPortsEnable[0] = upd->SataPortsEnable[1] = 1; + upd->PortUsb30Enable[0] = upd->PortUsb30Enable[1] = upd->PortUsb30Enable[2] = upd->PortUsb30Enable[3] = 1; + upd->XdciEnable = 1; for (i = 0; i < sizeof(upd->SerialIoUartMode); i++) - upd->SerialIoUartMode[i] = 0x1; - - upd->SerialIoDebugUartNumber = 0x0; + upd->SerialIoUartMode[i] = 0x0; upd->SerialIoUartMode[0] = 0x4; upd->EnableMultiPhaseSiliconInit = 0; + upd->SerialIoUartMode[1] = upd->SerialIoUartMode[2] = 0x1; + upd->SerialIoDebugUartNumber = 0x0; + + memset(upd->PcieRpHotPlug, 0, sizeof(upd->PcieRpHotPlug)); + memset(upd->CpuPcieRpHotPlug, 0, sizeof(upd->CpuPcieRpHotPlug)); return 0; } /** @@ -499,14 +995,460 @@ static int tgl_setup_lpc_decode(uint32_t address, uint32_t length, return 0; } -/* only support native mode */ -struct tgl_gpio_info { +#define GPIO_OWN_MASK (0x3) +struct tgl_gpio { uint8_t comm_port_id; - uint8_t gpio_pad_off; - uint8_t pad_mode:3; - uint8_t pad_reset:2; + uint32_t cfg_offset; }; +enum gpio_config_flags { + GPIO_SET_MODE = (1 << 0), + GPIO_SET_OWN = (1 << 1), + GPIO_SET_INTERRUPT = (1 << 2), + GPIO_SET_DIRECTION = (1 << 3), + GPIO_SET_RXINV = (1 << 4), + GPIO_SET_RESET = (1 << 5), + GPIO_SET_TERM = (1 << 6), + GPIO_SET_RXEVCONF = (1 << 7) +}; + +struct tgl_gpio_conf { + struct tgl_gpio gpio; + enum gpio_config_flags flags; + uint8_t gpio_mode; + uint8_t gpio_own; + uint8_t gpio_interrupt; + uint8_t gpio_dir; + uint8_t gpio_reset; + uint8_t gpio_term; + uint8_t gpio_rxevconf; + uint8_t gpio_rxinv; +}; + +#if defined (TARGET_kontron_vx3060_s2) +static const struct tgl_gpio_conf gpio_table_tempram[] = { + /* UART 0 */ + {.gpio = + { + /* PAD C8 */ + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C8_CFG_OFF, + }, + .flags = + (GPIO_SET_DIRECTION | GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_term = GPIO_TERM_NONE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + /* PAD C9 */ + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C9_CFG_OFF, + }, + .flags = + (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_term = GPIO_TERM_NONE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C10_CFG_OFF, + }, + .flags = + (GPIO_SET_DIRECTION | GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_term = GPIO_TERM_NONE, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C11_CFG_OFF, + }, + .flags = + (GPIO_SET_DIRECTION | GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_term = GPIO_TERM_NONE, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_reset = GPIO_RESET_PLTRST}, + /* UART - 1*/ + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C12_CFG_OFF, + }, + .flags = + (GPIO_SET_DIRECTION | GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_term = GPIO_TERM_NONE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C13_CFG_OFF, + }, + .flags = + (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_term = GPIO_TERM_NONE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C14_CFG_OFF, + }, + .flags = + (GPIO_SET_DIRECTION | GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_term = GPIO_TERM_NONE, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C15_CFG_OFF, + }, + .flags = + (GPIO_SET_DIRECTION | GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_term = GPIO_TERM_NONE, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_reset = GPIO_RESET_PLTRST}, + /* UART - 2*/ + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C20_CFG_OFF, + }, + .flags = + (GPIO_SET_DIRECTION | GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_term = GPIO_TERM_NONE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C21_CFG_OFF, + }, + .flags = + (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_term = GPIO_TERM_NONE, + .gpio_reset = GPIO_RESET_PLTRST}, +}; + +static const struct tgl_gpio_conf gpio_table_premem[] = { + /* Disable CNVi (Bluetooth Radio Interface) */ + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_F2_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, +}; + +static const struct tgl_gpio_conf gpio_table_presilicon[] = { + + /* set to GPIO mode as native functions aren't used */ + {.gpio = + { + .comm_port_id = GPIO_COMM_0_PORT_ID, + .cfg_offset = GPIO_GPPC_A8_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_E12_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_E15_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_E16_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_F9_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + /* test points */ + {.gpio = + { + .comm_port_id = GPIO_COMM_0_PORT_ID, + .cfg_offset = GPIO_GPPC_A9_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_F4_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_F5_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + /* FUSA_DIAGTEST_PCHMODE and FUSA_DIAGTEST_EN, disabled in SBL*/ +/* {.gpio = + { + .comm_port_id = GPIO_COMM_0_PORT_ID, + .cfg_offset = GPIO_GPPC_T2_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, + {.gpio = + { + .comm_port_id = GPIO_COMM_0_PORT_ID, + .cfg_offset = GPIO_GPPC_T3_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_OUTPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST}, */ + /* TPM */ + {.gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C22_CFG_OFF, + }, + .flags = + (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_RXINV | GPIO_SET_RESET | + GPIO_SET_RXEVCONF | GPIO_SET_TERM | GPIO_SET_INTERRUPT), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_rxinv = 1, + .gpio_rxevconf = GPIO_RXEVCONF_LEVEL, + .gpio_interrupt = GPIO_INTERRUPT_SCI, + .gpio_reset = GPIO_RESET_HOSTDEEPRESET, + .gpio_term = GPIO_TERM_NONE}, + /* PCH I2C5 */ + {.gpio = + { + .comm_port_id = GPIO_COMM_0_PORT_ID, + .cfg_offset = GPIO_GPPC_B10_CFG_OFF, + }, + .flags = + (GPIO_SET_MODE | GPIO_SET_INTERRUPT | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + {.gpio = + { + .comm_port_id = GPIO_COMM_0_PORT_ID, + .cfg_offset = GPIO_GPPC_B9_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + /* SMLINK1 to PD */ + {/* SM1 CLK */ + .gpio = + { + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C6_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + {.gpio = + { + /* SM1 DATA */ + .comm_port_id = GPIO_COMM_4_PORT_ID, + .cfg_offset = GPIO_GPPC_C7_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_NATIVE_1, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + /* watchdog */ + {.gpio = + { + /* PLD_WDT_IRQ0 */ + .comm_port_id = GPIO_COMM_1_PORT_ID, + .cfg_offset = GPIO_GPPC_D1_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_HOSTDEEPRESET, + .gpio_term = GPIO_TERM_NONE}, + {.gpio = + { + /* PLD_WDT_IRQ1 */ + .comm_port_id = GPIO_COMM_1_PORT_ID, + .cfg_offset = GPIO_GPPC_D0_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_HOSTDEEPRESET, + .gpio_term = GPIO_TERM_NONE}, + /* wake from i225/E810/i210/M2_TOP/M2_BOT/XMC */ + {.gpio = + { + .comm_port_id = GPIO_COMM_1_PORT_ID, + .cfg_offset = GPIO_GPPC_D2_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_HOSTDEEPRESET, + .gpio_term = GPIO_TERM_NONE}, + /* Audio, disabled */ + {.gpio = + { + .comm_port_id = GPIO_COMM_5_PORT_ID, + .cfg_offset = GPIO_GPP_R0_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + {.gpio = + { + .comm_port_id = GPIO_COMM_5_PORT_ID, + .cfg_offset = GPIO_GPP_R1_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + {.gpio = + { + .comm_port_id = GPIO_COMM_5_PORT_ID, + .cfg_offset = GPIO_GPP_R2_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + {.gpio = + { + .comm_port_id = GPIO_COMM_5_PORT_ID, + .cfg_offset = GPIO_GPP_R3_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + {.gpio = + { + .comm_port_id = GPIO_COMM_5_PORT_ID, + .cfg_offset = GPIO_GPP_R4_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + {.gpio = + { + .comm_port_id = GPIO_COMM_5_PORT_ID, + .cfg_offset = GPIO_GPP_R5_CFG_OFF, + }, + .flags = (GPIO_SET_MODE | GPIO_SET_DIRECTION | GPIO_SET_INTERRUPT | + GPIO_SET_RESET | GPIO_SET_TERM), + .gpio_mode = GPIO_MODE_GPIO, + .gpio_dir = GPIO_DIR_INPUT, + .gpio_interrupt = GPIO_INTERRUPT_DISABLE, + .gpio_reset = GPIO_RESET_PLTRST, + .gpio_term = GPIO_TERM_NONE}, + +}; +#endif /* TARGET_kontron_vx3060_s2 */ /** * @brief Configure GPIO settings for a specific device. * @details This function configures GPIO settings for a specific device on @@ -516,21 +1458,52 @@ struct tgl_gpio_info { * GPIO information. * @return void */ -static void tgl_gpio_configure(struct tgl_gpio_info *gpio) +static void tgl_gpio_configure(const struct tgl_gpio_conf *gpio) { - uint16_t off; - uint32_t dw0; + uint32_t dw0, _dw0, dw1, _dw1; + struct tgl_gpio g; - off = gpio->gpio_pad_off * 16 + GPIO_PAD_CONF_OFF; - dw0 = pch_read32(gpio->comm_port_id, off); + g = gpio->gpio; - dw0 &= ~(GPIO_MODE_MASK); - dw0 |= gpio->pad_mode << GPIO_MODE_SHIFT; + GPIO_DEBUG_PRINTF("Gpio port: %d off: 0x%x :\r\n", i, g.comm_port_id, + g.cfg_offset); - dw0 &= ~(GPIO_RESET_MASK); - dw0 |= gpio->pad_reset << GPIO_RESET_SHIFT; + dw0 = _dw0 = pch_read32(g.comm_port_id, g.cfg_offset); + dw1 = _dw1 = pch_read32(g.comm_port_id, g.cfg_offset + 4); - pch_write32(gpio->comm_port_id, off, dw0); + if (gpio->flags & GPIO_SET_MODE) { + dw0 &= ~(GPIO_MODE_MASK); + dw0 |= gpio->gpio_mode << GPIO_MODE_SHIFT; + } + if (gpio->flags & GPIO_SET_RESET) { + dw0 &= ~(GPIO_RESET_MASK); + dw0 |= gpio->gpio_reset << GPIO_RESET_SHIFT; + } + if (gpio->flags & GPIO_SET_DIRECTION) { + dw0 &= ~(GPIO_DIR_MASK); + dw0 |= gpio->gpio_dir << GPIO_DIR_SHIFT; + } + if (gpio->flags & GPIO_SET_INTERRUPT) { + dw0 &= ~(GPIO_INTERRUPT_MASK); + dw0 |= gpio->gpio_interrupt << GPIO_INTERRUPT_SHIFT; + } + if (gpio->flags & GPIO_SET_TERM) { + dw1 &= ~(GPIO_TERM_MASK); + dw1 |= gpio->gpio_term << GPIO_TERM_SHIFT; + } + if (gpio->flags & GPIO_SET_RXEVCONF) { + dw0 &= ~(GPIO_RXEVCONF_MASK); + dw0 |= gpio->gpio_rxevconf << GPIO_RXEVCONF_SHIFT; + } + + GPIO_DEBUG_PRINTF("dw0: 0x%x -> 0x%x, dw1: 0x%x->0x%x\r\n", + _dw0, dw0, _dw1, dw1); + if (_dw1 != dw1) { + pch_write32(g.comm_port_id, g.cfg_offset + 4, dw1); + } + if (_dw0 != dw0) { + pch_write32(g.comm_port_id, g.cfg_offset, dw0); + } } #ifdef TARGET_kontron_vx3060_s2 @@ -638,25 +1611,28 @@ int post_temp_ram_init_cb(void) disable_watchdog_tco(); #ifdef TARGET_kontron_vx3060_s2 - struct tgl_gpio_info uart_gpio = { - .comm_port_id = GPIO_COMM_4_PORT_ID, - .pad_mode = GPIO_MODE_NATIVE_1, - .pad_reset = GPIO_RESET_PLTRST, - }; uint8_t reg; int err; - int i; + unsigned int i; + + reg = pch_read32(PCR_INTERRUPT_PORT_ID, GIC_OFFSET); + if (reg & GIC_SHUTDOWN_STATUS_BIT) { + /* CPU is in shutdown mode, probably after a triple fault. Force a full reset. */ + wolfBoot_printf("CPU Shutdown mode detected. Force reset.\r\n"); + reset(0); + panic(); + } err = configure_kontron_cpld(); if (err != 0) return err; - /* setup uart gpios */ - for (i = 0; i < 4; i++) { - uart_gpio.gpio_pad_off = GPIO_C_8_OFF + i; - tgl_gpio_configure(&uart_gpio); + /* setup GPIOs */ + for (i = 0; i < sizeof(gpio_table_tempram)/sizeof(gpio_table_tempram[0]); i++) { + tgl_gpio_configure(&gpio_table_tempram[i]); } + kontron_ask_for_recovery(); #else (void)tgl_gpio_configure; @@ -681,7 +1657,6 @@ int fsp_machine_update_m_parameters(uint8_t *default_m_params, uint32_t mem_size) { FSPM_UPD *new_udp; - int i; wolfBoot_printf("machine_update_m_params" ENDLINE); @@ -698,4 +1673,25 @@ int fsp_machine_update_m_parameters(uint8_t *default_m_params, return 0; } +int fsp_pre_mem_init_cb(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(gpio_table_premem)/sizeof(gpio_table_premem[0]); i++) { + tgl_gpio_configure(&gpio_table_premem[i]); + } + + return 0; +} + +int fsp_pre_silicon_init_cb(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(gpio_table_presilicon)/sizeof(gpio_table_presilicon[0]); i++) { + tgl_gpio_configure(&gpio_table_presilicon[i]); + } + + return 0; +} #endif /* TGL_FSP_H */ diff --git a/stage1/x86_fsp.mk b/stage1/x86_fsp.mk index 6ff7a056..cfa7e2ed 100644 --- a/stage1/x86_fsp.mk +++ b/stage1/x86_fsp.mk @@ -11,8 +11,7 @@ $(LSCRIPT_IN): $(WOLFBOOT_ROOT)/hal/$(LSCRIPT_IN).in FORCE sed -e "s/@FSP_S_BASE@/$(FSP_S_BASE)/g" | \ sed -e "s/@WOLFBOOT_LOAD_BASE@/$(WOLFBOOT_LOAD_BASE)/g" | \ sed -e "s/@UCODE0_BASE@/$(UCODE0_BASE)/g" | \ - sed -e "s/@UCODE1_BASE@/$(UCODE1_BASE)/g" | \ - sed -e "s/@FSP_S_UPD_DATA_BASE@/$(FSP_S_UPD_DATA_BASE)/g" \ + sed -e "s/@UCODE1_BASE@/$(UCODE1_BASE)/g" \ > $@ ./boot_x86_fsp_start.o: boot_x86_fsp_start.S @@ -38,17 +37,13 @@ sig_fsp_s.o: fsp_s.o $(SIGN_KEY) ../$(FSP_S_BIN) $(SIGN_TOOL) $(SIGN_OPTIONS) ../$(FSP_S_BIN) $(SIGN_KEY) 1 @dd if=$(X86FSP_PATH)/fsp_s_v1_signed.bin of=$(X86FSP_PATH)/fsp_s_signature.bin bs=$(IMAGE_HEADER_SIZE) count=1 $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.sig_fsp_s $(X86FSP_PATH)/fsp_s_signature.bin sig_fsp_s.o - @rm -f $(X86FSP_PATH)/fsp_s_v1_signed.bin $(X86FSP_PATH)/fsp_s_signature.bin + @rm -f $(X86FSP_PATH)/fsp_s_signature.bin sig_wolfboot_raw.o: wolfboot_raw.bin $(SIGN_KEY) $(SIGN_TOOL) $(SIGN_OPTIONS) wolfboot_raw.bin $(SIGN_KEY) 1 @dd if=wolfboot_raw_v1_signed.bin of=wolfboot_raw_signature.bin bs=$(IMAGE_HEADER_SIZE) count=1 $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.sig_wolfboot_raw wolfboot_raw_signature.bin sig_wolfboot_raw.o - -fsp_tgl_s_upd.o: ../$(FSP_S_UPD_DATA_BIN) - $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.fsps_upd $^ $@ - ucode0.o: ../$(UCODE0_BIN) $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.ucode0 $^ $@ diff --git a/test-app/Makefile b/test-app/Makefile index 43242382..d5e31e6d 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -358,6 +358,12 @@ ifeq ($(TARGET),psoc6) CFLAGS+=-DCY8C624ABZI_D44 endif +ifeq ($(TARGET),x86_fsp_qemu) + APP_OBJS:=app_$(TARGET).o ../hal/x86_uart.o ../src/x86/common.o ../src/string.o + LSCRIPT_TEMPLATE:=x86_fsp.ld + LDFLAGS= +endif + CFLAGS+=-I../lib/wolfssl diff --git a/test-app/app_x86_fsp_qemu.c b/test-app/app_x86_fsp_qemu.c new file mode 100644 index 00000000..dfe6cf50 --- /dev/null +++ b/test-app/app_x86_fsp_qemu.c @@ -0,0 +1,68 @@ +/* app_x86_fsp_qemu.c + * + * Test bare-metal boot application + * + * Copyright (C) 2021 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef PLATFORM_x86_fsp_qemu + +#include +#include + +struct mb2_header { + uint32_t magic; + uint32_t architecture; + uint32_t header_length; + uint32_t checksum; +} __attribute__((__packed__)); + +struct mb2_tag_info_req { + uint16_t type; + uint16_t flags; + uint32_t size; + uint32_t mbi_tag_types[2]; +} __attribute__((__packed__)); + +struct multiboot_header { + struct mb2_header hdr; + struct mb2_tag_info_req req; +} __attribute__((__packed__)); + +__attribute__((aligned(8))) struct multiboot_header mbh = { + .hdr.magic = 0xe85250d6, + .hdr.architecture = 0, + .hdr.checksum = 0, + .hdr.header_length = sizeof(struct mb2_header), + .req.type = 1, + .req.flags = 0, + .req.size = sizeof(struct mb2_tag_info_req), + /* basic mem info */ + .req.mbi_tag_types[0] = 4, + /* mem map */ + .req.mbi_tag_types[1] = 6, +}; + +void start() +{ + wolfBoot_printf("wolfBoot QEMU x86 FSP test app\r\n"); + __asm__ ("hlt\r\n"); +} +#endif diff --git a/test-app/x86_fsp.ld b/test-app/x86_fsp.ld new file mode 100644 index 00000000..0cd5bbb5 --- /dev/null +++ b/test-app/x86_fsp.ld @@ -0,0 +1,26 @@ +OUTPUT_FORMAT(elf64-x86-64) + +SECTIONS +{ + .text : + { + _start_text = .; + *(.text*) + _end_text = .; + } + + .data : + { + _start_data = .; + *(.data*) + _end_data = .; + } + + .bss (NOLOAD) : + { + _start_bss = .; + *(.bss*) + . = ALIGN(4); + _end_bss = .; + } +} diff --git a/tools/scripts/qemu64/qemu.sh b/tools/scripts/qemu64/qemu.sh deleted file mode 100755 index e41f400a..00000000 --- a/tools/scripts/qemu64/qemu.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -qemu-system-i386 -m 1G -machine q35 -serial mon:stdio -nographic \ - -pflash wolfboot_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk - diff --git a/tools/scripts/qemu64/qemu64-tpm-nobl.sh b/tools/scripts/qemu64/qemu64-tpm-nobl.sh deleted file mode 100755 index 917a7458..00000000 --- a/tools/scripts/qemu64/qemu64-tpm-nobl.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# - -## TPM emulator: -# https://github.com/stefanberger/swtpm - -if (test -z $OVMF_PATH); then - if (test -f /usr/share/edk2-ovmf/x64/OVMF.fd); then - OVMF_PATH=/usr/share/edk2-ovmf/x64 - elif (test -f /usr/share/qemu/OVMF.fd); then - OVMF_PATH=/usr/share/qemu - else - OVMF_PATH=/ - fi -fi - -QEMU_TPM_OPTIONS=" \ - -chardev socket,id=chrtpm,path=/tmp/swtpm/swtpm-sock \ - -tpmdev emulator,id=tpm0,chardev=chrtpm \ - -device tpm-tis,tpmdev=tpm0" -QEMU_OPTIONS=" \ - -m 1G -machine q35 -serial mon:stdio -nographic -smp cpus=8,sockets=2,cores=2,threads=2 \ - -kernel bzImage -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk" - -#killall swtpm -#sleep 1 -echo TPM Emulation ON -mkdir -p /tmp/swtpm -swtpm socket --tpm2 --tpmstate dir=/tmp/swtpm \ - --ctrl type=unixio,path=/tmp/swtpm/swtpm-sock --log level=20 & -sleep .5 -echo Running QEMU... - -qemu-system-x86_64 $QEMU_OPTIONS $QEMU_TPM_OPTIONS - diff --git a/tools/scripts/qemu64/qemu64-tpm.sh b/tools/scripts/qemu64/qemu64-tpm.sh deleted file mode 100755 index 1dbbd5d1..00000000 --- a/tools/scripts/qemu64/qemu64-tpm.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# - -## TPM emulator: -# https://github.com/stefanberger/swtpm - -if (test -z $OVMF_PATH); then - if (test -f /usr/share/edk2-ovmf/x64/OVMF.fd); then - OVMF_PATH=/usr/share/edk2-ovmf/x64 - elif (test -f /usr/share/qemu/OVMF.fd); then - OVMF_PATH=/usr/share/qemu - else - OVMF_PATH=/ - fi -fi - -QEMU_TPM_OPTIONS=" \ - -chardev socket,id=chrtpm,path=/tmp/swtpm/swtpm-sock \ - -tpmdev emulator,id=tpm0,chardev=chrtpm \ - -device tpm-tis,tpmdev=tpm0" - -QEMU_OPTIONS=" \ - -m 1G -machine q35 -serial mon:stdio -nographic \ - -pflash wolfboot_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk" - -QEMU=qemu-system-x86_64 -if [ "$DEBUG" = "1" ]; then - QEMU_OPTIONS="${QEMU_OPTIONS} -S -s" - QEMU=qemu-system-i386 -fi - -killall swtpm -sleep 1 -echo TPM Emulation ON -mkdir -p /tmp/swtpm -swtpm socket --tpm2 --tpmstate dir=/tmp/swtpm \ - --ctrl type=unixio,path=/tmp/swtpm/swtpm-sock --log level=20 & -sleep .5 -echo Running QEMU... - -$QEMU $QEMU_OPTIONS $QEMU_TPM_OPTIONS - diff --git a/tools/scripts/qemu64/qemu64.sh b/tools/scripts/qemu64/qemu64.sh deleted file mode 100755 index 3baf2a9d..00000000 --- a/tools/scripts/qemu64/qemu64.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -qemu-system-x86_64 -m 1G -machine q35 -serial mon:stdio -nographic \ - -pflash wolfboot_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk - diff --git a/tools/scripts/qemu64/qemu64dbg.sh b/tools/scripts/qemu64/qemu64dbg.sh deleted file mode 100755 index 43c35b65..00000000 --- a/tools/scripts/qemu64/qemu64dbg.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -qemu-system-x86_64 -m 1G -machine q35 -serial mon:stdio -nographic \ - -pflash wolfboot_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk -S -s - diff --git a/tools/scripts/qemu64/qemudbg.sh b/tools/scripts/qemu64/qemudbg.sh deleted file mode 100755 index 17f8b0de..00000000 --- a/tools/scripts/qemu64/qemudbg.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -qemu-system-i386 -m 1G -machine q35 -serial mon:stdio -nographic \ - -pflash stage1/loader_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk \ - -S -s - diff --git a/tools/scripts/qemu64/qemunobl.sh b/tools/scripts/qemu64/qemunobl.sh deleted file mode 100755 index b54cc7d6..00000000 --- a/tools/scripts/qemu64/qemunobl.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -qemu-system-x86_64 -m 1G -machine q35 -serial mon:stdio -nographic \ - -kernel bzImage \ - -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk - diff --git a/tools/scripts/qemu64/qemutpm.sh b/tools/scripts/qemu64/qemutpm.sh deleted file mode 100755 index e4eeaeb9..00000000 --- a/tools/scripts/qemu64/qemutpm.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -# - -## TPM emulator: -# https://github.com/stefanberger/swtpm - -if (test -z $OVMF_PATH); then - if (test -f /usr/share/edk2-ovmf/x64/OVMF.fd); then - OVMF_PATH=/usr/share/edk2-ovmf/x64 - elif (test -f /usr/share/qemu/OVMF.fd); then - OVMF_PATH=/usr/share/qemu - else - OVMF_PATH=/ - fi -fi - -QEMU_TPM_OPTIONS=" \ - -chardev socket,id=chrtpm,path=/tmp/swtpm/swtpm-sock \ - -tpmdev emulator,id=tpm0,chardev=chrtpm \ - -device tpm-tis,tpmdev=tpm0" -QEMU_OPTIONS=" \ - -m 1G -machine q35 -serial mon:stdio -nographic \ - -pflash wolfboot_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk \ - -S -gdb tcp::3333" - -#killall swtpm -#sleep 1 -echo TPM Emulation ON -mkdir -p /tmp/swtpm -swtpm socket --tpm2 --tpmstate dir=/tmp/swtpm \ - --ctrl type=unixio,path=/tmp/swtpm/swtpm-sock --log level=20 & -sleep .5 -echo Running QEMU... - -qemu-system-i386 $QEMU_OPTIONS $QEMU_TPM_OPTIONS - diff --git a/tools/scripts/qemu64/sign_linux.sh b/tools/scripts/qemu64/sign_linux.sh deleted file mode 100755 index 7d2a3c65..00000000 --- a/tools/scripts/qemu64/sign_linux.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -SIGN=${SIGN:-"--ecc256"} -HASH=${HASH:-"--sha256"} - -cp /tmp/br-linux-wolfboot/output/images/bzImage . -tools/keytools/sign $SIGN $HASH bzImage wolfboot_signing_private_key.der 8 -tools/keytools/sign $SIGN $HASH bzImage wolfboot_signing_private_key.der 2 - -cp base-part-image app.bin -dd if=bzImage_v8_signed.bin of=app.bin bs=1k seek=1024 conv=notrunc -dd if=bzImage_v2_signed.bin of=app.bin bs=1k seek=17408 conv=notrunc - - - diff --git a/tools/scripts/qemu64/test_sata.sh b/tools/scripts/qemu64/test_sata.sh deleted file mode 100755 index 67e85b99..00000000 --- a/tools/scripts/qemu64/test_sata.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -set -e - -#qemu-system-x86_64 -m 256M -machine q35 -serial mon:stdio -nographic -pflash \ -# ../wolfBoot/x86_qemu_flash.bin -gdb tcp::3333 -S \ -# -drive file=test_img.bin,if=none,id=SATADRV \ -# -device ich9-ahci,id=ahci \ -# -device ide-hd,drive=SATADRV,bus=ahci.0 - -# qemu-system-i386 -m 256M -machine q35 -serial mon:stdio -nographic -pflash \ -# x86_qemu_flash.bin -S -s \ -# -drive file=test_img.bin,if=none,id=SATADRV,format=raw \ -# -device ich9-ahci,id=ahci \ -# -device ide-hd,drive=SATADRV,bus=ahci.0 - - -# qemu-system-x86_64 -m 1G -machine q35 -serial mon:stdio -nographic \ -# -drive id=mydisk,format=raw,file=app.bin,if=none \ -# -device ide-hd,drive=mydisk \ -# -kernel /home/arch/br-linux-wolfboot/output/images/bzImage \ -# -append "acpi=off" - -#qemu-system-x86_64 -m 256M -machine q35 -serial mon:stdio -nographic \ -qemu-system-x86_64 -m 256M -machine q35 \ - -drive id=mydisk,format=raw,file=app.bin,if=none \ - -device ide-hd,drive=mydisk \ - -pflash loader.bin - # -kernel /home/arch/br-linux-wolfboot/output/images/bzImage \ - # -append "acpi=off loglevel=7 libata.noacpi=1 libata.force=6.0:noncq libata.dma=0" \ - - # -S -s diff --git a/tools/scripts/x86_fsp/compute_pcr.py b/tools/scripts/x86_fsp/compute_pcr.py new file mode 100644 index 00000000..2f5b0736 --- /dev/null +++ b/tools/scripts/x86_fsp/compute_pcr.py @@ -0,0 +1,125 @@ +""" +Parse IFWI Image to compute initial PCR0 value as obtained by Intel Boot Guard +""" +import struct +import argparse +import hashlib +import os +import re +import subprocess + +FLASH_SIZE_IN_MB = 64 + +def off_to_addr(off: int, image_size : int = FLASH_SIZE_IN_MB*1024*1024) -> int: + """ + convert offset in the image to address in memory + """ + return (4 * 1024 * 1024 * 1024) - (image_size - off) + +def addr_to_off(addr:int, image_size : int = FLASH_SIZE_IN_MB*1024*1024) -> int: + """ + convert address in memory to offset in the image + """ + return image_size - ((4 * 1024 * 1024 * 1024) - addr) + +def get_sha256_hash(data: bytearray) -> bytearray: + """ + return the sha256 of data + """ + h = hashlib.sha256() + h.update(data) + return h.digest() + +def get_config_value(config: str, name): + """ + Parse config to find line of type NAME=value, return value + """ + + pattern = rf'^{re.escape(name)}=(.*)$' + matches = re.findall(pattern, config, re.MULTILINE) + if matches: + return matches[0].strip() + return None + +def get_sha256_hash_of_wolfboot_image(file_path: str): + """ + Get sha256 hash of wolfboot image at file_path + """ + HDR_OFF = 8 + WOLFBOOT_SHA_HDR = 0x03 + with open(file_path, 'rb') as f: + data = f.read() + data = data[HDR_OFF:] + while True: + if data[0] == 0xff: + data = data[1:] + continue + t, l = struct.unpack(' int: + """ + get the address of symbol keystore from ELF file image + """ + symbols = subprocess.check_output(['nm', 'stage1/loader_stage1.elf']).split(b'\n') + _start_keystore = int(list(filter(lambda x: b'_start_keystore' in x, symbols))[0].split(b' ')[0], 16) + return _start_keystore + +def pcr_extend(pcr: bytearray, data: bytearray) -> bytearray: + """ + get value of extend operation on pcr with data + """ + return get_sha256_hash(pcr + data) + +if __name__ == '__main__': + if os.path.exists('.config'): + with open('.config', 'r', encoding='utf-8') as f: + config = f.read() + else: + print("The file .config does not exist.") + + parser = argparse.ArgumentParser() + parser.add_argument('image_file', type=str, help='Path to the image file') + parser.add_argument('--target', type=str, choices=['IBG', 'qemu'], + default='IBG', help='Target platform') + + args = parser.parse_args() + image = bytes() + + with open(args.image_file, 'rb') as f: + image = bytearray(f.read()) + + pcr0 = bytearray(b'\x00'*32) + if args.target == 'qemu': + keystore_addr = get_keystore_sym_addr() + keystore_off = addr_to_off(keystore_addr, image_size = len(image)) + ibb = image[keystore_off:] + h = hashlib.sha256() + h.update(ibb) + pcr0_data_hash = h.digest() + pcr0 = pcr_extend(b'\x00'*32, pcr0_data_hash) + + print(f"Initial PCR0: {pcr0.hex()}") + + is_stage1_auth_enabled = get_config_value(config, 'STAGE1_AUTH') == '1' + print(f"stage1 auth is {'enabled' if is_stage1_auth_enabled else 'disabled'}") + + if is_stage1_auth_enabled: + fsp_s_hash = get_sha256_hash_of_wolfboot_image("src/x86/fsp_s_v1_signed.bin") + pcr0 = pcr_extend(pcr0, fsp_s_hash) + print(f"PCR0 after FSP_S: {pcr0.hex()}") + + wb_hash = get_sha256_hash_of_wolfboot_image('stage1/wolfboot_raw_v1_signed.bin') + pcr0 = pcr_extend(pcr0, wb_hash) + print(f"PCR0 after wolfboot: {pcr0.hex()}") + + # the pcrdigest needed by policy_sign tool is the hash of the concatenation of all PCRs involved in the policy. + # we have only one PCR here + pcr_digest = get_sha256_hash(pcr0) + + print("PCR Policy (use with tpm/policy_sign with -pcrdigest arg)") + print(pcr_digest.hex()) diff --git a/tools/scripts/x86_fsp/print_flash_map.py b/tools/scripts/x86_fsp/print_flash_map.py new file mode 100755 index 00000000..a968061b --- /dev/null +++ b/tools/scripts/x86_fsp/print_flash_map.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +import re +import argparse + +pattern = r'^([\w\.]+) +(0x[0-9a-fA-F]+) +(0x[0-9a-fA-F]+)' + +def parse_map_file(map_file_path): + components = [] + mmap = False + flash_start = 0 + with open(map_file_path, 'r') as map_file: + current_component = None + for line in map_file: + if line.startswith('FLASH'): + m = re.match(r'FLASH +(0x[0-9a-fA-F]+)', line) + flash_start = int(m[1], 16) + if line == 'Linker script and memory map\n' or mmap: + mmap = True + else: + continue + # Check for start of a new component + m = re.match(pattern, line) + if m: + c = {'name': m[1], 'address': int(m[2], 16), 'size': int(m[3], 16)} + components.append(c) + return components, flash_start + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("map_file_path", type=str, + help="Path to the map file", + nargs='?', + default='stage1/loader_stage1.map') + args = parser.parse_args() + map_file_path = args.map_file_path + comps, flash = parse_map_file(map_file_path) + comps = filter(lambda x: x['address'] >= flash, comps) + comps = sorted(comps, key=lambda x: x['address']) + print(f'Name:{"":<20}Address:{"":<20}Size:{"":<20}') + for c in comps: + print (f"{c['name']:<20} {hex(c['address']):<20} {hex(c['size']):<20}") + total_sum = sum(map(lambda x: x['size'], comps)) + print(f"total sum: {hex(total_sum)} ({total_sum//1024} KB)") diff --git a/tools/x86_fsp/qemu/0002-add-W-no-warnings-to-compile-with-gcc-12.patch b/tools/scripts/x86_fsp/qemu/0002-add-W-no-warnings-to-compile-with-gcc-12.patch similarity index 100% rename from tools/x86_fsp/qemu/0002-add-W-no-warnings-to-compile-with-gcc-12.patch rename to tools/scripts/x86_fsp/qemu/0002-add-W-no-warnings-to-compile-with-gcc-12.patch diff --git a/tools/x86_fsp/qemu/0003-disable-optmizaion-patch-for-edk2.patch b/tools/scripts/x86_fsp/qemu/0003-disable-optmizaion-patch-for-edk2.patch similarity index 100% rename from tools/x86_fsp/qemu/0003-disable-optmizaion-patch-for-edk2.patch rename to tools/scripts/x86_fsp/qemu/0003-disable-optmizaion-patch-for-edk2.patch diff --git a/tools/x86_fsp/qemu/0004-fix-PatchFv-make-regex-match-both-8-and-16-length-ad.patch b/tools/scripts/x86_fsp/qemu/0004-fix-PatchFv-make-regex-match-both-8-and-16-length-ad.patch similarity index 100% rename from tools/x86_fsp/qemu/0004-fix-PatchFv-make-regex-match-both-8-and-16-length-ad.patch rename to tools/scripts/x86_fsp/qemu/0004-fix-PatchFv-make-regex-match-both-8-and-16-length-ad.patch diff --git a/tools/x86_fsp/qemu/fsp-headers-patch.patch b/tools/scripts/x86_fsp/qemu/fsp-headers-patch.patch similarity index 100% rename from tools/x86_fsp/qemu/fsp-headers-patch.patch rename to tools/scripts/x86_fsp/qemu/fsp-headers-patch.patch diff --git a/tools/scripts/x86_fsp/qemu/make_hd.sh b/tools/scripts/x86_fsp/qemu/make_hd.sh new file mode 100755 index 00000000..84df831e --- /dev/null +++ b/tools/scripts/x86_fsp/qemu/make_hd.sh @@ -0,0 +1,35 @@ +#!/bin/bash +SIGN=${SIGN:-"--ecc256"} +HASH=${HASH:-"--sha256"} + +IMAGE=${IMAGE:-"bzImage"} + +set -e + +dd if=/dev/zero of=app.bin bs=1M count=64 +/sbin/fdisk app.bin < /dev/null + mkfifo /tmp/qemu_mon.in /tmp/qemu_mon.out + QEMU_OPTIONS+="\ + -chardev pipe,id=qemu_mon,path=/tmp/qemu_mon \ + -mon chardev=qemu_mon \ + -serial stdio \ + " +fi + +# If waiting for GDB is true, append options to QEMU_OPTIONS +if [ "$WAIT_FOR_GDB" = true ]; then + QEMU_OPTIONS="${QEMU_OPTIONS} -S -s" +fi + +if [ "$DEBUG_STAGE" = "DEBUG_STAGE1" ]; then + QEMU=qemu-system-i386 +else + QEMU=qemu-system-x86_64 +fi + +if [ "$ENABLE_TPM" = true ]; then + killall swtpm || true + sleep 1 + echo TPM Emulation ON + mkdir -p /tmp/swtpm + swtpm socket --tpm2 --tpmstate dir=/tmp/swtpm \ + --ctrl type=unixio,path=/tmp/swtpm/swtpm-sock --log level=20 & + sleep .5 + QEMU_OPTIONS+=$QEMU_TPM_OPTIONS +fi + +echo Running QEMU... +echo "$QEMU $QEMU_OPTIONS" +$QEMU $QEMU_OPTIONS diff --git a/tools/x86_fsp/qemu/qemu_build_fsp.sh b/tools/scripts/x86_fsp/qemu/qemu_build_fsp.sh similarity index 84% rename from tools/x86_fsp/qemu/qemu_build_fsp.sh rename to tools/scripts/x86_fsp/qemu/qemu_build_fsp.sh index 0be29f9d..ac1c6e2e 100755 --- a/tools/x86_fsp/qemu/qemu_build_fsp.sh +++ b/tools/scripts/x86_fsp/qemu/qemu_build_fsp.sh @@ -6,12 +6,17 @@ EDKII_REPO=https://github.com/tianocore/edk2.git SBL_COMMIT_ID=c80d8d592cf127616daca5df03ac7731e78ffcc1 SBL_PATCH_URL=https://github.com/slimbootloader/slimbootloader/raw/${SBL_COMMIT_ID}/Silicon/QemuSocPkg/FspBin/Patches/0001-Build-QEMU-FSP-2.0-binaries.patch SCRIPT_DIR=$(readlink -f "$(dirname "$0")") -WOLFBOOT_DIR="${SCRIPT_DIR}/../../.." +WOLFBOOT_DIR="$(pwd)" FSP_NAME=QEMU_FSP_DEBUG CONFIG_FILE=${CONFIG_FILE:-"${WOLFBOOT_DIR}/.config"} set -e +if [ ! -f "${WOLFBOOT_DIR}/arch.mk" ]; then + echo "Error: Current directory is not the root directory of the source tree" + exit 1 +fi + if [ ! -d "$WORK_DIR" ]; then mkdir -p "$WORK_DIR" fi @@ -27,10 +32,18 @@ else fi download_edkii() { - (cd "$WORK_DIR" && - git clone "${EDKII_REPO}" edk2 && - cd edk2 && - git checkout "${EDKII_TAG}") + if [ ! -d "$WORK_DIR/edk2" ]; then + (cd "$WORK_DIR" && + git clone "${EDKII_REPO}" edk2) + else + (cd "$WORK_DIR/edk2" && + git stash save --include-untracked "Auto-stashed on $(date)" && + git clean -fd) # This will remove untracked files/directories + fi + + # Now, checkout the desired tag/branch + (cd "$WORK_DIR/edk2" && + git checkout "${EDKII_TAG}") } download_sbl_patch_and_patch_edkii() { diff --git a/tools/scripts/x86_fsp/qemu/test_qemu.sh b/tools/scripts/x86_fsp/qemu/test_qemu.sh new file mode 100755 index 00000000..e165e971 --- /dev/null +++ b/tools/scripts/x86_fsp/qemu/test_qemu.sh @@ -0,0 +1,73 @@ +#/bin/bash + +set -e + +WOLFBOOT_DIR=$(pwd) +# Parse command line options +while getopts "b" opt; do + case "$opt" in + b) + REBUILD_ONLY=true + ;; + *) + echo "Usage: $0 [-b]" + echo "-b : rebuild only (skip FSP build, key gen, ecc)" + exit 1 + ;; + esac +done + + +if [ "$REBUILD_ONLY" != true ]; then + CONFIG=x86_fsp_qemu_seal.config + + make distclean + cp "config/examples/${CONFIG}" .config + ./tools/scripts/x86_fsp/qemu/qemu_build_fsp.sh + make keytools + make tpmtools + # generate one key for images and one for the TPM + ./tools/keytools/keygen --force --ecc384 -g wolfboot_signing_private_key.der --ecc256 -g tpm_seal_key.key -keystoreDir src/ +fi + +# manual add ECC256 for TPM +make CFLAGS_EXTRA="-DHAVE_ECC256" + +# test-app +make test-app/image.elf + +# compute pcr0 value +PCR0=$(python ./tools/scripts/x86_fsp/compute_pcr.py --target qemu wolfboot_stage1.bin | tail -n 1) +echo $PCR0 +./tools/tpm/policy_sign -ecc256 -key=tpm_seal_key.key -pcr=0 -pcrdigest=$PCR0 + +./tools/scripts/x86_fsp/tpm_install_policy.sh policy.bin.sig +IMAGE=test-app/image.elf SIGN=--ecc384 ./tools/scripts/x86_fsp/qemu/make_hd.sh + +echo "RUNNING QEMU" +# launch qemu in background +./tools/scripts/x86_fsp/qemu/qemu.sh -t -p | tee /tmp/qemu_output & +echo "WAITING FOR QEMU TO RUN" +sleep 5 + +# close qemu +timeout 5 echo 'quit' > /tmp/qemu_mon.in +output=$(cat /tmp/qemu_output) +set +e +app=$(echo "$output" | grep -m 1 "wolfBoot QEMU x86 FSP test app") +if [ -n "$app" ]; then + echo "Found 'wolfBoot QEMU x86 FSP test app' in the output." +else + echo -e "\e[31mTEST FAILED\e[0m" + exit 255 +fi + +disk_unlocked=$(echo "$output" | grep -m 1 "DISK LOCK SECRET:") +if [ -n "$output" ]; then + echo -e "\e[32mTEST OK\e[0m" + exit 0 +else + echo "$output" + echo -e "\e[31mTEST FAILED\e[0m" + exit 255 +fi diff --git a/tools/x86_fsp/tgl/0001-FSP-wolfboot-patch.patch b/tools/scripts/x86_fsp/tgl/0001-FSP-wolfboot-patch.patch similarity index 100% rename from tools/x86_fsp/tgl/0001-FSP-wolfboot-patch.patch rename to tools/scripts/x86_fsp/tgl/0001-FSP-wolfboot-patch.patch diff --git a/tools/scripts/x86_fsp/tgl/assemble_image.sh b/tools/scripts/x86_fsp/tgl/assemble_image.sh new file mode 100755 index 00000000..adbe6e10 --- /dev/null +++ b/tools/scripts/x86_fsp/tgl/assemble_image.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +WOLFBOOT_DIR=$(pwd) + +# 16 MB +BIOS_REGION_SIZE=16777216 +BIOS_REGION_PATH=/tmp/bios.bin +SIGN_OPTIONS="--ecc384 --sha256" +SIGN_KEY=$WOLFBOOT_DIR/wolfboot_signing_private_key.der +SIGN_TOOL=./tools/keytools/sign + +set -e + +make_keys() +{ + make keytools + ./tools/keytools/keygen --ecc384 -g wolfboot_signing_private_key.der --ecc256 -g tpm_seal_key.key -keystoreDir src/ +} + +build_and_sign_image() +{ + # compute the size differences between $FLASH_DUMP and "$WOLFBOOT_DIR"/wolfboot_stage1.bin and store it in SIZE + FLASH_DUMP_SIZE=$(stat -c%s "$FLASH_DUMP") + WOLFBOOT_SIZE=$(stat -c%s "$BIOS_REGION_PATH") + SIZE=$((FLASH_DUMP_SIZE - WOLFBOOT_SIZE)) + cp "$FLASH_DUMP" "$WOLFBOOT_DIR/temp_image.bin" + truncate -s $SIZE "$WOLFBOOT_DIR/temp_image.bin" + cat "$WOLFBOOT_DIR/temp_image.bin" "$BIOS_REGION_PATH" > "$WOLFBOOT_DIR/final_image.bin" + PCR0=$(python ./tools/scripts/x86_fsp/compute_pcr.py "$WOLFBOOT_DIR"/final_image.bin | tail -n 1) + "$WOLFBOOT_DIR"/tools/tpm/policy_sign -ecc256 -key=tpm_seal_key.key -pcr=0 -pcrdigest=$PCR0 + IMAGE_FILE="$WOLFBOOT_DIR"/final_image.bin "$WOLFBOOT_DIR"/tools/scripts/x86_fsp/tpm_install_policy.sh policy.bin.sig +} + +assemble() +{ + cp $WOLFBOOT_DIR/wolfboot_stage1.bin $BIOS_REGION_PATH + build_and_sign_image +} + +# Parse command line options +while getopts "ks:n:m:" opt; do + case "$opt" in + k) + make_keys + exit 0 + ;; + n) + FLASH_DUMP="$OPTARG" + IBG=0 + ;; + *) + echo "Usage: $0 [-k] [-s FLASH_DUMP]" + echo "-k: make keys" + echo "-n FLASH_DUMP: assemble an image for being used without IBG" + exit 1 + ;; + esac +done + +assemble diff --git a/tools/x86_fsp/tgl/tgl_download_fsp.sh b/tools/scripts/x86_fsp/tgl/tgl_download_fsp.sh similarity index 93% rename from tools/x86_fsp/tgl/tgl_download_fsp.sh rename to tools/scripts/x86_fsp/tgl/tgl_download_fsp.sh index c4622e7d..ad6191f6 100755 --- a/tools/x86_fsp/tgl/tgl_download_fsp.sh +++ b/tools/scripts/x86_fsp/tgl/tgl_download_fsp.sh @@ -3,18 +3,23 @@ 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 -FSP_COMMIT_ID=6f5ae9679e662353bc5570a1bc89e137e262155f +FSP_COMMIT_ID=cfdf71ddce304e411e46d88f5ef635c6a515a54d FSP_URL=https://github.com/intel/FSP/raw/${FSP_COMMIT_ID}/TigerLakeFspBinPkg/TGL_IOT/Fsp.fd FSP_REPO=https://github.com/intel/FSP.git UCODE_URL=https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/raw/6f36ebde4519f8a21a047c3433b80a3fb41361e1/intel-ucode/06-8c-01 SCRIPT_DIR=$(readlink -f "$(dirname "$0")") -WOLFBOOT_DIR="${SCRIPT_DIR}/../../.." +WOLFBOOT_DIR="$(pwd)" FSP_PREFIX=Fsp CONFIG_FILE=${CONFIG_FILE:-"${WOLFBOOT_DIR}/.config"} PATCH="${SCRIPT_DIR}/0001-FSP-wolfboot-patch.patch" set -e +if [ ! -f "${WOLFBOOT_DIR}/arch.mk" ]; then + echo "Error: Current directory is not the root directory of the source tree" + exit 1 +fi + if [ ! -d "$WORK_DIR" ]; then mkdir -p "$WORK_DIR" fi diff --git a/tools/x86_fsp/tpm_install_policy.sh b/tools/scripts/x86_fsp/tpm_install_policy.sh similarity index 100% rename from tools/x86_fsp/tpm_install_policy.sh rename to tools/scripts/x86_fsp/tpm_install_policy.sh diff --git a/tools/tpm/policy_sign.c b/tools/tpm/policy_sign.c index 0b7ee812..47a1f591 100644 --- a/tools/tpm/policy_sign.c +++ b/tools/tpm/policy_sign.c @@ -205,7 +205,7 @@ static void printHexString(const unsigned char* bin, unsigned long sz, printf("\t"); for (i = 0; i < sz; i++) { printf("%02x", bin[i]); - if (((i+1) % maxLine) == 0 && i+1 != sz) + if (maxLine > 0 && ((i+1) % maxLine) == 0 && i+1 != sz) printf("\n\t"); } printf("\n"); diff --git a/tools/x86_fsp/qemu/make_hd.sh b/tools/x86_fsp/qemu/make_hd.sh deleted file mode 100755 index ef5ea6dc..00000000 --- a/tools/x86_fsp/qemu/make_hd.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -SIGN=${SIGN:-"--ecc256"} -HASH=${HASH:-"--sha256"} - -IMAGE=${IMAGE:-"bzImage"} - -set -e - -dd if=/dev/zero of=app.bin bs=1M count=64 -/sbin/fdisk app.bin <