Files
u-boot/examples/legacy_api/demo.c
Simon Glass c5188188e2 api: Rename legacy API files and examples
The API is not very useful these days, since it doesn't support driver
model. It is laborious to add new functions to the API as there are so
many needed.

A better approach would be to create a library containing all of U-Boot,
then have the API be generated by a script containing a list of
functions, perhaps with wildcards. Then a stub could be created, with
a list of entry points, which links with and calls through into the
library.

In preparation for heading in this direction, rename some of the
existing files and directories:

- examples/api -> examples/legacy_api
- include/api*.h -> include/legacy_api*.h
- API_BUILD to LEGACY_API_BUILD

Co-developed-by: Claude <noreply@anthropic.com>
2025-09-05 07:02:09 -06:00

314 lines
6.8 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2007-2008 Semihalf
*
* Written by: Rafal Jaworowski <raj@semihalf.com>
*/
#include <stdio.h>
#include <env.h>
#include <linux/types.h>
#include <legacy_api_public.h>
#include "glue.h"
#define errf(fmt, args...) do { printf("ERROR @ %s(): ", __func__); printf(fmt, ##args); } while (0)
#define BUF_SZ 2048
#define WAIT_SECS 5
void test_dump_buf(void *, int);
void test_dump_di(int);
void test_dump_si(struct sys_info *);
void test_dump_sig(struct api_signature *);
static char buf[BUF_SZ];
int main(int argc, char *const argv[])
{
int rv = 0, h, i, j, devs_no;
struct api_signature *sig = NULL;
ulong start, now;
struct device_info *di;
lbasize_t rlen;
struct display_info disinfo;
if (!api_search_sig(&sig))
return -1;
syscall_ptr = sig->syscall;
if (syscall_ptr == NULL)
return -2;
if (sig->version > API_SIG_VERSION)
return -3;
printf("API signature found @%p\n", sig);
test_dump_sig(sig);
printf("\n*** Consumer API test ***\n");
printf("syscall ptr 0x%p@%p\n", syscall_ptr, &syscall_ptr);
/* console activities */
ub_putc('B');
printf("*** Press any key to continue ***\n");
printf("got char 0x%x\n", ub_getc());
/* system info */
test_dump_si(ub_get_sys_info());
/* timing */
printf("\n*** Timing - wait a couple of secs ***\n");
start = ub_get_timer(0);
printf("\ntime: start %lu\n\n", start);
for (i = 0; i < WAIT_SECS; i++)
for (j = 0; j < 1000; j++)
ub_udelay(1000); /* wait 1 ms */
/* this is the number of milliseconds that passed from ub_get_timer(0) */
now = ub_get_timer(start);
printf("\ntime: now %lu\n\n", now);
/* enumerate devices */
printf("\n*** Enumerate devices ***\n");
devs_no = ub_dev_enum();
printf("Number of devices found: %d\n", devs_no);
if (devs_no == 0)
return -1;
printf("\n*** Show devices ***\n");
for (i = 0; i < devs_no; i++) {
test_dump_di(i);
printf("\n");
}
printf("\n*** Operations on devices ***\n");
/* test opening a device already opened */
h = 0;
if ((rv = ub_dev_open(h)) != 0) {
errf("open device %d error %d\n", h, rv);
return -1;
}
if ((rv = ub_dev_open(h)) != 0)
errf("open device %d error %d\n", h, rv);
ub_dev_close(h);
/* test storage */
printf("Trying storage devices...\n");
for (i = 0; i < devs_no; i++) {
di = ub_dev_get(i);
if (di->type & DEV_TYP_STOR)
break;
}
if (i == devs_no)
printf("No storage devices available\n");
else {
memset(buf, 0, BUF_SZ);
if ((rv = ub_dev_open(i)) != 0)
errf("open device %d error %d\n", i, rv);
else if ((rv = ub_dev_read(i, buf, 1, 0, &rlen)) != 0)
errf("could not read from device %d, error %d\n", i, rv);
else {
printf("Sector 0 dump (512B):\n");
test_dump_buf(buf, 512);
}
ub_dev_close(i);
}
/* test networking */
printf("Trying network devices...\n");
for (i = 0; i < devs_no; i++) {
di = ub_dev_get(i);
if (di->type == DEV_TYP_NET)
break;
}
if (i == devs_no)
printf("No network devices available\n");
else {
if ((rv = ub_dev_open(i)) != 0)
errf("open device %d error %d\n", i, rv);
else if ((rv = ub_dev_send(i, &buf, 2048)) != 0)
errf("could not send to device %d, error %d\n", i, rv);
ub_dev_close(i);
}
if (ub_dev_close(h) != 0)
errf("could not close device %d\n", h);
printf("\n*** Env vars ***\n");
printf("ethact = %s\n", ub_env_get("ethact"));
printf("old fileaddr = %s\n", ub_env_get("fileaddr"));
ub_env_set("fileaddr", "deadbeef");
printf("new fileaddr = %s\n", ub_env_get("fileaddr"));
const char *env = NULL;
while ((env = ub_env_enum(env)) != NULL)
printf("%s = %s\n", env, ub_env_get(env));
printf("\n*** Display ***\n");
if (ub_display_get_info(DISPLAY_TYPE_LCD, &disinfo)) {
printf("LCD info: failed\n");
} else {
printf("LCD info:\n");
printf(" pixel width: %d\n", disinfo.pixel_width);
printf(" pixel height: %d\n", disinfo.pixel_height);
printf(" screen rows: %d\n", disinfo.screen_rows);
printf(" screen cols: %d\n", disinfo.screen_cols);
}
if (ub_display_get_info(DISPLAY_TYPE_VIDEO, &disinfo)) {
printf("video info: failed\n");
} else {
printf("video info:\n");
printf(" pixel width: %d\n", disinfo.pixel_width);
printf(" pixel height: %d\n", disinfo.pixel_height);
printf(" screen rows: %d\n", disinfo.screen_rows);
printf(" screen cols: %d\n", disinfo.screen_cols);
}
printf("*** Press any key to continue ***\n");
printf("got char 0x%x\n", ub_getc());
/*
* This only clears messages on screen, not on serial port. It is
* equivalent to a no-op if no display is available.
*/
ub_display_clear();
/* reset */
printf("\n*** Resetting board ***\n");
ub_reset();
printf("\nHmm, reset returned...?!\n");
return rv;
}
void test_dump_sig(struct api_signature *sig)
{
printf("signature:\n");
printf(" version\t= %d\n", sig->version);
printf(" checksum\t= 0x%08x\n", sig->checksum);
printf(" sc entry\t= 0x%p\n", sig->syscall);
}
void test_dump_si(struct sys_info *si)
{
int i;
printf("sys info:\n");
printf(" clkbus\t= 0x%08x\n", (unsigned int)si->clk_bus);
printf(" clkcpu\t= 0x%08x\n", (unsigned int)si->clk_cpu);
printf(" bar\t\t= 0x%08x\n", (unsigned int)si->bar);
printf("---\n");
for (i = 0; i < si->mr_no; i++) {
if (si->mr[i].flags == 0)
break;
printf(" start\t= 0x%08lx\n", si->mr[i].start);
printf(" size\t= 0x%08lx\n", si->mr[i].size);
switch(si->mr[i].flags & 0x000F) {
case MR_ATTR_FLASH:
printf(" type FLASH\n");
break;
case MR_ATTR_DRAM:
printf(" type DRAM\n");
break;
case MR_ATTR_SRAM:
printf(" type SRAM\n");
break;
default:
printf(" type UNKNOWN\n");
}
printf("---\n");
}
}
static char *test_stor_typ(int type)
{
if (type & DT_STOR_IDE)
return "IDE";
if (type & DT_STOR_MMC)
return "MMC";
if (type & DT_STOR_SATA)
return "SATA";
if (type & DT_STOR_SCSI)
return "SCSI";
if (type & DT_STOR_USB)
return "USB";
return "Unknown";
}
void test_dump_buf(void *buf, int len)
{
int i;
int line_counter = 0;
int sep_flag = 0;
int addr = 0;
printf("%07x:\t", addr);
for (i = 0; i < len; i++) {
if (line_counter++ > 15) {
line_counter = 0;
sep_flag = 0;
addr += 16;
i--;
printf("\n%07x:\t", addr);
continue;
}
if (sep_flag++ > 1) {
sep_flag = 1;
printf(" ");
}
printf("%02x", *((char *)buf++));
}
printf("\n");
}
void test_dump_di(int handle)
{
int i;
struct device_info *di = ub_dev_get(handle);
printf("device info (%d):\n", handle);
printf(" cookie\t= 0x%p\n", di->cookie);
printf(" type\t\t= 0x%08x\n", di->type);
if (di->type == DEV_TYP_NET) {
printf(" hwaddr\t= ");
for (i = 0; i < 6; i++)
printf("%02x ", di->di_net.hwaddr[i]);
printf("\n");
} else if (di->type & DEV_TYP_STOR) {
printf(" type\t\t= %s\n", test_stor_typ(di->type));
printf(" blk size\t\t= %d\n", (unsigned int)di->di_stor.block_size);
printf(" blk count\t\t= %d\n", (unsigned int)di->di_stor.block_count);
}
}