Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: start payload through DRTM #521

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ payloads/external/U-Boot/u-boot/
payloads/external/Memtest86Plus/memtest86plus/
payloads/external/iPXE/ipxe/
payloads/external/sortbootorder/sortbootorder
payloads/external/skl/secure-kernel-loader/
util/crossgcc/acpica-unix-*/
util/crossgcc/binutils-*/
util/crossgcc/build-*BINUTILS/
Expand Down
27 changes: 27 additions & 0 deletions configs/config.pcengines_apu2_drtm_payload
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
CONFIG_LOCALVERSION="v4.9.0.4"
CONFIG_VENDOR_PCENGINES=y
CONFIG_FMDFILE="$(top)/src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd"
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000
CONFIG_BOARD_PCENGINES_APU2=y
CONFIG_BOTTOMIO_POSITION=0xD0000000
CONFIG_UART_PCI_ADDR=0x0
CONFIG_LAUNCH_DRTM_PAYLOAD=y
CONFIG_HUDSON_SATA_MODE=2
CONFIG_AGESA_BINARY_PI_LOCATION=0xFFE00000
CONFIG_NO_GFX_INIT=y
CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
CONFIG_I2C_TRANSFER_TIMEOUT_US=500000
CONFIG_SMMSTORE_V2=y
CONFIG_SMMSTORE_SIZE=0x40000
CONFIG_TPM2=y
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y
CONFIG_POST_IO_PORT=0x80
CONFIG_PAYLOAD_TIANOCORE=y
CONFIG_TIANOCORE_CUSTOM=y
CONFIG_TIANOCORE_REPOSITORY="https://github.com/3mdeb/edk2"
CONFIG_TIANOCORE_TAG_OR_REV="origin/drtm_payload"
CONFIG_TIANOCORE_DEBUG=y
CONFIG_TIANOCORE_CUSTOM_BUILD_PARAMS="-DSECURE_BOOT_ENABLE -DNETWORK_ENABLE -DSHELL_TYPE=BUILD_SHELL -DSERIAL_TERMINAL=TRUE"
CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
CONFIG_SORTBOOTORDER_MASTER=y
11 changes: 11 additions & 0 deletions payloads/external/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,14 @@ doom.wad-file := $(strip $(CONFIG_COREDOOM_WAD_FILE))
doom.wad-type := raw
doom.wad-compression := $(CBFS_SECONDARY_PAYLOAD_COMPRESS_FLAG)
endif

# SKL

payloads/external/skl/secure-kernel-loader/skl.bin:
$(MAKE) -C payloads/external/skl CC="$(HOSTCC)"

cbfs-files-$(CONFIG_LAUNCH_DRTM_PAYLOAD) += $(CONFIG_CBFS_PREFIX)/drtm_payload
$(CONFIG_CBFS_PREFIX)/drtm_payload-file := payloads/external/skl/secure-kernel-loader/skl.bin
$(CONFIG_CBFS_PREFIX)/drtm_payload-type := raw
$(CONFIG_CBFS_PREFIX)/drtm_payload-compression := $(CBFS_PAYLOAD_COMPRESS_FLAG)
$(CONFIG_CBFS_PREFIX)/drtm_payload-options := $(ADDITIONAL_PAYLOAD_CONFIG)
20 changes: 20 additions & 0 deletions payloads/external/skl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## SPDX-License-Identifier: GPL-2.0-only
project_git_repo=https://github.com/TrenchBoot/secure-kernel-loader.git
project_dir=secure-kernel-loader

all: skl

checkout:
test -d $(project_dir) || \
git clone $(project_git_repo) $(project_dir)

skl: checkout
$(MAKE) -C $(project_dir) DEBUG=y

clean:
test -d $(project_dir) && $(MAKE) -C $(project_dir) clean || exit 0

distclean:
rm -rf $(project_dir)

.PHONY: checkout skl clean distclean
10 changes: 6 additions & 4 deletions src/cpu/amd/pi/00730F01/model_16_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ static void model_16_init(struct device *dev)
msr.hi &= ~(1 << (46 - 32));
wrmsr(NB_CFG_MSR, msr);

