Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /* Copyright 2013-2019 IBM Corp.
3 : : * Copyright 2021 Stewart Smith
4 : : */
5 : :
6 : : #ifndef __SKIBOOT_H
7 : : #define __SKIBOOT_H
8 : :
9 : : #include <compiler.h>
10 : : #include <stdint.h>
11 : : #include <stdbool.h>
12 : : #include <string.h>
13 : : #include <stdlib.h>
14 : : #include <stdio.h>
15 : : #include <assert.h>
16 : : #include <errno.h>
17 : : #include <bitutils.h>
18 : : #include <types.h>
19 : :
20 : : #include <ccan/container_of/container_of.h>
21 : : #include <ccan/list/list.h>
22 : : #include <ccan/short_types/short_types.h>
23 : : #include <ccan/build_assert/build_assert.h>
24 : : #include <ccan/array_size/array_size.h>
25 : : #include <ccan/endian/endian.h>
26 : : #include <ccan/str/str.h>
27 : :
28 : : #include <libflash/blocklevel.h>
29 : :
30 : : #include <mem-map.h>
31 : : #include <op-panel.h>
32 : : #include <platform.h>
33 : :
34 : : /* Special ELF sections */
35 : : #define __force_data __section(".force.data")
36 : :
37 : : struct mem_region;
38 : : extern struct mem_region *mem_region_next(struct mem_region *region);
39 : :
40 : : /* Misc linker script symbols */
41 : : extern char _start[];
42 : : extern char _head_end[];
43 : : extern char _stext[];
44 : : extern char _etext[];
45 : : extern char __sym_map_end[];
46 : : extern char _romem_end[];
47 : :
48 : : #ifndef __TESTING__
49 : : /* Readonly section start and end. */
50 : : extern char __rodata_start[], __rodata_end[];
51 : :
52 : 1878 : static inline bool is_rodata(const void *p)
53 : : {
54 : 1878 : return ((const char *)p >= __rodata_start && (const char *)p < __rodata_end);
55 : : }
56 : : #else
57 : : static inline bool is_rodata(const void *p)
58 : : {
59 : : return false;
60 : : }
61 : : #endif
62 : :
63 : : /* Console logging
64 : : * Update console_get_level() if you add here
65 : : */
66 : : #define PR_EMERG 0
67 : : #define PR_ALERT 1
68 : : #define PR_CRIT 2
69 : : #define PR_ERR 3
70 : : #define PR_WARNING 4
71 : : #define PR_NOTICE 5
72 : : #define PR_PRINTF PR_NOTICE
73 : : #define PR_INFO 6
74 : : #define PR_DEBUG 7
75 : : #define PR_TRACE 8
76 : : #define PR_INSANE 9
77 : :
78 : : #ifndef pr_fmt
79 : : #define pr_fmt(fmt) fmt
80 : : #endif
81 : :
82 : : int vprlog(int log_level, const char *fmt, va_list ap);
83 : : void _prlog(int log_level, const char* fmt, ...) __attribute__((format (printf, 2, 3)));
84 : : #define prlog(l, f, ...) do { _prlog(l, pr_fmt(f), ##__VA_ARGS__); } while(0)
85 : : #define prerror(fmt...) do { prlog(PR_ERR, fmt); } while(0)
86 : : #define prlog_once(arg, ...) \
87 : : ({ \
88 : : static bool __prlog_once = false; \
89 : : if (!__prlog_once) { \
90 : : __prlog_once = true; \
91 : : prlog(arg, ##__VA_ARGS__); \
92 : : } \
93 : : })
94 : :
95 : : /* Location codes -- at most 80 chars with null termination */
96 : : #define LOC_CODE_SIZE 80
97 : :
98 : : /* Processor generation */
99 : : enum proc_gen {
100 : : proc_gen_unknown,
101 : : proc_gen_p8,
102 : : proc_gen_p9,
103 : : proc_gen_p10,
104 : : proc_gen_p11,
105 : : };
106 : : extern enum proc_gen proc_gen;
107 : :
108 : : extern bool lpar_per_core;
109 : :
110 : : extern unsigned int pcie_max_link_speed;
111 : :
112 : : /* Convert a 4-bit number to a hex char */
113 : : extern char __attrconst tohex(uint8_t nibble);
114 : :
115 : : #ifndef __TEST__
116 : : /* Bit position of the most significant 1-bit (LSB=0, MSB=63) */
117 : : static inline int ilog2(unsigned long val)
118 : : {
119 : : int left_zeros;
120 : :
121 : : asm volatile ("cntlzd %0,%1" : "=r" (left_zeros) : "r" (val));
122 : :
123 : : return 63 - left_zeros;
124 : : }
125 : :
126 : : static inline bool is_pow2(unsigned long val)
127 : : {
128 : : return val == (1ul << ilog2(val));
129 : : }
130 : : #endif
131 : :
132 : : #define lo32(x) ((x) & 0xffffffff)
133 : : #define hi32(x) (((x) >> 32) & 0xffffffff)
134 : :
135 : : /* WARNING: _a *MUST* be a power of two */
136 : : #define ALIGN_UP(_v, _a) (((_v) + (_a) - 1) & ~((_a) - 1))
137 : : #define ALIGN_DOWN(_v, _a) ((_v) & ~((_a) - 1))
138 : :
139 : : /* TCE alignment */
140 : : #define TCE_SHIFT 12
141 : : #define TCE_PSIZE (1ul << 12)
142 : : #define TCE_MASK (TCE_PSIZE - 1)
143 : :
144 : : /* Not the greatest variants but will do for now ... */
145 : : #define MIN(a, b) ((a) < (b) ? (a) : (b))
146 : : #define MAX(a, b) ((a) > (b) ? (a) : (b))
147 : :
148 : : /* PCI Geographical Addressing */
149 : : #define PCI_BUS_NUM(bdfn) (((bdfn) >> 8) & 0xff)
150 : : #define PCI_DEV(bdfn) (((bdfn) >> 3) & 0x1f)
151 : : #define PCI_FUNC(bdfn) ((bdfn) & 0x07)
152 : :
153 : : /*
154 : : * To help the FSP to distinguish between physical address and TCE mapped address.
155 : : * Also to help hostboot to distinguish physical and relative address.
156 : : */
157 : : #define HRMOR_BIT (1ul << 63)
158 : :
159 : : /* Clean the stray high bit which the FSP inserts: we only have 52 bits real */
160 : 53 : static inline u64 cleanup_addr(u64 addr)
161 : : {
162 : 53 : return addr & ((1ULL << 52) - 1);
163 : : }
164 : :
165 : : /* Start the kernel */
166 : : extern void start_kernel(uint64_t entry, void* fdt,
167 : : uint64_t mem_top) __noreturn;
168 : : extern void start_kernel32(uint64_t entry, void* fdt,
169 : : uint64_t mem_top) __noreturn;
170 : : extern void start_kernel_secondary(uint64_t entry) __noreturn;
171 : :
172 : : /* Re-set r16 register with CPU pointer, based on stack (r1) value */
173 : : extern void restore_cpu_ptr_r16(void);
174 : : /* Set r16 register with value in 'r16' parameter */
175 : : extern void set_cpu_ptr_r16(uint64_t r16);
176 : :
177 : : /* Get description of machine from HDAT and create device-tree */
178 : : extern int parse_hdat(bool is_opal);
179 : :
180 : : struct dt_node;
181 : :
182 : : /* Add /cpus/features node for boot environment that passes an fdt */
183 : : extern void dt_add_cpufeatures(struct dt_node *root);
184 : :
185 : : /* Root of device tree. */
186 : : extern struct dt_node *dt_root;
187 : :
188 : : /* Full skiboot version number (possibly includes gitid). */
189 : : extern const char version[];
190 : :
191 : : /* Debug support */
192 : : extern char __sym_map_start[];
193 : : extern char __sym_map_end[];
194 : : extern size_t snprintf_symbol(char *buf, size_t len, uint64_t addr);
195 : :
196 : : /* Direct controls */
197 : : extern void direct_controls_init(void);
198 : : extern int64_t opal_signal_system_reset(int cpu_nr);
199 : :
200 : : /* Fast reboot support */
201 : : extern void disable_fast_reboot(const char *reason);
202 : : extern void add_fast_reboot_dt_entries(void);
203 : : extern void fast_reboot(void);
204 : : extern void __noreturn __secondary_cpu_entry(void);
205 : : extern void __noreturn load_and_boot_kernel(bool is_reboot);
206 : : extern void cleanup_local_tlb(void);
207 : : extern void cleanup_global_tlb(void);
208 : : extern void init_shared_sprs(void);
209 : : extern void init_replicated_sprs(void);
210 : : extern bool start_preload_kernel(void);
211 : : extern void copy_exception_vectors(void);
212 : : extern void copy_sreset_vector(void);
213 : : extern void copy_sreset_vector_fast_reboot(void);
214 : : extern void patch_traps(bool enable);
215 : :
216 : : /* Various probe routines, to replace with an initcall system */
217 : : extern int preload_capp_ucode(void);
218 : : extern void preload_io_vpd(void);
219 : : extern void uart_init(void);
220 : : extern void mbox_init(void);
221 : : extern void early_uart_init(void);
222 : : extern void homer_init(void);
223 : : extern void add_cpu_idle_state_properties(void);
224 : : extern void lpc_rtc_init(void);
225 : :
226 : : /* flash support */
227 : : struct flash_chip;
228 : : extern int flash_register(struct blocklevel_device *bl);
229 : : extern int flash_start_preload_resource(enum resource_id id, uint32_t subid,
230 : : void *buf, size_t *len);
231 : : extern int flash_resource_loaded(enum resource_id id, uint32_t idx);
232 : : extern bool flash_reserve(void);
233 : : extern void flash_release(void);
234 : : extern bool flash_unregister(void);
235 : : #define FLASH_SUBPART_ALIGNMENT 0x1000
236 : : #define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT
237 : : extern int flash_subpart_info(void *part_header, uint32_t header_len,
238 : : uint32_t part_size, uint32_t *part_actual,
239 : : uint32_t subid, uint32_t *offset,
240 : : uint32_t *size);
241 : : extern void flash_fw_version_preload(void);
242 : : extern void flash_dt_add_fw_version(void);
243 : : extern const char *flash_map_resource_name(enum resource_id id);
244 : : extern int flash_secboot_info(uint32_t *total_size);
245 : : extern int flash_secboot_read(void *dst, uint32_t src, uint32_t len);
246 : : extern int flash_secboot_write(uint32_t dst, void *src, uint32_t len);
247 : :
248 : : /*
249 : : * Decompression routines
250 : : *
251 : : * The below structure members are needed for the xz library routines,
252 : : * src: Source address (The compressed binary)
253 : : * src_size: Source size
254 : : * dst: Destination address (The memory area where the `src` will be
255 : : * decompressed)
256 : : * dst_size: Destination size
257 : : */
258 : : struct xz_decompress {
259 : : void *dst;
260 : : void *src;
261 : : size_t dst_size;
262 : : size_t src_size;
263 : : /* The status of the decompress process:
264 : : - OPAL_PARTIAL: if the job is in progress
265 : : - OPAL_SUCCESS: if the job is successful
266 : : - OPAL_NO_MEM: memory allocation failure
267 : : - OPAL_PARAMETER: If any of the above (src, dst..) are invalid or
268 : : if xz decompress fails. In which case the caller should check the
269 : : xz_error for failure reason.
270 : : */
271 : : int status;
272 : : int xz_error;
273 : : /* The decompression job, this will be freed if the caller uses
274 : : * `wait_xz_decompression` function, in any other case its the
275 : : * responsibility of caller to free the allocation job. */
276 : : struct cpu_job *job;
277 : : };
278 : :
279 : : extern void xz_start_decompress(struct xz_decompress *);
280 : : extern void wait_xz_decompress(struct xz_decompress *);
281 : :
282 : : /* NVRAM support */
283 : : extern void nvram_init(void);
284 : : extern void nvram_read_complete(bool success);
285 : :
286 : : /* UART stuff */
287 : : enum {
288 : : UART_CONSOLE_OPAL,
289 : : UART_CONSOLE_OS
290 : : };
291 : : extern void uart_set_console_policy(int policy);
292 : : extern bool uart_enabled(void);
293 : :
294 : : /* PRD */
295 : : extern void prd_psi_interrupt(uint32_t proc);
296 : : extern void prd_tmgt_interrupt(uint32_t proc);
297 : : extern void prd_occ_reset(uint32_t proc);
298 : : extern void prd_sbe_passthrough(uint32_t proc);
299 : : extern void prd_init(void);
300 : : extern void prd_register_reserved_memory(void);
301 : : extern void prd_fsp_occ_reset(uint32_t proc);
302 : : extern void prd_fsp_occ_load_start(u32 proc);
303 : : extern void prd_fw_resp_fsp_response(int status);
304 : : extern int prd_hbrt_fsp_msg_notify(void *data, u32 dsize);
305 : :
306 : : /* Flatten device-tree */
307 : : extern void *create_dtb(const struct dt_node *root, bool exclusive);
308 : :
309 : : extern void nx_p9_rng_late_init(void);
310 : :
311 : : extern void fast_sleep_exit(void);
312 : :
313 : : /* Fallback fake RTC */
314 : : extern void fake_rtc_init(void);
315 : :
316 : : /* Exceptions */
317 : : struct stack_frame;
318 : : extern void exception_entry(struct stack_frame *stack);
319 : : extern void exception_entry_pm_sreset(void);
320 : : extern void __noreturn exception_entry_pm_mce(void);
321 : :
322 : : /* Assembly in head.S */
323 : : extern void disable_machine_check(void);
324 : : extern void enable_machine_check(void);
325 : : extern unsigned int enter_p8_pm_state(bool winkle);
326 : : extern unsigned int enter_p9_pm_state(uint64_t psscr);
327 : : extern void enter_p9_pm_lite_state(uint64_t psscr);
328 : : extern uint32_t reset_patch_start;
329 : : extern uint32_t reset_patch_end;
330 : : extern uint32_t reset_fast_reboot_patch_start;
331 : : extern uint32_t reset_fast_reboot_patch_end;
332 : :
333 : : /* Fallback fake NVRAM */
334 : : extern int fake_nvram_info(uint32_t *total_size);
335 : : extern int fake_nvram_start_read(void *dst, uint32_t src, uint32_t len);
336 : : extern int fake_nvram_write(uint32_t offset, void *src, uint32_t size);
337 : :
338 : : /*
339 : : * A bunch of hardware needs to be probed, sometimes in a particular order.
340 : : * Very simple dependency graph, with a even simpler way to resolve it.
341 : : * But it means we can now at link time choose what hardware we support.
342 : : * This struct should not be defined directly but with the macros.
343 : : */
344 : : struct hwprobe {
345 : : const char *name;
346 : : void (*probe)(void);
347 : :
348 : : bool probed;
349 : :
350 : : /* NULL or NULL-terminated array of strings */
351 : : const char **deps;
352 : : };
353 : :
354 : : #define DEFINE_HWPROBE(__name, __probe) \
355 : : static const struct hwprobe __used __section(".hwprobes") hwprobe_##__name = { \
356 : : .name = #__name, \
357 : : .probe = __probe, \
358 : : .deps = NULL, \
359 : : }
360 : :
361 : : #define DEFINE_HWPROBE_DEPS(__name, __probe, ...) \
362 : : static const struct hwprobe __used __section(".hwprobes") hwprobe_##__name = { \
363 : : .name = #__name, \
364 : : .probe = __probe, \
365 : : .deps = (const char *[]){ __VA_ARGS__, NULL}, \
366 : : }
367 : :
368 : : extern struct hwprobe __hwprobes_start;
369 : : extern struct hwprobe __hwprobes_end;
370 : :
371 : : extern void probe_hardware(void);
372 : :
373 : : #endif /* __SKIBOOT_H */
|