haswell: unify romstage logic

This commit pulls in all the common logic for romstage into
the Haswell cpu directory. The bits specific to the mainboard
still reside under their respective directories. The calling
sequence bounces from the cpu directory to mainboard then back
to the cpu directory. The reasoning is that Haswell systems use
cache-as-ram for backing memory in romstage. The stack is used to
allocate structures. However, now changes can be made to the
romstage for Haswell and apply to all boards.

Change-Id: I2bf08013c46a99235ffe4bde88a935c3378eb341
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/2754
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
Aaron Durbin 2013-02-06 21:41:01 -06:00 committed by Ronald G. Minnich
parent 9b7f9b9768
commit a267161362
5 changed files with 176 additions and 383 deletions

View File

@ -103,7 +103,16 @@
#ifndef __ROMCC__ #ifndef __ROMCC__
#if defined(__PRE_RAM__) #if defined(__PRE_RAM__)
void romstage_main(unsigned long bist); struct pei_data;
struct rcba_config_instruction;
struct romstage_params {
struct pei_data *pei_data;
const void *gpio_map;
const struct rcba_config_instruction *rcba_config;
unsigned long bist;
};
void mainboard_romstage_entry(unsigned long bist);
void romstage_common(const struct romstage_params *params);
#endif #endif
#ifdef __SMM__ #ifdef __SMM__

View File

@ -20,9 +20,32 @@
#include <stdint.h> #include <stdint.h>
#include <cbmem.h> #include <cbmem.h>
#include <console/console.h> #include <console/console.h>
#include <arch/cpu.h>
#include <cpu/x86/bist.h>
#include <cpu/x86/msr.h>
#include <lib.h>
#include <timestamp.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <device/pci_def.h>
#include <cpu/x86/lapic.h>
#include <cbmem.h>
#if CONFIG_CHROMEOS
#include <vendorcode/google/chromeos/chromeos.h>
#endif
#include "haswell.h"
#include "northbridge/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/raminit.h"
#include "southbridge/intel/lynxpoint/pch.h"
#include "southbridge/intel/lynxpoint/me.h"
/* Mainboard needs to supply this symbol. */
extern void romstage_main(unsigned long bist); /* The cache-as-ram assembly file calls main() after setting up cache-as-ram.
* main() will then call the mainboards's mainboard_romstage_entry() function.
* That function then calls romstage_common() below. The reason for the back
* and forth is to provide common entry point from cache-as-ram while still
* allowing for code sharing. Because we can't use global variables the stack
* is used for allocations -- thus the need to call back and forth. */
void main(unsigned long bist) void main(unsigned long bist)
{ {
@ -37,7 +60,7 @@ void main(unsigned long bist)
for (i = 0; i < num_guards; i++) for (i = 0; i < num_guards; i++)
stack_base[i] = stack_guard; stack_base[i] = stack_guard;
romstage_main(bist); mainboard_romstage_entry(bist);
/* Check the stack. */ /* Check the stack. */
for (i = 0; i < num_guards; i++) { for (i = 0; i < num_guards; i++) {
@ -51,3 +74,116 @@ void main(unsigned long bist)
cbmemc_reinit(); cbmemc_reinit();
#endif #endif
} }
void romstage_common(const struct romstage_params *params)
{
int boot_mode = 0;
int wake_from_s3;
int cbmem_was_initted;
#if CONFIG_COLLECT_TIMESTAMPS
tsc_t start_romstage_time;
tsc_t before_dram_time;
tsc_t after_dram_time;
tsc_t base_time = {
.lo = pci_read_config32(PCI_DEV(0, 0x00, 0), 0xdc),
.hi = pci_read_config32(PCI_DEV(0, 0x1f, 2), 0xd0)
};
#endif
#if CONFIG_COLLECT_TIMESTAMPS
start_romstage_time = rdtsc();
#endif
if (params->bist == 0)
enable_lapic();
wake_from_s3 = early_pch_init(params->gpio_map, params->rcba_config);
/* Halt if there was a built in self test failure */
report_bist_failure(params->bist);
/* Perform some early chipset initialization required
* before RAM initialization can work
*/
haswell_early_initialization(HASWELL_MOBILE);
printk(BIOS_DEBUG, "Back from haswell_early_initialization()\n");
if (wake_from_s3) {
#if CONFIG_HAVE_ACPI_RESUME
printk(BIOS_DEBUG, "Resume from S3 detected.\n");
boot_mode = 2;
#else
printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
#endif
}
/* Prepare USB controller early in S3 resume */
if (boot_mode == 2)
enable_usb_bar();
post_code(0x3a);
params->pei_data->boot_mode = boot_mode;
#if CONFIG_COLLECT_TIMESTAMPS
before_dram_time = rdtsc();
#endif
report_platform_info();
sdram_initialize(params->pei_data);
#if CONFIG_COLLECT_TIMESTAMPS
after_dram_time = rdtsc();
#endif
post_code(0x3b);
intel_early_me_status();
quick_ram_check();
post_code(0x3e);
#if CONFIG_EARLY_CBMEM_INIT
cbmem_was_initted = !cbmem_initialize();
#else
cbmem_was_initted = cbmem_reinit((uint64_t) (get_top_of_ram()
- HIGH_MEMORY_SIZE));
#endif
#if CONFIG_HAVE_ACPI_RESUME
/* If there is no high memory area, we didn't boot before, so
* this is not a resume. In that case we just create the cbmem toc.
*/
*(u32 *)CBMEM_BOOT_MODE = 0;
*(u32 *)CBMEM_RESUME_BACKUP = 0;
if ((boot_mode == 2) && cbmem_was_initted) {
void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
if (resume_backup_memory) {
*(u32 *)CBMEM_BOOT_MODE = boot_mode;
*(u32 *)CBMEM_RESUME_BACKUP = (u32)resume_backup_memory;
}
/* Magic for S3 resume */
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafed00d);
} else if (boot_mode == 2) {
/* Failed S3 resume, reset to come up cleanly */
outb(0x6, 0xcf9);
while (1) {
hlt();
}
} else {
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafebabe);
}
#endif
post_code(0x3f);
#if CONFIG_CHROMEOS
init_chromeos(boot_mode);
#endif
#if CONFIG_COLLECT_TIMESTAMPS
timestamp_init(base_time);
timestamp_add(TS_START_ROMSTAGE, start_romstage_time );
timestamp_add(TS_BEFORE_INITRAM, before_dram_time );
timestamp_add(TS_AFTER_INITRAM, after_dram_time );
timestamp_add_now(TS_END_ROMSTAGE);
#endif
}

