2 changes: 2 additions & 0 deletions payloads/external/depthcharge/Makefile
Expand Up @@ -68,6 +68,8 @@ $(libpayload_install_dir): $(project_dir)
false)
echo $(DEPTHCHARGE_LIBPAYLOAD_MSG)
cp $(libpayload_config) $(libpayload_dir)/.config
(grep -q '^\s*CONFIG_LP_CHROMEOS=' $(libpayload_dir)/.config) || \
(echo "CONFIG_LP_CHROMEOS=y" >> $(libpayload_dir)/.config)
$(MAKE) -C $(libpayload_dir) olddefconfig
$(MAKE) -C $(libpayload_dir)
$(MAKE) -C $(libpayload_dir) install DESTDIR=$(libpayload_install_dir)
Expand Down
2 changes: 0 additions & 2 deletions payloads/external/tianocore/Makefile
Expand Up @@ -86,8 +86,6 @@ endif

bootloader = $(word 8,$(subst /, ,$(BUILD_STR)))

export EDK_TOOLS_PATH=$(project_dir)/BaseTools

all: clean build

$(project_dir):
Expand Down
1 change: 0 additions & 1 deletion payloads/libpayload/drivers/video/graphics.c
Expand Up @@ -57,7 +57,6 @@ static const struct cb_framebuffer *fbinfo;
#define PIVOT_H_MASK (PIVOT_H_LEFT|PIVOT_H_CENTER|PIVOT_H_RIGHT)
#define PIVOT_V_MASK (PIVOT_V_TOP|PIVOT_V_CENTER|PIVOT_V_BOTTOM)
#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
#define ABS(x) ((x) < 0 ? -(x) : (x))

static char initialized = 0;

Expand Down
41 changes: 22 additions & 19 deletions payloads/libpayload/include/coreboot_tables.h
Expand Up @@ -83,17 +83,15 @@ enum {
CB_TAG_BOARD_CONFIG = 0x0040,
CB_TAG_ACPI_CNVS = 0x0041,
CB_TAG_TYPE_C_INFO = 0x0042,
CB_TAG_ACPI_RSDP = 0x0043,
CB_TAG_CMOS_OPTION_TABLE = 0x00c8,
CB_TAG_OPTION = 0x00c9,
CB_TAG_OPTION_ENUM = 0x00ca,
CB_TAG_OPTION_DEFAULTS = 0x00cb,
CB_TAG_OPTION_CHECKSUM = 0x00cc,
};

struct cbuint64 {
u32 lo;
u32 hi;
};
typedef __aligned(4) uint64_t cb_uint64_t;

struct cb_header {
u8 signature[4];
Expand All @@ -110,8 +108,8 @@ struct cb_record {
};

struct cb_memory_range {
struct cbuint64 start;
struct cbuint64 size;
cb_uint64_t start;
cb_uint64_t size;
u32 type;
};

Expand Down Expand Up @@ -270,14 +268,14 @@ struct cb_gpios {
struct lb_range {
uint32_t tag;
uint32_t size;
uint64_t range_start;
cb_uint64_t range_start;
uint32_t range_size;
};

struct cb_cbmem_tab {
uint32_t tag;
uint32_t size;
uint64_t cbmem_tab;
cb_uint64_t cbmem_tab;
};

struct cb_x86_rom_mtrr {
Expand Down Expand Up @@ -315,18 +313,18 @@ struct cb_boot_media_params {
uint32_t tag;
uint32_t size;
/* offsets are relative to start of boot media */
uint64_t fmap_offset;
uint64_t cbfs_offset;
uint64_t cbfs_size;
uint64_t boot_media_size;
cb_uint64_t fmap_offset;
cb_uint64_t cbfs_offset;
cb_uint64_t cbfs_size;
cb_uint64_t boot_media_size;
};


struct cb_cbmem_entry {
uint32_t tag;
uint32_t size;

uint64_t address;
cb_uint64_t address;
uint32_t entry_size;
uint32_t id;
};
Expand Down Expand Up @@ -368,7 +366,7 @@ struct cb_board_config {
uint32_t tag;
uint32_t size;

struct cbuint64 fw_config;
cb_uint64_t fw_config;
uint32_t board_id;
uint32_t ram_code;
uint32_t sku_id;
Expand Down Expand Up @@ -422,12 +420,17 @@ struct cb_cmos_checksum {
u32 type;
};

/* Helpful inlines */
/*
* Handoff the ACPI RSDP
*/
struct cb_acpi_rsdp {
uint32_t tag;
uint32_t size;
cb_uint64_t rsdp_pointer; /* Address of the ACPI RSDP */
};

static inline u64 cb_unpack64(struct cbuint64 val)
{
return (((u64) val.hi) << 32) | val.lo;
}

/* Helpful inlines */

static inline u16 cb_checksum(const void *ptr, unsigned len)
{
Expand Down
26 changes: 1 addition & 25 deletions payloads/libpayload/include/libpayload.h
Expand Up @@ -46,6 +46,7 @@
#include <libpayload-config.h>
#include <cbgfx.h>
#include <commonlib/bsd/fmap_serialized.h>
#include <commonlib/bsd/helpers.h>
#include <commonlib/bsd/mem_chip_info.h>
#include <ctype.h>
#include <die.h>
Expand All @@ -67,33 +68,8 @@
#include <pci.h>
#include <archive.h>

/* Double-evaluation unsafe min/max, for bitfields and outside of functions */
#define __CMP_UNSAFE(a, b, op) ((a) op (b) ? (a) : (b))
#define MIN_UNSAFE(a, b) __CMP_UNSAFE(a, b, <)
#define MAX_UNSAFE(a, b) __CMP_UNSAFE(a, b, >)

#define __CMP_SAFE(a, b, op, var_a, var_b) ({ \
__TYPEOF_UNLESS_CONST(a, b) var_a = (a); \
__TYPEOF_UNLESS_CONST(b, a) var_b = (b); \
var_a op var_b ? var_a : var_b; \
})

#define __CMP(a, b, op) __builtin_choose_expr( \
__builtin_constant_p(a) && __builtin_constant_p(b), \
__CMP_UNSAFE(a, b, op), __CMP_SAFE(a, b, op, __TMPNAME, __TMPNAME))

#define MIN(a, b) __CMP(a, b, <)
#define MAX(a, b) __CMP(a, b, >)

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define BIT(x) (1ul << (x))

#define DIV_ROUND_UP(x, y) ({ \
typeof(x) _div_local_x = (x); \
typeof(y) _div_local_y = (y); \
(_div_local_x + _div_local_y - 1) / _div_local_y; \
})

static inline u32 div_round_up(u32 n, u32 d) { return (n + d - 1) / d; }

#define LITTLE_ENDIAN 1234
Expand Down
17 changes: 1 addition & 16 deletions payloads/libpayload/include/stddef.h
Expand Up @@ -2,6 +2,7 @@
#define _STDDEF_H

#include <arch/types.h>
#include <commonlib/bsd/helpers.h>

#ifndef __WCHAR_TYPE__
#define __WCHAR_TYPE__ int
Expand All @@ -22,22 +23,6 @@ typedef __SIZE_TYPE__ size_t;
typedef __SIZE_TYPE__ ssize_t;
#undef unsigned

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
#define member_size(TYPE, MEMBER) (sizeof(((TYPE *) 0)->MEMBER))

#define check_member(structure, member, offset) _Static_assert( \
offsetof(struct structure, member) == offset, \
"`struct " #structure "` offset for `" #member "` is not " #offset)

/* Standard units. */
#define KiB (1 << 10)
#define MiB (1 << 20)
#define GiB (1 << 30)

#define KHz (1000)
#define MHz (1000*KHz)
#define GHz (1000*MHz)

#define NSECS_PER_SEC 1000000000
#define USECS_PER_SEC 1000000
#define MSECS_PER_SEC 1000
Expand Down
6 changes: 0 additions & 6 deletions payloads/libpayload/include/stdlib.h
Expand Up @@ -34,12 +34,6 @@
#include <stddef.h>
#include <string.h>

#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1UL)
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
#define ALIGN_UP(x,a) ALIGN((x),(a))
#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL))
#define IS_ALIGNED(x,a) (((x) & ((typeof(x))(a)-1UL)) == 0)

