26 changes: 16 additions & 10 deletions Documentation/mainboard/ocp/deltalake.md
Expand Up @@ -14,8 +14,9 @@ Delta Lake server is a single socket Cooper Lake Scalable Processor server.
Yosemite-V3 has multiple configurations. Depending on configurations, it may
host up to 4 Delta Lake servers in one sled.

Yosemite-V3 and Delta Lake are currently in DVT phase. Facebook, Intel and partners
jointly develop FSP/coreboot/LinuxBoot stack on Delta Lake as an alternative solution.
The Yosemite-V3 program has reached DVT exit. Facebook, Intel and partners
jointly develop FSP/coreboot/LinuxBoot stack on Delta Lake as an alternative
solution. This development is moving toward EVT exit equivalent status.

## Required blobs

Expand Down Expand Up @@ -60,7 +61,6 @@ as initramfs.
- Type 8 -- Port Connector Information
- Type 9 -- PCI Slot Information
- Type 11 -- OEM String
- Type 13 -- BIOS Language Information
- Type 32 -- System Boot Information
- Type 38 -- IPMI Device Information
- Type 127 -- End-of-Table
Expand All @@ -87,12 +87,19 @@ as initramfs.
- Power button
- localboot
- netboot from IPv6
- TPM

## Stress/performance tests passed
- OS warm reboot overnight (6 hours)
- OS warm reboot (300 cycles)
- DC reboot (300 cycles)
- AC reboot (300 cycle)
- Mprime test (6 hours)
- StressAppTest (6 hours)
- Ptugen (6 hours)
- MLC (Intel Memory Latency Check)
- Linkpack
- Iperf(IPv6)
- FIO

## Firmware configurations
[ChromeOS VPD] is used to store most of the firmware configurations.
Expand All @@ -105,19 +112,18 @@ VPD variables supported are:
- DeltaLake specific VPDs: check mb/ocp/deltalake/vpd.h.

## Known issues
- ME based power capping. This is a bug in ME. An IPS ticket is filed
with Intel.
- HECI is not set up correctly, so BMC is not able to get PCH and DIMM
temperature sensor readings. An IPS ticket is filed.
- spsInfoLinux64 command fail to return ME version.
- fwts test failures related to mtrr.
- kernel error message related to SleepButton ACPI event.

## Feature gaps
- SMBIOS:
- Type 16 -- Physical Memory Array
- Type 17 -- Memory Device
- Type 19 -- Memory Array Mapped Address
- Type 41 -- Onboard Devices Extended Information
- Hardware error injection, detection, reporting
- PFR/CBnT
- Verified measurement through CBnT
- Boot guard of CBnT
- RO_VPD region as well as other RO regions are not write protected.

## Technology
Expand Down
@@ -0,0 +1,103 @@
# Supermicro X11SSH-F

This section details how to run coreboot on the [Supermicro X11SSH-F].

## Flashing coreboot

The board can be flashed externally. [STM32-based programmers] worked.

The flash IC "W25Q128.V" (detected by flashrom) can be found near PCH PCIe Slot 4. It is sometime
socketed, and covered by a sticker, hindering the observation of its precise model.

It can be programmed in-system with a clip like pomona 5250.

## BMC (IPMI)

This board has an ASPEED [AST2400], which has BMC/[IPMI] functionality. The BMC firmware resides in a
32 MiB SOIC-16 chip in the corner of the mainboard near the PCH PCIe Slot 4. This chip is a
[MX25L25635F].

## IGD

If an IGD is integrated with CPU, it will be enabled on this board. Though there is no video output
for it (The onboard VGA port is connected to BMC), it is said to be capable of being used for compute
tasks, or for offloading graphics rendering via "muxless" [vga_witcheroo].

## Tested and working