View File

@ -19,29 +19,12 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <lib.h>
#include <timestamp.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <device/pci_def.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include <pc80/mc146818rtc.h>
#include <cbmem.h>
#include <console/console.h> #include <console/console.h>
#include "cpu/intel/haswell/haswell.h" #include "cpu/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/haswell.h" #include "northbridge/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/raminit.h" #include "northbridge/intel/haswell/raminit.h"
#include "southbridge/intel/lynxpoint/pch.h" #include "southbridge/intel/lynxpoint/pch.h"
#include "southbridge/intel/lynxpoint/me.h"
#include <arch/cpu.h>
#include <cpu/x86/bist.h>
#include <cpu/x86/msr.h>
#include "gpio.h" #include "gpio.h"
#if CONFIG_CHROMEOS
#include <vendorcode/google/chromeos/chromeos.h>
#endif
const struct rcba_config_instruction rcba_config[] = { const struct rcba_config_instruction rcba_config[] = {
/* /*
@ -83,21 +66,8 @@ const struct rcba_config_instruction rcba_config[] = {
RCBA_END_CONFIG, RCBA_END_CONFIG,
}; };
void romstage_main(unsigned long bist) void mainboard_romstage_entry(unsigned long bist)
{ {
int boot_mode = 0;
int wake_from_s3;
int cbmem_was_initted;
#if CONFIG_COLLECT_TIMESTAMPS
tsc_t start_romstage_time;
tsc_t before_dram_time;
tsc_t after_dram_time;
tsc_t base_time = {
.lo = pci_read_config32(PCI_DEV(0, 0x00, 0), 0xdc),
.hi = pci_read_config32(PCI_DEV(0, 0x1f, 2), 0xd0)
};
#endif
struct pei_data pei_data = { struct pei_data pei_data = {
pei_version: PEI_VERSION, pei_version: PEI_VERSION,
mchbar: DEFAULT_MCHBAR, mchbar: DEFAULT_MCHBAR,
@ -141,101 +111,13 @@ void romstage_main(unsigned long bist)
}, },
}; };
#if CONFIG_COLLECT_TIMESTAMPS struct romstage_params romstage_params = {
start_romstage_time = rdtsc(); .pei_data = &pei_data,
#endif .gpio_map = &mainboard_gpio_map,
.rcba_config = &rcba_config[0],
.bist = bist,
};
if (bist == 0) /* Call into the real romstage main with this board's attributes. */
enable_lapic(); romstage_common(&romstage_params);
wake_from_s3 = early_pch_init(&mainboard_gpio_map, &rcba_config[0]);
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
/* Perform some early chipset initialization required
* before RAM initialization can work
*/
haswell_early_initialization(HASWELL_MOBILE);
printk(BIOS_DEBUG, "Back from haswell_early_initialization()\n");
if (wake_from_s3) {
#if CONFIG_HAVE_ACPI_RESUME
printk(BIOS_DEBUG, "Resume from S3 detected.\n");
boot_mode = 2;
#else
printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
#endif
}
/* Prepare USB controller early in S3 resume */
if (boot_mode == 2)
enable_usb_bar();
post_code(0x3a);
pei_data.boot_mode = boot_mode;
#if CONFIG_COLLECT_TIMESTAMPS
before_dram_time = rdtsc();
#endif
report_platform_info();
sdram_initialize(&pei_data);
#if CONFIG_COLLECT_TIMESTAMPS
after_dram_time = rdtsc();
#endif
post_code(0x3b);
intel_early_me_status();
quick_ram_check();
post_code(0x3e);
MCHBAR16(SSKPD) = 0xCAFE;
#if CONFIG_EARLY_CBMEM_INIT
cbmem_was_initted = !cbmem_initialize();
#else
cbmem_was_initted = cbmem_reinit((uint64_t) (get_top_of_ram()
- HIGH_MEMORY_SIZE));
#endif
#if CONFIG_HAVE_ACPI_RESUME
/* If there is no high memory area, we didn't boot before, so
* this is not a resume. In that case we just create the cbmem toc.
*/
*(u32 *)CBMEM_BOOT_MODE = 0;
*(u32 *)CBMEM_RESUME_BACKUP = 0;
if ((boot_mode == 2) && cbmem_was_initted) {
void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
if (resume_backup_memory) {
*(u32 *)CBMEM_BOOT_MODE = boot_mode;
*(u32 *)CBMEM_RESUME_BACKUP = (u32)resume_backup_memory;
}
/* Magic for S3 resume */
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafed00d);
} else if (boot_mode == 2) {
/* Failed S3 resume, reset to come up cleanly */
outb(0x6, 0xcf9);
while (1) {
hlt();
}
} else {
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafebabe);
}
#endif
post_code(0x3f);
#if CONFIG_CHROMEOS
init_chromeos(boot_mode);
#endif
#if CONFIG_COLLECT_TIMESTAMPS
timestamp_init(base_time);
timestamp_add(TS_START_ROMSTAGE, start_romstage_time );
timestamp_add(TS_BEFORE_INITRAM, before_dram_time );
timestamp_add(TS_AFTER_INITRAM, after_dram_time );
timestamp_add_now(TS_END_ROMSTAGE);
#endif
} }