/* Write protect SMM space with SMMLOCK. */
msr = rdmsr(HWCR_MSR);
msr.lo |= (1 << 0);
wrmsr(HWCR_MSR, msr);
/* Write protect SMM space with SMMLOCK, or let SMI handler do it if any. */
if (!CONFIG(HAVE_SMI_HANDLER)) {
msr = rdmsr(HWCR_MSR);
msr.lo |= (1 << 0);
wrmsr(HWCR_MSR, msr);
}

amd_update_microcode_from_cbfs();

Expand Down
21 changes: 20 additions & 1 deletion src/cpu/amd/pi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ config CPU_AMD_PI
select UDELAY_LAPIC
select LAPIC_MONOTONIC_TIMER
select SPI_FLASH if HAVE_ACPI_RESUME
select NO_SMM
select SMM_TSEG
select PARALLEL_MP_AP_WORK
select SOC_AMD_COMMON_BLOCK_SMM
select SOC_AMD_COMMON_BLOCK_SMI
select SOC_AMD_COMMON_BLOCK_ACPI
select SSE2

if CPU_AMD_PI
Expand All @@ -35,6 +39,21 @@ config DCACHE_BSP_STACK_SIZE
hex
default 0x4000

config SMM_MODULE_STACK_SIZE
default 0x800

config SMM_TSEG_SIZE
default 0x100000 if HAVE_SMI_HANDLER
default 0

config LAUNCH_DRTM_PAYLOAD
bool "Launch DRTM payload before the real one"
default n
depends on MEMORY_MAPPED_TPM
help
Launch DRTM payload before the real one. This makes it possible to
put root of trust in hardware for platforms that don't support SRTM.

endif # CPU_AMD_PI

source "src/cpu/amd/pi/00730F01/Kconfig"
2 changes: 2 additions & 0 deletions src/cpu/amd/pi/Makefile.inc
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only

subdirs-$(CONFIG_CPU_AMD_PI_00730F01) += 00730F01

ramstage-$(CONFIG_LAUNCH_DRTM_PAYLOAD) += skinit.c
145 changes: 145 additions & 0 deletions src/cpu/amd/pi/skinit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <cbfs.h>
#include <cpu/x86/lapic.h>
#include <program_loading.h>
#include <stdlib.h>
#include <security/tpm/tis.h>
#include <cpu/amd/msr.h>

#include <lib.h>

static uintptr_t payload_start, payload_size;

/* For SELF, prog->start and prog->size are not set so obtain it differently. */
void platform_segment_loaded(uintptr_t start, size_t size, int flags)
{
/* FIXME: need to differentiate between payload and other loaded segments */
if (/*payload_start != 0 || payload_size != 0 || */flags != SEG_FINAL)
die("ELF payload must have only one loadable segment for DRTM!\n");

payload_start = start;
payload_size = size;
}

/* TODO: include tags.h from SKL somehow */
#define SKL_TAG_CLASS_MASK 0xF0

/* Tags with no particular class */
#define SKL_TAG_NO_CLASS 0x00
#define SKL_TAG_END 0x00
#define SKL_TAG_SETUP_INDIRECT 0x01
#define SKL_TAG_TAGS_SIZE 0x0F /* Always first */

/* Tags specifying kernel type */
#define SKL_TAG_BOOT_CLASS 0x10
#define SKL_TAG_BOOT_LINUX 0x10
#define SKL_TAG_BOOT_MB2 0x11
#define SKL_TAG_BOOT_SIMPLE 0x12

struct skl_tag_hdr {
uint8_t type;
uint8_t len;
} __packed;

struct skl_tag_tags_size {
struct skl_tag_hdr hdr;
uint16_t size;
} __packed;

struct skl_tag_boot_simple_payload {
struct skl_tag_hdr hdr;
uint32_t base;
uint32_t size;
uint32_t entry;
uint32_t arg;
} __packed;

struct skl_tag_evtlog {
struct skl_tag_hdr hdr;
uint32_t address;
uint32_t size;
} __packed;

