1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Global definition of all the bootwrapper operations. |
4 | * |
5 | * Author: Mark A. Greer <mgreer@mvista.com> |
6 | * |
7 | * 2006 (c) MontaVista Software, Inc. |
8 | */ |
9 | #ifndef _PPC_BOOT_OPS_H_ |
10 | #define _PPC_BOOT_OPS_H_ |
11 | |
12 | #include <stddef.h> |
13 | #include "types.h" |
14 | #include "string.h" |
15 | |
16 | #define BOOT_COMMAND_LINE_SIZE 2048 |
17 | #define MAX_PATH_LEN 256 |
18 | #define MAX_PROP_LEN 256 /* What should this be? */ |
19 | |
20 | typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5); |
21 | |
22 | /* Platform specific operations */ |
23 | struct platform_ops { |
24 | void (*fixups)(void); |
25 | void (*image_hdr)(const void *); |
26 | void * (*malloc)(unsigned long size); |
27 | void (*free)(void *ptr); |
28 | void * (*realloc)(void *ptr, unsigned long size); |
29 | void (*exit)(void); |
30 | void * (*vmlinux_alloc)(unsigned long size); |
31 | void (*kentry)(unsigned long fdt_addr, void *vmlinux_addr); |
32 | }; |
33 | extern struct platform_ops platform_ops; |
34 | |
35 | /* Device Tree operations */ |
36 | struct dt_ops { |
37 | void * (*finddevice)(const char *name); |
38 | int (*getprop)(const void *phandle, const char *name, void *buf, |
39 | const int buflen); |
40 | int (*setprop)(const void *phandle, const char *name, |
41 | const void *buf, const int buflen); |
42 | int (*del_node)(const void *phandle); |
43 | void *(*get_parent)(const void *phandle); |
44 | /* The node must not already exist. */ |
45 | void *(*create_node)(const void *parent, const char *name); |
46 | void *(*find_node_by_prop_value)(const void *prev, |
47 | const char *propname, |
48 | const char *propval, int proplen); |
49 | void *(*find_node_by_compatible)(const void *prev, |
50 | const char *compat); |
51 | unsigned long (*finalize)(void); |
52 | char *(*get_path)(const void *phandle, char *buf, int len); |
53 | }; |
54 | extern struct dt_ops dt_ops; |
55 | |
56 | /* Console operations */ |
57 | struct console_ops { |
58 | int (*open)(void); |
59 | void (*write)(const char *buf, int len); |
60 | void (*edit_cmdline)(char *buf, int len, unsigned int getline_timeout); |
61 | void (*close)(void); |
62 | void *data; |
63 | }; |
64 | extern struct console_ops console_ops; |
65 | |
66 | /* Serial console operations */ |
67 | struct serial_console_data { |
68 | int (*open)(void); |
69 | void (*putc)(unsigned char c); |
70 | unsigned char (*getc)(void); |
71 | u8 (*tstc)(void); |
72 | void (*close)(void); |
73 | }; |
74 | |
75 | struct loader_info { |
76 | void *promptr; |
77 | unsigned long initrd_addr, initrd_size; |
78 | char *cmdline; |
79 | int cmdline_len; |
80 | }; |
81 | extern struct loader_info loader_info; |
82 | |
83 | void start(void); |
84 | void fdt_init(void *blob); |
85 | int serial_console_init(void); |
86 | int ns16550_console_init(void *devp, struct serial_console_data *scdp); |
87 | int cpm_console_init(void *devp, struct serial_console_data *scdp); |
88 | int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp); |
89 | int opal_console_init(void *devp, struct serial_console_data *scdp); |
90 | void *simple_alloc_init(char *base, unsigned long heap_size, |
91 | unsigned long granularity, unsigned long max_allocs); |
92 | extern void flush_cache(void *, unsigned long); |
93 | int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size); |
94 | int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr); |
95 | int dt_is_compatible(void *node, const char *compat); |
96 | void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize); |
97 | int dt_get_virtual_reg(void *node, void **addr, int nres); |
98 | |
99 | static inline void *finddevice(const char *name) |
100 | { |
101 | return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL; |
102 | } |
103 | |
104 | static inline int getprop(void *devp, const char *name, void *buf, int buflen) |
105 | { |
106 | return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1; |
107 | } |
108 | |
109 | static inline int setprop(void *devp, const char *name, |
110 | const void *buf, int buflen) |
111 | { |
112 | return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1; |
113 | } |
114 | #define setprop_val(devp, name, val) \ |
115 | do { \ |
116 | typeof(val) x = (val); \ |
117 | setprop((devp), (name), &x, sizeof(x)); \ |
118 | } while (0) |
119 | |
120 | static inline int setprop_str(void *devp, const char *name, const char *buf) |
121 | { |
122 | if (dt_ops.setprop) |
123 | return dt_ops.setprop(devp, name, buf, strlen(buf) + 1); |
124 | |
125 | return -1; |
126 | } |
127 | |
128 | static inline int del_node(const void *devp) |
129 | { |
130 | return dt_ops.del_node ? dt_ops.del_node(devp) : -1; |
131 | } |
132 | |
133 | static inline void *get_parent(const char *devp) |
134 | { |
135 | return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL; |
136 | } |
137 | |
138 | static inline void *create_node(const void *parent, const char *name) |
139 | { |
140 | return dt_ops.create_node ? dt_ops.create_node(parent, name) : NULL; |
141 | } |
142 | |
143 | |
144 | static inline void *find_node_by_prop_value(const void *prev, |
145 | const char *propname, |
146 | const char *propval, int proplen) |
147 | { |
148 | if (dt_ops.find_node_by_prop_value) |
149 | return dt_ops.find_node_by_prop_value(prev, propname, |
150 | propval, proplen); |
151 | |
152 | return NULL; |
153 | } |
154 | |
155 | static inline void *find_node_by_prop_value_str(const void *prev, |
156 | const char *propname, |
157 | const char *propval) |
158 | { |
159 | return find_node_by_prop_value(prev, propname, propval, |
160 | proplen: strlen(propval) + 1); |
161 | } |
162 | |
163 | static inline void *find_node_by_devtype(const void *prev, |
164 | const char *type) |
165 | { |
166 | return find_node_by_prop_value_str(prev, propname: "device_type" , propval: type); |
167 | } |
168 | |
169 | static inline void *find_node_by_alias(const char *alias) |
170 | { |
171 | void *devp = finddevice(name: "/aliases" ); |
172 | |
173 | if (devp) { |
174 | char path[MAX_PATH_LEN]; |
175 | if (getprop(devp, name: alias, buf: path, MAX_PATH_LEN) > 0) |
176 | return finddevice(name: path); |
177 | } |
178 | |
179 | return NULL; |
180 | } |
181 | |
182 | static inline void *find_node_by_compatible(const void *prev, |
183 | const char *compat) |
184 | { |
185 | if (dt_ops.find_node_by_compatible) |
186 | return dt_ops.find_node_by_compatible(prev, compat); |
187 | |
188 | return NULL; |
189 | } |
190 | |
191 | void dt_fixup_memory(u64 start, u64 size); |
192 | void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq); |
193 | void dt_fixup_clock(const char *path, u32 freq); |
194 | void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr); |
195 | void dt_fixup_mac_address(u32 index, const u8 *addr); |
196 | void __dt_fixup_mac_addresses(u32 startindex, ...); |
197 | #define dt_fixup_mac_addresses(...) \ |
198 | __dt_fixup_mac_addresses(0, __VA_ARGS__, NULL) |
199 | |
200 | |
201 | static inline char *get_path(const void *phandle, char *buf, int len) |
202 | { |
203 | if (dt_ops.get_path) |
204 | return dt_ops.get_path(phandle, buf, len); |
205 | |
206 | return NULL; |
207 | } |
208 | |
209 | static inline void *malloc(unsigned long size) |
210 | { |
211 | return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; |
212 | } |
213 | |
214 | static inline void free(void *ptr) |
215 | { |
216 | if (platform_ops.free) |
217 | platform_ops.free(ptr); |
218 | } |
219 | |
220 | static inline void exit(void) |
221 | { |
222 | if (platform_ops.exit) |
223 | platform_ops.exit(); |
224 | for(;;); |
225 | } |
226 | #define fatal(args...) { printf(args); exit(); } |
227 | |
228 | |
229 | #define BSS_STACK(size) \ |
230 | static char _bss_stack[size]; \ |
231 | void *_platform_stack_top = _bss_stack + sizeof(_bss_stack); |
232 | |
233 | extern unsigned long timebase_period_ns; |
234 | void udelay(long delay); |
235 | |
236 | extern char _start[]; |
237 | extern char __bss_start[]; |
238 | extern char _end[]; |
239 | extern char _vmlinux_start[]; |
240 | extern char _vmlinux_end[]; |
241 | extern char _initrd_start[]; |
242 | extern char _initrd_end[]; |
243 | extern char _dtb_start[]; |
244 | extern char _dtb_end[]; |
245 | extern char _esm_blob_start[]; |
246 | extern char _esm_blob_end[]; |
247 | |
248 | static inline __attribute__((const)) |
249 | int __ilog2_u32(u32 n) |
250 | { |
251 | int bit; |
252 | asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n)); |
253 | return 31 - bit; |
254 | } |
255 | |
256 | long partial_decompress(void *inbuf, unsigned long input_size, void *outbuf, |
257 | unsigned long output_size, unsigned long skip); |
258 | |
259 | #endif /* _PPC_BOOT_OPS_H_ */ |
260 | |