29 changes: 19 additions & 10 deletions payloads/libpayload/drivers/i8042/keyboard.c
Expand Up @@ -317,26 +317,35 @@ void keyboard_init(void)
/* Enable first PS/2 port */
i8042_cmd(I8042_CMD_EN_KB);

/* Reset keyboard and self test (keyboard side) */
ret = keyboard_cmd(I8042_KBCMD_RESET);
if (ret != I8042_KBCMD_ACK) {
printf("ERROR: Keyboard reset failed ACK: 0x%x\n", ret);
return;
}

/* Set scancode set 1 */
ret = keyboard_cmd(I8042_KBCMD_SET_SCANCODE);
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE))
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) {
printf("ERROR: Keyboard set scancode failed!\n");
return;
}

ret = keyboard_cmd(I8042_SCANCODE_SET_1);
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE))
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) {
printf("ERROR: Keyboard scancode set#1 failed!\n");
return;
}

/*
* Set default parameters.
* Fix for broken QEMU ps/2 make scancodes.
*/
ret = keyboard_cmd(0xf6);
if (!ret) {
printf("ERROR: Keyboard set default params failed!\n");
return;
}

/* Enable scanning */
ret = keyboard_cmd(I8042_KBCMD_EN);
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE))
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) {
printf("ERROR: Keyboard enable scanning failed!\n");
return;
}

console_add_input_driver(&cons);
}
Expand Down
557 changes: 557 additions & 0 deletions payloads/libpayload/drivers/serial/qcs405.c

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions payloads/libpayload/drivers/usb/dwc2.c
Expand Up @@ -146,6 +146,8 @@ static int dwc2_disconnected(hci_t *controller)
return !(hprt.prtena && hprt.prtconnsts);
}

#define DWC2_SLEEP_TIME_US 5

/*
* This function returns the actual transfer length when the transfer succeeded
* or an error code if the transfer failed
Expand All @@ -157,14 +159,14 @@ wait_for_complete(endpoint_t *ep, uint32_t ch_num)
hcchar_t hcchar;
hctsiz_t hctsiz;
dwc2_reg_t *reg = DWC2_REG(ep->dev->controller);
int timeout = 600000; /* time out after 600000 * 5us == 3s */
int timeout = USB_MAX_PROCESSING_TIME_US / DWC_SLEEP_TIME_US;

/*
* TODO: We should take care of up to three times of transfer error
* retry here, according to the USB 2.0 spec 4.5.2
*/
do {
udelay(5);
udelay(DWC_SLEEP_TIME_US);
hcint.d32 = readl(&reg->host.hchn[ch_num].hcintn);
hctsiz.d32 = readl(&reg->host.hchn[ch_num].hctsizn);

Expand Down Expand Up @@ -374,12 +376,15 @@ static int dwc2_need_split(usbdev_t *dev, split_info_t *split)
return 1;
}

#define USB_FULL_LOW_SPEED_FRAME_US 1000

static int
dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num,
u8 *src, uint8_t skip_nak)
{
split_info_t split;
int ret, short_pkt, transferred = 0, timeout = 3000;
int ret, short_pkt, transferred = 0;
int timeout = USB_MAX_PROCESSING_TIME_US / USB_FULL_LOW_SPEED_FRAME_US;

ep->toggle = pid;

Expand All @@ -393,11 +398,11 @@ dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num,

/*
* dwc2_split_transfer() waits for the next FullSpeed
* frame boundary, so we have one try per millisecond.
* It's 3s timeout for each split transfer.
* frame boundary, so we only need to delay 500 us
* here to have one try per millisecond.
*/
if (ret == -HCSTAT_NAK && !skip_nak && --timeout) {
udelay(500);
udelay(USB_FULL_LOW_SPEED_FRAME_US / 2);
goto nak_retry;
}
} else {
Expand Down
14 changes: 4 additions & 10 deletions payloads/libpayload/drivers/usb/ehci.c
Expand Up @@ -247,6 +247,8 @@ static void free_qh_and_tds(ehci_qh_t *qh, qtd_t *cur)
free((void *)qh);
}

#define EHCI_SLEEP_TIME_US 50