/**
* @defgroup malloc Memory allocation functions
* @{
Expand Down
1 change: 1 addition & 0 deletions payloads/libpayload/include/sysinfo.h
Expand Up @@ -111,6 +111,7 @@ struct sysinfo_t {
uintptr_t mrc_cache;
uintptr_t acpi_gnvs;
uintptr_t acpi_cnvs;
uintptr_t acpi_rsdp;

#define UNDEFINED_STRAPPING_ID (~0)
#define UNDEFINED_FW_CONFIG ~((uint64_t)0)
Expand Down
19 changes: 12 additions & 7 deletions payloads/libpayload/libc/coreboot.c
Expand Up @@ -61,12 +61,8 @@ static void cb_parse_memory(void *ptr, struct sysinfo_t *info)
continue;
#endif

info->memrange[info->n_memranges].base =
cb_unpack64(range->start);

info->memrange[info->n_memranges].size =
cb_unpack64(range->size);

info->memrange[info->n_memranges].base = range->start;
info->memrange[info->n_memranges].size = range->size;
info->memrange[info->n_memranges].type = range->type;

info->n_memranges++;
Expand Down Expand Up @@ -121,7 +117,7 @@ static void cb_parse_mac_addresses(unsigned char *ptr,
static void cb_parse_board_config(unsigned char *ptr, struct sysinfo_t *info)
{
struct cb_board_config *const config = (struct cb_board_config *)ptr;
info->fw_config = cb_unpack64(config->fw_config);
info->fw_config = config->fw_config;
info->board_id = config->board_id;
info->ram_code = config->ram_code;
info->sku_id = config->sku_id;
Expand Down Expand Up @@ -268,6 +264,12 @@ static void cb_parse_cbmem_entry(void *ptr, struct sysinfo_t *info)
}
}

static void cb_parse_rsdp(void *ptr, struct sysinfo_t *info)
{
const struct cb_acpi_rsdp *cb_acpi_rsdp = ptr;
info->acpi_rsdp = cb_acpi_rsdp->rsdp_pointer;
}

int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
{
struct cb_header *header;
Expand Down Expand Up @@ -408,6 +410,9 @@ int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
cb_parse_tsc_info(ptr, info);
break;
#endif
case CB_TAG_ACPI_RSDP:
cb_parse_rsdp(ptr, info);
break;
default:
cb_parse_arch_specific(rec, info);
break;
Expand Down
7 changes: 4 additions & 3 deletions payloads/libpayload/vboot/Makefile.inc
Expand Up @@ -8,10 +8,11 @@ vboot_fw-objs += $(VBOOT_FW_LIB)
tlcl-objs += $(TLCL_LIB)

kconfig-to-binary=$(if $(strip $(1)),1,0)
vboot-fixup-includes = $(patsubst -I%,-I$(top)/%,\
vboot-fixup-includes = $(filter -I$(coreboottop)/%, $(1)) \
$(patsubst -I%,-I$(top)/%,\
$(patsubst include/%.h,$(top)/include/%.h,\
$(filter-out -I$(obj),$(1))))

$(filter-out -I$(obj),\
$(filter-out -I$(coreboottop)/%,$(1)))))
ifeq ($(CONFIG_LP_ARCH_MOCK),)
VBOOT_CFLAGS += $(call vboot-fixup-includes,$(CFLAGS))
VBOOT_CFLAGS += -I$(abspath $(obj))
Expand Down
2 changes: 1 addition & 1 deletion src/Kconfig
Expand Up @@ -1210,7 +1210,7 @@ config DEBUG_ADA_CODE
`pragma Debug`.

config HAVE_EM100_SUPPORT
bool "Platform can support the Dediprog EM100 SPI emulator"
bool
help
This is enabled by platforms which can support using the EM100.

Expand Down
4 changes: 4 additions & 0 deletions src/acpi/acpigen_dptf.c
Expand Up @@ -74,6 +74,10 @@ static const char *namestring_of(enum dptf_participant participant)
return "TSR4";
case DPTF_TPCH:
return "TPCH";
case DPTF_POWER:
return "TPWR";
case DPTF_BATTERY:
return "TBAT";
default:
return "";
}
Expand Down
13 changes: 13 additions & 0 deletions src/acpi/device.c
Expand Up @@ -670,6 +670,19 @@ void acpi_device_add_power_res(const struct acpi_power_res_params *params)

/* Method (_ON, 0, Serialized) */
acpigen_write_method_serialized("_ON", 0);
/* Call _STA and early return if the device is already enabled, since the Linux
kernel doesn't check the device status before calling _ON. This avoids
unnecessary delays while booting. */
if (params->use_gpio_for_status) {
/* Local0 = _STA () */
acpigen_write_store();
acpigen_emit_namestring("_STA");
acpigen_emit_byte(LOCAL0_OP);
/* If (( Local0 == ACPI_POWER_RESOURCE_STATUS_ON_OP)) */
acpigen_write_if_lequal_op_op(LOCAL0_OP, ACPI_POWER_RESOURCE_STATUS_ON_OP);
acpigen_write_return_op(ZERO_OP);
acpigen_write_if_end();
}
if (reset_gpio)
acpigen_enable_tx_gpio(params->reset_gpio);
if (enable_gpio) {
Expand Down
16 changes: 0 additions & 16 deletions src/arch/x86/Kconfig
Expand Up @@ -118,22 +118,6 @@ config SIPI_VECTOR_IN_ROM
default n
depends on ARCH_X86

# Set the rambase for systems that still need it, only 5 chipsets as of
# Sep 2018. This value was 0x100000, chosen to match the entry point
# of Linux 2.2 in 1999. The new value, 14 MiB, makes a lot more sense
# for as long as we need it; with luck, that won't be much longer.
# In the long term, both RAMBASE and RAMTOP should be removed.
# This value leaves more than 1 MiB which is required for fam10
# and broadwell_de.
config RAMBASE
hex
default 0xe00000

config RAMTOP
hex
default 0x1000000
depends on ARCH_X86

# Traditionally BIOS region on SPI flash boot media was memory mapped right below
# 4G and it was the last region in the IFD. This way translation between CPU
# address space to flash address was trivial. However some IFDs on newer SoCs
Expand Down
14 changes: 14 additions & 0 deletions src/arch/x86/exit_car.S
Expand Up @@ -35,6 +35,18 @@ post_car_stack_top:
.endm
#endif

/* Place the stack in the bss section. It's not necessary to define it in the
* the linker script. */
.section .bss, "aw", @nobits
.global _stack
.global _estack
.global _stack_size

_stack:
.space CONFIG_STACK_SIZE
_estack:
.set _stack_size, _estack - _stack

.text
.global _start
_start:
Expand Down Expand Up @@ -174,8 +186,10 @@ skip_clflush:
wrmsr
#endif /* CONFIG_SOC_SETS_MSRS */

movl $_estack, %esp
/* Align stack to 16 bytes at call instruction. */
andl $0xfffffff0, %esp

/* Call into main for postcar. */
call main
/* Should never return. */
Expand Down
4 changes: 0 additions & 4 deletions src/arch/x86/include/arch/memlayout.h
Expand Up @@ -3,10 +3,6 @@
#ifndef __ARCH_MEMLAYOUT_H
#define __ARCH_MEMLAYOUT_H

#if (CONFIG_RAMTOP == 0)
# error "CONFIG_RAMTOP not configured"
#endif

/* Intel386 psABI requires a 16 byte aligned stack. */
#define ARCH_STACK_ALIGN_SIZE 16

Expand Down
3 changes: 2 additions & 1 deletion src/arch/x86/memlayout.ld
Expand Up @@ -13,7 +13,8 @@ SECTIONS
* conditionalize with macros.
*/
#if ENV_RAMSTAGE
RAMSTAGE(CONFIG_RAMBASE, 8M)
/* Relocated at runtime in cbmem so the address does not matter. */
RAMSTAGE(64M, 8M)

#elif ENV_ROMSTAGE
/* The 1M size is not allocated. It's just for basic size checking.
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86/postcar_loader.c
Expand Up @@ -60,7 +60,7 @@ static void postcar_var_mtrr_set(const struct var_mtrr_context *ctx,
struct postcar_frame *pcf = ctx->arg;

printk(BIOS_DEBUG, "MTRR Range: Start=%lx End=%lx (Size %zx)\n",
addr, addr + size, size);
addr, addr + size - 1, size);

stack_push(pcf, mask.hi);
stack_push(pcf, mask.lo);
Expand Down
6 changes: 6 additions & 0 deletions src/commonlib/bsd/include/commonlib/bsd/helpers.h
Expand Up @@ -126,4 +126,10 @@
#define retry(attempts, condition, ...) \
_retry_impl(attempts, condition, __VA_ARGS__)

/* Stringify a token */
#ifndef STRINGIFY
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
#endif

#endif /* COMMONLIB_BSD_HELPERS_H */
7 changes: 7 additions & 0 deletions src/commonlib/bsd/include/commonlib/bsd/mem_chip_info.h
Expand Up @@ -3,6 +3,8 @@
#ifndef _COMMONLIB_BSD_MEM_CHIP_INFO_H_
#define _COMMONLIB_BSD_MEM_CHIP_INFO_H_

#include <stddef.h>

enum mem_chip_type {
MEM_CHIP_DDR3 = 0x30,
MEM_CHIP_LPDDR3 = 0x38,
Expand All @@ -25,4 +27,9 @@ struct mem_chip_info {
} channel[0];
};

static inline size_t mem_chip_info_size(struct mem_chip_info *info)
{
return sizeof(*info) + sizeof(info->channel[0]) * info->num_channels;
};

#endif /* _COMMONLIB_BSD_MEM_CHIP_INFO_H_ */
56 changes: 17 additions & 39 deletions src/commonlib/include/commonlib/coreboot_tables.h
Expand Up @@ -99,33 +99,11 @@ enum {
* 64bit system, a uint64_t would be aligned to 64bit boundaries,
* breaking the table format.
*
* lb_uint64 will keep 64bit coreboot table values aligned to 32bit
* to ensure compatibility. They can be accessed with the two functions
* below: unpack_lb64() and pack_lb64()
*
* See also: util/lbtdump/lbtdump.c
* lb_uint64_t will keep 64bit coreboot table values aligned to 32bit
* to ensure compatibility.
*/

struct lb_uint64 {
uint32_t lo;
uint32_t hi;
};

static inline uint64_t unpack_lb64(struct lb_uint64 value)
{
uint64_t result;
result = value.hi;
result = (result << 32) + value.lo;
return result;
}

static inline struct lb_uint64 pack_lb64(uint64_t value)
{
struct lb_uint64 result;
result.lo = (value >> 0) & 0xffffffff;
result.hi = (value >> 32) & 0xffffffff;
return result;
}
typedef __aligned(4) uint64_t lb_uint64_t;

struct lb_header {
uint8_t signature[4]; /* LBIO */
Expand All @@ -148,8 +126,8 @@ struct lb_record {
};

struct lb_memory_range {
struct lb_uint64 start;
struct lb_uint64 size;
lb_uint64_t start;
lb_uint64_t size;
uint32_t type;
#define LB_MEM_RAM 1 /* Memory anyone can use */
#define LB_MEM_RESERVED 2 /* Don't use this memory region */
Expand All @@ -169,7 +147,7 @@ struct lb_memory {
struct lb_hwrpb {
uint32_t tag;
uint32_t size;
uint64_t hwrpb;
lb_uint64_t hwrpb;
};

struct lb_mainboard {
Expand Down Expand Up @@ -237,7 +215,7 @@ struct lb_console {
struct lb_forward {
uint32_t tag;
uint32_t size;
uint64_t forward;
lb_uint64_t forward;
};

/**
Expand Down Expand Up @@ -295,7 +273,7 @@ struct lb_framebuffer {
uint32_t tag;
uint32_t size;

uint64_t physical_address;
lb_uint64_t physical_address;
uint32_t x_resolution;
uint32_t y_resolution;
uint32_t bytes_per_line;
Expand Down Expand Up @@ -333,7 +311,7 @@ struct lb_range {
uint32_t tag;
uint32_t size;

uint64_t range_start;
lb_uint64_t range_start;
uint32_t range_size;
};

Expand All @@ -343,7 +321,7 @@ struct lb_cbmem_ref {
uint32_t tag;
uint32_t size;

uint64_t cbmem_addr;
lb_uint64_t cbmem_addr;
};

struct lb_x86_rom_mtrr {
Expand Down Expand Up @@ -379,10 +357,10 @@ struct lb_boot_media_params {
uint32_t tag;
uint32_t size;
/* offsets are relative to start of boot media */
uint64_t fmap_offset;
uint64_t cbfs_offset;
uint64_t cbfs_size;
uint64_t boot_media_size;
lb_uint64_t fmap_offset;
lb_uint64_t cbfs_offset;
lb_uint64_t cbfs_size;
lb_uint64_t boot_media_size;
};

/*
Expand All @@ -392,7 +370,7 @@ struct lb_cbmem_entry {
uint32_t tag;
uint32_t size;

uint64_t address;
lb_uint64_t address;
uint32_t entry_size;
uint32_t id;
};
Expand Down Expand Up @@ -461,7 +439,7 @@ struct lb_board_config {
uint32_t tag;
uint32_t size;

struct lb_uint64 fw_config;
lb_uint64_t fw_config;
uint32_t board_id;
uint32_t ram_code;
uint32_t sku_id;
Expand Down Expand Up @@ -583,7 +561,7 @@ struct lb_tpm_physical_presence {
struct lb_acpi_rsdp {
uint32_t tag;
uint32_t size;
struct lb_uint64 rsdp_pointer; /* Address of the ACPI RSDP */
lb_uint64_t rsdp_pointer; /* Address of the ACPI RSDP */
};

#endif
286 changes: 154 additions & 132 deletions src/commonlib/include/commonlib/timestamp_serialized.h

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/cpu/intel/fit/Makefile.inc
Expand Up @@ -13,7 +13,7 @@ intel_fit-align := 16

$(call add_intermediate, set_fit_ptr, $(IFITTOOL))
@printf " UPDATE-FIT set FIT pointer to table\n"
$(IFITTOOL) -f $< -F -n intel_fit -r COREBOOT
$(IFITTOOL) -f $< -F -n intel_fit -r COREBOOT -c

FIT_ENTRY=$(call strip_quotes, $(CONFIG_INTEL_TOP_SWAP_FIT_ENTRY_FMAP_REG))

Expand Down
4 changes: 4 additions & 0 deletions src/cpu/x86/Kconfig
@@ -1,3 +1,5 @@
if ARCH_X86

config PARALLEL_MP
def_bool y
depends on !LEGACY_SMP_INIT
Expand Down Expand Up @@ -194,3 +196,5 @@ config CPU_INFO_V2
Enables the new method of locating struct cpu_info. This new method
uses the %gs segment to locate the cpu_info pointer. The old method
relied on the stack being CONFIG_STACK_SIZE aligned.

endif # ARCH_X86
4 changes: 4 additions & 0 deletions src/cpu/x86/Kconfig.debug_cpu
@@ -1,3 +1,5 @@
if ARCH_X86

config HAVE_DEBUG_CAR
bool

Expand All @@ -11,3 +13,5 @@ config DISPLAY_MTRRS
config DEBUG_SMM_RELOCATION
bool "Debug SMM relocation code"
depends on HAVE_SMI_HANDLER && SMM_ASEG

endif # ARCH_X86
4 changes: 1 addition & 3 deletions src/cpu/x86/mp_init.c
Expand Up @@ -247,11 +247,9 @@ static int save_bsp_msrs(char *start, int size)
int num_var_mtrrs;
struct saved_msr *msr_entry;
int i;
msr_t msr;

/* Determine number of MTRRs need to be saved. */
msr = rdmsr(MTRR_CAP_MSR);
num_var_mtrrs = msr.lo & 0xff;
num_var_mtrrs = get_var_mtrr_count();

/* 2 * num_var_mtrrs for base and mask. +1 for IA32_MTRR_DEF_TYPE. */
msr_count = 2 * num_var_mtrrs + NUM_FIXED_MTRRS + 1;
Expand Down
5 changes: 5 additions & 0 deletions src/cpu/x86/mtrr/Makefile.inc
@@ -1,5 +1,10 @@
ramstage-y += mtrr.c

ramstage-y += mtrrlib.c
romstage-y += mtrrlib.c
bootblock-y += mtrrlib.c
verstage_x86-y += mtrrlib.c

romstage-y += earlymtrr.c
bootblock-y += earlymtrr.c
verstage_x86-y += earlymtrr.c
Expand Down
60 changes: 0 additions & 60 deletions src/cpu/x86/mtrr/earlymtrr.c
Expand Up @@ -6,66 +6,6 @@
#include <console/console.h>
#include <commonlib/bsd/helpers.h>

/* Get first available variable MTRR.
* Returns var# if available, else returns -1.
*/
int get_free_var_mtrr(void)
{
msr_t maskm;
int vcnt;
int i;

vcnt = get_var_mtrr_count();

/* Identify the first var mtrr which is not valid. */
for (i = 0; i < vcnt; i++) {
maskm = rdmsr(MTRR_PHYS_MASK(i));
if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0)
return i;
}

/* No free var mtrr. */
return -1;
}

void set_var_mtrr(
unsigned int reg, unsigned int base, unsigned int size,
unsigned int type)
{
/* Bit 32-35 of MTRRphysMask should be set to 1 */
/* FIXME: It only support 4G less range */
msr_t basem, maskm;

if (!IS_POWER_OF_2(size))
printk(BIOS_ERR, "MTRR Error: size %#x is not a power of two\n", size);
if (size < 4 * KiB)
printk(BIOS_ERR, "MTRR Error: size %#x smaller than 4KiB\n", size);
if (base % size != 0)
printk(BIOS_ERR, "MTRR Error: base %#x must be aligned to size %#x\n", base,
size);

basem.lo = base | type;
basem.hi = 0;
wrmsr(MTRR_PHYS_BASE(reg), basem);
maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1;
wrmsr(MTRR_PHYS_MASK(reg), maskm);
}

void clear_all_var_mtrr(void)
{
msr_t mtrr = {0, 0};
int vcnt;
int i;

vcnt = get_var_mtrr_count();

for (i = 0; i < vcnt; i++) {
wrmsr(MTRR_PHYS_MASK(i), mtrr);
wrmsr(MTRR_PHYS_BASE(i), mtrr);
}
}

void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg)
{
ctx->upper_mask = (1U << (cpu_phys_address_size() - 32)) - 1;
Expand Down
21 changes: 11 additions & 10 deletions src/cpu/x86/mtrr/mtrr.c
Expand Up @@ -41,11 +41,7 @@ static int total_mtrrs;

static void detect_var_mtrrs(void)
{
msr_t msr;

msr = rdmsr(MTRR_CAP_MSR);

total_mtrrs = msr.lo & 0xff;
total_mtrrs = get_var_mtrr_count();

if (total_mtrrs > NUM_MTRR_STATIC_STORAGE) {
printk(BIOS_WARNING,
Expand Down Expand Up @@ -158,7 +154,7 @@ static void print_physical_address_space(const struct memranges *addr_space,
memranges_each_entry(r, addr_space)
printk(BIOS_DEBUG,
"0x%016llx - 0x%016llx size 0x%08llx type %ld\n",
range_entry_base(r), range_entry_end(r),
range_entry_base(r), range_entry_end(r) - 1,
range_entry_size(r), range_entry_tag(r));
}

Expand Down Expand Up @@ -276,7 +272,7 @@ static void calc_fixed_mtrrs(void)
type = range_entry_tag(r);
printk(MTRR_VERBOSE_LEVEL,
"MTRR addr 0x%x-0x%x set to %d type @ %d\n",
begin, begin + desc->step, type, type_index);
begin, begin + desc->step - 1, type, type_index);
if (type == MTRR_TYPE_WRBACK)
type |= MTRR_FIXED_WRBACK_BITS;
fixed_mtrr_types[type_index] = type;
Expand Down Expand Up @@ -864,6 +860,11 @@ void x86_mtrr_check(void)

static bool put_back_original_solution;

void need_restore_mtrr(void)
{
put_back_original_solution = true;
}

void mtrr_use_temp_range(uintptr_t begin, size_t size, int type)
{
const struct range_entry *r;
Expand Down Expand Up @@ -904,10 +905,10 @@ void mtrr_use_temp_range(uintptr_t begin, size_t size, int type)

if (commit_var_mtrrs(&sol) < 0)
printk(BIOS_WARNING, "Unable to insert temporary MTRR range: 0x%016llx - 0x%016llx size 0x%08llx type %d\n",
(long long)begin, (long long)begin + size,
(long long)begin, (long long)begin + size - 1,
(long long)size, type);
else
put_back_original_solution = true;
need_restore_mtrr();

memranges_teardown(&addr_space);
}
Expand All @@ -919,4 +920,4 @@ static void remove_temp_solution(void *unused)
}

BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, remove_temp_solution, NULL);
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, remove_temp_solution, NULL);
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, remove_temp_solution, NULL);
65 changes: 65 additions & 0 deletions src/cpu/x86/mtrr/mtrrlib.c
@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
#include <console/console.h>

/* Get first available variable MTRR.
* Returns var# if available, else returns -1.
*/
int get_free_var_mtrr(void)
{
msr_t maskm;
int vcnt;
int i;

vcnt = get_var_mtrr_count();

/* Identify the first var mtrr which is not valid. */
for (i = 0; i < vcnt; i++) {
maskm = rdmsr(MTRR_PHYS_MASK(i));
if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0)
return i;
}

/* No free var mtrr. */
return -1;
}

void set_var_mtrr(
unsigned int reg, unsigned int base, unsigned int size, unsigned int type)
{
/* Bit 32-35 of MTRRphysMask should be set to 1 */
/* FIXME: It only support 4G less range */
msr_t basem, maskm;

if (!IS_POWER_OF_2(size))
printk(BIOS_ERR, "MTRR Error: size %#x is not a power of two\n", size);
if (size < 4 * KiB)
printk(BIOS_ERR, "MTRR Error: size %#x smaller than 4KiB\n", size);
if (base % size != 0)
printk(BIOS_ERR, "MTRR Error: base %#x must be aligned to size %#x\n", base,
size);

basem.lo = base | type;
basem.hi = 0;
wrmsr(MTRR_PHYS_BASE(reg), basem);
maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1;
wrmsr(MTRR_PHYS_MASK(reg), maskm);
}

void clear_all_var_mtrr(void)
{
msr_t mtrr = {0, 0};
int vcnt;
int i;

vcnt = get_var_mtrr_count();

for (i = 0; i < vcnt; i++) {
wrmsr(MTRR_PHYS_MASK(i), mtrr);
wrmsr(MTRR_PHYS_BASE(i), mtrr);
}
}
3 changes: 1 addition & 2 deletions src/cpu/x86/mtrr/xip_cache.c
Expand Up @@ -14,8 +14,7 @@
the MTRR, no matter the caching type, are filled and not overlapping. */
static uint32_t max_cache_used(void)
{
msr_t msr = rdmsr(MTRR_CAP_MSR);
int i, total_mtrrs = msr.lo & MTRR_CAP_VCNT;
int i, total_mtrrs = get_var_mtrr_count();
uint32_t total_cache = 0;

for (i = 0; i < total_mtrrs; i++) {
Expand Down
24 changes: 6 additions & 18 deletions src/cpu/x86/smm/smm_module_loader.c
Expand Up @@ -126,38 +126,26 @@ static int smm_create_map(uintptr_t smbase, unsigned int num_cpus,
}

for (i = 0; i < num_cpus; i++) {
printk(BIOS_DEBUG, "CPU 0x%x\n", i);
cpus[i].smbase = base;
cpus[i].entry = base + smm_entry_offset;
printk(BIOS_DEBUG, " smbase %lx entry %lx\n", cpus[i].smbase,
cpus[i].entry);
cpus[i].ss_start = cpus[i].entry + (smm_entry_offset - ss_size);
cpus[i].code_start = cpus[i].entry;
cpus[i].code_end = cpus[i].entry + stub_size;
printk(BIOS_DEBUG, " ss_start %lx code_end %lx\n", cpus[i].ss_start,
cpus[i].code_end);
cpus[i].active = 1;
base -= ss_size;
seg_count++;
if (seg_count >= cpus_in_segment) {
base -= smm_entry_offset;
seg_count = 0;
printk(BIOS_DEBUG, "-------------NEW CODE SEGMENT --------------\n");
}
}

if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) {
seg_count = 0;
for (i = 0; i < num_cpus; i++) {
printk(BIOS_DEBUG, "CPU 0x%x\n", i);
printk(BIOS_DEBUG,
" smbase %lx entry %lx\n",
cpus[i].smbase, cpus[i].entry);
printk(BIOS_DEBUG,
" ss_start %lx code_end %lx\n",
cpus[i].ss_start, cpus[i].code_end);
seg_count++;
if (seg_count >= cpus_in_segment) {
printk(BIOS_DEBUG,
"-------------NEW CODE SEGMENT --------------\n");
seg_count = 0;
}
}
}
return 1;
}

Expand Down
39 changes: 39 additions & 0 deletions src/cpu/x86/smm/smm_stub.S
Expand Up @@ -45,10 +45,49 @@ fallback_stack_top:
(CR0_CD | CR0_NW | CR0_PG | CR0_AM | CR0_WP | \
CR0_NE | CR0_TS | CR0_EM | CR0_MP)

#define SMM_DEFAULT_SIZE 0x10000

.text
.code16
.global _start
_start:
smm_handler_start:
#if CONFIG(SMM_LAPIC_REMAP_MITIGATION)
/* Check if the LAPIC register block overlaps with the stub.
* This block needs to work without data accesses because they
* may be routed into the LAPIC register block.
* Code accesses, on the other hand, are never routed to LAPIC,
* which is what makes this work in the first place.
*/
mov $LAPIC_BASE_MSR, %ecx
rdmsr
and $(~0xfff), %eax
call 1f
/* Get the current program counter */
1:
pop %ebx
sub %ebx, %eax
cmp $(SMM_DEFAULT_SIZE), %eax
ja untampered_lapic
1:
#if CONFIG(CONSOLE_SERIAL)
/* emit "Crash" on serial */
mov $(CONFIG_TTYS0_BASE), %dx
mov $'C', %al
out %al, (%dx)
mov $'r', %al
out %al, (%dx)
mov $'a', %al
out %al, (%dx)
mov $'s', %al
out %al, (%dx)
mov $'h', %al
out %al, (%dx)
#endif /* CONFIG_CONSOLE_SERIAL */
/* now crash for real */
ud2
untampered_lapic:
#endif
movl $(smm_relocate_gdt), %ebx
lgdtl (%ebx)

Expand Down
2 changes: 1 addition & 1 deletion src/device/i2c_bus.c
Expand Up @@ -6,7 +6,7 @@
#include <device/i2c_bus.h>
#include <commonlib/endian.h>

struct bus *i2c_link(struct device *const dev)
struct bus *i2c_link(const struct device *const dev)
{
if (!dev || !dev->bus)
return NULL;
Expand Down
2 changes: 2 additions & 0 deletions src/device/pci_device.c
Expand Up @@ -1518,6 +1518,8 @@ static void pci_bridge_route(struct bus *link, scan_state state)
primary = parent->secondary;
secondary = link->secondary;
subordinate = link->subordinate;
} else {
return;
}

if (state == PCI_ROUTE_SCAN) {
Expand Down
1 change: 1 addition & 0 deletions src/device/pciexp_device.c
Expand Up @@ -589,6 +589,7 @@ static void pciexp_hotplug_dummy_read_resources(struct device *dev)

static struct device_operations pciexp_hotplug_dummy_ops = {
.read_resources = pciexp_hotplug_dummy_read_resources,
.set_resources = noop_set_resources,
};

void pciexp_hotplug_scan_bridge(struct device *dev)
Expand Down
3 changes: 1 addition & 2 deletions src/drivers/amd/agesa/mtrr_fixme.c
Expand Up @@ -14,8 +14,7 @@ static void set_range_uc(u32 base, u32 size)
{
int i, max_var_mtrrs;
msr_t msr;
msr = rdmsr(MTRR_CAP_MSR);
max_var_mtrrs = msr.lo & MTRR_CAP_VCNT;
max_var_mtrrs = get_var_mtrr_count();

for (i = 0; i < max_var_mtrrs; i++) {
msr = rdmsr(MTRR_PHYS_MASK(i));
Expand Down
8 changes: 4 additions & 4 deletions src/drivers/amd/agesa/romstage.c
Expand Up @@ -38,17 +38,17 @@ static void romstage_main(void)
struct sysinfo *cb = &romstage_state;
int cbmem_initted = 0;

fill_sysinfo(cb);

timestamp_add_now(TS_ROMSTAGE_START);

board_BeforeAgesa(cb);

console_init();

printk(BIOS_DEBUG, "APIC %02u: CPU Family_Model = %08x\n",
initial_lapicid(), cpuid_eax(1));

fill_sysinfo(cb);

board_BeforeAgesa(cb);

set_ap_entry_ptr(ap_romstage_main);

agesa_execute_state(cb, AMD_INIT_RESET);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/designware/dw_i2c.c
Expand Up @@ -570,7 +570,7 @@ static enum cb_err dw_i2c_gen_config_rise_fall_time(struct dw_i2c_regs *regs,
printk(DW_I2C_DEBUG, "dw_i2c: SoC %d/%d ns Bus: %d/%d ns\n",
soc->freq.ticks, soc->freq.ns, bus->freq.ticks, bus->freq.ns);
printk(DW_I2C_DEBUG,
" dw_i2c: period %d rise %d fall %d tlow %d thigh %d spk %d\n",
"dw_i2c: period %d rise %d fall %d tlow %d thigh %d spk %d\n",
period_cnt, rise_cnt, fall_cnt, min_tlow_cnt, min_thigh_cnt,
spk_cnt);

Expand Down
9 changes: 9 additions & 0 deletions src/drivers/i2c/tpm/Kconfig
Expand Up @@ -24,6 +24,15 @@ config MAINBOARD_HAS_I2C_TPM_GENERIC
help
Board has a generic I2C TPM support

config MAINBOARD_NEEDS_I2C_TI50_WORKAROUND
bool
default n
help
Ti50 FW versions below 0.15 don't support the firmware_version or board_cfg registers,
and trying to access them causes I2C errors. This config will skip accesses to these
registers, and should be selected for boards using Ti50 chips with FW < 0.15. The config
will be removed once all Ti50 stocks are updated to 0.15 or higher.

config DRIVER_TIS_DEFAULT
bool
depends on I2C_TPM
Expand Down
4 changes: 3 additions & 1 deletion src/drivers/i2c/tpm/cr50.c
Expand Up @@ -500,7 +500,9 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
printk(BIOS_DEBUG, "cr50 TPM 2.0 (i2c %u:0x%02x id 0x%x)\n",
bus, dev_addr, did_vid >> 16);

if (tpm_first_access_this_boot()) {
/* Ti50 FW version under 0.15 doesn't support board cfg command
TODO: remove this flag after all stocks Ti50 uprev to 0.15 or above */
if (!CONFIG(MAINBOARD_NEEDS_I2C_TI50_WORKAROUND) && tpm_first_access_this_boot()) {
/* This is called for the side-effect of printing the version string. */
cr50_get_firmware_version(&ver);
cr50_set_board_cfg();
Expand Down
14 changes: 14 additions & 0 deletions src/drivers/intel/dptf/Kconfig
Expand Up @@ -12,3 +12,17 @@ config DRIVERS_INTEL_DPTF_SUPPORTS_TPCH
help
When enabled, chip driver/intel/dptf will publish information to the
SSDT for the TPCH device.

config DRIVERS_INTEL_DPTF_SUPPORTS_TPWR
def_bool n
depends on DRIVERS_INTEL_DPTF
help
When enabled, chip driver/intel/dptf will publish information to the
SSDT for TPWR device.

config DRIVERS_INTEL_DPTF_SUPPORTS_TBAT
def_bool n
depends on DRIVERS_INTEL_DPTF
help
When enabled, chip driver/intel/dptf will publish information to the
SSDT for TBAT device.
48 changes: 48 additions & 0 deletions src/drivers/intel/dptf/dptf.c
Expand Up @@ -14,10 +14,14 @@ enum dptf_generic_participant_type {
DPTF_GENERIC_PARTICIPANT_TYPE_TSR = 0x3,
DPTF_GENERIC_PARTICIPANT_TYPE_TPCH = 0x5,
DPTF_GENERIC_PARTICIPANT_TYPE_CHARGER = 0xB,
DPTF_GENERIC_PARTICIPANT_TYPE_BATTERY = 0xC,
DPTF_GENERIC_PARTICIPANT_TYPE_POWER = 0x11,
};

#define DEFAULT_CHARGER_STR "Battery Charger"
#define DEFAULT_TPCH_STR "Intel PCH FIVR Participant"
#define DEFAULT_POWER_STR "Power Participant"
#define DEFAULT_BATTERY_STR "Battery Participant"

#define PMC_IPC_COMMAND_FIVR_SIZE 0x8

Expand Down Expand Up @@ -368,6 +372,44 @@ static void write_tpch_methods(const struct dptf_platform_info *platform_info)
acpigen_write_device_end(); /* TPCH Device */
}

static void write_create_tpwr(const struct dptf_platform_info *platform_info)
{
acpigen_write_device("TPWR");
acpigen_write_name("_HID");
if (platform_info->tpwr_device_hid != NULL)
dptf_write_hid(platform_info->use_eisa_hids, platform_info->tpwr_device_hid);
acpigen_write_name_string("_UID", "TPWR");
acpigen_write_name_string("_STR", DEFAULT_POWER_STR);
acpigen_write_name_integer("PTYP", DPTF_GENERIC_PARTICIPANT_TYPE_POWER);
acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
acpigen_write_device_end(); /* TPWR Power Participant Device */
}

static void write_tpwr_methods(const struct dptf_platform_info *platform_info)
{
write_create_tpwr(platform_info);
}

static void write_create_tbat(const struct dptf_platform_info *platform_info)
{
acpigen_write_device("TBAT");
acpigen_write_name("_HID");
if (platform_info->tbat_device_hid != NULL)
dptf_write_hid(platform_info->use_eisa_hids, platform_info->tbat_device_hid);
acpigen_write_name_string("_UID", "TBAT");
acpigen_write_name_string("_STR", DEFAULT_BATTERY_STR);
acpigen_write_name_integer("PTYP", DPTF_GENERIC_PARTICIPANT_TYPE_BATTERY);
acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
acpigen_write_device_end(); /* TBAT Battery Participant Device */
}


static void write_tbat_methods(const struct dptf_platform_info *platform_info)
{
write_create_tbat(platform_info);
}


/* \_SB.DPTF - note: leaves the Scope open for child devices */
static void write_open_dptf_device(const struct device *dev,
const struct dptf_platform_info *platform_info)
Expand Down Expand Up @@ -406,6 +448,12 @@ static void write_device_definitions(const struct device *dev)
if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TPCH))
write_tpch_methods(platform_info);

if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TPWR))
write_tpwr_methods(platform_info);

if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TBAT))
write_tbat_methods(platform_info);

