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