Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_POWERPC_HEAD_64_H
0003 #define _ASM_POWERPC_HEAD_64_H
0004 
0005 #include <asm/cache.h>
0006 
0007 #ifdef __ASSEMBLY__
0008 /*
0009  * We can't do CPP stringification and concatination directly into the section
0010  * name for some reason, so these macros can do it for us.
0011  */
0012 .macro define_ftsec name
0013     .section ".head.text.\name\()","ax",@progbits
0014 .endm
0015 .macro define_data_ftsec name
0016     .section ".head.data.\name\()","a",@progbits
0017 .endm
0018 .macro use_ftsec name
0019     .section ".head.text.\name\()","ax",@progbits
0020 .endm
0021 
0022 /*
0023  * Fixed (location) sections are used by opening fixed sections and emitting
0024  * fixed section entries into them before closing them. Multiple fixed sections
0025  * can be open at any time.
0026  *
0027  * Each fixed section created in a .S file must have corresponding linkage
0028  * directives including location, added to  arch/powerpc/kernel/vmlinux.lds.S
0029  *
0030  * For each fixed section, code is generated into it in the order which it
0031  * appears in the source.  Fixed section entries can be placed at a fixed
0032  * location within the section using _LOCATION postifx variants. These must
0033  * be ordered according to their relative placements within the section.
0034  *
0035  * OPEN_FIXED_SECTION(section_name, start_address, end_address)
0036  * FIXED_SECTION_ENTRY_BEGIN(section_name, label1)
0037  *
0038  * USE_FIXED_SECTION(section_name)
0039  * label3:
0040  *     li  r10,128
0041  *     mv  r11,r10
0042 
0043  * FIXED_SECTION_ENTRY_BEGIN_LOCATION(section_name, label2, start_address, size)
0044  * FIXED_SECTION_ENTRY_END_LOCATION(section_name, label2, start_address, size)
0045  * CLOSE_FIXED_SECTION(section_name)
0046  *
0047  * ZERO_FIXED_SECTION can be used to emit zeroed data.
0048  *
0049  * Troubleshooting:
0050  * - If the build dies with "Error: attempt to move .org backwards" at
0051  *   CLOSE_FIXED_SECTION() or elsewhere, there may be something
0052  *   unexpected being added there. Remove the '. = x_len' line, rebuild, and
0053  *   check what is pushing the section down.
0054  * - If the build dies in linking, check arch/powerpc/tools/head_check.sh
0055  *   comments.
0056  * - If the kernel crashes or hangs in very early boot, it could be linker
0057  *   stubs at the start of the main text.
0058  */
0059 
0060 #define OPEN_FIXED_SECTION(sname, start, end)           \
0061     sname##_start = (start);                \
0062     sname##_end = (end);                    \
0063     sname##_len = (end) - (start);              \
0064     define_ftsec sname;                 \
0065     . = 0x0;                        \
0066 start_##sname:
0067 
0068 /*
0069  * .linker_stub_catch section is used to catch linker stubs from being
0070  * inserted in our .text section, above the start_text label (which breaks
0071  * the ABS_ADDR calculation). See kernel/vmlinux.lds.S and tools/head_check.sh
0072  * for more details. We would prefer to just keep a cacheline (0x80), but
0073  * 0x100 seems to be how the linker aligns branch stub groups.
0074  */
0075 #ifdef CONFIG_LD_HEAD_STUB_CATCH
0076 #define OPEN_TEXT_SECTION(start)                \
0077     .section ".linker_stub_catch","ax",@progbits;       \
0078 linker_stub_catch:                      \
0079     . = 0x4;                        \
0080     text_start = (start) + 0x100;               \
0081     .section ".text","ax",@progbits;            \
0082     .balign 0x100;                      \
0083 start_text:
0084 #else
0085 #define OPEN_TEXT_SECTION(start)                \
0086     text_start = (start);                   \
0087     .section ".text","ax",@progbits;            \
0088     . = 0x0;                        \
0089 start_text:
0090 #endif
0091 
0092 #define ZERO_FIXED_SECTION(sname, start, end)           \
0093     sname##_start = (start);                \
0094     sname##_end = (end);                    \
0095     sname##_len = (end) - (start);              \
0096     define_data_ftsec sname;                \
0097     . = 0x0;                        \
0098     . = sname##_len;
0099 
0100 #define USE_FIXED_SECTION(sname)                \
0101     use_ftsec sname;
0102 
0103 #define USE_TEXT_SECTION()                  \
0104     .text
0105 
0106 #define CLOSE_FIXED_SECTION(sname)              \
0107     USE_FIXED_SECTION(sname);               \
0108     . = sname##_len;                    \
0109 end_##sname:
0110 
0111 
0112 #define __FIXED_SECTION_ENTRY_BEGIN(sname, name, __align)   \
0113     USE_FIXED_SECTION(sname);               \
0114     .balign __align;                    \
0115     .global name;                       \
0116 name:
0117 
0118 #define FIXED_SECTION_ENTRY_BEGIN(sname, name)          \
0119     __FIXED_SECTION_ENTRY_BEGIN(sname, name, IFETCH_ALIGN_BYTES)
0120 
0121 #define FIXED_SECTION_ENTRY_BEGIN_LOCATION(sname, name, start, size) \
0122     USE_FIXED_SECTION(sname);               \
0123     name##_start = (start);                 \
0124     .if ((start) % (size) != 0);                \
0125     .error "Fixed section exception vector misalignment";   \
0126     .endif;                         \
0127     .if ((size) != 0x20) && ((size) != 0x80) && ((size) != 0x100) && ((size) != 0x1000); \
0128     .error "Fixed section exception vector bad size";   \
0129     .endif;                         \
0130     .if (start) < sname##_start;                \
0131     .error "Fixed section underflow";           \
0132     .abort;                         \
0133     .endif;                         \
0134     . = (start) - sname##_start;                \
0135     .global name;                       \
0136 name:
0137 
0138 #define FIXED_SECTION_ENTRY_END_LOCATION(sname, name, start, size) \
0139     .if (start) + (size) > sname##_end;         \
0140     .error "Fixed section overflow";            \
0141     .abort;                         \
0142     .endif;                         \
0143     .if (. - name > (start) + (size) - name##_start);   \
0144     .error "Fixed entry overflow";              \
0145     .abort;                         \
0146     .endif;                         \
0147     . = ((start) + (size) - sname##_start);         \
0148 
0149 
0150 /*
0151  * These macros are used to change symbols in other fixed sections to be
0152  * absolute or related to our current fixed section.
0153  *
0154  * - DEFINE_FIXED_SYMBOL / FIXED_SYMBOL_ABS_ADDR is used to find the
0155  *   absolute address of a symbol within a fixed section, from any section.
0156  *
0157  * - ABS_ADDR is used to find the absolute address of any symbol, from within
0158  *   a fixed section.
0159  */
0160 // define label as being _in_ sname
0161 #define DEFINE_FIXED_SYMBOL(label, sname) \
0162     label##_absolute = (label - start_ ## sname + sname ## _start)
0163 
0164 #define FIXED_SYMBOL_ABS_ADDR(label)                \
0165     (label##_absolute)
0166 
0167 // find label from _within_ sname
0168 #define ABS_ADDR(label, sname) (label - start_ ## sname + sname ## _start)
0169 
0170 #endif /* __ASSEMBLY__ */
0171 
0172 #endif  /* _ASM_POWERPC_HEAD_64_H */