acpigen_pop_len(); /* DPTF Device (write_open_dptf_device) */
acpigen_pop_len(); /* Scope */
}
Expand Down
2 changes: 2 additions & 0 deletions src/drivers/intel/dptf/dptf.h
Expand Up @@ -15,6 +15,8 @@ struct dptf_platform_info {
const char *generic_hid;
const char *fan_hid;
const char *tpch_device_hid;
const char *tpwr_device_hid;
const char *tbat_device_hid;
struct {
const char *set_fivr_low_clock_method;
const char *set_fivr_high_clock_method;
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/fsp1_1/exit_car.S
Expand Up @@ -7,7 +7,7 @@ chipset_teardown_car:

pop %ebx
/* Move the stack pointer to real RAM */
movl post_car_stack_top, %esp
movl _estack, %esp
/* Align the stack 16 bytes */
andl $0xfffffff0, %esp

Expand Down
51 changes: 8 additions & 43 deletions src/drivers/intel/fsp1_1/hob.c
Expand Up @@ -24,7 +24,7 @@ void *get_hob_list(void)
}

/* Returns the next instance of a HOB type from the starting HOB. */
void *get_next_hob(uint16_t type, const void *hob_start)
static void *get_next_hob(uint16_t type, const void *hob_start)
{
EFI_PEI_HOB_POINTERS hob;

Expand All @@ -44,14 +44,8 @@ void *get_next_hob(uint16_t type, const void *hob_start)
return NULL;
}

/* Returns the first instance of a HOB type among the whole HOB list. */
void *get_first_hob(uint16_t type)
{
return get_next_hob(type, get_hob_list());
}

/* Returns the next instance of the matched GUID HOB from the starting HOB. */
void *get_next_guid_hob(const EFI_GUID *guid, const void *hob_start)
void *get_guid_hob(const EFI_GUID *guid, const void *hob_start)
{
EFI_PEI_HOB_POINTERS hob;

Expand All @@ -65,18 +59,10 @@ void *get_next_guid_hob(const EFI_GUID *guid, const void *hob_start)
return hob.Raw;
}

/*
* Returns the first instance of the matched GUID HOB among the whole HOB list.
*/
void *get_first_guid_hob(const EFI_GUID *guid)
{
return get_next_guid_hob(guid, get_hob_list());
}

/*
* Returns the next instance of the matching resource HOB from the starting HOB.
*/
void *get_next_resource_hob(const EFI_GUID *guid, const void *hob_start)
void *get_resource_hob(const EFI_GUID *guid, const void *hob_start)
{
EFI_PEI_HOB_POINTERS hob;

Expand All @@ -90,15 +76,6 @@ void *get_next_resource_hob(const EFI_GUID *guid, const void *hob_start)
return hob.Raw;
}

/*
* Returns the first instance of the matching resource HOB among the whole HOB
* list.
*/
void *get_first_resource_hob(const EFI_GUID *guid)
{
return get_next_resource_hob(guid, get_hob_list());
}

static void print_hob_mem_attributes(void *hob_ptr)
{
EFI_MEMORY_TYPE hob_mem_type;
Expand Down Expand Up @@ -257,21 +234,19 @@ static const char *get_hob_type_string(void *hob_ptr)
*/
void print_hob_type_structure(u16 hob_type, void *hob_list_ptr)
{
u32 *current_hob;
u32 *next_hob = 0;
u8 last_hob = 0;
void *current_hob;
u32 current_type;
const char *current_type_str;

current_hob = hob_list_ptr;

/*
* Print out HOBs of our desired type until
* the end of the HOB list
*/
printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
printk(BIOS_DEBUG, "%p: hob_list_ptr\n", hob_list_ptr);
do {
for (current_hob = hob_list_ptr; !END_OF_HOB_LIST(current_hob);
current_hob = GET_NEXT_HOB(current_hob)) {

EFI_HOB_GENERIC_HEADER *current_header_ptr =
(EFI_HOB_GENERIC_HEADER *)current_hob;

Expand All @@ -292,16 +267,6 @@ void print_hob_type_structure(u16 hob_type, void *hob_list_ptr)
break;
}
}

/* Check for end of HOB list */
last_hob = END_OF_HOB_LIST(current_hob);
if (!last_hob) {
/* Get next HOB pointer */
next_hob = GET_NEXT_HOB(current_hob);

/* Start on next HOB */
current_hob = next_hob;
}
} while (!last_hob);
}
printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
}
10 changes: 2 additions & 8 deletions src/drivers/intel/fsp1_1/include/fsp/util.h
Expand Up @@ -24,10 +24,7 @@ void fsp_early_init(FSP_INFO_HEADER *fsp_info);
void fsp_notify(u32 phase);
void print_hob_type_structure(u16 hob_type, void *hob_list_ptr);
void print_fsp_info(FSP_INFO_HEADER *fsp_header);
void *get_next_type_guid_hob(UINT16 type, const EFI_GUID *guid,
const void *hob_start);
void *get_next_resource_hob(const EFI_GUID *guid, const void *hob_start);
void *get_first_resource_hob(const EFI_GUID *guid);
void *get_resource_hob(const EFI_GUID *guid, const void *hob_start);
void fsp_display_upd_value(const char *name, uint32_t size, uint64_t old,
uint64_t new);
void report_fsp_output(void);
Expand Down Expand Up @@ -80,10 +77,7 @@ extern void *FspHobListPtr;
#endif

