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