View File

@ -19,30 +19,13 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <lib.h>
#include <timestamp.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <device/pci_def.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include <pc80/mc146818rtc.h>
#include <cbmem.h>
#include <console/console.h> #include <console/console.h>
#include "cpu/intel/haswell/haswell.h" #include "cpu/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/haswell.h" #include "northbridge/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/raminit.h" #include "northbridge/intel/haswell/raminit.h"
#include "southbridge/intel/lynxpoint/me.h"
#include "southbridge/intel/lynxpoint/pch.h" #include "southbridge/intel/lynxpoint/pch.h"
#include "southbridge/intel/lynxpoint/lp_gpio.h" #include "southbridge/intel/lynxpoint/lp_gpio.h"
#include <arch/cpu.h>
#include <cpu/x86/bist.h>
#include <cpu/x86/msr.h>
#include "gpio.h" #include "gpio.h"
#if CONFIG_CHROMEOS
#include <vendorcode/google/chromeos/chromeos.h>
#endif
const struct rcba_config_instruction rcba_config[] = { const struct rcba_config_instruction rcba_config[] = {
@ -88,21 +71,8 @@ const struct rcba_config_instruction rcba_config[] = {
RCBA_END_CONFIG, RCBA_END_CONFIG,
}; };
void romstage_main(unsigned long bist) void mainboard_romstage_entry(unsigned long bist)
{ {
int boot_mode = 0;
int wake_from_s3;
int cbmem_was_initted;
#if CONFIG_COLLECT_TIMESTAMPS
tsc_t start_romstage_time;
tsc_t before_dram_time;
tsc_t after_dram_time;
tsc_t base_time = {
.lo = pci_read_config32(PCI_DEV(0, 0x00, 0), 0xdc),
.hi = pci_read_config32(PCI_DEV(0, 0x1f, 2), 0xd0)
};
#endif
struct pei_data pei_data = { struct pei_data pei_data = {
pei_version: PEI_VERSION, pei_version: PEI_VERSION,
mchbar: DEFAULT_MCHBAR, mchbar: DEFAULT_MCHBAR,
@ -146,100 +116,13 @@ void romstage_main(unsigned long bist)
}, },
}; };
#if CONFIG_COLLECT_TIMESTAMPS struct romstage_params romstage_params = {
start_romstage_time = rdtsc(); .pei_data = &pei_data,
#endif .gpio_map = &mainboard_gpio_map,
.rcba_config = &rcba_config[0],
.bist = bist,
};
if (bist == 0) /* Call into the real romstage main with this board's attributes. */
enable_lapic(); romstage_common(&romstage_params);
wake_from_s3 = early_pch_init(&mainboard_gpio_map, &rcba_config[0]);
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
/* Perform some early chipset initialization required
* before RAM initialization can work
*/
haswell_early_initialization(HASWELL_MOBILE);
printk(BIOS_DEBUG, "Back from haswell_early_initialization()\n");
if (wake_from_s3) {
#if CONFIG_HAVE_ACPI_RESUME
printk(BIOS_DEBUG, "Resume from S3 detected.\n");
boot_mode = 2;
#else
printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
#endif
}
/* Prepare USB controller early in S3 resume */
if (boot_mode == 2)
enable_usb_bar();
post_code(0x3a);
pei_data.boot_mode = boot_mode;
#if CONFIG_COLLECT_TIMESTAMPS
before_dram_time = rdtsc();
#endif
report_platform_info();
sdram_initialize(&pei_data);
#if CONFIG_COLLECT_TIMESTAMPS
after_dram_time = rdtsc();
#endif
post_code(0x3b);
intel_early_me_status();
quick_ram_check();
post_code(0x3e);
MCHBAR16(SSKPD) = 0xCAFE;
#if CONFIG_EARLY_CBMEM_INIT
cbmem_was_initted = !cbmem_initialize();
#else
cbmem_was_initted = cbmem_reinit((uint64_t) (get_top_of_ram()
- HIGH_MEMORY_SIZE));
#endif
#if CONFIG_HAVE_ACPI_RESUME
/* If there is no high memory area, we didn't boot before, so
* this is not a resume. In that case we just create the cbmem toc.
*/
*(u32 *)CBMEM_BOOT_MODE = 0;
*(u32 *)CBMEM_RESUME_BACKUP = 0;
if ((boot_mode == 2) && cbmem_was_initted) {
void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
if (resume_backup_memory) {
*(u32 *)CBMEM_BOOT_MODE = boot_mode;
*(u32 *)CBMEM_RESUME_BACKUP = (u32)resume_backup_memory;
}
/* Magic for S3 resume */
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafed00d);
} else if (boot_mode == 2) {
/* Failed S3 resume, reset to come up cleanly */
outb(0x6, 0xcf9);
while (1) {
hlt();
}
} else {
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafebabe);
}
#endif
post_code(0x3f);
#if CONFIG_CHROMEOS
init_chromeos(boot_mode);
#endif
#if CONFIG_COLLECT_TIMESTAMPS
timestamp_init(base_time);
timestamp_add(TS_START_ROMSTAGE, start_romstage_time );
timestamp_add(TS_BEFORE_INITRAM, before_dram_time );
timestamp_add(TS_AFTER_INITRAM, after_dram_time );
timestamp_add_now(TS_END_ROMSTAGE);
#endif
} }

