Xeon-SP boards: Factor out OCP VPD `get_cxl_mode()` impl
[coreboot2.git] / src / lib / program.ld
blobb3ddc0b762bacb19b1d96cf7e45f3e0dd465aa8d
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <memlayout.h>
5 /* This file is included inside a SECTIONS block */
7 /* First we place the code and read only data (typically const declared).
8  * This could theoretically be placed in rom.
9  * The '.' in '.text . : {' is actually significant to prevent missing some
10  * SoC's entry points due to artificial alignment restrictions, see
11  * https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
12  */
14 /* Starting with version 18 LLVM the combination -ffunction-section -mcmodel=large
15  * puts code and data in '.ltext, '.lrodata', '.ldata' and '.lbss'
16  */
18 .text . : {
19         _program = .;
20         _text = .;
21 #if !(ENV_X86 && ENV_BOOTBLOCK)
22         *(.init._start);
23         *(.init);
24         *(.init.*);
25 #endif
26         *(.text._start);
27         *(.text.stage_entry);
28         KEEP(*(.metadata_hash_anchor));
29         *(.text);
30         *(.text.*);
31         *(.ltext);
32         *(.ltext.*);
34 #if ENV_HAS_CBMEM
35         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
36         _cbmem_init_hooks = .;
37         KEEP(*(.rodata.cbmem_init_hooks_early));
38         KEEP(*(.rodata.cbmem_init_hooks));
39         _ecbmem_init_hooks = .;
40         RECORD_SIZE(cbmem_init_hooks)
41 #endif
43         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
44         _rsbe_init_begin = .;
45         KEEP(*(.rsbe_init));
46         _ersbe_init_begin = .;
47         RECORD_SIZE(rsbe_init_begin)
49 #if ENV_RAMSTAGE
50         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
51         _pci_drivers = .;
52         KEEP(*(.rodata.pci_driver));
53         _epci_drivers = .;
54         RECORD_SIZE(pci_drivers)
55         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
56         _cpu_drivers = .;
57         KEEP(*(.rodata.cpu_driver));
58         _ecpu_drivers = .;
59         RECORD_SIZE(cpu_drivers)
60 #endif
62         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
63         *(.rodata);
64         *(.rodata.*);
65         *(.lrodata);
66         *(.lrodata.*);
67         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
68         _etext = .;
69         RECORD_SIZE(text)
70 } : to_load
72 #if ENV_RAMSTAGE && (CONFIG(COVERAGE) || CONFIG(ASAN_IN_RAMSTAGE))
73 .ctors . : {
74         . = ALIGN(0x100);
75         __CTOR_LIST__ = .;
76         KEEP(*(.ctors));
77         LONG(0);
78         LONG(0);
79         __CTOR_END__ = .;
80 } : to_load
81 #endif
83 /* Include data, bss, and heap in that order. Not defined for all stages. */
84 #if !ENV_SEPARATE_DATA_AND_BSS
85 .data . : {
86         . = ALIGN(ARCH_CACHELINE_ALIGN_SIZE);
87         _data = .;
90  * The postcar phase uses a stack value that is located in the relocatable
91  * module section. While the postcar stage could be linked like smm and
92  * other rmodules the postcar stage needs similar semantics of the more
93  * traditional stages in the coreboot infrastructure. Therefore it's easier
94  * to specialize this case.
95  */
96 #if ENV_RMODULE || ENV_POSTCAR
97         _rmodule_params = .;
98         KEEP(*(.module_parameters));
99         _ermodule_params = .;
100         RECORD_SIZE(rmodule_params)
101 #endif
103         *(.data);
104         *(.data.*);
105         *(.ldata);
106         *(.ldata.*);
107         *(.sdata);
108         *(.sdata.*);
110 #if ENV_ROMSTAGE_OR_BEFORE
111         PROVIDE(_preram_cbmem_console = .);
112         PROVIDE(_epreram_cbmem_console = _preram_cbmem_console);
113         PROVIDE(_preram_cbmem_console_size = ABSOLUTE(0));
114 #elif ENV_RAMSTAGE
115         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
116         _bs_init_begin = .;
117         KEEP(*(.bs_init));
118         LONG(0);
119         LONG(0);
120         _ebs_init_begin = .;
121         RECORD_SIZE(bs_init_begin)
122 #endif
124         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
125         _edata = .;
126         RECORD_SIZE(data)
127 } : to_load
128 #endif
130 #if !ENV_SEPARATE_DATA_AND_BSS
131 .bss . (NOLOAD) : {
132         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
133         _bss = .;
134         *(.bss)
135         *(.bss.*)
136         *(.lbss)
137         *(.lbss.*)
138         *(.sbss)
139         *(.sbss.*)
140         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
141         _ebss = .;
142         RECORD_SIZE(bss)
143 } : to_load
144 #endif
146 #if ENV_HAS_HEAP_SECTION
147 .heap . (NOLOAD) : {
148         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
149         _heap = .;
150         . += CONFIG_HEAP_SIZE;
151         . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
152         _eheap = .;
153         RECORD_SIZE(heap)
154 } : to_load
155 #endif
157 #if ENV_RAMSTAGE && CONFIG(ASAN_IN_RAMSTAGE)
158         _shadow_size = (_eheap - _data) >> 3;
159         REGION(asan_shadow, ., _shadow_size, ARCH_POINTER_ALIGN_SIZE)
160 #endif
162 _eprogram = .;
163 RECORD_SIZE(program)
165 /* The stage cache drops CONFIG_HEAP_SIZE bytes from the end of the in-memory
166    image of the ramstage, so ensure that when moving that many bytes backwards
167    from the program end, we're in the heap (or later), in some region that
168    doesn't contain initialized code or data. */
169 #if ENV_RAMSTAGE
170 _bogus = ASSERT(_eprogram - CONFIG_HEAP_SIZE >= _heap,
171         "HEAP_SIZE and heap misaligned");
172 #endif
174 /* Discard the sections we don't need/want */
176 zeroptr = 0;
178 /DISCARD/ : {
179         *(.comment)
180         *(.comment.*)
181         *(.note)
182         *(.note.*)
183         *(.eh_frame);