uboot/examples/api/glue.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
   4 */
   5
   6#include <common.h>
   7#include <linux/types.h>
   8#include <api_public.h>
   9
  10#include "glue.h"
  11
  12static int valid_sig(struct api_signature *sig)
  13{
  14        uint32_t checksum;
  15        struct api_signature s;
  16
  17        if (sig == NULL)
  18                return 0;
  19        /*
  20         * Clear the checksum field (in the local copy) so as to calculate the
  21         * CRC with the same initial contents as at the time when the sig was
  22         * produced
  23         */
  24        s = *sig;
  25        s.checksum = 0;
  26
  27        checksum = crc32(0, (unsigned char *)&s, sizeof(struct api_signature));
  28
  29        if (checksum != sig->checksum)
  30                return 0;
  31
  32        return 1;
  33}
  34
  35/*
  36 * Searches for the U-Boot API signature
  37 *
  38 * returns 1/0 depending on found/not found result
  39 */
  40int api_search_sig(struct api_signature **sig)
  41{
  42        unsigned char *sp;
  43        uint32_t search_start = 0;
  44        uint32_t search_end = 0;
  45
  46        if (sig == NULL)
  47                return 0;
  48
  49        if (search_hint == 0)
  50                search_hint = 255 * 1024 * 1024;
  51
  52        search_start = search_hint & ~0x000fffff;
  53        search_end = search_start + API_SEARCH_LEN - API_SIG_MAGLEN;
  54
  55        sp = (unsigned char *)search_start;
  56        while ((sp + API_SIG_MAGLEN) < (unsigned char *)search_end) {
  57                if (!memcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
  58                        *sig = (struct api_signature *)sp;
  59                        if (valid_sig(*sig))
  60                                return 1;
  61                }
  62                sp += API_SIG_MAGLEN;
  63        }
  64
  65        *sig = NULL;
  66        return 0;
  67}
  68
  69/****************************************
  70 *
  71 * console
  72 *
  73 ****************************************/
  74
  75int ub_getc(void)
  76{
  77        int c;
  78
  79        if (!syscall(API_GETC, NULL, &c))
  80                return -1;
  81
  82        return c;
  83}
  84
  85int ub_tstc(void)
  86{
  87        int t;
  88
  89        if (!syscall(API_TSTC, NULL, &t))
  90                return -1;
  91
  92        return t;
  93}
  94
  95void ub_putc(char c)
  96{
  97        syscall(API_PUTC, NULL, &c);
  98}
  99
 100void ub_puts(const char *s)
 101{
 102        syscall(API_PUTS, NULL, s);
 103}
 104
 105/****************************************
 106 *
 107 * system
 108 *
 109 ****************************************/
 110
 111void ub_reset(void)
 112{
 113        syscall(API_RESET, NULL);
 114}
 115
 116static struct mem_region mr[UB_MAX_MR];
 117static struct sys_info si;
 118
 119struct sys_info * ub_get_sys_info(void)
 120{
 121        int err = 0;
 122
 123        memset(&si, 0, sizeof(struct sys_info));
 124        si.mr = mr;
 125        si.mr_no = UB_MAX_MR;
 126        memset(&mr, 0, sizeof(mr));
 127
 128        if (!syscall(API_GET_SYS_INFO, &err, &si))
 129                return NULL;
 130
 131        return ((err) ? NULL : &si);
 132}
 133
 134/****************************************
 135 *
 136 * timing
 137 *
 138 ****************************************/
 139
 140void ub_udelay(unsigned long usec)
 141{
 142        syscall(API_UDELAY, NULL, &usec);
 143}
 144
 145unsigned long ub_get_timer(unsigned long base)
 146{
 147        unsigned long cur;
 148
 149        if (!syscall(API_GET_TIMER, NULL, &cur, &base))
 150                return 0;
 151
 152        return cur;
 153}
 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        /*
 367         * It's OK to pass only the name piece as last (and not the whole
 368         * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
 369         * internally, which handles such case
 370         */
 371        if (!syscall(API_ENV_ENUM, NULL, last, &env))
 372                return NULL;
 373
 374        if (!env)
 375                /* no more env. variables to enumerate */
 376                return NULL;
 377
 378        /* next enumerated env var */
 379        memset(env_name, 0, 256);
 380        for (i = 0, str = env; *str != '=' && *str != '\0';)
 381                env_name[i++] = *str++;
 382
 383        env_name[i] = '\0';
 384
 385        return env_name;
 386}
 387
 388/****************************************
 389 *
 390 * display
 391 *
 392 ****************************************/
 393
 394int ub_display_get_info(int type, struct display_info *di)
 395{
 396        int err = 0;
 397
 398        if (!syscall(API_DISPLAY_GET_INFO, &err, type, di))
 399                return API_ESYSC;
 400
 401        return err;
 402}
 403
 404int ub_display_draw_bitmap(ulong bitmap, int x, int y)
 405{
 406        int err = 0;
 407
 408        if (!syscall(API_DISPLAY_DRAW_BITMAP, &err, bitmap, x, y))
 409                return API_ESYSC;
 410
 411        return err;
 412}
 413
 414void ub_display_clear(void)
 415{
 416        syscall(API_DISPLAY_CLEAR, NULL);
 417}
 418
 419__weak void *memcpy(void *dest, const void *src, size_t size)
 420{
 421        unsigned char *dptr = dest;
 422        const unsigned char *ptr = src;
 423        const unsigned char *end = src + size;
 424
 425        while (ptr < end)
 426                *dptr++ = *ptr++;
 427
 428        return dest;
 429}
 430