132 changes: 110 additions & 22 deletions src/device/oprom/realmode/x86.c
Expand Up @@ -18,14 +18,12 @@
#include <arch/interrupt.h>
#include <arch/registers.h>
#include <boot/coreboot_tables.h>
#include <cbfs.h>
#include <console/console.h>
#include <cpu/amd/lxdef.h>
#include <cpu/amd/vr.h>
#include <delay.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <lib/jpeg.h>
#include <pc80/i8259.h>
#include <pc80/i8254.h>
#include <string.h>
Expand All @@ -36,6 +34,16 @@

#include "x86.h"

typedef struct {
char signature[4];
u16 version;
u8 *oem_string_ptr;
u32 capabilities;
u32 video_mode_ptr;
u16 total_memory;
char reserved[236];
} __packed vbe_info_block;

/* The following symbols cannot be used directly. They need to be fixed up
* to point to the correct address location after the code has been copied
* to REALMODE_BASE. Absolute symbols are not used because those symbols are
Expand All @@ -50,11 +58,11 @@ extern unsigned char __realmode_buffer;
/* to have a common register file for interrupt handlers */
X86EMU_sysEnv _X86EMU_env;

void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx,
unsigned int (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx,
u32 esi, u32 edi) asmlinkage;

void (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx, u32 edx,
u32 esi, u32 edi) asmlinkage;
unsigned int (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx,
u32 edx, u32 esi, u32 edi) asmlinkage;

static void setup_realmode_code(void)
{
Expand Down Expand Up @@ -213,23 +221,111 @@ static void setup_realmode_idt(void)
}

#if CONFIG(FRAMEBUFFER_SET_VESA_MODE)
vbe_mode_info_t mode_info;
static vbe_mode_info_t mode_info;
static int mode_info_valid;

static int vbe_mode_info_valid(void)
{
return mode_info_valid;
}

const vbe_mode_info_t *vbe_mode_info(void)
{
if (!mode_info_valid || !mode_info.vesa.phys_base_ptr)
return NULL;
return &mode_info;
}

static int vbe_check_for_failure(int ah);

static void vbe_get_ctrl_info(vbe_info_block *info)
{
char *buffer = PTR_TO_REAL_MODE(__realmode_buffer);
u16 buffer_seg = (((unsigned long)buffer) >> 4) & 0xff00;
u16 buffer_adr = ((unsigned long)buffer) & 0xffff;
X86_EAX = realmode_interrupt(0x10, VESA_GET_INFO, 0x0000, 0x0000,
0x0000, buffer_seg, buffer_adr);
/* If the VBE function completed successfully, 0x0 is returned in AH */
if (X86_AH)
die("\nError: In %s function\n", __func__);
memcpy(info, buffer, sizeof(vbe_info_block));
}

static void vbe_oprom_list_supported_mode(uint16_t *video_mode_ptr)
{
uint16_t mode;
printk(BIOS_DEBUG, "Supported Video Mode list for OpRom:\n");
do {
mode = *video_mode_ptr++;
if (mode != 0xffff)
printk(BIOS_DEBUG, "%x\n", mode);
} while (mode != 0xffff);
}

static void vbe_oprom_supported_mode_list(void)
{
uint16_t segment, offset;
vbe_info_block info;

vbe_get_ctrl_info(&info);

offset = info.video_mode_ptr;
segment = info.video_mode_ptr >> 16;

vbe_oprom_list_supported_mode((uint16_t *)((segment << 4) + offset));
}
/*
* EAX register is used to indicate the completion status upon return from
* VBE function in real mode.
*
* If the VBE function completed successfully then 0x0 is returned in the AH
* register. Otherwise the AH register is set with the nature of the failure:
*
* AH == 0x00: Function call successful
* AH == 0x01: Function call failed
* AH == 0x02: Function is not supported in the current HW configuration
* AH == 0x03: Function call invalid in current video mode
*
* Return 0 on success else -1 for failure
*/
static int vbe_check_for_failure(int ah)
{
int status;

switch (ah) {
case 0x0:
status = 0;
break;
case 1:
printk(BIOS_DEBUG, "VBE: Function call failed!\n");
status = -1;
break;
case 2:
printk(BIOS_DEBUG, "VBE: Function is not supported!\n");
status = -1;
break;
case 3:
default:
printk(BIOS_DEBUG, "VBE: Unsupported video mode %x!\n",
CONFIG_FRAMEBUFFER_VESA_MODE);
vbe_oprom_supported_mode_list();
status = -1;
break;
}

return status;
}
static u8 vbe_get_mode_info(vbe_mode_info_t * mi)
{
printk(BIOS_DEBUG, "VBE: Getting information about VESA mode %04x\n",
mi->video_mode);
char *buffer = PTR_TO_REAL_MODE(__realmode_buffer);
u16 buffer_seg = (((unsigned long)buffer) >> 4) & 0xff00;
u16 buffer_adr = ((unsigned long)buffer) & 0xffff;
realmode_interrupt(0x10, VESA_GET_MODE_INFO, 0x0000,
X86_EAX = realmode_interrupt(0x10, VESA_GET_MODE_INFO, 0x0000,
mi->video_mode, 0x0000, buffer_seg, buffer_adr);
if (vbe_check_for_failure(X86_AH))
die("\nError: In %s function\n", __func__);
memcpy(mi->mode_info_block, buffer, sizeof(mi->mode_info_block));
mode_info_valid = 1;
return 0;
Expand All @@ -242,8 +338,10 @@ static u8 vbe_set_mode(vbe_mode_info_t * mi)
mi->video_mode |= (1 << 14);
// request clearing of framebuffer
mi->video_mode &= ~(1 << 15);
realmode_interrupt(0x10, VESA_SET_MODE, mi->video_mode,
X86_EAX = realmode_interrupt(0x10, VESA_SET_MODE, mi->video_mode,
0x0000, 0x0000, 0x0000, 0x0000);
if (vbe_check_for_failure(X86_AH))
die("\nError: In %s function\n", __func__);
return 0;
}

Expand All @@ -260,6 +358,7 @@ void vbe_set_graphics(void)
le16_to_cpu(mode_info.vesa.x_resolution),
le16_to_cpu(mode_info.vesa.y_resolution),
mode_info.vesa.bits_per_pixel);

printk(BIOS_DEBUG, "VBE: framebuffer: %p\n", framebuffer);
if (!framebuffer) {
printk(BIOS_DEBUG, "VBE: Mode does not support linear "
Expand All @@ -268,26 +367,15 @@ void vbe_set_graphics(void)
}

vbe_set_mode(&mode_info);
#if CONFIG(BOOTSPLASH)
struct jpeg_decdata *decdata;
unsigned char *jpeg = cbfs_boot_map_with_leak("bootsplash.jpg",
CBFS_TYPE_BOOTSPLASH,
NULL);
if (!jpeg) {
printk(BIOS_DEBUG, "VBE: No bootsplash found.\n");
return;
}
decdata = malloc(sizeof(*decdata));
int ret = 0;
ret = jpeg_decode(jpeg, framebuffer, 1024, 768, 16, decdata);
#endif
}

void vbe_textmode_console(void)
{
delay(2);
realmode_interrupt(0x10, 0x0003, 0x0000, 0x0000,
X86_EAX = realmode_interrupt(0x10, 0x0003, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000);
if (vbe_check_for_failure(X86_AH))
die("\nError: In %s function\n", __func__);
}

int fill_lb_framebuffer(struct lb_framebuffer *framebuffer)
Expand Down
8 changes: 4 additions & 4 deletions src/device/oprom/realmode/x86.h
Expand Up @@ -33,11 +33,11 @@ extern unsigned int __idt_handler_size;
extern unsigned char __realmode_code;
extern unsigned int __realmode_code_size;

extern void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx,
u32 esi, u32 edi) asmlinkage;
extern unsigned int (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx,
u32 edx, u32 esi, u32 edi) asmlinkage;

extern void (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx, u32 edx,
u32 esi, u32 edi) asmlinkage;
extern unsigned int (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx,
u32 edx, u32 esi, u32 edi) asmlinkage;

#define FAKE_MEMORY_SIZE (1024*1024) // only 1MB
#define INITIAL_EBDA_SEGMENT 0xF600
Expand Down
23 changes: 22 additions & 1 deletion src/device/oprom/realmode/x86_asm.S
Expand Up @@ -43,6 +43,10 @@ __idt_handler_size:
.globl __realmode_code
__realmode_code:

/* Realmode function return. */
__realmode_ret = RELOCATED(.)
.long 0

/* Realmode IDT pointer structure. */
__realmode_idt = RELOCATED(.)
.word 1023 /* 16 bit limit */
Expand Down Expand Up @@ -167,6 +171,13 @@ __lcall_instr = RELOCATED(.)
.word 0x0000, 0x0000
/* ************************************ */

/*
* Here is end of real mode call and time to go back to protected mode.
* Before that its better to store current eax into some memory address
* so that context persist in protected mode too.
*/
mov %eax, __realmode_ret

/* If we got here, we are just about done.
* Need to get back to protected mode.
*/
Expand Down Expand Up @@ -196,7 +207,8 @@ __lcall_instr = RELOCATED(.)
popa

/* and exit */
// TODO return AX from OPROM call
/* return AX from OPROM call */
mov __realmode_ret, %eax
ret

.globl __realmode_interrupt
Expand Down Expand Up @@ -291,6 +303,13 @@ __realmode_interrupt:
__intXX_instr = RELOCATED(.)
.byte 0xcd, 0x00 /* This becomes intXX */

/*
* Here is end of real mode call and time to go back to protected mode.
* Before that its better to store current eax into some memory address
* so that context persist in protected mode too.
*/
mov %eax, __realmode_ret

/* Ok, the job is done, now go back to protected mode coreboot */
movl %cr0, %eax
orl $PE, %eax
Expand All @@ -314,6 +333,8 @@ __intXX_instr = RELOCATED(.)
movl __stack, %esp
popf
popa
/* return AX from OPROM call */
mov __realmode_ret, %eax
ret

/* This is the 16-bit interrupt entry point called by the IDT stub code.
Expand Down
2 changes: 1 addition & 1 deletion src/device/oprom/realmode/x86_interrupts.c
Expand Up @@ -174,7 +174,7 @@ int int1a_handler(void)
devfn = X86_EBX & 0xff;
bus = X86_EBX >> 8;
reg = X86_EDI;
dev = dev_find_slot(bus, devfn);
dev = pcidev_path_on_bus(bus, devfn);
if (!dev) {
printk(BIOS_DEBUG, "0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
// Or are we supposed to return PCIBIOS_NODEV?
Expand Down
2 changes: 2 additions & 0 deletions src/device/oprom/yabel/device.h
Expand Up @@ -85,7 +85,9 @@ typedef struct {
u8 devfn;
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
struct device* dev;
u64 puid; /* unused */
#else
void *dev;
u64 puid;
phandle_t phandle;
ihandle_t ihandle;
Expand Down
206 changes: 103 additions & 103 deletions src/device/oprom/yabel/interrupt.c
Expand Up @@ -343,7 +343,8 @@ handleInt1a(void)
{
// function number in AX
u8 bus, devfn, offs;
struct device* dev;
struct device *dev = NULL;

switch (M.x86.R_AX) {
case 0xb101:
// Installation check
Expand All @@ -361,30 +362,28 @@ handleInt1a(void)
//
DEBUG_PRINTF_INTR("%s(): function: %x: PCI Find Device\n",
__func__, M.x86.R_AX);

/* FixME: support SI != 0 */
#if CONFIG(YABEL_PCI_ACCESS_OTHER_DEVICES)
dev = dev_find_device(M.x86.R_DX, M.x86.R_CX, 0);
if (dev != 0) {
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Find Device --> 0x%04x\n",
__func__, M.x86.R_AX, M.x86.R_BX);

M.x86.R_BH = dev->bus->secondary;
M.x86.R_BL = dev->path.pci.devfn;
M.x86.R_AH = 0x00; // return code: success
CLEAR_FLAG(F_CF);
#else
// only allow the device to find itself...
if ((M.x86.R_CX == bios_device.pci_device_id)
&& (M.x86.R_DX == bios_device.pci_vendor_id)
// device index must be 0
&& (M.x86.R_SI == 0)) {
CLEAR_FLAG(F_CF);
M.x86.R_AH = 0x00; // return code: success
dev = bios_device.dev;
M.x86.R_BH = bios_device.bus;
M.x86.R_BL = bios_device.devfn;
#endif
} else {
} else if (CONFIG(YABEL_PCI_ACCESS_OTHER_DEVICES)) {
dev = dev_find_device(M.x86.R_DX, M.x86.R_CX, 0);
if (dev != NULL) {
M.x86.R_BH = dev->bus->secondary;
M.x86.R_BL = dev->path.pci.devfn;
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Find Device --> 0x%04x\n",
__func__, M.x86.R_AX, M.x86.R_BX);
}
}
if (dev == NULL) {
DEBUG_PRINTF_INTR
("%s(): function %x: invalid device/vendor/device index! (%04x/%04x/%02x expected: %04x/%04x/00)\n",
__func__, M.x86.R_AX, M.x86.R_CX, M.x86.R_DX,
Expand All @@ -393,7 +392,10 @@ handleInt1a(void)

SET_FLAG(F_CF);
M.x86.R_AH = 0x86; // return code: device not found
return;
}
CLEAR_FLAG(F_CF);
M.x86.R_AH = 0x00; // return code: success
break;
case 0xb108: //read configuration byte
case 0xb109: //read configuration word
Expand All @@ -403,18 +405,16 @@ handleInt1a(void)
offs = M.x86.R_DI;
DEBUG_PRINTF_INTR("%s(): function: %x: PCI Config Read from device: bus: %02x, devfn: %02x, offset: %02x\n",
__func__, M.x86.R_AX, bus, devfn, offs);
#if CONFIG(YABEL_PCI_ACCESS_OTHER_DEVICES)
dev = dev_find_slot(bus, devfn);
DEBUG_PRINTF_INTR("%s(): function: %x: dev_find_slot() returned: %s\n",

if ((bus == bios_device.bus) && (devfn == bios_device.devfn)) {
dev = bios_device.dev;
} else if (CONFIG(YABEL_PCI_ACCESS_OTHER_DEVICES)) {
dev = pcidev_path_on_bus(bus, devfn);
DEBUG_PRINTF_INTR("%s(): function: %x: pcidev_path_on_bus() returned: %s\n",
__func__, M.x86.R_AX, dev_path(dev));
if (dev == 0) {
// fail accesses to non-existent devices...
#else
dev = bios_device.dev;
if ((bus != bios_device.bus)
|| (devfn != bios_device.devfn)) {
// fail accesses to any device but ours...
#endif
}

if (dev == NULL) {
printf
("%s(): Config read access invalid device! bus: %02x (%02x), devfn: %02x (%02x), offs: %02x\n",
__func__, bus, bios_device.bus, devfn,
Expand All @@ -423,67 +423,67 @@ handleInt1a(void)
M.x86.R_AH = 0x87; //return code: bad pci register
HALT_SYS();
return;
} else {
switch (M.x86.R_AX) {
case 0xb108:
M.x86.R_CL =
}

switch (M.x86.R_AX) {
case 0xb108:
M.x86.R_CL =
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
pci_read_config8(dev, offs);
pci_read_config8(dev, offs);
#else
(u8) rtas_pci_config_read(bios_device.
puid, 1,
bus, devfn,
offs);
(u8) rtas_pci_config_read(bios_device.puid, 1,
bus, devfn,
offs);
#endif
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Read @%02x --> 0x%02x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_CL);
break;
case 0xb109:
M.x86.R_CX =
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Read @%02x --> 0x%02x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_CL);
break;
case 0xb109:
M.x86.R_CX =
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
pci_read_config16(dev, offs);
pci_read_config16(dev, offs);
#else
(u16) rtas_pci_config_read(bios_device.
puid, 2,
bus, devfn,
offs);
(u16) rtas_pci_config_read(bios_device.puid, 2,
bus, devfn,
offs);
#endif
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Read @%02x --> 0x%04x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_CX);
break;
case 0xb10a:
M.x86.R_ECX =
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Read @%02x --> 0x%04x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_CX);
break;
case 0xb10a:
M.x86.R_ECX =
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
pci_read_config32(dev, offs);
pci_read_config32(dev, offs);
#else
(u32) rtas_pci_config_read(bios_device.
puid, 4,
bus, devfn,
offs);
(u32) rtas_pci_config_read(bios_device.puid, 4,
bus, devfn,
offs);
#endif
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Read @%02x --> 0x%08x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_ECX);
break;
}
CLEAR_FLAG(F_CF);
M.x86.R_AH = 0x0; // return code: success
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Read @%02x --> 0x%08x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_ECX);
break;
}
CLEAR_FLAG(F_CF);
M.x86.R_AH = 0x0; // return code: success
break;
case 0xb10b: //write configuration byte
case 0xb10c: //write configuration word
case 0xb10d: //write configuration dword
bus = M.x86.R_BH;
devfn = M.x86.R_BL;
offs = M.x86.R_DI;
if ((bus != bios_device.bus)
|| (devfn != bios_device.devfn)) {
// fail accesses to any device but ours...

if ((bus == bios_device.bus) && (devfn == bios_device.devfn)) {
dev = bios_device.dev;
}

if (dev == NULL) {
printf
("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n",
__func__, bus, bios_device.bus, devfn,
Expand All @@ -492,48 +492,48 @@ handleInt1a(void)
M.x86.R_AH = 0x87; //return code: bad pci register
HALT_SYS();
return;
} else {
switch (M.x86.R_AX) {
case 0xb10b:
}

switch (M.x86.R_AX) {
case 0xb10b:
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
pci_write_config8(bios_device.dev, offs, M.x86.R_CL);
pci_write_config8(dev, offs, M.x86.R_CL);
#else
rtas_pci_config_write(bios_device.puid, 1, bus,
devfn, offs, M.x86.R_CL);
rtas_pci_config_write(bios_device.puid, 1, bus,
devfn, offs, M.x86.R_CL);
#endif
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Write @%02x <-- 0x%02x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_CL);
break;
case 0xb10c:
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Write @%02x <-- 0x%02x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_CL);
break;
case 0xb10c:
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
pci_write_config16(bios_device.dev, offs, M.x86.R_CX);
pci_write_config16(dev, offs, M.x86.R_CX);
#else
rtas_pci_config_write(bios_device.puid, 2, bus,
devfn, offs, M.x86.R_CX);
rtas_pci_config_write(bios_device.puid, 2, bus,
devfn, offs, M.x86.R_CX);
#endif
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Write @%02x <-- 0x%04x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_CX);
break;
case 0xb10d:
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Write @%02x <-- 0x%04x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_CX);
break;
case 0xb10d:
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
pci_write_config32(bios_device.dev, offs, M.x86.R_ECX);
pci_write_config32(dev, offs, M.x86.R_ECX);
#else
rtas_pci_config_write(bios_device.puid, 4, bus,
devfn, offs, M.x86.R_ECX);
rtas_pci_config_write(bios_device.puid, 4, bus,
devfn, offs, M.x86.R_ECX);
#endif
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Write @%02x <-- 0x%08x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_ECX);
break;
}
CLEAR_FLAG(F_CF);
M.x86.R_AH = 0x0; // return code: success
DEBUG_PRINTF_INTR
("%s(): function %x: PCI Config Write @%02x <-- 0x%08x\n",
__func__, M.x86.R_AX, offs,
M.x86.R_ECX);
break;
}
CLEAR_FLAG(F_CF);
M.x86.R_AH = 0x0; // return code: success
break;
default:
printf("%s(): unknown function (%x) for int1a handler.\n",
Expand Down
211 changes: 108 additions & 103 deletions src/device/oprom/yabel/io.c
Expand Up @@ -184,8 +184,7 @@ my_inb(X86EMU_pioAddr addr)
X86EMU_trace_on();
}
M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
//HALT_SYS();
// no break, intentional fall-through to default!!
// fall-through
default:
DEBUG_PRINTF_IO
("%s(%04x) reading from bios_device.io_buffer\n",
Expand Down Expand Up @@ -410,118 +409,124 @@ my_outl(X86EMU_pioAddr addr, u32 val)
u32
pci_cfg_read(X86EMU_pioAddr addr, u8 size)
{
u32 port_cf8_val = 0;
u32 rval = 0xFFFFFFFF;
struct device * dev;
if ((addr >= 0xCFC) && ((addr + size) <= 0xD00)) {
// PCI Configuration Mechanism 1 step 1
// write to 0xCF8, sets bus, device, function and Config Space offset
// later read from 0xCFC-0xCFF returns the value...
u8 bus, devfn, offs;
u32 port_cf8_val = my_inl(0xCF8);
if ((port_cf8_val & 0x80000000) != 0) {
//highest bit enables config space mapping
bus = (port_cf8_val & 0x00FF0000) >> 16;
devfn = (port_cf8_val & 0x0000FF00) >> 8;
offs = (port_cf8_val & 0x000000FF);
offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly
DEBUG_PRINTF_INTR("%s(): PCI Config Read from device: bus: %02x, devfn: %02x, offset: %02x\n",
__func__, bus, devfn, offs);
#if CONFIG(YABEL_PCI_ACCESS_OTHER_DEVICES)
dev = dev_find_slot(bus, devfn);
DEBUG_PRINTF_INTR("%s(): dev_find_slot() returned: %s\n",
__func__, dev_path(dev));
if (dev == 0) {
// fail accesses to non-existent devices...
#else
dev = bios_device.dev;
if ((bus != bios_device.bus)
|| (devfn != bios_device.devfn)) {
// fail accesses to any device but ours...
#endif
printf
("%s(): Config read access invalid device! bus: %02x (%02x), devfn: %02x (%02x), offs: %02x\n",
__func__, bus, bios_device.bus, devfn,
bios_device.devfn, offs);
SET_FLAG(F_CF);
HALT_SYS();
return 0;
} else {
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
switch (size) {
case 1:
rval = pci_read_config8(dev, offs);
break;
case 2:
rval = pci_read_config16(dev, offs);
break;
case 4:
rval = pci_read_config32(dev, offs);
break;
}
#else
rval =
(u32) rtas_pci_config_read(bios_device.
puid, size,
bus, devfn,
offs);
#endif
DEBUG_PRINTF_IO
("%s(%04x) PCI Config Read @%02x, size: %d --> 0x%08x\n",
__func__, addr, offs, size, rval);
}
struct device *dev = NULL;
u8 bus, devfn, offs;

// PCI Configuration Mechanism 1 step 1
// write to 0xCF8, sets bus, device, function and Config Space offset
// later read from 0xCFC-0xCFF returns the value...
if ((addr >= 0xCFC) && ((addr + size) <= 0xD00))
port_cf8_val = my_inl(0xCF8);

if ((port_cf8_val & 0x80000000) == 0)
return rval;

//highest bit enables config space mapping
bus = (port_cf8_val & 0x00FF0000) >> 16;
devfn = (port_cf8_val & 0x0000FF00) >> 8;
offs = (port_cf8_val & 0x000000FF);
offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly
DEBUG_PRINTF_INTR("%s(): PCI Config Read from device: bus: %02x, devfn: %02x, offset: %02x\n",
__func__, bus, devfn, offs);

if ((bus == bios_device.bus) && (devfn == bios_device.devfn)) {
dev = bios_device.dev;
} else if (CONFIG(YABEL_PCI_ACCESS_OTHER_DEVICES)) {
dev = pcidev_path_on_bus(bus, devfn);
DEBUG_PRINTF_INTR("%s(): pcidev_path_on_bus() returned: %s\n",
__func__, dev_path(dev));
}

if (dev == NULL) {
printf
("%s(): Config read access invalid device! bus: %02x (%02x), devfn: %02x (%02x), offs: %02x\n",
__func__, bus, bios_device.bus, devfn,
bios_device.devfn, offs);
SET_FLAG(F_CF);
HALT_SYS();
return 0;
}

if (CONFIG(PCI_OPTION_ROM_RUN_YABEL)) {
switch (size) {
case 1:
rval = pci_read_config8(dev, offs);
break;
case 2:
rval = pci_read_config16(dev, offs);
break;
case 4:
rval = pci_read_config32(dev, offs);
break;
}
} else {
rval = (u32) rtas_pci_config_read(bios_device.puid, size, bus, devfn, offs);
}

DEBUG_PRINTF_IO
("%s(%04x) PCI Config Read @%02x, size: %d --> 0x%08x\n",
__func__, addr, offs, size, rval);

return rval;
}

void
pci_cfg_write(X86EMU_pioAddr addr, u32 val, u8 size)
{
if ((addr >= 0xCFC) && ((addr + size) <= 0xD00)) {
// PCI Configuration Mechanism 1 step 1
// write to 0xCF8, sets bus, device, function and Config Space offset
// later write to 0xCFC-0xCFF sets the value...
u8 bus, devfn, offs;
u32 port_cf8_val = my_inl(0xCF8);
if ((port_cf8_val & 0x80000000) != 0) {
//highest bit enables config space mapping
bus = (port_cf8_val & 0x00FF0000) >> 16;
devfn = (port_cf8_val & 0x0000FF00) >> 8;
offs = (port_cf8_val & 0x000000FF);
offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly
if ((bus != bios_device.bus)
|| (devfn != bios_device.devfn)) {
// fail accesses to any device but ours...
printf
("Config write access invalid! PCI device %x:%x.%x, offs: %x\n",
bus, devfn >> 3, devfn & 7, offs);
#if !CONFIG(YABEL_PCI_FAKE_WRITING_OTHER_DEVICES_CONFIG)
HALT_SYS();
#endif
} else {
#if CONFIG(PCI_OPTION_ROM_RUN_YABEL)
switch (size) {
case 1:
pci_write_config8(bios_device.dev, offs, val);
break;
case 2:
pci_write_config16(bios_device.dev, offs, val);
break;
case 4:
pci_write_config32(bios_device.dev, offs, val);
break;
}
#else
rtas_pci_config_write(bios_device.puid,
size, bus, devfn, offs,
val);
#endif
DEBUG_PRINTF_IO
("%s(%04x) PCI Config Write @%02x, size: %d <-- 0x%08x\n",
__func__, addr, offs, size, val);
}
struct device *dev = NULL;
u32 port_cf8_val = 0;
u8 bus, devfn, offs;

// PCI Configuration Mechanism 1 step 1
// write to 0xCF8, sets bus, device, function and Config Space offset
// later write to 0xCFC-0xCFF sets the value...

if ((addr >= 0xCFC) && ((addr + size) <= 0xD00))
port_cf8_val = my_inl(0xCF8);

if ((port_cf8_val & 0x80000000) == 0)
return;

//highest bit enables config space mapping
bus = (port_cf8_val & 0x00FF0000) >> 16;
devfn = (port_cf8_val & 0x0000FF00) >> 8;
offs = (port_cf8_val & 0x000000FF);
offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly

if ((bus == bios_device.bus) && (devfn == bios_device.devfn)) {
dev = bios_device.dev;
} else {
printf
("Config write access invalid! PCI device %x:%x.%x, offs: %x\n",
bus, devfn >> 3, devfn & 7, offs);

if (CONFIG(YABEL_PCI_FAKE_WRITING_OTHER_DEVICES_CONFIG))
return;
// fail accesses to any device but ours...
HALT_SYS();
}

if (CONFIG(PCI_OPTION_ROM_RUN_YABEL)) {
switch (size) {
case 1:
pci_write_config8(dev, offs, val);
break;
case 2:
pci_write_config16(dev, offs, val);
break;
case 4:
pci_write_config32(dev, offs, val);
break;
}
} else {
rtas_pci_config_write(bios_device.puid, size, bus, devfn, offs, val);
}

DEBUG_PRINTF_IO
("%s(%04x) PCI Config Write @%02x, size: %d <-- 0x%08x\n",
__func__, addr, offs, size, val);
}

u8
Expand Down
55 changes: 20 additions & 35 deletions src/device/oprom/yabel/vbe.c
Expand Up @@ -34,9 +34,6 @@

#include <string.h>
#include <types.h>
#if CONFIG(FRAMEBUFFER_SET_VESA_MODE)
#include <boot/coreboot_tables.h>
#endif

#include <endian.h>

Expand All @@ -52,13 +49,22 @@
#include "interrupt.h"
#include "device.h"

#include <cbfs.h>

#include <delay.h>
#include "../../src/lib/jpeg.h"

#include <vbe.h>

// these structs only store a subset of the VBE defined fields
// only those needed.
typedef struct {
char signature[4];
u16 version;
u8 *oem_string_ptr;
u32 capabilities;
u16 video_mode_list[256]; // lets hope we never have more than
// 256 video modes...
u16 total_memory;
} vbe_info_t;

// pointer to VBEInfoBuffer, set by vbe_prepare
u8 *vbe_info_buffer = 0;

Expand Down Expand Up @@ -705,7 +711,14 @@ vbe_get_info(void)
}
#endif

vbe_mode_info_t mode_info;
static vbe_mode_info_t mode_info;

const vbe_mode_info_t *vbe_mode_info(void)
{
if (!mode_info_valid || !mode_info.vesa.phys_base_ptr)
return NULL;
return &mode_info;
}

void vbe_set_graphics(void)
{
Expand Down Expand Up @@ -733,34 +746,6 @@ void vbe_set_graphics(void)
mode_info.video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE;
vbe_get_mode_info(&mode_info);
vbe_set_mode(&mode_info);

#if CONFIG(BOOTSPLASH)
unsigned char *framebuffer =
(unsigned char *) le32_to_cpu(mode_info.vesa.phys_base_ptr);
DEBUG_PRINTF_VBE("FRAMEBUFFER: 0x%p\n", framebuffer);

struct jpeg_decdata *decdata;

/* Switching Intel IGD to 1MB video memory will break this. Who
* cares. */
// int imagesize = 1024*768*2;

unsigned char *jpeg = cbfs_boot_map_with_leak("bootsplash.jpg",
CBFS_TYPE_BOOTSPLASH,
NULL);
if (!jpeg) {
DEBUG_PRINTF_VBE("Could not find bootsplash.jpg\n");
return;
}
DEBUG_PRINTF_VBE("Splash at %p ...\n", jpeg);
dump(jpeg, 64);

decdata = malloc(sizeof(*decdata));
int ret = 0;
DEBUG_PRINTF_VBE("Decompressing boot splash screen...\n");
ret = jpeg_decode(jpeg, framebuffer, 1024, 768, 16, decdata);
DEBUG_PRINTF_VBE("returns %x\n", ret);
#endif
}

int fill_lb_framebuffer(struct lb_framebuffer *framebuffer)
Expand Down
46 changes: 22 additions & 24 deletions src/device/pci_device.c
Expand Up @@ -34,6 +34,7 @@
#include <arch/acpi.h>
#include <device/pci_ops.h>
#include <bootmode.h>
#include <bootsplash.h>
#include <console/console.h>
#include <stdlib.h>
#include <stdint.h>
Expand All @@ -49,6 +50,8 @@
#include <pc80/i8259.h>
#include <security/vboot/vbnv.h>
#include <timestamp.h>
#include <types.h>


u8 pci_moving_config8(struct device *dev, unsigned int reg)
{
Expand Down Expand Up @@ -592,11 +595,12 @@ void pci_dev_set_resources(struct device *dev)

void pci_dev_enable_resources(struct device *dev)
{
const struct pci_operations *ops;
const struct pci_operations *ops = NULL;
u16 command;

/* Set the subsystem vendor and device ID for mainboard devices. */
ops = ops_pci(dev);
if (dev->ops)
ops = dev->ops->ops_pci;
if (dev->on_mainboard && ops && ops->set_subsystem) {
if (CONFIG_SUBSYSTEM_VENDOR_ID)
dev->subsystem_vendor = CONFIG_SUBSYSTEM_VENDOR_ID;
Expand Down Expand Up @@ -626,11 +630,6 @@ void pci_dev_enable_resources(struct device *dev)
pci_write_config16(dev, PCI_COMMAND, command);
}

void __noreturn pcidev_die(void)
{
die("PCI: dev is NULL!\n");
}

void pci_bus_enable_resources(struct device *dev)
{
u16 ctrl;
Expand Down Expand Up @@ -763,9 +762,13 @@ void pci_dev_init(struct device *dev)
return;

run_bios(dev, (unsigned long)ram);

gfx_set_init_done(1);
printk(BIOS_DEBUG, "VGA Option ROM was run\n");
timestamp_add_now(TS_OPROM_END);

if (CONFIG(BOOTSPLASH))
set_vesa_bootsplash();
}

/** Default device operation for PCI devices */
Expand Down Expand Up @@ -1499,39 +1502,34 @@ int get_pci_irq_pins(struct device *dev, struct device **parent_bdg)
*
* This function should be called for each PCI slot in your system.
*
* @param bus Pointer to the bus structure.
* @param slot TODO
* @param dev Pointer to dev structure.
* @param pIntAtoD An array of IRQ #s that are assigned to PINTA through PINTD
* of this slot. The particular IRQ #s that are passed in depend on the
* routing inside your southbridge and on your board.
*/
void pci_assign_irqs(unsigned bus, unsigned slot,
const unsigned char pIntAtoD[4])
void pci_assign_irqs(struct device *dev, const unsigned char pIntAtoD[4])
{
unsigned int funct;
struct device *pdev;
u8 line, irq;
u8 slot, line, irq;

/* Each slot may contain up to eight functions. */
for (funct = 0; funct < 8; funct++) {
pdev = dev_find_slot(bus, (slot << 3) + funct);
/* Each device may contain up to eight functions. */
slot = dev->path.pci.devfn >> 3;

if (!pdev)
continue;
for (; dev ; dev = dev->sibling) {

if (dev->path.pci.devfn >> 3 != slot)
break;

line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
line = pci_read_config8(dev, PCI_INTERRUPT_PIN);

/* PCI spec says all values except 1..4 are reserved. */
if ((line < 1) || (line > 4))
continue;

irq = pIntAtoD[line - 1];

printk(BIOS_DEBUG, "Assigning IRQ %d to %d:%x.%d\n",
irq, bus, slot, funct);
printk(BIOS_DEBUG, "Assigning IRQ %d to %s\n", irq, dev_path(dev));

pci_write_config8(pdev, PCI_INTERRUPT_LINE,
pIntAtoD[line - 1]);
pci_write_config8(dev, PCI_INTERRUPT_LINE, pIntAtoD[line - 1]);

#ifdef PARANOID_IRQ_ASSIGNMENTS
irq = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
Expand Down
6 changes: 6 additions & 0 deletions src/device/pci_ops.c
Expand Up @@ -14,6 +14,7 @@
#define __SIMPLE_DEVICE__

#include <stdint.h>
#include <console/console.h>
#include <device/pci.h>
#include <device/pci_def.h>
#include <device/pci_ops.h>
Expand Down Expand Up @@ -85,3 +86,8 @@ u16 pci_s_find_capability(pci_devfn_t dev, u16 cap)
{
return pci_s_find_next_capability(dev, cap, 0);
}

void __noreturn pcidev_die(void)
{
die("PCI: dev is NULL!\n");
}
2 changes: 1 addition & 1 deletion src/device/pci_rom.c
Expand Up @@ -192,7 +192,7 @@ static struct rom_header *check_initialized(struct device *dev)
return NULL;

rom_data = (struct pci_data *)((u8 *)run_rom
+ read_le32(&run_rom->data));
+ read_le16(&run_rom->data));

if (read_le32(&rom_data->signature) == PCI_DATA_HDR
&& read_le16(&rom_data->device) == dev->device
Expand Down
3 changes: 0 additions & 3 deletions src/drivers/amd/agesa/oem_s3.c
Expand Up @@ -18,7 +18,6 @@
#include <string.h>
#include <cbmem.h>
#include <console/console.h>
#include <program_loading.h>
#include <northbridge/amd/agesa/state_machine.h>
#include <AGESA.h>
#include <northbridge/amd/agesa/agesa_helper.h>
Expand Down Expand Up @@ -122,8 +121,6 @@ AGESA_STATUS OemS3Save(AMD_S3_PARAMS *dataBlock)
u32 MTRRStorageSize = 0;
uintptr_t pos, size;

romstage_ram_stack_base(HIGH_ROMSTAGE_STACK_SIZE, ROMSTAGE_STACK_CBMEM);

/* To be consumed in AmdInitResume. */
get_s3nv_data(S3DataTypeNonVolatile, &pos, &size);
if (size && dataBlock->NvStorageSize)
Expand Down
17 changes: 17 additions & 0 deletions src/drivers/crb/Kconfig
@@ -0,0 +1,17 @@
config CRB_TPM
bool
help
CRB TPM driver is enabled!

config CRB_TPM_BASE_ADDRESS
hex
default 0xfed40000
help
Base Address of the CRB TPM Command Structure

config MAINBOARD_HAS_CRB_TPM
bool
default n
select CRB_TPM
help
Mainboard has Command Response Buffer support
5 changes: 5 additions & 0 deletions src/drivers/crb/Makefile.inc
@@ -0,0 +1,5 @@
bootblock-$(CONFIG_CRB_TPM) += tis.c tpm.c
verstage-$(CONFIG_CRB_TPM) += tis.c tpm.c
romstage-$(CONFIG_CRB_TPM) += tis.c tpm.c
ramstage-$(CONFIG_CRB_TPM) += tis.c tpm.c
postcar-$(CONFIG_CRB_TPM) += tis.c tpm.c
@@ -1,6 +1,8 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2014 Google Inc. All Rights Reserved.
*
* 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.
Expand All @@ -11,10 +13,10 @@
* GNU General Public License for more details.
*/

/*
* TODO: This is a dummy file for making bootblock build and link. At some
* point, this should be removed from picasso since bootblock is
* ignored.
*/
.global bootblock_pre_c_entry
bootblock_pre_c_entry:
#ifndef DRIVERS_CRB_CHIP_H
#define DRIVERS_CRB_CHIP_H

typedef struct drivers_crb_config {
} tpm_config_t;

#endif /* DRIVERS_CRB_CHIP_H */
159 changes: 159 additions & 0 deletions src/drivers/crb/tis.c
@@ -0,0 +1,159 @@
/*
* This file is part of the coreboot project.
*
* 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 <arch/early_variables.h>
#include <console/console.h>
#include <security/tpm/tis.h>
#include <arch/acpigen.h>
#include <device/device.h>
#include <drivers/intel/ptt/ptt.h>

#include "tpm.h"
#include "chip.h"

static unsigned tpm_is_open CAR_GLOBAL;

static const struct {
uint16_t vid;
uint16_t did;
const char *device_name;
} dev_map[] = {
{0x1ae0, 0x0028, "CR50"},
{0xa13a, 0x8086, "Intel iTPM"}
};

static const char *tis_get_dev_name(struct tpm2_info *info)
{
int i;

for (i = 0; i < ARRAY_SIZE(dev_map); i++)
if ((dev_map[i].vid == info->vendor_id) && (dev_map[i].did == info->device_id))
return dev_map[i].device_name;
return "Unknown";
}


int tis_open(void)
{
if (car_get_var(tpm_is_open)) {
printk(BIOS_ERR, "%s called twice.\n", __func__);
return -1;
}

if (CONFIG(HAVE_INTEL_PTT)) {
if (!ptt_active()) {
printk(BIOS_ERR, "%s: Intel PTT is not active.\n", __func__);
return -1;
}
printk(BIOS_DEBUG, "%s: Intel PTT is active.\n", __func__);
}

return 0;
}

int tis_close(void)
{
if (car_get_var(tpm_is_open)) {

/*
* Do we need to do something here, like waiting for a
* transaction to stop?
*/
car_set_var(tpm_is_open, 0);
}

return 0;
}

int tis_init(void)
{
struct tpm2_info info;

// Wake TPM up (if necessary)
if (tpm2_init() != 0)
return -1;

tpm2_get_info(&info);

printk(BIOS_INFO, "Initialized TPM device %s revision %d\n", tis_get_dev_name(&info),
info.revision);

return 0;
}


int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, size_t *rbuf_len)
{
int len = tpm2_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len);

if (len == 0)
return -1;

*rbuf_len = len;

return 0;
}

#ifdef __RAMSTAGE__

static void crb_tpm_fill_ssdt(struct device *dev)
{
const char *path = acpi_device_path(dev);
if (!path) {
path = "\\_SB_.TPM";
printk(BIOS_DEBUG, "Using default TPM2 ACPI path: '%s'\n", path);
}

/* Device */
acpigen_write_device(path);

acpigen_write_name_string("_HID", "MSFT0101");
acpigen_write_name_string("_CID", "MSFT0101");

acpigen_write_name_integer("_UID", 1);

acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);

/* Resources */
acpigen_write_name("_CRS");
acpigen_write_resourcetemplate_header();
acpigen_write_mem32fixed(1, TPM_CRB_BASE_ADDRESS, 0x5000);

acpigen_write_resourcetemplate_footer();

acpigen_pop_len(); /* Device */
}

static const char *crb_tpm_acpi_name(const struct device *dev)
{
return "TPM";
}

static struct device_operations crb_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
#if CONFIG(HAVE_ACPI_TABLES)
.acpi_name = crb_tpm_acpi_name,
.acpi_fill_ssdt_generator = crb_tpm_fill_ssdt,
#endif

};

static void enable_dev(struct device *dev)
{
dev->ops = &crb_ops;
}

struct chip_operations drivers_crb_ops = {CHIP_NAME("CRB TPM").enable_dev = enable_dev};

#endif /* __RAMSTAGE__ */
280 changes: 280 additions & 0 deletions src/drivers/crb/tpm.c
@@ -0,0 +1,280 @@
/*.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* This is a driver for a CRB Interface.
*
* The general flow looks like this:
*
* TPM starts in IDLE Mode
*
* IDLE --> READY --> Command Receiption
* ^ |
* | v
-- Cmd Complete <-- Command Execution
*/

#include <timer.h>
#include <arch/early_variables.h>
#include <console/console.h>
#include <arch/mmio.h>
#include <delay.h>
#include <string.h>
#include <endian.h>
#include <soc/pci_devs.h>
#include <device/pci_ops.h>

#include "tpm.h"

static struct control_area {
uint32_t request;
uint32_t status;
uint32_t cancel;
uint32_t start;
uint64_t interrupt_control;
uint32_t command_size;
void *command_bfr;
uint32_t response_size;
void *response_bfr;
} control_area;

static uint8_t cur_loc = 0;

/* Read Control Area Structure back */
static void crb_readControlArea(void)
{
control_area.request = read32(CRB_REG(cur_loc, CRB_REG_REQUEST));
control_area.status = read32(CRB_REG(cur_loc, CRB_REG_STATUS));
control_area.cancel = read32(CRB_REG(cur_loc, CRB_REG_CANCEL));
control_area.interrupt_control = read64(CRB_REG(cur_loc, CRB_REG_INT_CTRL));
control_area.command_size = read32(CRB_REG(cur_loc, CRB_REG_CMD_SIZE));
control_area.command_bfr = (void *)(uint32_t)read64(CRB_REG(cur_loc, CRB_REG_CMD_ADDR));
control_area.response_size = read32(CRB_REG(cur_loc, CRB_REG_RESP_SIZE));
control_area.response_bfr =
(void *)(uint32_t)read64(CRB_REG(cur_loc, CRB_REG_RESP_ADDR));
}

/* Wait for Reg to be expected Value */
static int crb_wait_for_reg32(const void *addr, uint32_t timeoutMs, uint32_t mask,
uint32_t expectedValue)
{
uint32_t regValue;
struct stopwatch sw;

// Set up a timer which breaks the loop after timeout
stopwatch_init_msecs_expire(&sw, timeoutMs);

while (1) {
// Now check if the TPM is in IDLE mode
regValue = read32(addr);

if ((regValue & mask) == expectedValue)
return 0;

if (stopwatch_expired(&sw)) {
printk(BIOS_ERR,
"CRB_WAIT: Error - Returning Zero with RegValue: %08x, Mask: %08x, Expected: %08x\n",
regValue, mask, expectedValue);
return -1;
}
}
}

/* CRB PROBE
*
* Checks if the CRB Interface is ready
*/
static int crb_probe(void)
{
uint64_t tpmStatus = read64(CRB_REG(cur_loc, CRB_REG_INTF_ID));
printk(BIOS_SPEW, "Interface ID Reg. %llx\n", tpmStatus);

if ((tpmStatus & CRB_INTF_REG_CAP_CRB) == 0) {
printk(BIOS_DEBUG, "TPM: CRB Interface is not supported.\n");
return -1;
}

if ((tpmStatus & (0xf)) != 1) {
printk(BIOS_DEBUG,
"TPM: CRB Interface is not active. System needs reboot in order to active TPM.\n");
write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL);
return -1;
}

write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL);
write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_LOCK);

return 0;
}

/*
* Get active Locality
*
* Get the active locality
*/
static uint8_t crb_activate_locality(void)
{

uint8_t locality = (read8(CRB_REG(0, CRB_REG_LOC_STATE)) >> 2) & 0x07;
printk(BIOS_SPEW, "Active locality: %i\n", locality);

int rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750,
LOC_STATE_LOC_ASSIGN, LOC_STATE_LOC_ASSIGN);
if (!rc && (locality == 0))
return locality;

if (rc)
write8(CRB_REG(locality, CRB_REG_LOC_CTRL), LOC_CTRL_REQ_ACCESS);


rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750, LOC_STATE_LOC_ASSIGN,
LOC_STATE_LOC_ASSIGN);
if (rc) {
printk(BIOS_ERR, "TPM: Error - No Locality has been assigned TPM-wise.\n");
return 0;
}

rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 1500,
LOC_STATE_REG_VALID_STS, LOC_STATE_REG_VALID_STS);
if (rc) {
printk(BIOS_ERR, "TPM: Error - LOC_STATE Register %u contains errors.\n",
locality);
return 0;
}


return locality;
}

/* Switch Device into a Ready State */
static int crb_switch_to_ready(void)
{
/* Transition into ready state */
write8(CRB_REG(cur_loc, CRB_REG_REQUEST), 0x1);
int rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_REQUEST), 200,
CRB_REG_REQUEST_CMD_RDY, 0x0);
if (rc) {
printk(BIOS_ERR,
"TPM: Error - TPM did not transition into ready state in time.\n");
return -1;
}

/* Check TPM_CRB_CTRL_STS[0] to be "0" - no unrecoverable error */
rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 500, CRB_REG_STATUS_ERROR,
0x0);
if (rc) {
printk(BIOS_ERR, "TPM: Fatal Error - Could not recover.\n");
return -1;
}

return 0;
}

/*
* tpm2_init
*
* Even though the TPM does not need an initialization we check
* if the TPM responds and is in IDLE mode, which should be the
* normal bring up mode.
*
*/
int tpm2_init(void)
{


if (crb_probe()) {
printk(BIOS_ERR, "TPM: Probe failed.\n");
return -1;
}

/* Read back control area structure */
crb_readControlArea();

/* Good to go. */
printk(BIOS_SPEW, "TPM: CRB TPM initialized successfully\n");

return 0;
}