- SeaBIOS payload to boot Kali Linux live USB
- ECC ram (Linux' ie31200 driver works)
- Integrated graphics device available without output
- USB ports
- Ethernet
- SATA ports
- RS232 external
- PCIe slots
- BMC (IPMI)
- VGA on Aspeed
- TPM on TPM expansion header

## Known issues

- See general issue section
- S3 resume not working (vendor and coreboot)
- SeaBIOS cannot make use of VGA on Aspeed (even if IGD is disabled)

## ToDo

- Fix known issues
- Testing other payloads

## Technology

```eval_rst
+------------------+--------------------------------------------------+
| CPU | Intel Kaby Lake |
+------------------+--------------------------------------------------+
| PCH | Intel C236 |
+------------------+--------------------------------------------------+
| Coprocessor | Intel SPS (server version of the ME) |
+------------------+--------------------------------------------------+
| Super I/O | ASPEED AST2400 |
+------------------+--------------------------------------------------+
| Ethernet | 2x Intel I210-AT 1 GbE |
| | 1x dedicated BMC |
+------------------+--------------------------------------------------+
| PCIe slots | 1x 3.0 x8 |
| | 1x 3.0 x8 (in x16) |
| | 1x 3.0 x4 (in x8) |
| | 1x 3.0 x2 (in M.2 slot with key M) |
+------------------+--------------------------------------------------+
| USB slots | 2x USB 2.0 (ext) |
| | 2x USB 3.0 (ext) |
| | 1x USB 3.0 (int) |
| | 1x dual USB 3.0 header |
| | 2x dual USB 2.0 header |
+------------------+--------------------------------------------------+
| SATA slots | 8x S-ATA III |
+------------------+--------------------------------------------------+
| Other slots | 1x RS232 (ext) |
| | 1x RS232 header |
| | 1x TPM header |
| | 1x Power SMB header |
| | 5x PWM Fan connector |
| | 2x I-SGPIO |
| | 2x S-ATA DOM Power connector |
| | 1x XDP Port (connector may absent) |
| | 1x External BMC I2C Header (for IPMI card) |
| | 1x Chassis Intrusion Header |
+------------------+--------------------------------------------------+
```

## Extra links

- [Supermicro X11SSH-F]
- [Board manual]

[Supermicro X11SSH-F]: https://www.supermicro.com/en/products/motherboard/X11SSH-F
[Board manual]: https://www.supermicro.com/manuals/motherboard/C236/MNL-1778.pdf
[AST2400]: https://www.aspeedtech.com/products.php?fPath=20&rId=376
[IPMI]: ../../../../drivers/ipmi_kcs.md
[MX25L25635F]: https://media.digikey.com/pdf/Data%20Sheets/Macronix/MX25L25635F.pdf
[STM32-based programmers]: https://github.com/dword1511/stm32-vserprog
[vga_switcheroo]: https://01.org/linuxgraphics/gfx-docs/drm/gpu/vga-switcheroo.html
8 changes: 8 additions & 0 deletions MAINTAINERS
Expand Up @@ -208,6 +208,14 @@ F: src/mainboard/asus/p8z77-v_lx2/



CLEVO MAINBOARDS
M: Felix Singer <felixsinger@posteo.net>
M: Michael Niewöhner <foss@mniewoehner.de>
S: Supported
F: src/mainboard/clevo



FACEBOOK FBG1701 MAINBOARD
M: Frans Hendriks <fhendriks@eltan.com>
M: Wim Vervoorn <wvervoorn@eltan.com>
Expand Down
22 changes: 15 additions & 7 deletions Makefile.inc
Expand Up @@ -13,6 +13,7 @@ CONFIG_CBFS_PREFIX:=$(call strip_quotes,$(CONFIG_CBFS_PREFIX))
CONFIG_FMDFILE:=$(call strip_quotes,$(CONFIG_FMDFILE))
CONFIG_DEVICETREE:=$(call strip_quotes, $(CONFIG_DEVICETREE))
CONFIG_OVERRIDE_DEVICETREE:=$(call strip_quotes, $(CONFIG_OVERRIDE_DEVICETREE))
CONFIG_CHIPSET_DEVICETREE:=$(call strip_quotes, $(CONFIG_CHIPSET_DEVICETREE))
CONFIG_MEMLAYOUT_LD_FILE:=$(call strip_quotes, $(CONFIG_MEMLAYOUT_LD_FILE))

#######################################################################
Expand Down Expand Up @@ -79,9 +80,9 @@ subdirs-y := src/lib src/commonlib/ src/console src/device src/acpi
subdirs-y += src/ec/acpi $(wildcard src/ec/*/*) $(wildcard src/southbridge/*/*)
subdirs-y += $(wildcard src/soc/*/*) $(wildcard src/northbridge/*/*)
subdirs-y += src/superio
subdirs-y += $(wildcard src/drivers/*) $(wildcard src/drivers/*/*)
subdirs-y += $(wildcard src/drivers/*) $(wildcard src/drivers/*/*) $(wildcard src/drivers/*/*/*)
subdirs-y += src/cpu src/vendorcode
subdirs-y += util/cbfstool util/sconfig util/nvramtool util/pgtblgen
subdirs-y += util/cbfstool util/sconfig util/nvramtool util/pgtblgen util/amdfwtool
subdirs-y += util/futility util/marvell util/bincfg util/supermicro
subdirs-y += $(wildcard src/arch/*)
subdirs-y += src/mainboard/$(MAINBOARDDIR)
Expand Down Expand Up @@ -576,9 +577,6 @@ $(IFDTOOL):
cp -a $(top)/util/ifdtool/ifdtool $@

AMDFWTOOL:=$(objutil)/amdfwtool/amdfwtool
$(AMDFWTOOL): $(top)/util/amdfwtool/amdfwtool.c
@printf " HOSTCC $(subst $(obj)/,,$(@))\n"
$(HOSTCC) $(HOSTCFLAGS) -DCONFIG_ROM_SIZE=$(CONFIG_ROM_SIZE) -o $@ $<

APCB_EDIT_TOOL:=$(top)/util/apcb/apcb_edit.py

Expand All @@ -602,13 +600,24 @@ OVERRIDE_DEVICETREE_FILE := $(src)/mainboard/$(MAINBOARDDIR)/$(CONFIG_OVERRIDE_D
SCONFIG_OPTIONS += --override_devtree=$(OVERRIDE_DEVICETREE_FILE)
endif

ifneq ($(CONFIG_CHIPSET_DEVICETREE),)
CHIPSET_DEVICETREE_FILE := $(src)/$(CONFIG_CHIPSET_DEVICETREE)
SCONFIG_OPTIONS += --chipset_devtree=$(CHIPSET_DEVICETREE_FILE)
endif

DEVICETREE_STATIC_C := $(obj)/mainboard/$(MAINBOARDDIR)/static.c
SCONFIG_OPTIONS += --output_c=$(DEVICETREE_STATIC_C)

DEVICETREE_STATIC_H := $(obj)/static.h
SCONFIG_OPTIONS += --output_h=$(DEVICETREE_STATIC_H)

$(DEVICETREE_STATIC_C): $(DEVICETREE_FILE) $(OVERRIDE_DEVICETREE_FILE) $(objutil)/sconfig/sconfig
DEVICETREE_DEVICENAMES_H := $(obj)/static_devices.h
SCONFIG_OPTIONS += --output_d=$(DEVICETREE_DEVICENAMES_H)

DEVICETREE_FWCONFIG_H := $(obj)/static_fw_config.h
SCONFIG_OPTIONS += --output_f=$(DEVICETREE_FWCONFIG_H)

$(DEVICETREE_STATIC_C): $(DEVICETREE_FILE) $(OVERRIDE_DEVICETREE_FILE) $(CHIPSET_DEVICETREE_FILE) $(objutil)/sconfig/sconfig
@printf " SCONFIG $(subst $(src)/,,$(<))\n"
mkdir -p $(dir $(DEVICETREE_STATIC_C))
$(objutil)/sconfig/sconfig $(SCONFIG_OPTIONS)
Expand Down Expand Up @@ -1108,7 +1117,6 @@ RAMSTAGE=
endif

$(obj)/coreboot.rom: $(obj)/coreboot.pre $(RAMSTAGE) $(CBFSTOOL) $$(INTERMEDIATE)

@printf " CBFS $(subst $(obj)/,,$(@))\n"
# The full ROM may be larger than the CBFS part, so create an empty
# file (filled with \377 = 0xff) and copy the CBFS image over it.
Expand Down
10 changes: 10 additions & 0 deletions configs/config.asrock_b85m_pro4.tpm2_txt_placeholder_acms
@@ -0,0 +1,10 @@
# Known-working configuration to boot with TXT enabled. Since BIOS
# and SINIT ACM blobs are missing, use something else as placeholder.
# Used ACMs were extracted from a Supermicro X10SLH firmware update.
CONFIG_VENDOR_ASROCK=y
CONFIG_BOARD_ASROCK_B85M_PRO4=y
CONFIG_USER_TPM2=y
CONFIG_INTEL_TXT=y
CONFIG_INTEL_TXT_BIOSACM_FILE="3rdparty/blobs/cpu/intel/stm/stm.bin"
CONFIG_INTEL_TXT_SINITACM_FILE="3rdparty/blobs/cpu/intel/stm/stm.bin"
CONFIG_INTEL_TXT_LOGGING=y
1 change: 0 additions & 1 deletion configs/config.emulation_qemu_x86_i440fx_debug
Expand Up @@ -4,6 +4,5 @@ CONFIG_FATAL_ASSERTS=y
CONFIG_DEBUG_CBFS=y
CONFIG_DEBUG_PIRQ=y
CONFIG_DEBUG_MALLOC=y
CONFIG_TRACE=y
CONFIG_DEBUG_BOOT_STATE=y
CONFIG_DEBUG_ADA_CODE=y
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu1
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.5"
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_NO_GFX_INIT=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu2
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.5"
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU2=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu3
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.5"
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU3=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu4
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.5"
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU4=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu5
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.5"
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU5=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu6
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.5"
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU6=y
Expand Down
6 changes: 3 additions & 3 deletions payloads/coreinfo/pci_module.c
Expand Up @@ -151,7 +151,7 @@ static int pci_module_redraw(WINDOW *win)
return 0;
}

static void pci_scan_bus(int bus)
static void ci_pci_scan_bus(int bus)
{
int slot, func;
unsigned int val;
Expand Down Expand Up @@ -196,7 +196,7 @@ static void pci_scan_bus(int bus)

busses = pci_read_config32(dev, REG_PRIMARY_BUS);

pci_scan_bus((busses >> 8) & 0xff);
ci_pci_scan_bus((busses >> 8) & 0xff);

}
}
Expand Down Expand Up @@ -240,7 +240,7 @@ static int pci_module_handle(int key)

static int pci_module_init(void)
{
pci_scan_bus(0);
ci_pci_scan_bus(0);
return 0;
}

Expand Down
6 changes: 6 additions & 0 deletions payloads/external/BOOTBOOT/Kconfig
@@ -0,0 +1,6 @@
if PAYLOAD_BOOTBOOT

config PAYLOAD_FILE
default "payloads/external/BOOTBOOT/bootboot/dist/bootbootcb.elf"

endif
8 changes: 8 additions & 0 deletions payloads/external/BOOTBOOT/Kconfig.name
@@ -0,0 +1,8 @@
config PAYLOAD_BOOTBOOT
bool "BOOTBOOT"
depends on ARCH_X86 || ARCH_ARM64
help
Select this option if you want to build a coreboot image
with a BOOTBOOT Protocol payload.

See https://gitlab.com/bztsrc/bootboot for more information.
44 changes: 44 additions & 0 deletions payloads/external/BOOTBOOT/Makefile
@@ -0,0 +1,44 @@
project_git_repo=https://gitlab.com/bztsrc/bootboot.git
project_dir=bootboot
ifeq ($(CONFIG_COREBOOT_BUILD),)
include ../../../.config
endif
ifeq ($(CONFIG_ARCH_ARM64),y)
loader_dir=$(project_dir)/aarch64-cb
else
loader_dir=$(project_dir)/x86_64-cb
endif

unexport KCONFIG_AUTOHEADER
unexport KCONFIG_AUTOCONFIG
unexport KCONFIG_DEPENDENCIES
unexport KCONFIG_SPLITCONFIG
unexport KCONFIG_TRISTATE
unexport KCONFIG_NEGATIVES

all: bootboot

checkout:
echo " GIT BOOTBOOT $(loader_dir)"
test -L $(project_dir) || test -d $(project_dir) || \
git clone $(project_git_repo) $(project_dir)

bootboot: libpayload
echo " MAKE $(loader_dir)"
$(MAKE) -C $(loader_dir) LIBCONFIG_PATH=../../../libpayload

libpayload: checkout
cp $(loader_dir)/lib.config ../../libpayload/.config
cd ../../libpayload && $(MAKE) oldconfig && \
$(MAKE) && $(MAKE) DESTDIR=../external/BOOTBOOT/$(loader_dir) install

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

distclean:
rm -rf $(project_dir)

print-repo-info:
echo "$(project_git_repo) $(project_dir)"

.PHONY: checkout bootboot libpayload clean distclean print-repo-info
5 changes: 5 additions & 0 deletions payloads/external/Makefile.inc
Expand Up @@ -369,3 +369,8 @@ payloads/external/Yabits/uefi/build/uefi.elf yabits:
CONFIG_YABITS_MASTER=$(CONFIG_YABITS_MASTER) \
CONFIG_YABITS_STABLE=$(CONFIG_YABITS_STABLE) \
MFLAGS= MAKEFLAGS=

# BOOTBOOT

payloads/external/BOOTBOOT/bootboot/dist/bootbootcb.elf:
$(MAKE) -C payloads/external/BOOTBOOT all
5 changes: 5 additions & 0 deletions payloads/libpayload/arch/x86/sysinfo.c
Expand Up @@ -78,5 +78,10 @@ int lib_get_sysinfo(void)
lib_sysinfo.memrange[1].type = CB_MEM_RAM;
}

#if CONFIG(LP_PCI)
pci_init(&lib_sysinfo.pacc);
pci_scan_bus(&lib_sysinfo.pacc);
#endif

return ret;
}
9 changes: 1 addition & 8 deletions payloads/libpayload/curses/PDCurses/curses.h
Expand Up @@ -41,19 +41,14 @@ PDCurses portable platform definitions list:
/*----------------------------------------------------------------------*/

#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h> /* Required by X/Open usage below */

#ifdef PDC_WIDE
# include <wchar.h>
#endif

#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
extern "C"
{
# define bool _bool
#endif

/*----------------------------------------------------------------------
*
* PDCurses Manifest Constants
Expand Down Expand Up @@ -82,8 +77,6 @@ extern "C"
*
*/

typedef unsigned char bool; /* PDCurses Boolean type */

#ifdef CHTYPE_LONG
# if _LP64
typedef unsigned int chtype;
Expand Down
2 changes: 1 addition & 1 deletion payloads/libpayload/curses/curses.h
Expand Up @@ -87,7 +87,7 @@
* User-definable tweak to disable the include of <stdbool.h>.
*/
#ifndef NCURSES_ENABLE_STDBOOL_H
#define NCURSES_ENABLE_STDBOOL_H 0 //// XXX
#define NCURSES_ENABLE_STDBOOL_H 1
#endif

/*
Expand Down
20 changes: 11 additions & 9 deletions payloads/libpayload/drivers/i8042/keyboard.c
Expand Up @@ -27,6 +27,8 @@
* SUCH DAMAGE.
*/

#include <stdbool.h>

#include <keycodes.h>
#include <libpayload-config.h>
#include <libpayload.h>
Expand Down Expand Up @@ -169,14 +171,14 @@ static struct layout_maps keyboard_layouts[] = {
#endif
};

static unsigned char keyboard_cmd(unsigned char cmd)
static bool keyboard_cmd(unsigned char cmd)
{
i8042_write_data(cmd);

return i8042_wait_read_ps2() == 0xfa;
}

int keyboard_havechar(void)
bool keyboard_havechar(void)
{
return i8042_data_ready_ps2();
}
Expand Down Expand Up @@ -306,13 +308,13 @@ int keyboard_set_layout(char *country)
}

static struct console_input_driver cons = {
.havekey = keyboard_havechar,
.havekey = (int (*)(void))keyboard_havechar,
.getchar = keyboard_getchar,
.input_type = CONSOLE_INPUT_TYPE_EC,
};

/* Enable keyboard translated */
static int enable_translated(void)
static bool enable_translated(void)
{
if (!i8042_cmd(I8042_CMD_RD_CMD_BYTE)) {
int cmd = i8042_read_data_ps2();
Expand All @@ -321,19 +323,19 @@ static int enable_translated(void)
i8042_write_data(cmd);
} else {
printf("ERROR: i8042_cmd WR_CMD failed!\n");
return 0;
return false;
}
} else {
printf("ERROR: i8042_cmd RD_CMD failed!\n");
return 0;
return false;
}
return 1;
return true;
}

/* Set scancode set 1 */
static int set_scancode_set(void)
static bool set_scancode_set(void)
{
unsigned int ret;
bool ret;
ret = keyboard_cmd(I8042_KBCMD_SET_SCANCODE);
if (!ret) {
printf("ERROR: Keyboard set scancode failed!\n");
Expand Down
5 changes: 4 additions & 1 deletion payloads/libpayload/drivers/options.c
Expand Up @@ -26,8 +26,11 @@
* SUCH DAMAGE.
*/

#define __STDC_FORMAT_MACROS

#include <libpayload.h>
#include <coreboot_tables.h>
#include <inttypes.h>

u8 *mem_accessor_base;

Expand Down Expand Up @@ -325,7 +328,7 @@ int get_option_as_string(const struct nvram_accessor *nvram, struct cb_cmos_opti
/* only works on little endian.
26 bytes is enough for a 64bit value in decimal */
*dest = malloc(26);
sprintf(*dest, "%llu", *(u64*)raw);
sprintf(*dest, "%" PRIu64, *(u64 *)raw);
break;
case 's':
*dest = strdup(raw);
Expand Down
6 changes: 3 additions & 3 deletions payloads/libpayload/drivers/storage/Kconfig
Expand Up @@ -12,7 +12,7 @@ config STORAGE
config STORAGE_64BIT_LBA
bool "Use 64-bit integers to address sectors"
depends on STORAGE
default n
default y
help
If this is selected, sectors will be addressed by an 64-bit integer.
Select this to support LBA-48 for ATA drives.
Expand Down Expand Up @@ -45,7 +45,7 @@ config STORAGE_AHCI
config STORAGE_AHCI_ONLY_TESTED
bool "Only enable tested controllers"
depends on STORAGE_AHCI
default y
default n
help
If this option is selected only AHCI controllers which are known
If this option is selected, only AHCI controllers which are known
to work will be used.
40 changes: 9 additions & 31 deletions payloads/libpayload/drivers/storage/ahci.c
Expand Up @@ -227,34 +227,28 @@ static u32 working_controllers[] = {
0x8086 | 0x5ae3 << 16, /* Apollo Lake */
};
#endif
static void ahci_init_pci(pcidev_t dev)

void ahci_initialize(struct pci_dev *dev)
{
int i;

const u16 class = pci_read_config16(dev, 0xa);
if (class != 0x0106)
return;
const u16 vendor = pci_read_config16(dev, 0x00);
const u16 device = pci_read_config16(dev, 0x02);

#if CONFIG(LP_STORAGE_AHCI_ONLY_TESTED)
const u32 vendor_device = pci_read_config32(dev, 0x0);
const u32 vendor_device = dev->vendor_id | dev->device_id << 16;
for (i = 0; i < ARRAY_SIZE(working_controllers); ++i)
if (vendor_device == working_controllers[i])
break;
if (i == ARRAY_SIZE(working_controllers)) {
printf("ahci: Not using untested SATA controller "
"%02x:%02x.%02x (%04x:%04x).\n", PCI_BUS(dev),
PCI_SLOT(dev), PCI_FUNC(dev), vendor, device);
"%02x:%02x.%02x (%04x:%04x).\n", dev->bus,
dev->dev, dev->func, dev->vendor_id, dev->device_id);
return;
}
#endif

printf("ahci: Found SATA controller %02x:%02x.%02x (%04x:%04x).\n",
PCI_BUS(dev), PCI_SLOT(dev), PCI_FUNC(dev), vendor, device);
dev->bus, dev->dev, dev->func, dev->vendor_id, dev->device_id);

hba_ctrl_t *const ctrl = phys_to_virt(
pci_read_config32(dev, 0x24) & ~0x3ff);
hba_ctrl_t *const ctrl = phys_to_virt(pci_read_long(dev, 0x24) & ~0x3ff);
hba_port_t *const ports = ctrl->ports;

/* Reset host controller. */
Expand All @@ -273,28 +267,12 @@ static void ahci_init_pci(pcidev_t dev)
ctrl->global_ctrl |= HBA_CTRL_AHCI_EN;

/* Enable bus mastering. */
const u16 command = pci_read_config16(dev, PCI_COMMAND);
pci_write_config16(dev, PCI_COMMAND, command | PCI_COMMAND_MASTER);
const u16 command = pci_read_word(dev, PCI_COMMAND);
pci_write_word(dev, PCI_COMMAND, command | PCI_COMMAND_MASTER);

/* Probe for devices. */
for (i = 0; i < 32; ++i) {
if (ctrl->ports_impl & (1 << i))
ahci_port_probe(ctrl, &ports[i], i + 1);
}
}

void ahci_initialize(void)
{
int bus, dev, func;

for (bus = 0; bus < 256; ++bus) {
for (dev = 0; dev < 32; ++dev) {
const u16 class =
pci_read_config16(PCI_DEV(bus, dev, 0), 0xa);
if (class != 0xffff) {
for (func = 0; func < 8; ++func)
ahci_init_pci(PCI_DEV(bus, dev, func));
}
}
}
}
14 changes: 13 additions & 1 deletion payloads/libpayload/drivers/storage/storage.c
Expand Up @@ -27,6 +27,7 @@
*/

#include <libpayload.h>
#include <pci/pci.h>
#if CONFIG(LP_STORAGE_AHCI)
# include <storage/ahci.h>
#endif
Expand Down Expand Up @@ -108,7 +109,18 @@ ssize_t storage_read_blocks512(const size_t dev_num,
*/
void storage_initialize(void)
{
#if CONFIG(LP_PCI)
struct pci_dev *dev;
for (dev = lib_sysinfo.pacc.devices; dev; dev = dev->next) {
switch (dev->device_class) {
#if CONFIG(LP_STORAGE_AHCI)
ahci_initialize();
case PCI_CLASS_STORAGE_AHCI:
ahci_initialize(dev);
break;
#endif
default:
break;
}
}
#endif
}
Empty file modified payloads/libpayload/drivers/usb/usbmsc.c 100755 → 100644
Empty file.
1 change: 1 addition & 0 deletions payloads/libpayload/include/coreboot_tables.h
Expand Up @@ -79,6 +79,7 @@ enum {
CB_TAG_MMC_INFO = 0x0035,
CB_TAG_TCPA_LOG = 0x0036,
CB_TAG_FMAP = 0x0037,
CB_TAG_SMMSTOREV2 = 0x0039,
CB_TAG_CMOS_OPTION_TABLE = 0x00c8,
CB_TAG_OPTION = 0x00c9,
CB_TAG_OPTION_ENUM = 0x00ca,
Expand Down
14 changes: 13 additions & 1 deletion payloads/libpayload/include/libpayload.h
Expand Up @@ -42,6 +42,7 @@
#ifndef _LIBPAYLOAD_H
#define _LIBPAYLOAD_H

#include <stdbool.h>
#include <libpayload-config.h>
#include <compiler.h>
#include <cbgfx.h>
Expand Down Expand Up @@ -186,7 +187,7 @@ int add_reset_handler(void (*new_handler)(void));
*/
void keyboard_init(void);
void keyboard_disconnect(void);
int keyboard_havechar(void);
bool keyboard_havechar(void);
unsigned char keyboard_get_scancode(void);
int keyboard_getchar(void);
int keyboard_set_layout(char *country);
Expand Down Expand Up @@ -445,6 +446,8 @@ u8 hex2bin(u8 h);
void hexdump(const void *memory, size_t length);
void fatal(const char *msg) __attribute__((noreturn));

/* Population Count: number of bits that are one */
static inline int popcnt(u32 x) { return __builtin_popcount(x); }
/* Count Leading Zeroes: clz(0) == 32, clz(0xf) == 28, clz(1 << 31) == 0 */
static inline int clz(u32 x)
{
Expand All @@ -454,6 +457,15 @@ static inline int clz(u32 x)
static inline int log2(u32 x) { return (int)sizeof(x) * 8 - clz(x) - 1; }
/* Find First Set: __ffs(0xf) == 0, __ffs(0) == -1, __ffs(1 << 31) == 31 */
static inline int __ffs(u32 x) { return log2(x & (u32)(-(s32)x)); }

static inline int popcnt64(u64 x) { return __builtin_popcountll(x); }
static inline int clz64(u64 x)
{
return x ? __builtin_clzll(x) : sizeof(x) * 8;
}

static inline int log2_64(u64 x) { return sizeof(x) * 8 - clz64(x) - 1; }
static inline int __ffs64(u64 x) { return log2_64(x & (u64)(-(s64)x)); }
/** @} */

/**
Expand Down
2 changes: 2 additions & 0 deletions payloads/libpayload/include/pci/pci.h
Expand Up @@ -66,6 +66,7 @@
#define PCI_ROM_ADDRESS1 0x38 // on bridges
#define PCI_ROM_ADDRESS_MASK ~0x7ff

#define PCI_CLASS_STORAGE_AHCI 0x0106
#define PCI_CLASS_MEMORY_OTHER 0x0580

#define PCI_VENDOR_ID_INTEL 0x8086
Expand All @@ -74,6 +75,7 @@ struct pci_dev {
u16 domain;
u8 bus, dev, func;
u16 vendor_id, device_id;
u16 device_class;
struct pci_dev *next;
};

Expand Down
10 changes: 10 additions & 0 deletions payloads/libpayload/include/stdbool.h
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: BSD-3-Clause */

#ifndef __STDBOOL_H
#define __STDBOOL_H

#define bool _Bool
#define false 0
#define true (!false)

#endif
4 changes: 3 additions & 1 deletion payloads/libpayload/include/storage/ahci.h
Expand Up @@ -26,9 +26,11 @@
* SUCH DAMAGE.
*/

#include <pci/pci.h>

#ifndef _STORAGE_AHCI_H
#define _STORAGE_AHCI_H

void ahci_initialize(void);
void ahci_initialize(struct pci_dev *dev);

#endif
5 changes: 5 additions & 0 deletions payloads/libpayload/include/sysinfo.h
Expand Up @@ -29,6 +29,7 @@
#ifndef _SYSINFO_H
#define _SYSINFO_H

#include <pci/pci.h>
#include <stdint.h>

/* Maximum number of memory range definitions. */
Expand Down Expand Up @@ -130,6 +131,10 @@ struct sysinfo_t {

/* Pointer to FMAP cache in CBMEM */
uintptr_t fmap_cache;

#if CONFIG(LP_PCI)
struct pci_access pacc;
#endif
};

extern struct sysinfo_t lib_sysinfo;
Expand Down
32 changes: 32 additions & 0 deletions payloads/libpayload/include/x86/arch/cpuid.h
Expand Up @@ -32,4 +32,36 @@
#define cpuid(fn, eax, ebx, ecx, edx) \
asm("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "0"(fn))

#define _declare_cpuid(reg) \
static inline unsigned int cpuid_##reg(unsigned int fn) \
{ \
unsigned int eax, ebx, ecx, edx; \
cpuid(fn, eax, ebx, ecx, edx); \
return reg; \
}

_declare_cpuid(eax)
_declare_cpuid(ebx)
_declare_cpuid(ecx)
_declare_cpuid(edx)

#undef _declare_cpuid

static inline unsigned int cpuid_max(void)
{
return cpuid_eax(0);
}

static inline unsigned int cpuid_family(void)
{
const unsigned int eax = cpuid_eax(1);
return (eax & 0xff00000) >> (20 - 4) | (eax & 0xf00) >> 8;
}

static inline unsigned int cpuid_model(void)
{
const unsigned int eax = cpuid_eax(1);
return (eax & 0xf0000) >> (16 - 4) | (eax & 0xf0) >> 4;
}

#endif
5 changes: 4 additions & 1 deletion payloads/libpayload/libc/time.c
Expand Up @@ -31,11 +31,14 @@
* General time functions
*/

#define __STDC_FORMAT_MACROS

#include <libpayload-config.h>
#include <libpayload.h>
#if CONFIG(LP_ARCH_X86) && CONFIG(LP_NVRAM)
#include <arch/rdtsc.h>
#endif
#include <inttypes.h>

extern u32 cpu_khz;

Expand Down Expand Up @@ -173,7 +176,7 @@ u64 timer_us(u64 base)
if (hz == 0) {
hz = timer_hz();
if (hz < 1000000) {
printf("Timer frequency %lld is too low, "
printf("Timer frequency %" PRIu64 " is too low, "
"must be at least 1MHz.\n", hz);
halt();
}
Expand Down
4 changes: 2 additions & 2 deletions payloads/libpayload/libpci/libpci.c
Expand Up @@ -72,8 +72,7 @@ int pci_write_long(struct pci_dev *dev, int pos, u32 data)

struct pci_access *pci_alloc(void)
{
struct pci_access *pacc = malloc(sizeof(*pacc));
return pacc;
return malloc(sizeof(struct pci_access));
}

void pci_init(struct pci_access *pacc)
Expand Down Expand Up @@ -179,6 +178,7 @@ static struct pci_dev *pci_scan_single_bus(struct pci_dev *dev, uint8_t bus)
dev->func = func;
dev->vendor_id = val & 0xffff;
dev->device_id = (uint16_t)(val >> 16);
dev->device_class = pci_read_config16(PCI_DEV(bus, slot, func), PCI_CLASS_DEVICE);
dev->next = 0;

hdr = pci_read_config8(PCI_DEV(bus, slot, func),
Expand Down
14 changes: 13 additions & 1 deletion src/Kconfig
Expand Up @@ -536,13 +536,25 @@ source "src/vendorcode/*/Kconfig"

source "src/arch/*/Kconfig"

config CHIPSET_DEVICETREE
string
default ""
help
This symbol allows a chipset to provide a set of default settings in
a devicetree which are common to all mainboards. This may include
devices (including alias names), chip drivers, register settings,
and others. This path is relative to the src/ directory.

Example: "chipset.cb"

endmenu

source "src/device/Kconfig"

menu "Generic Drivers"
source "src/drivers/*/Kconfig"
source "src/drivers/*/*/Kconfig"
source "src/drivers/*/*/*/Kconfig"
source "src/commonlib/storage/Kconfig"
endmenu

Expand Down Expand Up @@ -878,7 +890,7 @@ config DEBUG_SMI
bool "Output verbose SMI debug messages"
default n
depends on HAVE_SMI_HANDLER
select SPI_FLASH_SMM if SPI_CONSOLE || CONSOLE_SPI_FLASH
select SPI_FLASH_SMM if EM100PRO_SPI_CONSOLE || CONSOLE_SPI_FLASH
help
This option enables additional SMI related debug messages.

Expand Down
3 changes: 2 additions & 1 deletion src/acpi/acpi.c
Expand Up @@ -1367,7 +1367,8 @@ unsigned long write_acpi_tables(unsigned long start)
if (slic_file
&& (slic_file->length > slic_size
|| slic_file->length < sizeof(acpi_header_t)
|| memcmp(slic_file->signature, "SLIC", 4) != 0)) {
|| (memcmp(slic_file->signature, "SLIC", 4) != 0
&& memcmp(slic_file->signature, "MSDM", 4) != 0))) {
slic_file = 0;
}

Expand Down
48 changes: 42 additions & 6 deletions src/acpi/acpigen.c
Expand Up @@ -408,7 +408,7 @@ void acpigen_write_processor_cnot(const unsigned int number_of_cores)
* len is region length.
* OperationRegion(regionname, regionspace, regionoffset, regionlength)
*/
void acpigen_write_opregion(struct opregion *opreg)
void acpigen_write_opregion(const struct opregion *opreg)
{
/* OpregionOp */
acpigen_emit_ext_op(OPREGION_OP);
Expand Down Expand Up @@ -505,6 +505,12 @@ static void acpigen_write_field_name(const char *name, uint32_t size)
acpigen_write_field_length(size);
}

static void acpigen_write_field_reserved(uint32_t size)
{
acpigen_emit_byte(0);
acpigen_write_field_length(size);
}

/*
* Generate ACPI AML code for Field
* Arg0: region name
Expand All @@ -515,14 +521,16 @@ static void acpigen_write_field_name(const char *name, uint32_t size)
* struct fieldlist l[] = {
* FIELDLIST_OFFSET(0x84),
* FIELDLIST_NAMESTR("PMCS", 2),
* FIELDLIST_RESERVED(6),
* };
* acpigen_write_field("UART", l, ARRAY_SIZE(l), FIELD_ANYACC | FIELD_NOLOCK |
* FIELD_PRESERVE);
* Output:
* Field (UART, AnyAcc, NoLock, Preserve)
* {
* Offset (0x84),
* PMCS, 2
* PMCS, 2,
* , 6,
* }
*/
void acpigen_write_field(const char *name, const struct fieldlist *l, size_t count,
Expand All @@ -546,6 +554,10 @@ void acpigen_write_field(const char *name, const struct fieldlist *l, size_t cou
acpigen_write_field_name(l[i].name, l[i].bits);
current_bit_pos += l[i].bits;
break;
case RESERVED:
acpigen_write_field_reserved(l[i].bits);
current_bit_pos += l[i].bits;
break;
case OFFSET:
acpigen_write_field_offset(l[i].bits, current_bit_pos);
current_bit_pos = l[i].bits;
Expand Down Expand Up @@ -1231,6 +1243,22 @@ void acpigen_write_store_op_to_namestr(uint8_t src, const char *dst)
acpigen_emit_namestring(dst);
}

/* Store (src, "namestr") */
void acpigen_write_store_int_to_namestr(uint64_t src, const char *dst)
{
acpigen_write_store();
acpigen_write_integer(src);
acpigen_emit_namestring(dst);
}

/* Store (src, dst) */
void acpigen_write_store_int_to_op(uint64_t src, uint8_t dst)
{
acpigen_write_store();
acpigen_write_integer(src);
acpigen_emit_byte(dst);
}

/* Or (arg1, arg2, res) */
void acpigen_write_or(uint8_t arg1, uint8_t arg2, uint8_t res)
{
Expand Down Expand Up @@ -1353,6 +1381,14 @@ void acpigen_write_else(void)
acpigen_write_len_f();
}

void acpigen_write_shiftleft_op_int(uint8_t src_result, uint64_t count)
{
acpigen_emit_byte(SHIFT_LEFT_OP);
acpigen_emit_byte(src_result);
acpigen_write_integer(count);
acpigen_emit_byte(ZERO_OP);
}

void acpigen_write_to_buffer(uint8_t src, uint8_t dst)
{
acpigen_emit_byte(TO_BUFFER_OP);
Expand Down Expand Up @@ -1829,31 +1865,31 @@ int __weak acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
*
* Returns 0 on success and -1 on error.
*/
int acpigen_enable_tx_gpio(struct acpi_gpio *gpio)
int acpigen_enable_tx_gpio(const struct acpi_gpio *gpio)
{
if (gpio->active_low)
return acpigen_soc_clear_tx_gpio(gpio->pins[0]);
else
return acpigen_soc_set_tx_gpio(gpio->pins[0]);
}

int acpigen_disable_tx_gpio(struct acpi_gpio *gpio)
int acpigen_disable_tx_gpio(const struct acpi_gpio *gpio)
{
if (gpio->active_low)
return acpigen_soc_set_tx_gpio(gpio->pins[0]);
else
return acpigen_soc_clear_tx_gpio(gpio->pins[0]);
}

void acpigen_get_rx_gpio(struct acpi_gpio *gpio)
void acpigen_get_rx_gpio(const struct acpi_gpio *gpio)
{
acpigen_soc_read_rx_gpio(gpio->pins[0]);

if (gpio->active_low)
acpigen_write_xor(LOCAL0_OP, 1, LOCAL0_OP);
}

void acpigen_get_tx_gpio(struct acpi_gpio *gpio)
void acpigen_get_tx_gpio(const struct acpi_gpio *gpio)
{
acpigen_soc_get_tx_gpio(gpio->pins[0]);

Expand Down
23 changes: 11 additions & 12 deletions src/acpi/acpigen_dsm.c
Expand Up @@ -7,28 +7,27 @@

#define ACPI_DSM_I2C_HID_UUID "3CDFF6F7-4267-4555-AD05-B30A3D8938DE"

/* I2C HID currently supports revision 1 only, for which, only 1 additional
* function is supported. Thus, the query function should return 0x3:
* bit 0 = additional function supported
* bit 1 = function with index 1 supported
* All other revisions do not support additional functions and hence return 0
*/

static void i2c_hid_func0_cb(void *arg)
{
/* ToInteger (Arg1, Local2) */
acpigen_write_to_integer(ARG1_OP, LOCAL2_OP);
/* If (LEqual (Local2, 0x0)) */
acpigen_write_if_lequal_op_int(LOCAL2_OP, 0x0);
/* Return (Buffer (One) { 0x1f }) */
acpigen_write_return_singleton_buffer(0x1f);
acpigen_pop_len(); /* Pop : If */
/* Else */
acpigen_write_else();
/* If (LEqual (Local2, 0x1)) */
/* If (LEqual (Local2, 0x1)) */
acpigen_write_if_lequal_op_int(LOCAL2_OP, 0x1);
/* Return (Buffer (One) { 0x3f }) */
acpigen_write_return_singleton_buffer(0x3f);
/* Return (Buffer (One) { 0x3 }) */
acpigen_write_return_singleton_buffer(0x3);
acpigen_pop_len(); /* Pop : If */
/* Else */
/* Else */
acpigen_write_else();
/* Return (Buffer (One) { 0x0 }) */
acpigen_write_return_singleton_buffer(0x0);
acpigen_pop_len(); /* Pop : Else */
acpigen_pop_len(); /* Pop : Else */
}

static void i2c_hid_func1_cb(void *arg)
Expand Down
2 changes: 1 addition & 1 deletion src/acpi/acpigen_usb.c
Expand Up @@ -71,7 +71,7 @@ static void add_device_ref(struct acpi_dp *dsd,
const char *path;
char *fresh;

if (!dev)
if (!dev || !dev->enabled)
return;

/*
Expand Down
67 changes: 53 additions & 14 deletions src/acpi/device.c
Expand Up @@ -1019,33 +1019,72 @@ struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
return dp_array;
}

struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
const char *ref, int index, int pin,
int active_low)
struct acpi_dp *acpi_dp_add_gpio_array(struct acpi_dp *dp, const char *name,
const struct acpi_gpio_res_params *params,
size_t param_count)
{
if (!dp)
return NULL;
struct acpi_dp *gpio;
uint32_t i;

struct acpi_dp *gpio = acpi_dp_new_table(name);
if (!dp || !param_count)
return NULL;

gpio = acpi_dp_new_table(name);
if (!gpio)
return NULL;

/* The device that has _CRS containing GpioIO()/GpioInt() */
acpi_dp_add_reference(gpio, NULL, ref);
/*
* Generate ACPI identifiers as follows:
* Package () {
* name, // e.g. cs-gpios
* Package() {
* ref, index, pin, active_low, // GPIO-0 (params[0])
* ref, index, pin, active_low, // GPIO-1 (params[1])
* ...
* }
* }
*/
for (i = 0; i < param_count; i++, params++) {
/*
* If refs is NULL, leave a hole in the gpio array. This can be used in
* conditions where some controllers use both GPIOs and native signals.
*/
if (!params->ref) {
acpi_dp_add_integer(gpio, NULL, 0);
continue;
}

/* Index of the GPIO resource in _CRS starting from zero */
acpi_dp_add_integer(gpio, NULL, index);
/* The device that has _CRS containing GpioIO()/GpioInt() */
acpi_dp_add_reference(gpio, NULL, params->ref);

/* Pin in the GPIO resource, typically zero */
acpi_dp_add_integer(gpio, NULL, pin);
/* Index of the GPIO resource in _CRS starting from zero */
acpi_dp_add_integer(gpio, NULL, params->index);

/* Set if pin is active low */
acpi_dp_add_integer(gpio, NULL, active_low);
/* Pin in the GPIO resource, typically zero */
acpi_dp_add_integer(gpio, NULL, params->pin);

/* Set if pin is active low */
acpi_dp_add_integer(gpio, NULL, params->active_low);
}
acpi_dp_add_array(dp, gpio);

return gpio;

}


struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
const char *ref, int index, int pin,
int active_low)
{
struct acpi_gpio_res_params param = {
.ref = ref,
.index = index,
.pin = pin,
.active_low = active_low,
};

return acpi_dp_add_gpio_array(dp, name, &param, 1);
}

/*
Expand Down
1 change: 1 addition & 0 deletions src/arch/arm64/Makefile.inc
Expand Up @@ -31,6 +31,7 @@ bootblock-y += id.S
$(call src-to-obj,decompressor,$(dir)/id.S): $(obj)/build.h
$(call src-to-obj,bootblock,$(dir)/id.S): $(obj)/build.h

decompressor-$(CONFIG_ARM64_USE_ARCH_TIMER) += arch_timer.c
bootblock-$(CONFIG_ARM64_USE_ARCH_TIMER) += arch_timer.c
bootblock-y += transition.c transition_asm.S

Expand Down
16 changes: 15 additions & 1 deletion src/arch/x86/Kconfig
Expand Up @@ -28,6 +28,13 @@ config ARCH_RAMSTAGE_X86_32
bool
select ARCH_X86

config ARCH_ALL_STAGES_X86_32
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32

# stage selectors for x64

config ARCH_BOOTBLOCK_X86_64
Expand All @@ -50,12 +57,19 @@ config ARCH_RAMSTAGE_X86_64
bool
select ARCH_X86

config ARCH_ALL_STAGES_X86_64
bool
select ARCH_BOOTBLOCK_X86_64
select ARCH_VERSTAGE_X86_64
select ARCH_ROMSTAGE_X86_64
select ARCH_RAMSTAGE_X86_64

if ARCH_X86

config ARCH_X86_64_PGTBL_LOC
hex "x86_64 page table location in CBFS"
depends on ARCH_BOOTBLOCK_X86_64
default 0xfffea000
default 0xfffe9000
help
The position where to place pagetables. Needs to be known at
compile time. Must not overlap other files in CBFS.
Expand Down
6 changes: 0 additions & 6 deletions src/arch/x86/bootblock_crt0.S
Expand Up @@ -20,12 +20,6 @@
#include <cpu/x86/16bit/reset16.inc>
#include <cpu/x86/32bit/entry32.inc>

/* BIST result in eax */
mov %eax, %ebx
/* entry64.inc preserves ebx. */
#include <cpu/x86/64bit/entry64.inc>
mov %ebx, %eax

#if CONFIG(BOOTBLOCK_DEBUG_SPINLOOP)

/* Wait for a JTAG debugger to break in and set EBX non-zero */
Expand Down
69 changes: 62 additions & 7 deletions src/arch/x86/smbios.c
Expand Up @@ -430,6 +430,8 @@ static int smbios_write_type0(unsigned long *current, int handle)
t->system_bios_major_release = coreboot_major_revision;
t->system_bios_minor_release = coreboot_minor_revision;

smbios_ec_revision(&t->ec_major_release, &t->ec_minor_release);

t->bios_characteristics =
BIOS_CHARACTERISTICS_PCI_SUPPORTED |
BIOS_CHARACTERISTICS_SELECTABLE_BOOT |
Expand Down Expand Up @@ -476,6 +478,51 @@ unsigned int __weak smbios_processor_family(struct cpuid_result res)
return (res.eax > 0) ? 0x0c : 0x6;
}

unsigned int __weak smbios_cache_error_correction_type(u8 level)
{
return SMBIOS_CACHE_ERROR_CORRECTION_UNKNOWN;
}

unsigned int __weak smbios_cache_sram_type(void)
{
return SMBIOS_CACHE_SRAM_TYPE_UNKNOWN;
}

unsigned int __weak smbios_cache_conf_operation_mode(u8 level)
{
return SMBIOS_CACHE_OP_MODE_UNKNOWN; /* Unknown */
}

static size_t get_number_of_caches(struct cpuid_result res_deterministic_cache)
{
size_t max_logical_cpus_sharing_cache = 0;
size_t number_of_cpus_per_package = 0;
size_t max_logical_cpus_per_package = 0;
struct cpuid_result res;

if (!cpu_have_cpuid())
return 1;

res = cpuid(1);

max_logical_cpus_per_package = (res.ebx >> 16) & 0xff;

max_logical_cpus_sharing_cache = ((res_deterministic_cache.eax >> 14) & 0xfff) + 1;

/* Check if it's last level cache */
if (max_logical_cpus_sharing_cache == max_logical_cpus_per_package)
return 1;

if (cpuid_get_max_func() >= 0xb) {
res = cpuid_ext(0xb, 1);
number_of_cpus_per_package = res.ebx & 0xff;
} else {
number_of_cpus_per_package = max_logical_cpus_per_package;
}

return number_of_cpus_per_package / max_logical_cpus_sharing_cache;
}

static int smbios_write_type1(unsigned long *current, int handle)
{
struct smbios_type1 *t = (struct smbios_type1 *)*current;
Expand Down Expand Up @@ -552,6 +599,8 @@ static int smbios_write_type4(unsigned long *current, int handle)
struct smbios_type4 *t = (struct smbios_type4 *)*current;
int len = sizeof(struct smbios_type4);
uint16_t characteristics = 0;
static unsigned int cnt = 0;
char buf[8];

/* Provide sane defaults even for CPU without CPUID */
res.eax = res.edx = 0;
Expand All @@ -564,6 +613,10 @@ static int smbios_write_type4(unsigned long *current, int handle)
t->type = SMBIOS_PROCESSOR_INFORMATION;
t->handle = handle;
t->length = len - 2;

snprintf(buf, sizeof(buf), "CPU%d", cnt++);
t->socket_designation = smbios_add_string(t->eos, buf);

t->processor_id[0] = res.eax;
t->processor_id[1] = res.edx;
t->processor_manufacturer = smbios_cpu_vendor(t->eos);
Expand All @@ -588,11 +641,13 @@ static int smbios_write_type4(unsigned long *current, int handle)
}
t->core_count2 = leaf_b_cores / leaf_b_threads;
t->core_count = t->core_count2 > 0xff ? 0xff : t->core_count2;
t->thread_count2 = leaf_b_threads;
t->thread_count2 = leaf_b_cores;
t->thread_count = t->thread_count2 > 0xff ? 0xff : t->thread_count2;
} else {
t->core_count = (res.ebx >> 16) & 0xff;
t->core_count2 = t->core_count;
t->thread_count2 = t->core_count2;
t->thread_count = t->thread_count2;
}
/* Assume we enable all the cores always, capped only by MAX_CPUS */
t->core_enabled = MIN(t->core_count, CONFIG_MAX_CPUS);
Expand Down Expand Up @@ -652,21 +707,20 @@ static int smbios_write_type7(unsigned long *current,
{
struct smbios_type7 *t = (struct smbios_type7 *)*current;
int len = sizeof(struct smbios_type7);
static unsigned int cnt = 0;
char buf[8];

memset(t, 0, sizeof(struct smbios_type7));
t->type = SMBIOS_CACHE_INFORMATION;
t->handle = handle;
t->length = len - 2;

snprintf(buf, sizeof(buf), "CACHE%x", cnt++);
snprintf(buf, sizeof(buf), "CACHE%x", level);
t->socket_designation = smbios_add_string(t->eos, buf);

t->cache_configuration = SMBIOS_CACHE_CONF_LEVEL(level) |
SMBIOS_CACHE_CONF_LOCATION(0) | /* Internal */
SMBIOS_CACHE_CONF_ENABLED(1) | /* Enabled */
SMBIOS_CACHE_CONF_OPERATION_MODE(3); /* Unknown */
SMBIOS_CACHE_CONF_OPERATION_MODE(smbios_cache_conf_operation_mode(level));

if (max_cache_size < (SMBIOS_CACHE_SIZE_MASK * KiB)) {
t->max_cache_size = max_cache_size / KiB;
Expand Down Expand Up @@ -706,7 +760,7 @@ static int smbios_write_type7(unsigned long *current,
t->supported_sram_type = sram_type;
t->current_sram_type = sram_type;
t->cache_speed = 0; /* Unknown */
t->error_correction_type = SMBIOS_CACHE_ERROR_CORRECTION_UNKNOWN;
t->error_correction_type = smbios_cache_error_correction_type(level);
t->system_cache_type = type;

len = t->length + smbios_string_table_len(t->eos);
Expand Down Expand Up @@ -801,7 +855,8 @@ static int smbios_write_type7_cache_parameters(unsigned long *current,
const size_t partitions = CPUID_CACHE_PHYS_LINE(res) + 1;
const size_t cache_line_size = CPUID_CACHE_COHER_LINE(res) + 1;
const size_t number_of_sets = CPUID_CACHE_NO_OF_SETS(res) + 1;
const size_t cache_size = assoc * partitions * cache_line_size * number_of_sets;
const size_t cache_size = assoc * partitions * cache_line_size * number_of_sets
* get_number_of_caches(res);

if (!cache_type)
/* No more caches in the system */
Expand Down Expand Up @@ -830,7 +885,7 @@ static int smbios_write_type7_cache_parameters(unsigned long *current,
const int h = (*handle)++;

update_max(len, *max_struct_size, smbios_write_type7(current, h,
level, SMBIOS_CACHE_SRAM_TYPE_UNKNOWN, associativity,
level, smbios_cache_sram_type(), associativity,
type, cache_size, cache_size));

if (type4) {
Expand Down
6 changes: 6 additions & 0 deletions src/arch/x86/smbios_defaults.c
Expand Up @@ -63,6 +63,12 @@ __weak smbios_board_type smbios_mainboard_board_type(void)
return SMBIOS_BOARD_TYPE_UNKNOWN;
}

__weak void smbios_ec_revision(uint8_t *ec_major_revision, uint8_t *ec_minor_revision)
{
*ec_major_revision = 0x0;
*ec_minor_revision = 0x0;
}

/*
* System Enclosure or Chassis Types as defined in SMBIOS specification.
* The default value is SMBIOS_ENCLOSURE_DESKTOP (0x03) but laptop,
Expand Down
1 change: 1 addition & 0 deletions src/commonlib/include/commonlib/cbmem_id.h
Expand Up @@ -69,6 +69,7 @@
#define CBMEM_ID_ROM3 0x524f4d33
#define CBMEM_ID_FMAP 0x464d4150
#define CBMEM_ID_FSP_LOGO 0x4c4f474f
#define CBMEM_ID_SMM_COMBUFFER 0x53534d32

#define CBMEM_ID_TO_NAME_TABLE \
{ CBMEM_ID_ACPI, "ACPI " }, \
Expand Down
17 changes: 17 additions & 0 deletions src/commonlib/include/commonlib/coreboot_tables.h
Expand Up @@ -80,6 +80,7 @@ enum {
LB_TAG_TCPA_LOG = 0x0036,
LB_TAG_FMAP = 0x0037,
LB_TAG_PLATFORM_BLOB_VERSION = 0x0038,
LB_TAG_SMMSTOREV2 = 0x0039,
LB_TAG_CMOS_OPTION_TABLE = 0x00c8,
LB_TAG_OPTION = 0x00c9,
LB_TAG_OPTION_ENUM = 0x00ca,
Expand Down Expand Up @@ -484,4 +485,20 @@ struct cmos_checksum {
#define CHECKSUM_PCBIOS 1
};

/* SMMSTOREv2 record
* This record contains information to use SMMSTOREv2.
*/

struct lb_smmstorev2 {
uint32_t tag;
uint32_t size;
uint32_t num_blocks; /* Number of writeable blocks in SMM */
uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */
uint32_t mmap_addr; /* MMIO address of the store for read only access */
uint32_t com_buffer; /* Physical address of the communication buffer */
uint32_t com_buffer_size; /* Size of the communication buffer in bytes */
uint8_t apm_cmd; /* The command byte to write to the APM I/O port */
uint8_t unused[3]; /* Set to zero */
};

#endif
6 changes: 3 additions & 3 deletions src/console/Kconfig
Expand Up @@ -294,9 +294,9 @@ config CONSOLE_QEMU_DEBUGCON_PORT
depends on CONSOLE_QEMU_DEBUGCON
default 0x402

config SPI_CONSOLE
bool "SPI debug console output"
depends on HAVE_SPI_CONSOLE_SUPPORT && !DEBUG_SPI_FLASH
config EM100PRO_SPI_CONSOLE
bool "EM100Pro SPI debug console output"
depends on HAVE_EM100PRO_SPI_CONSOLE_SUPPORT && !DEBUG_SPI_FLASH
help
Enable support for the debug console on the Dediprog EM100Pro.
This is currently working only in ramstage due to how the spi
Expand Down
25 changes: 5 additions & 20 deletions src/console/init.c
Expand Up @@ -8,40 +8,25 @@
#include <option.h>
#include <version.h>

/* Mutable console log level only allowed when RAM comes online. */
#define CONSOLE_LEVEL_CONST !ENV_STAGE_HAS_DATA_SECTION
#define FIRST_CONSOLE (ENV_BOOTBLOCK || (CONFIG(NO_BOOTBLOCK_CONSOLE) && ENV_ROMSTAGE))

static int console_inited;
static int console_loglevel = CONFIG_DEFAULT_CONSOLE_LOGLEVEL;
static int console_loglevel;

static inline int get_log_level(void)
{
if (console_inited == 0)
return -1;
if (CONSOLE_LEVEL_CONST)
return get_console_loglevel();

return console_loglevel;
}

static inline void set_log_level(int new_level)
{
if (CONSOLE_LEVEL_CONST)
return;

console_loglevel = new_level;
}

static void init_log_level(void)
{
int debug_level = get_console_loglevel();

if (CONSOLE_LEVEL_CONST)
return;

get_option(&debug_level, "debug_level");
console_loglevel = get_console_loglevel();

set_log_level(debug_level);
if (!FIRST_CONSOLE)
get_option(&console_loglevel, "debug_level");
}

int console_log_level(int msg_level)
Expand Down
5 changes: 1 addition & 4 deletions src/cpu/amd/agesa/Kconfig
Expand Up @@ -6,10 +6,7 @@ config CPU_AMD_AGESA
default y if CPU_AMD_AGESA_FAMILY15_TN
default y if CPU_AMD_AGESA_FAMILY16_KB
default n
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select DRIVERS_AMD_PI
select TSC_SYNC_LFENCE
select UDELAY_LAPIC
Expand Down
5 changes: 1 addition & 4 deletions src/cpu/amd/pi/Kconfig
Expand Up @@ -6,10 +6,7 @@ config CPU_AMD_PI
default y if CPU_AMD_PI_00730F01
default y if CPU_AMD_PI_00660F01
default n
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select DRIVERS_AMD_PI
select TSC_SYNC_LFENCE
select UDELAY_LAPIC
Expand Down
11 changes: 8 additions & 3 deletions src/cpu/intel/common/Kconfig
Expand Up @@ -19,10 +19,15 @@ config SET_IA32_FC_LOCK_BIT
However, leaving the lock bit unset will break Windows' detection of
VMX support and built-in virtualization features like Hyper-V.

config CPU_INTEL_COMMON_TIMEBASE
bool
config SET_MSR_AESNI_LOCK_BIT
bool "Lock the AES-NI enablement state"
default y
help
This config sets the AES-NI lock bit, if available, to prevent any
further change of AES-NI enablement. This may be disabled for e.g.
testing or debugging.

config CPU_INTEL_COMMON_HYPERTHREADING
config CPU_INTEL_COMMON_TIMEBASE
bool

endif
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/common/Makefile.inc
@@ -1,5 +1,5 @@
ramstage-$(CONFIG_CPU_INTEL_COMMON) += common_init.c
ramstage-$(CONFIG_CPU_INTEL_COMMON_HYPERTHREADING) += hyperthreading.c
ramstage-$(CONFIG_CPU_INTEL_COMMON) += hyperthreading.c

ifeq ($(CONFIG_CPU_INTEL_COMMON_TIMEBASE),y)
bootblock-y += fsb.c
Expand Down
18 changes: 18 additions & 0 deletions src/cpu/intel/common/common.h
Expand Up @@ -27,4 +27,22 @@ bool intel_ht_supported(void);
*/
bool intel_ht_sibling(void);

/*
* Lock AES-NI feature (MSR_FEATURE_CONFIG) to prevent unintended changes
* to the enablement state as suggested in Intel document 325384-070US.
*/
void set_aesni_lock(void);

/* Enable local CPU APIC TPR (Task Priority Register) updates */
void enable_lapic_tpr(void);

/* Enable DCA (Direct Cache Access) */
void configure_dca_cap(void);

/*
* Set EPB (Energy Performance Bias)
* Possible values are 0 (performance) to 15 (powersave).
*/
void set_energy_perf_bias(u8 policy);

#endif
67 changes: 63 additions & 4 deletions src/cpu/intel/common/common_init.c
Expand Up @@ -3,9 +3,13 @@
#include <acpi/acpigen.h>
#include <arch/cpu.h>
#include <console/console.h>
#include <cpu/intel/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/msr.h>
#include "common.h"

#define CPUID_6_ECX_EPB (1 << 3)

void set_vmx_and_lock(void)
{
set_feature_ctrl_vmx();
Expand Down Expand Up @@ -235,11 +239,23 @@ void cpu_init_cppc_config(struct cppc_config *config, u32 version)
if (version >= 2) {
/* Autonomous Selection Enable is populated below */

/* Autonomous Activity Window Register */
config->regs[CPPC_AUTO_ACTIVITY_WINDOW] = unsupported;
msr.addrl = IA32_HWP_REQUEST;

/*
* Autonomous Activity Window Register
* ResourceTemplate(){Register(FFixedHW, 0x0a, 0x20, 0x774, 0x04,)},
*/
msr.bit_width = 10;
msr.bit_offset = 32;
config->regs[CPPC_AUTO_ACTIVITY_WINDOW] = msr;

/* Energy Performance Preference Register */
config->regs[CPPC_PERF_PREF] = unsupported;
/*
* Autonomous Energy Performance Preference Register
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x18, 0x774, 0x04,)},
*/
msr.bit_width = 8;
msr.bit_offset = 24;
config->regs[CPPC_PERF_PREF] = msr;

/* Reference Performance */
config->regs[CPPC_REF_PERF] = unsupported;
Expand All @@ -264,3 +280,46 @@ void cpu_init_cppc_config(struct cppc_config *config, u32 version)
config->regs[CPPC_AUTO_SELECT] = msr;
}
}

void set_aesni_lock(void)
{
msr_t msr;

if (!CONFIG(SET_MSR_AESNI_LOCK_BIT))
return;

if (!(cpu_get_feature_flags_ecx() & CPUID_AES))
return;

/* Only run once per core as specified in the MSR datasheet */
if (intel_ht_sibling())
return;

msr = rdmsr(MSR_FEATURE_CONFIG);
if (msr.lo & AESNI_LOCK)
return;

msr_set(MSR_FEATURE_CONFIG, AESNI_LOCK);
}

void enable_lapic_tpr(void)
{
msr_unset(MSR_PIC_MSG_CONTROL, TPR_UPDATES_DISABLE);
}

void configure_dca_cap(void)
{
if (cpu_get_feature_flags_ecx() & CPUID_DCA)
msr_set(IA32_PLATFORM_DCA_CAP, DCA_TYPE0_EN);
}

void set_energy_perf_bias(u8 policy)
{
u8 epb = policy & ENERGY_POLICY_MASK;

if (!(cpuid_ecx(6) & CPUID_6_ECX_EPB))
return;

msr_unset_and_set(IA32_ENERGY_PERF_BIAS, ENERGY_POLICY_MASK, epb);
printk(BIOS_DEBUG, "cpu: energy policy set to %u\n", epb);
}
6 changes: 2 additions & 4 deletions src/cpu/intel/haswell/Kconfig
Expand Up @@ -6,10 +6,8 @@ if CPU_INTEL_HASWELL

config CPU_SPECIFIC_OPTIONS
def_bool y
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select BOOT_DEVICE_SPI_FLASH_NO_EARLY_WRITES
select MMX
select SSE2
select UDELAY_TSC
Expand Down
94 changes: 47 additions & 47 deletions src/cpu/intel/haswell/acpi.c
Expand Up @@ -65,50 +65,6 @@ static void generate_cstate_entries(acpi_cstate_t *cstates,
acpigen_pop_len();
}

static void generate_C_state_entries(void)
{
struct cpu_info *info;
struct cpu_driver *cpu;
struct device *lapic;
struct cpu_intel_haswell_config *conf = NULL;

/* Find the SpeedStep CPU in the device tree using magic APIC ID */
lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
if (!lapic)
return;
conf = lapic->chip_info;
if (!conf)
return;

/* Find CPU map of supported C-states */
info = cpu_info();
if (!info)
return;
cpu = find_cpu_driver(info->cpu);
if (!cpu || !cpu->cstates)
return;

acpigen_emit_byte(0x14); /* MethodOp */
acpigen_write_len_f(); /* PkgLength */
acpigen_emit_namestring("_CST");
acpigen_emit_byte(0x00); /* No Arguments */

/* If running on AC power */
acpigen_emit_byte(0xa0); /* IfOp */
acpigen_write_len_f(); /* PkgLength */
acpigen_emit_namestring("PWRS");
acpigen_emit_byte(0xa4); /* ReturnOp */
generate_cstate_entries(cpu->cstates, conf->c1_acpower,
conf->c2_acpower, conf->c3_acpower);
acpigen_pop_len();

/* Else on battery power */
acpigen_emit_byte(0xa4); /* ReturnOp */
generate_cstate_entries(cpu->cstates, conf->c1_battery,
conf->c2_battery, conf->c3_battery);
acpigen_pop_len();
}

static acpi_tstate_t tss_table_fine[] = {
{ 100, 1000, 0, 0x00, 0 },
{ 94, 940, 0, 0x1f, 0 },
Expand Down Expand Up @@ -161,6 +117,50 @@ static void generate_T_state_entries(int core, int cores_per_package)
ARRAY_SIZE(tss_table_coarse), tss_table_coarse);
}

static void generate_C_state_entries(void)
{
struct cpu_info *info;
struct cpu_driver *cpu;
struct device *lapic;
struct cpu_intel_haswell_config *conf = NULL;

/* Find the SpeedStep CPU in the device tree using magic APIC ID */
lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
if (!lapic)
return;
conf = lapic->chip_info;
if (!conf)
return;

/* Find CPU map of supported C-states */
info = cpu_info();
if (!info)
return;
cpu = find_cpu_driver(info->cpu);
if (!cpu || !cpu->cstates)
return;

acpigen_emit_byte(0x14); /* MethodOp */
acpigen_write_len_f(); /* PkgLength */
acpigen_emit_namestring("_CST");
acpigen_emit_byte(0x00); /* No Arguments */

/* If running on AC power */
acpigen_emit_byte(0xa0); /* IfOp */
acpigen_write_len_f(); /* PkgLength */
acpigen_emit_namestring("PWRS");
acpigen_emit_byte(0xa4); /* ReturnOp */
generate_cstate_entries(cpu->cstates, conf->c1_acpower,
conf->c2_acpower, conf->c3_acpower);
acpigen_pop_len();

/* Else on battery power */
acpigen_emit_byte(0xa4); /* ReturnOp */
generate_cstate_entries(cpu->cstates, conf->c1_battery,
conf->c2_battery, conf->c3_battery);
acpigen_pop_len();
}

static int calculate_power(int tdp, int p1_ratio, int ratio)
{
u32 m;
Expand Down Expand Up @@ -307,19 +307,19 @@ void generate_cpu_entries(const struct device *device)

/* Generate processor \_SB.CPUx */
acpigen_write_processor(
(cpuID-1)*cores_per_package+coreID-1,
(cpuID - 1) * cores_per_package+coreID - 1,
pcontrol_blk, plen);

/* Generate P-state tables */
generate_P_state_entries(
coreID-1, cores_per_package);
coreID - 1, cores_per_package);

/* Generate C-state tables */
generate_C_state_entries();

/* Generate T-state tables */
generate_T_state_entries(
cpuID-1, cores_per_package);
cpuID - 1, cores_per_package);

acpigen_pop_len();
}
Expand Down
3 changes: 2 additions & 1 deletion src/cpu/intel/haswell/finalize.c
@@ -1,11 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <types.h>
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include "haswell.h"

void intel_cpu_haswell_finalize_smm(void)
{
/* Lock memory configuration to protect SMM */
msr_set_bit(MSR_LT_LOCK_MEMORY, 0);
msr_set(MSR_LT_LOCK_MEMORY, BIT(0));
}
1 change: 0 additions & 1 deletion src/cpu/intel/haswell/haswell.h
Expand Up @@ -28,7 +28,6 @@
#define MSR_TEMPERATURE_TARGET 0x1a2
#define MSR_LT_LOCK_MEMORY 0x2e7

#define MSR_PIC_MSG_CONTROL 0x2e
#define MSR_PLATFORM_INFO 0xce
#define PLATFORM_INFO_SET_TDP (1 << 29)
#define MSR_PKG_CST_CONFIG_CONTROL 0xe2
Expand Down
53 changes: 5 additions & 48 deletions src/cpu/intel/haswell/haswell_init.c
Expand Up @@ -207,8 +207,8 @@ int haswell_is_ult(void)
return ult;
}

/* The core 100MHz BLCK is disabled in deeper c-states. One needs to calibrate
* the 100MHz BCLCK against the 24MHz BLCK to restore the clocks properly
/* The core 100MHz BCLK is disabled in deeper c-states. One needs to calibrate
* the 100MHz BCLK against the 24MHz BCLK to restore the clocks properly
* when a core is woken up. */
static int pcode_ready(void)
{
Expand Down Expand Up @@ -247,7 +247,7 @@ static void calibrate_24mhz_bclk(void)

err_code = MCHBAR32(BIOS_MAILBOX_INTERFACE) & 0xff;

printk(BIOS_DEBUG, "PCODE: 24MHz BLCK calibration response: %d\n",
printk(BIOS_DEBUG, "PCODE: 24MHz BCLK calibration response: %d\n",
err_code);

/* Read the calibrated value. */
Expand All @@ -259,7 +259,7 @@ static void calibrate_24mhz_bclk(void)
return;
}

printk(BIOS_DEBUG, "PCODE: 24MHz BLCK calibration value: 0x%08x\n",
printk(BIOS_DEBUG, "PCODE: 24MHz BCLK calibration value: 0x%08x\n",
MCHBAR32(BIOS_MAILBOX_DATA));
}

Expand Down Expand Up @@ -577,29 +577,6 @@ static void configure_misc(void)
wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
}

static void enable_lapic_tpr(void)
{
msr_t msr;

msr = rdmsr(MSR_PIC_MSG_CONTROL);
msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
wrmsr(MSR_PIC_MSG_CONTROL, msr);
}

static void configure_dca_cap(void)
{
uint32_t feature_flag;
msr_t msr;

/* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
feature_flag = cpu_get_feature_flags_ecx();
if (feature_flag & CPUID_DCA) {
msr = rdmsr(IA32_PLATFORM_DCA_CAP);
msr.lo |= 1;
wrmsr(IA32_PLATFORM_DCA_CAP, msr);
}
}

static void set_max_ratio(void)
{
msr_t msr, perf_ctl;
Expand All @@ -618,30 +595,10 @@ static void set_max_ratio(void)
}
wrmsr(IA32_PERF_CTL, perf_ctl);

printk(BIOS_DEBUG, "haswell: frequency set to %d\n",
printk(BIOS_DEBUG, "CPU: frequency set to %d\n",
((perf_ctl.lo >> 8) & 0xff) * HASWELL_BCLK);
}

static void set_energy_perf_bias(u8 policy)
{
msr_t msr;
int ecx;

/* Determine if energy efficient policy is supported. */
ecx = cpuid_ecx(0x6);
if (!(ecx & (1 << 3)))
return;

/* Energy Policy is bits 3:0 */
msr = rdmsr(IA32_ENERGY_PERF_BIAS);
msr.lo &= ~0xf;
msr.lo |= policy & 0xf;
wrmsr(IA32_ENERGY_PERF_BIAS, msr);

printk(BIOS_DEBUG, "haswell: energy policy set to %u\n",
policy);
}

static void configure_mca(void)
{
msr_t msr;
Expand Down
8 changes: 3 additions & 5 deletions src/cpu/intel/haswell/smmrelocate.c
Expand Up @@ -109,7 +109,7 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
msr_t mtrr_cap;
struct smm_relocation_params *relo_params = &smm_reloc_params;

printk(BIOS_DEBUG, "In relocation handler: cpu %d\n", cpu);
printk(BIOS_DEBUG, "In relocation handler: CPU %d\n", cpu);

/* Determine if the processor supports saving state in MSRs. If so,
* enable it before the non-BSPs run so that SMM relocation can occur
Expand Down Expand Up @@ -156,7 +156,6 @@ static void fill_in_relocation_params(struct smm_relocation_params *params)
{
uintptr_t tseg_base;
size_t tseg_size;

u32 prmrr_base;
u32 prmrr_size;
int phys_bits;
Expand Down Expand Up @@ -197,7 +196,7 @@ static void fill_in_relocation_params(struct smm_relocation_params *params)
params->uncore_prmrr_base.lo = prmrr_base;
params->uncore_prmrr_base.hi = 0;
params->uncore_prmrr_mask.lo = (~(prmrr_size - 1) & rmask) |
MTRR_PHYS_MASK_VALID;
MTRR_PHYS_MASK_VALID;
params->uncore_prmrr_mask.hi = (1 << (39 - 32)) - 1;
}

Expand Down Expand Up @@ -282,6 +281,5 @@ void smm_lock(void)
* make the SMM registers writable again.
*/
printk(BIOS_DEBUG, "Locking SMM.\n");
pci_write_config8(pcidev_on_root(0, 0), SMRAM,
D_LCK | G_SMRAME | C_BASE_SEG);
pci_write_config8(pcidev_on_root(0, 0), SMRAM, D_LCK | G_SMRAME | C_BASE_SEG);
}
5 changes: 1 addition & 4 deletions src/cpu/intel/model_1067x/Kconfig
@@ -1,9 +1,6 @@
config CPU_INTEL_MODEL_1067X
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SSE2
select UDELAY_TSC
select TSC_MONOTONIC_TIMER
Expand Down
5 changes: 1 addition & 4 deletions src/cpu/intel/model_106cx/Kconfig
@@ -1,9 +1,6 @@
config CPU_INTEL_MODEL_106CX
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SSE2
select UDELAY_TSC
select TSC_MONOTONIC_TIMER
Expand Down
6 changes: 2 additions & 4 deletions src/cpu/intel/model_2065x/Kconfig
Expand Up @@ -5,10 +5,8 @@ if CPU_INTEL_MODEL_2065X

config CPU_SPECIFIC_OPTIONS
def_bool y
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select BOOT_DEVICE_SPI_FLASH_NO_EARLY_WRITES
select SSE2
select UDELAY_TSC
select TSC_MONOTONIC_TIMER
Expand Down
9 changes: 3 additions & 6 deletions src/cpu/intel/model_2065x/finalize.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <types.h>
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/intel/speedstep.h>
Expand All @@ -13,12 +14,8 @@
void intel_model_2065x_finalize_smm(void)
{
/* Lock C-State MSR */
msr_set_bit(MSR_PKG_CST_CONFIG_CONTROL, 15);

/* Lock AES-NI only if supported */
if (cpuid_ecx(1) & (1 << 25))
msr_set_bit(MSR_FEATURE_CONFIG, 0);
msr_set(MSR_PKG_CST_CONFIG_CONTROL, BIT(15));

/* Lock TM interrupts - route thermal events to all processors */
msr_set_bit(MSR_MISC_PWR_MGMT, 22);
msr_set(MSR_MISC_PWR_MGMT, BIT(22));
}
1 change: 0 additions & 1 deletion src/cpu/intel/model_2065x/model_2065x.h
Expand Up @@ -15,7 +15,6 @@
#define IA32_FERR_CAPABILITY 0x1f1
#define FERR_ENABLE (1 << 0)

#define MSR_PIC_MSG_CONTROL 0x2e
#define MSR_PLATFORM_INFO 0xce
#define PLATFORM_INFO_SET_TDP (1 << 29)

Expand Down
11 changes: 2 additions & 9 deletions src/cpu/intel/model_2065x/model_2065x_init.c
Expand Up @@ -148,15 +148,6 @@ static void configure_misc(void)
wrmsr(IA32_THERM_INTERRUPT, msr);
}

static void enable_lapic_tpr(void)
{
msr_t msr;

msr = rdmsr(MSR_PIC_MSG_CONTROL);
msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
wrmsr(MSR_PIC_MSG_CONTROL, msr);
}

static void set_max_ratio(void)
{
msr_t msr, perf_ctl;
Expand Down Expand Up @@ -216,6 +207,8 @@ static void model_2065x_init(struct device *cpu)
/* Set virtualization based on Kconfig option */
set_vmx_and_lock();

set_aesni_lock();

/* Configure Enhanced SpeedStep and Thermal Sensors */
configure_misc();

Expand Down
6 changes: 2 additions & 4 deletions src/cpu/intel/model_206ax/Kconfig
Expand Up @@ -5,10 +5,8 @@ if CPU_INTEL_MODEL_206AX

config CPU_SPECIFIC_OPTIONS
def_bool y
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select BOOT_DEVICE_SPI_FLASH_NO_EARLY_WRITES
select MMX
select SSE2
select UDELAY_TSC
Expand Down
18 changes: 4 additions & 14 deletions src/cpu/intel/model_206ax/acpi.c
Expand Up @@ -13,20 +13,10 @@
#include "model_206ax.h"
#include "chip.h"

static int get_cores_per_package(void)
static int get_logical_cores_per_package(void)
{
struct cpuinfo_x86 c;
struct cpuid_result result;
int cores = 1;

get_fms(&c, cpuid_eax(1));
if (c.x86 != 6)
return 1;

result = cpuid_ext(0xb, 1);
cores = result.ebx & 0xff;

return cores;
msr_t msr = rdmsr(MSR_CORE_THREAD_COUNT);
return msr.lo & 0xffff;
}

static void generate_cstate_entries(acpi_cstate_t *cstates,
Expand Down Expand Up @@ -288,7 +278,7 @@ void generate_cpu_entries(const struct device *device)
{
int coreID, cpuID, pcontrol_blk = PMB0_BASE, plen = 6;
int totalcores = dev_count_cpu();
int cores_per_package = get_cores_per_package();
int cores_per_package = get_logical_cores_per_package();
int numcpus = totalcores/cores_per_package;

printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n",
Expand Down
9 changes: 3 additions & 6 deletions src/cpu/intel/model_206ax/finalize.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <types.h>
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include "model_206ax.h"
Expand All @@ -11,13 +12,9 @@

void intel_model_206ax_finalize_smm(void)
{
/* Lock AES-NI only if supported */
if (cpuid_ecx(1) & (1 << 25))
msr_set_bit(MSR_FEATURE_CONFIG, 0);

/* Lock TM interrupts - route thermal events to all processors */
msr_set_bit(MSR_MISC_PWR_MGMT, 22);
msr_set(MSR_MISC_PWR_MGMT, BIT(22));

/* Lock memory configuration to protect SMM */
msr_set_bit(MSR_LT_LOCK_MEMORY, 0);
msr_set(MSR_LT_LOCK_MEMORY, BIT(0));
}
1 change: 0 additions & 1 deletion src/cpu/intel/model_206ax/model_206ax.h
Expand Up @@ -15,7 +15,6 @@
#define FLEX_RATIO_EN (1 << 16)
#define MSR_TEMPERATURE_TARGET 0x1a2
#define MSR_LT_LOCK_MEMORY 0x2e7
#define MSR_PIC_MSG_CONTROL 0x2e
#define MSR_PLATFORM_INFO 0xce
#define PLATFORM_INFO_SET_TDP (1 << 29)

Expand Down
39 changes: 2 additions & 37 deletions src/cpu/intel/model_206ax/model_206ax_init.c
Expand Up @@ -338,29 +338,6 @@ static void configure_misc(void)
wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
}

static void enable_lapic_tpr(void)
{
msr_t msr;

msr = rdmsr(MSR_PIC_MSG_CONTROL);
msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
wrmsr(MSR_PIC_MSG_CONTROL, msr);
}

static void configure_dca_cap(void)
{
uint32_t feature_flag;
msr_t msr;

/* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
feature_flag = cpu_get_feature_flags_ecx();
if (feature_flag & CPUID_DCA) {
msr = rdmsr(IA32_PLATFORM_DCA_CAP);
msr.lo |= 1;
wrmsr(IA32_PLATFORM_DCA_CAP, msr);
}
}

static void set_max_ratio(void)
{
msr_t msr, perf_ctl;
Expand All @@ -383,20 +360,6 @@ static void set_max_ratio(void)
((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK);
}

static void set_energy_perf_bias(u8 policy)
{
msr_t msr;

/* Energy Policy is bits 3:0 */
msr = rdmsr(IA32_ENERGY_PERF_BIAS);
msr.lo &= ~0xf;
msr.lo |= policy & 0xf;
wrmsr(IA32_ENERGY_PERF_BIAS, msr);

printk(BIOS_DEBUG, "model_x06ax: energy policy set to %u\n",
policy);
}

static void configure_mca(void)
{
msr_t msr;
Expand Down Expand Up @@ -470,6 +433,8 @@ static void model_206ax_init(struct device *cpu)
/* Thermal throttle activation offset */
configure_thermal_target();

set_aesni_lock();

/* Enable Direct Cache Access */
configure_dca_cap();

Expand Down
5 changes: 1 addition & 4 deletions src/cpu/intel/model_65x/Kconfig
@@ -1,7 +1,4 @@
config CPU_INTEL_MODEL_65X
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SUPPORT_CPU_UCODE_IN_CBFS
5 changes: 1 addition & 4 deletions src/cpu/intel/model_67x/Kconfig
@@ -1,7 +1,4 @@
config CPU_INTEL_MODEL_67X
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SUPPORT_CPU_UCODE_IN_CBFS
5 changes: 1 addition & 4 deletions src/cpu/intel/model_68x/Kconfig
Expand Up @@ -2,8 +2,5 @@

config CPU_INTEL_MODEL_68X
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SUPPORT_CPU_UCODE_IN_CBFS
5 changes: 1 addition & 4 deletions src/cpu/intel/model_6bx/Kconfig
@@ -1,7 +1,4 @@
config CPU_INTEL_MODEL_6BX
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SUPPORT_CPU_UCODE_IN_CBFS
5 changes: 1 addition & 4 deletions src/cpu/intel/model_6ex/Kconfig
@@ -1,9 +1,6 @@
config CPU_INTEL_MODEL_6EX
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SSE2
select UDELAY_TSC
select TSC_MONOTONIC_TIMER
Expand Down
5 changes: 1 addition & 4 deletions src/cpu/intel/model_6fx/Kconfig
@@ -1,9 +1,6 @@
config CPU_INTEL_MODEL_6FX
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SSE2
select UDELAY_TSC
select TSC_MONOTONIC_TIMER
Expand Down
5 changes: 1 addition & 4 deletions src/cpu/intel/model_6xx/Kconfig
@@ -1,7 +1,4 @@
config CPU_INTEL_MODEL_6XX
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SUPPORT_CPU_UCODE_IN_CBFS
6 changes: 1 addition & 5 deletions src/cpu/intel/model_f2x/Kconfig
@@ -1,10 +1,6 @@
config CPU_INTEL_MODEL_F2X
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SUPPORT_CPU_UCODE_IN_CBFS
select SMM_ASEG
select CPU_INTEL_COMMON
select CPU_INTEL_COMMON_HYPERTHREADING
6 changes: 1 addition & 5 deletions src/cpu/intel/model_f3x/Kconfig
@@ -1,9 +1,5 @@
config CPU_INTEL_MODEL_F3X
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SUPPORT_CPU_UCODE_IN_CBFS
select CPU_INTEL_COMMON
select CPU_INTEL_COMMON_HYPERTHREADING
5 changes: 1 addition & 4 deletions src/cpu/intel/model_f4x/Kconfig
@@ -1,7 +1,4 @@
config CPU_INTEL_MODEL_F4X
bool
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select SUPPORT_CPU_UCODE_IN_CBFS
11 changes: 2 additions & 9 deletions src/cpu/qemu-x86/Kconfig
Expand Up @@ -2,7 +2,6 @@

config CPU_QEMU_X86
bool
select SMP
select UDELAY_TSC
select TSC_MONOTONIC_TIMER
select UNKNOWN_TSC_RATE
Expand All @@ -12,19 +11,13 @@ if CPU_QEMU_X86

config CPU_QEMU_X86_64
bool "Experimental 64bit support"
select ARCH_BOOTBLOCK_X86_64
select ARCH_VERSTAGE_X86_64
select ARCH_ROMSTAGE_X86_64
select ARCH_ALL_STAGES_X86_64
select ARCH_POSTCAR_X86_64
select ARCH_RAMSTAGE_X86_64

config CPU_QEMU_X86_32
bool
default n if CPU_QEMU_X86_64
default y
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_ALL_STAGES_X86_32
select ARCH_POSTCAR_X86_32
select ARCH_RAMSTAGE_X86_32
endif
5 changes: 4 additions & 1 deletion src/cpu/qemu-x86/cache_as_ram_bootblock.S
Expand Up @@ -27,10 +27,13 @@ cache_as_ram:
/* Align the stack and keep aligned for call to bootblock_c_entry() */
and $0xfffffff0, %esp

/* entry64.inc preserves ebx. */
#include <cpu/x86/64bit/entry64.inc>

/* Restore the BIST result and timestamps. */
#if defined(__x86_64__)
movd %mm2, %rdi
shld %rdi, 32
shlq $32, %rdi
movd %mm1, %rsi
or %rsi, %rdi

Expand Down
56 changes: 41 additions & 15 deletions src/cpu/x86/mtrr/mtrr.c
Expand Up @@ -104,9 +104,7 @@ static void enable_var_mtrr(unsigned char deftype)

#define MTRR_VERBOSE_LEVEL BIOS_NEVER

/* MTRRs are at a 4KiB granularity. Therefore all address calculations can
* be done with 32-bit numbers. This allows for the MTRR code to handle
* up to 2^44 bytes (16 TiB) of address space. */
/* MTRRs are at a 4KiB granularity. */
#define RANGE_SHIFT 12
#define ADDR_SHIFT_TO_RANGE_SHIFT(x) \
(((x) > RANGE_SHIFT) ? ((x) - RANGE_SHIFT) : RANGE_SHIFT)
Expand All @@ -115,18 +113,18 @@ static void enable_var_mtrr(unsigned char deftype)
#define NUM_FIXED_MTRRS (NUM_FIXED_RANGES / RANGES_PER_FIXED_MTRR)

/* Helpful constants. */
#define RANGE_1MB PHYS_TO_RANGE_ADDR(1 << 20)
#define RANGE_4GB (1 << (ADDR_SHIFT_TO_RANGE_SHIFT(32)))
#define RANGE_1MB PHYS_TO_RANGE_ADDR(1ULL << 20)
#define RANGE_4GB (1ULL << (ADDR_SHIFT_TO_RANGE_SHIFT(32)))

#define MTRR_ALGO_SHIFT (8)
#define MTRR_TAG_MASK ((1 << MTRR_ALGO_SHIFT) - 1)

static inline uint32_t range_entry_base_mtrr_addr(struct range_entry *r)
static inline uint64_t range_entry_base_mtrr_addr(struct range_entry *r)
{
return PHYS_TO_RANGE_ADDR(range_entry_base(r));
}

static inline uint32_t range_entry_end_mtrr_addr(struct range_entry *r)
static inline uint64_t range_entry_end_mtrr_addr(struct range_entry *r)
{
return PHYS_TO_RANGE_ADDR(range_entry_end(r));
}
Expand Down Expand Up @@ -402,7 +400,7 @@ static void clear_var_mtrr(int index)
}

static void prep_var_mtrr(struct var_mtrr_state *var_state,
uint32_t base, uint32_t size, int mtrr_type)
uint64_t base, uint64_t size, int mtrr_type)
{
struct var_mtrr_regs *regs;
resource_t rbase;
Expand Down Expand Up @@ -444,16 +442,43 @@ static void prep_var_mtrr(struct var_mtrr_state *var_state,
regs->mask.hi = rsize >> 32;
}

/*
* fls64: find least significant bit set in a 64-bit word
* As samples, fls64(0x0) = 64; fls64(0x4400) = 10;
* fls64(0x40400000000) = 34.
*/
static uint32_t fls64(uint64_t x)
{
uint32_t lo = (uint32_t)x;
if (lo)
return fls(lo);
uint32_t hi = x >> 32;
return fls(hi) + 32;
}

/*
* fms64: find most significant bit set in a 64-bit word
* As samples, fms64(0x0) = 0; fms64(0x4400) = 14;
* fms64(0x40400000000) = 42.
*/
static uint32_t fms64(uint64_t x)
{
uint32_t hi = (uint32_t)(x >> 32);
if (!hi)
return fms((uint32_t)x);
return fms(hi) + 32;
}

static void calc_var_mtrr_range(struct var_mtrr_state *var_state,
uint32_t base, uint32_t size, int mtrr_type)
uint64_t base, uint64_t size, int mtrr_type)
{
while (size != 0) {
uint32_t addr_lsb;
uint32_t size_msb;
uint32_t mtrr_size;
uint64_t mtrr_size;

addr_lsb = fls(base);
size_msb = fms(size);
addr_lsb = fls64(base);
size_msb = fms64(size);

/* All MTRR entries need to have their base aligned to the mask
* size. The maximum size is calculated by a function of the
Expand All @@ -472,8 +497,8 @@ static void calc_var_mtrr_range(struct var_mtrr_state *var_state,
}
}

static uint32_t optimize_var_mtrr_hole(const uint32_t base,
const uint32_t hole,
static uint64_t optimize_var_mtrr_hole(const uint64_t base,
const uint64_t hole,
const uint64_t limit,
const int carve_hole)
{
Expand Down Expand Up @@ -531,7 +556,7 @@ static uint32_t optimize_var_mtrr_hole(const uint32_t base,
static void calc_var_mtrrs_with_hole(struct var_mtrr_state *var_state,
struct range_entry *r)
{
uint32_t a1, a2, b1, b2;
uint64_t a1, a2, b1, b2;
int mtrr_type, carve_hole;

/*
Expand Down Expand Up @@ -671,6 +696,7 @@ static void __calc_var_mtrrs(struct memranges *addr_space,
wb_deftype_count += var_state.mtrr_index;
}
}

*num_def_wb_mtrrs = wb_deftype_count;
*num_def_uc_mtrrs = uc_deftype_count;
}
Expand Down
25 changes: 22 additions & 3 deletions src/cpu/x86/smm/smihandler.c
Expand Up @@ -128,6 +128,24 @@ uint32_t smm_revision(void)
return *(uint32_t *)(SMM_BASE + SMM_ENTRY_OFFSET * 2 - SMM_REVISION_OFFSET_FROM_TOP);
}

void *smm_get_save_state(int cpu)
{
switch (smm_revision()) {
case 0x00030002:
case 0x00030007:
return smm_save_state(SMM_BASE, SMM_LEGACY_ARCH_OFFSET, cpu);
case 0x00030100:
return smm_save_state(SMM_BASE, SMM_EM64T100_ARCH_OFFSET, cpu);
case 0x00030101: /* SandyBridge, IvyBridge, and Haswell */
return smm_save_state(SMM_BASE, SMM_EM64T101_ARCH_OFFSET, cpu);
case 0x00020064:
case 0x00030064:
return smm_save_state(SMM_BASE, SMM_AMD64_ARCH_OFFSET, cpu);
}

return NULL;
}

bool smm_region_overlaps_handler(const struct region *r)
{
const struct region r_smm = {SMM_BASE, SMM_DEFAULT_SIZE};
Expand All @@ -141,9 +159,10 @@ bool smm_region_overlaps_handler(const struct region *r)
* @param smm_revision revision of the smm state save map
*/

void smi_handler(u32 smm_revision)
void smi_handler(void)
{
unsigned int node;
const uint32_t smm_rev = smm_revision();
smm_state_save_area_t state_save;
u32 smm_base = SMM_BASE; /* ASEG */

Expand Down Expand Up @@ -171,7 +190,7 @@ void smi_handler(u32 smm_revision)

printk(BIOS_SPEW, "\nSMI# #%d\n", node);

switch (smm_revision) {
switch (smm_rev) {
case 0x00030002:
case 0x00030007:
state_save.type = LEGACY;
Expand Down Expand Up @@ -199,7 +218,7 @@ void smi_handler(u32 smm_revision)
SMM_AMD64_ARCH_OFFSET, node);
break;
default:
printk(BIOS_DEBUG, "smm_revision: 0x%08x\n", smm_revision);
printk(BIOS_DEBUG, "smm_revision: 0x%08x\n", smm_rev);
printk(BIOS_DEBUG, "SMI# not supported on your CPU\n");
/* Don't release lock, so no further SMI will happen,
* if we don't handle it anyways.
Expand Down
10 changes: 0 additions & 10 deletions src/cpu/x86/smm/smmhandler.S
Expand Up @@ -165,10 +165,6 @@ untampered_lapic:
addl $SMM_STACK_SIZE, %ebx
movl %ebx, %esp

/* Get SMM revision */
movl $0xa8000 + 0x7efc, %ebx /* core 0 address */
subl %ebp, %ebx /* subtract core X offset */

#if defined(__x86_64__)
/* Backup IA32_EFER. Preserves ebx. */
movl $(IA32_EFER), %ecx
Expand All @@ -179,13 +175,7 @@ untampered_lapic:
/* Enable long mode. Preserves ebx. */
#include <cpu/x86/64bit/entry64.inc>

mov (%ebx), %rdi

#else
movl (%ebx), %eax
pushl %eax
#endif

/* Call C handler */
call smi_handler

Expand Down
2 changes: 1 addition & 1 deletion src/device/device_util.c
Expand Up @@ -519,7 +519,7 @@ void report_resource_stored(struct device *dev, struct resource *resource,
end = resource_end(resource);
buf[0] = '\0';

if (resource->flags & IORESOURCE_PCI_BRIDGE) {
if (dev->link_list && (resource->flags & IORESOURCE_PCI_BRIDGE)) {
snprintf(buf, sizeof(buf),
"bus %02x ", dev->link_list->secondary);
}
Expand Down
43 changes: 33 additions & 10 deletions src/device/pci_device.c
Expand Up @@ -1006,16 +1006,11 @@ static struct device *pci_scan_get_dev(struct bus *bus, unsigned int devfn)

prev = &bus->children;
for (dev = bus->children; dev; dev = dev->sibling) {
if (dev->path.type == DEVICE_PATH_PCI) {
if (dev->path.pci.devfn == devfn) {
/* Unlink from the list. */
*prev = dev->sibling;
dev->sibling = NULL;
break;
}
} else {
printk(BIOS_ERR, "child %s not a PCI device\n",
dev_path(dev));
if (dev->path.type == DEVICE_PATH_PCI && dev->path.pci.devfn == devfn) {
/* Unlink from the list. */
*prev = dev->sibling;
dev->sibling = NULL;
break;
}
prev = &dev->sibling;
}
Expand Down Expand Up @@ -1283,6 +1278,16 @@ void pci_scan_bus(struct bus *bus, unsigned int min_devfn,

prev = &bus->children;
for (dev = bus->children; dev; dev = dev->sibling) {

/*
* If static device is not PCI then enable it here and don't
* treat it as a leftover device.
*/
if (dev->path.type != DEVICE_PATH_PCI) {
enable_static_device(dev);
continue;
}

/*
* The device is only considered leftover if it is not hidden
* and it has a Vendor ID of 0 (the default for a device that
Expand Down Expand Up @@ -1643,3 +1648,21 @@ void pci_dev_disable_bus_master(const struct device *dev)
pci_update_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MASTER, 0x0);
}
#endif

bool pci_dev_is_wake_source(const struct device *dev)
{
unsigned int pm_cap;
uint16_t pmcs;

if (dev->path.type != DEVICE_PATH_PCI)
return false;

pm_cap = pci_find_capability(dev, PCI_CAP_ID_PM);
if (!pm_cap)
return false;

pmcs = pci_read_config16(dev, pm_cap + PCI_PM_CTRL);

/* PCI Device is a wake source if PME_ENABLE and PME_STATUS are set in PMCS register. */
return (pmcs & PCI_PM_CTRL_PME_ENABLE) && (pmcs & PCI_PM_CTRL_PME_STATUS);
}
4 changes: 4 additions & 0 deletions src/device/pciexp_device.c
Expand Up @@ -182,6 +182,8 @@ static void pciexp_enable_ltr(struct device *dev)

for (bus = dev->link_list ; bus ; bus = bus->next) {
for (child = bus->children; child; child = child->sibling) {
if (child->path.type != DEVICE_PATH_PCI)
continue;
pciexp_configure_ltr(child);
if (child->ops && child->ops->scan_bus)
pciexp_enable_ltr(child);
Expand Down Expand Up @@ -482,6 +484,8 @@ void pciexp_scan_bus(struct bus *bus, unsigned int min_devfn,
pci_scan_bus(bus, min_devfn, max_devfn);

for (child = bus->children; child; child = child->sibling) {
if (child->path.type != DEVICE_PATH_PCI)
continue;
if ((child->path.pci.devfn < min_devfn) ||
(child->path.pci.devfn > max_devfn)) {
continue;
Expand Down
33 changes: 14 additions & 19 deletions src/device/root_device.c
Expand Up @@ -7,6 +7,18 @@

const char mainboard_name[] = CONFIG_MAINBOARD_VENDOR " " CONFIG_MAINBOARD_PART_NUMBER;

void enable_static_device(struct device *dev)
{
if (dev->chip_ops && dev->chip_ops->enable_dev)
dev->chip_ops->enable_dev(dev);

if (dev->ops && dev->ops->enable)
dev->ops->enable(dev);

printk(BIOS_DEBUG, "%s %s\n", dev_path(dev),
dev->enabled ? "enabled" : "disabled");
}

/**
* Enable devices on static buses.
*
Expand All @@ -32,15 +44,7 @@ void enable_static_devices(struct device *bus)

for (link = bus->link_list; link; link = link->next) {
for (child = link->children; child; child = child->sibling) {

if (child->chip_ops && child->chip_ops->enable_dev)
child->chip_ops->enable_dev(child);

if (child->ops && child->ops->enable)
child->ops->enable(child);

printk(BIOS_DEBUG, "%s %s\n", dev_path(child),
child->enabled ? "enabled" : "disabled");
enable_static_device(child);
}
}
}
Expand All @@ -58,18 +62,9 @@ void scan_generic_bus(struct device *bus)
link->secondary = ++bus_max;

for (child = link->children; child; child = child->sibling) {

if (child->chip_ops && child->chip_ops->enable_dev)
child->chip_ops->enable_dev(child);

if (child->ops && child->ops->enable)
child->ops->enable(child);

enable_static_device(child);
printk(BIOS_DEBUG, "bus: %s[%d]->", dev_path(child->bus->dev),
child->bus->link_num);

printk(BIOS_DEBUG, "%s %s\n", dev_path(child),
child->enabled ? "enabled" : "disabled");
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/drivers/camera/Kconfig
@@ -0,0 +1,7 @@
config CHROMEOS_CAMERA
bool
default n
help
Camera with identifiers following Chrome OS Camera Info. The info is
usually available on MIPI camera EEPROM for identifying correct
drivers and config.
1 change: 1 addition & 0 deletions src/drivers/camera/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_CHROMEOS_CAMERA) += cros_camera.c
39 changes: 39 additions & 0 deletions src/drivers/camera/cros_camera.c
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <crc_byte.h>
#include <string.h>

#include "cros_camera.h"

int check_cros_camera_info(const struct cros_camera_info *info)
{
if (memcmp(info->magic, CROS_CAMERA_INFO_MAGIC, sizeof(info->magic))) {
printk(BIOS_ERR, "Invalid magic in camera info\n");
return -1;
}

const uint8_t *ptr = (void *)(&info->crc16 + 1);
uint16_t crc16 = 0;
while (ptr < (uint8_t *)info + sizeof(struct cros_camera_info))
crc16 = crc16_byte(crc16, *ptr++);

if (info->crc16 != crc16) {
printk(BIOS_ERR, "Incorrect CRC16: expected %#06x, got %#06x\n",
crc16, info->crc16);
return -1;
}

if (info->version != CROS_CAMERA_INFO_VERSION) {
printk(BIOS_ERR, "Unknown camera info version: %u\n",
info->version);
return -1;
}
if (info->size < CROS_CAMERA_INFO_SIZE_MIN) {
printk(BIOS_ERR, "Size of camera info is too small: %u\n",
info->size);
return -1;
}

return 0;
}
27 changes: 27 additions & 0 deletions src/drivers/camera/cros_camera.h
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __VENDORCODE_GOOGLE_CHROMEOS_CAMERA_H
#define __VENDORCODE_GOOGLE_CHROMEOS_CAMERA_H

#include <stdint.h>

#define CROS_CAMERA_INFO_MAGIC "CrOS"
#define CROS_CAMERA_INFO_VERSION 1
#define CROS_CAMERA_INFO_SIZE_MIN 0x0a

struct cros_camera_info {
uint8_t magic[4]; /* CROS_CAMERA_INFO_MAGIC */
uint16_t crc16;
uint8_t version;
uint8_t size;
uint16_t data_format;
uint16_t module_pid;
uint8_t module_vid[2];
uint8_t sensor_vid[2];
uint16_t sensor_pid;
};

/* Returns 0 on success, non-zero on errors. */
int check_cros_camera_info(const struct cros_camera_info *info);

#endif
6 changes: 6 additions & 0 deletions src/drivers/i2c/gpiomux/Kconfig
@@ -0,0 +1,6 @@
config DRIVERS_I2C_GPIO_MUX
bool
default n
depends on HAVE_ACPI_TABLES
help
When enabled, add identifiers in ACPI tables for GPIO based I2C multiplexer.
2 changes: 2 additions & 0 deletions src/drivers/i2c/gpiomux/Makefile.inc
@@ -0,0 +1,2 @@
subdirs-$(CONFIG_DRIVERS_I2C_GPIO_MUX) += mux
subdirs-$(CONFIG_DRIVERS_I2C_GPIO_MUX) += bus
1 change: 1 addition & 0 deletions src/drivers/i2c/gpiomux/bus/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_I2C_GPIO_MUX) += bus.c
60 changes: 60 additions & 0 deletions src/drivers/i2c/gpiomux/bus/bus.c
@@ -0,0 +1,60 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
#include <device/device.h>
#include <device/path.h>
#include <stdlib.h>
#include <string.h>
#include "chip.h"

static const char *i2c_gpiomux_bus_acpi_name(const struct device *dev)
{
static char name[ACPI_NAME_BUFFER_SIZE];

snprintf(name, ACPI_NAME_BUFFER_SIZE, "MXA%01.1X", dev->path.generic.id);
return name;
}

static void i2c_gpiomux_bus_fill_ssdt(const struct device *dev)
{
const char *scope = acpi_device_scope(dev);
const char *path = acpi_device_path(dev);

if (!dev || !dev->enabled || !scope || !path)
return;

/* Device */
acpigen_write_scope(scope);
acpigen_write_device(acpi_device_name(dev));

acpigen_write_STA(acpi_device_status(dev));
acpigen_write_ADR(dev->path.generic.id);

acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */

printk(BIOS_INFO, "%s: %s at %s\n", path, dev->chip_ops->name, dev_path(dev));
}

static struct device_operations i2c_gpiomux_bus_ops = {
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.scan_bus = scan_static_bus,
.acpi_name = i2c_gpiomux_bus_acpi_name,
.acpi_fill_ssdt = i2c_gpiomux_bus_fill_ssdt,
};

static void i2c_gpiomux_bus_enable(struct device *dev)
{
if (!dev)
return;

dev->ops = &i2c_gpiomux_bus_ops;
}

struct chip_operations drivers_i2c_gpiomux_bus_ops = {
CHIP_NAME("I2C GPIO MUX Bus Device")
.enable_dev = i2c_gpiomux_bus_enable
};
9 changes: 9 additions & 0 deletions src/drivers/i2c/gpiomux/bus/chip.h
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __I2C_GPIOMUX_BUS_CHIP_H__
#define __I2C_GPIOMUX_BUS_CHIP_H__

struct drivers_i2c_gpiomux_bus_config {
};

#endif /* __I2C_GPIOMUX_BUS_CHIP_H__ */
1 change: 1 addition & 0 deletions src/drivers/i2c/gpiomux/mux/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_I2C_GPIO_MUX) += mux.c
17 changes: 17 additions & 0 deletions src/drivers/i2c/gpiomux/mux/chip.h
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __I2C_GPIOMUX_MUX_CHIP_H__
#define __I2C_GPIOMUX_MUX_CHIP_H__

#include <acpi/acpi_device.h>
#include <types.h>

#define MAX_NUM_MUX_GPIOS 4

struct drivers_i2c_gpiomux_mux_config {
/* GPIOs used to select the mux lines */
uint32_t mux_gpio_count;
struct acpi_gpio mux_gpio[MAX_NUM_MUX_GPIOS];
};

#endif /* __I2C_GPIOMUX_MUX_CHIP_H__ */
82 changes: 82 additions & 0 deletions src/drivers/i2c/gpiomux/mux/mux.c
@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
#include <device/device.h>
#include <device/path.h>
#include <stdlib.h>
#include <string.h>
#include "chip.h"

static const char *i2c_gpiomux_mux_acpi_name(const struct device *dev)
{
static char name[ACPI_NAME_BUFFER_SIZE];

snprintf(name, ACPI_NAME_BUFFER_SIZE, "MUX%01.1X", dev->path.generic.id);
return name;
}

static void i2c_gpiomux_mux_fill_ssdt(const struct device *dev)
{
const char *scope = acpi_device_scope(dev);
const char *path = acpi_device_path(dev);
struct drivers_i2c_gpiomux_mux_config *config = config_of(dev);
struct acpi_dp *dsd = NULL;
const char *compat_string = "i2c-mux-gpio";
struct acpi_gpio_res_params param[MAX_NUM_MUX_GPIOS];
int i;

if (!dev->enabled || !scope || !path)
return;

/* Device */
acpigen_write_scope(scope);
acpigen_write_device(acpi_device_name(dev));
acpigen_write_name_string("_HID", ACPI_DT_NAMESPACE_HID);
acpigen_write_STA(acpi_device_status(dev));

/* Resources */
acpigen_write_name("_CRS");
acpigen_write_resourcetemplate_header();
for (i = 0; i < config->mux_gpio_count; i++) {
acpi_device_write_gpio(&config->mux_gpio[i]);
param[i].ref = path;
param[i].index = i;
param[i].pin = 0;
param[i].active_low = config->mux_gpio[i].active_low;
}
acpigen_write_resourcetemplate_footer();

/* DSD */
dsd = acpi_dp_new_table("_DSD");
acpi_dp_add_string(dsd, "compatible", compat_string);
acpi_dp_add_gpio_array(dsd, "mux-gpios", param, config->mux_gpio_count);
acpi_dp_write(dsd);

acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */

printk(BIOS_INFO, "%s: %s at %s\n", path, dev->chip_ops->name, dev_path(dev));
}

static struct device_operations i2c_gpiomux_mux_ops = {
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.scan_bus = scan_static_bus,
.acpi_name = i2c_gpiomux_mux_acpi_name,
.acpi_fill_ssdt = i2c_gpiomux_mux_fill_ssdt,
};

static void i2c_gpiomux_mux_enable(struct device *dev)
{
if (!dev)
return;

dev->ops = &i2c_gpiomux_mux_ops;
}

struct chip_operations drivers_i2c_gpiomux_mux_ops = {
CHIP_NAME("I2C GPIO MUX Device")
.enable_dev = i2c_gpiomux_mux_enable
};
15 changes: 15 additions & 0 deletions src/drivers/i2c/nct7802y/chip.h
Expand Up @@ -7,6 +7,15 @@

#define NCT7802Y_PECI_CNT 2
#define NCT7802Y_FAN_CNT 3
#define NCT7802Y_RTD_CNT 3

/* Remote temperature diode sensors mode */
enum nct7802y_rtd_mode {
RTD_CLOSED = 0,
RTD_CURRENT_MODE,
RTD_THERMISTOR_MODE,
RTD_VOLTAGE_MODE,
};

enum nct7802y_peci_mode {
PECI_DISABLED = 0,
Expand Down Expand Up @@ -53,6 +62,11 @@ enum nct7802y_temp_source {
TEMP_SOURCE_PROGRAMMABLE_1,
};

struct nct7802y_sensors_config {
bool local_enable;
enum nct7802y_rtd_mode rtd[NCT7802Y_RTD_CNT];
};

struct nct7802y_fan_smartconfig {
enum nct7802y_fan_smartmode mode;
enum nct7802y_fan_speed speed;
Expand All @@ -76,6 +90,7 @@ struct nct7802y_fan_config {
struct drivers_i2c_nct7802y_config {
struct nct7802y_peci_config peci[NCT7802Y_PECI_CNT];
struct nct7802y_fan_config fan[NCT7802Y_FAN_CNT];
struct nct7802y_sensors_config sensors;
enum nct7802y_fan_pecierror on_pecierror;
u8 pecierror_minduty;
};
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/i2c/nct7802y/nct7802y.h
Expand Up @@ -11,6 +11,9 @@
#define BANK_SELECT 0x00

/* Bank 0 */
#define MODE_SELECTION 0x22
#define MODE_SELECTION_LTD_EN (1 << 6)
#define MODE_SELECTION_RTDx(x, val) ((val) << (x) * 2)

#define PECI_ENABLE 0x23
#define PECI_ENABLE_AGENTx(x) (1 << (x))
Expand Down
20 changes: 13 additions & 7 deletions src/drivers/i2c/nct7802y/nct7802y_fan.c
Expand Up @@ -68,7 +68,7 @@ void nct7802y_init_fan(struct device *const dev)
{
const struct drivers_i2c_nct7802y_config *const config = dev->chip_info;
unsigned int i;
u8 set;
u8 value;

if (nct7802y_select_bank(dev, 0) != CB_SUCCESS)
return;
Expand All @@ -78,21 +78,27 @@ void nct7802y_init_fan(struct device *const dev)
init_fan(dev, &config->fan[i], i);
}

value = 0;
for (i = 0; i < NCT7802Y_RTD_CNT; ++i)
value |= MODE_SELECTION_RTDx(i, config->sensors.rtd[i]);
if (config->sensors.local_enable)
value |= MODE_SELECTION_LTD_EN;
nct7802y_write(dev, MODE_SELECTION, value);

switch (config->on_pecierror) {
case PECI_ERROR_KEEP:
set = CLOSE_LOOP_FAN_PECI_ERR_CURR;
value = CLOSE_LOOP_FAN_PECI_ERR_CURR;
break;
case PECI_ERROR_VALUE:
set = CLOSE_LOOP_FAN_PECI_ERR_VALUE;
value = CLOSE_LOOP_FAN_PECI_ERR_VALUE;
break;
case PECI_ERROR_FULLSPEED:
set = CLOSE_LOOP_FAN_PECI_ERR_MAX;
value = CLOSE_LOOP_FAN_PECI_ERR_MAX;
break;
default:
set = 0;
value = 0;
break;
}
nct7802y_update(dev, CLOSE_LOOP_FAN_RPM_CTRL,
CLOSE_LOOP_FAN_PECI_ERR_MASK, set);
nct7802y_update(dev, CLOSE_LOOP_FAN_RPM_CTRL, CLOSE_LOOP_FAN_PECI_ERR_MASK, value);
nct7802y_write(dev, FAN_DUTY_ON_PECI_ERROR, config->pecierror_minduty);
}