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