struct skl_tag_hash {
struct skl_tag_hdr hdr;
uint16_t algo_id;
uint8_t digest[];
} __packed;

static inline void *next_tag(void* t)
{
void *x = t + ((struct skl_tag_hdr*)t)->len;
return x;
}

void platform_prog_run(struct prog *prog)
{
void *skl = NULL;
uint16_t bootloader_data_offset;
struct skl_tag_tags_size *tags;
struct skl_tag_boot_simple_payload *sp;
struct skl_tag_hdr *end;

/*
* Check if we're on 32b platform.
* TODO: add support for 64b?
*/
assert(sizeof(skl) == 4);

hexdump(prog, sizeof(*prog));

/*
* APs have to be in wait-for-SIPI state for at least 1000 cycles before
* SKINIT. Send INIT now and assume that loading SKL from CBFS is long
* enough.
*/
lapic_send_ipi_others(LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT);

skl = memalign(64*KiB, 64*KiB);

cbfs_load(CONFIG_CBFS_PREFIX "/drtm_payload", skl, 64*KiB);

bootloader_data_offset = ((uint16_t *)skl)[1];
tags = (struct skl_tag_tags_size *)(skl + bootloader_data_offset);

memset(tags, 0, 64*KiB - (skl - (void *)tags));

tags->hdr.type = SKL_TAG_TAGS_SIZE;
tags->hdr.len = sizeof(struct skl_tag_tags_size);
tags->size += tags->hdr.len;

sp = next_tag(tags);
sp->hdr.type = SKL_TAG_BOOT_SIMPLE;
sp->hdr.len = sizeof(struct skl_tag_boot_simple_payload);
sp->base = payload_start;
sp->size = payload_size;
sp->entry = (uint32_t)prog->entry;
sp->arg = (uint32_t)prog->arg;
tags->size += sp->hdr.len;

/* TODO: DRTM TPM event log and SKL hash(es) */

end = next_tag(sp);
end->type = SKL_TAG_END;
end->len = sizeof(struct skl_tag_hdr);
tags->size += end->len;

msr_t msr;

msr = rdmsr(SMM_BASE_MSR);
printk(BIOS_DEBUG, "SMM_BASE_MSR = %#8.8x%8.8x\n", msr.hi, msr.lo);

msr = rdmsr(SMM_ADDR_MSR);
printk(BIOS_DEBUG, "SMM_ADDR_MSR = %#8.8x%8.8x\n", msr.hi, msr.lo);

msr = rdmsr(SMM_MASK_MSR);
printk(BIOS_DEBUG, "SMM_MASK_MSR = %#8.8x%8.8x\n", msr.hi, msr.lo);

msr = rdmsr(HWCR_MSR);
printk(BIOS_DEBUG, "HWCR_MSR = %#8.8x%8.8x\n", msr.hi, msr.lo);

tis_close();

asm volatile ("skinit" :: "a"(skl));
}
3 changes: 3 additions & 0 deletions src/cpu/x86/lapic/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ bootblock-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
romstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
ramstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
postcar-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
# Use TSC for SMM, should be safer than LAPIC after OS takes over
smm-$(CONFIG_UDELAY_LAPIC) += ../tsc/delay_tsc.c

bootblock-y += boot_cpu.c
verstage_x86-y += boot_cpu.c
romstage-y += boot_cpu.c
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/x86/tsc/delay_tsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void udelay(unsigned int us)
}
}

#if CONFIG(TSC_MONOTONIC_TIMER)
#if CONFIG(TSC_MONOTONIC_TIMER) || (CONFIG(LAPIC_MONOTONIC_TIMER) && ENV_SMM)
#include <timer.h>

static struct monotonic_counter {
Expand Down
2 changes: 2 additions & 0 deletions src/drivers/uart/uart8250io.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ uintptr_t uart_platform_base(unsigned int idx)
return 0;
}

__weak int check_com2(void) { return 0; }

