head-64.h 5.4 KB

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