mirror of https://github.com/wolfSSL/wolfBoot.git
commit
027c6847e5
|
@ -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
|
|
@ -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
|
||||
|
|
17
arch.mk
17
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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
184
docs/Targets.md
184
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.
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
|
@ -23,10 +23,66 @@
|
|||
#include <stdint.h>
|
||||
#include <uart_drv.h>
|
||||
#include <printf.h>
|
||||
#include <x86/tgl_fsp.h>
|
||||
#include <pci.h>
|
||||
#include <x86/common.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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 = .;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 <stdint.h>
|
||||
|
||||
int setup_interrupt_gate(int vnum, uintptr_t handler);
|
||||
int setup_interrupts();
|
||||
void deinit_interrupts();
|
||||
void wfi();
|
||||
|
||||
#endif /* EXCEPTIONS_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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <x86/paging.h>
|
||||
#include <pci.h>
|
||||
#include <target.h>
|
||||
#include <stage1.h>
|
||||
#include <stage2_params.h>
|
||||
|
||||
#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.
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <x86/common.h>
|
||||
|
||||
#include <printf.h>
|
||||
#include <stage1.h>
|
||||
#include <stage2_params.h>
|
||||
#include <x86/mptable.h>
|
||||
|
||||
#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();
|
||||
|
|
|
@ -151,6 +151,7 @@ TempRamInitSuccess:
|
|||
[section .reset_vector]
|
||||
BITS 16
|
||||
ALIGN 16
|
||||
global reset_vector
|
||||
reset_vector:
|
||||
nop
|
||||
nop
|
||||
|
|
14
src/elf.c
14
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;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <multiboot.h>
|
||||
|
||||
#ifdef WOLFBOOT_FSP
|
||||
#include <stage1.h>
|
||||
#include <stage2_params.h>
|
||||
#endif
|
||||
|
||||
#define MB2_HEADER_MAX_OFF (32768 - 4)
|
||||
|
|
96
src/pci.c
96
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;
|
||||
|
|
|
@ -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 <stage2_params.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* 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
|
19
src/tpm.c
19
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 */
|
||||
|
|
|
@ -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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
@ -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_ */
|
||||
|
|
141
src/x86/ahci.c
141
src/x86/ahci.c
|
@ -45,7 +45,7 @@
|
|||
#include <tpm.h>
|
||||
|
||||
#if defined(WOLFBOOT_FSP)
|
||||
#include <stage1.h>
|
||||
#include <stage2_params.h>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/coding.h>
|
||||
|
@ -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",
|
||||
|
|
155
src/x86/ata.c
155
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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 <x86/common.h>
|
||||
#include <x86/exceptions.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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 <printf.h>
|
||||
#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();
|
||||
}
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
#ifndef GPT_C
|
||||
#define GPT_C
|
||||
#include <stdint.h>
|
||||
#include <x86/common.h>
|
||||
#include <x86/ahci.h>
|
||||
#include <x86/ata.h>
|
||||
|
@ -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 */
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#ifdef WOLFBOOT_FSP
|
||||
#include <x86/hob.h>
|
||||
#include <stage1.h>
|
||||
#include <stage2_params.h>
|
||||
#endif /* WOLFBOOT_FSP */
|
||||
|
||||
#define ENDLINE "\r\n"
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <x86/hob.h>
|
||||
#include <uart_drv.h>
|
||||
#include <x86/ahci.h>
|
||||
#include <stage2_params.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
1100
src/x86/tgl_fsp.c
1100
src/x86/tgl_fsp.c
File diff suppressed because it is too large
Load Diff
|
@ -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 $^ $@
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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 <printf.h>
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
|
@ -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 = .;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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('<HH', data[:4])
|
||||
if l == 0:
|
||||
return None
|
||||
if t == WOLFBOOT_SHA_HDR:
|
||||
return data[4:4+l]
|
||||
data = data[4+l:]
|
||||
|
||||
def get_keystore_sym_addr() -> 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())
|
|
@ -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)")
|
|
@ -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 <<EOF
|
||||
g
|
||||
n
|
||||
1
|
||||
|
||||
+16M
|
||||
n
|
||||
|
||||
|
||||
+16M
|
||||
x
|
||||
n
|
||||
1
|
||||
OFP_A
|
||||
n
|
||||
2
|
||||
OFP_B
|
||||
r
|
||||
w
|
||||
EOF
|
||||
|
||||
cp ${IMAGE} "image.bin"
|
||||
tools/keytools/sign $SIGN $HASH image.bin wolfboot_signing_private_key.der 1
|
||||
tools/keytools/sign $SIGN $HASH image.bin wolfboot_signing_private_key.der 2
|
||||
dd if=image_v1_signed.bin of=app.bin bs=512 seek=2048 conv=notrunc
|
||||
dd if=image_v2_signed.bin of=app.bin bs=512 seek=34816 conv=notrunc
|
|
@ -0,0 +1,122 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
#By default, the script will run without waiting for GDB. If you use the
|
||||
# -w parameter, it will wait for GDB to connect.
|
||||
|
||||
# Usage:
|
||||
|
||||
|
||||
# For DEBUG_STAGE1 without waiting for GDB: ./qemu.sh -d DEBUG_STAGE1
|
||||
# For DEBUG_STAGE2 without waiting for GDB (default): ./qemu.sh
|
||||
# For DEBUG_STAGE1 with waiting for GDB: ./qemu.sh -d DEBUG_STAGE1 -w
|
||||
# For DEBUG_STAGE2 with waiting for GDB: ./qemu.sh -w
|
||||
|
||||
|
||||
# To DEBUG_STAGE1
|
||||
# $ gdb stage1/loader_stage1.elf
|
||||
# target remote :1234
|
||||
# b start
|
||||
# c
|
||||
|
||||
# To DEBUG_STAGE2
|
||||
# $ gdb wolfboot.elf
|
||||
# target remote :1234
|
||||
# b main
|
||||
# c
|
||||
|
||||
|
||||
## TPM emulator:
|
||||
# https://github.com/stefanberger/swtpm
|
||||
# sudo apt install swtpm
|
||||
|
||||
# Default values
|
||||
DEBUG_STAGE="DEBUG_STAGE2"
|
||||
WAIT_FOR_GDB=false
|
||||
|
||||
echo "Running wolfBoot on QEMU"
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Parse command line options
|
||||
while getopts "d:wpt" opt; do
|
||||
case "$opt" in
|
||||
d)
|
||||
DEBUG_STAGE="$OPTARG"
|
||||
;;
|
||||
w)
|
||||
WAIT_FOR_GDB=true
|
||||
;;
|
||||
p)
|
||||
CREATE_PIPE=true
|
||||
;;
|
||||
t) ENABLE_TPM=true
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [-d DEBUG_STAGE1 | DEBUG_STAGE2] [-w] [-p]"
|
||||
echo "-p : create /tmp/qemu_mon.in and /tmp/qemu_mon.out pipes for monitor qemu"
|
||||
echo "-w : wait for GDB to connect to the QEMU gdb server"
|
||||
echo "-t : enable TPM emulation (requires swtpm)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
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 -nographic \
|
||||
-pflash wolfboot_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \
|
||||
-device ide-hd,drive=mydisk \
|
||||
"
|
||||
|
||||
if [ "$CREATE_PIPE" = true ]; then
|
||||
rm /tmp/qemu_mon.in /tmp/qemu_mon.out || true &> /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
|
|
@ -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() {
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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");
|
||||
|
|
|
@ -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 <<EOF
|
||||
g
|
||||
n
|
||||
1
|
||||
|
||||
+16M
|
||||
n
|
||||
|
||||
|
||||
+16M
|
||||
w
|
||||
EOF
|
||||
# copy bzImage in the root folder
|
||||
tools/keytools/sign $SIGN $HASH ${IMAGE} wolfboot_signing_private_key.der 1
|
||||
tools/keytools/sign $SIGN $HASH ${IMAGE} wolfboot_signing_private_key.der 2
|
||||
dd if=${IMAGE}_v1_signed.bin of=app.bin bs=512 seek=2048 conv=notrunc
|
||||
dd if=${IMAGE}_v2_signed.bin of=app.bin bs=512 seek=34816 conv=notrunc
|
Loading…
Reference in New Issue