aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2024-03-23 15:47:39 +0100
committerMartin L Roth <gaumless@gmail.com>2024-03-28 15:20:43 +0000
commit41eaf2dba315dabb51b5c6a77b083165187ebb18 (patch)
tree2005acb5a43b4c6f9b780ea9c328ba1a9ed28f7e
parentefc615e239004c604a2c907ee36fa21dc6adaf58 (diff)
soc/amd/non_car/memlayout_x86.ld: Top align the code
This does the following: - Top align the bootblock so that the only the memory needed gets used. This might slightly reduce the time the PSP needs to decompress the bootblock in memory - Use a memory directive to assert that the 16bit code is inside the top 64K segment - Use the program counter less. While the BDF linker is happy about running the program counter backwards, LLD is not. There is no downside to this. - Use a symbol rather that the program counter for sections. LLD gets confused when (.) is used along with '<': it places the section at the start of the memory region, rather than at the program counter. Using a variable name works around this. - Use a 'last_byte' section to make sure the first instruction is at 0xfff0. Both the BDF and the LLD linkers seems to work well with this code TEST: Both BFD and LLD are able to link the bootblock Change-Id: I18bdf262f9c358aa01795b11efcb863686edc79c Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81433 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin L Roth <gaumless@gmail.com>
-rw-r--r--src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld34
1 files changed, 22 insertions, 12 deletions
diff --git a/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld b/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld
index 9eb9d21ce6..3c596f4c20 100644
--- a/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld
+++ b/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld
@@ -95,7 +95,6 @@ SECTIONS
PSP_SHAREDMEM_DRAM_END(CONFIG_PSP_SHAREDMEM_BASE + CONFIG_PSP_SHAREDMEM_SIZE)
#endif
_ = ASSERT(BOOTBLOCK_END == ((BOOTBLOCK_END + 0xFFFF) & 0xFFFF0000), "Bootblock end must be 16 bit aligned");
- BOOTBLOCK(BOOTBLOCK_ADDR, CONFIG_C_ENV_BOOTBLOCK_SIZE)
ROMSTAGE(CONFIG_ROMSTAGE_ADDR, CONFIG_ROMSTAGE_SIZE)
#if CONFIG(PLATFORM_USES_FSP2_0)
@@ -124,19 +123,29 @@ SECTIONS
gdtptr_offset = gdtptr & 0xffff;
nullidt_offset = nullidt & 0xffff;
+MEMORY
+{
+ /* Make sure all the 16bit code is in the same 64K segment as the reset vector */
+ resetsection (rwx) : ORIGIN = BOOTBLOCK_END - 64K, LENGTH = 64K
+}
+
SECTIONS {
- /* Trigger an error if I have an unusable start address */
- _TOO_LOW = _X86_RESET_VECTOR - 0xfff0;
- _bogus = ASSERT(_start16bit >= _TOO_LOW, "_start16bit too low. Please report.");
+ /* Page tables need to be at a 4K boundary so align the bootblock downwards */
+ . = (BOOTBLOCK_TOP - PROGRAM_SZ) & ~(4096 - 1);
+ _bootblock = .;
+
+ INCLUDE "bootblock/lib/program.ld"
+
+ PROGRAM_SZ = SIZEOF(.text) + SIZEOF(.bss) + SIZEOF(.data);
. = _X86_RESET_VECTOR - EARLYASM_SZ;
. = ALIGN(16);
BOOTBLOCK_TOP = .;
- .init (.) : {
+ .init BOOTBLOCK_TOP : {
*(.init._start);
*(.init);
*(.init.*);
- }
+ } >resetsection
/*
* Allocation reserves extra space here. Alignment requirements
@@ -145,13 +154,14 @@ SECTIONS {
*/
EARLYASM_SZ = SIZEOF(.init) + 16;
- . = BOOTBLOCK_END - 0x10;
- _X86_RESET_VECTOR = .;
+ _X86_RESET_VECTOR = BOOTBLOCK_END - 0x10;
_bogus = ASSERT((_X86_RESET_VECTOR & 0xffff) == 0xfff0, "IP needs to be 0xfff0");
- .reset . : {
+ .reset (_X86_RESET_VECTOR) : {
*(.reset);
- . = 15;
- BYTE(0x00);
- }
+ } >resetsection
+ .last_byte (BOOTBLOCK_END - 1) : {
+ BYTE(0xff);
+ } >resetsection
+ _ebootblock = BOOTBLOCK_END;
}
#endif /* ENV_BOOTBLOCK */