View File

@ -19,30 +19,13 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <lib.h>
#include <timestamp.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <device/pci_def.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include <pc80/mc146818rtc.h>
#include <cbmem.h>
#include <console/console.h> #include <console/console.h>
#include "cpu/intel/haswell/haswell.h" #include "cpu/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/haswell.h" #include "northbridge/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/raminit.h" #include "northbridge/intel/haswell/raminit.h"
#include "southbridge/intel/lynxpoint/me.h"
#include "southbridge/intel/lynxpoint/pch.h" #include "southbridge/intel/lynxpoint/pch.h"
#include "southbridge/intel/lynxpoint/lp_gpio.h" #include "southbridge/intel/lynxpoint/lp_gpio.h"
#include <arch/cpu.h>
#include <cpu/x86/bist.h>
#include <cpu/x86/msr.h>
#include "gpio.h" #include "gpio.h"
#if CONFIG_CHROMEOS
#include <vendorcode/google/chromeos/chromeos.h>
#endif
const struct rcba_config_instruction rcba_config[] = { const struct rcba_config_instruction rcba_config[] = {
@ -88,21 +71,8 @@ const struct rcba_config_instruction rcba_config[] = {
RCBA_END_CONFIG, RCBA_END_CONFIG,
}; };
void romstage_main(unsigned long bist) void mainboard_romstage_entry(unsigned long bist)
{ {
int boot_mode = 0;
int wake_from_s3;
int cbmem_was_initted;
#if CONFIG_COLLECT_TIMESTAMPS
tsc_t start_romstage_time;
tsc_t before_dram_time;
tsc_t after_dram_time;
tsc_t base_time = {
.lo = pci_read_config32(PCI_DEV(0, 0x00, 0), 0xdc),
.hi = pci_read_config32(PCI_DEV(0, 0x1f, 2), 0xd0)
};
#endif
struct pei_data pei_data = { struct pei_data pei_data = {
pei_version: PEI_VERSION, pei_version: PEI_VERSION,
mchbar: DEFAULT_MCHBAR, mchbar: DEFAULT_MCHBAR,
@ -146,100 +116,13 @@ void romstage_main(unsigned long bist)
}, },
}; };
#if CONFIG_COLLECT_TIMESTAMPS struct romstage_params romstage_params = {
start_romstage_time = rdtsc(); .pei_data = &pei_data,
#endif .gpio_map = &mainboard_gpio_map,
.rcba_config = &rcba_config[0],
.bist = bist,
};
if (bist == 0) /* Call into the real romstage main with this board's attributes. */
enable_lapic(); romstage_common(&romstage_params);
wake_from_s3 = early_pch_init(&mainboard_gpio_map, &rcba_config[0]);
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
/* Perform some early chipset initialization required
* before RAM initialization can work
*/
haswell_early_initialization(HASWELL_MOBILE);
printk(BIOS_DEBUG, "Back from haswell_early_initialization()\n");
if (wake_from_s3) {
#if CONFIG_HAVE_ACPI_RESUME
printk(BIOS_DEBUG, "Resume from S3 detected.\n");
boot_mode = 2;
#else
printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
#endif
}
/* Prepare USB controller early in S3 resume */
if (boot_mode == 2)
enable_usb_bar();
post_code(0x3a);
pei_data.boot_mode = boot_mode;
#if CONFIG_COLLECT_TIMESTAMPS
before_dram_time = rdtsc();
#endif
report_platform_info();
sdram_initialize(&pei_data);
#if CONFIG_COLLECT_TIMESTAMPS
after_dram_time = rdtsc();
#endif
post_code(0x3b);
intel_early_me_status();
quick_ram_check();
post_code(0x3e);
MCHBAR16(SSKPD) = 0xCAFE;
#if CONFIG_EARLY_CBMEM_INIT
cbmem_was_initted = !cbmem_initialize();
#else
cbmem_was_initted = cbmem_reinit((uint64_t) (get_top_of_ram()
- HIGH_MEMORY_SIZE));
#endif
#if CONFIG_HAVE_ACPI_RESUME
/* If there is no high memory area, we didn't boot before, so
* this is not a resume. In that case we just create the cbmem toc.
*/
*(u32 *)CBMEM_BOOT_MODE = 0;
*(u32 *)CBMEM_RESUME_BACKUP = 0;
if ((boot_mode == 2) && cbmem_was_initted) {
void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
if (resume_backup_memory) {
*(u32 *)CBMEM_BOOT_MODE = boot_mode;
*(u32 *)CBMEM_RESUME_BACKUP = (u32)resume_backup_memory;
}
/* Magic for S3 resume */
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafed00d);
} else if (boot_mode == 2) {
/* Failed S3 resume, reset to come up cleanly */
outb(0x6, 0xcf9);
while (1) {
hlt();
}
} else {
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafebabe);
}
#endif
post_code(0x3f);
#if CONFIG_CHROMEOS
init_chromeos(boot_mode);
#endif
#if CONFIG_COLLECT_TIMESTAMPS
timestamp_init(base_time);
timestamp_add(TS_START_ROMSTAGE, start_romstage_time );
timestamp_add(TS_BEFORE_INITRAM, before_dram_time );
timestamp_add(TS_AFTER_INITRAM, after_dram_time );
timestamp_add_now(TS_END_ROMSTAGE);
#endif
} }