/*
* tpm2_process_command
*/
size_t tpm2_process_command(const void *tpm2_command, size_t command_size, void *tpm2_response,
size_t max_response)
{
int rc;

if (command_size > control_area.command_size) {
printk(BIOS_ERR, "TPM: Command size is too big.\n");
return -1;
}

if (control_area.response_size < max_response) {
printk(BIOS_ERR, "TPM: Response size could be too big.\n");
return -1;
}

cur_loc = crb_activate_locality();

// Check if CMD bit is cleared.
rc = crb_wait_for_reg32(CRB_REG(0, CRB_REG_START), 250, CRB_REG_START_START, 0x0);
if (rc) {
printk(BIOS_ERR, "TPM: Error - Cmd Bit not cleared.\n");
return -1;
}

if (crb_switch_to_ready())
return -1;

// Write to Command Buffer
memcpy(control_area.command_bfr, tpm2_command, command_size);

// Write Start Bit
write8(CRB_REG(cur_loc, CRB_REG_START), 0x1);

// Poll for Response
rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_START), 3500, CRB_REG_START_START, 0);
if (rc) {
printk(BIOS_DEBUG, "TPM: Command Timed out.\n");
return -1;
}

// Check for errors
rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 200, CRB_REG_STATUS_ERROR, 0);
if (rc) {
printk(BIOS_DEBUG, "TPM: Command errored.\n");
return -1;
}

