linux/arch/powerpc/include/asm/head-64.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _ASM_POWERPC_HEAD_64_H
   3#define _ASM_POWERPC_HEAD_64_H
   4
   5#include <asm/cache.h>
   6
   7#ifdef __ASSEMBLY__
   8/*
   9 * We can't do CPP stringification and concatination directly into the section
  10 * name for some reason, so these macros can do it for us.
  11 */
  12.macro define_ftsec name
  13        .section ".head.text.\name\()","ax",@progbits
  14.endm
  15.macro define_data_ftsec name
  16        .section ".head.data.\name\()","a",@progbits
  17.endm
  18.macro use_ftsec name
  19        .section ".head.text.\name\()","ax",@progbits
  20.endm
  21
  22/*
  23 * Fixed (location) sections are used by opening fixed sections and emitting
  24 * fixed section entries into them before closing them. Multiple fixed sections
  25 * can be open at any time.
  26 *
  27 * Each fixed section created in a .S file must have corresponding linkage
  28 * directives including location, added to  arch/powerpc/kernel/vmlinux.lds.S
  29 *
  30 * For each fixed section, code is generated into it in the order which it
  31 * appears in the source.  Fixed section entries can be placed at a fixed
  32 * location within the section using _LOCATION postifx variants. These must
  33 * be ordered according to their relative placements within the section.
  34 *
  35 * OPEN_FIXED_SECTION(section_name, start_address, end_address)
  36 * FIXED_SECTION_ENTRY_BEGIN(section_name, label1)
  37 *
  38 * USE_FIXED_SECTION(section_name)
  39 * label3:
  40 *     li  r10,128
  41 *     mv  r11,r10
  42
  43 * FIXED_SECTION_ENTRY_BEGIN_LOCATION(section_name, label2, start_address, size)
  44 * FIXED_SECTION_ENTRY_END_LOCATION(section_name, label2, start_address, size)
  45 * CLOSE_FIXED_SECTION(section_name)
  46 *
  47 * ZERO_FIXED_SECTION can be used to emit zeroed data.
  48 *
  49 * Troubleshooting:
  50 * - If the build dies with "Error: attempt to move .org backwards" at
  51 *   CLOSE_FIXED_SECTION() or elsewhere, there may be something
  52 *   unexpected being added there. Remove the '. = x_len' line, rebuild, and
  53 *   check what is pushing the section down.
  54 * - If the build dies in linking, check arch/powerpc/tools/head_check.sh
  55 *   comments.
  56 * - If the kernel crashes or hangs in very early boot, it could be linker
  57 *   stubs at the start of the main text.
  58 */
  59
  60#define OPEN_FIXED_SECTION(sname, start, end)                   \
  61        sname##_start = (start);                                \
  62        sname##_end = (end);                                    \
  63        sname##_len = (end) - (start);                          \
  64        define_ftsec sname;                                     \
  65        . = 0x0;                                                \
  66start_##sname:
  67
  68/*
  69 * .linker_stub_catch section is used to catch linker stubs from being
  70 * inserted in our .text section, above the start_text label (which breaks
  71 * the ABS_ADDR calculation). See kernel/vmlinux.lds.S and tools/head_check.sh
  72 * for more details. We would prefer to just keep a cacheline (0x80), but
  73 * 0x100 seems to be how the linker aligns branch stub groups.
  74 */
  75#ifdef CONFIG_LD_HEAD_STUB_CATCH
  76#define OPEN_TEXT_SECTION(start)                                \
  77        .section ".linker_stub_catch","ax",@progbits;           \
  78linker_stub_catch:                                              \
  79        . = 0x4;                                                \
  80        text_start = (start) + 0x100;                           \
  81        .section ".text","ax",@progbits;                        \
  82        .balign 0x100;                                          \
  83start_text:
  84#else
  85#define OPEN_TEXT_SECTION(start)                                \
  86        text_start = (start);                                   \
  87        .section ".text","ax",@progbits;                        \
  88        . = 0x0;                                                \
  89start_text:
  90#endif
  91
  92#define ZERO_FIXED_SECTION(sname, start, end)                   \
  93        sname##_start = (start);                                \
  94        sname##_end = (end);                                    \
  95        sname##_len = (end) - (start);                          \
  96        define_data_ftsec sname;                                \
  97        . = 0x0;                                                \
  98        . = sname##_len;
  99
 100#define USE_FIXED_SECTION(sname)                                \
 101        fs_label = start_##sname;                               \
 102        fs_start = sname##_start;                               \
 103        use_ftsec sname;
 104
 105#define USE_TEXT_SECTION()                                      \
 106        fs_label = start_text;                                  \
 107        fs_start = text_start;                                  \
 108        .text
 109
 110#define CLOSE_FIXED_SECTION(sname)                              \
 111        USE_FIXED_SECTION(sname);                               \
 112        . = sname##_len;                                        \
 113end_##sname:
 114
 115
 116#define __FIXED_SECTION_ENTRY_BEGIN(sname, name, __align)       \
 117        USE_FIXED_SECTION(sname);                               \
 118        .balign __align;                                        \
 119        .global name;                                           \
 120name:
 121
 122#define FIXED_SECTION_ENTRY_BEGIN(sname, name)                  \
 123        __FIXED_SECTION_ENTRY_BEGIN(sname, name, IFETCH_ALIGN_BYTES)
 124
 125#define FIXED_SECTION_ENTRY_BEGIN_LOCATION(sname, name, start, size) \
 126        USE_FIXED_SECTION(sname);                               \
 127        name##_start = (start);                                 \
 128        .if ((start) % (size) != 0);                            \
 129        .error "Fixed section exception vector misalignment";   \
 130        .endif;                                                 \
 131        .if ((size) != 0x20) && ((size) != 0x80) && ((size) != 0x100) && ((size) != 0x1000); \
 132        .error "Fixed section exception vector bad size";       \
 133        .endif;                                                 \
 134        .if (start) < sname##_start;                            \
 135        .error "Fixed section underflow";                       \
 136        .abort;                                                 \
 137        .endif;                                                 \
 138        . = (start) - sname##_start;                            \
 139        .global name;                                           \
 140name:
 141
 142#define FIXED_SECTION_ENTRY_END_LOCATION(sname, name, start, size) \
 143        .if (start) + (size) > sname##_end;                     \
 144        .error "Fixed section overflow";                        \
 145        .abort;                                                 \
 146        .endif;                                                 \
 147        .if (. - name > (start) + (size) - name##_start);       \
 148        .error "Fixed entry overflow";                          \
 149        .abort;                                                 \
 150        .endif;                                                 \
 151        . = ((start) + (size) - sname##_start);                 \
 152
 153
 154/*
 155 * These macros are used to change symbols in other fixed sections to be
 156 * absolute or related to our current fixed section.
 157 *
 158 * - DEFINE_FIXED_SYMBOL / FIXED_SYMBOL_ABS_ADDR is used to find the
 159 *   absolute address of a symbol within a fixed section, from any section.
 160 *
 161 * - ABS_ADDR is used to find the absolute address of any symbol, from within
 162 *   a fixed section.
 163 */
 164#define DEFINE_FIXED_SYMBOL(label)                              \
 165        label##_absolute = (label - fs_label + fs_start)
 166
 167#define FIXED_SYMBOL_ABS_ADDR(label)                            \
 168        (label##_absolute)
 169
 170#define ABS_ADDR(label) (label - fs_label + fs_start)
 171
 172#endif /* __ASSEMBLY__ */
 173
 174#endif  /* _ASM_POWERPC_HEAD_64_H */
 175