static int wait_for_tds(qtd_t *head)
{
/* returns the amount of bytes *not* transmitted, or -1 for error */
Expand All @@ -256,18 +258,10 @@ static int wait_for_tds(qtd_t *head)
if (0) dump_td(virt_to_phys(cur));

/* wait for results */
/* how long to wait?
* tested with some USB2.0 flash sticks:
* TUR turn around took
* about 2.2s for the slowest (13fe:3800)
* max. 250ms for the others
* slowest non-TUR turn around took about 1.3s
* set to 3s to be safe as a failed TUR can be fatal
*/
int timeout = 60000; /* time out after 60000 * 50us == 3s */
int timeout = USB_MAX_PROCESSING_TIME_US / EHCI_SLEEP_TIME_US;
while ((cur->token & QTD_ACTIVE) && !(cur->token & QTD_HALTED)
&& timeout--)
udelay(50);
udelay(EHCI_SLEEP_TIME_US);
if (timeout < 0) {
usb_debug("Error: ehci: queue transfer "
"processing timed out.\n");
Expand Down
11 changes: 5 additions & 6 deletions payloads/libpayload/drivers/usb/ohci.c
Expand Up @@ -292,14 +292,13 @@ ohci_stop (hci_t *controller)
OHCI_INST (controller)->opreg->HcControl &= ~PeriodicListEnable;
}

#define OHCI_SLEEP_TIME_US 1000

static int
wait_for_ed(usbdev_t *dev, ed_t *head, int pages)
{
/* wait for results */
/* TOTEST: how long to wait?
* give 2s per TD (2 pages) plus another 2s for now
*/
int timeout = pages*1000 + 2000;
int timeout = USB_MAX_PROCESSING_TIME_US / OHCI_SLEEP_TIME_US;
while (((head->head_pointer & ~3) != head->tail_pointer) &&
!(head->head_pointer & 1) &&
((((td_t*)phys_to_virt(head->head_pointer & ~3))->config
Expand All @@ -315,9 +314,9 @@ wait_for_ed(usbdev_t *dev, ed_t *head, int pages)
((td_t*)phys_to_virt(head->head_pointer & ~3))->next_td,
head->tail_pointer,
(((td_t*)phys_to_virt(head->head_pointer & ~3))->config & TD_CC_MASK) >> TD_CC_SHIFT);
mdelay(1);
udelay(OHCI_SLEEP_TIME_US);
}
if (timeout < 0)
if (timeout <= 0)
usb_debug("Error: ohci: endpoint "
"descriptor processing timed out.\n");
/* Clear the done queue. */
Expand Down
8 changes: 5 additions & 3 deletions payloads/libpayload/drivers/usb/uhci.c
Expand Up @@ -272,21 +272,23 @@ uhci_stop (hci_t *controller)
uhci_reg_read16(controller, USBCMD) & ~1); // stop work on schedule
}

#define UHCI_SLEEP_TIME_US 30
#define UHCI_TIMEOUT (USB_MAX_PROCESSING_TIME_US / UHCI_SLEEP_TIME_US)
#define GET_TD(x) ((void*)(((unsigned int)(x))&~0xf))

static td_t *
wait_for_completed_qh (hci_t *controller, qh_t *qh)
{
int timeout = 1000; /* max 30 ms. */
int timeout = UHCI_TIMEOUT;
void *current = GET_TD (qh->elementlinkptr);
while (((qh->elementlinkptr & FLISTP_TERMINATE) == 0) && (timeout-- > 0)) {
if (current != GET_TD (qh->elementlinkptr)) {
current = GET_TD (qh->elementlinkptr);
timeout = 1000;
timeout = UHCI_TIMEOUT;
}
uhci_reg_write16(controller, USBSTS,
uhci_reg_read16(controller, USBSTS) | 0); // clear resettable registers
udelay (30);
udelay(UHCI_SLEEP_TIME_US);
}
return (GET_TD (qh->elementlinkptr) ==
0) ? 0 : GET_TD (phys_to_virt (qh->elementlinkptr));
Expand Down
14 changes: 4 additions & 10 deletions payloads/libpayload/drivers/usb/xhci_events.c
Expand Up @@ -236,7 +236,7 @@ xhci_wait_for_command_aborted(xhci_t *const xhci, const trb_t *const address)
* we don't get a response after 5s. Still, let the caller decide,
* what to do then.
*/
unsigned long timeout_us = 5 * 1000 * 1000; /* 5s */
unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US; /* 5s */
int cc = TIMEOUT;
/*
* Expects two command completion events:
Expand Down Expand Up @@ -280,13 +280,7 @@ xhci_wait_for_command_done(xhci_t *const xhci,
const trb_t *const address,
const int clear_event)
{
/*
* The Address Device Command should take most time, as it has to
* communicate with the USB device. Set address processing shouldn't
* take longer than 50ms (at the slave). Let's take a timeout of
* 100ms.
*/
unsigned long timeout_us = 100 * 1000; /* 100ms */
unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US; /* 5s */
int cc = TIMEOUT;
while (xhci_wait_for_event_type(xhci, TRB_EV_CMD_CMPL, &timeout_us)) {
if ((xhci->er.cur->ptr_low == virt_to_phys(address)) &&
Expand All @@ -311,8 +305,8 @@ int
xhci_wait_for_transfer(xhci_t *const xhci, const int slot_id, const int ep_id)
{
xhci_spew("Waiting for transfer on ID %d EP %d\n", slot_id, ep_id);
/* 3s for all types of transfers */ /* TODO: test, wait longer? */
unsigned long timeout_us = 3 * 1000 * 1000;
/* 5s for all types of transfers */
unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US;
int ret = TIMEOUT;
while (xhci_wait_for_event_type(xhci, TRB_EV_TRANSFER, &timeout_us)) {
if (TRB_GET(ID, xhci->er.cur) == slot_id &&
Expand Down
7 changes: 4 additions & 3 deletions payloads/libpayload/drivers/video/graphics.c
Expand Up @@ -183,6 +183,10 @@ int draw_box(const struct rect *box, const struct rgb_color *rgb)
struct vector top_left;
struct vector size;
struct vector p, t;

if (cbgfx_init())
return CBGFX_ERROR_INIT;

const uint32_t color = calculate_color(rgb, 0);
const struct scale top_left_s = {
.x = { .n = box->offset.x, .d = CANVAS_SCALE, },
Expand All @@ -193,9 +197,6 @@ int draw_box(const struct rect *box, const struct rgb_color *rgb)
.y = { .n = box->size.y, .d = CANVAS_SCALE, }
};

if (cbgfx_init())
return CBGFX_ERROR_INIT;

transform_vector(&top_left, &canvas.size, &top_left_s, &canvas.offset);
transform_vector(&size, &canvas.size, &size_s, &vzero);
add_vectors(&t, &top_left, &size);
Expand Down
107 changes: 52 additions & 55 deletions payloads/libpayload/include/coreboot_tables.h
Expand Up @@ -33,6 +33,58 @@
#include <arch/types.h>
#include <ipchksum.h>

enum {
CB_TAG_UNUSED = 0x0000,
CB_TAG_MEMORY = 0x0001,
CB_TAG_HWRPB = 0x0002,
CB_TAG_MAINBOARD = 0x0003,
CB_TAG_VERSION = 0x0004,
CB_TAG_EXTRA_VERSION = 0x0005,
CB_TAG_BUILD = 0x0006,
CB_TAG_COMPILE_TIME = 0x0007,
CB_TAG_COMPILE_BY = 0x0008,
CB_TAG_COMPILE_HOST = 0x0009,
CB_TAG_COMPILE_DOMAIN = 0x000a,
CB_TAG_COMPILER = 0x000b,
CB_TAG_LINKER = 0x000c,
CB_TAG_ASSEMBLER = 0x000d,
CB_TAG_SERIAL = 0x000f,
CB_TAG_CONSOLE = 0x0010,
CB_TAG_FORWARD = 0x0011,
CB_TAG_FRAMEBUFFER = 0x0012,
CB_TAG_GPIO = 0x0013,
CB_TAG_TIMESTAMPS = 0x0016,
CB_TAG_CBMEM_CONSOLE = 0x0017,
CB_TAG_MRC_CACHE = 0x0018,
CB_TAG_VBNV = 0x0019,
CB_TAG_VBOOT_HANDOFF = 0x0020,
CB_TAG_X86_ROM_MTRR = 0x0021,
CB_TAG_DMA = 0x0022,
CB_TAG_RAM_OOPS = 0x0023,
CB_TAG_ACPI_GNVS = 0x0024,
CB_TAG_BOARD_ID = 0x0025,
CB_TAG_VERSION_TIMESTAMP = 0x0026,
CB_TAG_WIFI_CALIBRATION = 0x0027,
CB_TAG_RAM_CODE = 0x0028,
CB_TAG_SPI_FLASH = 0x0029,
CB_TAG_SERIALNO = 0x002a,
CB_TAG_MTC = 0x002b,
CB_TAG_VPD = 0x002c,
CB_TAG_SKU_ID = 0x002d,
CB_TAG_BOOT_MEDIA_PARAMS = 0x0030,
CB_TAG_CBMEM_ENTRY = 0x0031,
CB_TAG_TSC_INFO = 0x0032,
CB_TAG_MAC_ADDRS = 0x0033,
CB_TAG_VBOOT_WORKBUF = 0x0034,
CB_TAG_MMC_INFO = 0x0035,
CB_TAG_TCPA_LOG = 0x0036,
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;
Expand All @@ -52,9 +104,6 @@ struct cb_record {
u32 size;
};

#define CB_TAG_UNUSED 0x0000
#define CB_TAG_MEMORY 0x0001

struct cb_memory_range {
struct cbuint64 start;
struct cbuint64 size;
Expand All @@ -75,16 +124,12 @@ struct cb_memory {
struct cb_memory_range map[0];
};

#define CB_TAG_HWRPB 0x0002

struct cb_hwrpb {
u32 tag;
u32 size;
u64 hwrpb;
};

#define CB_TAG_MAINBOARD 0x0003

struct cb_mainboard {
u32 tag;
u32 size;
Expand All @@ -93,25 +138,12 @@ struct cb_mainboard {
u8 strings[0];
};

#define CB_TAG_VERSION 0x0004
#define CB_TAG_EXTRA_VERSION 0x0005
#define CB_TAG_BUILD 0x0006
#define CB_TAG_COMPILE_TIME 0x0007
#define CB_TAG_COMPILE_BY 0x0008
#define CB_TAG_COMPILE_HOST 0x0009
#define CB_TAG_COMPILE_DOMAIN 0x000a
#define CB_TAG_COMPILER 0x000b
#define CB_TAG_LINKER 0x000c
#define CB_TAG_ASSEMBLER 0x000d

struct cb_string {
u32 tag;
u32 size;
u8 string[0];
};

#define CB_TAG_SERIAL 0x000f

struct cb_serial {
u32 tag;
u32 size;
Expand All @@ -138,8 +170,6 @@ struct cb_serial {
u32 uart_pci_addr;
};

#define CB_TAG_CONSOLE 0x00010

struct cb_console {
u32 tag;
u32 size;
Expand All @@ -153,15 +183,12 @@ struct cb_console {
#define CB_TAG_CONSOLE_SROM 4 // OBSOLETE
#define CB_TAG_CONSOLE_EHCI 5

#define CB_TAG_FORWARD 0x00011

struct cb_forward {
u32 tag;
u32 size;
u64 forward;
};

#define CB_TAG_FRAMEBUFFER 0x0012
struct cb_framebuffer {
u32 tag;
u32 size;
Expand All @@ -181,7 +208,6 @@ struct cb_framebuffer {
u8 reserved_mask_size;
};

#define CB_TAG_GPIO 0x0013
#define CB_GPIO_ACTIVE_LOW 0
#define CB_GPIO_ACTIVE_HIGH 1
#define CB_GPIO_MAX_NAME_LENGTH 16
Expand All @@ -200,32 +226,19 @@ struct cb_gpios {
struct cb_gpio gpios[0];
};

#define CB_TAG_VBNV 0x0019
#define CB_TAG_VBOOT_HANDOFF 0x0020
#define CB_TAG_VBOOT_WORKBUF 0x0034
#define CB_TAG_DMA 0x0022
#define CB_TAG_RAM_OOPS 0x0023
#define CB_TAG_MTC 0x002b
#define CB_TAG_VPD 0x002c
struct lb_range {
uint32_t tag;
uint32_t size;
uint64_t range_start;
uint32_t range_size;
};

#define CB_TAG_TIMESTAMPS 0x0016
#define CB_TAG_CBMEM_CONSOLE 0x0017
#define CB_TAG_MRC_CACHE 0x0018
#define CB_TAG_ACPI_GNVS 0x0024
#define CB_TAG_WIFI_CALIBRATION 0x0027
struct cb_cbmem_tab {
uint32_t tag;
uint32_t size;
uint64_t cbmem_tab;
};

#define CB_TAG_X86_ROM_MTRR 0x0021
struct cb_x86_rom_mtrr {
uint32_t tag;
uint32_t size;
Expand All @@ -236,17 +249,12 @@ struct cb_x86_rom_mtrr {
uint32_t index;
};


#define CB_TAG_BOARD_ID 0x0025
#define CB_TAG_RAM_CODE 0x0028
#define CB_TAG_SKU_ID 0x002d
struct cb_strapping_id {
uint32_t tag;
uint32_t size;
uint32_t id_code;
};

#define CB_TAG_SPI_FLASH 0x0029
struct cb_spi_flash {
uint32_t tag;
uint32_t size;
Expand All @@ -255,7 +263,6 @@ struct cb_spi_flash {
uint32_t erase_cmd;
};

#define CB_TAG_BOOT_MEDIA_PARAMS 0x0030
struct cb_boot_media_params {
uint32_t tag;
uint32_t size;
Expand All @@ -266,15 +273,13 @@ struct cb_boot_media_params {
uint64_t boot_media_size;
};

#define CB_TAG_TSC_INFO 0x0032
struct cb_tsc_info {
uint32_t tag;
uint32_t size;

uint32_t freq_khz;
};

#define CB_TAG_MAC_ADDRS 0x0033
struct mac_address {
uint8_t mac_addr[6];
uint8_t pad[2]; /* Pad it to 8 bytes to keep it simple. */
Expand All @@ -287,7 +292,6 @@ struct cb_macs {
struct mac_address mac_addrs[0];
};

#define CB_TAG_MMC_INFO 0x0035
struct cb_mmc_info {
uint32_t tag;
uint32_t size;
Expand All @@ -302,17 +306,14 @@ struct cb_mmc_info {
int32_t early_cmd1_status;
};

#define CB_TAG_SERIALNO 0x002a
#define CB_MAX_SERIALNO_LENGTH 32

#define CB_TAG_CMOS_OPTION_TABLE 0x00c8
struct cb_cmos_option_table {
u32 tag;
u32 size;
u32 header_length;
};

#define CB_TAG_OPTION 0x00c9
#define CB_CMOS_MAX_NAME_LENGTH 32
struct cb_cmos_entries {
u32 tag;
Expand All @@ -324,8 +325,6 @@ struct cb_cmos_entries {
u8 name[CB_CMOS_MAX_NAME_LENGTH];
};


#define CB_TAG_OPTION_ENUM 0x00ca
#define CB_CMOS_MAX_TEXT_LENGTH 32
struct cb_cmos_enums {
u32 tag;
Expand All @@ -335,7 +334,6 @@ struct cb_cmos_enums {
u8 text[CB_CMOS_MAX_TEXT_LENGTH];
};

#define CB_TAG_OPTION_DEFAULTS 0x00cb
#define CB_CMOS_IMAGE_BUFFER_SIZE 128
struct cb_cmos_defaults {
u32 tag;
Expand All @@ -345,7 +343,6 @@ struct cb_cmos_defaults {
u8 default_set[CB_CMOS_IMAGE_BUFFER_SIZE];
};

#define CB_TAG_OPTION_CHECKSUM 0x00cc
#define CB_CHECKSUM_NONE 0
#define CB_CHECKSUM_PCBIOS 1
struct cb_cmos_checksum {
Expand Down
18 changes: 18 additions & 0 deletions payloads/libpayload/include/usb/usb.h
Expand Up @@ -71,6 +71,24 @@ typedef enum {
/* SetAddress() recovery interval (USB 2.0 specification 9.2.6.3 */
#define SET_ADDRESS_MDELAY 2

/*
* USB sets an upper limit of 5 seconds for any transfer to be completed.
*
* Data originally from EHCI driver:
* Tested with some USB2.0 flash sticks:
* TUR turn around took about 2.2s for the slowest (13fe:3800), maximum
* of 250ms for the others.
*
* SET ADDRESS on xHCI controllers.
* The USB specification indicates that devices must complete processing
* of a SET ADDRESS request within 50 ms. However, some hubs were found
* to take more than 100 ms to complete a SET ADDRESS request on a
* downstream port.
*/
#define USB_MAX_PROCESSING_TIME_US (5 * 1000 * 1000)

#define USB_FULL_LOW_SPEED_FRAME_US 1000

typedef struct {
unsigned char bDescLength;
unsigned char bDescriptorType;
Expand Down
11 changes: 6 additions & 5 deletions payloads/libpayload/sample/Makefile
Expand Up @@ -28,19 +28,20 @@
##

# Sample libpayload Makefile.
include ../.xcompile
include ../.config
include ../.xcompile

ARCH-$(CONFIG_LP_ARCH_ARMV) := arm
ARCH-$(CONFIG_LP_ARCH_POWERPC) := powerpc
ARCH-$(CONFIG_LP_ARCH_X86) := i386
ARCH-$(CONFIG_LP_ARCH_ARM) := arm
ARCH-$(CONFIG_LP_ARCH_X86) := x86_32
ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64
ARCH-$(CONFIG_LP_ARCH_MIPS) := mips

CC := $(CC_$(ARCH-y))
AS := $(AS_$(ARCH-y))
LIBPAYLOAD_DIR := ../install/libpayload
XCC := CC="$(CC)" $(LIBPAYLOAD_DIR)/bin/lpgcc
XAS := AS="$(AS)" $(LIBPAYLOAD_DIR)/bin/lpas
CFLAGS := -Wall -Werror -Os
CFLAGS := -fno-builtin -Wall -Werror -Os
TARGET := hello
OBJS := $(TARGET).o

Expand Down
42 changes: 38 additions & 4 deletions src/Kconfig
Expand Up @@ -32,8 +32,13 @@ config LOCALVERSION
the coreboot version number, so that you can easily distinguish
boot logs of different boards from each other.

config CONFIGURABLE_CBFS_PREFIX
bool
help
Select this to prompt to use to configure the prefix for cbfs files.

config CBFS_PREFIX
string "CBFS prefix to use"
string "CBFS prefix to use" if CONFIGURABLE_CBFS_PREFIX
default "fallback"
help
Select the prefix to all files put into the image. It's "fallback"
Expand Down Expand Up @@ -129,6 +134,7 @@ config STATIC_OPTION_TABLE

config COMPRESS_RAMSTAGE
bool "Compress ramstage with LZMA"
depends on HAVE_RAMSTAGE
# Default value set at the end of the file
help
Compress ramstage to save memory in the flash image. Note
Expand All @@ -137,7 +143,7 @@ config COMPRESS_RAMSTAGE

config COMPRESS_PRERAM_STAGES
bool "Compress romstage and verstage with LZ4"
depends on !ARCH_X86
depends on !ARCH_X86 && (HAVE_ROMSTAGE || HAVE_VERSTAGE)
# Default value set at the end of the file
help
Compress romstage and (if it exists) verstage with LZ4 to save flash
Expand All @@ -148,6 +154,7 @@ config COMPRESS_PRERAM_STAGES

config COMPRESS_BOOTBLOCK
bool
depends on HAVE_BOOTBLOCK
help
This option can be used to compress the bootblock with LZ4 and attach
a small self-decompression stub to its front. This can drastically
Expand Down Expand Up @@ -234,6 +241,7 @@ config NO_RELOCATABLE_RAMSTAGE

config RELOCATABLE_RAMSTAGE
bool
depends on HAVE_RAMSTAGE
default !NO_RELOCATABLE_RAMSTAGE
select RELOCATABLE_MODULES
help
Expand Down Expand Up @@ -277,10 +285,13 @@ config BOOTSPLASH_FILE
The path and filename of the file to use as graphical bootsplash
screen. The file format has to be jpg.

config HAVE_RAMPAYLOAD
bool

config RAMPAYLOAD
bool "Enable coreboot flow without executing ramstage"
default n
depends on ARCH_X86
default y if ARCH_X86
depends on HAVE_RAMPAYLOAD
help
If this option is enabled, coreboot flow will skip ramstage
loading and execution of ramstage to load payload.
Expand Down Expand Up @@ -1188,3 +1199,26 @@ config BOOTSPLASH_FILE

config CBFS_SIZE
default ROM_SIZE

config HAVE_BOOTBLOCK
bool
default y

config HAVE_VERSTAGE
bool
depends on VBOOT_SEPARATE_VERSTAGE
default y

config HAVE_ROMSTAGE
bool
default y

config HAVE_POSTCAR
bool
depends on POSTCAR_STAGE
default y

config HAVE_RAMSTAGE
bool
default n if RAMPAYLOAD
default y
1 change: 1 addition & 0 deletions src/arch/arm/armv7/mmu.c
Expand Up @@ -29,6 +29,7 @@
*/

#include <assert.h>
#include <commonlib/helpers.h>
#include <stdlib.h>
#include <stdint.h>
#include <symbols.h>
Expand Down
3 changes: 2 additions & 1 deletion src/arch/arm/cpu.c
Expand Up @@ -29,6 +29,7 @@
*/
#include <stdlib.h>
#include <arch/cpu.h>
#include <commonlib/helpers.h>

/* Return the CPU struct which is at the high memory address of the stack.
*/
Expand All @@ -39,7 +40,7 @@ struct cpu_info *cpu_info(void)
"feature, make sure you add the proper assertions " \
"(and maybe consider revising the whole thing to work closer to what " \
"arm64 is doing now)."
uintptr_t addr = ALIGN((uintptr_t)__builtin_frame_address(0),
uintptr_t addr = ALIGN_UP((uintptr_t)__builtin_frame_address(0),
CONFIG_STACK_SIZE);
addr -= sizeof(struct cpu_info);
return (void *)addr;
Expand Down
2 changes: 1 addition & 1 deletion src/arch/arm64/armv8/bootblock.S
Expand Up @@ -19,7 +19,7 @@
/* NOTE: When making changes to general ARM64 initialization, keep in mind that
* there are other CPU entry points, using BOOTBLOCK_CUSTOM or entering the CPU
* in a later stage (like Tegra). Changes should generally be put into
* arm64_cpu_init so they can be shared between those instances. */
* arm64_init_cpu so they can be shared between those instances. */

ENTRY(_start)
/* Initialize PSTATE, SCTLR and caches to clean state, set up stack. */
Expand Down
11 changes: 3 additions & 8 deletions src/arch/arm64/fit_payload.c
Expand Up @@ -20,6 +20,7 @@
#include <string.h>
#include <commonlib/compression.h>
#include <commonlib/cbfs_serialized.h>
#include <commonlib/helpers.h>
#include <lib.h>
#include <fit.h>
#include <endian.h>
Expand Down Expand Up @@ -184,20 +185,14 @@ bool fit_payload_arch(struct prog *payload, struct fit_config_node *config,
bool place_anywhere;
void *arg = NULL;

if (!config->fdt || !fdt) {
printk(BIOS_CRIT, "CRIT: Providing a valid FDT is mandatory to "
"boot an ARM64 kernel!\n");
return false;
}

if (!decompress_kernel_header(config->kernel_node)) {
if (!decompress_kernel_header(config->kernel)) {
printk(BIOS_CRIT, "CRIT: Payload doesn't look like an ARM64"
" kernel Image.\n");
return false;
}

/* Update kernel size from image header, if possible */
kernel->size = get_kernel_size(config->kernel_node);
kernel->size = get_kernel_size(config->kernel);
printk(BIOS_DEBUG, "FIT: Using kernel size of 0x%zx bytes\n",
kernel->size);

Expand Down
27 changes: 14 additions & 13 deletions src/arch/riscv/Kconfig
@@ -1,6 +1,15 @@
config ARCH_RISCV_RV64
bool
select ARCH_RISCV

config ARCH_RISCV_RV32
bool
select ARCH_RISCV

config ARCH_RISCV
bool
default n

if ARCH_RISCV

config RISCV_ARCH
string
Expand All @@ -24,8 +33,8 @@ config ARCH_RISCV_M
# one implementation that will not have it due
# to security concerns.
bool
default n if ARCH_RISCV_M_DISABLED
default y
default y if ARCH_RISCV && !ARCH_RISCV_M_DISABLED
default n

config ARCH_RISCV_S
# S (supervisor) mode is for kernels. It is optional.
Expand All @@ -37,16 +46,6 @@ config ARCH_RISCV_U
bool
default n

config ARCH_RISCV_RV64
bool
default n
select ARCH_RISCV

config ARCH_RISCV_RV32
bool
default n
select ARCH_RISCV

config ARCH_RISCV_PMP
bool
default n
Expand Down Expand Up @@ -74,3 +73,5 @@ config RISCV_USE_ARCH_TIMER

config RISCV_WORKING_HARTID
int

endif # if ARCH_RISCV
7 changes: 7 additions & 0 deletions src/arch/riscv/boot.c
Expand Up @@ -19,6 +19,7 @@
#include <arch/encoding.h>
#include <arch/smp/smp.h>
#include <mcall.h>
#include <commonlib/cbfs_serialized.h>

/*
* A pointer to the Flattened Device Tree passed to coreboot by the boot ROM.
Expand All @@ -33,6 +34,12 @@ static void do_arch_prog_run(struct prog *prog)
int hart_id;
void *fdt = prog_entry_arg(prog);

/*
* Workaround selfboot putting the coreboot table into prog_entry_arg
*/
if (prog_cbfs_type(prog) == CBFS_TYPE_SELF)
fdt = HLS()->fdt;

/*
* If prog_entry_arg is not set (e.g. by fit_payload), use fdt from HLS
* instead.
Expand Down
2 changes: 1 addition & 1 deletion src/arch/riscv/include/mcall.h
Expand Up @@ -27,7 +27,7 @@
#endif

/* We save 37 registers, currently. */
#define MENTRY_FRAME_SIZE (HLS_SIZE + 37 * 8)
#define MENTRY_FRAME_SIZE (HLS_SIZE + 37 * __SIZEOF_POINTER__)

#ifndef __ASSEMBLER__

Expand Down
9 changes: 0 additions & 9 deletions src/arch/riscv/mcall.c
Expand Up @@ -25,24 +25,15 @@
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/

#include <arch/barrier.h>
#include <arch/errno.h>
#include <console/console.h>
#include <mcall.h>
#include <string.h>
#include <vm.h>

int mcalldebug; // set this interactively for copious debug.

void hls_init(uint32_t hart_id, void *fdt)
{
printk(BIOS_SPEW, "hart %d: HLS is %p\n", hart_id, HLS());
memset(HLS(), 0, sizeof(*HLS()));
HLS()->fdt = fdt;
HLS()->hart_id = hart_id;

mtime_init();

printk(BIOS_SPEW, "Time is %p and timecmp is %p\n",
HLS()->time, HLS()->timecmp);
}
25 changes: 20 additions & 5 deletions src/arch/riscv/payload.c
Expand Up @@ -19,23 +19,38 @@
#include <arch/boot.h>
#include <arch/encoding.h>
#include <console/console.h>
#include <vm.h>

void run_payload(struct prog *prog, void *fdt, int payload_mode)
{
void (*doit)(int hart_id, void *fdt) = prog_entry(prog);
int hart_id = read_csr(mhartid);
uintptr_t status = read_csr(mstatus);
status &= ~MSTATUS_MPIE;
status &= ~MSTATUS_MPP;
status = INSERT_FIELD(status, MSTATUS_MPIE, 0);
switch (payload_mode) {
case RISCV_PAYLOAD_MODE_U:
status = INSERT_FIELD(status, MSTATUS_MPP, PRV_U);
/* Trap vector base address point to the payload */
write_csr(utvec, doit);
/* disable U-Mode interrupt */
write_csr(uie, 0);
break;
case RISCV_PAYLOAD_MODE_S:
status |= MSTATUS_SPP;
status = INSERT_FIELD(status, MSTATUS_MPP, PRV_S);
/* Trap vector base address point to the payload */
write_csr(stvec, doit);
/* disable S-Mode interrupt */
write_csr(sie, 0);
/* disable MMU */
write_csr(satp, 0);
break;
case RISCV_PAYLOAD_MODE_M:
doit(hart_id, fdt);
return;
status = INSERT_FIELD(status, MSTATUS_MPP, PRV_M);
/* Trap vector base address point to the payload */
write_csr(mtvec, doit);
/* disable M-Mode interrupt */
write_csr(mie, 0);
break;
default:
die("wrong privilege level for payload");
break;
Expand Down
3 changes: 3 additions & 0 deletions src/arch/x86/Kconfig
Expand Up @@ -239,14 +239,17 @@ config ROMSTAGE_DEBUG_SPINLOOP
Add a spin (JMP .) in assembly_entry.S during early romstage to wait
for a JTAG debugger to break into the execution sequence.

# Selecting a cbfs prefix from the bootblock is only implemented with romcc
choice
prompt "Bootblock behaviour"
default BOOTBLOCK_SIMPLE
depends on !C_ENVIRONMENT_BOOTBLOCK

config BOOTBLOCK_SIMPLE
bool "Always load fallback"

config BOOTBLOCK_NORMAL
select CONFIGURABLE_CBFS_PREFIX
bool "Switch to normal if CMOS says so"

endchoice
Expand Down
29 changes: 15 additions & 14 deletions src/arch/x86/Makefile.inc
Expand Up @@ -193,7 +193,7 @@ verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += gdt_init.S
verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S

verstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c
verstage-y += cpu_common.c
verstage-y += memset.c
verstage-y += memcpy.c
verstage-y += memmove.c
Expand Down Expand Up @@ -230,7 +230,7 @@ romstage-y += boot.c
romstage-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += gdt_init.S
romstage-y += cbmem.c
romstage-y += cbfs_and_run.c
romstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c
romstage-y += cpu_common.c
romstage-$(CONFIG_EARLY_EBDA_INIT) += ebda.c
romstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
romstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
Expand Down Expand Up @@ -336,13 +336,6 @@ ramstage-$(CONFIG_COOP_MULTITASKING) += thread_switch.S
ramstage-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += wakeup.S

smm-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
smm-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
smm-y += memcpy.c
smm-y += memmove.c
smm-y += memset.c
smm-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c

ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
rmodules_x86_32-y += memcpy.c
rmodules_x86_32-y += memmove.c
Expand Down Expand Up @@ -379,11 +372,6 @@ ifneq ($(wildcard src/mainboard/$(MAINBOARDDIR)/fadt.c),)
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/fadt.c
endif
endif # CONFIG_GENERATE_ACPI_TABLES
ifeq ($(CONFIG_HAVE_SMI_HANDLER),y)
ifneq ($(wildcard src/mainboard/$(MAINBOARDDIR)/smihandler.c),)
smm-srcs += src/mainboard/$(MAINBOARDDIR)/smihandler.c
endif
endif

ramstage-libs ?=

Expand All @@ -408,3 +396,16 @@ else
endif

endif # CONFIG_ARCH_RAMSTAGE_X86_32 / CONFIG_ARCH_RAMSTAGE_X86_64

smm-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
smm-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
smm-y += memcpy.c
smm-y += memmove.c
smm-y += memset.c
smm-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c

ifeq ($(CONFIG_HAVE_SMI_HANDLER),y)
ifneq ($(wildcard src/mainboard/$(MAINBOARDDIR)/smihandler.c),)
smm-srcs += src/mainboard/$(MAINBOARDDIR)/smihandler.c
endif
endif
116 changes: 112 additions & 4 deletions src/arch/x86/acpi.c
Expand Up @@ -44,6 +44,7 @@
#include <arch/acpigen.h>
#include <device/pci.h>
#include <cbmem.h>
#include <commonlib/helpers.h>
#include <cpu/x86/lapic_def.h>
#include <cpu/cpu.h>
#include <cbfs.h>
Expand Down Expand Up @@ -218,6 +219,9 @@ void acpi_create_madt(acpi_madt_t *madt)

memset((void *)madt, 0, sizeof(acpi_madt_t));

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "APIC", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -248,6 +252,9 @@ void acpi_create_mcfg(acpi_mcfg_t *mcfg)

memset((void *)mcfg, 0, sizeof(acpi_mcfg_t));

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "MCFG", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -302,6 +309,9 @@ static void acpi_create_tcpa(acpi_tcpa_t *tcpa)
if (!lasa)
return;

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "TCPA", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -361,6 +371,9 @@ static void acpi_create_tpm2(acpi_tpm2_t *tpm2)
if (!lasa)
tpm2_log_len = 0;

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "TPM2", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -481,6 +494,9 @@ void acpi_create_srat(acpi_srat_t *srat,

memset((void *)srat, 0, sizeof(acpi_srat_t));

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "SRAT", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -508,6 +524,9 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,

memset((void *)dmar, 0, sizeof(acpi_dmar_t));

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "DMAR", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -669,6 +688,9 @@ void acpi_create_slit(acpi_slit_t *slit,

memset((void *)slit, 0, sizeof(acpi_slit_t));

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "SLIT", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand All @@ -694,6 +716,9 @@ void acpi_create_hpet(acpi_hpet_t *hpet)

memset((void *)hpet, 0, sizeof(acpi_hpet_t));

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "HPET", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -728,23 +753,80 @@ void acpi_create_vfct(struct device *device,

memset((void *)vfct, 0, sizeof(struct acpi_vfct));

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "VFCT", 4);
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
memcpy(header->asl_compiler_id, ASLC, 4);

header->asl_compiler_revision = asl_revision;
header->length = sizeof(struct acpi_vfct);
header->revision = get_acpi_table_revision(VFCT);

current = acpi_fill_vfct(device, vfct, current);

/* If no BIOS image, return with header->length == 0. */
if (!vfct->VBIOSImageOffset)
return;

/* (Re)calculate length and checksum. */
header->length = current - (unsigned long)vfct;
header->checksum = acpi_checksum((void *)vfct, header->length);
}

void acpi_create_ipmi(struct device *device,
struct acpi_spmi *spmi,
const u16 ipmi_revision,
const acpi_addr_t *addr,
const enum acpi_ipmi_interface_type type,
const s8 gpe_interrupt,
const u32 apic_interrupt,
const u32 uid)
{
acpi_header_t *header = &(spmi->header);
memset((void *)spmi, 0, sizeof(struct acpi_spmi));

/* Fill out header fields. */
memcpy(header->signature, "SPMI", 4);
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
memcpy(header->asl_compiler_id, ASLC, 4);

header->asl_compiler_revision = asl_revision;
header->length = sizeof(struct acpi_spmi);
header->revision = get_acpi_table_revision(SPMI);

spmi->reserved = 1;

if (device->path.type == DEVICE_PATH_PCI) {
spmi->pci_device_flag = ACPI_IPMI_PCI_DEVICE_FLAG;
spmi->pci_bus = device->bus->secondary;
spmi->pci_device = device->path.pci.devfn >> 3;
spmi->pci_function = device->path.pci.devfn & 0x7;
} else if (type != IPMI_INTERFACE_SSIF) {
memcpy(spmi->uid, &uid, sizeof(spmi->uid));
}

spmi->base_address = *addr;
spmi->specification_revision = ipmi_revision;

spmi->interface_type = type;

if (gpe_interrupt >= 0 && gpe_interrupt < 32) {
spmi->gpe = gpe_interrupt;
spmi->interrupt_type |= ACPI_IPMI_INT_TYPE_SCI;
}
if (apic_interrupt > 0) {
spmi->global_system_interrupt = apic_interrupt;
spmi->interrupt_type |= ACPI_IPMI_INT_TYPE_APIC;
}

/* Calculate checksum. */
header->checksum = acpi_checksum((void *)spmi, header->length);
}

void acpi_create_ivrs(acpi_ivrs_t *ivrs,
unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
unsigned long current))
Expand All @@ -754,6 +836,9 @@ void acpi_create_ivrs(acpi_ivrs_t *ivrs,

memset((void *)ivrs, 0, sizeof(acpi_ivrs_t));

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "IVRS", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -783,7 +868,7 @@ unsigned long acpi_write_hpet(struct device *device, unsigned long current,

hpet = (acpi_hpet_t *) current;
current += sizeof(acpi_hpet_t);
current = ALIGN(current, 16);
current = ALIGN_UP(current, 16);
acpi_create_hpet(hpet);
acpi_add_table(rsdp, hpet);

Expand All @@ -807,6 +892,10 @@ void acpi_create_dbg2(acpi_dbg2_header_t *dbg2,
current = (uintptr_t)dbg2;
memset(dbg2, 0, sizeof(acpi_dbg2_header_t));
header = &(dbg2->header);

if (!header)
return;

header->revision = get_acpi_table_revision(DBG2);
memcpy(header->signature, "DBG2", 4);
memcpy(header->oem_id, OEM_ID, 6);
Expand Down Expand Up @@ -926,6 +1015,9 @@ static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id)
{
acpi_header_t *header = &(rsdt->header);

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "RSDT", 4);
memcpy(header->oem_id, oem_id, 6);
Expand All @@ -946,6 +1038,9 @@ static void acpi_write_xsdt(acpi_xsdt_t *xsdt, char *oem_id, char *oem_table_id)
{
acpi_header_t *header = &(xsdt->header);

if (!header)
return;

/* Fill out header fields. */
memcpy(header->signature, "XSDT", 4);
memcpy(header->oem_id, oem_id, 6);
Expand Down Expand Up @@ -1046,7 +1141,8 @@ unsigned long acpi_create_hest_error_source(acpi_hest_t *hest,

memcpy(pos, data, data_len);
len += data_len;
header->length += len;
if (header)
header->length += len;

return len;
}
Expand All @@ -1059,6 +1155,9 @@ void acpi_write_hest(acpi_hest_t *hest,

memset(hest, 0, sizeof(acpi_hest_t));

if (!header)
return;

memcpy(header->signature, "HEST", 4);
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
Expand All @@ -1080,6 +1179,9 @@ void acpi_write_bert(acpi_bert_t *bert, uintptr_t region, size_t length)

memset(bert, 0, sizeof(acpi_bert_t));

if (!header)
return;

memcpy(header->signature, "BERT", 4);
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
Expand All @@ -1101,6 +1203,10 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
acpi_header_t *header = &(fadt->header);

memset((void *) fadt, 0, sizeof(acpi_fadt_t));

if (!header)
return;

memcpy(header->signature, "FACP", 4);
header->length = sizeof(acpi_fadt_t);
header->revision = get_acpi_table_revision(FADT);
Expand Down Expand Up @@ -1220,7 +1326,7 @@ unsigned long write_acpi_tables(unsigned long start)
acpi_write_xsdt(xsdt, oem_id, oem_table_id);

printk(BIOS_DEBUG, "ACPI: * FACS\n");
current = (ALIGN(current, 64));
current = ALIGN_UP(current, 64);
facs = (acpi_facs_t *) current;
current += sizeof(acpi_facs_t);
current = acpi_align_current(current);
Expand Down Expand Up @@ -1439,6 +1545,8 @@ int get_acpi_table_revision(enum acpi_tables table)
return 1;
case SLIT: /* ACPI 2.0 upto 6.3: 1 */
return 1;
case SPMI: /* IMPI 2.0 */
return 5;
case HPET: /* Currently 1. Table added in ACPI 2.0. */
return 1;
case VFCT: /* ACPI 2.0/3.0/4.0: 1 */
Expand Down
21 changes: 18 additions & 3 deletions src/arch/x86/acpi_device.c
Expand Up @@ -740,6 +740,9 @@ size_t acpi_dp_add_property_list(struct acpi_dp *dp,
const struct acpi_dp *prop;
size_t i, properties_added = 0;

if (!dp || !property_list)
return 0;

for (i = 0; i < property_count; i++) {
prop = &property_list[i];

Expand Down Expand Up @@ -775,6 +778,9 @@ size_t acpi_dp_add_property_list(struct acpi_dp *dp,
struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name,
uint64_t value)
{
if (!dp)
return NULL;

struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_INTEGER, name);

if (new)
Expand All @@ -786,6 +792,9 @@ struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name,
struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name,
const char *string)
{
if (!dp)
return NULL;

struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_STRING, name);

if (new)
Expand All @@ -797,6 +806,9 @@ struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name,
struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name,
const char *reference)
{
if (!dp)
return NULL;

struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_REFERENCE, name);

if (new)
Expand All @@ -810,7 +822,7 @@ struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
{
struct acpi_dp *new;

if (!child || child->type != ACPI_DP_TYPE_TABLE)
if (!dp || !child || child->type != ACPI_DP_TYPE_TABLE)
return NULL;

new = acpi_dp_new(dp, ACPI_DP_TYPE_CHILD, name);
Expand All @@ -826,7 +838,7 @@ struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array)
{
struct acpi_dp *new;

if (!array || array->type != ACPI_DP_TYPE_TABLE)
if (!dp || !array || array->type != ACPI_DP_TYPE_TABLE)
return NULL;

new = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, array->name);
Expand All @@ -842,7 +854,7 @@ struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
struct acpi_dp *dp_array;
int i;

if (len <= 0)
if (!dp || len <= 0)
return NULL;

dp_array = acpi_dp_new_table(name);
Expand All @@ -862,6 +874,9 @@ struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
const char *ref, int index, int pin,
int active_low)
{
if (!dp)
return NULL;

struct acpi_dp *gpio = acpi_dp_new_table(name);

if (!gpio)
Expand Down
1 change: 1 addition & 0 deletions src/arch/x86/acpi_s3.c
Expand Up @@ -18,6 +18,7 @@
#include <arch/acpi.h>
#include <arch/cpu.h>
#include <cbmem.h>
#include <commonlib/helpers.h>
#include <fallback.h>
#include <timestamp.h>
#include <program_loading.h>
Expand Down
57 changes: 57 additions & 0 deletions src/arch/x86/acpigen.c
Expand Up @@ -514,6 +514,63 @@ void acpigen_write_field(const char *name, struct fieldlist *l, size_t count,
acpigen_pop_len();
}

/*
* Generate ACPI AML code for IndexField
* Arg0: region name
* Arg1: Pointer to struct fieldlist.
* Arg2: no. of entries in Arg1
* Arg3: flags which indicate filed access type, lock rule & update rule.
* Example with fieldlist
* struct fieldlist l[] = {
* FIELDLIST_OFFSET(0x84),
* FIELDLIST_NAMESTR("PMCS", 2),
* };
* acpigen_write_field("IDX", "DATA" l, ARRAY_SIZE(l), FIELD_ANYACC |
* FIELD_NOLOCK |
* FIELD_PRESERVE);
* Output:
* IndexField (IDX, DATA, AnyAcc, NoLock, Preserve)
* {
* Offset (0x84),
* PMCS, 2
* }
*/
void acpigen_write_indexfield(const char *idx, const char *data,
struct fieldlist *l, size_t count, uint8_t flags)
{
uint16_t i;
uint32_t current_bit_pos = 0;

/* FieldOp */
acpigen_emit_ext_op(INDEX_FIELD_OP);
/* Package Length */
acpigen_write_len_f();
/* NameString 4 chars only */
acpigen_emit_simple_namestring(idx);
/* NameString 4 chars only */
acpigen_emit_simple_namestring(data);
/* Field Flag */
acpigen_emit_byte(flags);

for (i = 0; i < count; i++) {
switch (l[i].type) {
case NAME_STRING:
acpigen_write_field_name(l[i].name, 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;
break;
default:
printk(BIOS_ERR, "%s: Invalid field type 0x%X\n"
, __func__, l[i].type);
break;
}
}
acpigen_pop_len();
}

void acpigen_write_empty_PCT(void)
{
/*
Expand Down
7 changes: 0 additions & 7 deletions src/arch/x86/car.ld
Expand Up @@ -91,13 +91,6 @@
_car_global_end = .;
_car_relocatable_data_end = .;

#if CONFIG(NORTHBRIDGE_INTEL_SANDYBRIDGE) && !CONFIG(USE_NATIVE_RAMINIT)
. = ABSOLUTE(0xff7e1000);
_mrc_pool = .;
. += 0x5000;
_emrc_pool = .;
#endif

#if !CONFIG(C_ENVIRONMENT_BOOTBLOCK)
_car_stack_start = .;
_car_stack_end = _car_region_end;
Expand Down
2 changes: 2 additions & 0 deletions src/arch/x86/cpu.c
Expand Up @@ -113,6 +113,7 @@ static struct {
{ X86_VENDOR_TRANSMETA, "TransmetaCPU", },
{ X86_VENDOR_NSC, "Geode by NSC", },
{ X86_VENDOR_SIS, "SiS SiS SiS ", },
{ X86_VENDOR_HYGON, "HygonGenuine", },
};

static const char *const x86_vendor_name[] = {
Expand All @@ -126,6 +127,7 @@ static const char *const x86_vendor_name[] = {
[X86_VENDOR_TRANSMETA] = "Transmeta",
[X86_VENDOR_NSC] = "NSC",
[X86_VENDOR_SIS] = "SiS",
[X86_VENDOR_HYGON] = "Hygon",
};

static const char *cpu_vendor_name(int vendor)
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86/cpu_common.c
Expand Up @@ -49,7 +49,7 @@ int cpu_have_cpuid(void)
}
#endif

int cpu_cpuid_extended_level(void)
unsigned int cpu_cpuid_extended_level(void)
{
return cpuid_eax(0x80000000);
}
Expand Down
3 changes: 2 additions & 1 deletion src/arch/x86/gdt.c
Expand Up @@ -16,6 +16,7 @@
#include <types.h>
#include <string.h>
#include <cbmem.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <cpu/x86/gdt.h>

Expand Down Expand Up @@ -46,7 +47,7 @@ static void move_gdt(int is_recovery)
newgdt = cbmem_find(CBMEM_ID_GDT);
num_gdt_bytes = (uintptr_t)&gdt_end - (uintptr_t)&gdt;
if (!newgdt) {
newgdt = cbmem_add(CBMEM_ID_GDT, ALIGN(num_gdt_bytes, 512));
newgdt = cbmem_add(CBMEM_ID_GDT, ALIGN_UP(num_gdt_bytes, 512));
if (!newgdt) {
printk(BIOS_ERR, "Error: Could not relocate GDT.\n");
return;
Expand Down
52 changes: 49 additions & 3 deletions src/arch/x86/include/arch/acpi.h
Expand Up @@ -56,11 +56,11 @@
#define OEM_ID "COREv4" /* Must be exactly 6 bytes long! */

#if !defined(__ASSEMBLER__) && !defined(__ACPI__) && !defined(__ROMCC__)
#include <stdint.h>
#include <commonlib/helpers.h>
#include <device/device.h>
#include <uuid.h>
#include <cper.h>
#include <types.h>

#define RSDP_SIG "RSD PTR " /* RSDT pointer signature */
#define ASLC "CORE" /* Must be exactly 4 bytes long! */
Expand All @@ -82,7 +82,7 @@ enum acpi_tables {
BERT, DBG2, DMAR, DSDT, FACS, FADT, HEST, HPET, IVRS, MADT, MCFG,
RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT,
/* Additional proprietary tables used by coreboot */
VFCT, NHLT
VFCT, NHLT, SPMI
};

/* RSDP (Root System Description Pointer) */
Expand Down Expand Up @@ -782,6 +782,43 @@ enum acpi_upc_type {
UPC_TYPE_HUB
};

enum acpi_ipmi_interface_type {
IPMI_INTERFACE_RESERVED = 0,
IPMI_INTERFACE_KCS,
IPMI_INTERFACE_SMIC,
IPMI_INTERFACE_BT,
IPMI_INTERFACE_SSIF,
};

#define ACPI_IPMI_PCI_DEVICE_FLAG (1 << 0)
#define ACPI_IPMI_INT_TYPE_SCI (1 << 0)
#define ACPI_IPMI_INT_TYPE_APIC (1 << 1)

/* ACPI IPMI 2.0 */
struct acpi_spmi {
struct acpi_table_header header;
u8 interface_type;
u8 reserved;
u16 specification_revision;
u8 interrupt_type;
u8 gpe;
u8 reserved2;
u8 pci_device_flag;

u32 global_system_interrupt;
acpi_addr_t base_address;
union {
struct {
u8 pci_segment_group;
u8 pci_bus;
u8 pci_device;
u8 pci_function;
};
u8 uid[4];
};
u8 reserved3;
} __packed;

unsigned long fw_cfg_acpi_tables(unsigned long start);

/* These are implemented by the target port or north/southbridge. */
Expand Down Expand Up @@ -834,6 +871,15 @@ void acpi_create_vfct(struct device *device,
struct acpi_vfct *vfct_struct,
unsigned long current));

void acpi_create_ipmi(struct device *device,
struct acpi_spmi *spmi,
const u16 ipmi_revision,
const acpi_addr_t *addr,
const enum acpi_ipmi_interface_type type,
const s8 gpe_interrupt,
const u32 apic_interrupt,
const u32 uid);

void acpi_create_ivrs(acpi_ivrs_t *ivrs,
unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
unsigned long current));
Expand Down Expand Up @@ -958,7 +1004,7 @@ static inline int acpi_is_wakeup_s4(void) { return 0; }

static inline uintptr_t acpi_align_current(uintptr_t current)
{
return ALIGN(current, 16);
return ALIGN_UP(current, 16);
}

/* ACPI table revisions should match the revision of the ACPI spec
Expand Down
6 changes: 6 additions & 0 deletions src/arch/x86/include/arch/acpigen.h
Expand Up @@ -420,6 +420,12 @@ void acpigen_write_opregion(struct opregion *opreg);
*/
void acpigen_write_field(const char *name, struct fieldlist *l, size_t count,
uint8_t flags);
/*
* Generate ACPI AML code for IndexField
* This function takes input index name, data name, fieldlist, count & flags.
*/
void acpigen_write_indexfield(const char *idx, const char *data,
struct fieldlist *l, size_t count, uint8_t flags);

int get_cst_entries(acpi_cstate_t **);

Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86/include/arch/bert_storage.h
Expand Up @@ -67,7 +67,7 @@ size_t bert_storage_remaining(void);
/* Find if errors were added, a BERT region is present, and ACPI table needed */
int bert_errors_present(void);

/* Get the number of entries accociated with status */
/* Get the number of entries associated with status */
static inline size_t bert_entry_count(acpi_generic_error_status_t *status)
{
return (status->block_status & GENERIC_ERR_STS_ENTRY_COUNT_MASK)
Expand Down
8 changes: 5 additions & 3 deletions src/arch/x86/include/arch/cpu.h
Expand Up @@ -152,6 +152,7 @@ static inline unsigned int cpuid_edx(unsigned int op)
#define X86_VENDOR_TRANSMETA 8
#define X86_VENDOR_NSC 9
#define X86_VENDOR_SIS 10
#define X86_VENDOR_HYGON 11
#define X86_VENDOR_ANY 0xfe
#define X86_VENDOR_UNKNOWN 0xff

Expand Down Expand Up @@ -199,7 +200,7 @@ static inline unsigned int cpuid_edx(unsigned int op)
#define CPUID_CACHE_NO_OF_SETS_MASK 0xffffffff
#define CPUID_CACHE_NO_OF_SETS(res) CPUID_CACHE(NO_OF_SETS, (res).ecx)

int cpu_cpuid_extended_level(void);
unsigned int cpu_cpuid_extended_level(void);
int cpu_have_cpuid(void);

void smm_init(void);
Expand Down Expand Up @@ -308,8 +309,9 @@ struct postcar_frame {
};

/*
* Initialize postcar_frame object allocating stack size in cbmem
* with the provided size. Returns 0 on success, < 0 on error.
* Initialize postcar_frame object allocating stack from cbmem,
* with stack_size == 0, default 4 KiB is allocated.
* Returns 0 on success, < 0 on error.
*/
int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size);

Expand Down
3 changes: 2 additions & 1 deletion src/arch/x86/include/arch/early_variables.h
Expand Up @@ -17,6 +17,7 @@
#define ARCH_EARLY_VARIABLES_H

#include <arch/symbols.h>
#include <commonlib/helpers.h>
#include <stdlib.h>

#if ENV_CACHE_AS_RAM && !CONFIG(NO_CAR_GLOBAL_MIGRATION)
Expand Down Expand Up @@ -69,7 +70,7 @@ int car_active(void);
static inline size_t car_data_size(void)
{
size_t car_size = _car_relocatable_data_size;
return ALIGN(car_size, 64);
return ALIGN_UP(car_size, 64);
}

static inline size_t car_object_offset(void *ptr)
Expand Down
24 changes: 24 additions & 0 deletions src/arch/x86/include/arch/memory_clear.h
@@ -0,0 +1,24 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2019 9elements Agency GmbH
* Copyright (C) 2019 Facebook Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#ifndef MEMORY_CLEAR_H
#define MEMORY_CLEAR_H

#include <memrange.h>

int arch_clear_memranges(const struct memranges *mem_reserved);

#endif /* MEMORY_CLEAR_H */
3 changes: 2 additions & 1 deletion src/arch/x86/pirq_routing.c
Expand Up @@ -16,6 +16,7 @@
*/
#include <console/console.h>
#include <arch/pirq_routing.h>
#include <commonlib/helpers.h>
#include <string.h>
#include <device/pci.h>

Expand Down Expand Up @@ -191,7 +192,7 @@ unsigned long copy_pirq_routing_table(unsigned long addr,
const struct irq_routing_table *routing_table)
{
/* Align the table to be 16 byte aligned. */
addr = ALIGN(addr, 16);
addr = ALIGN_UP(addr, 16);

/* This table must be between 0xf0000 & 0x100000 */
printk(BIOS_INFO, "Copying Interrupt Routing Table to 0x%08lx... ",
Expand Down
12 changes: 10 additions & 2 deletions src/arch/x86/postcar_loader.c
Expand Up @@ -48,6 +48,15 @@ int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size)
{
void *stack;

/*
* Use default postcar stack size of 4 KiB. This value should
* not be decreased, because if mainboards use vboot, 1 KiB will
* not be enough anymore.
*/

if (stack_size == 0)
stack_size = 4 * KiB;

stack = cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, stack_size);
if (stack == NULL) {
printk(BIOS_ERR, "Couldn't add %zd byte stack in cbmem.\n",
Expand Down Expand Up @@ -154,8 +163,7 @@ static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf)

finalize_load(rsl.params, pcf->stack);

if (!CONFIG(NO_STAGE_CACHE))
stage_cache_add(STAGE_POSTCAR, prog);
stage_cache_add(STAGE_POSTCAR, prog);
}

void run_postcar_phase(struct postcar_frame *pcf)
Expand Down
1 change: 0 additions & 1 deletion src/arch/x86/rdrand.c
Expand Up @@ -75,7 +75,6 @@ int get_random_number_64(uint64_t *rand)
#if ENV_X86_64
if (rdrand_64(rand))
return 0;
else
#endif
if (rdrand_32(&rand_high) && rdrand_32(&rand_low)) {
*rand = ((uint64_t)rand_high << 32) |
Expand Down
83 changes: 80 additions & 3 deletions src/arch/x86/smbios.c
Expand Up @@ -30,6 +30,10 @@
#include <memory_info.h>
#include <spd.h>
#include <cbmem.h>
#include <commonlib/helpers.h>
#include <device/pci_ids.h>
#include <device/pci_def.h>
#include <device/pci.h>
#if CONFIG(CHROMEOS)
#include <vendorcode/google/chromeos/gnvs.h>
#endif
Expand All @@ -50,6 +54,41 @@ static u8 smbios_checksum(u8 *p, u32 length)
return -ret;
}

/* Get the device type 41 from the dev struct */
static u8 smbios_get_device_type_from_dev(struct device *dev)
{
u16 pci_basesubclass = (dev->class >> 8) & 0xFFFF;

switch (pci_basesubclass) {
case PCI_CLASS_NOT_DEFINED:
return SMBIOS_DEVICE_TYPE_OTHER;
case PCI_CLASS_DISPLAY_VGA:
case PCI_CLASS_DISPLAY_XGA:
case PCI_CLASS_DISPLAY_3D:
case PCI_CLASS_DISPLAY_OTHER:
return SMBIOS_DEVICE_TYPE_VIDEO;
case PCI_CLASS_STORAGE_SCSI:
return SMBIOS_DEVICE_TYPE_SCSI;
case PCI_CLASS_NETWORK_ETHERNET:
return SMBIOS_DEVICE_TYPE_ETHERNET;
case PCI_CLASS_NETWORK_TOKEN_RING:
return SMBIOS_DEVICE_TYPE_TOKEN_RING;
case PCI_CLASS_MULTIMEDIA_VIDEO:
case PCI_CLASS_MULTIMEDIA_AUDIO:
case PCI_CLASS_MULTIMEDIA_PHONE:
case PCI_CLASS_MULTIMEDIA_OTHER:
return SMBIOS_DEVICE_TYPE_SOUND;
case PCI_CLASS_STORAGE_ATA:
return SMBIOS_DEVICE_TYPE_PATA;
case PCI_CLASS_STORAGE_SATA:
return SMBIOS_DEVICE_TYPE_SATA;
case PCI_CLASS_STORAGE_SAS:
return SMBIOS_DEVICE_TYPE_SAS;
default:
return SMBIOS_DEVICE_TYPE_UNKNOWN;
}
}


int smbios_add_string(u8 *start, const char *str)
{
Expand Down Expand Up @@ -334,6 +373,11 @@ static int create_smbios_type17_for_dimm(struct dimm_info *dimm,
dimm->module_part_number[DIMM_INFO_PART_NUMBER_SIZE - 1] = '\0';
smbios_fill_dimm_part_number((char *)dimm->module_part_number, t);

/* Voltage Levels */
t->configured_voltage = dimm->vdd_voltage;
t->minimum_voltage = dimm->vdd_voltage;
t->maximum_voltage = dimm->vdd_voltage;

/* Synchronous = 1 */
t->type_detail = 0x0080;
/* no handle for error information */
Expand Down Expand Up @@ -1014,6 +1058,38 @@ static int smbios_write_type127(unsigned long *current, int handle)
return len;
}

/* Generate Type41 entries from devicetree */
static int smbios_walk_device_tree_type41(struct device *dev, int *handle,
unsigned long *current)
{
static u8 type41_inst_cnt[SMBIOS_DEVICE_TYPE_COUNT + 1] = {};

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

u8 device_type = smbios_get_device_type_from_dev(dev);

if (device_type == SMBIOS_DEVICE_TYPE_OTHER ||
device_type == SMBIOS_DEVICE_TYPE_UNKNOWN)
return 0;

if (device_type > SMBIOS_DEVICE_TYPE_COUNT)
return 0;

const char *name = get_pci_subclass_name(dev);

return smbios_write_type41(current, handle,
name, // name
type41_inst_cnt[device_type]++, // inst
0, // segment
dev->bus->secondary, //bus
PCI_SLOT(dev->path.pci.devfn), // device
PCI_FUNC(dev->path.pci.devfn), // func
device_type);
}

/* Generate Type9 entries from devicetree */
static int smbios_walk_device_tree_type9(struct device *dev, int *handle,
unsigned long *current)
Expand Down Expand Up @@ -1077,6 +1153,7 @@ static int smbios_walk_device_tree(struct device *tree, int *handle,
len += dev->ops->get_smbios_data(dev, handle, current);
}
len += smbios_walk_device_tree_type9(dev, handle, current);
len += smbios_walk_device_tree_type41(dev, handle, current);
}
return len;
}
Expand All @@ -1089,12 +1166,12 @@ unsigned long smbios_write_tables(unsigned long current)
int max_struct_size = 0;
int handle = 0;

current = ALIGN(current, 16);
current = ALIGN_UP(current, 16);
printk(BIOS_DEBUG, "%s: %08lx\n", __func__, current);

se = (struct smbios_entry *)current;
current += sizeof(struct smbios_entry);
current = ALIGN(current, 16);
current = ALIGN_UP(current, 16);

tables = current;
update_max(len, max_struct_size, smbios_write_type0(&current,
Expand Down Expand Up @@ -1134,7 +1211,7 @@ unsigned long smbios_write_tables(unsigned long current)
memcpy(se->anchor, "_SM_", 4);
se->length = sizeof(struct smbios_entry);
se->major_version = 2;
se->minor_version = 7;
se->minor_version = 8;
se->max_struct_size = max_struct_size;
se->struct_count = handle;
memcpy(se->intermediate_anchor_string, "_DMI_", 5);
Expand Down
15 changes: 8 additions & 7 deletions src/arch/x86/tables.c
Expand Up @@ -23,6 +23,7 @@
#include <arch/pirq_routing.h>
#include <arch/smp/mpspec.h>
#include <arch/acpi.h>
#include <commonlib/helpers.h>
#include <string.h>
#include <cbmem.h>
#include <smbios.h>
Expand All @@ -36,7 +37,7 @@ static unsigned long write_pirq_table(unsigned long rom_table_end)

/* This table must be between 0x0f0000 and 0x100000 */
rom_table_end = write_pirq_routing_table(rom_table_end);
rom_table_end = ALIGN(rom_table_end, 1024);
rom_table_end = ALIGN_UP(rom_table_end, 1024);

/* And add a high table version for those payloads that
* want to live in the F segment
Expand Down Expand Up @@ -68,7 +69,7 @@ static unsigned long write_mptable(unsigned long rom_table_end)

/* The smp table must be in 0-1K, 639K-640K, or 960K-1M */
rom_table_end = write_smp_table(rom_table_end);
rom_table_end = ALIGN(rom_table_end, 1024);
rom_table_end = ALIGN_UP(rom_table_end, 1024);

high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_MPTABLE,
MAX_MP_TABLE_SIZE);
Expand Down Expand Up @@ -114,7 +115,7 @@ static unsigned long write_acpi_table(unsigned long rom_table_end)
unsigned long acpi_start = high_table_pointer;
unsigned long new_high_table_pointer;

rom_table_end = ALIGN(rom_table_end, 16);
rom_table_end = ALIGN_UP(rom_table_end, 16);
new_high_table_pointer = write_acpi_tables(high_table_pointer);
if (new_high_table_pointer > (high_table_pointer
+ MAX_ACPI_SIZE))
Expand Down Expand Up @@ -146,10 +147,10 @@ static unsigned long write_acpi_table(unsigned long rom_table_end)
printk(BIOS_ERR,
"ERROR: Didn't find RSDP in high table.\n");
}
rom_table_end = ALIGN(rom_table_end + sizeof(acpi_rsdp_t), 16);
rom_table_end = ALIGN_UP(rom_table_end + sizeof(acpi_rsdp_t), 16);
} else {
rom_table_end = write_acpi_tables(rom_table_end);
rom_table_end = ALIGN(rom_table_end, 1024);
rom_table_end = ALIGN_UP(rom_table_end, 1024);
}

return rom_table_end;
Expand All @@ -168,7 +169,7 @@ static unsigned long write_smbios_table(unsigned long rom_table_end)

new_high_table_pointer =
smbios_write_tables(high_table_pointer);
rom_table_end = ALIGN(rom_table_end, 16);
rom_table_end = ALIGN_UP(rom_table_end, 16);
memcpy((void *)rom_table_end, (void *)high_table_pointer,
sizeof(struct smbios_entry));
rom_table_end += sizeof(struct smbios_entry);
Expand All @@ -184,7 +185,7 @@ static unsigned long write_smbios_table(unsigned long rom_table_end)
new_rom_table_end = smbios_write_tables(rom_table_end);
printk(BIOS_DEBUG, "SMBIOS size %ld bytes\n", new_rom_table_end
- rom_table_end);
rom_table_end = ALIGN(new_rom_table_end, 16);
rom_table_end = ALIGN_UP(new_rom_table_end, 16);
}

return rom_table_end;
Expand Down
2 changes: 2 additions & 0 deletions src/commonlib/include/commonlib/cbmem_id.h
Expand Up @@ -19,6 +19,7 @@

#define CBMEM_ID_ACPI 0x41435049
#define CBMEM_ID_ACPI_GNVS 0x474e5653
#define CBMEM_ID_ACPI_UCSI 0x55435349
#define CBMEM_ID_AFTER_CAR 0xc4787a93
#define CBMEM_ID_AGESA_RUNTIME 0x41474553
#define CBMEM_ID_AMDMCT_MEMINFO 0x494D454E
Expand Down Expand Up @@ -82,6 +83,7 @@
#define CBMEM_ID_TO_NAME_TABLE \
{ CBMEM_ID_ACPI, "ACPI " }, \
{ CBMEM_ID_ACPI_GNVS, "ACPI GNVS " }, \
{ CBMEM_ID_ACPI_UCSI, "ACPI UCSI " }, \
{ CBMEM_ID_AGESA_RUNTIME, "AGESA RSVD " }, \
{ CBMEM_ID_AFTER_CAR, "AFTER CAR " }, \
{ CBMEM_ID_AMDMCT_MEMINFO, "AMDMEM INFO" }, \
Expand Down
102 changes: 52 additions & 50 deletions src/commonlib/include/commonlib/coreboot_tables.h
Expand Up @@ -44,6 +44,58 @@
* table entries and be backwards compatible, but it is not required.
*/

enum {
LB_TAG_UNUSED = 0x0000,
LB_TAG_MEMORY = 0x0001,
LB_TAG_HWRPB = 0x0002,
LB_TAG_MAINBOARD = 0x0003,
LB_TAG_VERSION = 0x0004,
LB_TAG_EXTRA_VERSION = 0x0005,
LB_TAG_BUILD = 0x0006,
LB_TAG_COMPILE_TIME = 0x0007,
LB_TAG_COMPILE_BY = 0x0008,
LB_TAG_COMPILE_HOST = 0x0009,
LB_TAG_COMPILE_DOMAIN = 0x000a,
LB_TAG_COMPILER = 0x000b,
LB_TAG_LINKER = 0x000c,
LB_TAG_ASSEMBLER = 0x000d,
LB_TAG_SERIAL = 0x000f,
LB_TAG_CONSOLE = 0x0010,
LB_TAG_FORWARD = 0x0011,
LB_TAG_FRAMEBUFFER = 0x0012,
LB_TAG_GPIO = 0x0013,
LB_TAG_TIMESTAMPS = 0x0016,
LB_TAG_CBMEM_CONSOLE = 0x0017,
LB_TAG_MRC_CACHE = 0x0018,
LB_TAG_VBNV = 0x0019,
LB_TAG_VBOOT_HANDOFF = 0x0020,
LB_TAG_X86_ROM_MTRR = 0x0021,
LB_TAG_DMA = 0x0022,
LB_TAG_RAM_OOPS = 0x0023,
LB_TAG_ACPI_GNVS = 0x0024,
LB_TAG_BOARD_ID = 0x0025,
LB_TAG_VERSION_TIMESTAMP = 0x0026,
LB_TAG_WIFI_CALIBRATION = 0x0027,
LB_TAG_RAM_CODE = 0x0028,
LB_TAG_SPI_FLASH = 0x0029,
LB_TAG_SERIALNO = 0x002a,
LB_TAG_MTC = 0x002b,
LB_TAG_VPD = 0x002c,
LB_TAG_SKU_ID = 0x002d,
LB_TAG_BOOT_MEDIA_PARAMS = 0x0030,
LB_TAG_CBMEM_ENTRY = 0x0031,
LB_TAG_TSC_INFO = 0x0032,
LB_TAG_MAC_ADDRS = 0x0033,
LB_TAG_VBOOT_WORKBUF = 0x0034,
LB_TAG_MMC_INFO = 0x0035,
LB_TAG_TCPA_LOG = 0x0036,
LB_TAG_CMOS_OPTION_TABLE = 0x00c8,
LB_TAG_OPTION = 0x00c9,
LB_TAG_OPTION_ENUM = 0x00ca,
LB_TAG_OPTION_DEFAULTS = 0x00cb,
LB_TAG_OPTION_CHECKSUM = 0x00cc,
};

/* Since coreboot is usually compiled 32bit, gcc will align 64bit
* types to 32bit boundaries. If the coreboot table is dumped on a
* 64bit system, a uint64_t would be aligned to 64bit boundaries,
Expand Down Expand Up @@ -97,9 +149,6 @@ struct lb_record {
uint32_t size; /* size of record (in bytes) */
};

#define LB_TAG_UNUSED 0x0000

#define LB_TAG_MEMORY 0x0001

struct lb_memory_range {
struct lb_uint64 start;
Expand All @@ -120,14 +169,12 @@ struct lb_memory {
struct lb_memory_range map[0];
};

#define LB_TAG_HWRPB 0x0002
struct lb_hwrpb {
uint32_t tag;
uint32_t size;
uint64_t hwrpb;
};

#define LB_TAG_MAINBOARD 0x0003
struct lb_mainboard {
uint32_t tag;
uint32_t size;
Expand All @@ -136,23 +183,12 @@ struct lb_mainboard {
uint8_t strings[0];
};

#define LB_TAG_VERSION 0x0004
#define LB_TAG_EXTRA_VERSION 0x0005
#define LB_TAG_BUILD 0x0006
#define LB_TAG_COMPILE_TIME 0x0007
#define LB_TAG_COMPILE_BY 0x0008
#define LB_TAG_COMPILE_HOST 0x0009
#define LB_TAG_COMPILE_DOMAIN 0x000a
#define LB_TAG_COMPILER 0x000b
#define LB_TAG_LINKER 0x000c
#define LB_TAG_ASSEMBLER 0x000d
struct lb_string {
uint32_t tag;
uint32_t size;
uint8_t string[0];
};

#define LB_TAG_VERSION_TIMESTAMP 0x0026
struct lb_timestamp {
uint32_t tag;
uint32_t size;
Expand All @@ -162,7 +198,6 @@ struct lb_timestamp {

/* 0xe is taken by v3 */

#define LB_TAG_SERIAL 0x000f
struct lb_serial {
uint32_t tag;
uint32_t size;
Expand All @@ -189,7 +224,6 @@ struct lb_serial {
uint32_t uart_pci_addr;
};

#define LB_TAG_CONSOLE 0x0010
struct lb_console {
uint32_t tag;
uint32_t size;
Expand All @@ -204,7 +238,6 @@ struct lb_console {
#define LB_TAG_CONSOLE_EHCI 5
#define LB_TAG_CONSOLE_SERIAL8250MEM 6

#define LB_TAG_FORWARD 0x0011
struct lb_forward {
uint32_t tag;
uint32_t size;
Expand Down Expand Up @@ -250,7 +283,6 @@ struct lb_forward {
* fields described above. It may, however, only implement a subset
* of the possible color formats.
*/
#define LB_TAG_FRAMEBUFFER 0x0012
struct lb_framebuffer {
uint32_t tag;
uint32_t size;
Expand All @@ -270,7 +302,6 @@ struct lb_framebuffer {
uint8_t reserved_mask_size;
};

#define LB_TAG_GPIO 0x0013

struct lb_gpio {
uint32_t port;
Expand All @@ -290,12 +321,6 @@ struct lb_gpios {
struct lb_gpio gpios[0];
};

#define LB_TAG_VBNV 0x0019
#define LB_TAB_VBOOT_HANDOFF 0x0020
#define LB_TAB_VBOOT_WORKBUF 0x0034
#define LB_TAB_DMA 0x0022
#define LB_TAG_RAM_OOPS 0x0023
#define LB_TAG_MTC 0x002b
struct lb_range {
uint32_t tag;
uint32_t size;
Expand All @@ -306,39 +331,27 @@ struct lb_range {

void lb_ramoops(struct lb_header *header);

#define LB_TAG_TIMESTAMPS 0x0016
#define LB_TAG_CBMEM_CONSOLE 0x0017
#define LB_TAG_MRC_CACHE 0x0018
#define LB_TAG_ACPI_GNVS 0x0024
#define LB_TAG_TCPA_LOG 0x0034
#define LB_TAG_WIFI_CALIBRATION 0x0027
#define LB_TAG_VPD 0x002c
struct lb_cbmem_ref {
uint32_t tag;
uint32_t size;

uint64_t cbmem_addr;
};

#define LB_TAG_X86_ROM_MTRR 0x0021
struct lb_x86_rom_mtrr {
uint32_t tag;
uint32_t size;
/* The variable range MTRR index covering the ROM. */
uint32_t index;
};

#define LB_TAG_BOARD_ID 0x0025
#define LB_TAG_RAM_CODE 0x0028
#define LB_TAG_SKU_ID 0x002d

struct lb_strapping_id {
uint32_t tag;
uint32_t size;
uint32_t id_code;
};

#define LB_TAG_SPI_FLASH 0x0029
struct lb_spi_flash {
uint32_t tag;
uint32_t size;
Expand All @@ -347,7 +360,6 @@ struct lb_spi_flash {
uint32_t erase_cmd;
};

#define LB_TAG_BOOT_MEDIA_PARAMS 0x0030
struct lb_boot_media_params {
uint32_t tag;
uint32_t size;
Expand All @@ -361,7 +373,6 @@ struct lb_boot_media_params {
/*
* There can be more than one of these records as there is one per cbmem entry.
*/
#define LB_TAG_CBMEM_ENTRY 0x0031
struct lb_cbmem_entry {
uint32_t tag;
uint32_t size;
Expand All @@ -371,21 +382,18 @@ struct lb_cbmem_entry {
uint32_t id;
};

#define LB_TAG_TSC_INFO 0x0032
struct lb_tsc_info {
uint32_t tag;
uint32_t size;

uint32_t freq_khz;
};

#define LB_TAG_MAC_ADDRS 0x0033
struct mac_address {
uint8_t mac_addr[6];
uint8_t pad[2]; /* Pad it to 8 bytes to keep it simple. */
};

#define LB_TAG_MMC_INFO 0x0035
struct lb_mmc_info {
uint32_t tag;
uint32_t size;
Expand All @@ -407,11 +415,9 @@ struct lb_macs {
struct mac_address mac_addrs[0];
};

#define LB_TAG_SERIALNO 0x002a
#define MAX_SERIALNO_LENGTH 32

/* The following structures are for the cmos definitions table */
#define LB_TAG_CMOS_OPTION_TABLE 200
/* cmos header record */
struct cmos_option_table {
uint32_t tag; /* CMOS definitions table type */
Expand All @@ -426,7 +432,6 @@ struct cmos_option_table {
* starts at the beginning of the byte and the length is
* fills complete bytes.
*/
#define LB_TAG_OPTION 201
struct cmos_entries {
uint32_t tag; /* entry type */
uint32_t size; /* length of this record */
Expand All @@ -444,7 +449,6 @@ struct cmos_entries {
* This record is variable length. The text field may be
* shorter than CMOS_MAX_TEXT_LENGTH.
*/
#define LB_TAG_OPTION_ENUM 202
struct cmos_enums {
uint32_t tag; /* enumeration type */
uint32_t size; /* length of this record */
Expand All @@ -458,7 +462,6 @@ struct cmos_enums {
/* cmos defaults record
* This record contains default settings for the cmos ram.
*/
#define LB_TAG_OPTION_DEFAULTS 203
struct cmos_defaults {
uint32_t tag; /* default type */
uint32_t size; /* length of this record */
Expand All @@ -468,7 +471,6 @@ struct cmos_defaults {
uint8_t default_set[CMOS_IMAGE_BUFFER_SIZE]; /* default settings */
};

#define LB_TAG_OPTION_CHECKSUM 204
struct cmos_checksum {
uint32_t tag;
uint32_t size;
Expand Down
2 changes: 1 addition & 1 deletion src/commonlib/storage/bouncebuf.h
Expand Up @@ -88,7 +88,7 @@ int bounce_buffer_stop(struct bounce_buffer *state);
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
char __##name[ROUND(size * sizeof(type), DMA_MINALIGN) + \
DMA_MINALIGN - 1]; \
type *name = (type *) ALIGN((uintptr_t)__##name, DMA_MINALIGN)
type *name = (type *) ALIGN_UP((uintptr_t)__##name, DMA_MINALIGN)
#ifndef ARCH_DMA_MINALIGN
#define ARCH_DMA_MINALIGN (DMA_MINALIGN)
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/commonlib/storage/storage.h
Expand Up @@ -23,7 +23,7 @@
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
char __##name[ROUND(size * sizeof(type), DMA_MINALIGN) + \
DMA_MINALIGN - 1]; \
type *name = (type *) ALIGN((uintptr_t)__##name, DMA_MINALIGN)
type *name = (type *) ALIGN_UP((uintptr_t)__##name, DMA_MINALIGN)

/* NOOPs mirroring ARM's cache API, since x86 devices usually cache snoop */
#define dcache_invalidate_by_mva(addr, len)
Expand Down
16 changes: 7 additions & 9 deletions src/console/die.c
Expand Up @@ -30,17 +30,15 @@ __weak void die_notify(void)
}

/* Report a fatal error */
void __noreturn die(const char *msg)
void __noreturn die(const char *fmt, ...)
{
printk(BIOS_EMERG, "%s", msg);
va_list args;

va_start(args, fmt);
vprintk(BIOS_EMERG, fmt, args);
va_end(args);

die_notify();
halt();
}

/* Report a fatal error with a post code */
void __noreturn die_with_post_code(uint8_t value, const char *msg)
{
post_code(value);
die(msg);
}
#endif
4 changes: 2 additions & 2 deletions src/console/printk.c
Expand Up @@ -45,7 +45,7 @@ static void wrap_putchar_cbmemc(unsigned char byte, void *data)
__cbmemc_tx_byte(byte);
}

int vprintk(int msg_level, const char *fmt, va_list args)
int do_vprintk(int msg_level, const char *fmt, va_list args)
{
int i, log_this;

Expand Down Expand Up @@ -91,7 +91,7 @@ int do_printk(int msg_level, const char *fmt, ...)
int i;

va_start(args, fmt);
i = vprintk(msg_level, fmt, args);
i = do_vprintk(msg_level, fmt, args);
va_end(args);

return i;
Expand Down
14 changes: 8 additions & 6 deletions src/console/vtxprintf.c
Expand Up @@ -16,7 +16,9 @@
*/

#include <console/vtxprintf.h>
#include <ctype.h>
#include <string.h>
#include <stdint.h>

#define call_tx(x) tx_byte(x, data)

Expand All @@ -37,7 +39,7 @@ static int number(void (*tx_byte)(unsigned char byte, void *data),
void *data)
{
char c, sign, tmp[66];
const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
const char *digits = "0123456789abcdef";
int i;
int count = 0;
#ifdef SUPPORT_64BIT_INTS
Expand All @@ -56,11 +58,9 @@ static int number(void (*tx_byte)(unsigned char byte, void *data),
#endif

if (type & LARGE)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
digits = "0123456789ABCDEF";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
Expand Down Expand Up @@ -137,7 +137,7 @@ int vtxprintf(void (*tx_byte)(unsigned char byte, void *data),
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'H', 'l', or 'L' for integer fields */
int qualifier; /* 'h', 'H', 'l', 'L', 'z', or 'j' for integer fields */

int count;

Expand Down Expand Up @@ -191,7 +191,7 @@ int vtxprintf(void (*tx_byte)(unsigned char byte, void *data),

/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'z') {
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'z' || *fmt == 'j') {
qualifier = *fmt;
++fmt;
if (*fmt == 'l') {
Expand Down Expand Up @@ -292,6 +292,8 @@ int vtxprintf(void (*tx_byte)(unsigned char byte, void *data),
num = va_arg(args, unsigned long);
} else if (qualifier == 'z') {
num = va_arg(args, size_t);
} else if (qualifier == 'j') {
num = va_arg(args, uintmax_t);
} else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
Expand Down
1 change: 0 additions & 1 deletion src/cpu/allwinner/a10/clock.c
Expand Up @@ -22,7 +22,6 @@
#include <console/console.h>
#include <delay.h>
#include <lib.h>
#include <stdlib.h>

static struct a10_ccm *const ccm = (void *)A1X_CCM_BASE;

Expand Down
7 changes: 4 additions & 3 deletions src/cpu/allwinner/a10/twi.c
Expand Up @@ -20,12 +20,13 @@
* Largely based on the uboot-sunxi code.
*/

#include "memmap.h"
#include "twi.h"

#include <device/mmio.h>
#include <delay.h>
#include <device/i2c_simple.h>
#include <types.h>

#include "memmap.h"
#include "twi.h"

#define TWI_BASE(n) (A1X_TWI0_BASE + 0x400 * (n))

Expand Down
4 changes: 3 additions & 1 deletion src/cpu/amd/car/post_cache_as_ram.c
Expand Up @@ -16,10 +16,12 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <string.h>
#include <console/console.h>
#include <arch/stages.h>
#include <arch/early_variables.h>
#include <commonlib/helpers.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/mtrr.h>
#include <cpu/amd/car.h>
Expand All @@ -45,7 +47,7 @@
static size_t backup_size(void)
{
size_t car_size = car_data_size();
return ALIGN(car_size + 1024, 1024);
return ALIGN_UP(car_size + 1024, 1024);
}

static void memcpy_(void *d, const void *s, size_t len)
Expand Down
29 changes: 12 additions & 17 deletions src/cpu/amd/family_10h-family_15h/init_cpus.c
Expand Up @@ -17,6 +17,8 @@
#include <console/console.h>
#include <cpu/amd/msr.h>
#include <device/pci_ops.h>
#include <types.h>

#include "init_cpus.h"

#if CONFIG(HAVE_OPTION_TABLE)
Expand Down Expand Up @@ -502,10 +504,9 @@ u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo)
if (is_fam15h()) {
/* core 1 on node 0 is special; to avoid corrupting the
* BSP do not alter MTRRs on that core */
fam15_bsp_core1_apicid = 1;
if (CONFIG(ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0))
fam15_bsp_core1_apicid = CONFIG_APIC_ID_OFFSET + 1;
else
fam15_bsp_core1_apicid = 1;
fam15_bsp_core1_apicid += CONFIG_APIC_ID_OFFSET;

if (apicid == fam15_bsp_core1_apicid)
set_mtrrs = 0;
Expand Down Expand Up @@ -984,7 +985,6 @@ void cpuSetAMDMSR(uint8_t node_id)
uint8_t nvram;
u32 platform;
uint64_t revision;
uint8_t enable_c_states;
uint8_t enable_cpb;

printk(BIOS_DEBUG, "cpuSetAMDMSR ");
Expand Down Expand Up @@ -1060,21 +1060,16 @@ void cpuSetAMDMSR(uint8_t node_id)
}

if (revision & (AMD_DR_Ex | AMD_FAM15_ALL)) {
enable_c_states = 0;
if (CONFIG(HAVE_ACPI_TABLES))
if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS)
enable_c_states = !!nvram;

if (enable_c_states) {
/* Set up the C-state base address */
msr_t c_state_addr_msr;
c_state_addr_msr = rdmsr(MSR_CSTATE_ADDRESS);
c_state_addr_msr.lo = ACPI_CPU_P_LVL2; /* CstateAddr = ACPI_CPU_P_LVL2 */
wrmsr(MSR_CSTATE_ADDRESS, c_state_addr_msr);
}
if ((get_option(&nvram, "cpu_c_states") == CB_SUCCESS) &&
(nvram)) {
/* Set up the C-state base address */
msr_t c_state_addr_msr;
c_state_addr_msr = rdmsr(MSR_CSTATE_ADDRESS);
c_state_addr_msr.lo = ACPI_CPU_P_LVL2;
wrmsr(MSR_CSTATE_ADDRESS, c_state_addr_msr);
}
}
#else
enable_c_states = 0;
#endif

if (revision & AMD_FAM15_ALL) {
Expand Down
1 change: 0 additions & 1 deletion src/cpu/amd/family_10h-family_15h/init_cpus.h
Expand Up @@ -16,7 +16,6 @@
#ifndef INIT_CPUS_H
#define INIT_CPUS_H

#include <stdlib.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/msr.h>
Expand Down
4 changes: 1 addition & 3 deletions src/cpu/amd/family_10h-family_15h/powernow_acpi.c
Expand Up @@ -16,7 +16,6 @@
*/

#include <console/console.h>
#include <stdint.h>
#include <option.h>
#include <cpu/x86/msr.h>
#include <cpu/amd/msr.h>
Expand All @@ -30,6 +29,7 @@
#include <northbridge/amd/amdht/AsPsDefs.h>
#include <northbridge/amd/amdmct/mct/mct.h>
#include <northbridge/amd/amdmct/amddefs.h>
#include <types.h>

static inline uint8_t is_fam15h(void)
{
Expand Down Expand Up @@ -259,8 +259,6 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
else if (mctGetLogicalCPUID(0) & AMD_FAM15_ALL)
boost_count = (dtemp >> 2) & 0x7;

Pstate_num = 0;

/* See if the CPUID(0x80000007) returned EDX[7]==1b */
cpuid1 = cpuid(0x80000007);
if ((cpuid1.edx & 0x80) != 0x80) {
Expand Down
1 change: 1 addition & 0 deletions src/cpu/amd/pi/00730F01/Kconfig
Expand Up @@ -17,6 +17,7 @@ config CPU_AMD_PI_00730F01
bool
select X86_AMD_FIXED_MTRRS
select SUPPORT_CPU_UCODE_IN_CBFS
select MICROCODE_BLOB_UNDISCLOSED

if CPU_AMD_PI_00730F01

Expand Down
4 changes: 4 additions & 0 deletions src/cpu/amd/pi/00730F01/Makefile.inc
Expand Up @@ -14,10 +14,14 @@
#

romstage-y += fixme.c
romstage-y += update_microcode.c
romstage-y += microcode_fam16h.c

ramstage-y += fixme.c
ramstage-y += chip_name.c
ramstage-y += model_16_init.c
ramstage-y += update_microcode.c
ramstage-y += microcode_fam16h.c

subdirs-y += ../../mtrr
subdirs-y += ../../../x86/tsc
Expand Down
169 changes: 169 additions & 0 deletions src/cpu/amd/pi/00730F01/microcode_fam16h.c
@@ -0,0 +1,169 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007 Advanced Micro Devices, Inc.
* Copyright (C) 2015 Raptor Engineering
* Copyright (C) 2019 PC Engines GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <stdint.h>
#include <console/console.h>
#include <cpu/x86/msr.h>
#include <cpu/amd/microcode.h>
#include <cbfs.h>
#include <arch/io.h>
#include <smp/spinlock.h>

/*
* Values and header structure from:
* BKDG for AMD Family 16h Models 30h-3Fh Processors
* 52740 Rev 3.06 - March 18, 2016
*/

#define F16H_MPB_MAX_SIZE 3458
#define F16H_MPB_DATA_OFFSET 32

/*
* STRUCTURE OF A MICROCODE (UCODE) FILE FOR FAM16h
* Microcode Patch Block
* Microcode Header
* Microcode "Blob"
* ...
* ...
* (end of file)
*
*
* MICROCODE HEADER (offset 0 bytes from start of file)
* Total size = 32 bytes
* [0:3] Date code (32 bits)
* [4:7] Patch level (32 bits)
* [8:9] Microcode patch data ID (16 bits)
* [10:15] Reserved (48 bits)
* [16:19] Chipset 1 device ID (32 bits)
* [20:23] Chipset 2 device ID (32 bits)
* [24:25] Processor Revisions ID (16 bits)
* [26] Chipset 1 revision ID (8 bits)
* [27] Chipset 2 revision ID (8 bits)
* [28:31] Reserved (32 bits)
*
* MICROCODE BLOB (offset += 32)
* Total size = m bytes
*
*/

struct microcode {
uint32_t date_code;
uint32_t patch_id;

uint16_t mc_patch_data_id;
uint8_t reserved1[6];

uint32_t chipset1_dev_id;
uint32_t chipset2_dev_id;

uint16_t processor_rev_id;

uint8_t chipset1_rev_id;
uint8_t chipset2_rev_id;

uint8_t reserved2[4];

uint8_t m_patch_data[F16H_MPB_MAX_SIZE-F16H_MPB_DATA_OFFSET];

};

static void apply_microcode_patch(const struct microcode *m)
{
uint32_t new_patch_id;
msr_t msr;

/* apply patch */
msr.hi = 0;
msr.lo = (uint32_t)m;

wrmsr(0xc0010020, msr);

printk(BIOS_DEBUG, "microcode: patch id to apply = 0x%08x\n",
m->patch_id);

/* patch authentication */
msr = rdmsr(0x8b);
new_patch_id = msr.lo;

printk(BIOS_DEBUG, "microcode: updated to patch id = 0x%08x %s\n",
new_patch_id,
(new_patch_id == m->patch_id) ? "success" : "fail");
}

static void amd_update_microcode(const void *ucode, size_t ucode_len,
uint32_t equivalent_processor_rev_id)
{
const struct microcode *m;
const uint8_t *c = ucode;

m = (struct microcode *)c;

if (m->processor_rev_id == equivalent_processor_rev_id)
apply_microcode_patch(m);
}

void amd_update_microcode_from_cbfs(uint32_t equivalent_processor_rev_id)
{
const void *ucode;
size_t ucode_len;

if (equivalent_processor_rev_id == 0) {
printk(BIOS_DEBUG, "microcode: rev id not found. "
"Skipping microcode patch!\n");
return;
}
#ifdef __PRE_RAM__
#if CONFIG(HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
spin_lock(romstage_microcode_cbfs_lock());
#endif
#endif
ucode = cbfs_boot_map_with_leak("cpu_microcode_blob.bin",
CBFS_TYPE_MICROCODE,
&ucode_len);
if (!ucode) {
printk(BIOS_DEBUG, "cpu_microcode_blob.bin not found. "
"Skipping updates.\n");
#ifdef __PRE_RAM__
#if CONFIG(HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
spin_unlock(romstage_microcode_cbfs_lock());
#endif
#endif
return;
}

if (ucode_len > F16H_MPB_MAX_SIZE ||
ucode_len < F16H_MPB_DATA_OFFSET) {
printk(BIOS_DEBUG, "microcode file invalid. Skipping "
"updates.\n");
#ifdef __PRE_RAM__
#if CONFIG(HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
spin_unlock(romstage_microcode_cbfs_lock());
#endif
#endif
return;
}

amd_update_microcode(ucode, ucode_len,
equivalent_processor_rev_id);

#ifdef __PRE_RAM__
#if CONFIG(HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
spin_unlock(romstage_microcode_cbfs_lock());
#endif
#endif

}
3 changes: 3 additions & 0 deletions src/cpu/amd/pi/00730F01/model_16_init.c
Expand Up @@ -14,6 +14,7 @@
*/

#include <console/console.h>
#include <cpu/amd/microcode.h>
#include <cpu/x86/msr.h>
#include <cpu/amd/msr.h>
#include <cpu/x86/mtrr.h>
Expand Down Expand Up @@ -98,6 +99,8 @@ static void model_16_init(struct device *dev)
msr = rdmsr(HWCR_MSR);
msr.lo |= (1 << 0);
wrmsr(HWCR_MSR, msr);

update_microcode(cpuid_eax(1));
}

static struct device_operations cpu_dev_ops = {
Expand Down
58 changes: 58 additions & 0 deletions src/cpu/amd/pi/00730F01/update_microcode.c
@@ -0,0 +1,58 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
* Copyright (C) 2007 Advanced Micro Devices, Inc.
* Copyright (C) 2019 PC Engines GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <stdint.h>
#include <cpu/amd/microcode.h>

struct id_mapping {
uint32_t orig_id;
uint16_t new_id;
};

static u16 get_equivalent_processor_rev_id(u32 orig_id)
{
static const struct id_mapping id_mapping_table[] = {
/* Family 16h */

/* TODO This equivalent processor revisions ID needs verification */
{ 0x730f01, 0x7301 },

/* Array terminator */
{ 0xffffff, 0x0000 },
};

u32 new_id;
int i;

new_id = 0;

for (i = 0; id_mapping_table[i].orig_id != 0xffffff; i++) {
if (id_mapping_table[i].orig_id == orig_id) {
new_id = id_mapping_table[i].new_id;
break;
}
}

return new_id;
}

void update_microcode(u32 cpu_deviceid)
{
u32 equivalent_processor_rev_id =
get_equivalent_processor_rev_id(cpu_deviceid);
amd_update_microcode_from_cbfs(equivalent_processor_rev_id);
}
1 change: 1 addition & 0 deletions src/cpu/intel/car/romstage.c
Expand Up @@ -16,6 +16,7 @@
#include <cpu/intel/romstage.h>
#include <cpu/x86/mtrr.h>
#include <arch/symbols.h>
#include <commonlib/helpers.h>
#include <program_loading.h>
#include <timestamp.h>

Expand Down
1 change: 1 addition & 0 deletions src/cpu/intel/common/fsb.c
Expand Up @@ -46,6 +46,7 @@ static int get_fsb(void)
case 0x3a: /* IvyBridge BCLK fixed at 100MHz */
case 0x3c: /* Haswell BCLK fixed at 100MHz */
case 0x45: /* Haswell-ULT BCLK fixed at 100MHz */
case 0x4d: /* Rangeley BCLK fixed at 100MHz */
ret = 100;
break;
}
Expand Down
8 changes: 6 additions & 2 deletions src/cpu/intel/haswell/Makefile.inc
Expand Up @@ -17,6 +17,9 @@ smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c

ifneq ($(CONFIG_TSC_MONOTONIC_TIMER),y)
bootblock-y += monotonic_timer.c
romstage-y += monotonic_timer.c
postcar-y += monotonic_timer.c
ramstage-y += monotonic_timer.c
smm-y += monotonic_timer.c
endif
Expand All @@ -25,6 +28,7 @@ bootblock-y += ../car/non-evict/cache_as_ram.S
bootblock-y += ../car/bootblock.c
bootblock-y += ../../x86/early_reset.S
bootblock-y += bootblock.c
bootblock-y += tsc_freq.c

postcar-y += ../car/non-evict/exit_car.S

Expand All @@ -39,5 +43,5 @@ subdirs-y += ../microcode
subdirs-y += ../turbo
subdirs-y += ../common

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_306cx/microcode.bin
cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_4065x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-3c-*)
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-45-*)
1 change: 0 additions & 1 deletion src/cpu/intel/haswell/finalize.c
Expand Up @@ -15,7 +15,6 @@
*/

#include <stdint.h>
#include <stdlib.h>
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include "haswell.h"
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/haswell/haswell.h
Expand Up @@ -34,7 +34,7 @@
/* Haswell bus clock is fixed at 100MHz */
#define HASWELL_BCLK 100

#define CORE_THREAD_COUNT_MSR 0x35
#define MSR_CORE_THREAD_COUNT 0x35
#define MSR_FEATURE_CONFIG 0x13c
#define MSR_FLEX_RATIO 0x194
#define FLEX_RATIO_LOCK (1 << 20)
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/haswell/haswell_init.c
Expand Up @@ -732,7 +732,7 @@ static int get_cpu_count(void)
int num_threads;
int num_cores;

msr = rdmsr(CORE_THREAD_COUNT_MSR);
msr = rdmsr(MSR_CORE_THREAD_COUNT);
num_threads = (msr.lo >> 0) & 0xffff;
num_cores = (msr.lo >> 16) & 0xffff;
printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
Expand Down
5 changes: 2 additions & 3 deletions src/cpu/intel/haswell/romstage.c
Expand Up @@ -24,6 +24,7 @@
#include <device/pci_def.h>
#include <cpu/x86/lapic.h>
#include <cbmem.h>
#include <commonlib/helpers.h>
#include <program_loading.h>
#include <romstage_handoff.h>
#include <vendorcode/google/chromeos/chromeos.h>
Expand All @@ -37,8 +38,6 @@
#include <cpu/intel/romstage.h>
#include "haswell.h"

#define ROMSTAGE_RAM_STACK_SIZE 0x5000

/* platform_enter_postcar() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use,
* and continues execution in postcar stage. */
Expand All @@ -47,7 +46,7 @@ void platform_enter_postcar(void)
struct postcar_frame pcf;
uintptr_t top_of_ram;

if (postcar_frame_init(&pcf, ROMSTAGE_RAM_STACK_SIZE))
if (postcar_frame_init(&pcf, 0))
die("Unable to initialize postcar frame.\n");
/* Cache the ROM as WP just below 4GiB. */
postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRPROT);
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/model_1067x/Makefile.inc
Expand Up @@ -4,4 +4,4 @@ subdirs-y += ../../x86/name
subdirs-y += ../common
subdirs-$(CONFIG_SMM_TSEG) += ../smm/gen1

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_1067x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-17-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_106cx/Makefile.inc
Expand Up @@ -4,4 +4,4 @@ subdirs-y += ../common
subdirs-$(CONFIG_SMM_TSEG) += ../smm/gen1
ramstage-$(CONFIG_PARALLEL_MP) += ../model_1067x/mp_init.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_106cx/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-1c-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_2065x/Makefile.inc
Expand Up @@ -23,7 +23,7 @@ romstage-y += stage_cache.c
ramstage-y += stage_cache.c
postcar-y += stage_cache.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_2065x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-25-*)

cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S
postcar-y += ../car/non-evict/exit_car.S
Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/model_2065x/finalize.c
Expand Up @@ -15,7 +15,6 @@
*/

#include <stdint.h>
#include <stdlib.h>
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/intel/speedstep.h>
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/model_2065x/model_2065x.h
Expand Up @@ -20,7 +20,7 @@
/* Nehalem bus clock is fixed at 133MHz */
#define NEHALEM_BCLK 133

#define CORE_THREAD_COUNT_MSR 0x35
#define MSR_CORE_THREAD_COUNT 0x35
#define MSR_FEATURE_CONFIG 0x13c
#define MSR_FLEX_RATIO 0x194
#define FLEX_RATIO_LOCK (1 << 20)
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/model_2065x/model_2065x_init.c
Expand Up @@ -287,7 +287,7 @@ static int get_cpu_count(void)
int num_threads;
int num_cores;

msr = rdmsr(CORE_THREAD_COUNT_MSR);
msr = rdmsr(MSR_CORE_THREAD_COUNT);
num_threads = (msr.lo >> 0) & 0xffff;
num_cores = (msr.lo >> 16) & 0xffff;
printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
Expand Down
4 changes: 2 additions & 2 deletions src/cpu/intel/model_206ax/Makefile.inc
Expand Up @@ -28,8 +28,8 @@ romstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
postcar-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
ramstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_206ax/microcode.bin
cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_306ax/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-2a-*)
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-3a-*)

cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S
postcar-y += ../car/non-evict/exit_car.S
Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/model_206ax/finalize.c
Expand Up @@ -15,7 +15,6 @@
*/

#include <stdint.h>
#include <stdlib.h>
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/intel/speedstep.h>
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/model_206ax/model_206ax.h
Expand Up @@ -22,7 +22,7 @@
/* SandyBridge/IvyBridge bus clock is fixed at 100MHz */
#define SANDYBRIDGE_BCLK 100

#define CORE_THREAD_COUNT_MSR 0x35
#define MSR_CORE_THREAD_COUNT 0x35
#define MSR_FEATURE_CONFIG 0x13c
#define MSR_FLEX_RATIO 0x194
#define FLEX_RATIO_LOCK (1 << 20)
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/model_206ax/model_206ax_init.c
Expand Up @@ -513,7 +513,7 @@ static int get_cpu_count(void)
int num_threads;
int num_cores;

msr = rdmsr(CORE_THREAD_COUNT_MSR);
msr = rdmsr(MSR_CORE_THREAD_COUNT);
num_threads = (msr.lo >> 0) & 0xffff;
num_cores = (msr.lo >> 16) & 0xffff;
printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/model_65x/Makefile.inc
Expand Up @@ -16,4 +16,4 @@

ramstage-y += model_65x_init.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_65x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-05-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_67x/Makefile.inc
Expand Up @@ -16,4 +16,4 @@

ramstage-y += model_67x_init.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_67x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-07-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_68x/Makefile.inc
Expand Up @@ -17,4 +17,4 @@
ramstage-y += model_68x_init.c
subdirs-y += ../../x86/name

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_68x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-08-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_6bx/Makefile.inc
@@ -1,4 +1,4 @@
ramstage-y += model_6bx_init.c
subdirs-y += ../../x86/name

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6bx/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-0b-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_6ex/Makefile.inc
Expand Up @@ -4,4 +4,4 @@ subdirs-y += ../common
subdirs-$(CONFIG_SMM_TSEG) += ../smm/gen1
ramstage-y += ../model_1067x/mp_init.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6ex/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-0e-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_6fx/Makefile.inc
Expand Up @@ -4,4 +4,4 @@ subdirs-y += ../common
ramstage-$(CONFIG_PARALLEL_MP) += ../model_1067x/mp_init.c
subdirs-$(CONFIG_SMM_TSEG) += ../smm/gen1

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6fx/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-0f-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_6xx/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_6xx_init.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_66x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/06-06-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_f2x/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_f2x_init.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_f2x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/0f-02-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_f3x/Makefile.inc
Expand Up @@ -2,4 +2,4 @@ ramstage-y += model_f3x_init.c
subdirs-$(CONFIG_SMM_TSEG) += ../smm/gen1
ramstage-$(CONFIG_PARALLEL_MP) += ../model_1067x/mp_init.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_f3x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/0f-03-*)
2 changes: 1 addition & 1 deletion src/cpu/intel/model_f4x/Makefile.inc
Expand Up @@ -2,4 +2,4 @@ ramstage-y += model_f4x_init.c
subdirs-$(CONFIG_SMM_TSEG) += ../smm/gen1
ramstage-$(CONFIG_PARALLEL_MP) += ../model_1067x/mp_init.c

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_f4x/microcode.bin
cpu_microcode_bins += $(wildcard 3rdparty/intel-microcode/intel-ucode/0f-04-*)
1 change: 1 addition & 0 deletions src/cpu/intel/smm/gen1/smmrelocate.c
Expand Up @@ -21,6 +21,7 @@
#include <string.h>
#include <device/device.h>
#include <device/pci.h>
#include <commonlib/helpers.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/mp.h>
#include <cpu/x86/msr.h>
Expand Down
1 change: 0 additions & 1 deletion src/cpu/ti/am335x/gpio.c
Expand Up @@ -16,7 +16,6 @@
#include <console/console.h>
#include <cpu/ti/am335x/gpio.h>
#include <stdint.h>
#include <stdlib.h>

static struct am335x_gpio_regs *gpio_regs_and_bit(unsigned int gpio,
uint32_t *bit)
Expand Down
1 change: 0 additions & 1 deletion src/cpu/ti/am335x/uart.c
Expand Up @@ -12,7 +12,6 @@
* GNU General Public License for more details.
*/

#include <stdlib.h>
#include <types.h>
#include <console/uart.h>
#include <device/mmio.h>
Expand Down