summaryrefslogtreecommitdiff
path: root/arch/sandbox
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sandbox')
-rw-r--r--arch/sandbox/config.mk2
-rw-r--r--arch/sandbox/cpu/cpu.c1
-rw-r--r--arch/sandbox/cpu/eth-raw-os.c6
-rw-r--r--arch/sandbox/cpu/os.c48
-rw-r--r--arch/sandbox/cpu/sdl.c338
-rw-r--r--arch/sandbox/cpu/start.c69
-rw-r--r--arch/sandbox/cpu/state.c23
-rw-r--r--arch/sandbox/dts/sandbox.dtsi1
-rw-r--r--arch/sandbox/dts/test.dts3
-rw-r--r--arch/sandbox/include/asm/malloc.h26
-rw-r--r--arch/sandbox/include/asm/sdl.h9
-rw-r--r--arch/sandbox/include/asm/state.h1
-rw-r--r--arch/sandbox/include/asm/test.h7
13 files changed, 338 insertions, 196 deletions
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index a225c9cbfa..189e9c2b0c 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -5,7 +5,7 @@ PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
PLATFORM_CPPFLAGS += -fPIC
PLATFORM_LIBS += -lrt
-SDL_CONFIG ?= sdl-config
+SDL_CONFIG ?= sdl2-config
# Define this to avoid linking with SDL, which requires SDL libraries
# This can solve 'sdl-config: Command not found' errors
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index ff7430393f..56ee3f5826 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -10,6 +10,7 @@
#include <linux/libfdt.h>
#include <os.h>
#include <asm/io.h>
+#include <asm/malloc.h>
#include <asm/setjmp.h>
#include <asm/state.h>
#include <dm/root.h>
diff --git a/arch/sandbox/cpu/eth-raw-os.c b/arch/sandbox/cpu/eth-raw-os.c
index 8d05bc2eda..da01d1addf 100644
--- a/arch/sandbox/cpu/eth-raw-os.c
+++ b/arch/sandbox/cpu/eth-raw-os.c
@@ -74,7 +74,7 @@ static int _raw_packet_start(struct eth_sandbox_raw_priv *priv,
/* Prepare device struct */
priv->local_bind_sd = -1;
- priv->device = os_malloc(sizeof(struct sockaddr_ll));
+ priv->device = malloc(sizeof(struct sockaddr_ll));
if (priv->device == NULL)
return -ENOMEM;
device = priv->device;
@@ -147,7 +147,7 @@ static int _local_inet_start(struct eth_sandbox_raw_priv *priv)
/* Prepare device struct */
priv->local_bind_sd = -1;
priv->local_bind_udp_port = 0;
- priv->device = os_malloc(sizeof(struct sockaddr_in));
+ priv->device = malloc(sizeof(struct sockaddr_in));
if (priv->device == NULL)
return -ENOMEM;
device = priv->device;
@@ -282,7 +282,7 @@ int sandbox_eth_raw_os_recv(void *packet, int *length,
void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv)
{
- os_free(priv->device);
+ free(priv->device);
priv->device = NULL;
close(priv->sd);
priv->sd = -1;
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 79094fb7f3..f7c73e3a0b 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -137,7 +137,7 @@ int os_read_file(const char *fname, void **bufp, int *sizep)
printf("Cannot seek to start of file '%s'\n", fname);
goto err;
}
- *bufp = os_malloc(size);
+ *bufp = malloc(size);
if (!*bufp) {
printf("Not enough memory to read file '%s'\n", fname);
ret = -ENOMEM;
@@ -238,29 +238,6 @@ void os_free(void *ptr)
}
}
-void *os_realloc(void *ptr, size_t length)
-{
- int page_size = getpagesize();
- struct os_mem_hdr *hdr;
- void *buf = NULL;
-
- if (length) {
- buf = os_malloc(length);
- if (!buf)
- return buf;
- if (ptr) {
- hdr = ptr - page_size;
- if (length > hdr->length)
- length = hdr->length;
- memcpy(buf, ptr, length);
- }
- }
- if (ptr)
- os_free(ptr);
-
- return buf;
-}
-
void os_usleep(unsigned long usec)
{
usleep(usec);
@@ -306,8 +283,8 @@ int os_parse_args(struct sandbox_state *state, int argc, char *argv[])
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);
+ short_opts = malloc(sizeof(*short_opts) * num_options * 2 + 1);
+ long_opts = malloc(sizeof(*long_opts) * (num_options + 1));
if (!short_opts || !long_opts)
return 1;
@@ -337,6 +314,7 @@ int os_parse_args(struct sandbox_state *state, int argc, char *argv[])
/* we need to handle output ourselves since u-boot provides printf */
opterr = 0;
+ memset(&long_opts[num_options], '\0', sizeof(*long_opts));
/*
* walk all of the options the user gave us on the command line,
* figure out what u-boot option structure they belong to (via
@@ -385,7 +363,7 @@ void os_dirent_free(struct os_dirent_node *node)
while (node) {
next = node->next;
- os_free(node);
+ free(node);
node = next;
}
}
@@ -410,7 +388,7 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
/* Create a buffer upfront, with typically sufficient size */
dirlen = strlen(dirname) + 2;
len = dirlen + 256;
- fname = os_malloc(len);
+ fname = malloc(len);
if (!fname) {
ret = -ENOMEM;
goto done;
@@ -423,7 +401,7 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
ret = errno;
break;
}
- next = os_malloc(sizeof(*node) + strlen(entry->d_name) + 1);
+ next = malloc(sizeof(*node) + strlen(entry->d_name) + 1);
if (!next) {
os_dirent_free(head);
ret = -ENOMEM;
@@ -432,10 +410,10 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
if (dirlen + strlen(entry->d_name) > len) {
len = dirlen + strlen(entry->d_name);
old_fname = fname;
- fname = os_realloc(fname, len);
+ fname = realloc(fname, len);
if (!fname) {
- os_free(old_fname);
- os_free(next);
+ free(old_fname);
+ free(next);
os_dirent_free(head);
ret = -ENOMEM;
goto done;
@@ -469,7 +447,7 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
done:
closedir(dir);
- os_free(fname);
+ free(fname);
return ret;
}
@@ -586,7 +564,7 @@ static int add_args(char ***argvp, char *add_args[], int count)
for (argc = 0; (*argvp)[argc]; argc++)
;
- argv = os_malloc((argc + count + 1) * sizeof(char *));
+ argv = malloc((argc + count + 1) * sizeof(char *));
if (!argv) {
printf("Out of memory for %d argv\n", count);
return -ENOMEM;
@@ -669,7 +647,7 @@ static int os_jump_to_file(const char *fname)
os_exit(2);
err = execv(fname, argv);
- os_free(argv);
+ free(argv);
if (err) {
perror("Unable to run image");
printf("Image filename '%s'\n", fname);
diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index 080c7c8d74..6416cab96c 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -5,8 +5,9 @@
#include <errno.h>
#include <unistd.h>
+#include <stdbool.h>
#include <linux/input.h>
-#include <SDL.h>
+#include <SDL2/SDL.h>
#include <asm/state.h>
/**
@@ -24,19 +25,42 @@ struct buf_info {
uint8_t *data;
};
+/**
+ * struct sdl_info - Information about our use of the SDL library
+ *
+ * @width: Width of simulated LCD display
+ * @height: Height of simulated LCD display
+ * @vis_width: Visible width (may be larger to allow for scaling up)
+ * @vis_height: Visible height (may be larger to allow for scaling up)
+ * @depth: Depth of the display in bits per pixel (16 or 32)
+ * @pitch: Number of bytes per line of the display
+ * @sample_rate: Current sample rate for audio
+ * @audio_active: true if audio can be used
+ * @inited: true if this module is initialised
+ * @cur_buf: Current audio buffer being used by sandbox_sdl_fill_audio (0 or 1)
+ * @buf: The two available audio buffers. SDL can be reading from one while we
+ * are setting up the next
+ * @running: true if audio is running
+ * @stopping: true if audio will stop once it runs out of data
+ * @texture: SDL texture to use for U-Boot display contents
+ * @renderer: SDL renderer to use
+ */
static struct sdl_info {
- SDL_Surface *screen;
int width;
int height;
+ int vis_width;
+ int vis_height;
int depth;
int pitch;
- uint frequency;
uint sample_rate;
bool audio_active;
bool inited;
int cur_buf;
struct buf_info buf[2];
bool running;
+ bool stopping;
+ SDL_Texture *texture;
+ SDL_Renderer *renderer;
} sdl;
static void sandbox_sdl_poll_events(void)
@@ -62,7 +86,7 @@ static int sandbox_sdl_ensure_init(void)
{
if (!sdl.inited) {
if (SDL_Init(0) < 0) {
- printf("Unable to initialize SDL: %s\n",
+ printf("Unable to initialise SDL: %s\n",
SDL_GetError());
return -EIO;
}
@@ -74,7 +98,8 @@ static int sandbox_sdl_ensure_init(void)
return 0;
}
-int sandbox_sdl_init_display(int width, int height, int log2_bpp)
+int sandbox_sdl_init_display(int width, int height, int log2_bpp,
+ bool double_size)
{
struct sandbox_state *state = state_get_current();
int err;
@@ -85,16 +110,52 @@ int sandbox_sdl_init_display(int width, int height, int log2_bpp)
if (err)
return err;
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
- printf("Unable to initialize SDL LCD: %s\n", SDL_GetError());
+ printf("Unable to initialise SDL LCD: %s\n", SDL_GetError());
return -EPERM;
}
- SDL_WM_SetCaption("U-Boot", "U-Boot");
-
sdl.width = width;
sdl.height = height;
+ if (double_size) {
+ sdl.vis_width = sdl.width * 2;
+ sdl.vis_height = sdl.height * 2;
+ } else {
+ sdl.vis_width = sdl.width;
+ sdl.vis_height = sdl.height;
+ }
+
sdl.depth = 1 << log2_bpp;
sdl.pitch = sdl.width * sdl.depth / 8;
- sdl.screen = SDL_SetVideoMode(width, height, 0, 0);
+ SDL_Window *screen = SDL_CreateWindow("U-Boot", SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ sdl.vis_width, sdl.vis_height, 0);
+ if (!screen) {
+ printf("Unable to initialise SDL screen: %s\n",
+ SDL_GetError());
+ return -EIO;
+ }
+ if (log2_bpp != 4 && log2_bpp != 5) {
+ printf("U-Boot SDL does not support depth %d\n", log2_bpp);
+ return -EINVAL;
+ }
+ sdl.renderer = SDL_CreateRenderer(screen, -1,
+ SDL_RENDERER_ACCELERATED |
+ SDL_RENDERER_PRESENTVSYNC);
+ if (!sdl.renderer) {
+ printf("Unable to initialise SDL renderer: %s\n",
+ SDL_GetError());
+ return -EIO;
+ }
+
+ sdl.texture = SDL_CreateTexture(sdl.renderer, log2_bpp == 4 ?
+ SDL_PIXELFORMAT_RGB565 :
+ SDL_PIXELFORMAT_RGB888,
+ SDL_TEXTUREACCESS_STREAMING,
+ width, height);
+ if (!sdl.texture) {
+ printf("Unable to initialise SDL texture: %s\n",
+ SDL_GetError());
+ return -EBADF;
+ }
sandbox_sdl_poll_events();
return 0;
@@ -102,136 +163,137 @@ int sandbox_sdl_init_display(int width, int height, int log2_bpp)
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);
+ SDL_UpdateTexture(sdl.texture, NULL, lcd_base, sdl.pitch);
+ SDL_RenderCopy(sdl.renderer, sdl.texture, NULL, NULL);
+ SDL_RenderPresent(sdl.renderer);
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,
+static const unsigned short sdl_to_keycode[SDL_NUM_SCANCODES] = {
+ [SDL_SCANCODE_A] = KEY_A,
+ [SDL_SCANCODE_B] = KEY_B,
+ [SDL_SCANCODE_C] = KEY_C,
+ [SDL_SCANCODE_D] = KEY_D,
+ [SDL_SCANCODE_E] = KEY_E,
+ [SDL_SCANCODE_F] = KEY_F,
+ [SDL_SCANCODE_G] = KEY_G,
+ [SDL_SCANCODE_H] = KEY_H,
+ [SDL_SCANCODE_I] = KEY_I,
+ [SDL_SCANCODE_J] = KEY_J,
+ [SDL_SCANCODE_K] = KEY_K,
+ [SDL_SCANCODE_L] = KEY_L,
+ [SDL_SCANCODE_M] = KEY_M,
+ [SDL_SCANCODE_N] = KEY_N,
+ [SDL_SCANCODE_O] = KEY_O,
+ [SDL_SCANCODE_P] = KEY_P,
+ [SDL_SCANCODE_Q] = KEY_Q,
+ [SDL_SCANCODE_R] = KEY_R,
+ [SDL_SCANCODE_S] = KEY_S,
+ [SDL_SCANCODE_T] = KEY_T,
+ [SDL_SCANCODE_U] = KEY_U,
+ [SDL_SCANCODE_V] = KEY_V,
+ [SDL_SCANCODE_W] = KEY_W,
+ [SDL_SCANCODE_X] = KEY_X,
+ [SDL_SCANCODE_Y] = KEY_Y,
+ [SDL_SCANCODE_Z] = KEY_Z,
+
+ [SDL_SCANCODE_1] = KEY_1,
+ [SDL_SCANCODE_2] = KEY_2,
+ [SDL_SCANCODE_3] = KEY_3,
+ [SDL_SCANCODE_4] = KEY_4,
+ [SDL_SCANCODE_5] = KEY_5,
+ [SDL_SCANCODE_6] = KEY_6,
+ [SDL_SCANCODE_7] = KEY_7,
+ [SDL_SCANCODE_8] = KEY_8,
+ [SDL_SCANCODE_9] = KEY_9,
+ [SDL_SCANCODE_0] = KEY_0,
+
+ [SDL_SCANCODE_RETURN] = KEY_ENTER,
+ [SDL_SCANCODE_ESCAPE] = KEY_ESC,
+ [SDL_SCANCODE_BACKSPACE] = KEY_BACKSPACE,
+ [SDL_SCANCODE_TAB] = KEY_TAB,
+ [SDL_SCANCODE_SPACE] = KEY_SPACE,
+
+ [SDL_SCANCODE_MINUS] = KEY_MINUS,
+ [SDL_SCANCODE_EQUALS] = KEY_EQUAL,
+ [SDL_SCANCODE_BACKSLASH] = KEY_BACKSLASH,
+ [SDL_SCANCODE_SEMICOLON] = KEY_SEMICOLON,
+ [SDL_SCANCODE_APOSTROPHE] = KEY_APOSTROPHE,
+ [SDL_SCANCODE_GRAVE] = KEY_GRAVE,
+ [SDL_SCANCODE_COMMA] = KEY_COMMA,
+ [SDL_SCANCODE_PERIOD] = KEY_DOT,
+ [SDL_SCANCODE_SLASH] = KEY_SLASH,
+
+ [SDL_SCANCODE_CAPSLOCK] = KEY_CAPSLOCK,
+
+ [SDL_SCANCODE_F1] = KEY_F1,
+ [SDL_SCANCODE_F2] = KEY_F2,
+ [SDL_SCANCODE_F3] = KEY_F3,
+ [SDL_SCANCODE_F4] = KEY_F4,
+ [SDL_SCANCODE_F5] = KEY_F5,
+ [SDL_SCANCODE_F6] = KEY_F6,
+ [SDL_SCANCODE_F7] = KEY_F7,
+ [SDL_SCANCODE_F8] = KEY_F8,
+ [SDL_SCANCODE_F9] = KEY_F9,
+ [SDL_SCANCODE_F10] = KEY_F10,
+ [SDL_SCANCODE_F11] = KEY_F11,
+ [SDL_SCANCODE_F12] = KEY_F12,
+
+ [SDL_SCANCODE_PRINTSCREEN] = KEY_PRINT,
+ [SDL_SCANCODE_SCROLLLOCK] = KEY_SCROLLLOCK,
+ [SDL_SCANCODE_PAUSE] = KEY_PAUSE,
+ [SDL_SCANCODE_INSERT] = KEY_INSERT,
+ [SDL_SCANCODE_HOME] = KEY_HOME,
+ [SDL_SCANCODE_PAGEUP] = KEY_PAGEUP,
+ [SDL_SCANCODE_DELETE] = KEY_DELETE,
+ [SDL_SCANCODE_END] = KEY_END,
+ [SDL_SCANCODE_PAGEDOWN] = KEY_PAGEDOWN,
+ [SDL_SCANCODE_RIGHT] = KEY_RIGHT,
+ [SDL_SCANCODE_LEFT] = KEY_LEFT,
+ [SDL_SCANCODE_DOWN] = KEY_DOWN,
+ [SDL_SCANCODE_UP] = KEY_UP,
+
+ [SDL_SCANCODE_NUMLOCKCLEAR] = KEY_NUMLOCK,
+ [SDL_SCANCODE_KP_DIVIDE] = KEY_KPSLASH,
+ [SDL_SCANCODE_KP_MULTIPLY] = KEY_KPASTERISK,
+ [SDL_SCANCODE_KP_MINUS] = KEY_KPMINUS,
+ [SDL_SCANCODE_KP_PLUS] = KEY_KPPLUS,
+ [SDL_SCANCODE_KP_ENTER] = KEY_KPENTER,
+ [SDL_SCANCODE_KP_1] = KEY_KP1,
+ [SDL_SCANCODE_KP_2] = KEY_KP2,
+ [SDL_SCANCODE_KP_3] = KEY_KP3,
+ [SDL_SCANCODE_KP_4] = KEY_KP4,
+ [SDL_SCANCODE_KP_5] = KEY_KP5,
+ [SDL_SCANCODE_KP_6] = KEY_KP6,
+ [SDL_SCANCODE_KP_7] = KEY_KP7,
+ [SDL_SCANCODE_KP_8] = KEY_KP8,
+ [SDL_SCANCODE_KP_9] = KEY_KP9,
+ [SDL_SCANCODE_KP_0] = KEY_KP0,
+ [SDL_SCANCODE_KP_PERIOD] = KEY_KPDOT,
+
+ [SDL_SCANCODE_KP_EQUALS] = KEY_KPEQUAL,
+ [SDL_SCANCODE_KP_COMMA] = KEY_KPCOMMA,
+
+ [SDL_SCANCODE_SYSREQ] = KEY_SYSRQ,
};
int sandbox_sdl_scan_keys(int key[], int max_keys)
{
- Uint8 *keystate;
+ const Uint8 *keystate;
+ int num_keys;
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];
+ keystate = SDL_GetKeyboardState(&num_keys);
+ for (i = count = 0; i < num_keys; i++) {
+ if (count < max_keys && keystate[i]) {
+ int keycode = sdl_to_keycode[i];
+
+ if (keycode)
+ key[count++] = keycode;
+ }
}
return count;
@@ -256,6 +318,7 @@ void sandbox_sdl_fill_audio(void *udata, Uint8 *stream, int len)
{
struct buf_info *buf;
int avail;
+ bool have_data = false;
int i;
for (i = 0; i < 2; i++) {
@@ -267,6 +330,7 @@ void sandbox_sdl_fill_audio(void *udata, Uint8 *stream, int len)
}
if (avail > len)
avail = len;
+ have_data = true;
SDL_MixAudio(stream, buf->data + buf->pos, avail,
SDL_MIX_MAXVOLUME);
@@ -279,11 +343,12 @@ void sandbox_sdl_fill_audio(void *udata, Uint8 *stream, int len)
else
break;
}
+ sdl.stopping = !have_data;
}
int sandbox_sdl_sound_init(int rate, int channels)
{
- SDL_AudioSpec wanted;
+ SDL_AudioSpec wanted, have;
int i;
if (sandbox_sdl_ensure_init())
@@ -316,19 +381,23 @@ int sandbox_sdl_sound_init(int rate, int channels)
}
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
- printf("Unable to initialize SDL audio: %s\n", SDL_GetError());
+ printf("Unable to initialise SDL audio: %s\n", SDL_GetError());
goto err;
}
/* Open the audio device, forcing the desired format */
- if (SDL_OpenAudio(&wanted, NULL) < 0) {
+ if (SDL_OpenAudio(&wanted, &have) < 0) {
printf("Couldn't open audio: %s\n", SDL_GetError());
goto err;
}
+ if (have.format != wanted.format) {
+ printf("Couldn't select required audio format\n");
+ goto err;
+ }
sdl.audio_active = true;
sdl.sample_rate = wanted.freq;
sdl.cur_buf = 0;
- sdl.running = 0;
+ sdl.running = false;
return 0;
@@ -359,7 +428,8 @@ int sandbox_sdl_sound_play(const void *data, uint size)
buf->pos = 0;
if (!sdl.running) {
SDL_PauseAudio(0);
- sdl.running = 1;
+ sdl.running = true;
+ sdl.stopping = false;
}
return 0;
@@ -368,8 +438,12 @@ int sandbox_sdl_sound_play(const void *data, uint size)
int sandbox_sdl_sound_stop(void)
{
if (sdl.running) {
+ while (!sdl.stopping)
+ SDL_Delay(100);
+
SDL_PauseAudio(1);
sdl.running = 0;
+ sdl.stopping = false;
}
return 0;
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index fff9cbdd79..b6ff5c3d64 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -8,14 +8,46 @@
#include <errno.h>
#include <os.h>
#include <cli.h>
-#include <malloc.h>
+#include <sort.h>
#include <asm/getopt.h>
#include <asm/io.h>
+#include <asm/malloc.h>
#include <asm/sections.h>
#include <asm/state.h>
+#include <linux/ctype.h>
DECLARE_GLOBAL_DATA_PTR;
+/* Compare two options so that they can be sorted into alphabetical order */
+static int h_compare_opt(const void *p1, const void *p2)
+{
+ const struct sandbox_cmdline_option *opt1 = p1;
+ const struct sandbox_cmdline_option *opt2 = p2;
+ const char *str1, *str2;
+ char flag1[2], flag2[2];
+
+ opt1 = *(struct sandbox_cmdline_option **)p1;
+ opt2 = *(struct sandbox_cmdline_option **)p2;
+ flag1[1] = '\0';
+ flag2[1] = '\0';
+
+ *flag1 = opt1->flag_short < 0x100 ? opt1->flag_short : '\0';
+ *flag2 = opt2->flag_short < 0x100 ? opt2->flag_short : '\0';
+
+ str1 = *flag1 ? flag1 : opt1->flag;
+ str2 = *flag2 ? flag2 : opt2->flag;
+
+ /*
+ * Force lower-case flags to come before upper-case ones. We only
+ * support upper-case for short flags.
+ */
+ if (isalpha(*str1) && isalpha(*str2) &&
+ tolower(*str1) == tolower(*str2))
+ return isupper(*str1) - isupper(*str2);
+
+ return strcasecmp(str1, str2);
+}
+
int sandbox_early_getopt_check(void)
{
struct sandbox_state *state = state_get_current();
@@ -23,6 +55,8 @@ int sandbox_early_getopt_check(void)
size_t num_options = __u_boot_sandbox_option_count();
size_t i;
int max_arg_len, max_noarg_len;
+ struct sandbox_cmdline_option **sorted_opt;
+ int size;
/* parse_err will be a string of the faulting option */
if (!state->parse_err)
@@ -45,8 +79,18 @@ int sandbox_early_getopt_check(void)
max_arg_len = max((int)strlen(sb_opt[i]->flag), max_arg_len);
max_noarg_len = max_arg_len + 7;
+ /* Sort the options */
+ size = sizeof(*sorted_opt) * num_options;
+ sorted_opt = malloc(size);
+ if (!sorted_opt) {
+ printf("No memory to sort options\n");
+ os_exit(1);
+ }
+ memcpy(sorted_opt, sb_opt, size);
+ qsort(sorted_opt, num_options, sizeof(*sorted_opt), h_compare_opt);
+
for (i = 0; i < num_options; ++i) {
- struct sandbox_cmdline_option *opt = sb_opt[i];
+ struct sandbox_cmdline_option *opt = sorted_opt[i];
/* first output the short flag if it has one */
if (opt->flag_short >= 0x100)
@@ -137,7 +181,7 @@ static int sandbox_cmdline_cb_default_fdt(struct sandbox_state *state,
int len;
len = strlen(state->argv[0]) + strlen(fmt) + 1;
- fname = os_malloc(len);
+ fname = malloc(len);
if (!fname)
return -ENOMEM;
snprintf(fname, len, fmt, state->argv[0]);
@@ -157,7 +201,7 @@ static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
int len;
len = strlen(state->argv[0]) + strlen(fmt) + 1;
- fname = os_malloc(len);
+ fname = malloc(len);
if (!fname)
return -ENOMEM;
strcpy(fname, state->argv[0]);
@@ -264,6 +308,16 @@ static int sandbox_cmdline_cb_show_lcd(struct sandbox_state *state,
SANDBOX_CMDLINE_OPT_SHORT(show_lcd, 'l', 0,
"Show the sandbox LCD display");
+static int sandbox_cmdline_cb_double_lcd(struct sandbox_state *state,
+ const char *arg)
+{
+ state->double_lcd = true;
+
+ return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(double_lcd, 'K', 0,
+ "Double the LCD display size in each direction");
+
static const char *term_args[STATE_TERM_COUNT] = {
"raw-with-sigs",
"raw",
@@ -319,13 +373,6 @@ static int sandbox_cmdline_cb_show_of_platdata(struct sandbox_state *state,
}
SANDBOX_CMDLINE_OPT(show_of_platdata, 0, "Show of-platdata in SPL");
-int board_run_command(const char *cmdline)
-{
- printf("## Commands are disabled. Please enable CONFIG_CMDLINE.\n");
-
- return 1;
-}
-
static void setup_ram_buf(struct sandbox_state *state)
{
/* Zero the RAM buffer if we didn't read it, to keep valgrind happy */
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index cd46e000f5..a347cec528 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -7,6 +7,7 @@
#include <errno.h>
#include <fdtdec.h>
#include <os.h>
+#include <asm/malloc.h>
#include <asm/state.h>
/* Main state record for the sandbox */
@@ -16,28 +17,28 @@ static struct sandbox_state *state; /* Pointer to current state record */
static int state_ensure_space(int extra_size)
{
void *blob = state->state_fdt;
- int used, size, free;
+ int used, size, free_bytes;
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)
+ free_bytes = size - used;
+ if (free_bytes > extra_size)
return 0;
size = used + extra_size;
- buf = os_malloc(size);
+ buf = malloc(size);
if (!buf)
return -ENOMEM;
ret = fdt_open_into(blob, buf, size);
if (ret) {
- os_free(buf);
+ free(buf);
return -EIO;
}
- os_free(blob);
+ free(blob);
state->state_fdt = buf;
return 0;
}
@@ -53,7 +54,7 @@ static int state_read_file(struct sandbox_state *state, const char *fname)
printf("Cannot find sandbox state file '%s'\n", fname);
return -ENOENT;
}
- state->state_fdt = os_malloc(size);
+ state->state_fdt = malloc(size);
if (!state->state_fdt) {
puts("No memory to read sandbox state\n");
return -ENOMEM;
@@ -75,7 +76,7 @@ static int state_read_file(struct sandbox_state *state, const char *fname)
err_read:
os_close(fd);
err_open:
- os_free(state->state_fdt);
+ free(state->state_fdt);
state->state_fdt = NULL;
return ret;
@@ -242,7 +243,7 @@ int sandbox_write_state(struct sandbox_state *state, const char *fname)
/* Create a state FDT if we don't have one */
if (!state->state_fdt) {
size = 0x4000;
- state->state_fdt = os_malloc(size);
+ state->state_fdt = malloc(size);
if (!state->state_fdt) {
puts("No memory to create FDT\n");
return -ENOMEM;
@@ -300,7 +301,7 @@ int sandbox_write_state(struct sandbox_state *state, const char *fname)
err_write:
os_close(fd);
err_create:
- os_free(state->state_fdt);
+ free(state->state_fdt);
return ret;
}
@@ -418,7 +419,7 @@ int state_uninit(void)
os_unlink(state->jumped_fname);
if (state->state_fdt)
- os_free(state->state_fdt);
+ free(state->state_fdt);
memset(state, '\0', sizeof(*state));
return 0;
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 7bf144f532..7cd56c14f2 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -83,6 +83,7 @@
compatible = "sandbox,lcd-sdl";
xres = <1366>;
yres = <768>;
+ log2-depth = <5>;
};
leds {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index c228447431..4a277934a7 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -816,6 +816,9 @@
chosen {
#address-cells = <1>;
#size-cells = <1>;
+ setting = "sunrise ohoka";
+ other-node = "/some-bus/c-test@5";
+ int-values = <0x1937 72993>;
chosen-test {
compatible = "denx,u-boot-fdt-test";
reg = <9 1>;
diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h
new file mode 100644
index 0000000000..a1467b5ead
--- /dev/null
+++ b/arch/sandbox/include/asm/malloc.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Sandbox access to system malloc (i.e. not U-Boot's)
+ *
+ * Copyright 2020 Google LLC
+ */
+
+#ifndef __ASM_MALLOC_H
+
+void *malloc(size_t size);
+void free(void *ptr);
+void *calloc(size_t nmemb, size_t size);
+void *realloc(void *ptr, size_t size);
+void *reallocarray(void *ptr, size_t nmemb, size_t size);
+
+/*
+ * This header allows calling the system allocation routines. It makes no
+ * sense to also include U-Boot's malloc.h since that redfines malloc to
+ * have a 'dl' prefix. These two implementations cannot be mixed and matched
+ * in the same file.
+ */
+#ifdef __MALLOC_H__
+#error "This sandbox header file cannot be included with malloc.h"
+#endif
+
+#endif
diff --git a/arch/sandbox/include/asm/sdl.h b/arch/sandbox/include/asm/sdl.h
index c45dbddd70..47fc4889d2 100644
--- a/arch/sandbox/include/asm/sdl.h
+++ b/arch/sandbox/include/asm/sdl.h
@@ -17,10 +17,13 @@
* @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
+ * @double_size: true to double the visible size in each direction for high-DPI
+ * displays
* @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);
+int sandbox_sdl_init_display(int width, int height, int log2_bpp,
+ bool double_size);
/**
* sandbox_sdl_sync() - Sync current U-Boot LCD frame buffer to SDL
@@ -78,8 +81,8 @@ int sandbox_sdl_sound_stop(void);
int sandbox_sdl_sound_init(int rate, int channels);
#else
-static inline int sandbox_sdl_init_display(int width, int height,
- int log2_bpp)
+static inline int sandbox_sdl_init_display(int width, int height, int log2_bpp,
+ bool double_size)
{
return -ENODEV;
}
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index ad3e94beb9..705645d714 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -83,6 +83,7 @@ struct sandbox_state {
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 */
+ bool double_lcd; /* Double display size for high-DPI */
enum sysreset_t last_sysreset; /* Last system reset type */
bool sysreset_allowed[SYSRESET_COUNT]; /* Allowed system reset types */
enum state_terminal_raw term_raw; /* Terminal raw/cooked */
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index 7775794eaa..7f99d07c47 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -170,6 +170,13 @@ int sandbox_get_i2s_sum(struct udevice *dev);
int sandbox_get_setup_called(struct udevice *dev);
/**
+ * sandbox_get_sound_active() - Returns whether sound play is in progress
+ *
+ * @return true if active, false if not
+ */
+int sandbox_get_sound_active(struct udevice *dev);
+
+/**
* sandbox_get_sound_sum() - Read back the sum of the sound data so far
*
* This data is provided to the sandbox driver by the sound play() method.