xref: /rk3399_rockchip-uboot/arch/sandbox/cpu/os.c (revision cfd13e8dda9d2db3f6bdf32d623aecf10ee1ba50)
17a9219c1SSimon Glass /*
27a9219c1SSimon Glass  * Copyright (c) 2011 The Chromium OS Authors.
31a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
47a9219c1SSimon Glass  */
57a9219c1SSimon Glass 
662584db1SSimon Glass #include <dirent.h>
7e1012472SSimon Glass #include <errno.h>
87a9219c1SSimon Glass #include <fcntl.h>
970db4212SSimon Glass #include <getopt.h>
1062584db1SSimon Glass #include <stdio.h>
112a54d159SSimon Glass #include <stdint.h>
127a9219c1SSimon Glass #include <stdlib.h>
1362584db1SSimon Glass #include <string.h>
14ab06a758SMike Frysinger #include <termios.h>
15d99a6874SMatthias Weisser #include <time.h>
16e1012472SSimon Glass #include <unistd.h>
1721899b10SMatthias Weisser #include <sys/mman.h>
18e1012472SSimon Glass #include <sys/stat.h>
193bdf56b7SSimon Glass #include <sys/time.h>
20e1012472SSimon Glass #include <sys/types.h>
21d99a6874SMatthias Weisser #include <linux/types.h>
227a9219c1SSimon Glass 
2370db4212SSimon Glass #include <asm/getopt.h>
2470db4212SSimon Glass #include <asm/sections.h>
2570db4212SSimon Glass #include <asm/state.h>
267a9219c1SSimon Glass #include <os.h>
277a9219c1SSimon Glass 
287a9219c1SSimon Glass /* Operating System Interface */
297a9219c1SSimon Glass 
3077595c6dSSimon Glass struct os_mem_hdr {
3177595c6dSSimon Glass 	size_t length;		/* number of bytes in the block */
3277595c6dSSimon Glass };
3377595c6dSSimon Glass 
347a9219c1SSimon Glass ssize_t os_read(int fd, void *buf, size_t count)
357a9219c1SSimon Glass {
367a9219c1SSimon Glass 	return read(fd, buf, count);
377a9219c1SSimon Glass }
387a9219c1SSimon Glass 
39e101550aSTaylor Hutt ssize_t os_read_no_block(int fd, void *buf, size_t count)
40e101550aSTaylor Hutt {
41e101550aSTaylor Hutt 	const int flags = fcntl(fd, F_GETFL, 0);
42e101550aSTaylor Hutt 
43e101550aSTaylor Hutt 	fcntl(fd, F_SETFL, flags | O_NONBLOCK);
44e101550aSTaylor Hutt 	return os_read(fd, buf, count);
45e101550aSTaylor Hutt }
46e101550aSTaylor Hutt 
477a9219c1SSimon Glass ssize_t os_write(int fd, const void *buf, size_t count)
487a9219c1SSimon Glass {
497a9219c1SSimon Glass 	return write(fd, buf, count);
507a9219c1SSimon Glass }
517a9219c1SSimon Glass 
52e2dcefcbSMike Frysinger off_t os_lseek(int fd, off_t offset, int whence)
53e2dcefcbSMike Frysinger {
54e2dcefcbSMike Frysinger 	if (whence == OS_SEEK_SET)
55e2dcefcbSMike Frysinger 		whence = SEEK_SET;
56e2dcefcbSMike Frysinger 	else if (whence == OS_SEEK_CUR)
57e2dcefcbSMike Frysinger 		whence = SEEK_CUR;
58e2dcefcbSMike Frysinger 	else if (whence == OS_SEEK_END)
59e2dcefcbSMike Frysinger 		whence = SEEK_END;
60e2dcefcbSMike Frysinger 	else
61e2dcefcbSMike Frysinger 		os_exit(1);
62e2dcefcbSMike Frysinger 	return lseek(fd, offset, whence);
63e2dcefcbSMike Frysinger }
64e2dcefcbSMike Frysinger 
65d9165153SSimon Glass int os_open(const char *pathname, int os_flags)
667a9219c1SSimon Glass {
67d9165153SSimon Glass 	int flags;
68d9165153SSimon Glass 
69d9165153SSimon Glass 	switch (os_flags & OS_O_MASK) {
70d9165153SSimon Glass 	case OS_O_RDONLY:
71d9165153SSimon Glass 	default:
72d9165153SSimon Glass 		flags = O_RDONLY;
73d9165153SSimon Glass 		break;
74d9165153SSimon Glass 
75d9165153SSimon Glass 	case OS_O_WRONLY:
76d9165153SSimon Glass 		flags = O_WRONLY;
77d9165153SSimon Glass 		break;
78d9165153SSimon Glass 
79d9165153SSimon Glass 	case OS_O_RDWR:
80d9165153SSimon Glass 		flags = O_RDWR;
81d9165153SSimon Glass 		break;
82d9165153SSimon Glass 	}
83d9165153SSimon Glass 
84d9165153SSimon Glass 	if (os_flags & OS_O_CREAT)
85d9165153SSimon Glass 		flags |= O_CREAT;
86d9165153SSimon Glass 
87d9165153SSimon Glass 	return open(pathname, flags, 0777);
887a9219c1SSimon Glass }
897a9219c1SSimon Glass 
907a9219c1SSimon Glass int os_close(int fd)
917a9219c1SSimon Glass {
927a9219c1SSimon Glass 	return close(fd);
937a9219c1SSimon Glass }
947a9219c1SSimon Glass 
95*cfd13e8dSStephen Warren int os_unlink(const char *pathname)
96*cfd13e8dSStephen Warren {
97*cfd13e8dSStephen Warren 	return unlink(pathname);
98*cfd13e8dSStephen Warren }
99*cfd13e8dSStephen Warren 
1007a9219c1SSimon Glass void os_exit(int exit_code)
1017a9219c1SSimon Glass {
1027a9219c1SSimon Glass 	exit(exit_code);
1037a9219c1SSimon Glass }
104ab06a758SMike Frysinger 
105ab06a758SMike Frysinger /* Restore tty state when we exit */
106ab06a758SMike Frysinger static struct termios orig_term;
107ab06a758SMike Frysinger 
108ab06a758SMike Frysinger static void os_fd_restore(void)
109ab06a758SMike Frysinger {
110ab06a758SMike Frysinger 	tcsetattr(0, TCSANOW, &orig_term);
111ab06a758SMike Frysinger }
112ab06a758SMike Frysinger 
113ab06a758SMike Frysinger /* Put tty into raw mode so <tab> and <ctrl+c> work */
114ab06a758SMike Frysinger void os_tty_raw(int fd)
115ab06a758SMike Frysinger {
116ab06a758SMike Frysinger 	static int setup = 0;
117ab06a758SMike Frysinger 	struct termios term;
118ab06a758SMike Frysinger 
119ab06a758SMike Frysinger 	if (setup)
120ab06a758SMike Frysinger 		return;
121ab06a758SMike Frysinger 	setup = 1;
122ab06a758SMike Frysinger 
123ab06a758SMike Frysinger 	/* If not a tty, don't complain */
124ab06a758SMike Frysinger 	if (tcgetattr(fd, &orig_term))
125ab06a758SMike Frysinger 		return;
126ab06a758SMike Frysinger 
127ab06a758SMike Frysinger 	term = orig_term;
128ab06a758SMike Frysinger 	term.c_iflag = IGNBRK | IGNPAR;
129ab06a758SMike Frysinger 	term.c_oflag = OPOST | ONLCR;
130ab06a758SMike Frysinger 	term.c_cflag = CS8 | CREAD | CLOCAL;
131ab06a758SMike Frysinger 	term.c_lflag = 0;
132ab06a758SMike Frysinger 	if (tcsetattr(fd, TCSANOW, &term))
133ab06a758SMike Frysinger 		return;
134ab06a758SMike Frysinger 
135ab06a758SMike Frysinger 	atexit(os_fd_restore);
136ab06a758SMike Frysinger }
13721899b10SMatthias Weisser 
13821899b10SMatthias Weisser void *os_malloc(size_t length)
13921899b10SMatthias Weisser {
14077595c6dSSimon Glass 	struct os_mem_hdr *hdr;
14177595c6dSSimon Glass 
14277595c6dSSimon Glass 	hdr = mmap(NULL, length + sizeof(*hdr), PROT_READ | PROT_WRITE,
14321899b10SMatthias Weisser 		   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
14477595c6dSSimon Glass 	if (hdr == MAP_FAILED)
14577595c6dSSimon Glass 		return NULL;
14677595c6dSSimon Glass 	hdr->length = length;
14777595c6dSSimon Glass 
14877595c6dSSimon Glass 	return hdr + 1;
14977595c6dSSimon Glass }
15077595c6dSSimon Glass 
151347d06deSMasahiro Yamada void os_free(void *ptr)
15277595c6dSSimon Glass {
15377595c6dSSimon Glass 	struct os_mem_hdr *hdr = ptr;
15477595c6dSSimon Glass 
15577595c6dSSimon Glass 	hdr--;
15677595c6dSSimon Glass 	if (ptr)
15777595c6dSSimon Glass 		munmap(hdr, hdr->length + sizeof(*hdr));
15877595c6dSSimon Glass }
15977595c6dSSimon Glass 
16077595c6dSSimon Glass void *os_realloc(void *ptr, size_t length)
16177595c6dSSimon Glass {
16277595c6dSSimon Glass 	struct os_mem_hdr *hdr = ptr;
16377595c6dSSimon Glass 	void *buf = NULL;
16477595c6dSSimon Glass 
16577595c6dSSimon Glass 	hdr--;
16677595c6dSSimon Glass 	if (length != 0) {
16777595c6dSSimon Glass 		buf = os_malloc(length);
16877595c6dSSimon Glass 		if (!buf)
16977595c6dSSimon Glass 			return buf;
17077595c6dSSimon Glass 		if (ptr) {
17177595c6dSSimon Glass 			if (length > hdr->length)
17277595c6dSSimon Glass 				length = hdr->length;
17377595c6dSSimon Glass 			memcpy(buf, ptr, length);
17477595c6dSSimon Glass 		}
17577595c6dSSimon Glass 	}
17677595c6dSSimon Glass 	os_free(ptr);
17777595c6dSSimon Glass 
17877595c6dSSimon Glass 	return buf;
17921899b10SMatthias Weisser }
180d99a6874SMatthias Weisser 
181d99a6874SMatthias Weisser void os_usleep(unsigned long usec)
182d99a6874SMatthias Weisser {
183d99a6874SMatthias Weisser 	usleep(usec);
184d99a6874SMatthias Weisser }
185d99a6874SMatthias Weisser 
1862a54d159SSimon Glass uint64_t __attribute__((no_instrument_function)) os_get_nsec(void)
187d99a6874SMatthias Weisser {
188d99a6874SMatthias Weisser #if defined(CLOCK_MONOTONIC) && defined(_POSIX_MONOTONIC_CLOCK)
189d99a6874SMatthias Weisser 	struct timespec tp;
190d99a6874SMatthias Weisser 	if (EINVAL == clock_gettime(CLOCK_MONOTONIC, &tp)) {
191d99a6874SMatthias Weisser 		struct timeval tv;
192d99a6874SMatthias Weisser 
193d99a6874SMatthias Weisser 		gettimeofday(&tv, NULL);
194d99a6874SMatthias Weisser 		tp.tv_sec = tv.tv_sec;
195d99a6874SMatthias Weisser 		tp.tv_nsec = tv.tv_usec * 1000;
196d99a6874SMatthias Weisser 	}
197d99a6874SMatthias Weisser 	return tp.tv_sec * 1000000000ULL + tp.tv_nsec;
198d99a6874SMatthias Weisser #else
199d99a6874SMatthias Weisser 	struct timeval tv;
200d99a6874SMatthias Weisser 	gettimeofday(&tv, NULL);
201d99a6874SMatthias Weisser 	return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000;
202d99a6874SMatthias Weisser #endif
203d99a6874SMatthias Weisser }
20470db4212SSimon Glass 
20570db4212SSimon Glass static char *short_opts;
20670db4212SSimon Glass static struct option *long_opts;
20770db4212SSimon Glass 
20870db4212SSimon Glass int os_parse_args(struct sandbox_state *state, int argc, char *argv[])
20970db4212SSimon Glass {
2107b3efc66SSimon Glass 	struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start;
21170db4212SSimon Glass 	size_t num_options = __u_boot_sandbox_option_count();
21270db4212SSimon Glass 	size_t i;
21370db4212SSimon Glass 
21470db4212SSimon Glass 	int hidden_short_opt;
21570db4212SSimon Glass 	size_t si;
21670db4212SSimon Glass 
21770db4212SSimon Glass 	int c;
21870db4212SSimon Glass 
21970db4212SSimon Glass 	if (short_opts || long_opts)
22070db4212SSimon Glass 		return 1;
22170db4212SSimon Glass 
22270db4212SSimon Glass 	state->argc = argc;
22370db4212SSimon Glass 	state->argv = argv;
22470db4212SSimon Glass 
22570db4212SSimon Glass 	/* dynamically construct the arguments to the system getopt_long */
22670db4212SSimon Glass 	short_opts = os_malloc(sizeof(*short_opts) * num_options * 2 + 1);
22770db4212SSimon Glass 	long_opts = os_malloc(sizeof(*long_opts) * num_options);
22870db4212SSimon Glass 	if (!short_opts || !long_opts)
22970db4212SSimon Glass 		return 1;
23070db4212SSimon Glass 
23170db4212SSimon Glass 	/*
23270db4212SSimon Glass 	 * getopt_long requires "val" to be unique (since that is what the
23370db4212SSimon Glass 	 * func returns), so generate unique values automatically for flags
23470db4212SSimon Glass 	 * that don't have a short option.  pick 0x100 as that is above the
23570db4212SSimon Glass 	 * single byte range (where ASCII/ISO-XXXX-X charsets live).
23670db4212SSimon Glass 	 */
23770db4212SSimon Glass 	hidden_short_opt = 0x100;
23870db4212SSimon Glass 	si = 0;
23970db4212SSimon Glass 	for (i = 0; i < num_options; ++i) {
24070db4212SSimon Glass 		long_opts[i].name = sb_opt[i]->flag;
24170db4212SSimon Glass 		long_opts[i].has_arg = sb_opt[i]->has_arg ?
24270db4212SSimon Glass 			required_argument : no_argument;
24370db4212SSimon Glass 		long_opts[i].flag = NULL;
24470db4212SSimon Glass 
24570db4212SSimon Glass 		if (sb_opt[i]->flag_short) {
24670db4212SSimon Glass 			short_opts[si++] = long_opts[i].val = sb_opt[i]->flag_short;
24770db4212SSimon Glass 			if (long_opts[i].has_arg == required_argument)
24870db4212SSimon Glass 				short_opts[si++] = ':';
24970db4212SSimon Glass 		} else
25070db4212SSimon Glass 			long_opts[i].val = sb_opt[i]->flag_short = hidden_short_opt++;
25170db4212SSimon Glass 	}
25270db4212SSimon Glass 	short_opts[si] = '\0';
25370db4212SSimon Glass 
25470db4212SSimon Glass 	/* we need to handle output ourselves since u-boot provides printf */
25570db4212SSimon Glass 	opterr = 0;
25670db4212SSimon Glass 
25770db4212SSimon Glass 	/*
25870db4212SSimon Glass 	 * walk all of the options the user gave us on the command line,
25970db4212SSimon Glass 	 * figure out what u-boot option structure they belong to (via
26070db4212SSimon Glass 	 * the unique short val key), and call the appropriate callback.
26170db4212SSimon Glass 	 */
26270db4212SSimon Glass 	while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
26370db4212SSimon Glass 		for (i = 0; i < num_options; ++i) {
26470db4212SSimon Glass 			if (sb_opt[i]->flag_short == c) {
26570db4212SSimon Glass 				if (sb_opt[i]->callback(state, optarg)) {
26670db4212SSimon Glass 					state->parse_err = sb_opt[i]->flag;
26770db4212SSimon Glass 					return 0;
26870db4212SSimon Glass 				}
26970db4212SSimon Glass 				break;
27070db4212SSimon Glass 			}
27170db4212SSimon Glass 		}
27270db4212SSimon Glass 		if (i == num_options) {
27370db4212SSimon Glass 			/*
27470db4212SSimon Glass 			 * store the faulting flag for later display.  we have to
27570db4212SSimon Glass 			 * store the flag itself as the getopt parsing itself is
27670db4212SSimon Glass 			 * tricky: need to handle the following flags (assume all
27770db4212SSimon Glass 			 * of the below are unknown):
27870db4212SSimon Glass 			 *   -a        optopt='a' optind=<next>
27970db4212SSimon Glass 			 *   -abbbb    optopt='a' optind=<this>
28070db4212SSimon Glass 			 *   -aaaaa    optopt='a' optind=<this>
28170db4212SSimon Glass 			 *   --a       optopt=0   optind=<this>
28270db4212SSimon Glass 			 * as you can see, it is impossible to determine the exact
28370db4212SSimon Glass 			 * faulting flag without doing the parsing ourselves, so
28470db4212SSimon Glass 			 * we just report the specific flag that failed.
28570db4212SSimon Glass 			 */
28670db4212SSimon Glass 			if (optopt) {
28770db4212SSimon Glass 				static char parse_err[3] = { '-', 0, '\0', };
28870db4212SSimon Glass 				parse_err[1] = optopt;
28970db4212SSimon Glass 				state->parse_err = parse_err;
29070db4212SSimon Glass 			} else
29170db4212SSimon Glass 				state->parse_err = argv[optind - 1];
29270db4212SSimon Glass 			break;
29370db4212SSimon Glass 		}
29470db4212SSimon Glass 	}
29570db4212SSimon Glass 
29670db4212SSimon Glass 	return 0;
29770db4212SSimon Glass }
29862584db1SSimon Glass 
29962584db1SSimon Glass void os_dirent_free(struct os_dirent_node *node)
30062584db1SSimon Glass {
30162584db1SSimon Glass 	struct os_dirent_node *next;
30262584db1SSimon Glass 
30362584db1SSimon Glass 	while (node) {
30462584db1SSimon Glass 		next = node->next;
30562584db1SSimon Glass 		free(node);
30662584db1SSimon Glass 		node = next;
30762584db1SSimon Glass 	}
30862584db1SSimon Glass }
30962584db1SSimon Glass 
31062584db1SSimon Glass int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
31162584db1SSimon Glass {
31262584db1SSimon Glass 	struct dirent entry, *result;
31362584db1SSimon Glass 	struct os_dirent_node *head, *node, *next;
31462584db1SSimon Glass 	struct stat buf;
31562584db1SSimon Glass 	DIR *dir;
31662584db1SSimon Glass 	int ret;
31762584db1SSimon Glass 	char *fname;
31862584db1SSimon Glass 	int len;
31962584db1SSimon Glass 
32062584db1SSimon Glass 	*headp = NULL;
32162584db1SSimon Glass 	dir = opendir(dirname);
32262584db1SSimon Glass 	if (!dir)
32362584db1SSimon Glass 		return -1;
32462584db1SSimon Glass 
32562584db1SSimon Glass 	/* Create a buffer for the maximum filename length */
32662584db1SSimon Glass 	len = sizeof(entry.d_name) + strlen(dirname) + 2;
32762584db1SSimon Glass 	fname = malloc(len);
32862584db1SSimon Glass 	if (!fname) {
32962584db1SSimon Glass 		ret = -ENOMEM;
33062584db1SSimon Glass 		goto done;
33162584db1SSimon Glass 	}
33262584db1SSimon Glass 
33362584db1SSimon Glass 	for (node = head = NULL;; node = next) {
33462584db1SSimon Glass 		ret = readdir_r(dir, &entry, &result);
33562584db1SSimon Glass 		if (ret || !result)
33662584db1SSimon Glass 			break;
33762584db1SSimon Glass 		next = malloc(sizeof(*node) + strlen(entry.d_name) + 1);
33862584db1SSimon Glass 		if (!next) {
33962584db1SSimon Glass 			os_dirent_free(head);
34062584db1SSimon Glass 			ret = -ENOMEM;
34162584db1SSimon Glass 			goto done;
34262584db1SSimon Glass 		}
34362584db1SSimon Glass 		strcpy(next->name, entry.d_name);
34462584db1SSimon Glass 		switch (entry.d_type) {
34562584db1SSimon Glass 		case DT_REG:
34662584db1SSimon Glass 			next->type = OS_FILET_REG;
34762584db1SSimon Glass 			break;
34862584db1SSimon Glass 		case DT_DIR:
34962584db1SSimon Glass 			next->type = OS_FILET_DIR;
35062584db1SSimon Glass 			break;
35162584db1SSimon Glass 		case DT_LNK:
35262584db1SSimon Glass 			next->type = OS_FILET_LNK;
35362584db1SSimon Glass 			break;
35462584db1SSimon Glass 		}
35562584db1SSimon Glass 		next->size = 0;
35662584db1SSimon Glass 		snprintf(fname, len, "%s/%s", dirname, next->name);
35762584db1SSimon Glass 		if (!stat(fname, &buf))
35862584db1SSimon Glass 			next->size = buf.st_size;
35962584db1SSimon Glass 		if (node)
36062584db1SSimon Glass 			node->next = next;
36162584db1SSimon Glass 		if (!head)
36262584db1SSimon Glass 			head = node;
36362584db1SSimon Glass 	}
36462584db1SSimon Glass 	*headp = head;
36562584db1SSimon Glass 
36662584db1SSimon Glass done:
36762584db1SSimon Glass 	closedir(dir);
36862584db1SSimon Glass 	return ret;
36962584db1SSimon Glass }
37062584db1SSimon Glass 
37162584db1SSimon Glass const char *os_dirent_typename[OS_FILET_COUNT] = {
37262584db1SSimon Glass 	"   ",
37362584db1SSimon Glass 	"SYM",
37462584db1SSimon Glass 	"DIR",
37562584db1SSimon Glass 	"???",
37662584db1SSimon Glass };
37762584db1SSimon Glass 
37862584db1SSimon Glass const char *os_dirent_get_typename(enum os_dirent_t type)
37962584db1SSimon Glass {
38062584db1SSimon Glass 	if (type >= 0 && type < OS_FILET_COUNT)
38162584db1SSimon Glass 		return os_dirent_typename[type];
38262584db1SSimon Glass 
38362584db1SSimon Glass 	return os_dirent_typename[OS_FILET_UNKNOWN];
38462584db1SSimon Glass }
38562584db1SSimon Glass 
38662584db1SSimon Glass ssize_t os_get_filesize(const char *fname)
38762584db1SSimon Glass {
38862584db1SSimon Glass 	struct stat buf;
38962584db1SSimon Glass 	int ret;
39062584db1SSimon Glass 
39162584db1SSimon Glass 	ret = stat(fname, &buf);
39262584db1SSimon Glass 	if (ret)
39362584db1SSimon Glass 		return ret;
39462584db1SSimon Glass 	return buf.st_size;
39562584db1SSimon Glass }
39691b136c7SSimon Glass 
39791b136c7SSimon Glass void os_putc(int ch)
39891b136c7SSimon Glass {
39991b136c7SSimon Glass 	putchar(ch);
40091b136c7SSimon Glass }
40191b136c7SSimon Glass 
40291b136c7SSimon Glass void os_puts(const char *str)
40391b136c7SSimon Glass {
40491b136c7SSimon Glass 	while (*str)
40591b136c7SSimon Glass 		os_putc(*str++);
40691b136c7SSimon Glass }
4075c2859cdSSimon Glass 
4085c2859cdSSimon Glass int os_write_ram_buf(const char *fname)
4095c2859cdSSimon Glass {
4105c2859cdSSimon Glass 	struct sandbox_state *state = state_get_current();
4115c2859cdSSimon Glass 	int fd, ret;
4125c2859cdSSimon Glass 
4135c2859cdSSimon Glass 	fd = open(fname, O_CREAT | O_WRONLY, 0777);
4145c2859cdSSimon Glass 	if (fd < 0)
4155c2859cdSSimon Glass 		return -ENOENT;
4165c2859cdSSimon Glass 	ret = write(fd, state->ram_buf, state->ram_size);
4175c2859cdSSimon Glass 	close(fd);
4185c2859cdSSimon Glass 	if (ret != state->ram_size)
4195c2859cdSSimon Glass 		return -EIO;
4205c2859cdSSimon Glass 
4215c2859cdSSimon Glass 	return 0;
4225c2859cdSSimon Glass }
4235c2859cdSSimon Glass 
4245c2859cdSSimon Glass int os_read_ram_buf(const char *fname)
4255c2859cdSSimon Glass {
4265c2859cdSSimon Glass 	struct sandbox_state *state = state_get_current();
4275c2859cdSSimon Glass 	int fd, ret;
4285c2859cdSSimon Glass 	int size;
4295c2859cdSSimon Glass 
4305c2859cdSSimon Glass 	size = os_get_filesize(fname);
4315c2859cdSSimon Glass 	if (size < 0)
4325c2859cdSSimon Glass 		return -ENOENT;
4335c2859cdSSimon Glass 	if (size != state->ram_size)
4345c2859cdSSimon Glass 		return -ENOSPC;
4355c2859cdSSimon Glass 	fd = open(fname, O_RDONLY);
4365c2859cdSSimon Glass 	if (fd < 0)
4375c2859cdSSimon Glass 		return -ENOENT;
4385c2859cdSSimon Glass 
4395c2859cdSSimon Glass 	ret = read(fd, state->ram_buf, state->ram_size);
4405c2859cdSSimon Glass 	close(fd);
4415c2859cdSSimon Glass 	if (ret != state->ram_size)
4425c2859cdSSimon Glass 		return -EIO;
4435c2859cdSSimon Glass 
4445c2859cdSSimon Glass 	return 0;
4455c2859cdSSimon Glass }
446