1d4abc757SPeter Tyser /* 2d4abc757SPeter Tyser * (C) Copyright 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com> 3d4abc757SPeter Tyser * 41a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 5d4abc757SPeter Tyser */ 6d4abc757SPeter Tyser 7d4abc757SPeter Tyser #include <common.h> 8d4abc757SPeter Tyser #include <linux/types.h> 9d4abc757SPeter Tyser #include <api_public.h> 10d4abc757SPeter Tyser 11d4abc757SPeter Tyser #include "glue.h" 12d4abc757SPeter Tyser 13d4abc757SPeter Tyser static int valid_sig(struct api_signature *sig) 14d4abc757SPeter Tyser { 15d4abc757SPeter Tyser uint32_t checksum; 16d4abc757SPeter Tyser struct api_signature s; 17d4abc757SPeter Tyser 18d4abc757SPeter Tyser if (sig == NULL) 19d4abc757SPeter Tyser return 0; 20d4abc757SPeter Tyser /* 21d4abc757SPeter Tyser * Clear the checksum field (in the local copy) so as to calculate the 22d4abc757SPeter Tyser * CRC with the same initial contents as at the time when the sig was 23d4abc757SPeter Tyser * produced 24d4abc757SPeter Tyser */ 25d4abc757SPeter Tyser s = *sig; 26d4abc757SPeter Tyser s.checksum = 0; 27d4abc757SPeter Tyser 28d4abc757SPeter Tyser checksum = crc32(0, (unsigned char *)&s, sizeof(struct api_signature)); 29d4abc757SPeter Tyser 30d4abc757SPeter Tyser if (checksum != sig->checksum) 31d4abc757SPeter Tyser return 0; 32d4abc757SPeter Tyser 33d4abc757SPeter Tyser return 1; 34d4abc757SPeter Tyser } 35d4abc757SPeter Tyser 36d4abc757SPeter Tyser /* 37d4abc757SPeter Tyser * Searches for the U-Boot API signature 38d4abc757SPeter Tyser * 39d4abc757SPeter Tyser * returns 1/0 depending on found/not found result 40d4abc757SPeter Tyser */ 41d4abc757SPeter Tyser int api_search_sig(struct api_signature **sig) 42d4abc757SPeter Tyser { 43d4abc757SPeter Tyser unsigned char *sp; 44d4abc757SPeter Tyser uint32_t search_start = 0; 45d4abc757SPeter Tyser uint32_t search_end = 0; 46d4abc757SPeter Tyser 47d4abc757SPeter Tyser if (sig == NULL) 48d4abc757SPeter Tyser return 0; 49d4abc757SPeter Tyser 50d4abc757SPeter Tyser if (search_hint == 0) 51d4abc757SPeter Tyser search_hint = 255 * 1024 * 1024; 52d4abc757SPeter Tyser 53d4abc757SPeter Tyser search_start = search_hint & ~0x000fffff; 54d4abc757SPeter Tyser search_end = search_start + API_SEARCH_LEN - API_SIG_MAGLEN; 55d4abc757SPeter Tyser 56d4abc757SPeter Tyser sp = (unsigned char *)search_start; 57d4abc757SPeter Tyser while ((sp + API_SIG_MAGLEN) < (unsigned char *)search_end) { 58d4abc757SPeter Tyser if (!memcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) { 59d4abc757SPeter Tyser *sig = (struct api_signature *)sp; 60d4abc757SPeter Tyser if (valid_sig(*sig)) 61d4abc757SPeter Tyser return 1; 62d4abc757SPeter Tyser } 63d4abc757SPeter Tyser sp += API_SIG_MAGLEN; 64d4abc757SPeter Tyser } 65d4abc757SPeter Tyser 66d4abc757SPeter Tyser *sig = NULL; 67d4abc757SPeter Tyser return 0; 68d4abc757SPeter Tyser } 69d4abc757SPeter Tyser 70d4abc757SPeter Tyser /**************************************** 71d4abc757SPeter Tyser * 72d4abc757SPeter Tyser * console 73d4abc757SPeter Tyser * 74d4abc757SPeter Tyser ****************************************/ 75d4abc757SPeter Tyser 76d4abc757SPeter Tyser int ub_getc(void) 77d4abc757SPeter Tyser { 78d4abc757SPeter Tyser int c; 79d4abc757SPeter Tyser 8078757d52SStanislav Galabov if (!syscall(API_GETC, NULL, &c)) 81d4abc757SPeter Tyser return -1; 82d4abc757SPeter Tyser 83d4abc757SPeter Tyser return c; 84d4abc757SPeter Tyser } 85d4abc757SPeter Tyser 86d4abc757SPeter Tyser int ub_tstc(void) 87d4abc757SPeter Tyser { 88d4abc757SPeter Tyser int t; 89d4abc757SPeter Tyser 9078757d52SStanislav Galabov if (!syscall(API_TSTC, NULL, &t)) 91d4abc757SPeter Tyser return -1; 92d4abc757SPeter Tyser 93d4abc757SPeter Tyser return t; 94d4abc757SPeter Tyser } 95d4abc757SPeter Tyser 96d4abc757SPeter Tyser void ub_putc(char c) 97d4abc757SPeter Tyser { 9878757d52SStanislav Galabov syscall(API_PUTC, NULL, &c); 99d4abc757SPeter Tyser } 100d4abc757SPeter Tyser 101d4abc757SPeter Tyser void ub_puts(const char *s) 102d4abc757SPeter Tyser { 10378757d52SStanislav Galabov syscall(API_PUTS, NULL, s); 104d4abc757SPeter Tyser } 105d4abc757SPeter Tyser 106d4abc757SPeter Tyser /**************************************** 107d4abc757SPeter Tyser * 108d4abc757SPeter Tyser * system 109d4abc757SPeter Tyser * 110d4abc757SPeter Tyser ****************************************/ 111d4abc757SPeter Tyser 112d4abc757SPeter Tyser void ub_reset(void) 113d4abc757SPeter Tyser { 114d4abc757SPeter Tyser syscall(API_RESET, NULL); 115d4abc757SPeter Tyser } 116d4abc757SPeter Tyser 117d4abc757SPeter Tyser static struct mem_region mr[UB_MAX_MR]; 118d4abc757SPeter Tyser static struct sys_info si; 119d4abc757SPeter Tyser 120d4abc757SPeter Tyser struct sys_info * ub_get_sys_info(void) 121d4abc757SPeter Tyser { 122d4abc757SPeter Tyser int err = 0; 123d4abc757SPeter Tyser 124d4abc757SPeter Tyser memset(&si, 0, sizeof(struct sys_info)); 125d4abc757SPeter Tyser si.mr = mr; 126d4abc757SPeter Tyser si.mr_no = UB_MAX_MR; 127d4abc757SPeter Tyser memset(&mr, 0, sizeof(mr)); 128d4abc757SPeter Tyser 12978757d52SStanislav Galabov if (!syscall(API_GET_SYS_INFO, &err, &si)) 130d4abc757SPeter Tyser return NULL; 131d4abc757SPeter Tyser 132d4abc757SPeter Tyser return ((err) ? NULL : &si); 133d4abc757SPeter Tyser } 134d4abc757SPeter Tyser 135d4abc757SPeter Tyser /**************************************** 136d4abc757SPeter Tyser * 137d4abc757SPeter Tyser * timing 138d4abc757SPeter Tyser * 139d4abc757SPeter Tyser ****************************************/ 140d4abc757SPeter Tyser 141d4abc757SPeter Tyser void ub_udelay(unsigned long usec) 142d4abc757SPeter Tyser { 143d4abc757SPeter Tyser syscall(API_UDELAY, NULL, &usec); 144d4abc757SPeter Tyser } 145d4abc757SPeter Tyser 146d4abc757SPeter Tyser unsigned long ub_get_timer(unsigned long base) 147d4abc757SPeter Tyser { 148d4abc757SPeter Tyser unsigned long cur; 149d4abc757SPeter Tyser 150d4abc757SPeter Tyser if (!syscall(API_GET_TIMER, NULL, &cur, &base)) 151d4abc757SPeter Tyser return 0; 152d4abc757SPeter Tyser 153d4abc757SPeter Tyser return cur; 154d4abc757SPeter Tyser } 155d4abc757SPeter Tyser 156d4abc757SPeter Tyser 157d4abc757SPeter Tyser /**************************************************************************** 158d4abc757SPeter Tyser * 159d4abc757SPeter Tyser * devices 160d4abc757SPeter Tyser * 161d4abc757SPeter Tyser * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1 162d4abc757SPeter Tyser * 163d4abc757SPeter Tyser ***************************************************************************/ 164d4abc757SPeter Tyser 165d4abc757SPeter Tyser static struct device_info devices[UB_MAX_DEV]; 166d4abc757SPeter Tyser 167d4abc757SPeter Tyser struct device_info * ub_dev_get(int i) 168d4abc757SPeter Tyser { 169d4abc757SPeter Tyser return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]); 170d4abc757SPeter Tyser } 171d4abc757SPeter Tyser 172d4abc757SPeter Tyser /* 173d4abc757SPeter Tyser * Enumerates the devices: fills out device_info elements in the devices[] 174d4abc757SPeter Tyser * array. 175d4abc757SPeter Tyser * 176d4abc757SPeter Tyser * returns: number of devices found 177d4abc757SPeter Tyser */ 178d4abc757SPeter Tyser int ub_dev_enum(void) 179d4abc757SPeter Tyser { 180d4abc757SPeter Tyser struct device_info *di; 181d4abc757SPeter Tyser int n = 0; 182d4abc757SPeter Tyser 183d4abc757SPeter Tyser memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV); 184d4abc757SPeter Tyser di = &devices[0]; 185d4abc757SPeter Tyser 186d4abc757SPeter Tyser if (!syscall(API_DEV_ENUM, NULL, di)) 187d4abc757SPeter Tyser return 0; 188d4abc757SPeter Tyser 189d4abc757SPeter Tyser while (di->cookie != NULL) { 190d4abc757SPeter Tyser 191d4abc757SPeter Tyser if (++n >= UB_MAX_DEV) 192d4abc757SPeter Tyser break; 193d4abc757SPeter Tyser 194d4abc757SPeter Tyser /* take another device_info */ 195d4abc757SPeter Tyser di++; 196d4abc757SPeter Tyser 197d4abc757SPeter Tyser /* pass on the previous cookie */ 198d4abc757SPeter Tyser di->cookie = devices[n - 1].cookie; 199d4abc757SPeter Tyser 200d4abc757SPeter Tyser if (!syscall(API_DEV_ENUM, NULL, di)) 201d4abc757SPeter Tyser return 0; 202d4abc757SPeter Tyser } 203d4abc757SPeter Tyser 204d4abc757SPeter Tyser return n; 205d4abc757SPeter Tyser } 206d4abc757SPeter Tyser 207d4abc757SPeter Tyser /* 208d4abc757SPeter Tyser * handle: 0-based id of the device 209d4abc757SPeter Tyser * 210d4abc757SPeter Tyser * returns: 0 when OK, err otherwise 211d4abc757SPeter Tyser */ 212d4abc757SPeter Tyser int ub_dev_open(int handle) 213d4abc757SPeter Tyser { 214d4abc757SPeter Tyser struct device_info *di; 215d4abc757SPeter Tyser int err = 0; 216d4abc757SPeter Tyser 217d4abc757SPeter Tyser if (handle < 0 || handle >= UB_MAX_DEV) 218d4abc757SPeter Tyser return API_EINVAL; 219d4abc757SPeter Tyser 220d4abc757SPeter Tyser di = &devices[handle]; 221d4abc757SPeter Tyser 222d4abc757SPeter Tyser if (!syscall(API_DEV_OPEN, &err, di)) 223d4abc757SPeter Tyser return -1; 224d4abc757SPeter Tyser 225d4abc757SPeter Tyser return err; 226d4abc757SPeter Tyser } 227d4abc757SPeter Tyser 228d4abc757SPeter Tyser int ub_dev_close(int handle) 229d4abc757SPeter Tyser { 230d4abc757SPeter Tyser struct device_info *di; 231d4abc757SPeter Tyser 232d4abc757SPeter Tyser if (handle < 0 || handle >= UB_MAX_DEV) 233d4abc757SPeter Tyser return API_EINVAL; 234d4abc757SPeter Tyser 235d4abc757SPeter Tyser di = &devices[handle]; 236d4abc757SPeter Tyser if (!syscall(API_DEV_CLOSE, NULL, di)) 237d4abc757SPeter Tyser return -1; 238d4abc757SPeter Tyser 239d4abc757SPeter Tyser return 0; 240d4abc757SPeter Tyser } 241d4abc757SPeter Tyser 242d4abc757SPeter Tyser /* 243d4abc757SPeter Tyser * 244d4abc757SPeter Tyser * Validates device for read/write, it has to: 245d4abc757SPeter Tyser * 246d4abc757SPeter Tyser * - have sane handle 247d4abc757SPeter Tyser * - be opened 248d4abc757SPeter Tyser * 249d4abc757SPeter Tyser * returns: 0/1 accordingly 250d4abc757SPeter Tyser */ 251d4abc757SPeter Tyser static int dev_valid(int handle) 252d4abc757SPeter Tyser { 253d4abc757SPeter Tyser if (handle < 0 || handle >= UB_MAX_DEV) 254d4abc757SPeter Tyser return 0; 255d4abc757SPeter Tyser 256d4abc757SPeter Tyser if (devices[handle].state != DEV_STA_OPEN) 257d4abc757SPeter Tyser return 0; 258d4abc757SPeter Tyser 259d4abc757SPeter Tyser return 1; 260d4abc757SPeter Tyser } 261d4abc757SPeter Tyser 262d4abc757SPeter Tyser static int dev_stor_valid(int handle) 263d4abc757SPeter Tyser { 264d4abc757SPeter Tyser if (!dev_valid(handle)) 265d4abc757SPeter Tyser return 0; 266d4abc757SPeter Tyser 267d4abc757SPeter Tyser if (!(devices[handle].type & DEV_TYP_STOR)) 268d4abc757SPeter Tyser return 0; 269d4abc757SPeter Tyser 270d4abc757SPeter Tyser return 1; 271d4abc757SPeter Tyser } 272d4abc757SPeter Tyser 273d4abc757SPeter Tyser int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start, 274d4abc757SPeter Tyser lbasize_t *rlen) 275d4abc757SPeter Tyser { 276d4abc757SPeter Tyser struct device_info *di; 277d4abc757SPeter Tyser lbasize_t act_len; 278d4abc757SPeter Tyser int err = 0; 279d4abc757SPeter Tyser 280d4abc757SPeter Tyser if (!dev_stor_valid(handle)) 281d4abc757SPeter Tyser return API_ENODEV; 282d4abc757SPeter Tyser 283d4abc757SPeter Tyser di = &devices[handle]; 284d4abc757SPeter Tyser if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len)) 285d4abc757SPeter Tyser return API_ESYSC; 286d4abc757SPeter Tyser 287d4abc757SPeter Tyser if (!err && rlen) 288d4abc757SPeter Tyser *rlen = act_len; 289d4abc757SPeter Tyser 290d4abc757SPeter Tyser return err; 291d4abc757SPeter Tyser } 292d4abc757SPeter Tyser 293d4abc757SPeter Tyser static int dev_net_valid(int handle) 294d4abc757SPeter Tyser { 295d4abc757SPeter Tyser if (!dev_valid(handle)) 296d4abc757SPeter Tyser return 0; 297d4abc757SPeter Tyser 298d4abc757SPeter Tyser if (devices[handle].type != DEV_TYP_NET) 299d4abc757SPeter Tyser return 0; 300d4abc757SPeter Tyser 301d4abc757SPeter Tyser return 1; 302d4abc757SPeter Tyser } 303d4abc757SPeter Tyser 304d4abc757SPeter Tyser int ub_dev_recv(int handle, void *buf, int len, int *rlen) 305d4abc757SPeter Tyser { 306d4abc757SPeter Tyser struct device_info *di; 307d4abc757SPeter Tyser int err = 0, act_len; 308d4abc757SPeter Tyser 309d4abc757SPeter Tyser if (!dev_net_valid(handle)) 310d4abc757SPeter Tyser return API_ENODEV; 311d4abc757SPeter Tyser 312d4abc757SPeter Tyser di = &devices[handle]; 313d4abc757SPeter Tyser if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len)) 314d4abc757SPeter Tyser return API_ESYSC; 315d4abc757SPeter Tyser 316d4abc757SPeter Tyser if (!err && rlen) 317d4abc757SPeter Tyser *rlen = act_len; 318d4abc757SPeter Tyser 319d4abc757SPeter Tyser return (err); 320d4abc757SPeter Tyser } 321d4abc757SPeter Tyser 322d4abc757SPeter Tyser int ub_dev_send(int handle, void *buf, int len) 323d4abc757SPeter Tyser { 324d4abc757SPeter Tyser struct device_info *di; 325d4abc757SPeter Tyser int err = 0; 326d4abc757SPeter Tyser 327d4abc757SPeter Tyser if (!dev_net_valid(handle)) 328d4abc757SPeter Tyser return API_ENODEV; 329d4abc757SPeter Tyser 330d4abc757SPeter Tyser di = &devices[handle]; 331d4abc757SPeter Tyser if (!syscall(API_DEV_WRITE, &err, di, buf, &len)) 332d4abc757SPeter Tyser return API_ESYSC; 333d4abc757SPeter Tyser 334d4abc757SPeter Tyser return err; 335d4abc757SPeter Tyser } 336d4abc757SPeter Tyser 337d4abc757SPeter Tyser /**************************************** 338d4abc757SPeter Tyser * 339d4abc757SPeter Tyser * env vars 340d4abc757SPeter Tyser * 341d4abc757SPeter Tyser ****************************************/ 342d4abc757SPeter Tyser 343d4abc757SPeter Tyser char * ub_env_get(const char *name) 344d4abc757SPeter Tyser { 345d4abc757SPeter Tyser char *value; 346d4abc757SPeter Tyser 34778757d52SStanislav Galabov if (!syscall(API_ENV_GET, NULL, name, &value)) 348d4abc757SPeter Tyser return NULL; 349d4abc757SPeter Tyser 350d4abc757SPeter Tyser return value; 351d4abc757SPeter Tyser } 352d4abc757SPeter Tyser 353d4abc757SPeter Tyser void ub_env_set(const char *name, char *value) 354d4abc757SPeter Tyser { 35578757d52SStanislav Galabov syscall(API_ENV_SET, NULL, name, value); 356d4abc757SPeter Tyser } 357d4abc757SPeter Tyser 358d4abc757SPeter Tyser static char env_name[256]; 359d4abc757SPeter Tyser 360d4abc757SPeter Tyser const char * ub_env_enum(const char *last) 361d4abc757SPeter Tyser { 362d4abc757SPeter Tyser const char *env, *str; 363d4abc757SPeter Tyser int i; 364d4abc757SPeter Tyser 365d4abc757SPeter Tyser env = NULL; 366d4abc757SPeter Tyser 367d4abc757SPeter Tyser /* 368d4abc757SPeter Tyser * It's OK to pass only the name piece as last (and not the whole 369d4abc757SPeter Tyser * 'name=val' string), since the API_ENUM_ENV call uses envmatch() 370d4abc757SPeter Tyser * internally, which handles such case 371d4abc757SPeter Tyser */ 37278757d52SStanislav Galabov if (!syscall(API_ENV_ENUM, NULL, last, &env)) 373d4abc757SPeter Tyser return NULL; 374d4abc757SPeter Tyser 375d4abc757SPeter Tyser if (!env) 376d4abc757SPeter Tyser /* no more env. variables to enumerate */ 377d4abc757SPeter Tyser return NULL; 378d4abc757SPeter Tyser 379d4abc757SPeter Tyser /* next enumerated env var */ 380d4abc757SPeter Tyser memset(env_name, 0, 256); 381d4abc757SPeter Tyser for (i = 0, str = env; *str != '=' && *str != '\0';) 382d4abc757SPeter Tyser env_name[i++] = *str++; 383d4abc757SPeter Tyser 384d4abc757SPeter Tyser env_name[i] = '\0'; 385d4abc757SPeter Tyser 386d4abc757SPeter Tyser return env_name; 387d4abc757SPeter Tyser } 388a2a5729fSChe-Liang Chiou 389a2a5729fSChe-Liang Chiou /**************************************** 390a2a5729fSChe-Liang Chiou * 391a2a5729fSChe-Liang Chiou * display 392a2a5729fSChe-Liang Chiou * 393a2a5729fSChe-Liang Chiou ****************************************/ 394a2a5729fSChe-Liang Chiou 395a2a5729fSChe-Liang Chiou int ub_display_get_info(int type, struct display_info *di) 396a2a5729fSChe-Liang Chiou { 397a2a5729fSChe-Liang Chiou int err = 0; 398a2a5729fSChe-Liang Chiou 39978757d52SStanislav Galabov if (!syscall(API_DISPLAY_GET_INFO, &err, type, di)) 400a2a5729fSChe-Liang Chiou return API_ESYSC; 401a2a5729fSChe-Liang Chiou 402a2a5729fSChe-Liang Chiou return err; 403a2a5729fSChe-Liang Chiou } 404a2a5729fSChe-Liang Chiou 405a2a5729fSChe-Liang Chiou int ub_display_draw_bitmap(ulong bitmap, int x, int y) 406a2a5729fSChe-Liang Chiou { 407a2a5729fSChe-Liang Chiou int err = 0; 408a2a5729fSChe-Liang Chiou 409a2a5729fSChe-Liang Chiou if (!syscall(API_DISPLAY_DRAW_BITMAP, &err, bitmap, x, y)) 410a2a5729fSChe-Liang Chiou return API_ESYSC; 411a2a5729fSChe-Liang Chiou 412a2a5729fSChe-Liang Chiou return err; 413a2a5729fSChe-Liang Chiou } 414a2a5729fSChe-Liang Chiou 415a2a5729fSChe-Liang Chiou void ub_display_clear(void) 416a2a5729fSChe-Liang Chiou { 417a2a5729fSChe-Liang Chiou syscall(API_DISPLAY_CLEAR, NULL); 418a2a5729fSChe-Liang Chiou } 419*7e3e2056SRob Clark 420*7e3e2056SRob Clark __weak void *memcpy(void *dest, const void *src, size_t size) 421*7e3e2056SRob Clark { 422*7e3e2056SRob Clark unsigned char *dptr = dest; 423*7e3e2056SRob Clark const unsigned char *ptr = src; 424*7e3e2056SRob Clark const unsigned char *end = src + size; 425*7e3e2056SRob Clark 426*7e3e2056SRob Clark while (ptr < end) 427*7e3e2056SRob Clark *dptr++ = *ptr++; 428*7e3e2056SRob Clark 429*7e3e2056SRob Clark return dest; 430*7e3e2056SRob Clark } 431