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