void *get_hob_list(void);
void *get_next_hob(uint16_t type, const void *hob_start);
void *get_first_hob(uint16_t type);
void *get_next_guid_hob(const EFI_GUID *guid, const void *hob_start);
void *get_first_guid_hob(const EFI_GUID *guid);
void *get_guid_hob(const EFI_GUID *guid, const void *hob_start);

asmlinkage void chipset_teardown_car_main(void);

Expand Down
10 changes: 5 additions & 5 deletions src/drivers/intel/fsp1_1/raminit.c
Expand Up @@ -120,7 +120,7 @@ void raminit(struct romstage_params *params)

/* Locate the FSP reserved memory area */
fsp_reserved_bytes = 0;
fsp_memory = get_next_resource_hob(&fsp_reserved_guid, hob_list_ptr);
fsp_memory = get_resource_hob(&fsp_reserved_guid, hob_list_ptr);
if (fsp_memory == NULL) {
fsp_verification_failure = 1;
printk(BIOS_ERR,
Expand Down Expand Up @@ -155,7 +155,7 @@ void raminit(struct romstage_params *params)
fsp_set_runtime(fsp_header, hob_list_ptr);

/* Lookup the FSP_BOOTLOADER_TOLUM_HOB */
cbmem_root = get_next_resource_hob(&bootldr_tolum_guid, hob_list_ptr);
cbmem_root = get_resource_hob(&bootldr_tolum_guid, hob_list_ptr);
if (cbmem_root == NULL) {
fsp_verification_failure = 1;
printk(BIOS_ERR, "7.4: FSP_BOOTLOADER_TOLUM_HOB missing!\n");
Expand All @@ -164,7 +164,7 @@ void raminit(struct romstage_params *params)
}

/* Locate the FSP_SMBIOS_MEMORY_INFO HOB */
memory_info_hob = get_next_guid_hob(&memory_info_hob_guid,
memory_info_hob = get_guid_hob(&memory_info_hob_guid,
hob_list_ptr);
if (memory_info_hob == NULL) {
printk(BIOS_ERR, "FSP_SMBIOS_MEMORY_INFO HOB missing!\n");
Expand All @@ -185,7 +185,7 @@ void raminit(struct romstage_params *params)
* 7.5: EFI_PEI_GRAPHICS_INFO_HOB produced by SiliconInit
* FSP_SMBIOS_MEMORY_INFO HOB verified above
*/
hob_ptr.Raw = get_next_guid_hob(&mrc_guid, hob_list_ptr);
hob_ptr.Raw = get_guid_hob(&mrc_guid, hob_list_ptr);
if ((hob_ptr.Raw == NULL) && (params->saved_data == NULL)) {
printk(BIOS_ERR, "7.3: FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
fsp_verification_failure = 1;
Expand Down Expand Up @@ -236,7 +236,7 @@ void raminit(struct romstage_params *params)
"ERROR - coreboot's requirements not met by FSP binary!\n");

/* Locate the memory configuration data to speed up the next reboot */
mrc_hob = get_next_guid_hob(&mrc_guid, hob_list_ptr);
mrc_hob = get_guid_hob(&mrc_guid, hob_list_ptr);
if (mrc_hob == NULL) {
printk(BIOS_DEBUG,
"Memory Configuration Data Hob not present\n");
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/intel/fsp1_1/ramstage.c
Expand Up @@ -38,7 +38,7 @@ static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
* FSP_SMBIOS_MEMORY_INFO HOB verified by raminit
*/
if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) &&
!get_next_guid_hob(&graphics_info_guid, hob_list_ptr) &&
!get_guid_hob(&graphics_info_guid, hob_list_ptr) &&
CONFIG(DISPLAY_HOBS)) {
printk(BIOS_ERR, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
printk(BIOS_ERR, "Missing one or more required FSP HOBs!\n");
Expand Down Expand Up @@ -117,7 +117,7 @@ static void fsp_run_silicon_init(FSP_INFO_HEADER *fsp_info_header)
u32 *vbt_hob;

void *hob_list_ptr = get_hob_list();
vbt_hob = get_next_guid_hob(&vbt_guid, hob_list_ptr);
vbt_hob = get_guid_hob(&vbt_guid, hob_list_ptr);
if (vbt_hob == NULL) {
printk(BIOS_ERR, "FSP_ERR: Graphics Data HOB is not present\n");
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/fsp1_1/romstage.c
Expand Up @@ -152,7 +152,7 @@ __weak void mainboard_save_dimm_info(

/* Locate the memory info HOB, presence validated by raminit */
hob_list_ptr = fsp_get_hob_list();
hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
hob_ptr = get_guid_hob(&memory_info_hob_guid, hob_list_ptr);
memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);

/* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
Expand Down
29 changes: 29 additions & 0 deletions src/drivers/intel/fsp2_0/Kconfig
Expand Up @@ -352,4 +352,33 @@ config USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE
to perform the required lock down and chipset register configuration prior
boot to payload.

config FSP_USES_CB_DEBUG_EVENT_HANDLER
bool
default n
help
This option allows to create `Debug Event Handler` to print FSP debug messages
to output device using coreboot native implementation.

config DISPLAY_FSP_TIMESTAMPS
bool "Display FSP Timestamps"
default n
help
Select this config to retrieve FSP timestamps from Firmware Performance Data Table
(FPDT) and display from ramstage after FSP-S is executed.

To be able to use this, FSP has to be compiled with `PcdFspPerformanceEnable` set to
`TRUE`.

config FSP_ENABLE_SERIAL_DEBUG
bool "Output FSP debug messages on serial console"
default y
depends on FSP_USES_CB_DEBUG_EVENT_HANDLER
help
Output FSP debug messages on serial console.

The config option is selected based on your FSP configuration i.e., debug or
release. Enable this option from site-local to print FSP serial messages using
coreboot native debug driver when coreboot has integrated the debug FSP
binaries. coreboot disables serial messages when this config is not enabled.

endif
3 changes: 3 additions & 0 deletions src/drivers/intel/fsp2_0/Makefile.inc
Expand Up @@ -5,6 +5,7 @@ ifeq ($(CONFIG_PLATFORM_USES_FSP2_0),y)
bootblock-$(CONFIG_FSP_CAR) += fspt_report.c

romstage-y += debug.c
romstage-$(CONFIG_FSP_USES_CB_DEBUG_EVENT_HANDLER) += fsp_debug_event.c
romstage-y += hand_off_block.c
romstage-$(CONFIG_DISPLAY_FSP_HEADER) += header_display.c
romstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c
Expand All @@ -16,7 +17,9 @@ romstage-$(CONFIG_MMA) += mma_core.c
romstage-y += cbmem.c

ramstage-y += debug.c
ramstage-$(CONFIG_FSP_USES_CB_DEBUG_EVENT_HANDLER) += fsp_debug_event.c
ramstage-$(CONFIG_USE_INTEL_FSP_MP_INIT) += fsp_mpinit.c
ramstage-$(CONFIG_DISPLAY_FSP_TIMESTAMPS) += fsp_timestamp.c
ramstage-$(CONFIG_RUN_FSP_GOP) += graphics.c
ramstage-y += hand_off_block.c
ramstage-$(CONFIG_DISPLAY_FSP_HEADER) += header_display.c
Expand Down
28 changes: 28 additions & 0 deletions src/drivers/intel/fsp2_0/fsp_debug_event.c
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <fsp/api.h>
#include <fsp/fsp_debug_event.h>
#include <fsp/util.h>

static const uint8_t fsp_string_type_guid[16] = {
0x80, 0x10, 0xd1, 0x92, 0x6f, 0x49, 0x95, 0x4d,
0xbe, 0x7e, 0x03, 0x74, 0x88, 0x38, 0x2b, 0x0a
};

static efi_return_status_t print_fsp_string_data(const efi_status_code_data_t *data)
{
printk(BIOS_SPEW, "%s", ((efi_status_code_string_data *) data)->String.Ascii);

return FSP_SUCCESS;
}

efi_return_status_t fsp_debug_event_handler(efi_status_code_type_t ignored1,
efi_status_code_value_t ignored2, efi_uint32_t ignored3, efi_guid_t *ignored4,
efi_status_code_data_t *data)
{
if (!fsp_guid_compare((uint8_t *)&(data->Type), fsp_string_type_guid))
return FSP_NOT_FOUND;

return print_fsp_string_data(data);
}
109 changes: 109 additions & 0 deletions src/drivers/intel/fsp2_0/fsp_timestamp.c
@@ -0,0 +1,109 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <commonlib/bsd/compiler.h>
#include <console/console.h>
#include <fsp/util.h>
#include <lib.h>

#define TIMESTAMP_MS(x) ((x) / 1000ull)

static const uint8_t fpdt_guid[16] = {
0xfd, 0x7b, 0x38, 0x3b, 0xbc, 0x7a, 0xf2, 0x4c,
0xa0, 0xca, 0xb6, 0xa1, 0x6c, 0x1b, 0x1b, 0x25,
};

enum fpdt_record_type {
FPDT_GUID_EVENT = 0x1010,
FPDT_STRING_EVENT = 0x1011,
};

struct perf_record_hdr {
uint16_t type;
uint8_t length;
uint8_t revision;
} __packed;

struct generic_event_record {
struct perf_record_hdr header;
uint16_t progress_id;
uint32_t apic_id;
uint64_t timestamp;
uint8_t guid[16];
uint8_t string[0];
} __packed;

/*
* Performance Hob:
* GUID - fpdt_guid;
* Data - FPDT_PEI_EXT_PERF_HEADER one or more FPDT records
*/
struct fpdt_pei_ext_perf_header {
uint32_t table_size;
uint32_t load_image_count;
uint32_t hob_is_full;
} __packed;

static void print_guid_record(const struct generic_event_record *rec)
{
printk(BIOS_INFO, "%5x\t%16llu\t\t", rec->progress_id, TIMESTAMP_MS(rec->timestamp));
fsp_print_guid(rec->guid);
printk(BIOS_INFO, "\n");
}

static void print_string_record(const struct generic_event_record *rec)
{
size_t str_len = rec->header.length - offsetof(struct generic_event_record, string);
printk(BIOS_INFO, "%5x\t%16llu\t\t%*s/",
rec->progress_id, TIMESTAMP_MS(rec->timestamp), (int)str_len, rec->string);
fsp_print_guid(rec->guid);
printk(BIOS_INFO, "\n");
}

static void print_fsp_perf_timestamp(const struct generic_event_record *rec)
{
switch (rec->header.type) {
case FPDT_GUID_EVENT:
print_guid_record(rec);
break;
case FPDT_STRING_EVENT:
print_string_record(rec);
break;
default:
printk(BIOS_INFO, "Unhandled Event Type 0x%x\n", rec->header.type);
break;
}
}

static void print_fsp_timestamp_header(void)
{
printk(BIOS_INFO, "+---------------------------------------------------+\n");
printk(BIOS_INFO, "|------ FSP Performance Timestamp Table Dump -------|\n");
printk(BIOS_INFO, "+---------------------------------------------------+\n");
printk(BIOS_INFO, "| Perf-ID\tTimestamp(ms)\t\tString/GUID |\n");
printk(BIOS_INFO, "+---------------------------------------------------+\n");
}

void fsp_display_timestamp(void)
{
size_t size;
const struct fpdt_pei_ext_perf_header *hdr = fsp_find_extension_hob_by_guid(fpdt_guid,
&size);

if (!hdr || !size) {
printk(BIOS_INFO, "FPDT Extended Firmware Performance HOB Not Found!\n"
"Check if PcdFspPerformanceEnable is set to `TRUE` inside FSP package\n");
return;
}

const struct generic_event_record *rec = (const struct generic_event_record *)(
(uint8_t *)hdr + sizeof(struct fpdt_pei_ext_perf_header));

print_fsp_timestamp_header();
for (size_t i = 0; i < hdr->table_size;) {
print_fsp_perf_timestamp(rec);

i += rec->header.length;
rec = (const struct generic_event_record *)((uint8_t *)rec +
rec->header.length);
}
}
15 changes: 15 additions & 0 deletions src/drivers/intel/fsp2_0/hand_off_block.c
Expand Up @@ -22,6 +22,11 @@ const uint8_t fsp_reserved_memory_guid[16] = {
0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e,
};

const uint8_t fsp_nv_storage_guid_2[16] = {
0x8f, 0x78, 0x66, 0x48, 0xa8, 0x6b, 0xd8, 0x47,
0x83, 0x6, 0xac, 0xf7, 0x7f, 0x55, 0x10, 0x46
};

const uint8_t fsp_nv_storage_guid[16] = {
0x02, 0xcf, 0x1a, 0x72, 0x77, 0x4d, 0x2a, 0x4c,
0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0
Expand Down Expand Up @@ -306,6 +311,16 @@ void fsp_display_fvi_version_hob(void)

const void *fsp_find_nv_storage_data(size_t *size)
{
if (CONFIG(PLATFORM_USES_FSP2_3)) {
const struct fsp_nvs_hob2_data_region_header *hob;

hob = (const struct fsp_nvs_hob2_data_region_header *)
fsp_find_extension_hob_by_guid(fsp_nv_storage_guid_2, size);
if (hob != NULL) {
*size = hob->nvs_data_length;
return (void *)(uintptr_t)hob->nvs_data_ptr;
}
}
return fsp_find_extension_hob_by_guid(fsp_nv_storage_guid, size);
}

Expand Down
19 changes: 19 additions & 0 deletions src/drivers/intel/fsp2_0/include/fsp/fsp_debug_event.h
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef FSP_DEBUG_EVENT_H
#define FSP_DEBUG_EVENT_H

/*
* This file to implement FSP_EVENT_HANDLER for Intel FSP to use.
* More details about this structure can be found here :
* http://github.com/tianocore/edk2/blob/master/IntelFsp2Pkg/Include/FspEas/FspApi.h
*/
#include <efi/efi_datatype.h>
#include <fsp/soc_binding.h>

/* fsp debug event handler */
efi_return_status_t fsp_debug_event_handler(efi_status_code_type_t ignored1,
efi_status_code_value_t ignored2, efi_uint32_t ignored3, efi_guid_t *ignored4,
efi_status_code_data_t *data);

#endif /* FSP_DEBUG_EVENT_H */
8 changes: 8 additions & 0 deletions src/drivers/intel/fsp2_0/include/fsp/util.h
Expand Up @@ -8,6 +8,7 @@
#include <commonlib/region.h>
#include <arch/cpu.h>
#include <fsp/api.h>
#include <efi/efi_datatype.h>
#include <fsp/info_header.h>
#include <memrange.h>
#include <program_loading.h>
Expand All @@ -27,6 +28,11 @@ struct hob_header {
uint16_t length;
} __packed;

struct fsp_nvs_hob2_data_region_header {
efi_physical_address nvs_data_ptr;
uint64_t nvs_data_length;
};

struct fsp_notify_params {
enum fsp_notify_phase phase;
};
Expand Down Expand Up @@ -100,6 +106,8 @@ extern const uint8_t fsp_bootloader_tolum_guid[16];
extern const uint8_t fsp_nv_storage_guid[16];
extern const uint8_t fsp_reserved_memory_guid[16];

/* Function to extract the FSP timestamp from FPDT Hob and display */
void fsp_display_timestamp(void);
const void *fsp_get_hob_list(void);
void *fsp_get_hob_list_ptr(void);
const void *fsp_find_extension_hob_by_guid(const uint8_t *guid, size_t *size);
Expand Down
1 change: 0 additions & 1 deletion src/drivers/intel/fsp2_0/memory_init.c
Expand Up @@ -3,7 +3,6 @@
#include <security/vboot/antirollback.h>
#include <arch/symbols.h>
#include <assert.h>
#include <bootmode.h>
#include <cbfs.h>
#include <cbmem.h>
#include <cf9_reset.h>
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/intel/fsp2_0/silicon_init.c
Expand Up @@ -244,6 +244,9 @@ void fsp_silicon_init(void)
timestamp_add_now(TS_FSP_SILICON_INIT_LOAD);
fsps_load();
do_silicon_init(&fsps_hdr);

if (CONFIG(DISPLAY_FSP_TIMESTAMPS))
fsp_display_timestamp();
}

__weak void soc_load_logo(FSPS_UPD *supd) { }
2 changes: 1 addition & 1 deletion src/drivers/intel/mipi_camera/camera.c
Expand Up @@ -138,7 +138,7 @@ static void camera_fill_cio2(const struct device *dev)
port_name[i] = strdup(name);
if (CONFIG(ACPI_ADL_IPU_ES_SUPPORT)) {
u32 cpu_id = cpu_get_cpuid();
if (cpu_id == CPUID_ALDERLAKE_A0 || cpu_id == CPUID_ALDERLAKE_A1 ||
if (cpu_id == CPUID_ALDERLAKE_J0 || cpu_id == CPUID_ALDERLAKE_Q0 ||
cpu_id == CPUID_ALDERLAKE_N_A0)
acpi_dp_add_integer(dsd, "is_es", 1);
else
Expand Down
8 changes: 8 additions & 0 deletions src/drivers/tpm/cr50.c
Expand Up @@ -142,6 +142,14 @@ enum cb_err cr50_set_board_cfg(void)

bool cr50_is_long_interrupt_pulse_enabled(void)
{
/*
* Ti50 FW versions under 0.15 don't support the board cfg register,
* and all Ti50 versions only support long IRQ pulses.
* TODO: Remove this after all Ti50 stocks uprev to 0.15 or above.
*/
if (CONFIG(MAINBOARD_NEEDS_I2C_TI50_WORKAROUND))
return true;

return !!(cr50_get_board_cfg() & CR50_BOARD_CFG_100US_READY_PULSE);
}

Expand Down
6 changes: 6 additions & 0 deletions src/drivers/usb/acpi/chip.h
Expand Up @@ -66,6 +66,12 @@ struct drivers_usb_acpi_config {
* E.g. On a mic: if it is one, it is recording white-noise.
*/
struct acpi_gpio privacy_gpio;

/* Write a _STA method that uses the state of the GPIOs to determine if
* the PowerResource is ON or OFF. If this is false, the _STA method
* will always return ON.
*/
bool use_gpio_for_status;
};

/* Method to get PLD structure from USB device */
Expand Down
3 changes: 2 additions & 1 deletion src/drivers/usb/acpi/usb_acpi.c
Expand Up @@ -95,7 +95,8 @@ static void usb_acpi_fill_ssdt_generator(const struct device *dev)
config->enable_off_delay_ms,
NULL,
0,
0
0,
config->use_gpio_for_status
};
acpi_device_add_power_res(&power_res_params);
}
Expand Down
8 changes: 4 additions & 4 deletions src/drivers/wifi/generic/acpi.c
Expand Up @@ -533,11 +533,9 @@ static void wifi_ssdt_write_device(const struct device *dev, const char *path)

static void wifi_ssdt_write_properties(const struct device *dev, const char *scope)
{
bool is_cnvi_ddr_rfim_enabled = false;

const struct drivers_wifi_generic_config *config = dev->chip_info;
if (dev && config)
is_cnvi_ddr_rfim_enabled = config->enable_cnvi_ddr_rfim;

bool is_cnvi_ddr_rfim_enabled = config && config->enable_cnvi_ddr_rfim;

/* Scope */
acpigen_write_scope(scope);
Expand Down Expand Up @@ -646,6 +644,8 @@ const char *wifi_pcie_acpi_name(const struct device *dev)
void wifi_cnvi_fill_ssdt(const struct device *dev)
{
const char *path;
if (!dev)
return;

path = acpi_device_path(dev->bus->dev);
if (!path)
Expand Down
1 change: 1 addition & 0 deletions src/ec/google/chromeec/ec_acpi.c
Expand Up @@ -270,6 +270,7 @@ void google_chromeec_fill_ssdt_generator(const struct device *dev)
/* Set up a minimal EC0 device to pass to the DPTF helpers */
path.type = DEVICE_PATH_GENERIC;
path.generic.id = 0;
path.generic.subid = 0;
ec = alloc_find_dev(dev->bus, &path);
ec->ops = &ec_ops;

Expand Down
12 changes: 9 additions & 3 deletions src/ec/starlabs/merlin/Kconfig
@@ -1,5 +1,11 @@
## SPDX-License-Identifier: GPL-2.0-only

config EC_STARLABS_NUVOTON
bool
select EC_ACPI
help
Interface to Nuvoton embedded controller principally in Star Labs notebooks.

config EC_STARLABS_ITE
bool
select EC_ACPI
Expand Down Expand Up @@ -33,21 +39,21 @@ config EC_STARLABS_ITE_BIN_PATH
config EC_STARLABS_KBL_LEVELS
bool
default n
depends on EC_STARLABS_ITE
depends on EC_STARLABS_ITE || EC_STARLABS_NUVOTON
help
Select if the mainboard supports multiple levels of brightness for the keyboard.

config EC_STARLABS_FAN
bool
default n
depends on EC_STARLABS_ITE
depends on EC_STARLABS_ITE || EC_STARLABS_NUVOTON
help
Select if the mainboard has a fan.

config EC_STARLABS_MAX_CHARGE
bool
default n
depends on EC_STARLABS_ITE
depends on EC_STARLABS_ITE || EC_STARLABS_NUVOTON
help
Select if the mainboard supports limiting the maximum charge of the battery.

Expand Down
11 changes: 10 additions & 1 deletion src/ec/starlabs/merlin/Makefile.inc
Expand Up @@ -8,7 +8,7 @@ INTERMEDIATE+=add_ite_fw
EC_VARIANT_DIR := $(call strip_quotes, $(CONFIG_EC_VARIANT_DIR))
CPPFLAGS_common += -I$(src)/ec/starlabs/merlin/variants/$(EC_VARIANT_DIR)

all-y += ec.c
all-y += ite.c

ifeq ($(CONFIG_EC_STARLABS_NEED_ITE_BIN),y)
ifeq ($(CONFIG_EC_STARLABS_ADD_ITE_BIN),y)
Expand All @@ -26,3 +26,12 @@ warn_no_ite_fw:
endif
endif
endif

ifeq ($(CONFIG_EC_STARLABS_NUVOTON),y)

EC_VARIANT_DIR := $(call strip_quotes, $(CONFIG_EC_VARIANT_DIR))
CPPFLAGS_common += -I$(src)/ec/starlabs/merlin/variants/$(EC_VARIANT_DIR)

all-y += nuvoton.c

endif
23 changes: 18 additions & 5 deletions src/ec/starlabs/merlin/ec.h
@@ -1,19 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/*
* EC communication interface for ITE Embedded Controller.
* EC communication interface for Embedded Controller.
*/

#ifndef _EC_STARLABS_ITE_H
#define _EC_STARLABS_ITE_H
#ifndef _EC_STARLABS_EC_H
#define _EC_STARLABS_EC_H

/*
* Define the expected value of the PNP base address that is fixed through
* the BADRSEL register controlled within the EC domain by the EC Firmware.
*/
#define ITE_FIXED_ADDR 0x4e
#define NUVOTON_FIXED_ADDR 0x4e

/* Logical device number (LDN) assignments. */
/* Logical device number (LDN) assignments for ITE. */
#define ITE_SP1 0x01 /* Serial Port 1 (UART) */
#define ITE_SP2 0x02 /* Serial Port 2 (UART) */
#define ITE_SWUC 0x04 /* System Wake-Up Control (SWUC) */
Expand All @@ -30,9 +31,21 @@
#define ITE_PMC4 0x18 /* Power Management I/F Channel 4 (PMC4) */
#define ITE_PMC5 0x19 /* Power Management I/F Channel 5 (PMC5) */

/* Logical device number (LDN) assignments for Nuvoton. */
#define NUVOTON_MSWC 0x04 /* Mobile System Wake-Up Control (MSWC) */
#define NUVOTON_KBCM 0x05 /* KBC / Mouse Interface */
#define NUVOTON_KBCK 0x06 /* KBC / Keyboard Interface */
#define NUVOTON_SHM 0x0f /* Shared Memory (SHM) */
#define NUVOTON_PM1 0x11 /* Power Management I/F Channel 1 (PM1) */
#define NUVOTON_PM2 0x12 /* Power Management I/F Channel 2 (PM2) */
#define NUVOTON_PM3 0x17 /* Power Management I/F Channel 3 (PM3) */
#define NUVOTON_ESHM 0x1d /* Extended Shared Memory (ESHM) */
#define NUVOTON_PM4 0x1e /* Power Management I/F Channel 3 (PM4) */

/* Host domain registers. */
#define ITE_CHIPID1 0x20 /* Device ID register 1 */
#define ITE_CHIPID2 0x21 /* Device ID register 2 */
#define NUVOTON_CHIPID 0x27 /* Device ID register */

/* EC RAM common offsets */
#define ECRAM_MAJOR_VERSION 0x00
Expand Down Expand Up @@ -81,6 +94,6 @@
#define KBL_DISABLED 0x00
#define KBL_ENABLED 0xdd

uint16_t it_get_version(void);
uint16_t ec_get_version(void);

#endif
Expand Up @@ -10,7 +10,7 @@
#include "ec.h"
#include "ecdefs.h"

uint16_t it_get_version(void)
uint16_t ec_get_version(void)
{
return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION);
}
Expand All @@ -26,7 +26,7 @@ static uint8_t get_ec_value_from_option(const char *name,
return lut[index];
}

static uint16_t ite_get_chip_id(unsigned int port)
static uint16_t ec_get_chip_id(unsigned int port)
{
return (pnp_read_index(port, ITE_CHIPID1) << 8) |
pnp_read_index(port, ITE_CHIPID2);
Expand All @@ -49,7 +49,7 @@ static void merlin_init(struct device *dev)
return;
}

const uint16_t chip_id = ite_get_chip_id(dev->path.pnp.port);
const uint16_t chip_id = ec_get_chip_id(dev->path.pnp.port);

if (chip_id != ITE_CHIPID_VAL) {
printk(BIOS_ERR, "ITE: Expected chip ID 0x%04x, but got 0x%04x instead.\n",
Expand Down
287 changes: 287 additions & 0 deletions src/ec/starlabs/merlin/nuvoton.c
@@ -0,0 +1,287 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <device/device.h>
#include <device/pnp.h>
#include <ec/acpi/ec.h>
#include <option.h>
#include <pc80/keyboard.h>

#include "ec.h"
#include "ecdefs.h"

uint16_t ec_get_version(void)
{
return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION);
}

static uint8_t get_ec_value_from_option(const char *name,
unsigned int fallback,
const uint8_t *lut,
size_t lut_size)
{
unsigned int index = get_uint_option(name, fallback);
if (index >= lut_size)
index = fallback;
return lut[index];
}

static uint16_t ec_get_chip_id(unsigned int port)
{
return pnp_read_index(port, NUVOTON_CHIPID);
}

static void merlin_init(struct device *dev)
{
if (!dev->enabled)
return;

/*
* The address/data IO port pair for the Nuvoton EC are configurable
* through the EC domain and are fixed by the EC's firmware blob. If
* the value(s) passed through the "dev" structure don't match the
* expected values then output severe warnings.
*/
if (dev->path.pnp.port != NUVOTON_FIXED_ADDR) {
printk(BIOS_ERR, "NUVOTON: Incorrect ports defined in devicetree.cb.\n");
printk(BIOS_ERR, "NUVOTON: Serious operational issues will arise.\n");
return;
}

const uint16_t chip_id = ec_get_chip_id(dev->path.pnp.port);

if (chip_id != NUVOTON_CHIPID_VAL) {
printk(BIOS_ERR, "NUVOTON: Expected chip ID 0x%04x, but got 0x%04x instead.\n",
NUVOTON_CHIPID_VAL, chip_id);
return;
}

pc_keyboard_init(NO_AUX_DEVICE);

/*
* Restore settings from CMOS into EC RAM:
*
* kbl_timeout
* fn_ctrl_swap
* max_charge
* fan_mode
* fn_lock_state
* trackpad_state
* kbl_brightness
* kbl_state
*/

/*
* Keyboard Backlight Timeout
*
* Setting: kbl_timeout
*
* Values: 30 Seconds, 1 Minute, 3 Minutes, 5 Minutes, Never
* Default: 30 Seconds
*
*/
const uint8_t kbl_timeout[] = {
SEC_30,
MIN_1,
MIN_3,
MIN_5,
NEVER
};

ec_write(ECRAM_KBL_TIMEOUT,
get_ec_value_from_option("kbl_timeout",
0,
kbl_timeout,
ARRAY_SIZE(kbl_timeout)));

/*
* Fn Ctrl Reverse
*
* Setting: fn_ctrl_swap
*
* Values: Enabled, Disabled
* Default: Disabled
*
*/
const uint8_t fn_ctrl_swap[] = {
FN_CTRL,
CTRL_FN
};

ec_write(ECRAM_FN_CTRL_REVERSE,
get_ec_value_from_option("fn_ctrl_swap",
1,
fn_ctrl_swap,
ARRAY_SIZE(fn_ctrl_swap)));

/*
* Maximum Charge Level
*
* Setting: max_charge
*
* Values: 60%, 80%, 100%
* Default: 100%
*
*/
const uint8_t max_charge[] = {
CHARGE_100,
CHARGE_80,
CHARGE_60
};

if (CONFIG(EC_STARLABS_MAX_CHARGE))
ec_write(ECRAM_MAX_CHARGE,
get_ec_value_from_option("max_charge",
0,
max_charge,
ARRAY_SIZE(max_charge)));

/*
* Fan Mode
*
* Setting: fan_mode
*
* Values: Quiet, Normal, Aggressive
* Default: Normal
*
*/
const uint8_t fan_mode[] = {
FAN_NORMAL,
FAN_AGGRESSIVE,
FAN_QUIET
};

if (CONFIG(EC_STARLABS_FAN))
ec_write(ECRAM_FAN_MODE,
get_ec_value_from_option("fan_mode",
0,
fan_mode,
ARRAY_SIZE(fan_mode)));

/*
* Function Lock
*
* Setting: fn_lock_state
*
* Values: Locked, Unlocked
* Default: Locked
*
*/
const uint8_t fn_lock_state[] = {
UNLOCKED,
LOCKED
};

ec_write(ECRAM_FN_LOCK_STATE,
get_ec_value_from_option("fn_lock_state",
1,
fn_lock_state,
ARRAY_SIZE(fn_lock_state)));

/*
* Trackpad State
*
* Setting: trackpad_state
*
* Values: Enabled, Disabled
* Default: Enabled
*
*/
const uint8_t trackpad_state[] = {
TRACKPAD_ENABLED,
TRACKPAD_DISABLED
};

ec_write(ECRAM_TRACKPAD_STATE,
get_ec_value_from_option("trackpad_state",
0,
trackpad_state,
ARRAY_SIZE(trackpad_state)));

/*
* Keyboard Backlight Brightness
*
* Setting: kbl_brightness
*
* Values: Off, Low, High / Off, On
* Default: Low
*
*/
const uint8_t kbl_brightness[] = {
KBL_ON,
KBL_OFF,
KBL_LOW,
KBL_HIGH
};

if (CONFIG(EC_STARLABS_KBL_LEVELS))
ec_write(ECRAM_KBL_BRIGHTNESS,
get_ec_value_from_option("kbl_brightness",
2,
kbl_brightness,
ARRAY_SIZE(kbl_brightness)));
else
ec_write(ECRAM_KBL_BRIGHTNESS,
get_ec_value_from_option("kbl_brightness",
0,
kbl_brightness,
ARRAY_SIZE(kbl_brightness)));

/*
* Keyboard Backlight State
*
* Setting: kbl_state
*
* Values: Off, On
* Default: On
*
*/
const uint8_t kbl_state[] = {
KBL_DISABLED,
KBL_ENABLED
};

ec_write(ECRAM_KBL_STATE,
get_ec_value_from_option("kbl_state",
1,
kbl_state,
ARRAY_SIZE(kbl_state)));
}

static struct device_operations ops = {
.init = merlin_init,
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
};

static struct pnp_info pnp_dev_info[] = {
/* System Wake-Up Control (SWUC) */
{ NULL, NUVOTON_MSWC, PNP_IO0 | PNP_IRQ0, 0xfff0, },
/* KBC / Mouse Interface */
{ NULL, NUVOTON_KBCM, PNP_IRQ0, },
/* KBC / Keyboard Interface */
{ NULL, NUVOTON_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
/* Shared Memory / Flash Interface (SMFI) */
{ NULL, NUVOTON_SHM, PNP_IO0 | PNP_IRQ0, 0xfff0, },
/* Power Management I/F Channel 1 (PMC1) */
{ NULL, NUVOTON_PM1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
/* Power Management I/F Channel 2 (PMC2) */
{ NULL, NUVOTON_PM2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc,
0x07fc, 0xfff0, },
/* Power Management I/F Channel 3 (PMC3) */
{ NULL, NUVOTON_PM3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
/* Extended Shared Memory (ESHM) */
{ NULL, NUVOTON_ESHM },
/* Power Management I/F Channel 4 (PMC4) */
{ NULL, NUVOTON_PM4, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
};

static void enable_dev(struct device *dev)
{
pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
}

struct chip_operations ec_starlabs_merlin_ops = {
CHIP_NAME("NUVOTON EC")
.enable_dev = enable_dev
};
2 changes: 0 additions & 2 deletions src/ec/starlabs/merlin/variants/apl/emem.asl
Expand Up @@ -98,10 +98,8 @@ Field (ECF2, ByteAcc, Lock, Preserve)
BT1T, 16, // Bt1 Temperature
BT1C, 8, // Bt1 Control

// Unicorn - doesn't actually exist
Offset(0x9d),
OPWE, 8, // OPM write to EC flag for UCSI
// Unicorn - doesn't actually exist

Offset(0xbf),
EJ8A, 8, // EJ898A Firmware Version
Expand Down
23 changes: 23 additions & 0 deletions src/ec/starlabs/merlin/variants/cezanne/ecdefs.h
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/*
* EC communication interface for ITE Embedded Controller
*/

#ifndef _EC_STARLABS_CEZANNE_EC_DEFS_H
#define _EC_STARLABS_CEZANNE_EC_DEFS_H

/* IT5570 chip ID byte values */
#define ITE_CHIPID_VAL 0x5570

/* EC RAM offsets */
#define ECRAM_KBL_BRIGHTNESS 0x09
#define ECRAM_KBL_TIMEOUT 0x10
#define ECRAM_KBL_STATE 0x19
#define ECRAM_TRACKPAD_STATE 0x20
#define ECRAM_FN_LOCK_STATE 0x21
#define ECRAM_FN_CTRL_REVERSE 0x22
#define ECRAM_MAX_CHARGE 0x23
#define ECRAM_FAN_MODE 0x24

#endif
147 changes: 147 additions & 0 deletions src/ec/starlabs/merlin/variants/cezanne/emem.asl
@@ -0,0 +1,147 @@
/* SPDX-License-Identifier: GPL-2.0-only */

OperationRegion (ECF2, EmbeddedControl, 0x00, 0x100)
Field (ECF2, ByteAcc, Lock, Preserve)
{
Offset(0x00),
ECMV, 8, // Major Version Number
ECSV, 8, // Minor Version Number
KBVS, 8, // Keyboard Controller Version
ECTV, 8, // Test Version Number
OSFG, 8, // OS Flag
FRMF, 8, // Force Mirror Flag

Offset(0x0c),
P0MV, 8, // PD Port 0 Major Version
P0SV, 8, // PD Port 0 Minor Version
P1MV, 8, // PD Port 1 Major Version
P1SV, 8, // PD Port 1 Minor Version

Offset(0x13),
AUDI, 8, // Control Audio
TRAC, 8, // Trackpad Control

Offset(0x18),
BSEC, 8, // Save to CMOS
KLSE, 8, // Keyboard Backlight State
TPLE, 8, // Trackpad State
FLKE, 8, // Function Lock State
FCLS, 8, // Ctrl Fn Reverse (Make Keyboard Apple-like)
MXCH, 8, // Max Charge Level
FANM, 8, // Fan Mode

Offset(0x40),
SHIP, 8, // Shipping Mode Flag

Offset(0x46),
ECPS, 8, // AC & Battery Status

Offset(0x30),
STEF, 8, // Sensor T Error F

Offset(0x62),
SSKT, 8, // System Skin Temperature
SENF, 8, // Sensor F
TSHT, 8, // Thermal Sensor High Trip Point
TSLT, 8, // Thermal Sensor Low Trip Point
THER, 8, // Thermal Source

Offset(0x70),
CPUT, 8, // PECI CPU Temperature
PMXT, 8, // PLMX Temperature
CHAR, 8, // Charger Temperature

Offset(0x7f),
LSTE, 8, // Lid Status
ECPS, 8, // AC & Battery Status
B1MN, 8, // Battery Model Number Code
B1SN, 16, // Battery Serial Number
B1DC, 16, // Battery Design Capacity
B1DV, 16, // Battery Design Voltage
B1FC, 16, // Battery Last Full Charge Capacity
B1TP, 16, // Battery Trip Point
B1ST, 8, // Battery State
B1PR, 16, // Battery Present Rate
B1RC, 16, // Battery Remaining Capacity
B1PV, 16, // Battery Present Voltage
BPRP, 8, // Battery Remaining Percentage
CPUT, 8, // PECI CPU Temperature
STCD, 8, // Shutdown Code
B1HL, 8, // Battery Health
CWFU, 8, // CW2015 Full
B1CC, 16, // Battery Cycle Count

Offset(0xb0),
MGO0, 8, // UCSI DS MGO 0
MGO1, 8, // UCSI DS MGO 1
MGO2, 8, // UCSI DS MGO 2
MGO3, 8, // UCSI DS MGO 3
MGO4, 8, // UCSI DS MGO 4
MGO5, 8, // UCSI DS MGO 5
MGO6, 8, // UCSI DS MGO 6
MGO7, 8, // UCSI DS MGO 7
MGO8, 8, // UCSI DS MGO 8
MGO9, 8, // UCSI DS MGO 9
MGOA, 8, // UCSI DS MGO A
MGOB, 8, // UCSI DS MGO B
MGOC, 8, // UCSI DS MGO C
MGOD, 8, // UCSI DS MGO D
MGOE, 8, // UCSI DS MGO E
MGOF, 8, // UCSI DS MGO F

Offset(0xc0),
UCSV, 16, // UCSI DS Version
UCSD, 16, // UCSI DS Reserved
CCI0, 8, // UCSI DS CCI 0
CCI1, 8, // UCSI DS CCI 1
CCI2, 8, // UCSI DS CCI 2
CCI3, 8, // UCSI DS CCI 3
CTL0, 8, // UCSI DS Control 0
CTL1, 8, // UCSI DS Control 0
CTL2, 8, // UCSI DS Control 0
CTL3, 8, // UCSI DS Control 0
CTL4, 8, // UCSI DS Control 0
CTL5, 8, // UCSI DS Control 0
CTL6, 8, // UCSI DS Control 0
CTL7, 8, // UCSI DS Control 0

Offset(0xd0),
MGI0, 8, // UCSI DS MGI 0
MGI1, 8, // UCSI DS MGI 1
MGI2, 8, // UCSI DS MGI 2
MGI3, 8, // UCSI DS MGI 3
MGI4, 8, // UCSI DS MGI 4
MGI5, 8, // UCSI DS MGI 5
MGI6, 8, // UCSI DS MGI 6
MGI7, 8, // UCSI DS MGI 7
MGI8, 8, // UCSI DS MGI 8
MGI9, 8, // UCSI DS MGI 9
MGIA, 8, // UCSI DS MGI A
MGIB, 8, // UCSI DS MGI B
MGIC, 8, // UCSI DS MGI C
MGID, 8, // UCSI DS MGI D
MGIE, 8, // UCSI DS MGI E
MGIF, 8, // UCSI DS MGI F

Offset(0xe0),
CCS1, 8, // Cross Point Switch Status 1
CCS2, 8, // Cross Point Switch Status 2
TCI1, 8, // TC Input 1 / TCHC Thermal Charge CMD [TODO, Confirm]
TCI2, 8, // TC Input 2 / TCHF Thermal Charge Flag [TODO, Confirm]
PDDT, 8, // PD Det [TODO, Confirm]
PDBD, 8, // B PD Det [TODO, Confirm]
ECWD, 16, // EC Wakeup Delay
ECWE, 8, // EC Wakeup Enable
PDV1, 8, // PD Vol [TODO, Confirm]
PDV2, 8, // B PD Vol [TODO, Confirm]

// Below are the Thunderbolt Offsets from the shared EC code. There aren't
// use for AMD boards but left for reference.
//
// Offset(0xf7),
// TBTC, 8, // Thunderbolt Command
// TBTP, 8, // Thunderbolt Data Port
// TBTD, 8, // Thunderbolt Data
// TBTA, 8, // Thunderbolt Acknowledge
// TBTG, 16, // Thunderbolt DBG Data
}
193 changes: 193 additions & 0 deletions src/ec/starlabs/merlin/variants/cezanne/events.asl
@@ -0,0 +1,193 @@
/* SPDX-License-Identifier: GPL-2.0-only */

Method (_Q01, 0, NotSerialized) // Event: F1 Hot Key
{
Printf ("EC: F1")
}

Method (_Q02, 0, NotSerialized) // Event: F2 Hot Key
{
Printf ("EC: F2")
}

Method (_Q03, 0, NotSerialized) // Event: F3 Hot Key
{
Printf ("EC: F3")
}

Method (_Q04, 0, NotSerialized) // Event: F4 Hot Key
{
Printf ("EC: F4")
}

Method (_Q05, 0, NotSerialized) // Event: F5 Hot Key
{
Printf ("EC: F5")
}

Method (_Q06, 0, NotSerialized) // Event: F6 Hot Key
{
Printf ("EC: F6")
}

Method (_Q07, 0, NotSerialized) // Event: F7 Hot Key
{
Printf ("EC: F7")
}

Method (_Q08, 0, NotSerialized) // Event: F8 Hot Key
{
Printf ("EC: F8")
}

Method (_Q09, 0, NotSerialized) // Event: F9 Hot Key
{
Printf ("EC: F9")
}

Method (_Q10, 0, NotSerialized) // Event: F10 Hot Key
{
Printf ("EC: F10")
}

Method (_Q12, 0, NotSerialized) // Event: F12 Hot Key
{
Printf ("EC: F12")
}

Method (_Q0A, 0, NotSerialized) // Event: AC Power Connected
{
Notify (BAT0, 0x81)
Notify (ADP1, 0x80)
}

Method (_Q0B, 0, NotSerialized) // Event: AC Power Disconnected
{
Notify (BAT0, 0x81)
Notify (BAT0, 0x80)
}

Method (_Q0C, 0, NotSerialized) // Event: Lid Closed
{
\LIDS = LSTE
Notify (LID0, 0x80)
}

Method (_Q0D, 0, NotSerialized) // Event: Lid Open
{
\LIDS = LSTE
Notify (LID0, 0x80)
}

Method (_Q0E, 0, NotSerialized) // Event: SLEEP
{
Printf ("EC: SLEEP")
}

Method (_Q13, 0, NotSerialized) // Event: BRIGHTNESS
{
Printf ("EC: BRIGHTNESS")
}

Method (_Q20, 0, NotSerialized) // Event: CPU_T
{
Printf ("EC: CPU_T")
}

Method (_Q21, 0, NotSerialized) // Event: SKIN_T
{
Printf ("EC: SKIN_T")
}

Method (_Q22, 0, NotSerialized) // Event: CHARGER_T
{
Printf ("EC: CHARGER_T")
}

Method (_Q30, 0, NotSerialized) // Event: THROT_OFF
{
Printf ("EC: THROT_OFF")
}

Method (_Q31, 0, NotSerialized) // Event: THROT_LV1
{
Printf ("EC: THROT_LV1")
}

Method (_Q32, 0, NotSerialized) // Event: THROT_LV2
{
Printf ("EC: THROT_LV2")
}

Method (_Q33, 0, NotSerialized) // Event: THROT_LV3
{
Printf ("EC: THROT_LV3")
}

Method (_Q34, 0, NotSerialized) // Event: THROT_LV4
{
Printf ("EC: THROT_LV4")
}

Method (_Q35, 0, NotSerialized) // Event: THROT_LV5
Printf ("EC: THROT_LV5")
}

Method (_Q36, 0, NotSerialized) // Event: THROT_LV6
{
Printf ("EC:THROT_LV6")
}

Method (_Q37, 0, NotSerialized) // Event: THROT_LV7
{
Printf ("EC: THROT_LV7")
}

Method (_Q3B, 0, NotSerialized) // Event: CPU_DN_SPEED
Printf ("EC: CPU_DN_SPEED")
}

Method (_Q3C, 0, NotSerialized) // Event: CPU_UP_SPEED
{
Printf ("EC: CPU_UP_SPEED")
}

Method (_Q3D, 0, NotSerialized) // Event: CPU_TURBO_OFF
{
Printf ("EC: CPU_TURBO_OFF")
}

Method (_Q3E, 0, NotSerialized) // Event: CPU_TURBO_ON
{
Printf ("EC: CPU_TURBO_ON")
}

Method (_Q3F, 0, NotSerialized) // Event: SHUTDOWN
Printf ("EC: SHUTDOWN")
}

Method (_Q54, 0, NotSerialized) // Event: Power Button Press
{
Printf ("EC: PWRBTN")
}

Method (_Q79, 0, NotSerialized) // Event: USB Type-C
{
Printf ("EC: USB Type-C")
UCEV()
}

Method (_Q80, 0, NotSerialized) // Event: Volume Up
{
Printf ("EC:VOLUME_UP")
}

Method (_Q81, 0, NotSerialized) // Event: Volume Down
{
Printf ("EC: VOLUME_DOWN")
}

Method (_Q85, 0, NotSerialized) // Event: HOME
{
Printf ("EC: HOME")
}
2 changes: 0 additions & 2 deletions src/ec/starlabs/merlin/variants/cml/emem.asl
Expand Up @@ -108,10 +108,8 @@ Field (ECF2, ByteAcc, Lock, Preserve)
BT1T, 16, // Bt1 Temperature
BT1C, 8, // Bt1 Control

// Unicorn - doesn't actually exist
Offset(0x9d),
OPWE, 8, // OPM write to EC flag for UCSI
// Unicorn - doesn't actually exist

Offset(0xa0),
UCSV, 16, // UCSI DS Version
Expand Down
2 changes: 0 additions & 2 deletions src/ec/starlabs/merlin/variants/glk/emem.asl
Expand Up @@ -98,10 +98,8 @@ Field (ECF2, ByteAcc, Lock, Preserve)
BT1T, 16, // Bt1 Temperature
BT1C, 8, // Bt1 Control

// Unicorn - doesn't actually exist
Offset(0x9d),
OPWE, 8, // OPM write to EC flag for UCSI
// Unicorn - doesn't actually exist

Offset(0xbf),
EJ8A, 8, // EJ898A Firmware Version
Expand Down
26 changes: 26 additions & 0 deletions src/ec/starlabs/merlin/variants/glkr/ecdefs.h
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <stdint.h>

/*
* EC communication interface for Nuvoton Embedded Controller.
*/

#ifndef _EC_STARLABS_GLKR_EC_DEFS_H
#define _EC_STARLABS_GLKR_EC_DEFS_H

/* Nuvoton chip ID byte values. */
#define NUVOTON_CHIPID_VAL 0x0004

/* EC RAM offsets. */
#define ECRAM_TRACKPAD_STATE 0x14
#define ECRAM_KBL_STATE 0x16
#define ECRAM_KBL_BRIGHTNESS 0x17
#define ECRAM_KBL_TIMEOUT 0x12
#define ECRAM_FN_LOCK_STATE 0x15
#define ECRAM_FN_CTRL_REVERSE 0x13
#define ECRAM_MAX_CHARGE dead_code_t(uint8_t)
#define ECRAM_FAN_MODE dead_code_t(uint8_t)

#endif
160 changes: 160 additions & 0 deletions src/ec/starlabs/merlin/variants/glkr/emem.asl
@@ -0,0 +1,160 @@
/* SPDX-License-Identifier: GPL-2.0-only */

OperationRegion (ECF2, EmbeddedControl, 0x00, 0x100)
Field (ECF2, ByteAcc, Lock, Preserve)
{
Offset(0x00),
ECMV, 8, // Major Version Number
ECSV, 8, // Minor Version Number
KBVS, 8, // Keyboard Controller Version
ECTV, 8, // Test Version Number
P0MV, 8, // PD Port 0 Major Version
P0SV, 8, // PD Port 0 Minor Version
P1MV, 8, // PD Port 1 Major Version
P1SV, 8, // PD Port 1 Minor Version

Offset(0x0c),
ECT0, 8, // EC Build Time 0
ECT1, 8, // EC Build Time 1
ECT2, 8, // EC Build Time 2
ECT3, 8, // EC Build Time 3

Offset(0x12),
KLTE, 8, // Keyboard Backlight Timeout
FCLA, 8, // Fn Ctrl Reverse
TPLE, 8, // Trackpad State
FLKE, 8, // Function Lock State
KLSE, 8, // Keyboard Backlight State
KLBE, 8, // Keyboard Backlight Brightness

Offset(0x20),
RCMD, 8, // Send EC command
RCST, 8, // Status of EC command

Offset(0x60),
TSE1, 8, // Sensor 1 Temperature
TSE2, 8, // Sensor 2 Temperature
TSE3, 8, // Sensor 3 Temperature

Offset(0x63),
TSE4, 4, // Sensor 4 Temperature
SENF, 8, // Sensor F
TSHT, 8, // Thermal Sensor High Trip Point
TSLT, 8, // Thermal Sensor Low Trip Point
THER, 8, // Thermal Source
CHRA, 16, // Charge Rate

Offset(0x72),
CHAR, 8, // Charger Temperature

Offset(0x7e),
OSFG, 8, // OS Flag [TODO: Confirm]
LSTE, 1, // Lid Status
, 7, // Reserved

Offset(0x80),
ECPS, 8, // AC & Battery status
B1MN, 8, // Battery Model Number Code
B1SN, 16, // Battery Serial Number
B1DC, 16, // Battery Design Capacity
B1DV, 16, // Battery Design Voltage
B1FC, 16, // Battery Last Full Charge Capacity
B1TP, 16, // Battery Trip Point
B1ST, 8, // Battery State
B1PR, 16, // Battery Present Rate
B1RC, 16, // Battery Remaining Capacity
B1PV, 16, // Battery Present Voltage
BPRP, 8, // Battery Remaining percentage
BT1A, 8, // Bt1 ASOC
BT1T, 16, // Bt1 Temperature
BT1C, 8, // Bt1 Control

Offset(0x9d),
OPWE, 8, // OPM write to EC flag for UCSI

Offset(0xa0),
BSNL, 8, // Battery Serial Number Low byte
BSNH, 8, // Battery Serial Number High Byte
BMN1, 8, // Battery Manufactory Name 1
BMN2, 8, // Battery Manufactory Name 2
BMN3, 8, // Battery Manufactory Name 3
BMN4, 8, // Battery Manufactory Name 4
BMN5, 8, // Battery Manufactory Name 5
BMN6, 8, // Battery Manufactory Name 6
BMN7, 8, // Battery Manufactory Name 7
BMN8, 8, // Battery Manufactory Name 8
BMN9, 8, // Battery Manufactory Name 9
BMNA, 8, // Battery Manufactory Name 10
BMNB, 8, // Battery Manufactory Name 11
BMNC, 8, // Battery Manufactory Name 12
BDN1, 8, // Battery Device Name 1
BDN2, 8, // Battery Device Name 2
BDN3, 8, // Battery Device Name 3
BDN4, 8, // Battery Device Name 4
BDN5, 8, // Battery Device Name 5
BDN6, 8, // Battery Device Name 6
BDN7, 8, // Battery Device Name 7
BDN8, 8, // Battery Device Name 8
BDN9, 8, // Battery Device Name 9
BDNA, 8, // Battery Device Name 10
BDNB, 8, // Battery Device Name 11
BDNC, 8, // Battery Device Name 12
BCT1, 8, // Battery Chemistry Type 1
BCT2, 8, // Battery Chemistry Type 2
BCT3, 8, // Battery Chemistry Type 3
BCT4, 8, // Battery Chemistry Type 4
BCT5, 8, // Battery Chemistry Type 5
BCT6, 8, // Battery Chemistry Type 6

Offset(0xc0),
UCSV, 16, // UCSI DS Version
UCSD, 16, // UCSI DS Reserved
CCI0, 8, // UCSI DS CCI 0
CCI1, 8, // UCSI DS CCI 1
CCI2, 8, // UCSI DS CCI 2
CCI3, 8, // UCSI DS CCI 3
CTL0, 8, // UCSI DS Control 0
CTL1, 8, // UCSI DS Control 0
CTL2, 8, // UCSI DS Control 0
CTL3, 8, // UCSI DS Control 0
CTL4, 8, // UCSI DS Control 0
CTL5, 8, // UCSI DS Control 0
CTL6, 8, // UCSI DS Control 0
CTL7, 8, // UCSI DS Control 0

Offset(0xd0),
MGI0, 8, // UCSI DS MGI 0
MGI1, 8, // UCSI DS MGI 1
MGI2, 8, // UCSI DS MGI 2
MGI3, 8, // UCSI DS MGI 3
MGI4, 8, // UCSI DS MGI 4
MGI5, 8, // UCSI DS MGI 5
MGI6, 8, // UCSI DS MGI 6
MGI7, 8, // UCSI DS MGI 7
MGI8, 8, // UCSI DS MGI 8
MGI9, 8, // UCSI DS MGI 9
MGIA, 8, // UCSI DS MGI A
MGIB, 8, // UCSI DS MGI B
MGIC, 8, // UCSI DS MGI C
MGID, 8, // UCSI DS MGI D
MGIE, 8, // UCSI DS MGI E
MGIF, 8, // UCSI DS MGI F

Offset(0xe0),
MGO0, 8, // UCSI DS MGO 0
MGO1, 8, // UCSI DS MGO 1
MGO2, 8, // UCSI DS MGO 2
MGO3, 8, // UCSI DS MGO 3
MGO4, 8, // UCSI DS MGO 4
MGO5, 8, // UCSI DS MGO 5
MGO6, 8, // UCSI DS MGO 6
MGO7, 8, // UCSI DS MGO 7
MGO8, 8, // UCSI DS MGO 8
MGO9, 8, // UCSI DS MGO 9
MGOA, 8, // UCSI DS MGO A
MGOB, 8, // UCSI DS MGO B
MGOC, 8, // UCSI DS MGO C
MGOD, 8, // UCSI DS MGO D
MGOE, 8, // UCSI DS MGO E
MGOF, 8, // UCSI DS MGO F
}
78 changes: 78 additions & 0 deletions src/ec/starlabs/merlin/variants/glkr/events.asl
@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0-only */

Method (_Q0D, 0, NotSerialized) // Event: Lid Opened
{
\LIDS = LSTE
Notify (LID0, 0x80)
}

Method (_Q0C, 0, NotSerialized) // Event: Lid Closed
{
\LIDS = LSTE
Notify (LID0, 0x80)
}

Method (_Q0A, 0, NotSerialized) // Event: AC Power Connected
{
Notify (BAT0, 0x81)
Notify (ADP1, 0x80)
}

Method (_Q0B, 0, NotSerialized) // Event: AC Power Disconnected
{
Notify (BAT0, 0x81)
Notify (BAT0, 0x80)
}

Method (_Q09, 0, NotSerialized) // Event: Backlight Brightness Down
{
^^^^HIDD.HPEM (20)
}

Method (_Q10, 0, NotSerialized) // Event: Backlight Brightness Up
{
^^^^HIDD.HPEM (19)
}

Method (_Q08, 0, NotSerialized) // Event: Airplane Mode
{
^^^^HIDD.HPEM (8)
}

Method (_QD5, 0, NotSerialized) // Event: 10 Second Power Button Pressed
{
Notify (HIDD, 0xCE)
}

Method (_QD6, 0, NotSerialized) // Event: 10 Second Power Button Released
{
Notify (HIDD, 0xCF)
}

Method (_Q54, 0, NotSerialized) // Event: Power Button Press
{
Printf ("EC: PWRBTN")
}

Method (_Q02, 0, NotSerialized) // Event: Turn off Backlight
{
Printf ("EC: Backlight off")
}

Method (_Q79, 0, NotSerialized) // Event: USB Type-C
{
Printf ("EC: USB Type-C")
UCEV()
}

Method (_Q60, 0, NotSerialized) // Event: Trackpad Enable
{
Printf ("EC: Trackpad Enable")
SPC0 (0xD0C80600, 0x40800102)
}

Method (_Q61, 0, NotSerialized) // Event: Trackpad Disable
{
Printf ("EC: Trackpad Disable")
SPC0 (0xD0C80600, 0x40800200)
}
2 changes: 0 additions & 2 deletions src/ec/starlabs/merlin/variants/kbl/emem.asl
Expand Up @@ -85,10 +85,8 @@ Field (ECF2, ByteAcc, Lock, Preserve)
BPRP, 8, // Battery Remaining percentage
BT1A, 8, // Bt1 ASOC

// Unicorn - doesn't actually exist
Offset(0x9d),
OPWE, 8, // OPM write to EC flag for UCSI
// Unicorn - doesn't actually exist

Offset(0xbf),
EJ8A, 8, // EJ898A Firmware Version
Expand Down
2 changes: 0 additions & 2 deletions src/ec/starlabs/merlin/variants/merlin/emem.asl
Expand Up @@ -91,10 +91,8 @@ Field (ECF2, ByteAcc, Lock, Preserve)
BATT, 16, // Battery Temperature
BATC, 8, // Battery Temperature Ces

// Unicorn - doesn't actually exist
Offset(0x9d), // OPM:
OPWE, 8, // OPM write to EC flag for UCSI
// Unicorn - doesn't actually exist

Offset(0xb0), // MGO;
MGO0, 8, // UCSI DS MGO 0
Expand Down
2 changes: 0 additions & 2 deletions src/ec/starlabs/merlin/variants/tgl/emem.asl
Expand Up @@ -98,10 +98,8 @@ Field (ECF2, ByteAcc, Lock, Preserve)
B1PV, 16, // Battery Present Voltage
BPRP, 8, // Battery Remaining percentage

// Unicorn - doesn't actually exist
Offset(0x9d),
OPWE, 8, // OPM write to EC flag for UCSI
// Unicorn - doesn't actually exist

Offset(0xb0),
MGO0, 8, // UCSI DS MGO 0
Expand Down
2 changes: 1 addition & 1 deletion src/ec/starlabs/merlin/variants/tgl/events.asl
Expand Up @@ -238,7 +238,7 @@ Method (_Q37, 0, NotSerialized) // Event: THROT_LV7
Printf ("EC: THROT_LV7")
}

Method (_Q38, 0, NotSerialized) // Event: CPU_DN_SPEED
Method (_Q3B, 0, NotSerialized) // Event: CPU_DN_SPEED
{
Printf ("EC: CPU_DN_SPEED")
}
Expand Down
2 changes: 2 additions & 0 deletions src/include/acpi/acpigen_dptf.h
Expand Up @@ -26,6 +26,8 @@ enum dptf_participant {
DPTF_TEMP_SENSOR_3,
DPTF_TEMP_SENSOR_4,
DPTF_TPCH,
DPTF_POWER,
DPTF_BATTERY,
DPTF_PARTICIPANT_COUNT,
};

Expand Down
3 changes: 2 additions & 1 deletion src/include/bootmode.h
Expand Up @@ -3,8 +3,9 @@
#ifndef __BOOTMODE_H__
#define __BOOTMODE_H__

#include <stdbool.h>

/* functions implemented per mainboard: */
void init_bootmode_straps(void);
int get_write_protect_state(void);
int get_recovery_mode_switch(void);
int get_recovery_mode_retrain_switch(void);
Expand Down
9 changes: 5 additions & 4 deletions src/include/cpu/intel/cpu_ids.h
Expand Up @@ -51,10 +51,11 @@
#define CPUID_ELKHARTLAKE_A0 0x90660
#define CPUID_ELKHARTLAKE_B0 0x90661
#define CPUID_ALDERLAKE_S_A0 0x90670
#define CPUID_ALDERLAKE_A0 0x906a0
#define CPUID_ALDERLAKE_A1 0x906a1
#define CPUID_ALDERLAKE_A2 0x906a2
#define CPUID_ALDERLAKE_A3 0x906a4
#define CPUID_ALDERLAKE_J0 0x906a0
#define CPUID_ALDERLAKE_Q0 0x906a1
#define CPUID_ALDERLAKE_K0 0x906a2
#define CPUID_ALDERLAKE_L0 0x906a3
#define CPUID_ALDERLAKE_R0 0x906a4
#define CPUID_ALDERLAKE_N_A0 0xb06e0
#define CPUID_METEORLAKE_A0_1 0xa06a0
#define CPUID_METEORLAKE_A0_2 0xa06a1
Expand Down
1 change: 1 addition & 0 deletions src/include/cpu/x86/mtrr.h
Expand Up @@ -96,6 +96,7 @@ void x86_setup_fixed_mtrrs(void);
/* Set up fixed MTRRs but do not enable them. */
void x86_setup_fixed_mtrrs_no_enable(void);
void x86_mtrr_check(void);
void need_restore_mtrr(void);

/* Insert a temporary MTRR range for the duration of coreboot's runtime.
* This function needs to be called after the first MTRR solution is derived. */
Expand Down
4 changes: 2 additions & 2 deletions src/include/device/i2c_bus.h
Expand Up @@ -21,14 +21,14 @@ struct i2c_bus_operations {
* `->dev->ops->ops_i2c_bus` or `->dev->ops->ops_smbus_bus` are
* not NULL.
*/
struct bus *i2c_link(struct device *);
struct bus *i2c_link(const struct device *dev);

/*
* Shorthand for `i2c_link(dev)->dev`.
*
* Returns NULL if i2c_link(dev) returns NULL.
*/
static inline DEVTREE_CONST struct device *i2c_busdev(struct device *dev)
static inline DEVTREE_CONST struct device *i2c_busdev(const struct device *dev)
{
struct bus *const link = i2c_link(dev);
return link ? link->dev : NULL;
Expand Down
13 changes: 13 additions & 0 deletions src/include/efi/efi_datatype.h
Expand Up @@ -7,12 +7,23 @@
#include <Uefi/UefiBaseType.h>

#if CONFIG_UDK_VERSION >= CONFIG_UDK_2017_VERSION
#include <Guid/StatusCodeDataTypeId.h>
#include <Pi/PiPeiCis.h>
#include <Pi/PiStatusCode.h>
#include <Protocol/MpService.h>

/* Data structure for EFI_PEI_SERVICE. */
typedef EFI_PEI_SERVICES efi_pei_services;
/* Structure that describes information about a logical CPU. */
typedef EFI_PROCESSOR_INFORMATION efi_processor_information;
/* Status code type definition */
typedef EFI_STATUS_CODE_TYPE efi_status_code_type_t;
/* Status value type definition */
typedef EFI_STATUS_CODE_VALUE efi_status_code_value_t;
/* Status data type definition */
typedef EFI_STATUS_CODE_DATA efi_status_code_data_t;
/* Status string data type definition */
typedef EFI_STATUS_CODE_STRING_DATA efi_status_code_string_data;
#endif

/* Basic Data types */
Expand Down Expand Up @@ -46,6 +57,8 @@ typedef INTN efi_intn_t;
typedef EFI_STATUS efi_return_status_t;
/* Data structure for EFI_PHYSICAL_ADDRESS */
typedef EFI_PHYSICAL_ADDRESS efi_physical_address;
/* 128-bit buffer containing a unique identifier value */
typedef EFI_GUID efi_guid_t;

/*
* The function prototype for invoking a function on an
Expand Down
2 changes: 1 addition & 1 deletion src/include/espi.h
Expand Up @@ -3,7 +3,7 @@
#ifndef __ESPI_H__
#define __ESPI_H__

#include <stdint.h>
#include <types.h>

/* ESPI Slave Registers (Document # 327432-004 Revision 1.0 Chapter 7) */

Expand Down
4 changes: 2 additions & 2 deletions src/include/spd.h
Expand Up @@ -236,8 +236,8 @@ enum ddr4_module_type {
DDR4_SPD_LRDIMM = 0x04,
DDR4_SPD_MINI_RDIMM = 0x05,
DDR4_SPD_MINI_UDIMM = 0x06,
DDR4_SPD_72B_SO_UDIMM = 0x08,
DDR4_SPD_72B_SO_RDIMM = 0x09,
DDR4_SPD_72B_SO_RDIMM = 0x08,
DDR4_SPD_72B_SO_UDIMM = 0x09,
DDR4_SPD_16B_SO_DIMM = 0x0c,
DDR4_SPD_32B_SO_RDIMM = 0x0d,
};
Expand Down
6 changes: 0 additions & 6 deletions src/include/string.h
Expand Up @@ -7,12 +7,6 @@
#include <stddef.h>
#include <stdio.h>

/* Stringify a token */
#ifndef STRINGIFY
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
#endif

void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
Expand Down
1 change: 1 addition & 0 deletions src/include/symbols.h
Expand Up @@ -76,6 +76,7 @@ DECLARE_REGION(pdpt)
DECLARE_OPTIONAL_REGION(opensbi)
DECLARE_OPTIONAL_REGION(bl31)
DECLARE_REGION(transfer_buffer)
DECLARE_OPTIONAL_REGION(watchdog_tombstone)

/* Returns true when pre-RAM symbols are known to the linker.
* (Does not necessarily mean that the memory is accessible.) */
Expand Down
4 changes: 2 additions & 2 deletions src/lib/bootmem.c
Expand Up @@ -110,8 +110,8 @@ void bootmem_write_memory_table(struct lb_memory *mem)
bootmem_dump_ranges();

memranges_each_entry(r, &bootmem_os) {
lb_r->start = pack_lb64(range_entry_base(r));
lb_r->size = pack_lb64(range_entry_size(r));
lb_r->start = range_entry_base(r);
lb_r->size = range_entry_size(r);
lb_r->type = bootmem_to_lb_tag(range_entry_tag(r));

lb_r++;
Expand Down