// Get Response Length
uint32_t length = be32_to_cpu(read32(control_area.response_bfr + 2));

/* Response has to have at least 6 bytes */
if (length < 6)
return 1;

// Copy Response
memcpy(tpm2_response, control_area.response_bfr, length);

if (crb_switch_to_ready()) {
printk(BIOS_DEBUG, "TPM: Can not transition into ready state again.\n");
return -1;
}

return length;
}

/*
* tp2_get_info
*
* Returns information about the TPM
*
*/
void tpm2_get_info(struct tpm2_info *tpm2_info)
{
uint64_t interfaceReg = read64(CRB_REG(cur_loc, CRB_REG_INTF_ID));

tpm2_info->vendor_id = (interfaceReg >> 48) & 0xFFFF;
tpm2_info->device_id = (interfaceReg >> 32) & 0xFFFF;
tpm2_info->revision = (interfaceReg >> 24) & 0xFF;
}
70 changes: 70 additions & 0 deletions src/drivers/crb/tpm.h
@@ -0,0 +1,70 @@
/*
* Copyright 2016 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* This is a driver for a Command Response Buffer Interface
*/

/* CRB driver */
/* address of locality 0 (CRB) */
#define TPM_CRB_BASE_ADDRESS CONFIG_CRB_TPM_BASE_ADDRESS

#define CRB_REG(LOCTY, REG) \
(void *)(CONFIG_CRB_TPM_BASE_ADDRESS + (LOCTY << 12) + REG)

/* hardware registers */
#define CRB_REG_LOC_STATE 0x00
#define CRB_REG_LOC_CTRL 0x08
#define CRB_REG_LOC_STS 0x0C

/* LOC_CTRL BIT MASKS */
#define LOC_CTRL_REQ_ACCESS 0x01

/* LOC STATE BIT MASKS */
#define LOC_STATE_LOC_ASSIGN 0x02
#define LOC_STATE_REG_VALID_STS 0x80

/* LOC STS BIT MASKS */
#define LOC_STS_GRANTED 0x01

#define CRB_REG_INTF_ID 0x30
#define CRB_REG_REQUEST 0x40
#define CRB_REG_STATUS 0x44
#define CRB_REG_CANCEL 0x48
#define CRB_REG_START 0x4C
#define CRB_REG_INT_CTRL 0x50
#define CRB_REG_CMD_SIZE 0x58
#define CRB_REG_CMD_ADDR 0x5C
#define CRB_REG_RESP_SIZE 0x64
#define CRB_REG_RESP_ADDR 0x68

/* CRB INTF BIT MASK */
#define CRB_INTF_REG_CAP_CRB (1<<14)
#define CRB_INTF_REG_INTF_SEL (1<<17)
#define CRB_INTF_REG_INTF_LOCK (1<<19)


/*REQUEST Register related */
#define CRB_REG_REQUEST_CMD_RDY 0x01
#define CRB_REG_REQUEST_GO_IDLE 0x02

/* STATUS Register related */
#define CRB_REG_STATUS_ERROR 0x01
#define CRB_REG_STATUS_IDLE 0x02

/* START Register related */
#define CRB_REG_START_START 0x01

/* TPM Info Struct */
struct tpm2_info {
uint16_t vendor_id;
uint16_t device_id;
uint16_t revision;
};


int tpm2_init(void);
void tpm2_get_info(struct tpm2_info *tpm2_info);
size_t tpm2_process_command(const void *tpm2_command, size_t command_size,
void *tpm2_response, size_t max_response);
9 changes: 4 additions & 5 deletions src/drivers/elog/Kconfig
Expand Up @@ -42,10 +42,8 @@ config ELOG_PRERAM
help
This option will enable event logging from the preram stage.

endif

config ELOG_GSMI
depends on ELOG && SMM_TSEG
depends on HAVE_SMI_HANDLER
bool "SMI interface to write and clear event log"
select SPI_FLASH_SMM if BOOT_DEVICE_SPI_FLASH_RW_NOMMAP
default n
Expand All @@ -55,7 +53,6 @@ config ELOG_GSMI
kernel reset/shutdown messages to the event log.

config ELOG_BOOT_COUNT
depends on ELOG
bool "Maintain a monotonic boot number in CMOS"
default n
help
Expand All @@ -64,9 +61,11 @@ config ELOG_BOOT_COUNT
counter will be logged as part of the System Boot event.

config ELOG_BOOT_COUNT_CMOS_OFFSET
depends on ELOG && ELOG_BOOT_COUNT && !USE_OPTION_TABLE
depends on ELOG_BOOT_COUNT && !USE_OPTION_TABLE
int "Offset in CMOS to store the boot count"
default 0
help
This value must be greater than 16 bytes so as not to interfere
with the standard RTC region. Requires 8 bytes.

endif
24 changes: 7 additions & 17 deletions src/drivers/i2c/designware/dw_i2c.c
Expand Up @@ -817,14 +817,9 @@ void dw_i2c_acpi_fill_ssdt(struct device *dev)
const struct dw_i2c_bus_config *bcfg;
uintptr_t dw_i2c_addr;
struct dw_i2c_speed_config sgen;
enum i2c_speed speeds[DW_I2C_SPEED_CONFIG_COUNT] = {
I2C_SPEED_STANDARD,
I2C_SPEED_FAST,
I2C_SPEED_FAST_PLUS,
I2C_SPEED_HIGH,
};
int i, bus;
int bus;
const char *path;
unsigned int speed;

if (!dev->enabled)
return;
Expand All @@ -847,20 +842,15 @@ void dw_i2c_acpi_fill_ssdt(struct device *dev)
if (!path)
return;

acpigen_write_scope(path);
/* Ensure a default speed is available */
speed = (bcfg->speed == 0) ? I2C_SPEED_FAST : bcfg->speed;

/* Report timing values for the OS driver */
for (i = 0; i < DW_I2C_SPEED_CONFIG_COUNT; i++) {
/* Generate speed config. */
if (dw_i2c_gen_speed_config(dw_i2c_addr, speeds[i], bcfg,
&sgen) < 0)
continue;

/* Generate ACPI based on selected speed config */
if (dw_i2c_gen_speed_config(dw_i2c_addr, speed, bcfg, &sgen) >= 0) {
acpigen_write_scope(path);
dw_i2c_acpi_write_speed_config(&sgen);
acpigen_pop_len();
}

acpigen_pop_len();
}

