xref: /linux/arch/powerpc/include/asm/head-64.h (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2da2bc464SMichael Ellerman #ifndef _ASM_POWERPC_HEAD_64_H
3da2bc464SMichael Ellerman #define _ASM_POWERPC_HEAD_64_H
4da2bc464SMichael Ellerman 
5da2bc464SMichael Ellerman #include <asm/cache.h>
6da2bc464SMichael Ellerman 
78c388514SNicholas Piggin #ifdef __ASSEMBLY__
857f26649SNicholas Piggin /*
957f26649SNicholas Piggin  * We can't do CPP stringification and concatination directly into the section
1057f26649SNicholas Piggin  * name for some reason, so these macros can do it for us.
1157f26649SNicholas Piggin  */
1257f26649SNicholas Piggin .macro define_ftsec name
1357f26649SNicholas Piggin 	.section ".head.text.\name\()","ax",@progbits
1457f26649SNicholas Piggin .endm
1557f26649SNicholas Piggin .macro define_data_ftsec name
1657f26649SNicholas Piggin 	.section ".head.data.\name\()","a",@progbits
1757f26649SNicholas Piggin .endm
1857f26649SNicholas Piggin .macro use_ftsec name
19e754f4d1SNicholas Piggin 	.section ".head.text.\name\()","ax",@progbits
2057f26649SNicholas Piggin .endm
21da2bc464SMichael Ellerman 
2257f26649SNicholas Piggin /*
2357f26649SNicholas Piggin  * Fixed (location) sections are used by opening fixed sections and emitting
2457f26649SNicholas Piggin  * fixed section entries into them before closing them. Multiple fixed sections
2557f26649SNicholas Piggin  * can be open at any time.
2657f26649SNicholas Piggin  *
2757f26649SNicholas Piggin  * Each fixed section created in a .S file must have corresponding linkage
2857f26649SNicholas Piggin  * directives including location, added to  arch/powerpc/kernel/vmlinux.lds.S
2957f26649SNicholas Piggin  *
3057f26649SNicholas Piggin  * For each fixed section, code is generated into it in the order which it
3157f26649SNicholas Piggin  * appears in the source.  Fixed section entries can be placed at a fixed
3257f26649SNicholas Piggin  * location within the section using _LOCATION postifx variants. These must
3357f26649SNicholas Piggin  * be ordered according to their relative placements within the section.
3457f26649SNicholas Piggin  *
3557f26649SNicholas Piggin  * OPEN_FIXED_SECTION(section_name, start_address, end_address)
3657f26649SNicholas Piggin  * FIXED_SECTION_ENTRY_BEGIN(section_name, label1)
3757f26649SNicholas Piggin  *
3857f26649SNicholas Piggin  * USE_FIXED_SECTION(section_name)
3957f26649SNicholas Piggin  * label3:
4057f26649SNicholas Piggin  *     li  r10,128
4157f26649SNicholas Piggin  *     mv  r11,r10
4257f26649SNicholas Piggin 
431a6822d1SNicholas Piggin  * FIXED_SECTION_ENTRY_BEGIN_LOCATION(section_name, label2, start_address, size)
441a6822d1SNicholas Piggin  * FIXED_SECTION_ENTRY_END_LOCATION(section_name, label2, start_address, size)
4557f26649SNicholas Piggin  * CLOSE_FIXED_SECTION(section_name)
4657f26649SNicholas Piggin  *
4757f26649SNicholas Piggin  * ZERO_FIXED_SECTION can be used to emit zeroed data.
4857f26649SNicholas Piggin  *
4957f26649SNicholas Piggin  * Troubleshooting:
5057f26649SNicholas Piggin  * - If the build dies with "Error: attempt to move .org backwards" at
5157f26649SNicholas Piggin  *   CLOSE_FIXED_SECTION() or elsewhere, there may be something
5257f26649SNicholas Piggin  *   unexpected being added there. Remove the '. = x_len' line, rebuild, and
5357f26649SNicholas Piggin  *   check what is pushing the section down.
54c494adefSNicholas Piggin  * - If the build dies in linking, check arch/powerpc/tools/head_check.sh
55c494adefSNicholas Piggin  *   comments.
5657f26649SNicholas Piggin  * - If the kernel crashes or hangs in very early boot, it could be linker
5757f26649SNicholas Piggin  *   stubs at the start of the main text.
5857f26649SNicholas Piggin  */
5957f26649SNicholas Piggin 
6057f26649SNicholas Piggin #define OPEN_FIXED_SECTION(sname, start, end)			\
6157f26649SNicholas Piggin 	sname##_start = (start);				\
6257f26649SNicholas Piggin 	sname##_end = (end);					\
6357f26649SNicholas Piggin 	sname##_len = (end) - (start);				\
6457f26649SNicholas Piggin 	define_ftsec sname;					\
6557f26649SNicholas Piggin 	. = 0x0;						\
6657f26649SNicholas Piggin start_##sname:
6757f26649SNicholas Piggin 
68951eedebSNicholas Piggin /*
69951eedebSNicholas Piggin  * .linker_stub_catch section is used to catch linker stubs from being
70951eedebSNicholas Piggin  * inserted in our .text section, above the start_text label (which breaks
71951eedebSNicholas Piggin  * the ABS_ADDR calculation). See kernel/vmlinux.lds.S and tools/head_check.sh
72951eedebSNicholas Piggin  * for more details. We would prefer to just keep a cacheline (0x80), but
73951eedebSNicholas Piggin  * 0x100 seems to be how the linker aligns branch stub groups.
74951eedebSNicholas Piggin  */
75951eedebSNicholas Piggin #ifdef CONFIG_LD_HEAD_STUB_CATCH
76951eedebSNicholas Piggin #define OPEN_TEXT_SECTION(start)				\
77951eedebSNicholas Piggin 	.section ".linker_stub_catch","ax",@progbits;		\
78951eedebSNicholas Piggin linker_stub_catch:						\
79951eedebSNicholas Piggin 	. = 0x4;						\
80951eedebSNicholas Piggin 	text_start = (start) + 0x100;				\
81951eedebSNicholas Piggin 	.section ".text","ax",@progbits;			\
82951eedebSNicholas Piggin 	.balign 0x100;						\
83951eedebSNicholas Piggin start_text:
84951eedebSNicholas Piggin #else
8557f26649SNicholas Piggin #define OPEN_TEXT_SECTION(start)				\
8657f26649SNicholas Piggin 	text_start = (start);					\
8757f26649SNicholas Piggin 	.section ".text","ax",@progbits;			\
8857f26649SNicholas Piggin 	. = 0x0;						\
8957f26649SNicholas Piggin start_text:
90951eedebSNicholas Piggin #endif
9157f26649SNicholas Piggin 
9257f26649SNicholas Piggin #define ZERO_FIXED_SECTION(sname, start, end)			\
9357f26649SNicholas Piggin 	sname##_start = (start);				\
9457f26649SNicholas Piggin 	sname##_end = (end);					\
9557f26649SNicholas Piggin 	sname##_len = (end) - (start);				\
9657f26649SNicholas Piggin 	define_data_ftsec sname;				\
9757f26649SNicholas Piggin 	. = 0x0;						\
9857f26649SNicholas Piggin 	. = sname##_len;
9957f26649SNicholas Piggin 
10057f26649SNicholas Piggin #define USE_FIXED_SECTION(sname)				\
10157f26649SNicholas Piggin 	use_ftsec sname;
10257f26649SNicholas Piggin 
10357f26649SNicholas Piggin #define USE_TEXT_SECTION()					\
10457f26649SNicholas Piggin 	.text
10557f26649SNicholas Piggin 
10657f26649SNicholas Piggin #define CLOSE_FIXED_SECTION(sname)				\
10757f26649SNicholas Piggin 	USE_FIXED_SECTION(sname);				\
10857f26649SNicholas Piggin 	. = sname##_len;					\
10957f26649SNicholas Piggin end_##sname:
11057f26649SNicholas Piggin 
11157f26649SNicholas Piggin 
11257f26649SNicholas Piggin #define __FIXED_SECTION_ENTRY_BEGIN(sname, name, __align)	\
11357f26649SNicholas Piggin 	USE_FIXED_SECTION(sname);				\
114f4329f2eSNicholas Piggin 	.balign __align;					\
11557f26649SNicholas Piggin 	.global name;						\
11657f26649SNicholas Piggin name:
11757f26649SNicholas Piggin 
11857f26649SNicholas Piggin #define FIXED_SECTION_ENTRY_BEGIN(sname, name)			\
119f4329f2eSNicholas Piggin 	__FIXED_SECTION_ENTRY_BEGIN(sname, name, IFETCH_ALIGN_BYTES)
12057f26649SNicholas Piggin 
1211a6822d1SNicholas Piggin #define FIXED_SECTION_ENTRY_BEGIN_LOCATION(sname, name, start, size) \
12257f26649SNicholas Piggin 	USE_FIXED_SECTION(sname);				\
12357f26649SNicholas Piggin 	name##_start = (start);					\
1241a6822d1SNicholas Piggin 	.if ((start) % (size) != 0);				\
1251a6822d1SNicholas Piggin 	.error "Fixed section exception vector misalignment";	\
1261a6822d1SNicholas Piggin 	.endif;							\
1277fa95f9aSNicholas Piggin 	.if ((size) != 0x20) && ((size) != 0x80) && ((size) != 0x100) && ((size) != 0x1000); \
1281a6822d1SNicholas Piggin 	.error "Fixed section exception vector bad size";	\
1291a6822d1SNicholas Piggin 	.endif;							\
13057f26649SNicholas Piggin 	.if (start) < sname##_start;				\
13157f26649SNicholas Piggin 	.error "Fixed section underflow";			\
13257f26649SNicholas Piggin 	.abort;							\
13357f26649SNicholas Piggin 	.endif;							\
13457f26649SNicholas Piggin 	. = (start) - sname##_start;				\
13557f26649SNicholas Piggin 	.global name;						\
13657f26649SNicholas Piggin name:
13757f26649SNicholas Piggin 
1381a6822d1SNicholas Piggin #define FIXED_SECTION_ENTRY_END_LOCATION(sname, name, start, size) \
1391a6822d1SNicholas Piggin 	.if (start) + (size) > sname##_end;			\
14057f26649SNicholas Piggin 	.error "Fixed section overflow";			\
14157f26649SNicholas Piggin 	.abort;							\
14257f26649SNicholas Piggin 	.endif;							\
1431a6822d1SNicholas Piggin 	.if (. - name > (start) + (size) - name##_start);	\
14457f26649SNicholas Piggin 	.error "Fixed entry overflow";				\
14557f26649SNicholas Piggin 	.abort;							\
14657f26649SNicholas Piggin 	.endif;							\
1471a6822d1SNicholas Piggin 	. = ((start) + (size) - sname##_start);			\
14857f26649SNicholas Piggin 
14957f26649SNicholas Piggin 
15057f26649SNicholas Piggin /*
15157f26649SNicholas Piggin  * These macros are used to change symbols in other fixed sections to be
15257f26649SNicholas Piggin  * absolute or related to our current fixed section.
15357f26649SNicholas Piggin  *
15457f26649SNicholas Piggin  * - DEFINE_FIXED_SYMBOL / FIXED_SYMBOL_ABS_ADDR is used to find the
15557f26649SNicholas Piggin  *   absolute address of a symbol within a fixed section, from any section.
15657f26649SNicholas Piggin  *
15757f26649SNicholas Piggin  * - ABS_ADDR is used to find the absolute address of any symbol, from within
15857f26649SNicholas Piggin  *   a fixed section.
15957f26649SNicholas Piggin  */
160*d72c4a36SDaniel Axtens // define label as being _in_ sname
161*d72c4a36SDaniel Axtens #define DEFINE_FIXED_SYMBOL(label, sname) \
162*d72c4a36SDaniel Axtens 	label##_absolute = (label - start_ ## sname + sname ## _start)
16357f26649SNicholas Piggin 
16457f26649SNicholas Piggin #define FIXED_SYMBOL_ABS_ADDR(label)				\
16557f26649SNicholas Piggin 	(label##_absolute)
16657f26649SNicholas Piggin 
167*d72c4a36SDaniel Axtens // find label from _within_ sname
168*d72c4a36SDaniel Axtens #define ABS_ADDR(label, sname) (label - start_ ## sname + sname ## _start)
16957f26649SNicholas Piggin 
1708c388514SNicholas Piggin #endif /* __ASSEMBLY__ */
1718c388514SNicholas Piggin 
172da2bc464SMichael Ellerman #endif	/* _ASM_POWERPC_HEAD_64_H */
173