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