From e101247212f3aba3ece22c66e46e3fca89c0c768 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 10 Jan 2012 15:54:05 -0800 Subject: sandbox: sort header files in os.c Tidy this up as the list is long and likely to get longer. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/cpu/os.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 6d55b5cbce..a1d324b51f 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -19,15 +19,15 @@ * MA 02111-1307 USA */ +#include #include #include #include -#include #include -#include -#include -#include +#include #include +#include +#include #include #include -- cgit v1.2.3 From 3bdf56b78668769c091a74b40059a2ff14c5b80c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 10 Jan 2012 15:54:06 -0800 Subject: sandbox: add required header to os.c We should include the sys/time.h header to avoid warnings. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/cpu/os.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index a1d324b51f..093e7dc7ad 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 4f345d5673bc68122bcc5018a97fda2d8275437d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 19 Jan 2012 22:57:29 -0500 Subject: sandbox: add ifdef protection to os.h Acked-by: Simon Glass Signed-off-by: Mike Frysinger --- include/os.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/os.h b/include/os.h index f3af4f0e0e..c17a8a52ab 100644 --- a/include/os.h +++ b/include/os.h @@ -25,6 +25,9 @@ * This provides access to useful OS routines from the sandbox architecture */ +#ifndef __OS_H__ +#define __OS_H__ + /** * Access to the OS read() system call * @@ -98,3 +101,5 @@ void os_usleep(unsigned long usec); * \return A monotonic increasing time scaled in nano seconds */ u64 os_get_nsec(void); + +#endif -- cgit v1.2.3 From e2dcefcb404df39fc38786f4b76e3b94d4f476e1 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 25 Oct 2011 13:02:58 +0200 Subject: sandbox: add lseek helper Follow up patches want to be able to seek fd's. Acked-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/cpu/os.c | 13 +++++++++++++ include/os.h | 15 +++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 093e7dc7ad..f6d0e8457d 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -45,6 +45,19 @@ 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 flags) { return open(pathname, flags); diff --git a/include/os.h b/include/os.h index c17a8a52ab..f74766d16c 100644 --- a/include/os.h +++ b/include/os.h @@ -48,6 +48,21 @@ ssize_t os_read(int fd, void *buf, size_t count); */ ssize_t os_write(int fd, const void *buf, size_t count); +/** + * Access to the OS lseek() system call + * + * \param fd File descriptor as returned by os_open() + * \param offset File offset (based on whence) + * \param whence Position offset is relative to (see below) + * \return new file offset + */ +off_t os_lseek(int fd, off_t offset, int whence); + +/* Defines for "whence" in os_lseek() */ +#define OS_SEEK_SET 0 +#define OS_SEEK_CUR 1 +#define OS_SEEK_END 2 + /** * Access to the OS open() system call * -- cgit v1.2.3 From f7b2af0a228645f972cc882534b68d32c739f5e9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 15 Feb 2012 15:51:11 -0800 Subject: sandbox: fdt: add support for CONFIG_OF_CONTROL This adds support for a controlling fdt, mirroring the ARM implementation. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/include/asm/global_data.h | 1 + arch/sandbox/lib/board.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h index 8d47191f92..01a706362e 100644 --- a/arch/sandbox/include/asm/global_data.h +++ b/arch/sandbox/include/asm/global_data.h @@ -45,6 +45,7 @@ typedef struct global_data { unsigned long fb_base; /* base address of frame buffer */ u8 *ram_buf; /* emulated RAM buffer */ phys_size_t ram_size; /* RAM size */ + const void *fdt_blob; /* Our device tree, NULL if none */ void **jt; /* jump table */ char env_buf[32]; /* buffer for getenv() before reloc. */ } gd_t; diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c index b7997e9a73..6d464d6ae8 100644 --- a/arch/sandbox/lib/board.c +++ b/arch/sandbox/lib/board.c @@ -156,6 +156,14 @@ void board_init_f(ulong bootflag) memset((void *)gd, 0, sizeof(gd_t)); +#if defined(CONFIG_OF_EMBED) + /* Get a pointer to the FDT */ + gd->fdt_blob = _binary_dt_dtb_start; +#elif defined(CONFIG_OF_SEPARATE) + /* FDT is at end of image */ + gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE); +#endif + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) hang(); -- cgit v1.2.3 From 7b06b66cd7f9f4d33cfd3e68046c094a43024cda Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 15 Feb 2012 15:51:12 -0800 Subject: sandbox: config: enable fdt and snprintf() options Enable fdt code and safe snprintf() options for sandbox. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- include/configs/sandbox.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 10565e69c3..6790216751 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -28,6 +28,12 @@ /* Number of bits in a C 'long' on this architecture */ #define CONFIG_SANDBOX_BITS_PER_LONG 64 +#define CONFIG_OF_CONTROL +#define CONFIG_OF_LIBFDT +#define CONFIG_LMB + +#define CONFIG_SYS_VSNPRINTF + /* * Size of malloc() pool, although we don't actually use this yet. */ -- cgit v1.2.3 From d9165153caea9f342410ed3ac87cb68768ebec78 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Feb 2012 23:56:58 -0500 Subject: sandbox: add flags for open() call This provides a way for callers to create files for writing. The flags are translated at runtime, for the ones we support. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/cpu/os.c | 24 ++++++++++++++++++++++-- include/os.h | 17 +++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index f6d0e8457d..cb469e0510 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -58,9 +58,29 @@ off_t os_lseek(int fd, off_t offset, int whence) return lseek(fd, offset, whence); } -int os_open(const char *pathname, int flags) +int os_open(const char *pathname, int os_flags) { - return open(pathname, 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) diff --git a/include/os.h b/include/os.h index f74766d16c..6b7ee474f0 100644 --- a/include/os.h +++ b/include/os.h @@ -1,4 +1,9 @@ /* + * Operating System Interface + * + * This provides access to useful OS routines for the sandbox architecture. + * They are kept in a separate file so we can include system headers. + * * Copyright (c) 2011 The Chromium OS Authors. * See file CREDITS for list of people who contributed to this * project. @@ -19,12 +24,6 @@ * MA 02111-1307 USA */ -/* - * Operating System Interface - * - * This provides access to useful OS routines from the sandbox architecture - */ - #ifndef __OS_H__ #define __OS_H__ @@ -72,6 +71,12 @@ off_t os_lseek(int fd, off_t offset, int whence); */ int os_open(const char *pathname, int flags); +#define OS_O_RDONLY 0 +#define OS_O_WRONLY 1 +#define OS_O_RDWR 2 +#define OS_O_MASK 3 /* Mask for read/write flags */ +#define OS_O_CREAT 0100 + /** * Access to the OS close() system call * -- cgit v1.2.3 From 8d30fcd9a15da1fbe803af6d584ef0c4997e47e0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 15 Feb 2012 15:51:13 -0800 Subject: sandbox: gpio: add basic driver for simulating GPIOs This provides a way of simulating GPIOs by setting values which are seen by the normal gpio_get/set_value() calls. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/include/asm/gpio.h | 81 ++++++++++++++++ drivers/gpio/Makefile | 1 + drivers/gpio/sandbox.c | 209 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+) create mode 100644 arch/sandbox/include/asm/gpio.h create mode 100644 drivers/gpio/sandbox.c diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h new file mode 100644 index 0000000000..0500c539b3 --- /dev/null +++ b/arch/sandbox/include/asm/gpio.h @@ -0,0 +1,81 @@ +/* + * 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. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#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 + +/** + * 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(unsigned gp); + +/** + * 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(unsigned gp, 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(unsigned gp); + +/** + * 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(unsigned gp, int output); + +/* Display information about each GPIO */ +void gpio_info(void); + +#define gpio_status() gpio_info() + +#endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4375a55267..fb3b09ae74 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_MXS_GPIO) += mxs_gpio.o COBJS-$(CONFIG_PCA953X) += pca953x.o COBJS-$(CONFIG_PCA9698) += pca9698.o COBJS-$(CONFIG_S5P) += s5p_gpio.o +COBJS-$(CONFIG_SANDBOX_GPIO) += sandbox.o COBJS-$(CONFIG_TEGRA2_GPIO) += tegra2_gpio.o COBJS-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o COBJS-$(CONFIG_ALTERA_PIO) += altera_pio.o diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c new file mode 100644 index 0000000000..19d2db0242 --- /dev/null +++ b/drivers/gpio/sandbox.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* Flags for each GPIO */ +#define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */ +#define GPIOF_HIGH (1 << 1) /* Currently set high */ +#define GPIOF_RESERVED (1 << 2) /* Is in use / requested */ + +struct gpio_state { + const char *label; /* label given by requester */ + u8 flags; /* flags (GPIOF_...) */ +}; + +/* + * State of GPIOs + * TODO: Put this into sandbox state + */ +static struct gpio_state state[CONFIG_SANDBOX_GPIO_COUNT]; + +/* Access routines for GPIO state */ +static u8 *get_gpio_flags(unsigned gp) +{ + /* assert()'s could be disabled, so make sure we handle that */ + assert(gp < ARRAY_SIZE(state)); + if (gp >= ARRAY_SIZE(state)) { + static u8 invalid_flags; + printf("sandbox_gpio: error: invalid gpio %u\n", gp); + return &invalid_flags; + } + + return &state[gp].flags; +} + +static int get_gpio_flag(unsigned gp, int flag) +{ + return (*get_gpio_flags(gp) & flag) != 0; +} + +static int set_gpio_flag(unsigned gp, int flag, int value) +{ + u8 *gpio = get_gpio_flags(gp); + + if (value) + *gpio |= flag; + else + *gpio &= ~flag; + + return 0; +} + +static int check_reserved(unsigned gpio, const char *func) +{ + if (!get_gpio_flag(gpio, GPIOF_RESERVED)) { + printf("sandbox_gpio: %s: error: gpio %u not reserved\n", + func, gpio); + return -1; + } + + return 0; +} + +/* + * Back-channel sandbox-internal-only access to GPIO state + */ + +int sandbox_gpio_get_value(unsigned gp) +{ + if (get_gpio_flag(gp, GPIOF_OUTPUT)) + debug("sandbox_gpio: get_value on output gpio %u\n", gp); + return get_gpio_flag(gp, GPIOF_HIGH); +} + +int sandbox_gpio_set_value(unsigned gp, int value) +{ + return set_gpio_flag(gp, GPIOF_HIGH, value); +} + +int sandbox_gpio_get_direction(unsigned gp) +{ + return get_gpio_flag(gp, GPIOF_OUTPUT); +} + +int sandbox_gpio_set_direction(unsigned gp, int output) +{ + return set_gpio_flag(gp, GPIOF_OUTPUT, output); +} + +/* + * These functions implement the public interface within U-Boot + */ + +/* set GPIO port 'gp' as an input */ +int gpio_direction_input(unsigned gp) +{ + debug("%s: gp:%u\n", __func__, gp); + + if (check_reserved(gp, __func__)) + return -1; + + return sandbox_gpio_set_direction(gp, 0); +} + +/* set GPIO port 'gp' as an output, with polarity 'value' */ +int gpio_direction_output(unsigned gp, int value) +{ + debug("%s: gp:%u, value = %d\n", __func__, gp, value); + + if (check_reserved(gp, __func__)) + return -1; + + return sandbox_gpio_set_direction(gp, 1) | + sandbox_gpio_set_value(gp, value); +} + +/* read GPIO IN value of port 'gp' */ +int gpio_get_value(unsigned gp) +{ + debug("%s: gp:%u\n", __func__, gp); + + if (check_reserved(gp, __func__)) + return -1; + + return sandbox_gpio_get_value(gp); +} + +/* write GPIO OUT value to port 'gp' */ +int gpio_set_value(unsigned gp, int value) +{ + debug("%s: gp:%u, value = %d\n", __func__, gp, value); + + if (check_reserved(gp, __func__)) + return -1; + + if (!sandbox_gpio_get_direction(gp)) { + printf("sandbox_gpio: error: set_value on input gpio %u\n", gp); + return -1; + } + + return sandbox_gpio_set_value(gp, value); +} + +int gpio_request(unsigned gp, const char *label) +{ + debug("%s: gp:%u, label:%s\n", __func__, gp, label); + + if (gp >= ARRAY_SIZE(state)) { + printf("sandbox_gpio: error: invalid gpio %u\n", gp); + return -1; + } + + if (get_gpio_flag(gp, GPIOF_RESERVED)) { + printf("sandbox_gpio: error: gpio %u already reserved\n", gp); + return -1; + } + + state[gp].label = label; + return set_gpio_flag(gp, GPIOF_RESERVED, 1); +} + +int gpio_free(unsigned gp) +{ + debug("%s: gp:%u\n", __func__, gp); + + if (check_reserved(gp, __func__)) + return -1; + + state[gp].label = NULL; + return set_gpio_flag(gp, GPIOF_RESERVED, 0); +} + +/* Display GPIO information */ +void gpio_info(void) +{ + unsigned gpio; + + puts("Sandbox GPIOs\n"); + + for (gpio = 0; gpio < ARRAY_SIZE(state); ++gpio) { + const char *label = state[gpio].label; + + printf("%4d: %s: %d [%c] %s\n", + gpio, + sandbox_gpio_get_direction(gpio) ? "out" : " in", + sandbox_gpio_get_value(gpio), + get_gpio_flag(gpio, GPIOF_RESERVED) ? 'x' : ' ', + label ? label : ""); + } +} -- cgit v1.2.3 From eef448e1efeb589a3f725977a339a83d86b91331 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 15 Feb 2012 15:51:14 -0800 Subject: sandbox: enable GPIO driver Enable the new GPIO driver for sandbox. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- include/configs/sandbox.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 6790216751..a58a34e58c 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -34,6 +34,10 @@ #define CONFIG_SYS_VSNPRINTF +#define CONFIG_CMD_GPIO +#define CONFIG_SANDBOX_GPIO +#define CONFIG_SANDBOX_GPIO_COUNT 20 + /* * Size of malloc() pool, although we don't actually use this yet. */ -- cgit v1.2.3 From 6994ccf869ec20c4a69b8eb2fc321a4eb4217d24 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 21 Feb 2012 00:21:17 -0500 Subject: sandbox: add get_{tbclk,ticks} Fixes building after recent readline updates with timeouts. Signed-off-by: Mike Frysinger --- board/sandbox/sandbox/sandbox.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/board/sandbox/sandbox/sandbox.c b/board/sandbox/sandbox/sandbox.c index f376c74357..98830139a5 100644 --- a/board/sandbox/sandbox/sandbox.c +++ b/board/sandbox/sandbox/sandbox.c @@ -34,6 +34,16 @@ void flush_cache(unsigned long start, unsigned long size) { } +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} + +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + ulong get_timer(ulong base) { return (os_get_nsec() / 1000000) - base; -- cgit v1.2.3 From 3ab7d95aa0b57c5976e1cbb1cd80ec1a24ffa78a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 26 Feb 2012 14:13:31 -0500 Subject: sandbox: u-boot.lds: tweak style We use tabs for indentation, not spaces. Acked-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/cpu/u-boot.lds | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/sandbox/cpu/u-boot.lds b/arch/sandbox/cpu/u-boot.lds index 2d2e50fdbf..0c56aa7793 100644 --- a/arch/sandbox/cpu/u-boot.lds +++ b/arch/sandbox/cpu/u-boot.lds @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The Chromium OS Authors. + * 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. * @@ -24,11 +24,11 @@ SECTIONS { - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - __bss_start = .; + __u_boot_cmd_start = .; + _u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + __bss_start = .; } INSERT BEFORE .data; -- cgit v1.2.3 From 20186a1cbff3fd87954627538ce712a162c22351 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 26 Feb 2012 16:00:26 -0500 Subject: sandbox: disable fortification Since we provide all our own library calls, the fortification from glibc just gets in our way (which some distros enable by default). Acked-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 2ec1bb772b..02ce4a4410 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -17,5 +17,5 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, # MA 02111-1307 USA -PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ +PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE PLATFORM_LIBS += -lrt -- cgit v1.2.3 From 6fb62078210b78ff5cc87829a62166feebb8e9dc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 15 Feb 2012 15:51:15 -0800 Subject: sandbox: add concept of sandbox state The state exists through the life of U-Boot. It can be adjusted by command line options and perhaps later through a config file. It is available to U-Boot through state_...() calls (within sandbox code). The primary purpose of this is to contain the "hardware" state. It should only be used by sandbox internal code. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/cpu/Makefile | 2 +- arch/sandbox/cpu/start.c | 9 ++++++- arch/sandbox/cpu/state.c | 51 +++++++++++++++++++++++++++++++++++ arch/sandbox/include/asm/state.h | 57 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 arch/sandbox/cpu/state.c create mode 100644 arch/sandbox/include/asm/state.h diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile index 2ae0f7155c..6fd09ff65b 100644 --- a/arch/sandbox/cpu/Makefile +++ b/arch/sandbox/cpu/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).o -COBJS := cpu.o start.o os.o +COBJS := cpu.o os.o start.o state.o SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index a429e296ec..2b66eeddbb 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (c) 2011-2012 The Chromium OS Authors. * See file CREDITS for list of people who contributed to this * project. * @@ -20,9 +20,16 @@ */ #include +#include int main(int argc, char *argv[]) { + int err; + + err = state_init(); + if (err) + return err; + /* * Do pre- and post-relocation init, then start up U-Boot. This will * never return. diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c new file mode 100644 index 0000000000..88ae2b0820 --- /dev/null +++ b/arch/sandbox/cpu/state.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* 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; +} + +struct sandbox_state *state_get_current(void) +{ + assert(state); + return state; +} + +int state_init(void) +{ + state = &main_state; + + /* + * Example of how to use GPIOs: + * + * sandbox_gpio_set_direction(170, 0); + * sandbox_gpio_set_value(170, 0); + */ + return 0; +} diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h new file mode 100644 index 0000000000..5b34e9448e --- /dev/null +++ b/arch/sandbox/include/asm/state.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __SANDBOX_STATE_H +#define __SANDBOX_STATE_H + +/* How we exited U-Boot */ +enum exit_type_id { + STATE_EXIT_NORMAL, + STATE_EXIT_COLD_REBOOT, + STATE_EXIT_POWER_OFF, +}; + +/* The complete state of the test system */ +struct sandbox_state { + const char *cmd; /* Command to execute */ + enum exit_type_id exit_type; /* How we exited U-Boot */ +}; + +/** + * 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); + +/** + * Initialize the test system state + */ +int state_init(void); + +#endif -- cgit v1.2.3 From ab4e07eb71ca1913e5291316565c9d073987de85 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 26 Feb 2012 17:38:50 -0500 Subject: sandbox: allow processing before main loop In order to pass command line arguments to sandbox we need to be able to act on them. So take control back at the end of board_init_r() from where we can call the main loop or do something else. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/cpu/start.c | 5 +++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ arch/sandbox/lib/board.c | 2 ++ 3 files changed, 10 insertions(+) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 2b66eeddbb..4a84486c1e 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -22,6 +22,11 @@ #include #include +int sandbox_main_loop_init(void) +{ + return 0; +} + int main(int argc, char *argv[]) { int err; diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index 236b4ee287..99e950b805 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -35,4 +35,7 @@ int board_init(void); int dram_init(void); +/* start.c */ +int sandbox_main_loop_init(void); + #endif /* _U_BOOT_SANDBOX_H_ */ diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c index 6d464d6ae8..25a8d02fd7 100644 --- a/arch/sandbox/lib/board.c +++ b/arch/sandbox/lib/board.c @@ -269,6 +269,8 @@ void board_init_r(gd_t *id, ulong dest_addr) post_run(NULL, POST_RAM | post_bootmode_get(0)); #endif + sandbox_main_loop_init(); + /* * For now, run the main loop. Later we might let this be done * in the main program. -- cgit v1.2.3 From 70db4212fcdb080444a23dccaf673b68a3ffc1fa Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 15 Feb 2012 15:51:16 -0800 Subject: sandbox: add getopt support This adds simple command-line parsing to sandbox. The idea is that it sets up the state with options provided, and this state can then be queried later, as needed. New flags are declared with the SB_CMDLINE_OPT_SHORT helper macro, pointers are automatically gathered up in a special section, and then the core code takes care of gathering them up and processing at runtime. This way there is no central place where we have to store a list of flags with ifdefs. Signed-off-by: Simon Glass Signed-off-by: Mike Frysinger --- arch/sandbox/cpu/os.c | 98 +++++++++++++++++++++++++++++++ arch/sandbox/cpu/start.c | 88 +++++++++++++++++++++++++++ arch/sandbox/cpu/u-boot.lds | 4 ++ arch/sandbox/include/asm/getopt.h | 71 ++++++++++++++++++++++ arch/sandbox/include/asm/sections.h | 22 +++++++ arch/sandbox/include/asm/state.h | 5 ++ arch/sandbox/include/asm/u-boot-sandbox.h | 1 + arch/sandbox/lib/board.c | 1 + include/os.h | 14 +++++ 9 files changed, 304 insertions(+) create mode 100644 arch/sandbox/include/asm/getopt.h create mode 100644 arch/sandbox/include/asm/sections.h diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index cb469e0510..36637af6ce 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,9 @@ #include #include +#include +#include +#include #include /* Operating System Interface */ @@ -155,3 +159,97 @@ u64 os_get_nsec(void) 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 sb_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= + * -abbbb optopt='a' optind= + * -aaaaa optopt='a' optind= + * --a optopt=0 optind= + * 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; +} diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 4a84486c1e..6c3e8eb379 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -20,21 +20,109 @@ */ #include +#include +#include #include +#include + +int sandbox_early_getopt_check(void) +{ + struct sandbox_state *state = state_get_current(); + struct sb_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 sb_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", max_noarg_len, opt->flag); + else + printf("--%-*s ", max_arg_len, opt->flag); + + /* finally the help text */ + printf(" %s\n", opt->help); + } + + os_exit(0); +} + +static int sb_cmdline_cb_help(struct sandbox_state *state, const char *arg) +{ + /* just flag to sandbox_early_getopt_check to show usage */ + return 1; +} +SB_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) { + /* TODO: redo this when cmd tidy-up series lands */ +#ifdef CONFIG_SYS_HUSH_PARSER + run_command(state->cmd, 0); +#else + parse_string_outer(state->cmd, FLAG_PARSE_SEMICOLON | + FLAG_EXIT_FROM_LOOP); +#endif + os_exit(state->exit_type); + } + return 0; } +static int sb_cmdline_cb_command(struct sandbox_state *state, const char *arg) +{ + state->cmd = arg; + return 0; +} +SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command"); + int main(int argc, char *argv[]) { + struct sandbox_state *state; int err; err = state_init(); if (err) return err; + state = state_get_current(); + if (os_parse_args(state, argc, argv)) + return 1; + /* * Do pre- and post-relocation init, then start up U-Boot. This will * never return. diff --git a/arch/sandbox/cpu/u-boot.lds b/arch/sandbox/cpu/u-boot.lds index 0c56aa7793..99601387cb 100644 --- a/arch/sandbox/cpu/u-boot.lds +++ b/arch/sandbox/cpu/u-boot.lds @@ -28,6 +28,10 @@ SECTIONS _u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; + __u_boot_sandbox_option_start = .; + _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) } + __u_boot_sandbox_option_end = .; + __bss_start = .; } diff --git a/arch/sandbox/include/asm/getopt.h b/arch/sandbox/include/asm/getopt.h new file mode 100644 index 0000000000..685883cd3f --- /dev/null +++ b/arch/sandbox/include/asm/getopt.h @@ -0,0 +1,71 @@ +/* + * 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 sb_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 _SB_CMDLINE_OPT(f, s, ha, h) \ + static struct sb_cmdline_option sb_cmdline_option_##f = { \ + .flag = #f, \ + .flag_short = s, \ + .help = h, \ + .has_arg = ha, \ + .callback = sb_cmdline_cb_##f, \ + }; \ + /* Ppointer to the struct in a special section for the linker script */ \ + static __attribute__((section(".u_boot_sandbox_getopt"), used)) \ + struct sb_cmdline_option *sb_cmdline_option_##f##_ptr = \ + &sb_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: + * SB_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 + * sb_cmdline_cb_foo() will automatically be called. + */ +#define SB_CMDLINE_OPT(f, ha, h) _SB_CMDLINE_OPT(f, 0, ha, h) +/* + * Same as above, but @s is used to specify a short flag e.g. + * SB_CMDLINE_OPT(foo, 'f', 0, "The foo arg"); + */ +#define SB_CMDLINE_OPT_SHORT(f, s, ha, h) _SB_CMDLINE_OPT(f, s, ha, h) + +#endif diff --git a/arch/sandbox/include/asm/sections.h b/arch/sandbox/include/asm/sections.h new file mode 100644 index 0000000000..eafce7d8ab --- /dev/null +++ b/arch/sandbox/include/asm/sections.h @@ -0,0 +1,22 @@ +/* + * 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 + +struct sb_cmdline_option; + +extern struct sb_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/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 5b34e9448e..2b62b46ea2 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -22,6 +22,8 @@ #ifndef __SANDBOX_STATE_H #define __SANDBOX_STATE_H +#include + /* How we exited U-Boot */ enum exit_type_id { STATE_EXIT_NORMAL, @@ -33,6 +35,9 @@ enum exit_type_id { struct sandbox_state { const char *cmd; /* Command to execute */ 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; }; /** diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index 99e950b805..50bf8c605d 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -36,6 +36,7 @@ int board_init(void); int dram_init(void); /* start.c */ +int sandbox_early_getopt_check(void); int sandbox_main_loop_init(void); #endif /* _U_BOOT_SANDBOX_H_ */ diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c index 25a8d02fd7..306d1ec332 100644 --- a/arch/sandbox/lib/board.c +++ b/arch/sandbox/lib/board.c @@ -134,6 +134,7 @@ init_fnc_t *init_sequence[] = { env_init, /* initialize environment */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ + sandbox_early_getopt_check, /* process command line flags (err/help) */ display_banner, /* say that we are here */ #if defined(CONFIG_DISPLAY_CPUINFO) print_cpuinfo, /* display cpu info (and speed) */ diff --git a/include/os.h b/include/os.h index 6b7ee474f0..45729c1e44 100644 --- a/include/os.h +++ b/include/os.h @@ -27,6 +27,8 @@ #ifndef __OS_H__ #define __OS_H__ +struct sandbox_state; + /** * Access to the OS read() system call * @@ -122,4 +124,16 @@ void os_usleep(unsigned long usec); */ u64 os_get_nsec(void); +/** + * Parse arguments and update sandbox state. + * + * @param state Sandbox state to update + * @param argc Argument count + * @param argv Argument vector + * @return 0 if ok, and program should continue; + * 1 if ok, but program should stop; + * -1 on error: program should terminate. + */ +int os_parse_args(struct sandbox_state *state, int argc, char *argv[]); + #endif -- cgit v1.2.3 From 9d72e67b79a454dcd6847bcd80c9929e0ec9054d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 26 Feb 2012 17:46:30 -0500 Subject: sandbox: mark os_exit as noreturn Signed-off-by: Mike Frysinger --- include/os.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/os.h b/include/os.h index 45729c1e44..699682a408 100644 --- a/include/os.h +++ b/include/os.h @@ -95,7 +95,7 @@ int os_close(int fd); * * @param exit_code exit code for U-Boot */ -void os_exit(int exit_code); +void os_exit(int exit_code) __attribute__((noreturn)); /** * Put tty into raw mode to mimic serial console better -- cgit v1.2.3