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); |
a07940ba SW |
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); | |
b3bea15d KG |
49 | void *(*find_node_by_compatible)(const void *prev, |
50 | const char *compat); | |
35af89eb | 51 | unsigned long (*finalize)(void); |
21f3fe2f | 52 | char *(*get_path)(const void *phandle, char *buf, int len); |
b2c5f619 MG |
53 | }; |
54 | extern struct dt_ops dt_ops; | |
55 | ||
56 | /* Console operations */ | |
57 | struct console_ops { | |
58 | int (*open)(void); | |
b96fbb6e | 59 | void (*write)(const char *buf, int len); |
b2c5f619 MG |
60 | void (*edit_cmdline)(char *buf, int len); |
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 | ||
cd197ffc DG |
75 | struct loader_info { |
76 | void *promptr; | |
77 | unsigned long initrd_addr, initrd_size; | |
3af82a8b DG |
78 | char *cmdline; |
79 | int cmdline_len; | |
cd197ffc DG |
80 | }; |
81 | extern struct loader_info loader_info; | |
82 | ||
e5a2072b | 83 | void start(void); |
2f0dfeaa | 84 | void fdt_init(void *blob); |
c888554b MG |
85 | int serial_console_init(void); |
86 | int ns16550_console_init(void *devp, struct serial_console_data *scdp); | |
e12deb84 | 87 | int mpsc_console_init(void *devp, struct serial_console_data *scdp); |
d0f53faf | 88 | int cpm_console_init(void *devp, struct serial_console_data *scdp); |
85498ae8 | 89 | int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp); |
7ddc5f97 | 90 | int uartlite_console_init(void *devp, struct serial_console_data *scdp); |
4ca478e6 GU |
91 | void *simple_alloc_init(char *base, unsigned long heap_size, |
92 | unsigned long granularity, unsigned long max_allocs); | |
0e680673 | 93 | extern void flush_cache(void *, unsigned long); |
8895ea48 MG |
94 | int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size); |
95 | int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr); | |
a73ac50c | 96 | int dt_is_compatible(void *node, const char *compat); |
e5d8d54d | 97 | void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize); |
b2c5f619 MG |
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 | ||
f61e7cd2 SW |
109 | static inline int setprop(void *devp, const char *name, |
110 | const void *buf, int buflen) | |
b2c5f619 MG |
111 | { |
112 | return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1; | |
113 | } | |
27fbaa97 DG |
114 | #define setprop_val(devp, name, val) \ |
115 | do { \ | |
116 | typeof(val) x = (val); \ | |
117 | setprop((devp), (name), &x, sizeof(x)); \ | |
118 | } while (0) | |
b2c5f619 | 119 | |
a07940ba SW |
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 void *get_parent(const char *devp) | |
129 | { | |
130 | return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL; | |
131 | } | |
132 | ||
133 | static inline void *create_node(const void *parent, const char *name) | |
134 | { | |
135 | return dt_ops.create_node ? dt_ops.create_node(parent, name) : NULL; | |
136 | } | |
137 | ||
138 | ||
139 | static inline void *find_node_by_prop_value(const void *prev, | |
140 | const char *propname, | |
141 | const char *propval, int proplen) | |
142 | { | |
143 | if (dt_ops.find_node_by_prop_value) | |
144 | return dt_ops.find_node_by_prop_value(prev, propname, | |
145 | propval, proplen); | |
146 | ||
147 | return NULL; | |
148 | } | |
149 | ||
150 | static inline void *find_node_by_prop_value_str(const void *prev, | |
151 | const char *propname, | |
152 | const char *propval) | |
153 | { | |
154 | return find_node_by_prop_value(prev, propname, propval, | |
155 | strlen(propval) + 1); | |
156 | } | |
157 | ||
158 | static inline void *find_node_by_devtype(const void *prev, | |
159 | const char *type) | |
160 | { | |
161 | return find_node_by_prop_value_str(prev, "device_type", type); | |
162 | } | |
163 | ||
ad160681 KG |
164 | static inline void *find_node_by_alias(const char *alias) |
165 | { | |
166 | void *devp = finddevice("/aliases"); | |
167 | ||
168 | if (devp) { | |
169 | char path[MAX_PATH_LEN]; | |
170 | if (getprop(devp, alias, path, MAX_PATH_LEN) > 0) | |
171 | return finddevice(path); | |
172 | } | |
173 | ||
174 | return NULL; | |
175 | } | |
176 | ||
b3bea15d KG |
177 | static inline void *find_node_by_compatible(const void *prev, |
178 | const char *compat) | |
179 | { | |
180 | if (dt_ops.find_node_by_compatible) | |
181 | return dt_ops.find_node_by_compatible(prev, compat); | |
182 | ||
183 | return NULL; | |
184 | } | |
185 | ||
27fbaa97 DG |
186 | void dt_fixup_memory(u64 start, u64 size); |
187 | void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq); | |
188 | void dt_fixup_clock(const char *path, u32 freq); | |
ad160681 | 189 | void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr); |
27ff35d9 | 190 | void dt_fixup_mac_address(u32 index, const u8 *addr); |
27fbaa97 DG |
191 | void __dt_fixup_mac_addresses(u32 startindex, ...); |
192 | #define dt_fixup_mac_addresses(...) \ | |
193 | __dt_fixup_mac_addresses(0, __VA_ARGS__, NULL) | |
194 | ||
195 | ||
d6f1d2a9 MG |
196 | static inline void *find_node_by_linuxphandle(const u32 linuxphandle) |
197 | { | |
198 | return find_node_by_prop_value(NULL, "linux,phandle", | |
199 | (char *)&linuxphandle, sizeof(u32)); | |
200 | } | |
201 | ||
21f3fe2f SW |
202 | static inline char *get_path(const void *phandle, char *buf, int len) |
203 | { | |
204 | if (dt_ops.get_path) | |
205 | return dt_ops.get_path(phandle, buf, len); | |
206 | ||
207 | return NULL; | |
208 | } | |
209 | ||
4ca478e6 | 210 | static inline void *malloc(unsigned long size) |
b2c5f619 MG |
211 | { |
212 | return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; | |
213 | } | |
214 | ||
c888554b | 215 | static inline void free(void *ptr) |
b2c5f619 MG |
216 | { |
217 | if (platform_ops.free) | |
c888554b | 218 | platform_ops.free(ptr); |
b2c5f619 MG |
219 | } |
220 | ||
221 | static inline void exit(void) | |
222 | { | |
223 | if (platform_ops.exit) | |
224 | platform_ops.exit(); | |
225 | for(;;); | |
226 | } | |
6a923216 MM |
227 | #define fatal(args...) { printf(args); exit(); } |
228 | ||
b2c5f619 | 229 | |
cd197ffc DG |
230 | #define BSS_STACK(size) \ |
231 | static char _bss_stack[size]; \ | |
232 | void *_platform_stack_top = _bss_stack + sizeof(_bss_stack); | |
233 | ||
643d3c13 | 234 | extern unsigned long timebase_period_ns; |
3ee9b7ab | 235 | void udelay(long delay); |
643d3c13 | 236 | |
2f1d4899 SW |
237 | extern char _start[]; |
238 | extern char __bss_start[]; | |
239 | extern char _end[]; | |
240 | extern char _vmlinux_start[]; | |
241 | extern char _vmlinux_end[]; | |
242 | extern char _initrd_start[]; | |
243 | extern char _initrd_end[]; | |
244 | extern char _dtb_start[]; | |
245 | extern char _dtb_end[]; | |
246 | ||
e5d8d54d SW |
247 | static inline __attribute__((const)) |
248 | int __ilog2_u32(u32 n) | |
249 | { | |
250 | int bit; | |
251 | asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n)); | |
252 | return 31 - bit; | |
253 | } | |
254 | ||
b2c5f619 | 255 | #endif /* _PPC_BOOT_OPS_H_ */ |