1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
/* Copyright 2013-2014 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __SKIBOOT_H
#define __SKIBOOT_H
#include <compiler.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <bitutils.h>
#include <types.h>
#include <ccan/container_of/container_of.h>
#include <ccan/list/list.h>
#include <ccan/short_types/short_types.h>
#include <ccan/build_assert/build_assert.h>
#include <ccan/array_size/array_size.h>
#include <ccan/endian/endian.h>
#include <ccan/str/str.h>
#include <libflash/blocklevel.h>
#include <mem-map.h>
#include <op-panel.h>
#include <platform.h>
/* Special ELF sections */
#define __force_data __section(".force.data")
struct mem_region;
extern struct mem_region *mem_region_next(struct mem_region *region);
#ifndef __TESTING__
/* Readonly section start and end. */
extern char __rodata_start[], __rodata_end[];
static inline bool is_rodata(const void *p)
{
return ((const char *)p >= __rodata_start && (const char *)p < __rodata_end);
}
#else
static inline bool is_rodata(const void *p)
{
return false;
}
#endif
#define OPAL_BOOT_COMPLETE 0x1
/* Debug descriptor. This structure is pointed to by the word at offset
* 0x80 in the sapphire binary
*/
struct debug_descriptor {
u8 eye_catcher[8]; /* "OPALdbug" */
#define DEBUG_DESC_VERSION 1
u32 version;
u8 console_log_levels; /* high 4 bits in memory,
* low 4 bits driver (e.g. uart). */
u8 state_flags; /* various state flags - OPAL_BOOT_COMPLETE etc */
u16 reserved2;
u32 reserved[2];
/* Memory console */
u64 memcons_phys;
u32 memcons_tce;
u32 memcons_obuf_tce;
u32 memcons_ibuf_tce;
/* Traces */
u64 trace_mask;
u32 num_traces;
#define DEBUG_DESC_MAX_TRACES 256
u64 trace_phys[DEBUG_DESC_MAX_TRACES];
u32 trace_size[DEBUG_DESC_MAX_TRACES];
u32 trace_tce[DEBUG_DESC_MAX_TRACES];
};
extern struct debug_descriptor debug_descriptor;
static inline bool opal_booting(void)
{
return !(debug_descriptor.state_flags & OPAL_BOOT_COMPLETE);
}
/* Console logging
* Update console_get_level() if you add here
*/
#define PR_EMERG 0
#define PR_ALERT 1
#define PR_CRIT 2
#define PR_ERR 3
#define PR_WARNING 4
#define PR_NOTICE 5
#define PR_PRINTF PR_NOTICE
#define PR_INFO 6
#define PR_DEBUG 7
#define PR_TRACE 8
#define PR_INSANE 9
#ifndef pr_fmt
#define pr_fmt(fmt) fmt
#endif
void _prlog(int log_level, const char* fmt, ...) __attribute__((format (printf, 2, 3)));
#define prlog(l, f, ...) do { _prlog(l, pr_fmt(f), ##__VA_ARGS__); } while(0)
#define prerror(fmt...) do { prlog(PR_ERR, fmt); } while(0)
#define prlog_once(arg, ...) \
({ \
static bool __prlog_once = false; \
if (!__prlog_once) { \
__prlog_once = true; \
prlog(arg, ##__VA_ARGS__); \
} \
})
/* Location codes -- at most 80 chars with null termination */
#define LOC_CODE_SIZE 80
/* Processor generation */
enum proc_gen {
proc_gen_unknown,
proc_gen_p7, /* P7 and P7+ */
proc_gen_p8,
proc_gen_p9,
};
extern enum proc_gen proc_gen;
extern unsigned int pcie_max_link_speed;
/* Convert a 4-bit number to a hex char */
extern char __attrconst tohex(uint8_t nibble);
#ifndef __TEST__
/* Bit position of the most significant 1-bit (LSB=0, MSB=63) */
static inline int ilog2(unsigned long val)
{
int left_zeros;
asm volatile ("cntlzd %0,%1" : "=r" (left_zeros) : "r" (val));
return 63 - left_zeros;
}
static inline bool is_pow2(unsigned long val)
{
return val == (1ul << ilog2(val));
}
#endif
#define lo32(x) ((x) & 0xffffffff)
#define hi32(x) (((x) >> 32) & 0xffffffff)
/* WARNING: _a *MUST* be a power of two */
#define ALIGN_UP(_v, _a) (((_v) + (_a) - 1) & ~((_a) - 1))
#define ALIGN_DOWN(_v, _a) ((_v) & ~((_a) - 1))
/* TCE alignment */
#define TCE_SHIFT 12
#define TCE_PSIZE (1ul << 12)
#define TCE_MASK (TCE_PSIZE - 1)
/* Not the greatest variants but will do for now ... */
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
/* Clean the stray high bit which the FSP inserts: we only have 52 bits real */
static inline u64 cleanup_addr(u64 addr)
{
return addr & ((1ULL << 52) - 1);
}
/* Start the kernel */
extern void start_kernel(uint64_t entry, void* fdt,
uint64_t mem_top) __noreturn;
extern void start_kernel32(uint64_t entry, void* fdt,
uint64_t mem_top) __noreturn;
extern void start_kernel_secondary(uint64_t entry) __noreturn;
/* Get description of machine from HDAT and create device-tree */
extern int parse_hdat(bool is_opal);
struct dt_node;
/* Add /cpus/features node for boot environment that passes an fdt */
extern void dt_add_cpufeatures(struct dt_node *root);
/* Root of device tree. */
extern struct dt_node *dt_root;
/* Full skiboot version number (possibly includes gitid). */
extern const char version[];
/* Debug support */
extern char __sym_map_start[];
extern char __sym_map_end[];
extern size_t snprintf_symbol(char *buf, size_t len, uint64_t addr);
/* Direct controls */
extern void direct_controls_init(void);
extern int64_t opal_signal_system_reset(int cpu_nr);
/* Fast reboot support */
extern void disable_fast_reboot(const char *reason);
extern void add_fast_reboot_dt_entries(void);
extern void fast_reboot(void);
extern void __noreturn __secondary_cpu_entry(void);
extern void __noreturn load_and_boot_kernel(bool is_reboot);
extern void cleanup_local_tlb(void);
extern void cleanup_global_tlb(void);
extern void init_shared_sprs(void);
extern void init_replicated_sprs(void);
extern bool start_preload_kernel(void);
extern void copy_exception_vectors(void);
extern void setup_reset_vector(void);
/* Various probe routines, to replace with an initcall system */
extern void probe_p7ioc(void);
extern void probe_phb3(void);
extern void probe_phb4(void);
extern int preload_capp_ucode(void);
extern void preload_io_vpd(void);
extern void probe_npu(void);
extern void probe_npu2(void);
extern void probe_npu2_opencapi(void);
extern void uart_init(void);
extern void mbox_init(void);
extern void early_uart_init(void);
extern void homer_init(void);
extern void occ_pstates_init(void);
extern void slw_init(void);
extern void add_cpu_idle_state_properties(void);
extern void occ_fsp_init(void);
extern void lpc_rtc_init(void);
/* flash support */
struct flash_chip;
extern int flash_register(struct blocklevel_device *bl);
extern int flash_start_preload_resource(enum resource_id id, uint32_t subid,
void *buf, size_t *len);
extern int flash_resource_loaded(enum resource_id id, uint32_t idx);
extern bool flash_reserve(void);
extern void flash_release(void);
#define FLASH_SUBPART_ALIGNMENT 0x1000
#define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT
extern int flash_subpart_info(void *part_header, uint32_t header_len,
uint32_t part_size, uint32_t *part_actual,
uint32_t subid, uint32_t *offset,
uint32_t *size);
extern void flash_fw_version_preload(void);
extern void flash_dt_add_fw_version(void);
extern const char *flash_map_resource_name(enum resource_id id);
/* NVRAM support */
extern void nvram_init(void);
extern void nvram_read_complete(bool success);
/* UART stuff */
enum {
UART_CONSOLE_OPAL,
UART_CONSOLE_OS
};
extern void uart_set_console_policy(int policy);
extern bool uart_enabled(void);
/* OCC interrupt for P8 */
extern void occ_p8_interrupt(uint32_t chip_id);
extern void occ_send_dummy_interrupt(void);
/* OCC interrupt for P9 */
extern void occ_p9_interrupt(uint32_t chip_id);
/* OCC load support */
extern void occ_poke_load_queue(void);
/* OCC/Host PNOR ownership */
enum pnor_owner {
PNOR_OWNER_HOST,
PNOR_OWNER_EXTERNAL,
};
extern void occ_pnor_set_owner(enum pnor_owner owner);
/* PRD */
extern void prd_psi_interrupt(uint32_t proc);
extern void prd_tmgt_interrupt(uint32_t proc);
extern void prd_occ_reset(uint32_t proc);
extern void prd_sbe_passthrough(uint32_t proc);
extern void prd_init(void);
extern void prd_register_reserved_memory(void);
extern void prd_fsp_occ_reset(uint32_t proc);
extern void prd_fsp_occ_load_start(u32 proc);
/* Flatten device-tree */
extern void *create_dtb(const struct dt_node *root, bool exclusive);
/* Track failure in Wakup engine */
enum wakeup_engine_states {
WAKEUP_ENGINE_NOT_PRESENT,
WAKEUP_ENGINE_PRESENT,
WAKEUP_ENGINE_FAILED
};
extern enum wakeup_engine_states wakeup_engine_state;
extern bool has_deep_states;
extern void nx_p9_rng_late_init(void);
extern void xive_late_init(void);
/* SLW reinit function for switching core settings */
extern int64_t slw_reinit(uint64_t flags);
/* Patch SPR in SLW image */
extern int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val);
extern void fast_sleep_exit(void);
/* Fallback fake RTC */
extern void fake_rtc_init(void);
/* Assembly in head.S */
extern void disable_machine_check(void);
extern void enable_machine_check(void);
extern void enter_p8_pm_state(bool winkle);
extern void enter_p9_pm_state(uint64_t psscr);
extern void enter_p9_pm_lite_state(uint64_t psscr);
extern uint32_t reset_patch_start;
extern uint32_t reset_patch_end;
/* Fallback fake NVRAM */
extern int fake_nvram_info(uint32_t *total_size);
extern int fake_nvram_start_read(void *dst, uint32_t src, uint32_t len);
extern int fake_nvram_write(uint32_t offset, void *src, uint32_t size);
/* OCC Inband Sensors */
extern bool occ_sensors_init(void);
extern int occ_sensor_read(u32 handle, u64 *data);
extern int occ_sensor_group_clear(u32 group_hndl, int token);
extern void occ_add_sensor_groups(struct dt_node *sg, u32 *phandles,
u32 *ptype, int nr_phandles, int chipid);
extern int occ_sensor_group_enable(u32 group_hndl, int token, bool enable);
#endif /* __SKIBOOT_H */
|