static int dw_i2c_dev_transfer(struct device *dev,
Expand Down
3 changes: 0 additions & 3 deletions src/drivers/intel/fsp1_1/Makefile.inc
Expand Up @@ -29,21 +29,18 @@ romstage-y += fsp_util.c
romstage-y += hob.c
romstage-y += raminit.c
romstage-y += romstage.c
romstage-y += stage_cache.c
romstage-$(CONFIG_MMA) += mma_core.c

ramstage-$(CONFIG_RUN_FSP_GOP) += fsp_gop.c
ramstage-y += fsp_relocate.c
ramstage-y += fsp_util.c
ramstage-y += hob.c
ramstage-y += ramstage.c
ramstage-y += stage_cache.c
ramstage-$(CONFIG_INTEL_GMA_ADD_VBT) += vbt.c
ramstage-$(CONFIG_MMA) += mma_core.c

CPPFLAGS_common += -Isrc/drivers/intel/fsp1_1/include

postcar-y += stage_cache.c
ifneq ($(CONFIG_SKIP_FSP_CAR),y)
postcar-y += temp_ram_exit.c
postcar-y += exit_car.S
Expand Down
3 changes: 1 addition & 2 deletions src/drivers/intel/fsp1_1/car.c
Expand Up @@ -19,11 +19,10 @@
#include <commonlib/helpers.h>
#include <cpu/intel/romstage.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <fsp/car.h>
#include <fsp/util.h>
#include <fsp/memmap.h>
#include <program_loading.h>
#include <timestamp.h>

/* platform_enter_postcar() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use,
Expand Down
47 changes: 0 additions & 47 deletions src/drivers/intel/fsp1_1/include/fsp/memmap.h

This file was deleted.

85 changes: 26 additions & 59 deletions src/drivers/intel/fsp1_1/raminit.c
Expand Up @@ -2,7 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2014-2016 Intel Corporation
* Copyright (C) 2018 Eltan B.V.
* Copyright (C) 2018-2019 Eltan B.V.
*
* 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
Expand All @@ -19,7 +19,7 @@
#include <cf9_reset.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <fsp/memmap.h>
#include <cpu/x86/smm.h>
#include <fsp/romstage.h>
#include <fsp/util.h>
#include <lib.h> /* hexdump */
Expand Down Expand Up @@ -52,10 +52,9 @@ void raminit(struct romstage_params *params)
VPD_DATA_REGION *vpd_ptr;
UPD_DATA_REGION *upd_ptr;
int fsp_verification_failure = 0;
#if CONFIG(DISPLAY_HOBS)
unsigned long int data;
EFI_PEI_HOB_POINTERS hob_ptr;
#endif
uintptr_t smm_base;
size_t smm_size;

/*
* Find and copy the UPD region to the stack so the platform can modify
Expand Down Expand Up @@ -139,7 +138,7 @@ void raminit(struct romstage_params *params)
fsp_memory = get_next_resource_hob(&fsp_reserved_guid, hob_list_ptr);
if (fsp_memory == NULL) {
fsp_verification_failure = 1;
printk(BIOS_DEBUG,
printk(BIOS_ERR,
"7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB missing!\n");
} else {
fsp_reserved_bytes = fsp_memory->ResourceLength;
Expand All @@ -148,14 +147,11 @@ void raminit(struct romstage_params *params)
}

/* Display SMM area */
#if CONFIG(HAVE_SMI_HANDLER)
char *smm_base;
size_t smm_size;

smm_region((void **)&smm_base, &smm_size);
printk(BIOS_DEBUG, "0x%08x: smm_size\n", (unsigned int)smm_size);
printk(BIOS_DEBUG, "0x%p: smm_base\n", smm_base);
#endif
if (CONFIG(HAVE_SMI_HANDLER)) {
smm_region(&smm_base, &smm_size);
printk(BIOS_DEBUG, "0x%08x: smm_size\n", (unsigned int)smm_size);
printk(BIOS_DEBUG, "0x%08x: smm_base\n", (unsigned int)smm_base);
}

/* Migrate CAR data */
printk(BIOS_DEBUG, "0x%p: cbmem_top\n", cbmem_top());
Expand Down Expand Up @@ -190,64 +186,36 @@ void raminit(struct romstage_params *params)
if (memory_info_hob == NULL) {
printk(BIOS_ERR, "FSP_SMBIOS_MEMORY_INFO HOB missing!\n");
fsp_verification_failure = 1;
} else {
printk(BIOS_DEBUG,
"FSP_SMBIOS_MEMORY_INFO HOB: 0x%p\n",
memory_info_hob);
}

#if CONFIG(DISPLAY_HOBS)
if (hob_list_ptr == NULL)
die_with_post_code(POST_RAM_FAILURE,
"ERROR - HOB pointer is NULL!\n");

/*
* Verify that FSP is generating the required HOBs:
* 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
* 7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified above
* 7.3: FSP_NON_VOLATILE_STORAGE_HOB only produced when
* new NVS data is generated, verified below
* new NVS data is generated, verified below
* 7.4: FSP_BOOTLOADER_TOLUM_HOB verified above
* 7.5: EFI_PEI_GRAPHICS_INFO_HOB produced by SiliconInit
* FSP_SMBIOS_MEMORY_INFO HOB verified above
*/
if (cbmem_root != NULL) {
printk(BIOS_DEBUG,
"7.4: FSP_BOOTLOADER_TOLUM_HOB: 0x%p\n",
cbmem_root);
data = cbmem_root->PhysicalStart;
printk(BIOS_DEBUG, " 0x%016lx: PhysicalStart\n", data);
data = cbmem_root->ResourceLength;
printk(BIOS_DEBUG, " 0x%016lx: ResourceLength\n", data);
}
hob_ptr.Raw = get_next_guid_hob(&mrc_guid, hob_list_ptr);
if (hob_ptr.Raw == NULL) {
if (params->saved_data == NULL) {
printk(BIOS_ERR, "7.3: FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
fsp_verification_failure = 1;
}
} else {
printk(BIOS_DEBUG,
"7.3: FSP_NON_VOLATILE_STORAGE_HOB: 0x%p\n",
hob_ptr.Raw);
}
if (fsp_memory != NULL) {
printk(BIOS_DEBUG,
"7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB: 0x%p\n",
fsp_memory);
data = fsp_memory->PhysicalStart;
printk(BIOS_DEBUG, " 0x%016lx: PhysicalStart\n", data);
data = fsp_memory->ResourceLength;
printk(BIOS_DEBUG, " 0x%016lx: ResourceLength\n", data);
if ((hob_ptr.Raw == NULL) && (params->saved_data == NULL)) {
printk(BIOS_ERR, "7.3: FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
fsp_verification_failure = 1;
}

/* Verify all the HOBs are present */
if (fsp_verification_failure)
printk(BIOS_DEBUG,
printk(BIOS_ERR,
"ERROR - Missing one or more required FSP HOBs!\n");

/* Display the HOBs */
if (hob_list_ptr != NULL)
if (CONFIG(DISPLAY_HOBS))
print_hob_type_structure(0, hob_list_ptr);
else
printk(BIOS_ERR, "ERROR - HOB pointer is NULL!\n");
#endif

/* Get the address of the CBMEM region for the FSP reserved memory */
fsp_reserved_memory_area = cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY);
Expand All @@ -258,7 +226,7 @@ void raminit(struct romstage_params *params)
if ((fsp_memory != NULL) && (cbmem_root != NULL) &&
(cbmem_root->PhysicalStart <= fsp_memory->PhysicalStart)) {
fsp_verification_failure = 1;
printk(BIOS_DEBUG,
printk(BIOS_ERR,
"ERROR - FSP reserved memory above CBMEM root!\n");
}

Expand All @@ -267,19 +235,18 @@ void raminit(struct romstage_params *params)
(fsp_memory->PhysicalStart !=
(unsigned int)fsp_reserved_memory_area))) {
fsp_verification_failure = 1;
printk(BIOS_DEBUG, "ERROR - Reserving FSP memory area!\n");
#if CONFIG(HAVE_SMI_HANDLER)
if (cbmem_root != NULL) {
size_t delta_bytes = (unsigned int)smm_base
printk(BIOS_ERR, "ERROR - Reserving FSP memory area!\n");

if (CONFIG(HAVE_SMI_HANDLER) && cbmem_root != NULL) {
size_t delta_bytes = smm_base
- cbmem_root->PhysicalStart
- cbmem_root->ResourceLength;
printk(BIOS_DEBUG,
printk(BIOS_ERR,
"0x%08x: Chipset reserved bytes reported by FSP\n",
(unsigned int)delta_bytes);
die_with_post_code(POST_INVALID_VENDOR_BINARY,
"Please verify the chipset reserved size\n");
}
#endif
}

/* Verify the FSP 1.1 HOB interface */
Expand Down
29 changes: 12 additions & 17 deletions src/drivers/intel/fsp1_1/ramstage.c
Expand Up @@ -17,7 +17,7 @@
#include <bootmode.h>
#include <arch/acpi.h>
#include <console/console.h>
#include <fsp/memmap.h>
#include <cpu/x86/smm.h>
#include <fsp/ramstage.h>
#include <fsp/util.h>
#include <lib.h>
Expand All @@ -33,38 +33,35 @@ __weak void soc_after_silicon_init(void)
/* Display SMM memory map */
static void smm_memory_map(void)
{
void *base;
uintptr_t base;
size_t size;
int i;

printk(BIOS_SPEW, "SMM Memory Map\n");

smm_region(&base, &size);
printk(BIOS_SPEW, "SMRAM : %p 0x%zx\n", base, size);
printk(BIOS_SPEW, "SMRAM : 0x%zx 0x%zx\n", base, size);

for (i = 0; i < SMM_SUBREGION_NUM; i++) {
if (smm_subregion(i, &base, &size))
continue;
printk(BIOS_SPEW, " Subregion %d: %p 0x%zx\n", i, base, size);
printk(BIOS_SPEW, " Subregion %d: 0x%zx 0x%zx\n", i, base, size);
}
}

static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
{
const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID;
int missing_hob = 0;
void *hob_list_ptr = get_hob_list();

if (!CONFIG(DISPLAY_HOBS))
return;

/* Verify the HOBs */
if (hob_list_ptr == NULL) {
printk(BIOS_INFO, "ERROR - HOB pointer is NULL!\n");
printk(BIOS_ERR, "ERROR - HOB pointer is NULL!\n");
return;
}

print_hob_type_structure(0, hob_list_ptr);
if (CONFIG(DISPLAY_HOBS))
print_hob_type_structure(0, hob_list_ptr);

/*
* Verify that FSP is generating the required HOBs:
Expand All @@ -77,14 +74,12 @@ static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
* FSP_SMBIOS_MEMORY_INFO HOB verified by raminit
*/
if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) &&
!get_next_guid_hob(&graphics_info_guid, hob_list_ptr)) {
printk(BIOS_INFO, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
missing_hob = 1;
}

if (missing_hob)
printk(BIOS_INFO,
!get_next_guid_hob(&graphics_info_guid, hob_list_ptr) &&
CONFIG(DISPLAY_HOBS)) {
printk(BIOS_ERR, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
printk(BIOS_ERR,
"ERROR - Missing one or more required FSP HOBs!\n");
}
}

void fsp_run_silicon_init(FSP_INFO_HEADER *fsp_info_header, int is_s3_wakeup)
Expand Down
3 changes: 0 additions & 3 deletions src/drivers/intel/fsp2_0/Makefile.inc
Expand Up @@ -23,7 +23,6 @@ romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
romstage-$(CONFIG_VERIFY_HOBS) += hob_verify.c
romstage-y += util.c
romstage-y += memory_init.c
romstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
romstage-$(CONFIG_MMA) += mma_core.c

ramstage-y += debug.c
Expand All @@ -34,12 +33,10 @@ ramstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c
ramstage-$(CONFIG_VERIFY_HOBS) += hob_verify.c
ramstage-y += notify.c
ramstage-y += silicon_init.c
ramstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
ramstage-y += util.c
ramstage-$(CONFIG_MMA) += mma_core.c

postcar-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
postcar-$(CONFIG_FSP_CAR) += temp_ram_exit.c
postcar-$(CONFIG_FSP_CAR) += util.c
postcar-$(CONFIG_DISPLAY_FSP_HEADER) += header_display.c
Expand Down
47 changes: 0 additions & 47 deletions src/drivers/intel/fsp2_0/include/fsp/memmap.h

This file was deleted.

12 changes: 9 additions & 3 deletions src/drivers/intel/gma/Kconfig
Expand Up @@ -54,6 +54,9 @@ config INTEL_GMA_SWSMISCI
Select this option for Atom-based platforms which use the SWSMISCI
register (0xe0) rather than the SWSCI register (0xe8).

config INTEL_GMA_LIBGFXINIT_EDID
bool

config GFX_GMA_ANALOG_I2C_HDMI_B
bool

Expand All @@ -68,8 +71,10 @@ config GFX_GMA
depends on NORTHBRIDGE_INTEL_GM45 || NORTHBRIDGE_INTEL_X4X \
|| NORTHBRIDGE_INTEL_NEHALEM || NORTHBRIDGE_INTEL_SANDYBRIDGE \
|| NORTHBRIDGE_INTEL_HASWELL \
|| SOC_INTEL_BROADWELL || SOC_INTEL_SKYLAKE || SOC_INTEL_APOLLOLAKE
depends on MAINBOARD_USE_LIBGFXINIT
|| SOC_INTEL_BROADWELL || SOC_INTEL_SKYLAKE || SOC_INTEL_APOLLOLAKE \
|| SOC_INTEL_KABYLAKE || SOC_INTEL_COFFEELAKE \
|| SOC_INTEL_WHISKEYLAKE
depends on MAINBOARD_USE_LIBGFXINIT || INTEL_GMA_LIBGFXINIT_EDID
select RAMSTAGE_LIBHWBASE

config GFX_GMA_INTERNAL_IS_EDP
Expand All @@ -94,7 +99,8 @@ config GFX_GMA_DYN_CPU
config GFX_GMA_GENERATION
string
default "Broxton" if SOC_INTEL_APOLLOLAKE
default "Skylake" if SOC_INTEL_SKYLAKE
default "Skylake" if SOC_INTEL_SKYLAKE || SOC_INTEL_KABYLAKE || \
SOC_INTEL_COFFEELAKE || SOC_INTEL_WHISKEYLAKE
default "Haswell" if NORTHBRIDGE_INTEL_HASWELL || SOC_INTEL_BROADWELL
default "Ironlake" if NORTHBRIDGE_INTEL_NEHALEM || NORTHBRIDGE_INTEL_SANDYBRIDGE
default "G45" if NORTHBRIDGE_INTEL_GM45 || NORTHBRIDGE_INTEL_X4X
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/gma/Makefile.inc
Expand Up @@ -50,7 +50,7 @@ CONFIG_GFX_GMA_DEFAULT_MMIO := 0 # dummy, will be overwritten at runtime

subdirs-y += ../../../../3rdparty/libgfxinit

ramstage-y += gma.ads
ramstage-y += gma.ads gma.adb

ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-gfx_init.ads
ifeq ($(CONFIG_LINEAR_FRAMEBUFFER),y)
Expand Down
37 changes: 37 additions & 0 deletions src/drivers/intel/gma/gma.adb
@@ -0,0 +1,37 @@
with HW.GFX.GMA;
with HW.GFX.GMA.Display_Probing;

use HW.GFX.GMA;

package body GMA is

function read_edid
(raw_edid : out HW.GFX.EDID.Raw_EDID_Data;
port : in Interfaces.C.int)
return Interfaces.C.int
is
use type Interfaces.C.int;
success : Boolean := true;
begin
if port not in Active_Port_Type'Pos (Active_Port_Type'First)
.. Active_Port_Type'Pos (Active_Port_Type'Last)
then
raw_edid := (others => 0);
return -2;
else
if not HW.GFX.GMA.Is_Initialized then
HW.GFX.GMA.Initialize (Success => success);
end if;
if success then
HW.GFX.GMA.Display_Probing.Read_EDID
(raw_edid, Active_Port_Type'Val (port), success);
end if;
if success then
return 0;
else
return -1;
end if;
end if;
end read_edid;

end GMA;
12 changes: 12 additions & 0 deletions src/drivers/intel/gma/gma.ads
@@ -1,2 +1,14 @@
with Interfaces.C;

with HW.GFX.EDID;

package GMA is

function read_edid
(raw_edid : out HW.GFX.EDID.Raw_EDID_Data;
Port : in Interfaces.C.int)
return Interfaces.C.int
with
Export, Convention => C, External_Name => "gma_read_edid";

end GMA;
13 changes: 13 additions & 0 deletions src/drivers/intel/gma/libgfxinit.h
Expand Up @@ -14,6 +14,19 @@
#ifndef DRIVERS_INTEL_GMA_LIBGFXINIT_H
#define DRIVERS_INTEL_GMA_LIBGFXINIT_H

enum {
GMA_PORT_DISABLED,
GMA_PORT_INTERNAL,
GMA_PORT_DP1,
GMA_PORT_DP2,
GMA_PORT_DP3,
GMA_PORT_HDMI1, /* or DVI */
GMA_PORT_HDMI2, /* or DVI */
GMA_PORT_HDMI3, /* or DVI */
GMA_PORT_ANALOG,
};

void gma_gfxinit(int *lightup_ok);
int gma_read_edid(unsigned char edid[], int port);

#endif
6 changes: 6 additions & 0 deletions src/drivers/intel/ptt/Kconfig
@@ -0,0 +1,6 @@
config HAVE_INTEL_PTT
bool
default n
select VBOOT_MOCK_SECDATA if VBOOT
help
Activate if your platform has Intel Platform Trust Technology like Intel iTPM and you want to use it.
4 changes: 4 additions & 0 deletions src/drivers/intel/ptt/Makefile.inc
@@ -0,0 +1,4 @@
romstage-$(CONFIG_HAVE_INTEL_PTT) += ptt.c
ramstage-$(CONFIG_HAVE_INTEL_PTT) += ptt.c
postcar-$(CONFIG_HAVE_INTEL_PTT) += ptt.c
verstage-$(CONFIG_HAVE_INTEL_PTT) += ptt.c
53 changes: 53 additions & 0 deletions src/drivers/intel/ptt/ptt.c
@@ -0,0 +1,53 @@
/*
* This file is part of the coreboot project.
*
* 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 <soc/pci_devs.h>
#include <device/pci_ops.h>
#include <console/console.h>
#include <timer.h>

#include "ptt.h"

#define PCI_ME_HFSTS4 0x64
#define PTT_ENABLE (1 << 19)

/* Dump Intel ME register */
static uint32_t read_register(int reg_addr)
{
if (!PCH_DEV_CSE)
return 0xFFFFFFFF;

return pci_read_config32(PCH_DEV_CSE, reg_addr);
}

/*
* ptt_active()
*
* Check if PTT Flag is set - so that PTT is active.
*
* Return true if active, false otherwise.
*/
bool ptt_active(void)
{
uint32_t fwsts4 = read_register(PCI_ME_HFSTS4);

if (fwsts4 == 0xFFFFFFFF)
return false;

if ((fwsts4 & PTT_ENABLE) == 0) {
printk(BIOS_DEBUG, "Intel ME Establishment bit not valid.\n");
return false;
}

return true;
}
@@ -1,8 +1,6 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2015 Google, 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.
Expand All @@ -11,19 +9,19 @@
* 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.
*
* This driver checks if the PTT Bit is set correctly within the FWSTS4
* register. This is needed in order to use the iTPM, because we have to
* check prior using the interface that this bit is set correctly - otherwise
* it could work unpredictable. The bit should already be set if the Intel ME
* is still in the preboot phase.
*
*/

#include <stdint.h>
#include <stage_cache.h>
#include <cpu/intel/smm/gen1/smi.h>

void stage_cache_external_region(void **base, size_t *size)
{
/*
* The ramstage cache lives in the TSEG region at RESERVED_SMM_OFFSET.
* The top of RAM is defined to be the TSEG base address.
*/
*size = CONFIG_SMM_RESERVED_SIZE;
*base = (void *)(northbridge_get_tseg_base()
+ CONFIG_SMM_RESERVED_SIZE);
}
/*
* ptt_active
*
* Checks if the Intel PTT is active. If PTT is active, returns true,
* false otherwise.
*/
bool ptt_active(void);
49 changes: 2 additions & 47 deletions src/drivers/intel/wifi/Kconfig
@@ -1,53 +1,8 @@
config DRIVERS_INTEL_WIFI
bool "Support Intel PCI-e WiFi adapters"
depends on ARCH_X86
depends on PCI
default y if PCIEXP_PLUGIN_SUPPORT
select DRIVERS_GENERIC_WIFI if HAVE_ACPI_TABLES
help
When enabled, add identifiers in ACPI and SMBIOS tables to
make OS drivers work with certain Intel PCI-e WiFi chipsets.

config USE_SAR
bool
default n
help
Enable it when wifi driver uses SAR configuration feature.
VPD entry "wifi_sar" is read to get SAR settings, if its
not found driver may look into CBFS for default settigs.
WIFI_SAR_CBFS is option to enable CBFS lookup.

config SAR_ENABLE
bool
default n
depends on USE_SAR

config DSAR_ENABLE
bool
default n
depends on USE_SAR

config GEO_SAR_ENABLE
bool
default n
depends on USE_SAR

config WIFI_SAR_CBFS
bool "Enable SAR table addition to CBFS"
default n
depends on USE_SAR
help
wifi driver would look for "wifi_sar" vpd key and load SAR settings from
it, if the vpd key is not found then the driver tries to look for sar
settings from CBFS with file name wifi_sar_defaults.hex.
So OEM/ODM can override wifi sar with VPD.

config WIFI_SAR_CBFS_FILEPATH
string "The cbfs file which has WIFI SAR defaults"
depends on WIFI_SAR_CBFS
default "src/mainboard/$(MAINBOARDDIR)/wifi_sar_defaults.hex"

config DSAR_SET_NUM
hex "Number of SAR sets when D-SAR is enabled"
default 0x3
depends on USE_SAR
help
There can be up to 3 optional SAR table sets.
23 changes: 4 additions & 19 deletions src/drivers/intel/wifi/chip.h
Expand Up @@ -13,26 +13,11 @@
* GNU General Public License for more details.
*/

#ifndef _WIFI_CHIP_H_
#define _WIFI_CHIP_H_

/* WRDS Spec Revision */
#define WRDS_REVISION 0x0

/* EWRD Spec Revision */
#define EWRD_REVISION 0x0

/* WRDS Domain type */
#define WRDS_DOMAIN_TYPE_WIFI 0x7

/* EWRD Domain type */
#define EWRD_DOMAIN_TYPE_WIFI 0x7

/* WGDS Domain type */
#define WGDS_DOMAIN_TYPE_WIFI 0x7
#ifndef _INTEL_WIFI_CHIP_H_
#define _INTEL_WIFI_CHIP_H_

struct drivers_intel_wifi_config {
unsigned wake; /* Wake pin for ACPI _PRW */
unsigned int wake; /* Wake pin for ACPI _PRW */
};

#endif /* _WIFI_CHIP_H_ */
#endif /* _INTEL_WIFI_CHIP_H_ */
195 changes: 8 additions & 187 deletions src/drivers/intel/wifi/wifi.c
Expand Up @@ -15,19 +15,16 @@
* GNU General Public License for more details.
*/

#include <arch/acpi_device.h>
#include <arch/acpigen.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>
#include <device/pci_ids.h>
#include <elog.h>
#include <sar.h>
#include <smbios.h>
#include <string.h>
#include <wrdd.h>
#include "chip.h"
#include "drivers/wifi/generic_wifi.h"

#define PMCS_DR 0xcc
#define PME_STS (1 << 15)
Expand Down Expand Up @@ -65,194 +62,18 @@ static int smbios_write_wifi(struct device *dev, int *handle,
}
#endif

__weak
int get_wifi_sar_limits(struct wifi_sar_limits *sar_limits)
{
return -1;
}

#if CONFIG(HAVE_ACPI_TABLES)
static void emit_sar_acpi_structures(void)
{
int i, j, package_size;
struct wifi_sar_limits sar_limits;
struct wifi_sar_delta_table *wgds;

/* Retrieve the sar limits data */
if (get_wifi_sar_limits(&sar_limits) < 0) {
printk(BIOS_ERR, "Error: failed from getting SAR limits!\n");
return;
}

/*
* Name ("WRDS", Package () {
* Revision,
* Package () {
* Domain Type, // 0x7:WiFi
* WiFi SAR BIOS, // BIOS SAR Enable/disable
* SAR Table Set // Set#1 of SAR Table (10 bytes)
* }
* })
*/
acpigen_write_name("WRDS");
acpigen_write_package(2);
acpigen_write_dword(WRDS_REVISION);
/* Emit 'Domain Type' + 'WiFi SAR BIOS' + 10 bytes for Set#1 */
package_size = 1 + 1 + BYTES_PER_SAR_LIMIT;
acpigen_write_package(package_size);
acpigen_write_dword(WRDS_DOMAIN_TYPE_WIFI);
acpigen_write_dword(CONFIG(SAR_ENABLE));
for (i = 0; i < BYTES_PER_SAR_LIMIT; i++)
acpigen_write_byte(sar_limits.sar_limit[0][i]);
acpigen_pop_len();
acpigen_pop_len();

/*
* Name ("EWRD", Package () {
* Revision,
* Package () {
* Domain Type, // 0x7:WiFi
* Dynamic SAR Enable, // Dynamic SAR Enable/disable
* Extended SAR sets, // Number of optional SAR table sets
* SAR Table Set, // Set#2 of SAR Table (10 bytes)
* SAR Table Set, // Set#3 of SAR Table (10 bytes)
* SAR Table Set // Set#4 of SAR Table (10 bytes)
* }
* })
*/
acpigen_write_name("EWRD");
acpigen_write_package(2);
acpigen_write_dword(EWRD_REVISION);
/*
* Emit 'Domain Type' + "Dynamic SAR Enable' + 'Extended SAR sets'
* + number of bytes for Set#2 & 3 & 4
*/
package_size = 1 + 1 + 1 + (NUM_SAR_LIMITS - 1) * BYTES_PER_SAR_LIMIT;
acpigen_write_package(package_size);
acpigen_write_dword(EWRD_DOMAIN_TYPE_WIFI);
acpigen_write_dword(CONFIG(DSAR_ENABLE));
acpigen_write_dword(CONFIG_DSAR_SET_NUM);
for (i = 1; i < NUM_SAR_LIMITS; i++)
for (j = 0; j < BYTES_PER_SAR_LIMIT; j++)
acpigen_write_byte(sar_limits.sar_limit[i][j]);
acpigen_pop_len();
acpigen_pop_len();


if (!CONFIG(GEO_SAR_ENABLE))
return;

/*
* Name ("WGDS", Package() {
* Revision,
* Package() {
* DomainType, // 0x7:WiFi
* WgdsWiFiSarDeltaGroup1PowerMax1, // Group 1 FCC 2400 Max
* WgdsWiFiSarDeltaGroup1PowerChainA1, // Group 1 FCC 2400 A Offset
* WgdsWiFiSarDeltaGroup1PowerChainB1, // Group 1 FCC 2400 B Offset
* WgdsWiFiSarDeltaGroup1PowerMax2, // Group 1 FCC 5200 Max
* WgdsWiFiSarDeltaGroup1PowerChainA2, // Group 1 FCC 5200 A Offset
* WgdsWiFiSarDeltaGroup1PowerChainB2, // Group 1 FCC 5200 B Offset
* WgdsWiFiSarDeltaGroup2PowerMax1, // Group 2 EC Jap 2400 Max
* WgdsWiFiSarDeltaGroup2PowerChainA1, // Group 2 EC Jap 2400 A Offset
* WgdsWiFiSarDeltaGroup2PowerChainB1, // Group 2 EC Jap 2400 B Offset
* WgdsWiFiSarDeltaGroup2PowerMax2, // Group 2 EC Jap 5200 Max
* WgdsWiFiSarDeltaGroup2PowerChainA2, // Group 2 EC Jap 5200 A Offset
* WgdsWiFiSarDeltaGroup2PowerChainB2, // Group 2 EC Jap 5200 B Offset
* WgdsWiFiSarDeltaGroup3PowerMax1, // Group 3 ROW 2400 Max
* WgdsWiFiSarDeltaGroup3PowerChainA1, // Group 3 ROW 2400 A Offset
* WgdsWiFiSarDeltaGroup3PowerChainB1, // Group 3 ROW 2400 B Offset
* WgdsWiFiSarDeltaGroup3PowerMax2, // Group 3 ROW 5200 Max
* WgdsWiFiSarDeltaGroup3PowerChainA2, // Group 3 ROW 5200 A Offset
* WgdsWiFiSarDeltaGroup3PowerChainB2, // Group 3 ROW 5200 B Offset
* }
* })
*/

wgds = &sar_limits.wgds;
acpigen_write_name("WGDS");
acpigen_write_package(2);
acpigen_write_dword(wgds->version);
/* Emit 'Domain Type' +
* Group specific delta of power (6 bytes * NUM_WGDS_SAR_GROUPS)
*/
package_size = sizeof(sar_limits.wgds.group) + 1;
acpigen_write_package(package_size);
acpigen_write_dword(WGDS_DOMAIN_TYPE_WIFI);
for (i = 0; i < SAR_NUM_WGDS_GROUPS; i++) {
acpigen_write_byte(wgds->group[i].power_max_2400mhz);
acpigen_write_byte(wgds->group[i].power_chain_a_2400mhz);
acpigen_write_byte(wgds->group[i].power_chain_b_2400mhz);
acpigen_write_byte(wgds->group[i].power_max_5200mhz);
acpigen_write_byte(wgds->group[i].power_chain_a_5200mhz);
acpigen_write_byte(wgds->group[i].power_chain_b_5200mhz);
}

acpigen_pop_len();
acpigen_pop_len();
}

static void intel_wifi_fill_ssdt(struct device *dev)
{
struct drivers_intel_wifi_config *config = dev->chip_info;
const char *path = acpi_device_path(dev->bus->dev);
u32 address;

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

/* Device */
acpigen_write_scope(path);
acpigen_write_device(acpi_device_name(dev));
acpigen_write_name_integer("_UID", 0);
if (dev->chip_ops)
acpigen_write_name_string("_DDN", dev->chip_ops->name);
struct generic_wifi_config generic_config;

/* Address */
address = PCI_SLOT(dev->path.pci.devfn) & 0xffff;
address <<= 16;
address |= PCI_FUNC(dev->path.pci.devfn) & 0xffff;
acpigen_write_name_dword("_ADR", address);

/* Wake capabilities */
if (config && config->wake)
acpigen_write_PRW(config->wake, 3);

/* Fill regulatory domain structure */
if (CONFIG(HAVE_REGULATORY_DOMAIN)) {
/*
* Name ("WRDD", Package () {
* WRDD_REVISION, // Revision
* Package () {
* WRDD_DOMAIN_TYPE_WIFI, // Domain Type, 7:WiFi
* wifi_regulatory_domain() // Country Identifier
* }
* })
*/
acpigen_write_name("WRDD");
acpigen_write_package(2);
acpigen_write_integer(WRDD_REVISION);
acpigen_write_package(2);
acpigen_write_dword(WRDD_DOMAIN_TYPE_WIFI);
acpigen_write_dword(wifi_regulatory_domain());
acpigen_pop_len();
acpigen_pop_len();
if (config) {
generic_config.wake = config->wake;
/* By default, all intel wifi chips wake from S3 */
generic_config.maxsleep = 3;
}

/* Fill Wifi sar related ACPI structures */
if (CONFIG(USE_SAR))
emit_sar_acpi_structures();

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

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

static const char *intel_wifi_acpi_name(const struct device *dev)
{
return "WIFI";
generic_wifi_fill_ssdt(dev, config ? &generic_config : NULL);
}
#endif

Expand Down Expand Up @@ -282,7 +103,7 @@ struct device_operations device_ops = {
#endif
.ops_pci = &pci_ops,
#if CONFIG(HAVE_ACPI_TABLES)
.acpi_name = intel_wifi_acpi_name,
.acpi_name = generic_wifi_acpi_name,
.acpi_fill_ssdt_generator = intel_wifi_fill_ssdt,
#endif
};
Expand Down
11 changes: 11 additions & 0 deletions src/drivers/ipmi/chip.h
Expand Up @@ -24,6 +24,17 @@ struct drivers_ipmi_config {
u8 gpe_interrupt;
u8 have_apic;
u32 apic_interrupt;
/*
* Wait for BMC to boot.
* This can be used if the BMC takes a long time to boot after PoR:
* AST2400 on Supermicro X11SSH: 34 s
*/
bool wait_for_bmc;
/*
* The timeout in seconds to wait for the IPMI service to be loaded.
* Will be used if wait_for_bmc is true.
*/
u16 bmc_boot_timeout;
};

#endif /* _IMPI_CHIP_H_ */
26 changes: 26 additions & 0 deletions src/drivers/ipmi/ipmi_kcs_ops.c
Expand Up @@ -32,6 +32,7 @@
#endif
#include <version.h>
#include <delay.h>
#include <timer.h>
#include "ipmi_kcs.h"
#include "chip.h"

Expand Down Expand Up @@ -62,12 +63,37 @@ static void ipmi_kcs_init(struct device *dev)
{
struct ipmi_devid_rsp rsp;
uint32_t man_id = 0, prod_id = 0;
struct drivers_ipmi_config *conf = NULL;

if (!dev->enabled)
return;

printk(BIOS_DEBUG, "IPMI: PNP KCS 0x%x\n", dev->path.pnp.port);

if (dev->chip_info)
conf = dev->chip_info;

/* Get IPMI version for ACPI and SMBIOS */
if (conf && conf->wait_for_bmc && conf->bmc_boot_timeout) {
struct stopwatch sw;
stopwatch_init_msecs_expire(&sw, conf->bmc_boot_timeout * 1000);
printk(BIOS_DEBUG, "IPMI: Waiting for BMC...\n");

while (!stopwatch_expired(&sw)) {
if (inb(dev->path.pnp.port) != 0xff)
break;
mdelay(100);
}
if (stopwatch_expired(&sw)) {
printk(BIOS_INFO, "IPMI: Waiting for BMC timed out\n");
/* Don't write tables if communication failed */
dev->enabled = 0;
return;
}
}

if (!ipmi_get_device_id(dev, &rsp)) {
/* Queried the IPMI revision from BMC */
ipmi_revision_minor = IPMI_IPMI_VERSION_MINOR(rsp.ipmi_version);
ipmi_revision_major = IPMI_IPMI_VERSION_MAJOR(rsp.ipmi_version);

Expand Down
14 changes: 13 additions & 1 deletion src/drivers/pc80/pc/Kconfig
@@ -1,10 +1,11 @@
if PC80_SYSTEM

# Might be removed (alongside with the PS/2 init code) once payloads
# reliably support PS/2 init themselves.

config DRIVERS_PS2_KEYBOARD
bool "PS/2 keyboard init"
default n
depends on PC80_SYSTEM
help
Enable this option to initialize PS/2 keyboards found connected
to the PS/2 port.
Expand All @@ -16,3 +17,14 @@ config DRIVERS_PS2_KEYBOARD
If you know you will only use a payload which does not require
this option, then you can say N here to speed up boot time.
Otherwise say Y.

config UDELAY_IO
bool
default n

# This option is used in code but never selected.
config UDELAY_TIMER2
bool
default n

endif
3 changes: 2 additions & 1 deletion src/drivers/spi/adesto.c
Expand Up @@ -181,7 +181,8 @@ static int adesto_write(const struct spi_flash *flash, u32 offset, size_t len,
goto out;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
goto out;

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/amic.c
Expand Up @@ -155,7 +155,8 @@ static int amic_write(const struct spi_flash *flash, u32 offset, size_t len,
goto out;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
goto out;

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/atmel.c
Expand Up @@ -137,7 +137,8 @@ static int atmel_write(const struct spi_flash *flash, u32 offset, size_t len,
goto out;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
goto out;

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/eon.c
Expand Up @@ -270,7 +270,8 @@ static int eon_write(const struct spi_flash *flash,
goto out;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret) {
printk(BIOS_WARNING, "SF: EON Page Program timeout\n");
goto out;
Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/gigadevice.c
Expand Up @@ -212,7 +212,8 @@ static int gigadevice_write(const struct spi_flash *flash, u32 offset,
goto out;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
goto out;

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/macronix.c
Expand Up @@ -249,7 +249,8 @@ static int macronix_write(const struct spi_flash *flash, u32 offset, size_t len,
break;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
break;

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/spansion.c
Expand Up @@ -264,7 +264,8 @@ static int spansion_write(const struct spi_flash *flash, u32 offset, size_t len,
break;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
break;

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/spi_flash.c
Expand Up @@ -245,7 +245,8 @@ int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len)
if (ret)
goto out;

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PAGE_ERASE_TIMEOUT_MS);
if (ret)
goto out;
}
Expand Down
9 changes: 0 additions & 9 deletions src/drivers/spi/spi_flash_internal.h
Expand Up @@ -7,15 +7,6 @@
#ifndef SPI_FLASH_INTERNAL_H
#define SPI_FLASH_INTERNAL_H

/* Common parameters -- kind of high, but they should only occur when there
* is a problem (and well your system already is broken), so err on the side
* of caution in case we're dealing with slower SPI buses and/or processors.
*/
#define CONF_SYS_HZ 100
#define SPI_FLASH_PROG_TIMEOUT (2 * CONF_SYS_HZ)
#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONF_SYS_HZ)
#define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONF_SYS_HZ)

/* Common commands */
#define CMD_READ_ID 0x9f

Expand Down
8 changes: 5 additions & 3 deletions src/drivers/spi/sst.c
Expand Up @@ -179,7 +179,7 @@ sst_byte_write(const struct spi_flash *flash, u32 offset, const void *buf)
if (ret)
return ret;

return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT_MS);
}

static int sst_write_256(const struct spi_flash *flash, u32 offset, size_t len,
Expand Down Expand Up @@ -239,7 +239,8 @@ static int sst_write_256(const struct spi_flash *flash, u32 offset, size_t len,
break;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
break;

Expand Down Expand Up @@ -294,7 +295,8 @@ static int sst_write_ai(const struct spi_flash *flash, u32 offset, size_t len,
break;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
break;

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/stmicro.c
Expand Up @@ -331,7 +331,8 @@ static int stmicro_write(const struct spi_flash *flash,
goto out;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
goto out;

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/spi/winbond.c
Expand Up @@ -326,7 +326,8 @@ static int winbond_write(const struct spi_flash *flash, u32 offset, size_t len,
goto out;
}

ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
ret = spi_flash_cmd_wait_ready(flash,
SPI_FLASH_PROG_TIMEOUT_MS);
if (ret)
goto out;

Expand Down
57 changes: 57 additions & 0 deletions src/drivers/wifi/Kconfig
@@ -0,0 +1,57 @@
config DRIVERS_GENERIC_WIFI
bool
default n
depends on HAVE_ACPI_TABLES
help
When enabled, add identifiers in ACPI tables that are common
to WiFi chipsets from multiple vendors.

if DRIVERS_GENERIC_WIFI

config USE_SAR
bool
default n
help
Enable it when wifi driver uses SAR configuration feature.
VPD entry "wifi_sar" is read to get SAR settings, if its
not found driver may look into CBFS for default settigs.
WIFI_SAR_CBFS is option to enable CBFS lookup.

config SAR_ENABLE
bool
default n
depends on USE_SAR

config DSAR_ENABLE
bool
default n
depends on USE_SAR

config GEO_SAR_ENABLE
bool
default n
depends on USE_SAR

config WIFI_SAR_CBFS
bool "Enable SAR table addition to CBFS"
default n
depends on USE_SAR
help
wifi driver would look for "wifi_sar" vpd key and load SAR settings from
it, if the vpd key is not found then the driver tries to look for sar
settings from CBFS with file name wifi_sar_defaults.hex.
So OEM/ODM can override wifi sar with VPD.

config WIFI_SAR_CBFS_FILEPATH
string "The cbfs file which has WIFI SAR defaults"
depends on WIFI_SAR_CBFS
default "src/mainboard/$(MAINBOARDDIR)/wifi_sar_defaults.hex"

config DSAR_SET_NUM
hex "Number of SAR sets when D-SAR is enabled"
default 0x3
depends on USE_SAR
help
There can be up to 3 optional SAR table sets.

endif # DRIVERS_GENERIC_WIFI
1 change: 1 addition & 0 deletions src/drivers/wifi/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_GENERIC_WIFI) += generic.c