void uart_init(unsigned int idx)
{
if (!CONFIG(DRIVERS_UART_8250IO_SKIP_INIT)) {
Expand Down
1 change: 1 addition & 0 deletions src/mainboard/pcengines/apu2/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ config BOARD_SPECIFIC_OPTIONS
select PCIEXP_CLK_PM
select PCIEXP_COMMON_CLOCK
select PCIEXP_L1_SUB_STATE
select HAVE_SMI_HANDLER

config MAINBOARD_DIR
default "pcengines/apu2"
Expand Down
3 changes: 3 additions & 0 deletions src/mainboard/pcengines/apu2/bios_knobs.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ static u8 check_knob_value(const char *s)

u8 check_iommu(void)
{
if (CONFIG(LAUNCH_DRTM_PAYLOAD))
return 1;

u8 iommu;
iommu = check_knob_value("iommu");

Expand Down
4 changes: 2 additions & 2 deletions src/mainboard/pcengines/apu2/board.fmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ FLASH 8M {
SI_BIOS@0x0 0x800000 {
BOOTORDER(PRESERVE)@0x0 0x1000
RW_VPD(PRESERVE)@0x1000 0x4000
SMMSTORE(PRESERVE)@0x5000 0x20000
RW_UNUSED@0x25000 0x1db000
SMMSTORE(PRESERVE)@0x10000 0x40000
RW_UNUSED@0x50000 0x1b0000
WP_RO@0x200000 0x600000{
RO_VPD(PRESERVE)@0x0 0x4000
RO_SECTION@0x4000 0x5fc000{
Expand Down
5 changes: 5 additions & 0 deletions src/northbridge/amd/pi/00730F01/northbridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#include "mainboard/pcengines/apu2/bios_knobs.h"

#include <amdblocks/smm.h>

#define MAX_NODE_NUMS MAX_NODES
#define PCIE_CAP_AER BIT(5)
#define PCIE_CAP_ACS BIT(6)
Expand Down Expand Up @@ -982,6 +984,9 @@ static int get_cpu_count(void)
static const struct mp_ops mp_ops = {
.pre_mp_init = pre_mp_init,
.get_cpu_count = get_cpu_count,
.relocation_handler = smm_relocation_handler,
.get_smm_info = get_smm_info,
.post_mp_init = global_smi_enable,
};

void mp_init_cpus(struct bus *cpu_bus)
Expand Down
4 changes: 2 additions & 2 deletions src/northbridge/amd/pi/00730F01/state_machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ void platform_AfterInitPost(struct sysinfo *cb, AMD_POST_PARAMS *Post)
* UMA may or may not be cacheable, so Sub4GCacheTop could be
* higher than UmaBase. With UMA_NONE we see UmaBase==0. */
if (Post->MemConfig.UmaBase)
backup_top_of_low_cacheable(Post->MemConfig.UmaBase << 16);
backup_top_of_low_cacheable((Post->MemConfig.UmaBase << 16) - CONFIG_SMM_TSEG_SIZE);
else
backup_top_of_low_cacheable(Post->MemConfig.Sub4GCacheTop);
backup_top_of_low_cacheable(Post->MemConfig.Sub4GCacheTop - CONFIG_SMM_TSEG_SIZE);
}

void platform_BeforeInitEnv(struct sysinfo *cb, AMD_ENV_PARAMS *Env)
Expand Down
1 change: 1 addition & 0 deletions src/southbridge/amd/pi/hudson/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ all-y += reset.c

smm-y += smihandler.c
smm-y += smi_util.c
smm-y += lpc_simpledev.c

# ROMSIG At ROMBASE + 0x20000:
# +-----------+---------------+----------------+------------+
Expand Down
7 changes: 0 additions & 7 deletions src/southbridge/amd/pi/hudson/hudson.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@
#include "smi.h"
#include "fchec.h"

int acpi_get_sleep_type(void)
{
u16 tmp = inw(ACPI_PM1_CNT_BLK);
tmp = ((tmp & (7 << 10)) >> 10);
return (int)tmp;
}

void hudson_enable(struct device *dev)
{
printk(BIOS_DEBUG, "%s()\n", __func__);
Expand Down
Loading