18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Global definition of all the bootwrapper operations.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Author: Mark A. Greer <mgreer@mvista.com>
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * 2006 (c) MontaVista Software, Inc.  This file is licensed under
78c2ecf20Sopenharmony_ci * the terms of the GNU General Public License version 2.  This program
88c2ecf20Sopenharmony_ci * is licensed "as is" without any warranty of any kind, whether express
98c2ecf20Sopenharmony_ci * or implied.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci#ifndef _PPC_BOOT_OPS_H_
128c2ecf20Sopenharmony_ci#define _PPC_BOOT_OPS_H_
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <stddef.h>
158c2ecf20Sopenharmony_ci#include "types.h"
168c2ecf20Sopenharmony_ci#include "string.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#define	BOOT_COMMAND_LINE_SIZE	2048
198c2ecf20Sopenharmony_ci#define	MAX_PATH_LEN		256
208c2ecf20Sopenharmony_ci#define	MAX_PROP_LEN		256 /* What should this be? */
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_citypedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5);
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/* Platform specific operations */
258c2ecf20Sopenharmony_cistruct platform_ops {
268c2ecf20Sopenharmony_ci	void	(*fixups)(void);
278c2ecf20Sopenharmony_ci	void	(*image_hdr)(const void *);
288c2ecf20Sopenharmony_ci	void *	(*malloc)(unsigned long size);
298c2ecf20Sopenharmony_ci	void	(*free)(void *ptr);
308c2ecf20Sopenharmony_ci	void *	(*realloc)(void *ptr, unsigned long size);
318c2ecf20Sopenharmony_ci	void	(*exit)(void);
328c2ecf20Sopenharmony_ci	void *	(*vmlinux_alloc)(unsigned long size);
338c2ecf20Sopenharmony_ci	void  	(*kentry)(unsigned long fdt_addr, void *vmlinux_addr);
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ciextern struct platform_ops platform_ops;
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/* Device Tree operations */
388c2ecf20Sopenharmony_cistruct dt_ops {
398c2ecf20Sopenharmony_ci	void *	(*finddevice)(const char *name);
408c2ecf20Sopenharmony_ci	int	(*getprop)(const void *phandle, const char *name, void *buf,
418c2ecf20Sopenharmony_ci			const int buflen);
428c2ecf20Sopenharmony_ci	int	(*setprop)(const void *phandle, const char *name,
438c2ecf20Sopenharmony_ci			const void *buf, const int buflen);
448c2ecf20Sopenharmony_ci	int (*del_node)(const void *phandle);
458c2ecf20Sopenharmony_ci	void *(*get_parent)(const void *phandle);
468c2ecf20Sopenharmony_ci	/* The node must not already exist. */
478c2ecf20Sopenharmony_ci	void *(*create_node)(const void *parent, const char *name);
488c2ecf20Sopenharmony_ci	void *(*find_node_by_prop_value)(const void *prev,
498c2ecf20Sopenharmony_ci	                                 const char *propname,
508c2ecf20Sopenharmony_ci	                                 const char *propval, int proplen);
518c2ecf20Sopenharmony_ci	void *(*find_node_by_compatible)(const void *prev,
528c2ecf20Sopenharmony_ci	                                 const char *compat);
538c2ecf20Sopenharmony_ci	unsigned long (*finalize)(void);
548c2ecf20Sopenharmony_ci	char *(*get_path)(const void *phandle, char *buf, int len);
558c2ecf20Sopenharmony_ci};
568c2ecf20Sopenharmony_ciextern struct dt_ops dt_ops;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci/* Console operations */
598c2ecf20Sopenharmony_cistruct console_ops {
608c2ecf20Sopenharmony_ci	int	(*open)(void);
618c2ecf20Sopenharmony_ci	void	(*write)(const char *buf, int len);
628c2ecf20Sopenharmony_ci	void	(*edit_cmdline)(char *buf, int len, unsigned int getline_timeout);
638c2ecf20Sopenharmony_ci	void	(*close)(void);
648c2ecf20Sopenharmony_ci	void	*data;
658c2ecf20Sopenharmony_ci};
668c2ecf20Sopenharmony_ciextern struct console_ops console_ops;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci/* Serial console operations */
698c2ecf20Sopenharmony_cistruct serial_console_data {
708c2ecf20Sopenharmony_ci	int		(*open)(void);
718c2ecf20Sopenharmony_ci	void		(*putc)(unsigned char c);
728c2ecf20Sopenharmony_ci	unsigned char	(*getc)(void);
738c2ecf20Sopenharmony_ci	u8		(*tstc)(void);
748c2ecf20Sopenharmony_ci	void		(*close)(void);
758c2ecf20Sopenharmony_ci};
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_cistruct loader_info {
788c2ecf20Sopenharmony_ci	void *promptr;
798c2ecf20Sopenharmony_ci	unsigned long initrd_addr, initrd_size;
808c2ecf20Sopenharmony_ci	char *cmdline;
818c2ecf20Sopenharmony_ci	int cmdline_len;
828c2ecf20Sopenharmony_ci};
838c2ecf20Sopenharmony_ciextern struct loader_info loader_info;
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_civoid start(void);
868c2ecf20Sopenharmony_civoid fdt_init(void *blob);
878c2ecf20Sopenharmony_ciint serial_console_init(void);
888c2ecf20Sopenharmony_ciint ns16550_console_init(void *devp, struct serial_console_data *scdp);
898c2ecf20Sopenharmony_ciint cpm_console_init(void *devp, struct serial_console_data *scdp);
908c2ecf20Sopenharmony_ciint mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp);
918c2ecf20Sopenharmony_ciint opal_console_init(void *devp, struct serial_console_data *scdp);
928c2ecf20Sopenharmony_civoid *simple_alloc_init(char *base, unsigned long heap_size,
938c2ecf20Sopenharmony_ci			unsigned long granularity, unsigned long max_allocs);
948c2ecf20Sopenharmony_ciextern void flush_cache(void *, unsigned long);
958c2ecf20Sopenharmony_ciint dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
968c2ecf20Sopenharmony_ciint dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
978c2ecf20Sopenharmony_ciint dt_is_compatible(void *node, const char *compat);
988c2ecf20Sopenharmony_civoid dt_get_reg_format(void *node, u32 *naddr, u32 *nsize);
998c2ecf20Sopenharmony_ciint dt_get_virtual_reg(void *node, void **addr, int nres);
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistatic inline void *finddevice(const char *name)
1028c2ecf20Sopenharmony_ci{
1038c2ecf20Sopenharmony_ci	return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
1048c2ecf20Sopenharmony_ci}
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_cistatic inline int getprop(void *devp, const char *name, void *buf, int buflen)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci	return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1;
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cistatic inline int setprop(void *devp, const char *name,
1128c2ecf20Sopenharmony_ci                          const void *buf, int buflen)
1138c2ecf20Sopenharmony_ci{
1148c2ecf20Sopenharmony_ci	return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1;
1158c2ecf20Sopenharmony_ci}
1168c2ecf20Sopenharmony_ci#define setprop_val(devp, name, val) \
1178c2ecf20Sopenharmony_ci	do { \
1188c2ecf20Sopenharmony_ci		typeof(val) x = (val); \
1198c2ecf20Sopenharmony_ci		setprop((devp), (name), &x, sizeof(x)); \
1208c2ecf20Sopenharmony_ci	} while (0)
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cistatic inline int setprop_str(void *devp, const char *name, const char *buf)
1238c2ecf20Sopenharmony_ci{
1248c2ecf20Sopenharmony_ci	if (dt_ops.setprop)
1258c2ecf20Sopenharmony_ci		return dt_ops.setprop(devp, name, buf, strlen(buf) + 1);
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	return -1;
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic inline int del_node(const void *devp)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	return dt_ops.del_node ? dt_ops.del_node(devp) : -1;
1338c2ecf20Sopenharmony_ci}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_cistatic inline void *get_parent(const char *devp)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL;
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistatic inline void *create_node(const void *parent, const char *name)
1418c2ecf20Sopenharmony_ci{
1428c2ecf20Sopenharmony_ci	return dt_ops.create_node ? dt_ops.create_node(parent, name) : NULL;
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_cistatic inline void *find_node_by_prop_value(const void *prev,
1478c2ecf20Sopenharmony_ci                                            const char *propname,
1488c2ecf20Sopenharmony_ci                                            const char *propval, int proplen)
1498c2ecf20Sopenharmony_ci{
1508c2ecf20Sopenharmony_ci	if (dt_ops.find_node_by_prop_value)
1518c2ecf20Sopenharmony_ci		return dt_ops.find_node_by_prop_value(prev, propname,
1528c2ecf20Sopenharmony_ci		                                      propval, proplen);
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	return NULL;
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic inline void *find_node_by_prop_value_str(const void *prev,
1588c2ecf20Sopenharmony_ci                                                const char *propname,
1598c2ecf20Sopenharmony_ci                                                const char *propval)
1608c2ecf20Sopenharmony_ci{
1618c2ecf20Sopenharmony_ci	return find_node_by_prop_value(prev, propname, propval,
1628c2ecf20Sopenharmony_ci	                               strlen(propval) + 1);
1638c2ecf20Sopenharmony_ci}
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_cistatic inline void *find_node_by_devtype(const void *prev,
1668c2ecf20Sopenharmony_ci                                         const char *type)
1678c2ecf20Sopenharmony_ci{
1688c2ecf20Sopenharmony_ci	return find_node_by_prop_value_str(prev, "device_type", type);
1698c2ecf20Sopenharmony_ci}
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_cistatic inline void *find_node_by_alias(const char *alias)
1728c2ecf20Sopenharmony_ci{
1738c2ecf20Sopenharmony_ci	void *devp = finddevice("/aliases");
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	if (devp) {
1768c2ecf20Sopenharmony_ci		char path[MAX_PATH_LEN];
1778c2ecf20Sopenharmony_ci		if (getprop(devp, alias, path, MAX_PATH_LEN) > 0)
1788c2ecf20Sopenharmony_ci			return finddevice(path);
1798c2ecf20Sopenharmony_ci	}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	return NULL;
1828c2ecf20Sopenharmony_ci}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_cistatic inline void *find_node_by_compatible(const void *prev,
1858c2ecf20Sopenharmony_ci                                            const char *compat)
1868c2ecf20Sopenharmony_ci{
1878c2ecf20Sopenharmony_ci	if (dt_ops.find_node_by_compatible)
1888c2ecf20Sopenharmony_ci		return dt_ops.find_node_by_compatible(prev, compat);
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	return NULL;
1918c2ecf20Sopenharmony_ci}
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_civoid dt_fixup_memory(u64 start, u64 size);
1948c2ecf20Sopenharmony_civoid dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq);
1958c2ecf20Sopenharmony_civoid dt_fixup_clock(const char *path, u32 freq);
1968c2ecf20Sopenharmony_civoid dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr);
1978c2ecf20Sopenharmony_civoid dt_fixup_mac_address(u32 index, const u8 *addr);
1988c2ecf20Sopenharmony_civoid __dt_fixup_mac_addresses(u32 startindex, ...);
1998c2ecf20Sopenharmony_ci#define dt_fixup_mac_addresses(...) \
2008c2ecf20Sopenharmony_ci	__dt_fixup_mac_addresses(0, __VA_ARGS__, NULL)
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic inline void *find_node_by_linuxphandle(const u32 linuxphandle)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	return find_node_by_prop_value(NULL, "linux,phandle",
2068c2ecf20Sopenharmony_ci			(char *)&linuxphandle, sizeof(u32));
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_cistatic inline char *get_path(const void *phandle, char *buf, int len)
2108c2ecf20Sopenharmony_ci{
2118c2ecf20Sopenharmony_ci	if (dt_ops.get_path)
2128c2ecf20Sopenharmony_ci		return dt_ops.get_path(phandle, buf, len);
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	return NULL;
2158c2ecf20Sopenharmony_ci}
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_cistatic inline void *malloc(unsigned long size)
2188c2ecf20Sopenharmony_ci{
2198c2ecf20Sopenharmony_ci	return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
2208c2ecf20Sopenharmony_ci}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistatic inline void free(void *ptr)
2238c2ecf20Sopenharmony_ci{
2248c2ecf20Sopenharmony_ci	if (platform_ops.free)
2258c2ecf20Sopenharmony_ci		platform_ops.free(ptr);
2268c2ecf20Sopenharmony_ci}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_cistatic inline void exit(void)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	if (platform_ops.exit)
2318c2ecf20Sopenharmony_ci		platform_ops.exit();
2328c2ecf20Sopenharmony_ci	for(;;);
2338c2ecf20Sopenharmony_ci}
2348c2ecf20Sopenharmony_ci#define fatal(args...) { printf(args); exit(); }
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci#define BSS_STACK(size) \
2388c2ecf20Sopenharmony_ci	static char _bss_stack[size]; \
2398c2ecf20Sopenharmony_ci	void *_platform_stack_top = _bss_stack + sizeof(_bss_stack);
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ciextern unsigned long timebase_period_ns;
2428c2ecf20Sopenharmony_civoid udelay(long delay);
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ciextern char _start[];
2458c2ecf20Sopenharmony_ciextern char __bss_start[];
2468c2ecf20Sopenharmony_ciextern char _end[];
2478c2ecf20Sopenharmony_ciextern char _vmlinux_start[];
2488c2ecf20Sopenharmony_ciextern char _vmlinux_end[];
2498c2ecf20Sopenharmony_ciextern char _initrd_start[];
2508c2ecf20Sopenharmony_ciextern char _initrd_end[];
2518c2ecf20Sopenharmony_ciextern char _dtb_start[];
2528c2ecf20Sopenharmony_ciextern char _dtb_end[];
2538c2ecf20Sopenharmony_ciextern char _esm_blob_start[];
2548c2ecf20Sopenharmony_ciextern char _esm_blob_end[];
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_cistatic inline __attribute__((const))
2578c2ecf20Sopenharmony_ciint __ilog2_u32(u32 n)
2588c2ecf20Sopenharmony_ci{
2598c2ecf20Sopenharmony_ci	int bit;
2608c2ecf20Sopenharmony_ci	asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n));
2618c2ecf20Sopenharmony_ci	return 31 - bit;
2628c2ecf20Sopenharmony_ci}
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_cilong partial_decompress(void *inbuf, unsigned long input_size, void *outbuf,
2658c2ecf20Sopenharmony_ci	unsigned long output_size, unsigned long skip);
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci#endif /* _PPC_BOOT_OPS_H_ */
268