Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2788
-gerrit
commit 073a197607a06c585c92393bf20ee4bd482b5836
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Feb 8 17:05:36 2013 -0600
rmodule: add ability to calculate module placement
There is a need to calculate the proper placement for an rmodule
in memory. e.g. loading a compressed rmodule from flash into ram
can be an issue. Determining the placement is hard since the header
is not readable until it is decompressed so choosing the wrong location
may require a memmove() after decompression. This patch provides
a function to perform this calculation by finding region below a given
address while making an assumption on the size of the rmodule header..
Change-Id: I2703438f58ae847ed6e80b58063ff820fbcfcbc0
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/include/rmodule.h | 8 ++++++++
src/lib/rmodule.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/src/include/rmodule.h b/src/include/rmodule.h
index 89310c9..e8e7636 100644
--- a/src/include/rmodule.h
+++ b/src/include/rmodule.h
@@ -20,6 +20,7 @@
#define RMODULE_H
#include <stdint.h>
+#include <stddef.h>
#define RMODULE_MAGIC 0xf8fe
#define RMODULE_VERSION_1 1
@@ -41,6 +42,13 @@ int rmodule_memory_size(const struct rmodule *m);
int rmodule_load(void *loc, struct rmodule *m);
int rmodule_load_no_clear_bss(void *base, struct rmodule *m);
int rmodule_load_alignment(const struct rmodule *m);
+/* Returns the an aligned pointer that reflects a region used below addr
+ * based on the rmodule_size. i.e. the returned pointer up to addr is memory
+ * that may be utilized by the rmodule. program_start and rmodule_start
+ * are pointers updated to reflect where the rmodule program starts and where
+ * the rmodule (including header) should be placed respectively. */
+void *rmodule_find_region_below(void *addr, size_t rmodule_size,
+ void **program_start, void **rmodule_start);
#define FIELD_ENTRY(x_) ((u32)&x_)
#define RMODULE_HEADER(entry_, type_) \
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 6da7a6e..60c89f0 100644
--- a/src/lib/rmodule.c
+++ b/src/lib/rmodule.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#include <console/console.h>
#include <rmodule.h>
@@ -165,6 +166,12 @@ static void rmodule_copy_payload(const struct rmodule *module)
"filesize: 0x%x memsize: 0x%x\n",
module->location, rmodule_entry(module),
module->payload_size, rmodule_memory_size(module));
+
+ /* No need to copy the payload if the load location and the
+ * payload location are the same. */
+ if (module->location == module->payload)
+ return;
+
memcpy(module->location, module->payload, module->payload_size);
}
@@ -253,3 +260,48 @@ int rmodule_load_no_clear_bss(void *base, struct rmodule *module)
{
return __rmodule_load(base, module, 0);
}
+
+void *rmodule_find_region_below(void *addr, size_t rmodule_size,
+ void **program_start, void **rmodule_start)
+{
+ unsigned long ceiling;
+ unsigned long program_base;
+ unsigned long placement_loc;
+ unsigned long program_begin;
+
+ ceiling = (unsigned long)addr;
+ /* Place the rmodule just under the ceiling. The rmodule files
+ * themselves are packed as a header and a payload, however the rmodule
+ * itself is linked along with the header. The header starts at address
+ * 0. Immediately following the header in the file is the program,
+ * however its starting address is determined by the rmodule linker
+ * script. In short, sizeof(struct rmodule_header) can be less than
+ * or equal to the linked address of the program. Therefore we want
+ * to place the rmodule so that the prgoram falls on the aligned
+ * address with the header just before it. Therefore, we need at least
+ * a page to account for the size of the header. */
+ program_base = ALIGN((ceiling - (rmodule_size + 4096)), 4096);
+ /* The program starts immediately after the header. However,
+ * it needs to be aligned to a 4KiB boundary. Therefore, adjust the
+ * program location so that the program lands on a page boundary. The
+ * layout looks like the following:
+ *
+ * +--------------------------------+ ceiling
+ * | >= 0 bytes from alignment |
+ * +--------------------------------+ program end (4KiB aligned)
+ * | program size |
+ * +--------------------------------+ program_begin (4KiB aligned)
+ * | sizeof(struct rmodule_header) |
+ * +--------------------------------+ rmodule header start
+ * | >= 0 bytes from alignment |
+ * +--------------------------------+ program_base (4KiB aligned)
+ */
+ placement_loc = ALIGN(program_base + sizeof(struct rmodule_header),
+ 4096) - sizeof(struct rmodule_header);
+ program_begin = placement_loc + sizeof(struct rmodule_header);
+
+ *program_start = (void *)program_begin;
+ *rmodule_start = (void *)placement_loc;
+
+ return (void *)program_base;
+}
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2787
-gerrit
commit 0419e53ce6e0d08e34559ea70f5c85001b5ad400
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Feb 7 02:13:50 2013 -0600
rmodule: add bss clearing option to API
There are circumstances where the loader should not clear the bss. For
example, the ramstage clears its own bss. There is no sense in clearing
the bss twice. Therefore, allow the loader to optionally clear the bss
by adding a function that does not clear the bss.
Change-Id: Ic0a3f439b6289c680d3c3afc17e866d935c9f29f
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/include/rmodule.h | 1 +
src/lib/rmodule.c | 14 ++++++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/include/rmodule.h b/src/include/rmodule.h
index 5300c63..89310c9 100644
--- a/src/include/rmodule.h
+++ b/src/include/rmodule.h
@@ -39,6 +39,7 @@ void *rmodule_entry(const struct rmodule *m);
int rmodule_entry_offset(const struct rmodule *m);
int rmodule_memory_size(const struct rmodule *m);
int rmodule_load(void *loc, struct rmodule *m);
+int rmodule_load_no_clear_bss(void *base, struct rmodule *m);
int rmodule_load_alignment(const struct rmodule *m);
#define FIELD_ENTRY(x_) ((u32)&x_)
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 56d7c6d..6da7a6e 100644
--- a/src/lib/rmodule.c
+++ b/src/lib/rmodule.c
@@ -228,7 +228,7 @@ int rmodule_load_alignment(const struct rmodule *module)
return module->header->module_link_start_address;
}
-int rmodule_load(void *base, struct rmodule *module)
+static int __rmodule_load(void *base, struct rmodule *module, int clear_bss)
{
/*
* In order to load the module at a given address, the following steps
@@ -239,7 +239,17 @@ int rmodule_load(void *base, struct rmodule *module)
*/
module->location = base;
rmodule_copy_payload(module);
- rmodule_clear_bss(module);
+ if (clear_bss)
+ rmodule_clear_bss(module);
return rmodule_relocate(module);
}
+int rmodule_load(void *base, struct rmodule *module)
+{
+ return __rmodule_load(base, module, 1);
+}
+
+int rmodule_load_no_clear_bss(void *base, struct rmodule *module)
+{
+ return __rmodule_load(base, module, 0);
+}
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2786
-gerrit
commit 58e2e5b399791b0a5a5a543de8e5a27ebfeb5850
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Wed Feb 6 15:47:31 2013 -0600
rmodule: add ramstage support
Coreboot's ramstage defines certain sections/symbols in its fixed
static linker script. It uses these sections/symbols for locating the
drivers as well as its own program information. Add these sections
and symbols to the rmodule linker script so that ramstage can be
linked as an rmodule. These sections and symbols are a noop for other
rmodule-linked programs, but they are vital to the ramstage.
Also add a comment in coreboot_ram.ld to mirror any changes made there
to the rmodule linker script.
Change-Id: Ib9885a00e987aef0ee1ae34f1d73066e15bca9b1
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/arch/x86/coreboot_ram.ld | 5 +++++
src/include/rmodule.h | 9 +++++----
src/lib/rmodule.ld | 28 +++++++++++++++++++++++++---
3 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/src/arch/x86/coreboot_ram.ld b/src/arch/x86/coreboot_ram.ld
index d9f0909..2dd51d5 100644
--- a/src/arch/x86/coreboot_ram.ld
+++ b/src/arch/x86/coreboot_ram.ld
@@ -50,6 +50,10 @@ SECTIONS
.rodata : {
_rodata = .;
. = ALIGN(4);
+
+ /* If any changes are made to the driver start/symbols or the
+ * section names the equivalent changes need to made to
+ * rmodule.ld. */
console_drivers = .;
*(.rodata.console_drivers)
econsole_drivers = . ;
@@ -60,6 +64,7 @@ SECTIONS
cpu_drivers = . ;
*(.rodata.cpu_driver)
ecpu_drivers = . ;
+
*(.rodata)
*(.rodata.*)
/* kevinh/Ispiri - Added an align, because the objcopy tool
diff --git a/src/include/rmodule.h b/src/include/rmodule.h
index 30eee0e..5300c63 100644
--- a/src/include/rmodule.h
+++ b/src/include/rmodule.h
@@ -27,6 +27,7 @@
enum {
RMODULE_TYPE_SMM,
RMODULE_TYPE_SIPI_VECTOR,
+ RMODULE_TYPE_STAGE,
};
struct rmodule;
@@ -58,8 +59,8 @@ int rmodule_load_alignment(const struct rmodule *m);
.module_entry_point = FIELD_ENTRY(entry_), \
.parameters_begin = FIELD_ENTRY(_module_params_begin), \
.parameters_end = FIELD_ENTRY(_module_params_end), \
- .bss_begin = FIELD_ENTRY(_bss_begin), \
- .bss_end = FIELD_ENTRY(_bss_end), \
+ .bss_begin = FIELD_ENTRY(_bss), \
+ .bss_end = FIELD_ENTRY(_ebss), \
}
#define DEFINE_RMODULE_HEADER(name_, entry_, type_) \
@@ -119,8 +120,8 @@ extern char _relocations_begin_offset[];
extern char _relocations_end_offset[];
extern char _payload_end_offset[];
extern char _payload_begin_offset[];
-extern char _bss_begin[];
-extern char _bss_end[];
+extern char _bss[];
+extern char _ebss[];
extern char _module_program_size[];
extern char _module_link_start_addr[];
extern char _module_params_begin[];
diff --git a/src/lib/rmodule.ld b/src/lib/rmodule.ld
index fdee279..c8bd297 100644
--- a/src/lib/rmodule.ld
+++ b/src/lib/rmodule.ld
@@ -41,6 +41,22 @@ SECTIONS
*(.text.*);
/* C read-only data. */
. = ALIGN(16);
+
+ /* The driver sections are to allow linking coreboot's
+ * ramstage with the rmodule linker. Any changes made in
+ * coreboot_ram.ld should be made here as well. */
+ console_drivers = .;
+ *(.rodata.console_drivers)
+ econsole_drivers = . ;
+ . = ALIGN(4);
+ pci_drivers = . ;
+ *(.rodata.pci_driver)
+ epci_drivers = . ;
+ cpu_drivers = . ;
+ *(.rodata.cpu_driver)
+ ecpu_drivers = . ;
+ . = ALIGN(4);
+
*(.rodata);
*(.rodata.*);
. = ALIGN(4);
@@ -67,13 +83,13 @@ SECTIONS
_payload_end_offset = LOADADDR(.data) + SIZEOF(.data);
.bss (NOLOAD) : {
- /* C uninitialized data of the SMM handler */
- _bss_begin = .;
+ /* C uninitialized data of the module. */
+ _bss = .;
*(.bss);
*(.sbss);
*(COMMON);
. = ALIGN(8);
- _bss_end = .;
+ _ebss = .;
/*
* Place the heap after BSS. The heap size is passed in by
@@ -87,6 +103,12 @@ SECTIONS
/* _module_program_size is the total memory used by the program. */
_module_program_size = _eheap - _module_link_start_addr;
+ /* coreboot's ramstage uses the _ram_seg and _eram_seg symbols
+ * for determining its load location. Provide those to help it out.
+ * It's a nop for any non-ramstage rmodule. */
+ _ram_seg = _module_link_start_addr;
+ _eram_seg = _module_link_start_addr + _module_program_size;
+
/* The relocation information is linked on top of the BSS section
* because the BSS section takes no space on disk. The relocation data
* resides directly after the data section in the flat binary. */
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2785
-gerrit
commit 0ddffb26981a969f5bddafda2e91eb44e48a69de
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Wed Feb 6 15:28:40 2013 -0600
x86: remove stack definition in linker script
In order to prepare the ramstage to be linked by the rmodule linker the
stack needs to be self-contained within the ramstage objects. The
reasoning is that the rmodule linker provides a way to define a heap,
but it doesn't currently have a region for the stack.
The downside to this is that memory footprint of the ramstage can change
when compared before this change. The size difference stems from the
link ordering of the objects as the stack is now defined within
c_start.S. The size fluctuation ranges from 0 to CONFIG_STACK_SIZE - 1
because of the previous behavior or aligning to CONFIG_STACK_SIZE. It
should be noted that such an alignment is unnecessary for 32-bit x86 as
the alignment requirement for the stacks are 4 byte alignment. Also the
memory footprint is still dominated by CONFIG_RAMTOP and CONFIG_RAMBASE.
Change-Id: I63a4ddd249104bc27aff2ab6b39fc6db12b54028
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/arch/x86/coreboot_ram.ld | 14 --------------
src/arch/x86/lib/c_start.S | 36 ++++++++++++++++++++++++------------
2 files changed, 24 insertions(+), 26 deletions(-)
diff --git a/src/arch/x86/coreboot_ram.ld b/src/arch/x86/coreboot_ram.ld
index 7ce0367..d9f0909 100644
--- a/src/arch/x86/coreboot_ram.ld
+++ b/src/arch/x86/coreboot_ram.ld
@@ -92,20 +92,6 @@ SECTIONS
*(COMMON)
}
_ebss = .;
- _end = .;
-
- /* coreboot really "ends" here. Only heap and stack are placed after
- * this line.
- */
-
- . = ALIGN(CONFIG_STACK_SIZE);
-
- _stack = .;
- .stack . : {
- /* Reserve a stack for each possible cpu */
- . += CONFIG_MAX_CPUS*CONFIG_STACK_SIZE;
- }
- _estack = .;
_heap = .;
.heap . : {
diff --git a/src/arch/x86/lib/c_start.S b/src/arch/x86/lib/c_start.S
index 9a8b4ac..295283b 100644
--- a/src/arch/x86/lib/c_start.S
+++ b/src/arch/x86/lib/c_start.S
@@ -1,5 +1,16 @@
#include <cpu/x86/post_code.h>
+/* Place the stack in the bss section. It's not necessary to define it in the
+ * the linker script. */
+ .section .bss, "aw", @nobits
+.global _stack
+.global _estack
+
+.align CONFIG_STACK_SIZE
+_stack:
+.space CONFIG_MAX_CPUS*CONFIG_STACK_SIZE
+_estack:
+
.section ".textfirst"
.code32
.globl _start
@@ -16,19 +27,7 @@ _start:
post_code(POST_ENTRY_C_START) /* post 13 */
- /** poison the stack. Code should not count on the
- * stack being full of zeros. This stack poisoning
- * recently uncovered a bug in the broadcast SIPI
- * code.
- */
cld
- leal _stack, %edi
- movl $_estack, %ecx
- subl %edi, %ecx
- shrl $2, %ecx /* it is 32 bit aligned, right? */
- movl $0xDEADBEEF, %eax
- rep
- stosl
/** clear bss, which unlike the stack is zero by definition */
leal _bss, %edi
@@ -41,6 +40,19 @@ _start:
stosl
.Lnobss:
+ /** poison the stack. Code should not count on the
+ * stack being full of zeros. This stack poisoning
+ * recently uncovered a bug in the broadcast SIPI
+ * code.
+ */
+ leal _stack, %edi
+ movl $_estack, %ecx
+ subl %edi, %ecx
+ shrl $2, %ecx /* it is 32 bit aligned, right? */
+ movl $0xDEADBEEF, %eax
+ rep
+ stosl
+
/* set new stack */
movl $_estack, %esp
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2784
-gerrit
commit d192701093ff992dba924c2643beff2913e7dd16
Author: Ronald G. Minnich <rminnich(a)google.com>
Date: Mon Feb 4 20:31:51 2013 -0800
bd82x6x: Fix compiling with USB debug port support
At some point, compiles with USB Debug port stopped working. This change makes
a trivial reordering in the code and adds two makefile entries to make it build
without errors. It also works on stout.
Build and boot as normal. Works. Enable CONFIG_USB, connect USB debug hardware
to the correct port (on stout, that's the one on the left nearest the back) and
watch for output.
Change-Id: I7fbb7983a19b0872e2d9e4248db8949e72beaaa0
Signed-off-by: Ronald G. Minnich <rminnich(a)google.com>
---
src/southbridge/intel/bd82x6x/Makefile.inc | 2 ++
src/southbridge/intel/bd82x6x/usb_debug.c | 16 +++++++++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc
index e921bc1..bc3ff4b 100644
--- a/src/southbridge/intel/bd82x6x/Makefile.inc
+++ b/src/southbridge/intel/bd82x6x/Makefile.inc
@@ -40,7 +40,9 @@ ramstage-y += watchdog.c
ramstage-$(CONFIG_ELOG) += elog.c
ramstage-y += spi.c
+ramstage-$(CONFIG_USBDEBUG) += usb_debug.c
smm-$(CONFIG_SPI_FLASH_SMM) += spi.c
+smm-$(CONFIG_USBDEBUG) += usb_debug.c
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me.c me_8.x.c finalize.c pch.c
diff --git a/src/southbridge/intel/bd82x6x/usb_debug.c b/src/southbridge/intel/bd82x6x/usb_debug.c
index 1cee353..607a88c 100644
--- a/src/southbridge/intel/bd82x6x/usb_debug.c
+++ b/src/southbridge/intel/bd82x6x/usb_debug.c
@@ -19,18 +19,13 @@
#include <stdint.h>
#include <arch/io.h>
-#include <arch/romcc_io.h>
#include <console/console.h>
#include <usbdebug.h>
#include <device/pci_def.h>
#include "pch.h"
-/* Required for successful build, but currently empty. */
-void set_debug_port(unsigned int port)
-{
- /* Not needed, the ICH* southbridges hardcode physical USB port 1. */
-}
-
+#ifdef __PRE_RAM__
+#include <arch/romcc_io.h>
void enable_usbdebug(unsigned int port)
{
u32 dbgctl;
@@ -48,4 +43,11 @@ void enable_usbdebug(unsigned int port)
dbgctl |= (1 << 30);
write32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET, dbgctl);
}
+#endif /* __PRE_RAM__ */
+
+/* Required for successful build, but currently empty. */
+void set_debug_port(unsigned int port)
+{
+ /* Not needed, the ICH* southbridges hardcode physical USB port 1. */
+}
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2783
-gerrit
commit c08a22d0e402f99c40112afe98fa76fd82695c60
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Jan 22 13:54:12 2013 -0600
lynxpoint: Add cbfs_load_payload() implementation
SPI accesses can be slow depending on the setup and the access pattern.
The current SPI hardware setup to cache and prefetch. The alternative
cbfs_load_payload() function takes advantage of the caching in the CPU
because the ROM is cached as write protected as well as the SPI's
hardware's caching/prefetching implementation. The CPU will fetch
consecutive aligned cachelines which will hit the ROM as
cacheline-aligned addresses. Once the payload is mirrored into RAM the
segment loading can take place by reading RAM instead of ROM.
With the alternative cbfs_load_payload() the boot time on a baskingridge
board saves ~100ms. This savings is observed using cbmem.py after
performing warm reboots and looking at TS_SELFBOOT_JUMP (99) entries.
This is booting with a depthcharge payload whose payload file fits
within the SMM_DEFAULT_SIZE (0x10000 bytes).
Datapoints with TS_LOAD_PAYLOAD (90) & TS_SELFBOOT_JUMP (99) cbmem entries:
Baseline Alt
-------- --------
90:3,859,310 (473) 90:3,863,647 (454)
99:3,989,578 (130,268) 99:3,888,709 (25,062)
90:3,899,450 (477) 90:3,860,926 (463)
99:4,029,459 (130,008) 99:3,890,583 (29,657)
90:3,834,600 (466) 90:3,890,564 (465)
99:3,964,535 (129,934) 99:3,920,213 (29,649)
Booted baskingridge many times and observed 100ms reduction in
TS_SELFBOOT_JUMP times (time to load payload).
Change-Id: I27b2dec59ecd469a4906b4179b39928e9201db81
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/southbridge/intel/lynxpoint/Kconfig | 1 +
src/southbridge/intel/lynxpoint/Makefile.inc | 1 +
src/southbridge/intel/lynxpoint/spi_loading.c | 85 +++++++++++++++++++++++++++
3 files changed, 87 insertions(+)
diff --git a/src/southbridge/intel/lynxpoint/Kconfig b/src/southbridge/intel/lynxpoint/Kconfig
index 6f5bfe2..f79e963 100644
--- a/src/southbridge/intel/lynxpoint/Kconfig
+++ b/src/southbridge/intel/lynxpoint/Kconfig
@@ -31,6 +31,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy
select PCIEXP_ASPM
select PCIEXP_COMMON_CLOCK
select SPI_FLASH
+ select ALT_CBFS_LOAD_PAYLOAD
config INTEL_LYNXPOINT_LP
bool
diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc
index 6e84ce6..51bb428 100644
--- a/src/southbridge/intel/lynxpoint/Makefile.inc
+++ b/src/southbridge/intel/lynxpoint/Makefile.inc
@@ -37,6 +37,7 @@ ramstage-y += me_status.c
ramstage-y += reset.c
ramstage-y += watchdog.c
ramstage-y += acpi.c
+ramstage-$(CONFIG_ALT_CBFS_LOAD_PAYLOAD) += spi_loading.c
ramstage-$(CONFIG_ELOG) += elog.c
ramstage-y += spi.c
diff --git a/src/southbridge/intel/lynxpoint/spi_loading.c b/src/southbridge/intel/lynxpoint/spi_loading.c
new file mode 100644
index 0000000..0445904
--- /dev/null
+++ b/src/southbridge/intel/lynxpoint/spi_loading.c
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 ChromeOS Authors
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <arch/byteorder.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+
+#define CACHELINE_SIZE 64
+#define INTRA_CACHELINE_MASK (CACHELINE_SIZE - 1)
+#define CACHELINE_MASK (~INTRA_CACHELINE_MASK)
+
+/* Mirror the payload file to the default SMM location if it is small enough.x
+ * The default SMM region can be used since no one is using the memory at this
+ * location at this stage in the boot. */
+static inline void *spi_mirror(void *file_start, int file_len)
+{
+ int alignment_diff;
+ char *src;
+ char *dest = (void *)SMM_DEFAULT_BASE;
+
+ alignment_diff = (INTRA_CACHELINE_MASK & (long)file_start);
+
+ /* Adjust file length so that the start and end points are aligned to a
+ * cacheline. Coupled with the ROM caching in the CPU the SPI hardware
+ * will read and cache full length cachelines. It will also prefetch
+ * data as well. Once things are mirrored in memory all accesses should
+ * hit the CPUs cache. */
+ file_len += alignment_diff;
+ file_len = ALIGN(file_len, CACHELINE_SIZE);
+
+ printk(BIOS_DEBUG, "Payload aligned size: 0x%x\n", file_len);
+
+ /* Just pass back the pointer to ROM space if the file is larger
+ * than the RAM mirror region. */
+ if (file_len > SMM_DEFAULT_SIZE)
+ return file_start;
+
+ src = (void *)(CACHELINE_MASK & (long)file_start);
+ /* Note that if mempcy is not using 32-bit moves the performance will
+ * degrade because the SPI hardware prefetchers look for
+ * cacheline-aligned 32-bit accesses to kick in. */
+ memcpy(dest, src, file_len);
+
+ /* Provide pointer into mirrored space. */
+ return &dest[alignment_diff];
+}
+
+void *cbfs_load_payload(struct cbfs_media *media, const char *name)
+{
+ int file_len;
+ void *file_start;
+ struct cbfs_file *file = cbfs_get_file(media, name);
+
+ if (file == NULL)
+ return NULL;
+
+ if (ntohl(file->type) != CBFS_TYPE_PAYLOAD)
+ return NULL;
+
+ file_len = ntohl(file->len);
+
+ file_start = CBFS_SUBHEADER(file);
+
+ return spi_mirror(file_start, file_len);
+}
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2782
-gerrit
commit da654974d7cd92946e363e024b126daf67e36c12
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Jan 22 13:22:02 2013 -0600
cbfs: alternative support for cbfs_load_payload()
In certain situations boot speed can be increased by providing an
alternative implementation to cbfs_load_payload(). The
ALT_CBFS_LOAD_PAYLOAD option allows for the mainboard or chipset to
provide its own implementation.
Booted baskingridge board with alternative and regular
cbfs_load_payload().
Change-Id: I547ac9881a82bacbdb3bbdf38088dfcc22fd0c2c
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/Kconfig | 9 +++++++++
src/lib/cbfs.c | 2 ++
src/lib/selfboot.c | 1 -
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/Kconfig b/src/Kconfig
index 7206878..f6a83e8 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -47,6 +47,15 @@ config CBFS_PREFIX
Select the prefix to all files put into the image. It's "fallback"
by default, "normal" is a common alternative.
+config ALT_CBFS_LOAD_PAYLOAD
+ bool "Use alternative cbfs_load_payload() implementation."
+ default n
+ help
+ Either board or southbridge provide an alternative cbfs_load_payload()
+ implementation. This may be used, for example, if accessing the ROM
+ through memory-mapped I/O is slow and a faster alternative can be
+ provided.
+
choice
prompt "Compiler to use"
default COMPILER_GCC
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index bfdab6c..abb95ab 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -165,11 +165,13 @@ int cbfs_execute_stage(struct cbfs_media *media, const char *name)
return run_address((void *)(uintptr_t)ntohll(stage->entry));
}
+#if !CONFIG_ALT_CBFS_LOAD_PAYLOAD
void *cbfs_load_payload(struct cbfs_media *media, const char *name)
{
return (struct cbfs_payload *)cbfs_get_file_content(
media, name, CBFS_TYPE_PAYLOAD);
}
+#endif
/* Simple buffer */
diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c
index d64ba4c..f32bb81 100644
--- a/src/lib/selfboot.c
+++ b/src/lib/selfboot.c
@@ -536,4 +536,3 @@ int selfboot(struct lb_memory *mem, struct cbfs_payload *payload)
out:
return 0;
}
-
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2780
-gerrit
commit 4196a64aab245edcea4c93725ab817d9c527c2b7
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Jan 17 11:13:46 2013 -0600
haswell: wait 10ms after INIT IPI
There should be a fixed 10ms wait after sending an INIT IPI. The
previous implementation was just waiting up to 10ms for the IPI to
complete the send. That is not correct. The 10ms is unconditional
according to the documentation. No ill effects were observed with the
previous behavior, but it's important to follow the documentation.
Change-Id: Ib31d49ac74808f6eb512310e9f54a8f4abc3bfd7
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/intel/haswell/mp_init.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/src/cpu/intel/haswell/mp_init.c b/src/cpu/intel/haswell/mp_init.c
index b1567ba..3076d07 100644
--- a/src/cpu/intel/haswell/mp_init.c
+++ b/src/cpu/intel/haswell/mp_init.c
@@ -458,15 +458,8 @@ int start_aps(struct bus *cpu_bus, int ap_count)
lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0));
lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT |
LAPIC_DM_INIT);
- printk(BIOS_DEBUG, "Waiting for INIT to complete...");
-
- /* Wait for 10 ms to complete. */
- if (apic_wait_timeout(10000 /* 10 ms */, 100 /* us */)) {
- printk(BIOS_DEBUG, "timed out. Bailing. \n");
- return -1;
- } else {
- printk(BIOS_DEBUG, "done.\n");
- }
+ printk(BIOS_DEBUG, "Waiting for 10ms after sending INIT.\n");
+ mdelay(10);
/* Send 1st SIPI */
if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {