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