1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2007-2008 Semihalf
4 *
5 * Written by: Rafal Jaworowski <raj@semihalf.com>
6 */
7
8#include <common.h>
9#include <env.h>
10#include <linux/types.h>
11#include <api_public.h>
12
13#include "glue.h"
14
15#define errf(fmt, args...) do { printf("ERROR @ %s(): ", __func__); printf(fmt, ##args); } while (0)
16
17#define BUF_SZ		2048
18#define WAIT_SECS	5
19
20void	test_dump_buf(void *, int);
21void	test_dump_di(int);
22void	test_dump_si(struct sys_info *);
23void	test_dump_sig(struct api_signature *);
24
25static char buf[BUF_SZ];
26
27int main(int argc, char *const argv[])
28{
29	int rv = 0, h, i, j, devs_no;
30	struct api_signature *sig = NULL;
31	ulong start, now;
32	struct device_info *di;
33	lbasize_t rlen;
34	struct display_info disinfo;
35
36	if (!api_search_sig(&sig))
37		return -1;
38
39	syscall_ptr = sig->syscall;
40	if (syscall_ptr == NULL)
41		return -2;
42
43	if (sig->version > API_SIG_VERSION)
44		return -3;
45
46	printf("API signature found @%x\n", (unsigned int)sig);
47	test_dump_sig(sig);
48
49	printf("\n*** Consumer API test ***\n");
50	printf("syscall ptr 0x%08x@%08x\n", (unsigned int)syscall_ptr,
51		(unsigned int)&syscall_ptr);
52
53	/* console activities */
54	ub_putc('B');
55
56	printf("*** Press any key to continue ***\n");
57	printf("got char 0x%x\n", ub_getc());
58
59	/* system info */
60	test_dump_si(ub_get_sys_info());
61
62	/* timing */
63	printf("\n*** Timing - wait a couple of secs ***\n");
64	start = ub_get_timer(0);
65	printf("\ntime: start %lu\n\n", start);
66	for (i = 0; i < WAIT_SECS; i++)
67		for (j = 0; j < 1000; j++)
68			ub_udelay(1000);	/* wait 1 ms */
69
70	/* this is the number of milliseconds that passed from ub_get_timer(0) */
71	now = ub_get_timer(start);
72	printf("\ntime: now %lu\n\n", now);
73
74	/* enumerate devices */
75	printf("\n*** Enumerate devices ***\n");
76	devs_no = ub_dev_enum();
77
78	printf("Number of devices found: %d\n", devs_no);
79	if (devs_no == 0)
80		return -1;
81
82	printf("\n*** Show devices ***\n");
83	for (i = 0; i < devs_no; i++) {
84		test_dump_di(i);
85		printf("\n");
86	}
87
88	printf("\n*** Operations on devices ***\n");
89
90	/* test opening a device already opened */
91	h = 0;
92	if ((rv = ub_dev_open(h)) != 0) {
93		errf("open device %d error %d\n", h, rv);
94		return -1;
95	}
96	if ((rv = ub_dev_open(h)) != 0)
97		errf("open device %d error %d\n", h, rv);
98
99	ub_dev_close(h);
100
101	/* test storage */
102	printf("Trying storage devices...\n");
103	for (i = 0; i < devs_no; i++) {
104		di = ub_dev_get(i);
105
106		if (di->type & DEV_TYP_STOR)
107			break;
108
109	}
110	if (i == devs_no)
111		printf("No storage devices available\n");
112	else {
113		memset(buf, 0, BUF_SZ);
114
115		if ((rv = ub_dev_open(i)) != 0)
116			errf("open device %d error %d\n", i, rv);
117
118		else if ((rv = ub_dev_read(i, buf, 1, 0, &rlen)) != 0)
119			errf("could not read from device %d, error %d\n", i, rv);
120		else {
121			printf("Sector 0 dump (512B):\n");
122			test_dump_buf(buf, 512);
123		}
124
125		ub_dev_close(i);
126	}
127
128	/* test networking */
129	printf("Trying network devices...\n");
130	for (i = 0; i < devs_no; i++) {
131		di = ub_dev_get(i);
132
133		if (di->type == DEV_TYP_NET)
134			break;
135
136	}
137	if (i == devs_no)
138		printf("No network devices available\n");
139	else {
140		if ((rv = ub_dev_open(i)) != 0)
141			errf("open device %d error %d\n", i, rv);
142		else if ((rv = ub_dev_send(i, &buf, 2048)) != 0)
143			errf("could not send to device %d, error %d\n", i, rv);
144
145		ub_dev_close(i);
146	}
147
148	if (ub_dev_close(h) != 0)
149		errf("could not close device %d\n", h);
150
151	printf("\n*** Env vars ***\n");
152
153	printf("ethact = %s\n", ub_env_get("ethact"));
154	printf("old fileaddr = %s\n", ub_env_get("fileaddr"));
155	ub_env_set("fileaddr", "deadbeef");
156	printf("new fileaddr = %s\n", ub_env_get("fileaddr"));
157
158	const char *env = NULL;
159
160	while ((env = ub_env_enum(env)) != NULL)
161		printf("%s = %s\n", env, ub_env_get(env));
162
163	printf("\n*** Display ***\n");
164
165	if (ub_display_get_info(DISPLAY_TYPE_LCD, &disinfo)) {
166		printf("LCD info: failed\n");
167	} else {
168		printf("LCD info:\n");
169		printf("  pixel width:  %d\n", disinfo.pixel_width);
170		printf("  pixel height: %d\n", disinfo.pixel_height);
171		printf("  screen rows:  %d\n", disinfo.screen_rows);
172		printf("  screen cols:  %d\n", disinfo.screen_cols);
173	}
174	if (ub_display_get_info(DISPLAY_TYPE_VIDEO, &disinfo)) {
175		printf("video info: failed\n");
176	} else {
177		printf("video info:\n");
178		printf("  pixel width:  %d\n", disinfo.pixel_width);
179		printf("  pixel height: %d\n", disinfo.pixel_height);
180		printf("  screen rows:  %d\n", disinfo.screen_rows);
181		printf("  screen cols:  %d\n", disinfo.screen_cols);
182	}
183
184	printf("*** Press any key to continue ***\n");
185	printf("got char 0x%x\n", ub_getc());
186
187	/*
188	 * This only clears messages on screen, not on serial port. It is
189	 * equivalent to a no-op if no display is available.
190	 */
191	ub_display_clear();
192
193	/* reset */
194	printf("\n*** Resetting board ***\n");
195	ub_reset();
196	printf("\nHmm, reset returned...?!\n");
197
198	return rv;
199}
200
201void test_dump_sig(struct api_signature *sig)
202{
203	printf("signature:\n");
204	printf("  version\t= %d\n", sig->version);
205	printf("  checksum\t= 0x%08x\n", sig->checksum);
206	printf("  sc entry\t= 0x%08x\n", (unsigned int)sig->syscall);
207}
208
209void test_dump_si(struct sys_info *si)
210{
211	int i;
212
213	printf("sys info:\n");
214	printf("  clkbus\t= 0x%08x\n", (unsigned int)si->clk_bus);
215	printf("  clkcpu\t= 0x%08x\n", (unsigned int)si->clk_cpu);
216	printf("  bar\t\t= 0x%08x\n", (unsigned int)si->bar);
217
218	printf("---\n");
219	for (i = 0; i < si->mr_no; i++) {
220		if (si->mr[i].flags == 0)
221			break;
222
223		printf("  start\t= 0x%08lx\n", si->mr[i].start);
224		printf("  size\t= 0x%08lx\n", si->mr[i].size);
225
226		switch(si->mr[i].flags & 0x000F) {
227			case MR_ATTR_FLASH:
228				printf("  type FLASH\n");
229				break;
230			case MR_ATTR_DRAM:
231				printf("  type DRAM\n");
232				break;
233			case MR_ATTR_SRAM:
234				printf("  type SRAM\n");
235				break;
236			default:
237				printf("  type UNKNOWN\n");
238		}
239		printf("---\n");
240	}
241}
242
243static char *test_stor_typ(int type)
244{
245	if (type & DT_STOR_IDE)
246		return "IDE";
247
248	if (type & DT_STOR_MMC)
249		return "MMC";
250
251	if (type & DT_STOR_SATA)
252		return "SATA";
253
254	if (type & DT_STOR_SCSI)
255		return "SCSI";
256
257	if (type & DT_STOR_USB)
258		return "USB";
259
260	return "Unknown";
261}
262
263void test_dump_buf(void *buf, int len)
264{
265	int i;
266	int line_counter = 0;
267	int sep_flag = 0;
268	int addr = 0;
269
270	printf("%07x:\t", addr);
271
272	for (i = 0; i < len; i++) {
273		if (line_counter++ > 15) {
274			line_counter = 0;
275			sep_flag = 0;
276			addr += 16;
277			i--;
278			printf("\n%07x:\t", addr);
279			continue;
280		}
281
282		if (sep_flag++ > 1) {
283			sep_flag = 1;
284			printf(" ");
285		}
286
287		printf("%02x", *((char *)buf++));
288	}
289
290	printf("\n");
291}
292
293void test_dump_di(int handle)
294{
295	int i;
296	struct device_info *di = ub_dev_get(handle);
297
298	printf("device info (%d):\n", handle);
299	printf("  cookie\t= 0x%08x\n", (uint32_t)di->cookie);
300	printf("  type\t\t= 0x%08x\n", di->type);
301
302	if (di->type == DEV_TYP_NET) {
303		printf("  hwaddr\t= ");
304		for (i = 0; i < 6; i++)
305			printf("%02x ", di->di_net.hwaddr[i]);
306
307		printf("\n");
308
309	} else if (di->type & DEV_TYP_STOR) {
310		printf("  type\t\t= %s\n", test_stor_typ(di->type));
311		printf("  blk size\t\t= %d\n", (unsigned int)di->di_stor.block_size);
312		printf("  blk count\t\t= %d\n", (unsigned int)di->di_stor.block_count);
313	}
314}
315