diff options
Diffstat (limited to 'roms/u-boot/arch/sandbox')
36 files changed, 2982 insertions, 0 deletions
diff --git a/roms/u-boot/arch/sandbox/config.mk b/roms/u-boot/arch/sandbox/config.mk new file mode 100644 index 00000000..c3f889fb --- /dev/null +++ b/roms/u-boot/arch/sandbox/config.mk @@ -0,0 +1,26 @@ +# Copyright (c) 2011 The Chromium OS Authors. +# SPDX-License-Identifier:	GPL-2.0+ + +PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE +PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM -DCONFIG_SYS_GENERIC_BOARD +PLATFORM_LIBS += -lrt + +ifdef CONFIG_SANDBOX_SDL +PLATFORM_LIBS += $(shell sdl-config --libs) +PLATFORM_CPPFLAGS += $(shell sdl-config --cflags) +endif + +# Support generic board on sandbox +__HAVE_ARCH_GENERIC_BOARD := y + +cmd_u-boot__ = $(CC) -o $@ -T u-boot.lds \ +	-Wl,--start-group $(u-boot-main) -Wl,--end-group \ +	$(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map + +CONFIG_ARCH_DEVICE_TREE := sandbox + +# Define this to avoid linking with SDL, which requires SDL libraries +# This can solve 'sdl-config: Command not found' errors +ifneq ($(NO_SDL),) +PLATFORM_CPPFLAGS += -DSANDBOX_NO_SDL +endif diff --git a/roms/u-boot/arch/sandbox/cpu/Makefile b/roms/u-boot/arch/sandbox/cpu/Makefile new file mode 100644 index 00000000..7d4410c4 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/Makefile @@ -0,0 +1,22 @@ +# +# Copyright (c) 2011 The Chromium OS Authors. +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	:= cpu.o os.o start.o state.o +obj-$(CONFIG_SANDBOX_SDL)	+= sdl.o + +# os.c is build in the system environment, so needs standard includes +# CFLAGS_REMOVE_os.o cannot be used to drop header include path +quiet_cmd_cc_os.o = CC $(quiet_modtag)  $@ +cmd_cc_os.o = $(CC) $(filter-out -nostdinc, \ +	$(patsubst -I%,-idirafter%,$(c_flags))) -c -o $@ $< + +$(obj)/os.o: $(src)/os.c FORCE +	$(call if_changed_dep,cc_os.o) +$(obj)/sdl.o: $(src)/sdl.c FORCE +	$(call if_changed_dep,cc_os.o) diff --git a/roms/u-boot/arch/sandbox/cpu/cpu.c b/roms/u-boot/arch/sandbox/cpu/cpu.c new file mode 100644 index 00000000..3f4005b5 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/cpu.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <os.h> +#include <asm/state.h> + +DECLARE_GLOBAL_DATA_PTR; + +void reset_cpu(ulong ignored) +{ +	if (state_uninit()) +		os_exit(2); + +	/* This is considered normal termination for now */ +	os_exit(0); +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	reset_cpu(0); + +	return 0; +} + +/* delay x useconds */ +void __udelay(unsigned long usec) +{ +	os_usleep(usec); +} + +unsigned long __attribute__((no_instrument_function)) timer_get_us(void) +{ +	return os_get_nsec() / 1000; +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ +	if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { +		bootstage_mark(BOOTSTAGE_ID_RUN_OS); +		printf("## Transferring control to Linux (at address %08lx)...\n", +		       images->ep); +		reset_cpu(0); +	} + +	return 0; +} + +int cleanup_before_linux(void) +{ +	return 0; +} + +void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ +	return (void *)(gd->arch.ram_buf + paddr); +} + +phys_addr_t map_to_sysmem(const void *ptr) +{ +	return (u8 *)ptr - gd->arch.ram_buf; +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} diff --git a/roms/u-boot/arch/sandbox/cpu/os.c b/roms/u-boot/arch/sandbox/cpu/os.c new file mode 100644 index 00000000..57d04a45 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/os.c @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <time.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <linux/types.h> + +#include <asm/getopt.h> +#include <asm/sections.h> +#include <asm/state.h> +#include <os.h> + +/* Operating System Interface */ + +struct os_mem_hdr { +	size_t length;		/* number of bytes in the block */ +}; + +ssize_t os_read(int fd, void *buf, size_t count) +{ +	return read(fd, buf, count); +} + +ssize_t os_read_no_block(int fd, void *buf, size_t count) +{ +	const int flags = fcntl(fd, F_GETFL, 0); + +	fcntl(fd, F_SETFL, flags | O_NONBLOCK); +	return os_read(fd, buf, count); +} + +ssize_t os_write(int fd, const void *buf, size_t count) +{ +	return write(fd, buf, count); +} + +off_t os_lseek(int fd, off_t offset, int whence) +{ +	if (whence == OS_SEEK_SET) +		whence = SEEK_SET; +	else if (whence == OS_SEEK_CUR) +		whence = SEEK_CUR; +	else if (whence == OS_SEEK_END) +		whence = SEEK_END; +	else +		os_exit(1); +	return lseek(fd, offset, whence); +} + +int os_open(const char *pathname, int os_flags) +{ +	int flags; + +	switch (os_flags & OS_O_MASK) { +	case OS_O_RDONLY: +	default: +		flags = O_RDONLY; +		break; + +	case OS_O_WRONLY: +		flags = O_WRONLY; +		break; + +	case OS_O_RDWR: +		flags = O_RDWR; +		break; +	} + +	if (os_flags & OS_O_CREAT) +		flags |= O_CREAT; + +	return open(pathname, flags, 0777); +} + +int os_close(int fd) +{ +	return close(fd); +} + +int os_unlink(const char *pathname) +{ +	return unlink(pathname); +} + +void os_exit(int exit_code) +{ +	exit(exit_code); +} + +/* Restore tty state when we exit */ +static struct termios orig_term; +static bool term_setup; + +static void os_fd_restore(void) +{ +	if (term_setup) +		tcsetattr(0, TCSANOW, &orig_term); +} + +/* Put tty into raw mode so <tab> and <ctrl+c> work */ +void os_tty_raw(int fd, bool allow_sigs) +{ +	struct termios term; + +	if (term_setup) +		return; +	term_setup = true; + +	/* If not a tty, don't complain */ +	if (tcgetattr(fd, &orig_term)) +		return; + +	term = orig_term; +	term.c_iflag = IGNBRK | IGNPAR; +	term.c_oflag = OPOST | ONLCR; +	term.c_cflag = CS8 | CREAD | CLOCAL; +	term.c_lflag = allow_sigs ? ISIG : 0; +	if (tcsetattr(fd, TCSANOW, &term)) +		return; + +	atexit(os_fd_restore); +} + +void *os_malloc(size_t length) +{ +	struct os_mem_hdr *hdr; + +	hdr = mmap(NULL, length + sizeof(*hdr), PROT_READ | PROT_WRITE, +		   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +	if (hdr == MAP_FAILED) +		return NULL; +	hdr->length = length; + +	return hdr + 1; +} + +void os_free(void *ptr) +{ +	struct os_mem_hdr *hdr = ptr; + +	hdr--; +	if (ptr) +		munmap(hdr, hdr->length + sizeof(*hdr)); +} + +void *os_realloc(void *ptr, size_t length) +{ +	struct os_mem_hdr *hdr = ptr; +	void *buf = NULL; + +	hdr--; +	if (length != 0) { +		buf = os_malloc(length); +		if (!buf) +			return buf; +		if (ptr) { +			if (length > hdr->length) +				length = hdr->length; +			memcpy(buf, ptr, length); +		} +	} +	os_free(ptr); + +	return buf; +} + +void os_usleep(unsigned long usec) +{ +	usleep(usec); +} + +uint64_t __attribute__((no_instrument_function)) os_get_nsec(void) +{ +#if defined(CLOCK_MONOTONIC) && defined(_POSIX_MONOTONIC_CLOCK) +	struct timespec tp; +	if (EINVAL == clock_gettime(CLOCK_MONOTONIC, &tp)) { +		struct timeval tv; + +		gettimeofday(&tv, NULL); +		tp.tv_sec = tv.tv_sec; +		tp.tv_nsec = tv.tv_usec * 1000; +	} +	return tp.tv_sec * 1000000000ULL + tp.tv_nsec; +#else +	struct timeval tv; +	gettimeofday(&tv, NULL); +	return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000; +#endif +} + +static char *short_opts; +static struct option *long_opts; + +int os_parse_args(struct sandbox_state *state, int argc, char *argv[]) +{ +	struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start; +	size_t num_options = __u_boot_sandbox_option_count(); +	size_t i; + +	int hidden_short_opt; +	size_t si; + +	int c; + +	if (short_opts || long_opts) +		return 1; + +	state->argc = argc; +	state->argv = argv; + +	/* dynamically construct the arguments to the system getopt_long */ +	short_opts = os_malloc(sizeof(*short_opts) * num_options * 2 + 1); +	long_opts = os_malloc(sizeof(*long_opts) * num_options); +	if (!short_opts || !long_opts) +		return 1; + +	/* +	 * getopt_long requires "val" to be unique (since that is what the +	 * func returns), so generate unique values automatically for flags +	 * that don't have a short option.  pick 0x100 as that is above the +	 * single byte range (where ASCII/ISO-XXXX-X charsets live). +	 */ +	hidden_short_opt = 0x100; +	si = 0; +	for (i = 0; i < num_options; ++i) { +		long_opts[i].name = sb_opt[i]->flag; +		long_opts[i].has_arg = sb_opt[i]->has_arg ? +			required_argument : no_argument; +		long_opts[i].flag = NULL; + +		if (sb_opt[i]->flag_short) { +			short_opts[si++] = long_opts[i].val = sb_opt[i]->flag_short; +			if (long_opts[i].has_arg == required_argument) +				short_opts[si++] = ':'; +		} else +			long_opts[i].val = sb_opt[i]->flag_short = hidden_short_opt++; +	} +	short_opts[si] = '\0'; + +	/* we need to handle output ourselves since u-boot provides printf */ +	opterr = 0; + +	/* +	 * walk all of the options the user gave us on the command line, +	 * figure out what u-boot option structure they belong to (via +	 * the unique short val key), and call the appropriate callback. +	 */ +	while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { +		for (i = 0; i < num_options; ++i) { +			if (sb_opt[i]->flag_short == c) { +				if (sb_opt[i]->callback(state, optarg)) { +					state->parse_err = sb_opt[i]->flag; +					return 0; +				} +				break; +			} +		} +		if (i == num_options) { +			/* +			 * store the faulting flag for later display.  we have to +			 * store the flag itself as the getopt parsing itself is +			 * tricky: need to handle the following flags (assume all +			 * of the below are unknown): +			 *   -a        optopt='a' optind=<next> +			 *   -abbbb    optopt='a' optind=<this> +			 *   -aaaaa    optopt='a' optind=<this> +			 *   --a       optopt=0   optind=<this> +			 * as you can see, it is impossible to determine the exact +			 * faulting flag without doing the parsing ourselves, so +			 * we just report the specific flag that failed. +			 */ +			if (optopt) { +				static char parse_err[3] = { '-', 0, '\0', }; +				parse_err[1] = optopt; +				state->parse_err = parse_err; +			} else +				state->parse_err = argv[optind - 1]; +			break; +		} +	} + +	return 0; +} + +void os_dirent_free(struct os_dirent_node *node) +{ +	struct os_dirent_node *next; + +	while (node) { +		next = node->next; +		free(node); +		node = next; +	} +} + +int os_dirent_ls(const char *dirname, struct os_dirent_node **headp) +{ +	struct dirent entry, *result; +	struct os_dirent_node *head, *node, *next; +	struct stat buf; +	DIR *dir; +	int ret; +	char *fname; +	int len; + +	*headp = NULL; +	dir = opendir(dirname); +	if (!dir) +		return -1; + +	/* Create a buffer for the maximum filename length */ +	len = sizeof(entry.d_name) + strlen(dirname) + 2; +	fname = malloc(len); +	if (!fname) { +		ret = -ENOMEM; +		goto done; +	} + +	for (node = head = NULL;; node = next) { +		ret = readdir_r(dir, &entry, &result); +		if (ret || !result) +			break; +		next = malloc(sizeof(*node) + strlen(entry.d_name) + 1); +		if (!next) { +			os_dirent_free(head); +			ret = -ENOMEM; +			goto done; +		} +		strcpy(next->name, entry.d_name); +		switch (entry.d_type) { +		case DT_REG: +			next->type = OS_FILET_REG; +			break; +		case DT_DIR: +			next->type = OS_FILET_DIR; +			break; +		case DT_LNK: +			next->type = OS_FILET_LNK; +			break; +		} +		next->size = 0; +		snprintf(fname, len, "%s/%s", dirname, next->name); +		if (!stat(fname, &buf)) +			next->size = buf.st_size; +		if (node) +			node->next = next; +		if (!head) +			head = node; +	} +	*headp = head; + +done: +	closedir(dir); +	return ret; +} + +const char *os_dirent_typename[OS_FILET_COUNT] = { +	"   ", +	"SYM", +	"DIR", +	"???", +}; + +const char *os_dirent_get_typename(enum os_dirent_t type) +{ +	if (type >= 0 && type < OS_FILET_COUNT) +		return os_dirent_typename[type]; + +	return os_dirent_typename[OS_FILET_UNKNOWN]; +} + +ssize_t os_get_filesize(const char *fname) +{ +	struct stat buf; +	int ret; + +	ret = stat(fname, &buf); +	if (ret) +		return ret; +	return buf.st_size; +} + +void os_putc(int ch) +{ +	putchar(ch); +} + +void os_puts(const char *str) +{ +	while (*str) +		os_putc(*str++); +} + +int os_write_ram_buf(const char *fname) +{ +	struct sandbox_state *state = state_get_current(); +	int fd, ret; + +	fd = open(fname, O_CREAT | O_WRONLY, 0777); +	if (fd < 0) +		return -ENOENT; +	ret = write(fd, state->ram_buf, state->ram_size); +	close(fd); +	if (ret != state->ram_size) +		return -EIO; + +	return 0; +} + +int os_read_ram_buf(const char *fname) +{ +	struct sandbox_state *state = state_get_current(); +	int fd, ret; +	int size; + +	size = os_get_filesize(fname); +	if (size < 0) +		return -ENOENT; +	if (size != state->ram_size) +		return -ENOSPC; +	fd = open(fname, O_RDONLY); +	if (fd < 0) +		return -ENOENT; + +	ret = read(fd, state->ram_buf, state->ram_size); +	close(fd); +	if (ret != state->ram_size) +		return -EIO; + +	return 0; +} + +static int make_exec(char *fname, const void *data, int size) +{ +	int fd; + +	strcpy(fname, "/tmp/u-boot.jump.XXXXXX"); +	fd = mkstemp(fname); +	if (fd < 0) +		return -ENOENT; +	if (write(fd, data, size) < 0) +		return -EIO; +	close(fd); +	if (chmod(fname, 0777)) +		return -ENOEXEC; + +	return 0; +} + +static int add_args(char ***argvp, const char *add_args[], int count) +{ +	char **argv; +	int argc; + +	for (argv = *argvp, argc = 0; (*argvp)[argc]; argc++) +		; + +	argv = malloc((argc + count + 1) * sizeof(char *)); +	if (!argv) { +		printf("Out of memory for %d argv\n", count); +		return -ENOMEM; +	} +	memcpy(argv, *argvp, argc * sizeof(char *)); +	memcpy(argv + argc, add_args, count * sizeof(char *)); +	argv[argc + count] = NULL; + +	*argvp = argv; +	return 0; +} + +int os_jump_to_image(const void *dest, int size) +{ +	struct sandbox_state *state = state_get_current(); +	char fname[30], mem_fname[30]; +	int fd, err; +	const char *extra_args[5]; +	char **argv = state->argv; +#ifdef DEBUG +	int argc, i; +#endif + +	err = make_exec(fname, dest, size); +	if (err) +		return err; + +	strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX"); +	fd = mkstemp(mem_fname); +	if (fd < 0) +		return -ENOENT; +	close(fd); +	err = os_write_ram_buf(mem_fname); +	if (err) +		return err; + +	os_fd_restore(); + +	extra_args[0] = "-j"; +	extra_args[1] = fname; +	extra_args[2] = "-m"; +	extra_args[3] = mem_fname; +	extra_args[4] = "--rm_memory"; +	err = add_args(&argv, extra_args, +		       sizeof(extra_args) / sizeof(extra_args[0])); +	if (err) +		return err; + +#ifdef DEBUG +	for (i = 0; argv[i]; i++) +		printf("%d %s\n", i, argv[i]); +#endif + +	if (state_uninit()) +		os_exit(2); + +	err = execv(fname, argv); +	free(argv); +	if (err) +		return err; + +	return unlink(fname); +} diff --git a/roms/u-boot/arch/sandbox/cpu/sdl.c b/roms/u-boot/arch/sandbox/cpu/sdl.c new file mode 100644 index 00000000..18dc7edf --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/sdl.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2013 Google, Inc + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <errno.h> +#include <linux/input.h> +#include <SDL/SDL.h> +#include <sound.h> +#include <asm/state.h> + +static struct sdl_info { +	SDL_Surface *screen; +	int width; +	int height; +	int depth; +	int pitch; +	uint frequency; +	uint audio_pos; +	uint audio_size; +	uint8_t *audio_data; +	bool audio_active; +	bool inited; +} sdl; + +static void sandbox_sdl_poll_events(void) +{ +	/* +	 * We don't want to include common.h in this file since it uses +	 * system headers. So add a declation here. +	 */ +	extern void reset_cpu(unsigned long addr); +	SDL_Event event; + +	while (SDL_PollEvent(&event)) { +		switch (event.type) { +		case SDL_QUIT: +			puts("LCD window closed - quitting\n"); +			reset_cpu(1); +			break; +		} +	} +} + +static int sandbox_sdl_ensure_init(void) +{ +	if (!sdl.inited) { +		if (SDL_Init(0) < 0) { +			printf("Unable to initialize SDL: %s\n", +			       SDL_GetError()); +			return -EIO; +		} + +		atexit(SDL_Quit); + +		sdl.inited = true; +	} +	return 0; +} + +int sandbox_sdl_init_display(int width, int height, int log2_bpp) +{ +	struct sandbox_state *state = state_get_current(); +	int err; + +	if (!width || !state->show_lcd) +		return 0; +	err = sandbox_sdl_ensure_init(); +	if (err) +		return err; +	if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { +		printf("Unable to initialize SDL LCD: %s\n", SDL_GetError()); +		return -EPERM; +	} +	SDL_WM_SetCaption("U-Boot", "U-Boot"); + +	sdl.width = width; +	sdl.height = height; +	sdl.depth = 1 << log2_bpp; +	sdl.pitch = sdl.width * sdl.depth / 8; +	sdl.screen = SDL_SetVideoMode(width, height, 0, 0); +	sandbox_sdl_poll_events(); + +	return 0; +} + +int sandbox_sdl_sync(void *lcd_base) +{ +	SDL_Surface *frame; + +	frame = SDL_CreateRGBSurfaceFrom(lcd_base, sdl.width, sdl.height, +			sdl.depth, sdl.pitch, +			0x1f << 11, 0x3f << 5, 0x1f << 0, 0); +	SDL_BlitSurface(frame, NULL, sdl.screen, NULL); +	SDL_FreeSurface(frame); +	SDL_UpdateRect(sdl.screen, 0, 0, 0, 0); +	sandbox_sdl_poll_events(); + +	return 0; +} + +#define NONE (-1) +#define NUM_SDL_CODES	(SDLK_UNDO + 1) + +static int16_t sdl_to_keycode[NUM_SDL_CODES] = { +	/* 0 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, KEY_BACKSPACE, KEY_TAB, +	NONE, NONE, NONE, KEY_ENTER, NONE, +	NONE, NONE, NONE, NONE, KEY_POWER,	/* use PAUSE as POWER */ + +	/* 20 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, KEY_ESC, NONE, NONE, +	NONE, NONE, KEY_SPACE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 40 */ +	NONE, NONE, NONE, NONE, KEY_COMMA, +	KEY_MINUS, KEY_DOT, KEY_SLASH, KEY_0, KEY_1, +	KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, +	KEY_7, KEY_8, KEY_9, NONE, KEY_SEMICOLON, + +	/* 60 */ +	NONE, KEY_EQUAL, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 80 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, KEY_BACKSLASH, NONE, NONE, +	NONE, KEY_GRAVE, KEY_A, KEY_B, KEY_C, + +	/* 100 */ +	KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, +	KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, +	KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, +	KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, + +	/* 120 */ +	KEY_X, KEY_Y, KEY_Z, NONE, NONE, +	NONE, NONE, KEY_DELETE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 140 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 160 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 180 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 200 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 220 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 240 */ +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, NONE, NONE, NONE, NONE, +	NONE, KEY_KP0, KEY_KP1, KEY_KP2, KEY_KP3, + +	/* 260 */ +	KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8, +	KEY_KP9, KEY_KPDOT, KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, +	KEY_KPPLUS, KEY_KPENTER, KEY_KPEQUAL, KEY_UP, KEY_DOWN, +	KEY_RIGHT, KEY_LEFT, KEY_INSERT, KEY_HOME, KEY_END, + +	/* 280 */ +	KEY_PAGEUP, KEY_PAGEDOWN, KEY_F1, KEY_F2, KEY_F3, +	KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, +	KEY_F9, KEY_F10, KEY_F11, KEY_F12, NONE, +	NONE, NONE, NONE, NONE, NONE, + +	/* 300 */ +	KEY_NUMLOCK, KEY_CAPSLOCK, KEY_SCROLLLOCK, KEY_RIGHTSHIFT, +		KEY_LEFTSHIFT, +	KEY_RIGHTCTRL, KEY_LEFTCTRL, KEY_RIGHTALT, KEY_LEFTALT, KEY_RIGHTMETA, +	KEY_LEFTMETA, NONE, KEY_FN, NONE, KEY_COMPOSE, +	NONE, KEY_PRINT, KEY_SYSRQ, KEY_PAUSE, NONE, + +	/* 320 */ +	NONE, NONE, NONE, +}; + +int sandbox_sdl_scan_keys(int key[], int max_keys) +{ +	Uint8 *keystate; +	int i, count; + +	sandbox_sdl_poll_events(); +	keystate = SDL_GetKeyState(NULL); +	for (i = count = 0; i < NUM_SDL_CODES; i++) { +		if (count >= max_keys) +			break; +		else if (keystate[i]) +			key[count++] = sdl_to_keycode[i]; +	} + +	return count; +} + +int sandbox_sdl_key_pressed(int keycode) +{ +	int key[8];	/* allow up to 8 keys to be pressed at once */ +	int count; +	int i; + +	count = sandbox_sdl_scan_keys(key, sizeof(key) / sizeof(key[0])); +	for (i = 0; i < count; i++) { +		if (key[i] == keycode) +			return 0; +	} + +	return -ENOENT; +} + +void sandbox_sdl_fill_audio(void *udata, Uint8 *stream, int len) +{ +	int avail; + +	avail = sdl.audio_size - sdl.audio_pos; +	if (avail < len) +		len = avail; + +	SDL_MixAudio(stream, sdl.audio_data + sdl.audio_pos, len, +		     SDL_MIX_MAXVOLUME); +	sdl.audio_pos += len; + +	/* Loop if we are at the end */ +	if (sdl.audio_pos == sdl.audio_size) +		sdl.audio_pos = 0; +} + +int sandbox_sdl_sound_init(void) +{ +	SDL_AudioSpec wanted; + +	if (sandbox_sdl_ensure_init()) +		return -1; + +	if (sdl.audio_active) +		return 0; + +	/* +	 * At present all sandbox sounds crash. This is probably due to +	 * symbol name conflicts with U-Boot. We can remove the malloc() +	 * probles with: +	 * +	 * #define USE_DL_PREFIX +	 * +	 * and get this: +	 * +	 * Assertion 'e->pollfd->fd == e->fd' failed at pulse/mainloop.c:676, +	 *		function dispatch_pollfds(). Aborting. +	 * +	 * The right solution is probably to make U-Boot's names private or +	 * link os.c and sdl.c against their libraries before liking with +	 * U-Boot. TBD. For now sound is disabled. +	 */ +	printf("(Warning: sandbox sound disabled)\n"); +	return 0; + +	/* Set the audio format */ +	wanted.freq = 22050; +	wanted.format = AUDIO_S16; +	wanted.channels = 1;    /* 1 = mono, 2 = stereo */ +	wanted.samples = 1024;  /* Good low-latency value for callback */ +	wanted.callback = sandbox_sdl_fill_audio; +	wanted.userdata = NULL; + +	sdl.audio_size = sizeof(uint16_t) * wanted.freq; +	sdl.audio_data = malloc(sdl.audio_size); +	if (!sdl.audio_data) { +		printf("%s: Out of memory\n", __func__); +		return -1; +	} +	sdl.audio_pos = 0; + +	if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { +		printf("Unable to initialize SDL audio: %s\n", SDL_GetError()); +		goto err; +	} + +	/* Open the audio device, forcing the desired format */ +	if (SDL_OpenAudio(&wanted, NULL) < 0) { +		printf("Couldn't open audio: %s\n", SDL_GetError()); +		goto err; +	} +	sdl.audio_active = true; + +	return 0; + +err: +	free(sdl.audio_data); +	return -1; +} + +int sandbox_sdl_sound_start(uint frequency) +{ +	if (!sdl.audio_active) +		return -1; +	sdl.frequency = frequency; +	sound_create_square_wave((unsigned short *)sdl.audio_data, +				 sdl.audio_size, frequency); +	sdl.audio_pos = 0; +	SDL_PauseAudio(0); + +	return 0; +} + +int sandbox_sdl_sound_stop(void) +{ +	if (!sdl.audio_active) +		return -1; +	SDL_PauseAudio(1); + +	return 0; +} diff --git a/roms/u-boot/arch/sandbox/cpu/start.c b/roms/u-boot/arch/sandbox/cpu/start.c new file mode 100644 index 00000000..aad3b8b1 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/start.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <os.h> +#include <asm/getopt.h> +#include <asm/sections.h> +#include <asm/state.h> + +DECLARE_GLOBAL_DATA_PTR; + +int sandbox_early_getopt_check(void) +{ +	struct sandbox_state *state = state_get_current(); +	struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start; +	size_t num_options = __u_boot_sandbox_option_count(); +	size_t i; +	int max_arg_len, max_noarg_len; + +	/* parse_err will be a string of the faulting option */ +	if (!state->parse_err) +		return 0; + +	if (strcmp(state->parse_err, "help")) { +		printf("u-boot: error: failed while parsing option: %s\n" +			"\ttry running with --help for more information.\n", +			state->parse_err); +		os_exit(1); +	} + +	printf( +		"u-boot, a command line test interface to U-Boot\n\n" +		"Usage: u-boot [options]\n" +		"Options:\n"); + +	max_arg_len = 0; +	for (i = 0; i < num_options; ++i) +		max_arg_len = max(strlen(sb_opt[i]->flag), max_arg_len); +	max_noarg_len = max_arg_len + 7; + +	for (i = 0; i < num_options; ++i) { +		struct sandbox_cmdline_option *opt = sb_opt[i]; + +		/* first output the short flag if it has one */ +		if (opt->flag_short >= 0x100) +			printf("      "); +		else +			printf("  -%c, ", opt->flag_short); + +		/* then the long flag */ +		if (opt->has_arg) +			printf("--%-*s <arg> ", max_arg_len, opt->flag); +		else +			printf("--%-*s", max_noarg_len, opt->flag); + +		/* finally the help text */ +		printf("  %s\n", opt->help); +	} + +	os_exit(0); +} + +static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg) +{ +	/* just flag to sandbox_early_getopt_check to show usage */ +	return 1; +} +SANDBOX_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help"); + +int sandbox_main_loop_init(void) +{ +	struct sandbox_state *state = state_get_current(); + +	/* Execute command if required */ +	if (state->cmd) { +		run_command_list(state->cmd, -1, 0); +		if (!state->interactive) +			os_exit(state->exit_type); +	} + +	return 0; +} + +static int sandbox_cmdline_cb_command(struct sandbox_state *state, +				      const char *arg) +{ +	state->cmd = arg; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command"); + +static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg) +{ +	state->fdt_fname = arg; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT"); + +static int sandbox_cmdline_cb_interactive(struct sandbox_state *state, +					  const char *arg) +{ +	state->interactive = true; +	return 0; +} + +SANDBOX_CMDLINE_OPT_SHORT(interactive, 'i', 0, "Enter interactive mode"); + +static int sandbox_cmdline_cb_jump(struct sandbox_state *state, +				   const char *arg) +{ +	/* Remember to delete this U-Boot image later */ +	state->jumped_fname = arg; + +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(jump, 'j', 1, "Jumped from previous U-Boot"); + +static int sandbox_cmdline_cb_memory(struct sandbox_state *state, +				     const char *arg) +{ +	int err; + +	/* For now assume we always want to write it */ +	state->write_ram_buf = true; +	state->ram_buf_fname = arg; + +	if (os_read_ram_buf(arg)) { +		printf("Failed to read RAM buffer\n"); +		return err; +	} + +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(memory, 'm', 1, +			  "Read/write ram_buf memory contents from file"); + +static int sandbox_cmdline_cb_rm_memory(struct sandbox_state *state, +					const char *arg) +{ +	state->ram_buf_rm = true; + +	return 0; +} +SANDBOX_CMDLINE_OPT(rm_memory, 0, "Remove memory file after reading"); + +static int sandbox_cmdline_cb_state(struct sandbox_state *state, +				    const char *arg) +{ +	state->state_fname = arg; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(state, 's', 1, "Specify the sandbox state FDT"); + +static int sandbox_cmdline_cb_read(struct sandbox_state *state, +				   const char *arg) +{ +	state->read_state = true; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(read, 'r', 0, "Read the state FDT on startup"); + +static int sandbox_cmdline_cb_write(struct sandbox_state *state, +				    const char *arg) +{ +	state->write_state = true; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(write, 'w', 0, "Write state FDT on exit"); + +static int sandbox_cmdline_cb_ignore_missing(struct sandbox_state *state, +					     const char *arg) +{ +	state->ignore_missing_state_on_read = true; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(ignore_missing, 'n', 0, +			  "Ignore missing state on read"); + +static int sandbox_cmdline_cb_show_lcd(struct sandbox_state *state, +				       const char *arg) +{ +	state->show_lcd = true; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(show_lcd, 'l', 0, +			  "Show the sandbox LCD display"); + +static const char *term_args[STATE_TERM_COUNT] = { +	"raw-with-sigs", +	"raw", +	"cooked", +}; + +static int sandbox_cmdline_cb_terminal(struct sandbox_state *state, +				       const char *arg) +{ +	int i; + +	for (i = 0; i < STATE_TERM_COUNT; i++) { +		if (!strcmp(arg, term_args[i])) { +			state->term_raw = i; +			return 0; +		} +	} + +	printf("Unknown terminal setting '%s' (", arg); +	for (i = 0; i < STATE_TERM_COUNT; i++) +		printf("%s%s", i ? ", " : "", term_args[i]); +	puts(")\n"); + +	return 1; +} +SANDBOX_CMDLINE_OPT_SHORT(terminal, 't', 1, +			  "Set terminal to raw/cooked mode"); + +int main(int argc, char *argv[]) +{ +	struct sandbox_state *state; +	int ret; + +	ret = state_init(); +	if (ret) +		goto err; + +	state = state_get_current(); +	if (os_parse_args(state, argc, argv)) +		return 1; + +	ret = sandbox_read_state(state, state->state_fname); +	if (ret) +		goto err; + +	/* Remove old memory file if required */ +	if (state->ram_buf_rm && state->ram_buf_fname) +		os_unlink(state->ram_buf_fname); + +	/* Do pre- and post-relocation init */ +	board_init_f(0); + +	board_init_r(gd->new_gd, 0); + +	/* NOTREACHED - board_init_r() does not return */ +	return 0; + +err: +	printf("Error %d\n", ret); +	return 1; +} diff --git a/roms/u-boot/arch/sandbox/cpu/state.c b/roms/u-boot/arch/sandbox/cpu/state.c new file mode 100644 index 00000000..59adad65 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/state.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <fdtdec.h> +#include <os.h> +#include <asm/state.h> + +/* Main state record for the sandbox */ +static struct sandbox_state main_state; +static struct sandbox_state *state;	/* Pointer to current state record */ + +void state_record_exit(enum exit_type_id exit_type) +{ +	state->exit_type = exit_type; +} + +static int state_ensure_space(int extra_size) +{ +	void *blob = state->state_fdt; +	int used, size, free; +	void *buf; +	int ret; + +	used = fdt_off_dt_strings(blob) + fdt_size_dt_strings(blob); +	size = fdt_totalsize(blob); +	free = size - used; +	if (free > extra_size) +		return 0; + +	size = used + extra_size; +	buf = os_malloc(size); +	if (!buf) +		return -ENOMEM; + +	ret = fdt_open_into(blob, buf, size); +	if (ret) { +		os_free(buf); +		return -EIO; +	} + +	os_free(blob); +	state->state_fdt = buf; +	return 0; +} + +static int state_read_file(struct sandbox_state *state, const char *fname) +{ +	int size; +	int ret; +	int fd; + +	size = os_get_filesize(fname); +	if (size < 0) { +		printf("Cannot find sandbox state file '%s'\n", fname); +		return -ENOENT; +	} +	state->state_fdt = os_malloc(size); +	if (!state->state_fdt) { +		puts("No memory to read sandbox state\n"); +		return -ENOMEM; +	} +	fd = os_open(fname, OS_O_RDONLY); +	if (fd < 0) { +		printf("Cannot open sandbox state file '%s'\n", fname); +		ret = -EPERM; +		goto err_open; +	} +	if (os_read(fd, state->state_fdt, size) != size) { +		printf("Cannot read sandbox state file '%s'\n", fname); +		ret = -EIO; +		goto err_read; +	} +	os_close(fd); + +	return 0; +err_read: +	os_close(fd); +err_open: +	os_free(state->state_fdt); +	state->state_fdt = NULL; + +	return ret; +} + +/*** + * sandbox_read_state_nodes() - Read state associated with a driver + * + * This looks through all compatible nodes and calls the read function on + * each one, to read in the state. + * + * If nothing is found, it still calls the read function once, to set up a + * single global state for that driver. + * + * @state: Sandbox state + * @io: Method to use for reading state + * @blob: FDT containing state + * @return 0 if OK, -EINVAL if the read function returned failure + */ +int sandbox_read_state_nodes(struct sandbox_state *state, +			     struct sandbox_state_io *io, const void *blob) +{ +	int count; +	int node; +	int ret; + +	debug("   - read %s\n", io->name); +	if (!io->read) +		return 0; + +	node = -1; +	count = 0; +	while (blob) { +		node = fdt_node_offset_by_compatible(blob, node, io->compat); +		if (node < 0) +			return 0;	/* No more */ +		debug("   - read node '%s'\n", fdt_get_name(blob, node, NULL)); +		ret = io->read(blob, node); +		if (ret) { +			printf("Unable to read state for '%s'\n", io->compat); +			return -EINVAL; +		} +		count++; +	} + +	/* +	 * If we got no saved state, call the read function once without a +	 * node, to set up the global state. +	 */ +	if (count == 0) { +		debug("   - read global\n"); +		ret = io->read(NULL, -1); +		if (ret) { +			printf("Unable to read global state for '%s'\n", +			       io->name); +			return -EINVAL; +		} +	} + +	return 0; +} + +int sandbox_read_state(struct sandbox_state *state, const char *fname) +{ +	struct sandbox_state_io *io; +	const void *blob; +	bool got_err; +	int ret; + +	if (state->read_state && fname) { +		ret = state_read_file(state, fname); +		if (ret == -ENOENT && state->ignore_missing_state_on_read) +			ret = 0; +		if (ret) +			return ret; +	} + +	/* Call all the state read funtcions */ +	got_err = false; +	blob = state->state_fdt; +	io = ll_entry_start(struct sandbox_state_io, state_io); +	for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) { +		ret = sandbox_read_state_nodes(state, io, blob); +		if (ret < 0) +			got_err = true; +	} + +	if (state->read_state && fname) { +		debug("Read sandbox state from '%s'%s\n", fname, +		      got_err ? " (with errors)" : ""); +	} + +	return got_err ? -1 : 0; +} + +/*** + * sandbox_write_state_node() - Write state associated with a driver + * + * This calls the write function to write out global state for that driver. + * + * TODO(sjg@chromium.org): Support writing out state from multiple drivers + * of the same time. We don't need this yet,and it will be much easier to + * do when driver model is available. + * + * @state: Sandbox state + * @io: Method to use for writing state + * @return 0 if OK, -EIO if there is a fatal error (such as out of space + * for adding the data), -EINVAL if the write function failed. + */ +int sandbox_write_state_node(struct sandbox_state *state, +			     struct sandbox_state_io *io) +{ +	void *blob; +	int node; +	int ret; + +	if (!io->write) +		return 0; + +	ret = state_ensure_space(SANDBOX_STATE_MIN_SPACE); +	if (ret) { +		printf("Failed to add more space for state\n"); +		return -EIO; +	} + +	/* The blob location can change when the size increases */ +	blob = state->state_fdt; +	node = fdt_node_offset_by_compatible(blob, -1, io->compat); +	if (node == -FDT_ERR_NOTFOUND) { +		node = fdt_add_subnode(blob, 0, io->name); +		if (node < 0) { +			printf("Cannot create node '%s': %s\n", io->name, +			       fdt_strerror(node)); +			return -EIO; +		} + +		if (fdt_setprop_string(blob, node, "compatible", io->compat)) { +			puts("Cannot set compatible\n"); +			return -EIO; +		} +	} else if (node < 0) { +		printf("Cannot access node '%s': %s\n", io->name, +		       fdt_strerror(node)); +		return -EIO; +	} +	debug("Write state for '%s' to node %d\n", io->compat, node); +	ret = io->write(blob, node); +	if (ret) { +		printf("Unable to write state for '%s'\n", io->compat); +		return -EINVAL; +	} + +	return 0; +} + +int sandbox_write_state(struct sandbox_state *state, const char *fname) +{ +	struct sandbox_state_io *io; +	bool got_err; +	int size; +	int ret; +	int fd; + +	/* Create a state FDT if we don't have one */ +	if (!state->state_fdt) { +		size = 0x4000; +		state->state_fdt = os_malloc(size); +		if (!state->state_fdt) { +			puts("No memory to create FDT\n"); +			return -ENOMEM; +		} +		ret = fdt_create_empty_tree(state->state_fdt, size); +		if (ret < 0) { +			printf("Cannot create empty state FDT: %s\n", +			       fdt_strerror(ret)); +			ret = -EIO; +			goto err_create; +		} +	} + +	/* Call all the state write funtcions */ +	got_err = false; +	io = ll_entry_start(struct sandbox_state_io, state_io); +	ret = 0; +	for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) { +		ret = sandbox_write_state_node(state, io); +		if (ret == -EIO) +			break; +		else if (ret) +			got_err = true; +	} + +	if (ret == -EIO) { +		printf("Could not write sandbox state\n"); +		goto err_create; +	} + +	ret = fdt_pack(state->state_fdt); +	if (ret < 0) { +		printf("Cannot pack state FDT: %s\n", fdt_strerror(ret)); +		ret = -EINVAL; +		goto err_create; +	} +	size = fdt_totalsize(state->state_fdt); +	fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT); +	if (fd < 0) { +		printf("Cannot open sandbox state file '%s'\n", fname); +		ret = -EIO; +		goto err_create; +	} +	if (os_write(fd, state->state_fdt, size) != size) { +		printf("Cannot write sandbox state file '%s'\n", fname); +		ret = -EIO; +		goto err_write; +	} +	os_close(fd); + +	debug("Wrote sandbox state to '%s'%s\n", fname, +	      got_err ? " (with errors)" : ""); + +	return 0; +err_write: +	os_close(fd); +err_create: +	os_free(state->state_fdt); + +	return ret; +} + +int state_setprop(int node, const char *prop_name, const void *data, int size) +{ +	void *blob; +	int len; +	int ret; + +	fdt_getprop(state->state_fdt, node, prop_name, &len); + +	/* Add space for the new property, its name and some overhead */ +	ret = state_ensure_space(size - len + strlen(prop_name) + 32); +	if (ret) +		return ret; + +	/* This should succeed, barring a mutiny */ +	blob = state->state_fdt; +	ret = fdt_setprop(blob, node, prop_name, data, size); +	if (ret) { +		printf("%s: Unable to set property '%s' in node '%s': %s\n", +		       __func__, prop_name, fdt_get_name(blob, node, NULL), +			fdt_strerror(ret)); +		return -ENOSPC; +	} + +	return 0; +} + +struct sandbox_state *state_get_current(void) +{ +	assert(state); +	return state; +} + +int state_init(void) +{ +	state = &main_state; + +	state->ram_size = CONFIG_SYS_SDRAM_SIZE; +	state->ram_buf = os_malloc(state->ram_size); +	assert(state->ram_buf); + +	/* +	 * Example of how to use GPIOs: +	 * +	 * sandbox_gpio_set_direction(170, 0); +	 * sandbox_gpio_set_value(170, 0); +	 */ +	return 0; +} + +int state_uninit(void) +{ +	int err; + +	state = &main_state; + +	if (state->write_ram_buf && !state->ram_buf_rm) { +		err = os_write_ram_buf(state->ram_buf_fname); +		if (err) { +			printf("Failed to write RAM buffer\n"); +			return err; +		} +	} + +	if (state->write_state) { +		if (sandbox_write_state(state, state->state_fname)) { +			printf("Failed to write sandbox state\n"); +			return -1; +		} +	} + +	/* Delete this at the last moment so as not to upset gdb too much */ +	if (state->jumped_fname) +		os_unlink(state->jumped_fname); + +	if (state->state_fdt) +		os_free(state->state_fdt); +	memset(state, '\0', sizeof(*state)); + +	return 0; +} diff --git a/roms/u-boot/arch/sandbox/cpu/u-boot.lds b/roms/u-boot/arch/sandbox/cpu/u-boot.lds new file mode 100644 index 00000000..7e92b4ac --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/u-boot.lds @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +SECTIONS +{ + +	. = ALIGN(4); +	.u_boot_list : { +		KEEP(*(SORT(.u_boot_list*))); +	} + +	__u_boot_sandbox_option_start = .; +	_u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) } +	__u_boot_sandbox_option_end = .; + +	__bss_start = .; +} + +INSERT BEFORE .data; diff --git a/roms/u-boot/arch/sandbox/dts/.gitignore b/roms/u-boot/arch/sandbox/dts/.gitignore new file mode 100644 index 00000000..b60ed208 --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/.gitignore @@ -0,0 +1 @@ +*.dtb diff --git a/roms/u-boot/arch/sandbox/dts/Makefile b/roms/u-boot/arch/sandbox/dts/Makefile new file mode 100644 index 00000000..a4c980b2 --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/Makefile @@ -0,0 +1,11 @@ +dtb-$(CONFIG_SANDBOX) += sandbox.dtb + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) +	@: + +clean-files := *.dtb diff --git a/roms/u-boot/arch/sandbox/dts/sandbox.dts b/roms/u-boot/arch/sandbox/dts/sandbox.dts new file mode 100644 index 00000000..62d80378 --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/sandbox.dts @@ -0,0 +1,116 @@ +/dts-v1/; + +/ { +	triangle { +		compatible = "demo-shape"; +		colour = "cyan"; +		sides = <3>; +		character = <83>; +	}; +	square { +		compatible = "demo-shape"; +		colour = "blue"; +		sides = <4>; +	}; +	hexagon { +		compatible = "demo-simple"; +		colour = "white"; +		sides = <6>; +	}; + +	host@0 { +		#address-cells = <1>; +		#size-cells = <0>; +		compatible = "sandbox,host-emulation"; +		cros-ec@0 { +			reg = <0>; +			compatible = "google,cros-ec"; + +			/* +			 * This describes the flash memory within the EC. Note +			 * that the STM32L flash erases to 0, not 0xff. +			 */ +			#address-cells = <1>; +			#size-cells = <1>; +			flash@8000000 { +				reg = <0x08000000 0x20000>; +				erase-value = <0>; +				#address-cells = <1>; +				#size-cells = <1>; + +				/* Information for sandbox */ +				ro { +					reg = <0 0xf000>; +				}; +				wp-ro { +					reg = <0xf000 0x1000>; +				}; +				rw { +					reg = <0x10000 0x10000>; +				}; +			}; +		}; +	}; + +	lcd { +		compatible = "sandbox,lcd-sdl"; +		xres = <800>; +		yres = <600>; +	}; + +	cros-ec-keyb { +		compatible = "google,cros-ec-keyb"; +		google,key-rows = <8>; +		google,key-columns = <13>; +		google,repeat-delay-ms = <240>; +		google,repeat-rate-ms = <30>; +		google,ghost-filter; +		/* +		 * Keymap entries take the form of 0xRRCCKKKK where +		 * RR=Row CC=Column KKKK=Key Code +		 * The values below are for a US keyboard layout and +		 * are taken from the Linux driver. Note that the +		 * 102ND key is not used for US keyboards. +		 */ +		linux,keymap = < +			/* CAPSLCK F1         B          F10     */ +			0x0001003a 0x0002003b 0x00030030 0x00040044 +			/* N       =          R_ALT      ESC     */ +			0x00060031 0x0008000d 0x000a0064 0x01010001 +			/* F4      G          F7         H       */ +			0x0102003e 0x01030022 0x01040041 0x01060023 +			/* '       F9         BKSPACE    L_CTRL  */ +			0x01080028 0x01090043 0x010b000e 0x0200001d +			/* TAB     F3         T          F6      */ +			0x0201000f 0x0202003d 0x02030014 0x02040040 +			/* ]       Y          102ND      [       */ +			0x0205001b 0x02060015 0x02070056 0x0208001a +			/* F8      GRAVE      F2         5       */ +			0x02090042 0x03010029 0x0302003c 0x03030006 +			/* F5      6          -          \       */ +			0x0304003f 0x03060007 0x0308000c 0x030b002b +			/* R_CTRL  A          D          F       */ +			0x04000061 0x0401001e 0x04020020 0x04030021 +			/* S       K          J          ;       */ +			0x0404001f 0x04050025 0x04060024 0x04080027 +			/* L       ENTER      Z          C       */ +			0x04090026 0x040b001c 0x0501002c 0x0502002e +			/* V       X          ,          M       */ +			0x0503002f 0x0504002d 0x05050033 0x05060032 +			/* L_SHIFT /          .          SPACE   */ +			0x0507002a 0x05080035 0x05090034 0x050B0039 +			/* 1       3          4          2       */ +			0x06010002 0x06020004 0x06030005 0x06040003 +			/* 8       7          0          9       */ +			0x06050009 0x06060008 0x0608000b 0x0609000a +			/* L_ALT   DOWN       RIGHT      Q       */ +			0x060a0038 0x060b006c 0x060c006a 0x07010010 +			/* E       R          W          I       */ +			0x07020012 0x07030013 0x07040011 0x07050017 +			/* U       R_SHIFT    P          O       */ +			0x07060016 0x07070036 0x07080019 0x07090018 +			/* UP      LEFT    */ +			0x070b0067 0x070c0069>; +	}; + +}; diff --git a/roms/u-boot/arch/sandbox/include/asm/arch-sandbox/sound.h b/roms/u-boot/arch/sandbox/include/asm/arch-sandbox/sound.h new file mode 100644 index 00000000..a32e8c80 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/arch-sandbox/sound.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2013 Google, Inc + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __SANDBOX_SOUND_H +#define __SANDBOX_SOUND_H + +int sound_play(unsigned int msec, unsigned int frequency); + +int sound_init(const void *blob); + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/bitops.h b/roms/u-boot/arch/sandbox/include/asm/bitops.h new file mode 100644 index 00000000..74219c56 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/bitops.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * Copyright 1995, Russell King. + * Various bits and pieces copyrights include: + *  Linus Torvalds (test_bit). + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + * + * Please note that the code in this file should never be included + * from user space.  Many of these are not implemented in assembler + * since they would be too costly.  Also, they require priviledged + * instructions (which are not available from user mode) to ensure + * that they are atomic. + */ + +#ifndef __ASM_SANDBOX_BITOPS_H +#define __ASM_SANDBOX_BITOPS_H + +#include <asm/system.h> + +#ifdef __KERNEL__ + +#define smp_mb__before_clear_bit()	do { } while (0) +#define smp_mb__after_clear_bit()	do { } while (0) + +/* + * Function prototypes to keep gcc -Wall happy. + */ +extern void set_bit(int nr, void *addr); + +extern void clear_bit(int nr, void *addr); + +extern void change_bit(int nr, void *addr); + +static inline void __change_bit(int nr, void *addr) +{ +	unsigned long mask = BIT_MASK(nr); +	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + +	*p ^= mask; +} + +static inline int __test_and_set_bit(int nr, void *addr) +{ +	unsigned long mask = BIT_MASK(nr); +	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); +	unsigned long old = *p; + +	*p = old | mask; +	return (old & mask) != 0; +} + +static inline int test_and_set_bit(int nr, void *addr) +{ +	unsigned long flags; +	int out; + +	local_irq_save(flags); +	out = __test_and_set_bit(nr, addr); +	local_irq_restore(flags); + +	return out; +} + +static inline int __test_and_clear_bit(int nr, void *addr) +{ +	unsigned long mask = BIT_MASK(nr); +	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); +	unsigned long old = *p; + +	*p = old & ~mask; +	return (old & mask) != 0; +} + +static inline int test_and_clear_bit(int nr, void *addr) +{ +	unsigned long flags; +	int out; + +	local_irq_save(flags); +	out = __test_and_clear_bit(nr, addr); +	local_irq_restore(flags); + +	return out; +} + +extern int test_and_change_bit(int nr, void *addr); + +static inline int __test_and_change_bit(int nr, void *addr) +{ +	unsigned long mask = BIT_MASK(nr); +	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); +	unsigned long old = *p; + +	*p = old ^ mask; +	return (old & mask) != 0; +} + +extern int find_first_zero_bit(void *addr, unsigned size); +extern int find_next_zero_bit(void *addr, int size, int offset); + +/* + * This routine doesn't need to be atomic. + */ +static inline int test_bit(int nr, const void *addr) +{ +	return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7)); +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +static inline unsigned long ffz(unsigned long word) +{ +	int k; + +	word = ~word; +	k = 31; +	if (word & 0x0000ffff) { +		k -= 16; word <<= 16; +	} +	if (word & 0x00ff0000) { +		k -= 8;  word <<= 8; +	} +	if (word & 0x0f000000) { +		k -= 4;  word <<= 4; +	} +	if (word & 0x30000000) { +		k -= 2;  word <<= 2; +	} +	if (word & 0x40000000) +		k -= 1; +	return k; +} + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#define ext2_set_bit			test_and_set_bit +#define ext2_clear_bit			test_and_clear_bit +#define ext2_test_bit			test_bit +#define ext2_find_first_zero_bit	find_first_zero_bit +#define ext2_find_next_zero_bit		find_next_zero_bit + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr, addr)	test_and_set_bit(nr, addr) +#define minix_set_bit(nr, addr)			set_bit(nr, addr) +#define minix_test_and_clear_bit(nr, addr)	test_and_clear_bit(nr, addr) +#define minix_test_bit(nr, addr)		test_bit(nr, addr) +#define minix_find_first_zero_bit(addr, size)	find_first_zero_bit(addr, size) + +#endif /* __KERNEL__ */ + +#endif /* _ARM_BITOPS_H */ diff --git a/roms/u-boot/arch/sandbox/include/asm/byteorder.h b/roms/u-boot/arch/sandbox/include/asm/byteorder.h new file mode 100644 index 00000000..ba3c1643 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/byteorder.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __ASM_SANDBOX_BYTEORDER_H +#define __ASM_SANDBOX_BYTEORDER_H + + +#include <asm/types.h> + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +#  define __BYTEORDER_HAS_U64__ +#  define __SWAB_64_THRU_32__ +#endif + +#ifdef CONFIG_SANDBOX_BIG_ENDIAN +#include <linux/byteorder/big_endian.h> +#else +#include <linux/byteorder/little_endian.h> +#endif + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/cache.h b/roms/u-boot/arch/sandbox/include/asm/cache.h new file mode 100644 index 00000000..d28c385e --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/cache.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __SANDBOX_CACHE_H__ +#define __SANDBOX_CACHE_H__ + +/* + * For native compilation of the sandbox we should still align + * the contents of stack buffers to something reasonable.  The + * GCC macro __BIGGEST_ALIGNMENT__ is defined to be the maximum + * required alignment for any basic type.  This seems reasonable. + */ +#define ARCH_DMA_MINALIGN	__BIGGEST_ALIGNMENT__ + +#endif /* __SANDBOX_CACHE_H__ */ diff --git a/roms/u-boot/arch/sandbox/include/asm/config.h b/roms/u-boot/arch/sandbox/include/asm/config.h new file mode 100644 index 00000000..6c1bff99 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/config.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef _ASM_CONFIG_H_ +#define _ASM_CONFIG_H_ + +#define CONFIG_SYS_GENERIC_GLOBAL_DATA +#define CONFIG_SANDBOX_ARCH + +/* Used by drivers/spi/sandbox_spi.c and arch/sandbox/include/asm/state.h */ +#ifndef CONFIG_SANDBOX_SPI_MAX_BUS +#define CONFIG_SANDBOX_SPI_MAX_BUS 1 +#endif +#ifndef CONFIG_SANDBOX_SPI_MAX_CS +#define CONFIG_SANDBOX_SPI_MAX_CS 10 +#endif + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/errno.h b/roms/u-boot/arch/sandbox/include/asm/errno.h new file mode 100644 index 00000000..4c82b503 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/roms/u-boot/arch/sandbox/include/asm/getopt.h b/roms/u-boot/arch/sandbox/include/asm/getopt.h new file mode 100644 index 00000000..3048c2cc --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/getopt.h @@ -0,0 +1,72 @@ +/* + * Code for setting up command line flags like `./u-boot --help` + * + * Copyright (c) 2011 The Chromium OS Authors. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __SANDBOX_GETOPT_H +#define __SANDBOX_GETOPT_H + +struct sandbox_state; + +/* + * Internal structure for storing details about the flag. + * Most people should not have to dig around in this as + * it only gets parsed by the core sandbox code.  End + * consumer code should focus on the macros below and + * the callback function. + */ +struct sandbox_cmdline_option { +	/* The long flag name: "help" for "--help" */ +	const char *flag; +	/* The (optional) short flag name: "h" for "-h" */ +	int flag_short; +	/* The help string shown to the user when processing --help */ +	const char *help; +	/* Whether this flag takes an argument */ +	int has_arg; +	/* Callback into the end consumer code with the option */ +	int (*callback)(struct sandbox_state *state, const char *opt); +}; + +/* + * Internal macro to expand the lower macros into the necessary + * magic junk that makes this all work. + */ +#define _SANDBOX_CMDLINE_OPT(f, s, ha, h) \ +	static struct sandbox_cmdline_option sandbox_cmdline_option_##f = { \ +		.flag = #f, \ +		.flag_short = s, \ +		.help = h, \ +		.has_arg = ha, \ +		.callback = sandbox_cmdline_cb_##f, \ +	}; \ +	/* Ppointer to the struct in a special section for the linker script */ \ +	static __attribute__((section(".u_boot_sandbox_getopt"), used)) \ +		struct sandbox_cmdline_option \ +			*sandbox_cmdline_option_##f##_ptr = \ +			&sandbox_cmdline_option_##f + +/** + * Macros for end code to declare new command line flags. + * + * @param f   The long flag name e.g. help + * @param ha  Does the flag have an argument e.g. 0/1 + * @param h   The help string displayed when showing --help + * + * This invocation: + *   SANDBOX_CMDLINE_OPT(foo, 0, "The foo arg"); + * Will create a new flag named "--foo" (no short option) that takes + * no argument.  If the user specifies "--foo", then the callback func + * sandbox_cmdline_cb_foo() will automatically be called. + */ +#define SANDBOX_CMDLINE_OPT(f, ha, h) _SANDBOX_CMDLINE_OPT(f, 0, ha, h) +/* + * Same as above, but @s is used to specify a short flag e.g. + *   SANDBOX_CMDLINE_OPT(foo, 'f', 0, "The foo arg"); + */ +#define SANDBOX_CMDLINE_OPT_SHORT(f, s, ha, h) _SANDBOX_CMDLINE_OPT(f, s, ha, h) + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/global_data.h b/roms/u-boot/arch/sandbox/include/asm/global_data.h new file mode 100644 index 00000000..b2e9b488 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/global_data.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * (C) Copyright 2002-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef	__ASM_GBL_DATA_H +#define __ASM_GBL_DATA_H + +/* Architecture-specific global data */ +struct arch_global_data { +	uint8_t		*ram_buf;	/* emulated RAM buffer */ +}; + +#include <asm-generic/global_data.h> + +#define DECLARE_GLOBAL_DATA_PTR     extern gd_t *gd + +#endif /* __ASM_GBL_DATA_H */ diff --git a/roms/u-boot/arch/sandbox/include/asm/gpio.h b/roms/u-boot/arch/sandbox/include/asm/gpio.h new file mode 100644 index 00000000..95b59da6 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/gpio.h @@ -0,0 +1,61 @@ +/* + * This is the interface to the sandbox GPIO driver for test code which + * wants to change the GPIO values reported to U-Boot. + * + * Copyright (c) 2011 The Chromium OS Authors. + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __ASM_SANDBOX_GPIO_H +#define __ASM_SANDBOX_GPIO_H + +/* + * We use the generic interface, and add a back-channel. + * + * The back-channel functions are declared in this file. They should not be used + * except in test code. + * + * Test code can, for example, call sandbox_gpio_set_value() to set the value of + * a simulated GPIO. From then on, normal code in U-Boot will see this new + * value when it calls gpio_get_value(). + * + * NOTE: DO NOT use the functions in this file except in test code! + */ +#include <asm-generic/gpio.h> + +/** + * Return the simulated value of a GPIO (used only in sandbox test code) + * + * @param gp	GPIO number + * @return -1 on error, 0 if GPIO is low, >0 if high + */ +int sandbox_gpio_get_value(struct device *dev, unsigned int offset); + +/** + * Set the simulated value of a GPIO (used only in sandbox test code) + * + * @param gp	GPIO number + * @param value	value to set (0 for low, non-zero for high) + * @return -1 on error, 0 if ok + */ +int sandbox_gpio_set_value(struct device *dev, unsigned int offset, int value); + +/** + * Return the simulated direction of a GPIO (used only in sandbox test code) + * + * @param gp	GPIO number + * @return -1 on error, 0 if GPIO is input, >0 if output + */ +int sandbox_gpio_get_direction(struct device *dev, unsigned int offset); + +/** + * Set the simulated direction of a GPIO (used only in sandbox test code) + * + * @param gp	GPIO number + * @param output 0 to set as input, 1 to set as output + * @return -1 on error, 0 if ok + */ +int sandbox_gpio_set_direction(struct device *dev, unsigned int offset, +			       int output); + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/io.h b/roms/u-boot/arch/sandbox/include/asm/io.h new file mode 100644 index 00000000..79560411 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/io.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __SANDBOX_ASM_IO_H +#define __SANDBOX_ASM_IO_H + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + */ +#define MAP_NOCACHE	(0) +#define MAP_WRCOMBINE	(0) +#define MAP_WRBACK	(0) +#define MAP_WRTHROUGH	(0) + +void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags); + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ + +} + +/* For sandbox, we want addresses to point into our RAM buffer */ +static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) +{ +	return map_physmem(paddr, len, MAP_WRBACK); +} + +static inline void unmap_sysmem(const void *vaddr) +{ +} + +/* Map from a pointer to our RAM buffer */ +phys_addr_t map_to_sysmem(const void *ptr); + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/posix_types.h b/roms/u-boot/arch/sandbox/include/asm/posix_types.h new file mode 100644 index 00000000..ec18ed7e --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/posix_types.h @@ -0,0 +1,57 @@ +/* + *  linux/include/asm-arm/posix_types.h + * + *  Copyright (C) 1996-1998 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + *  Changelog: + *   27-06-1996	RMK	Created + */ +#ifndef __ARCH_ARM_POSIX_TYPES_H +#define __ARCH_ARM_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc.  Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short		__kernel_dev_t; +typedef unsigned long		__kernel_ino_t; +typedef unsigned short		__kernel_mode_t; +typedef unsigned short		__kernel_nlink_t; +typedef long			__kernel_off_t; +typedef int			__kernel_pid_t; +typedef unsigned short		__kernel_ipc_pid_t; +typedef unsigned short		__kernel_uid_t; +typedef unsigned short		__kernel_gid_t; +#if CONFIG_SANDBOX_BITS_PER_LONG == 32 +typedef unsigned int		__kernel_size_t; +typedef int			__kernel_ssize_t; +typedef int			__kernel_ptrdiff_t; +#else +typedef unsigned long		__kernel_size_t; +typedef long			__kernel_ssize_t; +typedef long			__kernel_ptrdiff_t; +#endif +typedef long			__kernel_time_t; +typedef long			__kernel_suseconds_t; +typedef long			__kernel_clock_t; +typedef int			__kernel_daddr_t; +typedef char			*__kernel_caddr_t; +typedef unsigned short		__kernel_uid16_t; +typedef unsigned short		__kernel_gid16_t; +typedef unsigned int		__kernel_uid32_t; +typedef unsigned int		__kernel_gid32_t; + +typedef unsigned short		__kernel_old_uid_t; +typedef unsigned short		__kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long		__kernel_loff_t; +#endif + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/ptrace.h b/roms/u-boot/arch/sandbox/include/asm/ptrace.h new file mode 100644 index 00000000..e9f552f4 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/ptrace.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __ASM_SANDBOX_PTRACE_H +#define __ASM_SANDBOX_PTRACE_H + +#ifndef __ASSEMBLY__ +/* This is not used in the sandbox architecture, but required by U-Boot */ +struct pt_regs { +}; + +#ifdef __KERNEL__ +extern void show_regs(struct pt_regs *); + +#endif + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/sdl.h b/roms/u-boot/arch/sandbox/include/asm/sdl.h new file mode 100644 index 00000000..6edec1ac --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/sdl.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013 Google, Inc + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __SANDBOX_SDL_H +#define __SANDBOX_SDL_H + +#include <errno.h> + +#ifdef CONFIG_SANDBOX_SDL + +/** + * sandbox_sdl_init_display() - Set up SDL video ready for use + * + * @width:	Window width in pixels + * @height	Window height in pixels + * @log2_bpp:	Log to base 2 of the number of bits per pixel. So a 32bpp + *		display will pass 5, since 2*5 = 32 + * @return 0 if OK, -ENODEV if no device, -EIO if SDL failed to initialize + *		and -EPERM if the video failed to come up. + */ +int sandbox_sdl_init_display(int width, int height, int log2_bpp); + +/** + * sandbox_sdl_sync() - Sync current U-Boot LCD frame buffer to SDL + * + * This must be called periodically to update the screen for SDL so that the + * user can see it. + * + * @lcd_base: Base of frame buffer + * @return 0 if screen was updated, -ENODEV is there is no screen. + */ +int sandbox_sdl_sync(void *lcd_base); + +/** + * sandbox_sdl_scan_keys() - scan for pressed keys + * + * Works out which keys are pressed and returns a list + * + * @key:	Array to receive keycodes + * @max_keys:	Size of array + * @return number of keycodes found, 0 if none, -ENODEV if no keyboard + */ +int sandbox_sdl_scan_keys(int key[], int max_keys); + +/** + * sandbox_sdl_key_pressed() - check if a particular key is pressed + * + * @keycode:	Keycode to check (KEY_... - see include/linux/input.h + * @return 0 if pressed, -ENOENT if not pressed. -ENODEV if keybord not + * available, + */ +int sandbox_sdl_key_pressed(int keycode); + +/** + * sandbox_sdl_sound_start() - start playing a sound + * + * @frequency:	Frequency of sounds in Hertz + * @return 0 if OK, -ENODEV if no sound is available + */ +int sandbox_sdl_sound_start(uint frequency); + +/** + * sandbox_sdl_sound_stop() - stop playing a sound + * + * @return 0 if OK, -ENODEV if no sound is available + */ +int sandbox_sdl_sound_stop(void); + +/** + * sandbox_sdl_sound_init() - set up the sound system + * + * @return 0 if OK, -ENODEV if no sound is available + */ +int sandbox_sdl_sound_init(void); + +#else +static inline int sandbox_sdl_init_display(int width, int height, +					    int log2_bpp) +{ +	return -ENODEV; +} + +static inline int sandbox_sdl_sync(void *lcd_base) +{ +	return -ENODEV; +} + +static inline int sandbox_sdl_scan_keys(int key[], int max_keys) +{ +	return -ENODEV; +} + +static inline int sandbox_sdl_key_pressed(int keycode) +{ +	return -ENODEV; +} + +static inline int sandbox_sdl_sound_start(uint frequency) +{ +	return -ENODEV; +} + +static inline int sandbox_sdl_sound_stop(void) +{ +	return -ENODEV; +} + +static inline int sandbox_sdl_sound_init(void) +{ +	return -ENODEV; +} + +#endif + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/sections.h b/roms/u-boot/arch/sandbox/include/asm/sections.h new file mode 100644 index 00000000..fbc1bd11 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/sections.h @@ -0,0 +1,24 @@ +/* + * decls for symbols defined in the linker script + * + * Copyright (c) 2012 The Chromium OS Authors. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __SANDBOX_SECTIONS_H +#define __SANDBOX_SECTIONS_H + +#include <asm-generic/sections.h> + +struct sandbox_cmdline_option; + +extern struct sandbox_cmdline_option *__u_boot_sandbox_option_start[], +	*__u_boot_sandbox_option_end[]; + +static inline size_t __u_boot_sandbox_option_count(void) +{ +	return __u_boot_sandbox_option_end - __u_boot_sandbox_option_start; +} + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/spi.h b/roms/u-boot/arch/sandbox/include/asm/spi.h new file mode 100644 index 00000000..49b4a0f1 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/spi.h @@ -0,0 +1,58 @@ +/* + * Simulate a SPI port and clients (see README.sandbox for details) + * + * Copyright (c) 2011-2013 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __ASM_SPI_H__ +#define __ASM_SPI_H__ + +#include <linux/types.h> + +/* + * The interface between the SPI bus and the SPI client.  The bus will + * instantiate a client, and that then call into it via these entry + * points.  These should be enough for the client to emulate the SPI + * device just like the real hardware. + */ +struct sandbox_spi_emu_ops { +	/* The bus wants to instantiate a new client, so setup everything */ +	int (*setup)(void **priv, const char *spec); +	/* The bus is done with us, so break things down */ +	void (*free)(void *priv); +	/* The CS has been "activated" -- we won't worry about low/high */ +	void (*cs_activate)(void *priv); +	/* The CS has been "deactivated" -- we won't worry about low/high */ +	void (*cs_deactivate)(void *priv); +	/* The client is rx-ing bytes from the bus, so it should tx some */ +	int (*xfer)(void *priv, const u8 *rx, u8 *tx, uint bytes); +}; + +/* + * There are times when the data lines are allowed to tristate.  What + * is actually sensed on the line depends on the hardware.  It could + * always be 0xFF/0x00 (if there are pull ups/downs), or things could + * float and so we'd get garbage back.  This func encapsulates that + * scenario so we can worry about the details here. + */ +static inline void sandbox_spi_tristate(u8 *buf, uint len) +{ +	/* XXX: make this into a user config option ? */ +	memset(buf, 0xff, len); +} + +/* + * Extract the bus/cs from the spi spec and return the start of the spi + * client spec.  If the bus/cs are invalid for the current config, then + * it returns NULL. + * + * Example: arg="0:1:foo" will set bus to 0, cs to 1, and return "foo" + */ +const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus, +				   unsigned long *cs); + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/state.h b/roms/u-boot/arch/sandbox/include/asm/state.h new file mode 100644 index 00000000..d17a82e9 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/state.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __SANDBOX_STATE_H +#define __SANDBOX_STATE_H + +#include <config.h> +#include <stdbool.h> +#include <linux/stringify.h> + +/* How we exited U-Boot */ +enum exit_type_id { +	STATE_EXIT_NORMAL, +	STATE_EXIT_COLD_REBOOT, +	STATE_EXIT_POWER_OFF, +}; + +/** + * Selects the behavior of the serial terminal. + * + * If Ctrl-C is processed by U-Boot, then the only way to quit sandbox is with + * the 'reset' command, or equivalent. + * + * If the terminal is cooked, then Ctrl-C will terminate U-Boot, and the + * command line will not be quite such a faithful emulation. + * + * Options are: + * + *	raw-with-sigs		- Raw, but allow signals (Ctrl-C will quit) + *	raw			- Terminal is always raw + *	cooked			- Terminal is always cooked + */ +enum state_terminal_raw { +	STATE_TERM_RAW_WITH_SIGS,	/* Default */ +	STATE_TERM_RAW, +	STATE_TERM_COOKED, + +	STATE_TERM_COUNT, +}; + +struct sandbox_spi_info { +	const char *spec; +	const struct sandbox_spi_emu_ops *ops; +}; + +/* The complete state of the test system */ +struct sandbox_state { +	const char *cmd;		/* Command to execute */ +	bool interactive;		/* Enable cmdline after execute */ +	const char *fdt_fname;		/* Filename of FDT binary */ +	enum exit_type_id exit_type;	/* How we exited U-Boot */ +	const char *parse_err;		/* Error to report from parsing */ +	int argc;			/* Program arguments */ +	char **argv;			/* Command line arguments */ +	const char *jumped_fname;	/* Jumped from previous U_Boot */ +	uint8_t *ram_buf;		/* Emulated RAM buffer */ +	unsigned int ram_size;		/* Size of RAM buffer */ +	const char *ram_buf_fname;	/* Filename to use for RAM buffer */ +	bool ram_buf_rm;		/* Remove RAM buffer file after read */ +	bool write_ram_buf;		/* Write RAM buffer on exit */ +	const char *state_fname;	/* File containing sandbox state */ +	void *state_fdt;		/* Holds saved state for sandbox */ +	bool read_state;		/* Read sandbox state on startup */ +	bool write_state;		/* Write sandbox state on exit */ +	bool ignore_missing_state_on_read;	/* No error if state missing */ +	bool show_lcd;			/* Show LCD on start-up */ +	enum state_terminal_raw term_raw;	/* Terminal raw/cooked */ + +	/* Pointer to information for each SPI bus/cs */ +	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS] +					[CONFIG_SANDBOX_SPI_MAX_CS]; +}; + +/* Minimum space we guarantee in the state FDT when calling read/write*/ +#define SANDBOX_STATE_MIN_SPACE		0x1000 + +/** + * struct sandbox_state_io - methods to saved/restore sandbox state + * @name: Name of of the device tree node, also the name of the variable + *	holding this data so it should be an identifier (use underscore + *	instead of minus) + * @compat: Compatible string for the node containing this state + * + * @read: Function to read state from FDT + *	If data is available, then blob and node will provide access to it. If + *	not (blob == NULL and node == -1) this function should set up an empty + *	data set for start-of-day. + *	@param blob: Pointer to device tree blob, or NULL if no data to read + *	@param node: Node offset to read from + *	@return 0 if OK, -ve on error + * + * @write: Function to write state to FDT + *	The caller will ensure that there is a node ready for the state. The + *	node may already contain the old state, in which case it should be + *	overridden. There is guaranteed to be SANDBOX_STATE_MIN_SPACE bytes + *	of free space, so error checking is not required for fdt_setprop...() + *	calls which add up to less than this much space. + * + *	For adding larger properties, use state_setprop(). + * + * @param blob: Device tree blob holding state + * @param node: Node to write our state into + * + * Note that it is possible to save data as large blobs or as individual + * hierarchical properties. However, unless you intend to keep state files + * around for a long time and be able to run an old state file on a new + * sandbox, it might not be worth using individual properties for everything. + * This is certainly supported, it is just a matter of the effort you wish + * to put into the state read/write feature. + */ +struct sandbox_state_io { +	const char *name; +	const char *compat; +	int (*write)(void *blob, int node); +	int (*read)(const void *blob, int node); +}; + +/** + * SANDBOX_STATE_IO - Declare sandbox state to read/write + * + * Sandbox permits saving state from one run and restoring it in another. This + * allows the test system to retain state between runs and thus better + * emulate a real system. Examples of state that might be useful to save are + * the emulated GPIOs pin settings, flash memory contents and TPM private + * data. U-Boot memory contents is dealth with separately since it is large + * and it is not normally useful to save it (since a normal system does not + * preserve DRAM between runs). See the '-m' option for this. + * + * See struct sandbox_state_io above for member documentation. + */ +#define SANDBOX_STATE_IO(_name, _compat, _read, _write) \ +	ll_entry_declare(struct sandbox_state_io, _name, state_io) = { \ +		.name = __stringify(_name), \ +		.read = _read, \ +		.write = _write, \ +		.compat = _compat, \ +	} + +/** + * Record the exit type to be reported by the test program. + * + * @param exit_type	Exit type to record + */ +void state_record_exit(enum exit_type_id exit_type); + +/** + * Gets a pointer to the current state. + * + * @return pointer to state + */ +struct sandbox_state *state_get_current(void); + +/** + * Read the sandbox state from the supplied device tree file + * + * This calls all registered state handlers to read in the sandbox state + * from a previous test run. + * + * @param state		Sandbox state to update + * @param fname		Filename of device tree file to read from + * @return 0 if OK, -ve on error + */ +int sandbox_read_state(struct sandbox_state *state, const char *fname); + +/** + * Write the sandbox state to the supplied device tree file + * + * This calls all registered state handlers to write out the sandbox state + * so that it can be preserved for a future test run. + * + * If the file exists it is overwritten. + * + * @param state		Sandbox state to update + * @param fname		Filename of device tree file to write to + * @return 0 if OK, -ve on error + */ +int sandbox_write_state(struct sandbox_state *state, const char *fname); + +/** + * Add a property to a sandbox state node + * + * This is equivalent to fdt_setprop except that it automatically enlarges + * the device tree if necessary. That means it is safe to write any amount + * of data here. + * + * This function can only be called from within struct sandbox_state_io's + * ->write method, i.e. within state I/O drivers. + * + * @param node		Device tree node to write to + * @param prop_name	Property to write + * @param data		Data to write into property + * @param size		Size of data to write into property + */ +int state_setprop(int node, const char *prop_name, const void *data, int size); + +/** + * Initialize the test system state + */ +int state_init(void); + +/** + * Uninitialize the test system state, writing out state if configured to + * do so. + * + * @return 0 if OK, -ve on error + */ +int state_uninit(void); + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/string.h b/roms/u-boot/arch/sandbox/include/asm/string.h new file mode 100644 index 00000000..f247ff3b --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/string.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <linux/string.h> diff --git a/roms/u-boot/arch/sandbox/include/asm/system.h b/roms/u-boot/arch/sandbox/include/asm/system.h new file mode 100644 index 00000000..066acc53 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/system.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __ASM_SANDBOX_SYSTEM_H +#define __ASM_SANDBOX_SYSTEM_H + +/* Define this as nops for sandbox architecture */ +static inline void local_irq_save(unsigned flags __attribute__((unused))) +{ +} + +#define local_irq_enable() +#define local_irq_disable() +#define local_save_flags(x) +#define local_irq_restore(x) + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/types.h b/roms/u-boot/arch/sandbox/include/asm/types.h new file mode 100644 index 00000000..6d3eb1f3 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/types.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __ASM_SANDBOX_TYPES_H +#define __ASM_SANDBOX_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG	CONFIG_SANDBOX_BITS_PER_LONG + +typedef unsigned long dma_addr_t; +typedef u32 phys_addr_t; +typedef u32 phys_size_t; + +#endif /* __KERNEL__ */ + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/u-boot-sandbox.h b/roms/u-boot/arch/sandbox/include/asm/u-boot-sandbox.h new file mode 100644 index 00000000..d2f1b656 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/u-boot-sandbox.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef _U_BOOT_SANDBOX_H_ +#define _U_BOOT_SANDBOX_H_ + +/* board/.../... */ +int board_init(void); +int dram_init(void); + +/* start.c */ +int sandbox_early_getopt_check(void); +int sandbox_main_loop_init(void); + +int cleanup_before_linux(void); + +/* drivers/video/sandbox_sdl.c */ +int sandbox_lcd_sdl_early_init(void); + +#endif	/* _U_BOOT_SANDBOX_H_ */ diff --git a/roms/u-boot/arch/sandbox/include/asm/u-boot.h b/roms/u-boot/arch/sandbox/include/asm/u-boot.h new file mode 100644 index 00000000..8279894e --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/u-boot.h @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_	1 + +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h> + +/* For image.h:image_check_target_arch() */ +#define IH_ARCH_DEFAULT IH_ARCH_SANDBOX + +#endif	/* _U_BOOT_H_ */ diff --git a/roms/u-boot/arch/sandbox/include/asm/unaligned.h b/roms/u-boot/arch/sandbox/include/asm/unaligned.h new file mode 100644 index 00000000..e5298049 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/unaligned.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-generic/unaligned.h> diff --git a/roms/u-boot/arch/sandbox/lib/Makefile b/roms/u-boot/arch/sandbox/lib/Makefile new file mode 100644 index 00000000..6480ebfc --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/Makefile @@ -0,0 +1,11 @@ +# +# Copyright (c) 2011 The Chromium OS Authors. +# +# (C) Copyright 2002-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + + +obj-y	+= interrupts.o sandbox.o diff --git a/roms/u-boot/arch/sandbox/lib/interrupts.c b/roms/u-boot/arch/sandbox/lib/interrupts.c new file mode 100644 index 00000000..c6d8ae91 --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/interrupts.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +int interrupt_init(void) +{ +	return 0; +} + +void enable_interrupts(void) +{ +	return; +} +int disable_interrupts(void) +{ +	return 0; +} diff --git a/roms/u-boot/arch/sandbox/lib/sandbox.c b/roms/u-boot/arch/sandbox/lib/sandbox.c new file mode 100644 index 00000000..e4d4e021 --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/sandbox.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <cros_ec.h> +#include <dm.h> +#include <os.h> +#include <asm/u-boot-sandbox.h> + +/* + * Pointer to initial global data area + * + * Here we initialize it. + */ +gd_t *gd; + +/* Add a simple GPIO device */ +U_BOOT_DEVICE(gpio_sandbox) = { +	.name = "gpio_sandbox", +}; + +void flush_cache(unsigned long start, unsigned long size) +{ +} + +unsigned long timer_read_counter(void) +{ +	return os_get_nsec() / 1000; +} + +int dram_init(void) +{ +	gd->ram_size = CONFIG_SYS_SDRAM_SIZE; +	return 0; +} + +#ifdef CONFIG_BOARD_EARLY_INIT_F +int board_early_init_f(void) +{ +#ifdef CONFIG_VIDEO_SANDBOX_SDL +	int ret; + +	ret = sandbox_lcd_sdl_early_init(); +	if (ret) { +		puts("Could not init sandbox LCD emulation\n"); +		return ret; +	} +#endif + +	return 0; +} +#endif + +int arch_early_init_r(void) +{ +#ifdef CONFIG_CROS_EC +	if (cros_ec_board_init()) { +		printf("%s: Failed to init EC\n", __func__); +		return 0; +	} +#endif + +	return 0; +} + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ +	if (cros_ec_get_error()) { +		/* Force console on */ +		gd->flags &= ~GD_FLG_SILENT; + +		printf("cros-ec communications failure %d\n", +		       cros_ec_get_error()); +		puts("\nPlease reset with Power+Refresh\n\n"); +		panic("Cannot init cros-ec device"); +		return -1; +	} +	return 0; +} +#endif  | 
