summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/Makefile.inc5
-rw-r--r--src/arch/x86/assembly_entry.S10
-rw-r--r--src/arch/x86/car.ld44
-rw-r--r--src/arch/x86/include/arch/header.ld3
-rw-r--r--src/arch/x86/memlayout.ld14
5 files changed, 51 insertions, 25 deletions
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index e0e8a3b7b9..accb022a81 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -64,11 +64,6 @@ $(1)-S-ccopts += -I.
$$(objcbfs)/$(1).debug: $$$$($(1)-libs) $$$$($(1)-objs)
@printf " LINK $$(subst $$(obj)/,,$$(@))\n"
$$(LD_$(1)) $$(LDFLAGS_$(1)) -o $$@ -L$$(obj) $$(COMPILER_RT_FLAGS_$(1)) --whole-archive --start-group $$(filter-out %.ld,$$($(1)-objs)) $$($(1)-libs) --no-whole-archive $$(COMPILER_RT_$(1)) --end-group -T $(call src-to-obj,$(1),$(CONFIG_MEMLAYOUT_LD_FILE)) --oformat $(2)
- -LANG=C LC_ALL= $$(OBJCOPY_$(1)) --only-section .illegal_globals $$(@) $$(objcbfs)/$(1)_null.offenders >/dev/null 2>&1
- if [ -z "$$$$($$(NM_$(1)) $$(objcbfs)/$(1)_null.offenders 2>&1 | grep 'no symbols')" ];then \
- echo "Forbidden global variables in $(1):"; \
- $$(NM_$(1)) $$(objcbfs)/$(1)_null.offenders; false; \
- fi
endef
###############################################################################
diff --git a/src/arch/x86/assembly_entry.S b/src/arch/x86/assembly_entry.S
index 869acc84e2..9a9a0465dc 100644
--- a/src/arch/x86/assembly_entry.S
+++ b/src/arch/x86/assembly_entry.S
@@ -33,8 +33,8 @@ _start:
/* reset stack pointer to CAR/EARLYRAM stack */
mov $_STACK_TOP, %esp
+#if ENV_SEPARATE_DATA_AND_BSS
/* clear .bss section as it is not shared */
-#if ENV_SEPARATE_BSS
cld
xor %eax, %eax
movl $(_ebss), %ecx
@@ -42,6 +42,14 @@ _start:
sub %edi, %ecx
shrl $2, %ecx
rep stosl
+
+ /* Copy .data section content to Cache-As-Ram */
+ movl $(_edata), %ecx
+ movl $(_data), %edi
+ sub %edi, %ecx
+ shrl $2, %ecx
+ movl $(_data_load),%esi
+ rep movsl
#endif
#if ((ENV_SEPARATE_VERSTAGE && CONFIG(VERSTAGE_DEBUG_SPINLOOP)) \
diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld
index ab6c3b0df8..a1a782ffe0 100644
--- a/src/arch/x86/car.ld
+++ b/src/arch/x86/car.ld
@@ -59,7 +59,7 @@
* cbmem console. This is useful for clearing this area on a per-stage
* basis when more than one stage uses cache-as-ram. */
-#if ENV_SEPARATE_BSS
+#if ENV_SEPARATE_DATA_AND_BSS
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
_bss = .;
/* Allow global uninitialized variables for stages without CAR teardown. */
@@ -89,11 +89,32 @@
_shadow_size = (_ebss - _car_region_start) >> 3;
REGION(asan_shadow, ., _shadow_size, ARCH_POINTER_ALIGN_SIZE)
#endif
- _car_unallocated_start = .;
- _car_region_end = . + CONFIG_DCACHE_RAM_SIZE - (. - _car_region_start)
- - CONFIG_FSP_T_RESERVED_SIZE;
}
+#if ENV_SEPARATE_DATA_AND_BSS
+/* This symbol defines the load address of the Cache-As-RAM .data
+ * section. It should be right at the end of the .text section (_etext)
+ * and ARCH_POINTER_ALIGN_SIZE aligned. */
+_data_load = _etext;
+
+_bogus = ASSERT(_etext == ALIGN(_etext, ARCH_POINTER_ALIGN_SIZE), "Cache-As-RAM load address is improperly defined.");
+
+.data ALIGN(ARCH_POINTER_ALIGN_SIZE) : AT (_data_load) {
+ _data = .;
+ *(.data);
+ *(.data.*);
+ *(.sdata);
+ *(.sdata.*);
+ . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
+ _edata = .;
+ RECORD_SIZE(data)
+} : data_segment
+#endif
+
+_car_unallocated_start = .;
+_car_region_end = . + CONFIG_DCACHE_RAM_SIZE - (. - _car_region_start)
+ - CONFIG_FSP_T_RESERVED_SIZE;
+
. = _car_region_start;
.car.fspm_rc_heap . (NOLOAD) : {
. += CONFIG_FSP_M_RC_HEAP_SIZE;
@@ -124,18 +145,11 @@ _rom_mtrr_mask = ~(CACHE_ROM_SIZE - 1);
_rom_mtrr_base = _rom_mtrr_mask;
#endif
-/* Global variables are not allowed in romstage
- * This section is checked during stage creation to ensure
- * that there are no global variables present
- */
-
-. = 0xffffff00;
-.illegal_globals . : {
- *(.data)
- *(.data.*)
-}
-
+#if ENV_SEPARATE_DATA_AND_BSS
+_bogus = ASSERT((CONFIG_DCACHE_RAM_SIZE == 0) || (SIZEOF(.car.data) + SIZEOF(.data) <= CONFIG_DCACHE_RAM_SIZE), "Cache as RAM area is too full");
+#else
_bogus = ASSERT((CONFIG_DCACHE_RAM_SIZE == 0) || (SIZEOF(.car.data) <= CONFIG_DCACHE_RAM_SIZE), "Cache as RAM area is too full");
+#endif
#if CONFIG(PAGING_IN_CACHE_AS_RAM)
_bogus2 = ASSERT(_pagetables == ALIGN(_pagetables, 4096), "_pagetables aren't 4KiB aligned");
#endif
diff --git a/src/arch/x86/include/arch/header.ld b/src/arch/x86/include/arch/header.ld
index 5b380faad5..2ee021226c 100644
--- a/src/arch/x86/include/arch/header.ld
+++ b/src/arch/x86/include/arch/header.ld
@@ -3,6 +3,9 @@
PHDRS
{
to_load PT_LOAD;
+#if ENV_SEPARATE_DATA_AND_BSS
+ data_segment PT_LOAD;
+#endif
}
ENTRY(_start)
diff --git a/src/arch/x86/memlayout.ld b/src/arch/x86/memlayout.ld
index 549c2f9041..f448bf89de 100644
--- a/src/arch/x86/memlayout.ld
+++ b/src/arch/x86/memlayout.ld
@@ -3,6 +3,16 @@
#include <memlayout.h>
#include <arch/header.ld>
+/*
+ * The bootblock linker script should be included before the Cache-As-RAM linker
+ * script. Indeed, if it is included after and Cache-As-RAM .data section
+ * support is enabled, the definition order of the sections makes the linker
+ * create an image with an almost 4 GB hole.
+ */
+#if ENV_BOOTBLOCK
+INCLUDE "bootblock/arch/x86/bootblock.ld"
+#endif /* ENV_BOOTBLOCK */
+
SECTIONS
{
/*
@@ -36,7 +46,3 @@ SECTIONS
POSTCAR(32M, 1M)
#endif
}
-
-#if ENV_BOOTBLOCK
- INCLUDE "bootblock/arch/x86/bootblock.ld"
-#endif /* ENV_BOOTBLOCK */