GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,49 @@
menu "Sandbox architecture"
depends on SANDBOX
config SYS_ARCH
default "sandbox"
config SYS_BOARD
default "sandbox"
config SYS_CPU
default "sandbox"
config SANDBOX64
bool "Use 64-bit addresses"
select PHYS_64BIT
select HOST_64BIT
config SANDBOX_SPL
bool "Enable SPL for sandbox"
select SUPPORT_SPL
config SYS_CONFIG_NAME
default "sandbox_spl" if SANDBOX_SPL
default "sandbox" if !SANDBOX_SPL
choice
prompt "Run sandbox on 32/64-bit host"
default HOST_64BIT
help
Sandbox can be built on 32-bit and 64-bit hosts.
The default is to build on a 64-bit host and run
on a 64-bit host. If you want to run sandbox on
a 32-bit host, change it here.
config HOST_32BIT
bool "32-bit host"
depends on !PHYS_64BIT
config HOST_64BIT
bool "64-bit host"
endchoice
config SANDBOX_BITS_PER_LONG
int
default 32 if HOST_32BIT
default 64 if HOST_64BIT
endmenu
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
head-y := arch/sandbox/cpu/start.o arch/sandbox/cpu/os.o
head-$(CONFIG_SANDBOX_SDL) += arch/sandbox/cpu/sdl.o
libs-y += arch/sandbox/cpu/
libs-y += arch/sandbox/lib/
@@ -0,0 +1,57 @@
# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2011 The Chromium OS Authors.
PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
PLATFORM_CPPFLAGS += -fPIC
PLATFORM_LIBS += -lrt
SDL_CONFIG ?= sdl-config
# 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
else
PLATFORM_LIBS += $(shell $(SDL_CONFIG) --libs)
PLATFORM_CPPFLAGS += $(shell $(SDL_CONFIG) --cflags)
endif
cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
-Wl,--start-group $(u-boot-main) -Wl,--end-group \
$(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map
cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \
$(patsubst $(obj)/%,%,$(u-boot-spl-init)) \
-Wl,--start-group $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
$(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \
$(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections)
CONFIG_ARCH_DEVICE_TREE := sandbox
ifeq ($(HOST_ARCH),$(HOST_ARCH_X86_64))
EFI_LDS := ${SRCDIR}/../../../arch/x86/lib/elf_x86_64_efi.lds
EFI_TARGET := --target=efi-app-x86_64
else ifeq ($(HOST_ARCH),$(HOST_ARCH_X86))
EFI_LDS := ${SRCDIR}/../../../arch/x86/lib/elf_ia32_efi.lds
EFI_TARGET := --target=efi-app-ia32
else ifeq ($(HOST_ARCH),$(HOST_ARCH_AARCH64))
EFI_LDS := ${SRCDIR}/../../../arch/arm/lib/elf_aarch64_efi.lds
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \
-j .u_boot_list -j .rela.dyn -j .got -j .got.plt \
-j .binman_sym_table -j .text_rest \
-j .efi_runtime -j .efi_runtime_rel
else ifeq ($(HOST_ARCH),$(HOST_ARCH_ARM))
EFI_LDS := ${SRCDIR}/../../../arch/arm/lib/elf_arm_efi.lds
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
-j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \
-j .binman_sym_table -j .text_rest \
-j .efi_runtime -j .efi_runtime_rel
else ifeq ($(HOST_ARCH),$(HOST_ARCH_RISCV32))
EFI_LDS := ${SRCDIR}/../../../arch/riscv/lib/elf_riscv32_efi.lds
else ifeq ($(HOST_ARCH),$(HOST_ARCH_RISCV64))
EFI_LDS := ${SRCDIR}/../../../arch/riscv/lib/elf_riscv64_efi.lds
endif
EFI_CRT0 := crt0_sandbox_efi.o
EFI_RELOC := reloc_sandbox_efi.o
AFLAGS_crt0_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)"
CFLAGS_reloc_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)"
@@ -0,0 +1,32 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2011 The Chromium OS Authors.
#
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
obj-y := cpu.o state.o
extra-y := start.o os.o
extra-$(CONFIG_SANDBOX_SDL) += sdl.o
obj-$(CONFIG_SPL_BUILD) += spl.o
obj-$(CONFIG_ETH_SANDBOX_RAW) += eth-raw-os.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)
# eth-raw-os.c is built in the system env, so needs standard includes
# CFLAGS_REMOVE_eth-raw-os.o cannot be used to drop header include path
quiet_cmd_cc_eth-raw-os.o = CC $(quiet_modtag) $@
cmd_cc_eth-raw-os.o = $(CC) $(filter-out -nostdinc, \
$(patsubst -I%,-idirafter%,$(c_flags))) -c -o $@ $<
$(obj)/eth-raw-os.o: $(src)/eth-raw-os.c FORCE
$(call if_changed_dep,cc_eth-raw-os.o)
@@ -0,0 +1,342 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <errno.h>
#include <linux/libfdt.h>
#include <os.h>
#include <asm/io.h>
#include <asm/setjmp.h>
#include <asm/state.h>
#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
/* Enable access to PCI memory with map_sysmem() */
static bool enable_pci_map;
#ifdef CONFIG_PCI
/* Last device that was mapped into memory, and length of mapping */
static struct udevice *map_dev;
unsigned long map_len;
#endif
void sandbox_exit(void)
{
/* Do this here while it still has an effect */
os_fd_restore();
if (state_uninit())
os_exit(2);
if (dm_uninit())
os_exit(2);
/* This is considered normal termination for now */
os_exit(0);
}
/* delay x useconds */
void __udelay(unsigned long usec)
{
struct sandbox_state *state = state_get_current();
if (!state->skip_delays)
os_usleep(usec);
}
int cleanup_before_linux(void)
{
return 0;
}
int cleanup_before_linux_select(int flags)
{
return 0;
}
/**
* is_in_sandbox_mem() - Checks if a pointer is within sandbox's emulated DRAM
*
* This provides a way to check if a pointer is owned by sandbox (and is within
* its RAM) or not. Sometimes pointers come from a test which conceptually runs
* output sandbox, potentially with direct access to the C-library malloc()
* function, or the sandbox stack (which is not actually within the emulated
* DRAM.
*
* Such pointers obviously cannot be mapped into sandbox's DRAM, so we must
* detect them an process them separately, by recording a mapping to a tag,
* which we can use to map back to the pointer later.
*
* @ptr: Pointer to check
* @return true if this is within sandbox emulated DRAM, false if not
*/
static bool is_in_sandbox_mem(const void *ptr)
{
return (const uint8_t *)ptr >= gd->arch.ram_buf &&
(const uint8_t *)ptr < gd->arch.ram_buf + gd->ram_size;
}
/**
* phys_to_virt() - Converts a sandbox RAM address to a pointer
*
* Sandbox uses U-Boot addresses from 0 to the size of DRAM. These index into
* the emulated DRAM buffer used by sandbox. This function converts such an
* address to a pointer into this buffer, which can be used to access the
* memory.
*
* If the address is outside this range, it is assumed to be a tag
*/
void *phys_to_virt(phys_addr_t paddr)
{
struct sandbox_mapmem_entry *mentry;
struct sandbox_state *state;
/* If the address is within emulated DRAM, calculate the value */
if (paddr < gd->ram_size)
return (void *)(gd->arch.ram_buf + paddr);
/*
* Otherwise search out list of tags for the correct pointer previously
* created by map_to_sysmem()
*/
state = state_get_current();
list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
if (mentry->tag == paddr) {
debug("%s: Used map from %lx to %p\n", __func__,
(ulong)paddr, mentry->ptr);
return mentry->ptr;
}
}
printf("%s: Cannot map sandbox address %lx (SDRAM from 0 to %lx)\n",
__func__, (ulong)paddr, (ulong)gd->ram_size);
os_abort();
/* Not reached */
return NULL;
}
struct sandbox_mapmem_entry *find_tag(const void *ptr)
{
struct sandbox_mapmem_entry *mentry;
struct sandbox_state *state = state_get_current();
list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
if (mentry->ptr == ptr) {
debug("%s: Used map from %p to %lx\n", __func__, ptr,
mentry->tag);
return mentry;
}
}
return NULL;
}
phys_addr_t virt_to_phys(void *ptr)
{
struct sandbox_mapmem_entry *mentry;
/*
* If it is in emulated RAM, don't bother looking for a tag. Just
* calculate the pointer using the provides offset into the RAM buffer.
*/
if (is_in_sandbox_mem(ptr))
return (phys_addr_t)((uint8_t *)ptr - gd->arch.ram_buf);
mentry = find_tag(ptr);
if (!mentry) {
/* Abort so that gdb can be used here */
printf("%s: Cannot map sandbox address %p (SDRAM from 0 to %lx)\n",
__func__, ptr, (ulong)gd->ram_size);
os_abort();
}
debug("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag);
return mentry->tag;
}
void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
#if defined(CONFIG_PCI) && !defined(CONFIG_SPL_BUILD)
unsigned long plen = len;
void *ptr;
map_dev = NULL;
if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) {
if (plen != len) {
printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n",
__func__, (uint)paddr, len, plen);
}
map_len = len;
return ptr;
}
#endif
return phys_to_virt(paddr);
}
void unmap_physmem(const void *ptr, unsigned long flags)
{
#ifdef CONFIG_PCI
if (map_dev) {
pci_unmap_physmem(ptr, map_len, map_dev);
map_dev = NULL;
}
#endif
}
phys_addr_t map_to_sysmem(const void *ptr)
{
struct sandbox_mapmem_entry *mentry;
/*
* If it is in emulated RAM, don't bother creating a tag. Just return
* the offset into the RAM buffer.
*/
if (is_in_sandbox_mem(ptr))
return (u8 *)ptr - gd->arch.ram_buf;
/*
* See if there is an existing tag with this pointer. If not, set up a
* new one.
*/
mentry = find_tag(ptr);
if (!mentry) {
struct sandbox_state *state = state_get_current();
mentry = malloc(sizeof(*mentry));
if (!mentry) {
printf("%s: Error: Out of memory\n", __func__);
os_exit(ENOMEM);
}
mentry->tag = state->next_tag++;
mentry->ptr = (void *)ptr;
list_add_tail(&mentry->sibling_node, &state->mapmem_head);
debug("%s: Added map from %p to %lx\n", __func__, ptr,
(ulong)mentry->tag);
}
/*
* Return the tag as the address to use. A later call to map_sysmem()
* will return ptr
*/
return mentry->tag;
}
unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size)
{
struct sandbox_state *state = state_get_current();
if (!state->allow_memio)
return 0;
switch (size) {
case SB_SIZE_8:
return *(u8 *)addr;
case SB_SIZE_16:
return *(u16 *)addr;
case SB_SIZE_32:
return *(u32 *)addr;
case SB_SIZE_64:
return *(u64 *)addr;
}
return 0;
}
void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size)
{
struct sandbox_state *state = state_get_current();
if (!state->allow_memio)
return;
switch (size) {
case SB_SIZE_8:
*(u8 *)addr = val;
break;
case SB_SIZE_16:
*(u16 *)addr = val;
break;
case SB_SIZE_32:
*(u32 *)addr = val;
break;
case SB_SIZE_64:
*(u64 *)addr = val;
break;
}
}
void sandbox_set_enable_memio(bool enable)
{
struct sandbox_state *state = state_get_current();
state->allow_memio = enable;
}
void sandbox_set_enable_pci_map(int enable)
{
enable_pci_map = enable;
}
void flush_dcache_range(unsigned long start, unsigned long stop)
{
}
void invalidate_dcache_range(unsigned long start, unsigned long stop)
{
}
int sandbox_read_fdt_from_file(void)
{
struct sandbox_state *state = state_get_current();
const char *fname = state->fdt_fname;
void *blob;
loff_t size;
int err;
int fd;
blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
if (!state->fdt_fname) {
err = fdt_create_empty_tree(blob, 256);
if (!err)
goto done;
printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
return -EINVAL;
}
err = os_get_filesize(fname, &size);
if (err < 0) {
printf("Failed to file FDT file '%s'\n", fname);
return err;
}
fd = os_open(fname, OS_O_RDONLY);
if (fd < 0) {
printf("Failed to open FDT file '%s'\n", fname);
return -EACCES;
}
if (os_read(fd, blob, size) != size) {
os_close(fd);
return -EIO;
}
os_close(fd);
done:
gd->fdt_blob = blob;
return 0;
}
ulong timer_get_boot_us(void)
{
static uint64_t base_count;
uint64_t count = os_get_nsec();
if (!base_count)
base_count = count;
return (count - base_count) / 1000;
}
@@ -0,0 +1,295 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2015-2018 National Instruments
* Copyright (c) 2015-2018 Joe Hershberger <joe.hershberger@ni.com>
*/
#include <asm/eth-raw-os.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <os.h>
struct sandbox_eth_raw_if_nameindex *sandbox_eth_raw_if_nameindex(void)
{
return (struct sandbox_eth_raw_if_nameindex *)if_nameindex();
}
void sandbox_eth_raw_if_freenameindex(struct sandbox_eth_raw_if_nameindex *ptr)
{
if_freenameindex((struct if_nameindex *)ptr);
}
int sandbox_eth_raw_os_is_local(const char *ifname)
{
int fd = socket(AF_INET, SOCK_DGRAM, 0);
struct ifreq ifr;
int ret = 0;
if (fd < 0)
return -errno;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
if (ret < 0) {
ret = -errno;
goto out;
}
ret = !!(ifr.ifr_flags & IFF_LOOPBACK);
out:
close(fd);
return ret;
}
int sandbox_eth_raw_os_idx_to_name(struct eth_sandbox_raw_priv *priv)
{
if (!if_indextoname(priv->host_ifindex, priv->host_ifname))
return -errno;
return 0;
}
static int _raw_packet_start(struct eth_sandbox_raw_priv *priv,
unsigned char *ethmac)
{
struct sockaddr_ll *device;
struct packet_mreq mr;
int ret;
int flags;
/* Prepare device struct */
priv->local_bind_sd = -1;
priv->device = os_malloc(sizeof(struct sockaddr_ll));
if (priv->device == NULL)
return -ENOMEM;
device = priv->device;
memset(device, 0, sizeof(struct sockaddr_ll));
device->sll_ifindex = if_nametoindex(priv->host_ifname);
priv->host_ifindex = device->sll_ifindex;
device->sll_family = AF_PACKET;
memcpy(device->sll_addr, ethmac, 6);
device->sll_halen = htons(6);
/* Open socket */
priv->sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (priv->sd < 0) {
printf("Failed to open socket: %d %s\n", errno,
strerror(errno));
return -errno;
}
/* Bind to the specified interface */
ret = setsockopt(priv->sd, SOL_SOCKET, SO_BINDTODEVICE,
priv->host_ifname, strlen(priv->host_ifname) + 1);
if (ret < 0) {
printf("Failed to bind to '%s': %d %s\n", priv->host_ifname,
errno, strerror(errno));
return -errno;
}
/* Make the socket non-blocking */
flags = fcntl(priv->sd, F_GETFL, 0);
fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK);
/* Enable promiscuous mode to receive responses meant for us */
mr.mr_ifindex = device->sll_ifindex;
mr.mr_type = PACKET_MR_PROMISC;
ret = setsockopt(priv->sd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&mr, sizeof(mr));
if (ret < 0) {
struct ifreq ifr;
printf("Failed to set promiscuous mode: %d %s\n"
"Falling back to the old \"flags\" way...\n",
errno, strerror(errno));
if (strlen(priv->host_ifname) >= IFNAMSIZ) {
printf("Interface name %s is too long.\n",
priv->host_ifname);
return -EINVAL;
}
strncpy(ifr.ifr_name, priv->host_ifname, IFNAMSIZ);
if (ioctl(priv->sd, SIOCGIFFLAGS, &ifr) < 0) {
printf("Failed to read flags: %d %s\n", errno,
strerror(errno));
return -errno;
}
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(priv->sd, SIOCSIFFLAGS, &ifr) < 0) {
printf("Failed to write flags: %d %s\n", errno,
strerror(errno));
return -errno;
}
}
return 0;
}
static int _local_inet_start(struct eth_sandbox_raw_priv *priv)
{
struct sockaddr_in *device;
int ret;
int flags;
int one = 1;
/* Prepare device struct */
priv->local_bind_sd = -1;
priv->local_bind_udp_port = 0;
priv->device = os_malloc(sizeof(struct sockaddr_in));
if (priv->device == NULL)
return -ENOMEM;
device = priv->device;
memset(device, 0, sizeof(struct sockaddr_in));
device->sin_family = AF_INET;
device->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
/**
* Open socket
* Since we specify UDP here, any incoming ICMP packets will
* not be received, so things like ping will not work on this
* localhost interface.
*/
priv->sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if (priv->sd < 0) {
printf("Failed to open socket: %d %s\n", errno,
strerror(errno));
return -errno;
}
/* Make the socket non-blocking */
flags = fcntl(priv->sd, F_GETFL, 0);
fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK);
/* Include the UDP/IP headers on send and receive */
ret = setsockopt(priv->sd, IPPROTO_IP, IP_HDRINCL, &one,
sizeof(one));
if (ret < 0) {
printf("Failed to set header include option: %d %s\n", errno,
strerror(errno));
return -errno;
}
return 0;
}
int sandbox_eth_raw_os_start(struct eth_sandbox_raw_priv *priv,
unsigned char *ethmac)
{
if (priv->local)
return _local_inet_start(priv);
else
return _raw_packet_start(priv, ethmac);
}
int sandbox_eth_raw_os_send(void *packet, int length,
struct eth_sandbox_raw_priv *priv)
{
int retval;
struct udphdr *udph = packet + sizeof(struct iphdr);
if (priv->sd < 0 || !priv->device)
return -EINVAL;
/*
* This block of code came about when testing tftp on the localhost
* interface. When using the RAW AF_INET API, the network stack is still
* in play responding to incoming traffic based on open "ports". Since
* it is raw (at the IP layer, no Ethernet) the network stack tells the
* TFTP server that the port it responded to is closed. This causes the
* TFTP transfer to be aborted. This block of code inspects the outgoing
* packet as formulated by the u-boot network stack to determine the
* source port (that the TFTP server will send packets back to) and
* opens a typical UDP socket on that port, thus preventing the network
* stack from sending that ICMP message claiming that the port has no
* bound socket.
*/
if (priv->local && (priv->local_bind_sd == -1 ||
priv->local_bind_udp_port != udph->source)) {
struct iphdr *iph = packet;
struct sockaddr_in addr;
if (priv->local_bind_sd != -1)
close(priv->local_bind_sd);
/* A normal UDP socket is required to bind */
priv->local_bind_sd = socket(AF_INET, SOCK_DGRAM, 0);
if (priv->local_bind_sd < 0) {
printf("Failed to open bind sd: %d %s\n", errno,
strerror(errno));
return -errno;
}
priv->local_bind_udp_port = udph->source;
/**
* Bind the UDP port that we intend to use as our source port
* so that the kernel will not send an ICMP port unreachable
* message to the server
*/
addr.sin_family = AF_INET;
addr.sin_port = udph->source;
addr.sin_addr.s_addr = iph->saddr;
retval = bind(priv->local_bind_sd, (struct sockaddr *)&addr,
sizeof(addr));
if (retval < 0)
printf("Failed to bind: %d %s\n", errno,
strerror(errno));
}
retval = sendto(priv->sd, packet, length, 0,
(struct sockaddr *)priv->device,
sizeof(struct sockaddr_ll));
if (retval < 0) {
printf("Failed to send packet: %d %s\n", errno,
strerror(errno));
return -errno;
}
return retval;
}
int sandbox_eth_raw_os_recv(void *packet, int *length,
const struct eth_sandbox_raw_priv *priv)
{
int retval;
int saddr_size;
if (priv->sd < 0 || !priv->device)
return -EINVAL;
saddr_size = sizeof(struct sockaddr);
retval = recvfrom(priv->sd, packet, 1536, 0,
(struct sockaddr *)priv->device,
(socklen_t *)&saddr_size);
*length = 0;
if (retval >= 0) {
*length = retval;
return 0;
}
/* The socket is non-blocking, so expect EAGAIN when there is no data */
if (errno == EAGAIN)
return 0;
return -errno;
}
void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv)
{
os_free(priv->device);
priv->device = NULL;
close(priv->sd);
priv->sd = -1;
if (priv->local) {
if (priv->local_bind_sd != -1)
close(priv->local_bind_sd);
priv->local_bind_sd = -1;
priv->local_bind_udp_port = 0;
}
}
@@ -0,0 +1,829 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <setjmp.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>
#include <rtc_def.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_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;
if (os_flags & OS_O_TRUNC)
flags |= O_TRUNC;
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);
}
int os_write_file(const char *fname, const void *buf, int size)
{
int fd;
fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT | OS_O_TRUNC);
if (fd < 0) {
printf("Cannot open file '%s'\n", fname);
return -EIO;
}
if (os_write(fd, buf, size) != size) {
printf("Cannot write to file '%s'\n", fname);
os_close(fd);
return -EIO;
}
os_close(fd);
return 0;
}
int os_read_file(const char *fname, void **bufp, int *sizep)
{
off_t size;
int ret = -EIO;
int fd;
fd = os_open(fname, OS_O_RDONLY);
if (fd < 0) {
printf("Cannot open file '%s'\n", fname);
goto err;
}
size = os_lseek(fd, 0, OS_SEEK_END);
if (size < 0) {
printf("Cannot seek to end of file '%s'\n", fname);
goto err;
}
if (os_lseek(fd, 0, OS_SEEK_SET) < 0) {
printf("Cannot seek to start of file '%s'\n", fname);
goto err;
}
*bufp = os_malloc(size);
if (!*bufp) {
printf("Not enough memory to read file '%s'\n", fname);
ret = -ENOMEM;
goto err;
}
if (os_read(fd, *bufp, size) != size) {
printf("Cannot read from file '%s'\n", fname);
goto err;
}
os_close(fd);
*sizep = size;
return 0;
err:
os_close(fd);
return ret;
}
/* Restore tty state when we exit */
static struct termios orig_term;
static bool term_setup;
static bool term_nonblock;
void os_fd_restore(void)
{
if (term_setup) {
int flags;
tcsetattr(0, TCSANOW, &orig_term);
if (term_nonblock) {
flags = fcntl(0, F_GETFL, 0);
fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
}
term_setup = false;
}
}
/* Put tty into raw mode so <tab> and <ctrl+c> work */
void os_tty_raw(int fd, bool allow_sigs)
{
struct termios term;
int flags;
if (term_setup)
return;
/* 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;
flags = fcntl(fd, F_GETFL, 0);
if (!(flags & O_NONBLOCK)) {
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
return;
term_nonblock = true;
}
term_setup = true;
atexit(os_fd_restore);
}
void *os_malloc(size_t length)
{
int page_size = getpagesize();
struct os_mem_hdr *hdr;
/*
* Use an address that is hopefully available to us so that pointers
* to this memory are fairly obvious. If we end up with a different
* address, that's fine too.
*/
hdr = mmap((void *)0x10000000, length + page_size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (hdr == MAP_FAILED)
return NULL;
hdr->length = length;
return (void *)hdr + page_size;
}
void os_free(void *ptr)
{
int page_size = getpagesize();
struct os_mem_hdr *hdr;
if (ptr) {
hdr = ptr - page_size;
munmap(hdr, hdr->length + page_size);
}
}
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);
}
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;
os_free(node);
node = next;
}
}
int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
{
struct dirent *entry;
struct os_dirent_node *head, *node, *next;
struct stat buf;
DIR *dir;
int ret;
char *fname;
char *old_fname;
int len;
int dirlen;
*headp = NULL;
dir = opendir(dirname);
if (!dir)
return -1;
/* Create a buffer upfront, with typically sufficient size */
dirlen = strlen(dirname) + 2;
len = dirlen + 256;
fname = os_malloc(len);
if (!fname) {
ret = -ENOMEM;
goto done;
}
for (node = head = NULL;; node = next) {
errno = 0;
entry = readdir(dir);
if (!entry) {
ret = errno;
break;
}
next = os_malloc(sizeof(*node) + strlen(entry->d_name) + 1);
if (!next) {
os_dirent_free(head);
ret = -ENOMEM;
goto done;
}
if (dirlen + strlen(entry->d_name) > len) {
len = dirlen + strlen(entry->d_name);
old_fname = fname;
fname = os_realloc(fname, len);
if (!fname) {
os_free(old_fname);
os_free(next);
os_dirent_free(head);
ret = -ENOMEM;
goto done;
}
}
next->next = NULL;
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;
default:
next->type = OS_FILET_UNKNOWN;
}
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;
else
head = next;
}
*headp = head;
done:
closedir(dir);
os_free(fname);
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 >= OS_FILET_REG && type < OS_FILET_COUNT)
return os_dirent_typename[type];
return os_dirent_typename[OS_FILET_UNKNOWN];
}
int os_get_filesize(const char *fname, loff_t *size)
{
struct stat buf;
int ret;
ret = stat(fname, &buf);
if (ret)
return ret;
*size = buf.st_size;
return 0;
}
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;
loff_t size;
ret = os_get_filesize(fname, &size);
if (ret < 0)
return ret;
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;
}
/**
* add_args() - Allocate a new argv with the given args
*
* This is used to create a new argv array with all the old arguments and some
* new ones that are passed in
*
* @argvp: Returns newly allocated args list
* @add_args: Arguments to add, each a string
* @count: Number of arguments in @add_args
* @return 0 if OK, -ENOMEM if out of memory
*/
static int add_args(char ***argvp, char *add_args[], int count)
{
char **argv, **ap;
int argc;
for (argc = 0; (*argvp)[argc]; argc++)
;
argv = os_malloc((argc + count + 1) * sizeof(char *));
if (!argv) {
printf("Out of memory for %d argv\n", count);
return -ENOMEM;
}
for (ap = *argvp, argc = 0; *ap; ap++) {
char *arg = *ap;
/* Drop args that we don't want to propagate */
if (*arg == '-' && strlen(arg) == 2) {
switch (arg[1]) {
case 'j':
case 'm':
ap++;
continue;
}
} else if (!strcmp(arg, "--rm_memory")) {
ap++;
continue;
}
argv[argc++] = arg;
}
memcpy(argv + argc, add_args, count * sizeof(char *));
argv[argc + count] = NULL;
*argvp = argv;
return 0;
}
/**
* os_jump_to_file() - Jump to a new program
*
* This saves the memory buffer, sets up arguments to the new process, then
* execs it.
*
* @fname: Filename to exec
* @return does not return on success, any return value is an error
*/
static int os_jump_to_file(const char *fname)
{
struct sandbox_state *state = state_get_current();
char mem_fname[30];
int fd, err;
char *extra_args[5];
char **argv = state->argv;
int argc;
#ifdef DEBUG
int i;
#endif
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] = (char *)fname;
extra_args[2] = "-m";
extra_args[3] = mem_fname;
argc = 4;
if (state->ram_buf_rm)
extra_args[argc++] = "--rm_memory";
err = add_args(&argv, extra_args, argc);
if (err)
return err;
argv[0] = (char *)fname;
#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);
os_free(argv);
if (err) {
perror("Unable to run image");
printf("Image filename '%s'\n", fname);
return err;
}
return unlink(fname);
}
int os_jump_to_image(const void *dest, int size)
{
char fname[30];
int err;
err = make_exec(fname, dest, size);
if (err)
return err;
return os_jump_to_file(fname);
}
int os_find_u_boot(char *fname, int maxlen)
{
struct sandbox_state *state = state_get_current();
const char *progname = state->argv[0];
int len = strlen(progname);
const char *suffix;
char *p;
int fd;
if (len >= maxlen || len < 4)
return -ENOSPC;
strcpy(fname, progname);
suffix = fname + len - 4;
/* If we are TPL, boot to SPL */
if (!strcmp(suffix, "-tpl")) {
fname[len - 3] = 's';
fd = os_open(fname, O_RDONLY);
if (fd >= 0) {
close(fd);
return 0;
}
/* Look for 'u-boot-tpl' in the tpl/ directory */
p = strstr(fname, "/tpl/");
if (p) {
p[1] = 's';
fd = os_open(fname, O_RDONLY);
if (fd >= 0) {
close(fd);
return 0;
}
}
return -ENOENT;
}
/* Look for 'u-boot' in the same directory as 'u-boot-spl' */
if (!strcmp(suffix, "-spl")) {
fname[len - 4] = '\0';
fd = os_open(fname, O_RDONLY);
if (fd >= 0) {
close(fd);
return 0;
}
}
/* Look for 'u-boot' in the parent directory of spl/ */
p = strstr(fname, "spl/");
if (p) {
/* Remove the "spl" characters */
memmove(p, p + 4, strlen(p + 4) + 1);
fd = os_open(fname, O_RDONLY);
if (fd >= 0) {
close(fd);
return 0;
}
}
return -ENOENT;
}
int os_spl_to_uboot(const char *fname)
{
return os_jump_to_file(fname);
}
void os_localtime(struct rtc_time *rt)
{
time_t t = time(NULL);
struct tm *tm;
tm = localtime(&t);
rt->tm_sec = tm->tm_sec;
rt->tm_min = tm->tm_min;
rt->tm_hour = tm->tm_hour;
rt->tm_mday = tm->tm_mday;
rt->tm_mon = tm->tm_mon + 1;
rt->tm_year = tm->tm_year + 1900;
rt->tm_wday = tm->tm_wday;
rt->tm_yday = tm->tm_yday;
rt->tm_isdst = tm->tm_isdst;
}
void os_abort(void)
{
abort();
}
int os_mprotect_allow(void *start, size_t len)
{
int page_size = getpagesize();
/* Move start to the start of a page, len to the end */
start = (void *)(((ulong)start) & ~(page_size - 1));
len = (len + page_size * 2) & ~(page_size - 1);
return mprotect(start, len, PROT_READ | PROT_WRITE);
}
void *os_find_text_base(void)
{
char line[500];
void *base = NULL;
int len;
int fd;
/*
* This code assumes that the first line of /proc/self/maps holds
* information about the text, for example:
*
* 5622d9907000-5622d9a55000 r-xp 00000000 08:01 15067168 u-boot
*
* The first hex value is assumed to be the address.
*
* This is tested in Linux 4.15.
*/
fd = open("/proc/self/maps", O_RDONLY);
if (fd == -1)
return NULL;
len = read(fd, line, sizeof(line));
if (len > 0) {
char *end = memchr(line, '-', len);
if (end) {
uintptr_t addr;
*end = '\0';
if (sscanf(line, "%zx", &addr) == 1)
base = (void *)addr;
}
}
close(fd);
return base;
}
@@ -0,0 +1,376 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2013 Google, Inc
*/
#include <errno.h>
#include <unistd.h>
#include <linux/input.h>
#include <SDL.h>
#include <asm/state.h>
/**
* struct buf_info - a data buffer holding audio data
*
* @pos: Current position playing in audio buffer
* @size: Size of data in audio buffer (0=empty)
* @alloced: Allocated size of audio buffer (max size it can hold)
* @data: Audio data
*/
struct buf_info {
uint pos;
uint size;
uint alloced;
uint8_t *data;
};
static struct sdl_info {
SDL_Surface *screen;
int width;
int 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;
} 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)
{
struct buf_info *buf;
int avail;
int i;
for (i = 0; i < 2; i++) {
buf = &sdl.buf[sdl.cur_buf];
avail = buf->size - buf->pos;
if (avail <= 0) {
sdl.cur_buf = 1 - sdl.cur_buf;
continue;
}
if (avail > len)
avail = len;
SDL_MixAudio(stream, buf->data + buf->pos, avail,
SDL_MIX_MAXVOLUME);
buf->pos += avail;
len -= avail;
/* Move to next buffer if we are at the end */
if (buf->pos == buf->size)
buf->size = 0;
else
break;
}
}
int sandbox_sdl_sound_init(int rate, int channels)
{
SDL_AudioSpec wanted;
int i;
if (sandbox_sdl_ensure_init())
return -1;
if (sdl.audio_active)
return 0;
/* Set the audio format */
wanted.freq = rate;
wanted.format = AUDIO_S16;
wanted.channels = channels;
wanted.samples = 1024; /* Good low-latency value for callback */
wanted.callback = sandbox_sdl_fill_audio;
wanted.userdata = NULL;
for (i = 0; i < 2; i++) {
struct buf_info *buf = &sdl.buf[i];
buf->alloced = sizeof(uint16_t) * wanted.freq * wanted.channels;
buf->data = malloc(buf->alloced);
if (!buf->data) {
printf("%s: Out of memory\n", __func__);
if (i == 1)
free(sdl.buf[0].data);
return -1;
}
buf->pos = 0;
buf->size = 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;
sdl.sample_rate = wanted.freq;
sdl.cur_buf = 0;
sdl.running = 0;
return 0;
err:
for (i = 0; i < 2; i++)
free(sdl.buf[i].data);
return -1;
}
int sandbox_sdl_sound_play(const void *data, uint size)
{
struct buf_info *buf;
if (!sdl.audio_active)
return 0;
buf = &sdl.buf[0];
if (buf->size)
buf = &sdl.buf[1];
while (buf->size)
usleep(1000);
if (size > buf->alloced)
return -E2BIG;
memcpy(buf->data, data, size);
buf->size = size;
buf->pos = 0;
if (!sdl.running) {
SDL_PauseAudio(0);
sdl.running = 1;
}
return 0;
}
int sandbox_sdl_sound_stop(void)
{
if (sdl.running) {
SDL_PauseAudio(1);
sdl.running = 0;
}
return 0;
}
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2016 Google, Inc
*/
#include <common.h>
#include <dm.h>
#include <os.h>
#include <spl.h>
#include <asm/spl.h>
#include <asm/state.h>
DECLARE_GLOBAL_DATA_PTR;
/* SPL / TPL init function */
void board_init_f(ulong flag)
{
struct sandbox_state *state = state_get_current();
gd->arch.ram_buf = state->ram_buf;
gd->ram_size = state->ram_size;
}
u32 spl_boot_device(void)
{
return BOOT_DEVICE_BOARD;
}
static int spl_board_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
char fname[256];
int ret;
ret = os_find_u_boot(fname, sizeof(fname));
if (ret) {
printf("(%s not found, error %d)\n", fname, ret);
return ret;
}
/* Set up spl_image to boot from jump_to_image_no_args() */
spl_image->arg = strdup(fname);
if (!spl_image->arg)
return log_msg_ret("Setup exec filename", -ENOMEM);
return 0;
}
SPL_LOAD_IMAGE_METHOD("sandbox", 9, BOOT_DEVICE_BOARD, spl_board_load_image);
void spl_board_init(void)
{
struct sandbox_state *state = state_get_current();
struct udevice *dev;
preloader_console_init();
if (state->show_of_platdata) {
/*
* Scan all the devices so that we can output their platform
* data. See sandbox_spl_probe().
*/
printf("Scanning misc devices\n");
for (uclass_first_device(UCLASS_MISC, &dev);
dev;
uclass_next_device(&dev))
;
}
}
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
{
const char *fname = spl_image->arg;
if (fname) {
os_fd_restore();
os_spl_to_uboot(fname);
} else {
printf("No filename provided for U-Boot\n");
}
hang();
}
int handoff_arch_save(struct spl_handoff *ho)
{
ho->arch.magic = TEST_HANDOFF_MAGIC;
return 0;
}
@@ -0,0 +1,396 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2011-2012 The Chromium OS Authors.
*/
#include <common.h>
#include <command.h>
#include <errno.h>
#include <os.h>
#include <cli.h>
#include <malloc.h>
#include <asm/getopt.h>
#include <asm/io.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((int)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);
}
int misc_init_f(void)
{
return sandbox_early_getopt_check();
}
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");
#ifndef CONFIG_SPL_BUILD
int sandbox_main_loop_init(void)
{
struct sandbox_state *state = state_get_current();
/* Execute command if required */
if (state->cmd || state->run_distro_boot) {
int retval = 0;
cli_init();
#ifdef CONFIG_CMDLINE
if (state->cmd)
retval = run_command_list(state->cmd, -1, 0);
if (state->run_distro_boot)
retval = cli_simple_run_command("run distro_bootcmd",
0);
#endif
if (!state->interactive)
os_exit(retval);
}
return 0;
}
#endif
static int sandbox_cmdline_cb_boot(struct sandbox_state *state,
const char *arg)
{
state->run_distro_boot = true;
return 0;
}
SANDBOX_CMDLINE_OPT_SHORT(boot, 'b', 0, "Run distro boot commands");
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_default_fdt(struct sandbox_state *state,
const char *arg)
{
const char *fmt = "%s.dtb";
char *fname;
int len;
len = strlen(state->argv[0]) + strlen(fmt) + 1;
fname = os_malloc(len);
if (!fname)
return -ENOMEM;
snprintf(fname, len, fmt, state->argv[0]);
state->fdt_fname = fname;
return 0;
}
SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0,
"Use the default u-boot.dtb control FDT in U-Boot directory");
static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
const char *arg)
{
const char *fmt = "/arch/sandbox/dts/test.dtb";
char *p;
char *fname;
int len;
len = strlen(state->argv[0]) + strlen(fmt) + 1;
fname = os_malloc(len);
if (!fname)
return -ENOMEM;
strcpy(fname, state->argv[0]);
p = strrchr(fname, '/');
if (!p)
p = fname + strlen(fname);
len -= p - fname;
snprintf(p, len, fmt, p);
state->fdt_fname = fname;
return 0;
}
SANDBOX_CMDLINE_OPT_SHORT(test_fdt, 'T', 0,
"Use the test.dtb control FDT in U-Boot directory");
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;
err = os_read_ram_buf(arg);
if (err) {
printf("Failed to read RAM buffer '%s': %d\n", arg, err);
return err;
}
state->ram_buf_read = true;
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");
static int sandbox_cmdline_cb_verbose(struct sandbox_state *state,
const char *arg)
{
state->show_test_output = true;
return 0;
}
SANDBOX_CMDLINE_OPT_SHORT(verbose, 'v', 0, "Show test output");
static int sandbox_cmdline_cb_log_level(struct sandbox_state *state,
const char *arg)
{
state->default_log_level = simple_strtol(arg, NULL, 10);
return 0;
}
SANDBOX_CMDLINE_OPT_SHORT(log_level, 'L', 1,
"Set log level (0=panic, 7=debug)");
static int sandbox_cmdline_cb_show_of_platdata(struct sandbox_state *state,
const char *arg)
{
state->show_of_platdata = true;
return 0;
}
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 */
if (!state->ram_buf_read)
memset(state->ram_buf, '\0', state->ram_size);
gd->arch.ram_buf = state->ram_buf;
gd->ram_size = state->ram_size;
}
void state_show(struct sandbox_state *state)
{
char **p;
printf("Arguments:\n");
for (p = state->argv; *p; p++)
printf("%s ", *p);
printf("\n");
}
int main(int argc, char *argv[])
{
struct sandbox_state *state;
gd_t data;
int ret;
memset(&data, '\0', sizeof(data));
gd = &data;
gd->arch.text_base = os_find_text_base();
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;
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
gd->malloc_base = CONFIG_MALLOC_F_ADDR;
#endif
#if CONFIG_IS_ENABLED(LOG)
gd->default_log_level = state->default_log_level;
#endif
setup_ram_buf(state);
/*
* Set up the relocation offset here, since sandbox symbols are always
* relocated by the OS before sandbox is entered.
*/
gd->reloc_off = (ulong)gd->arch.text_base;
/* 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;
}
@@ -0,0 +1,424 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2011-2012 The Chromium OS Authors.
*/
#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 */
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)
{
loff_t size;
int ret;
int fd;
ret = os_get_filesize(fname, &size);
if (ret < 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 functions */
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;
}
void state_set_skip_delays(bool skip_delays)
{
struct sandbox_state *state = state_get_current();
state->skip_delays = skip_delays;
}
bool state_get_skip_delays(void)
{
struct sandbox_state *state = state_get_current();
return state->skip_delays;
}
void state_reset_for_test(struct sandbox_state *state)
{
/* No reset yet, so mark it as such. Always allow power reset */
state->last_sysreset = SYSRESET_COUNT;
state->sysreset_allowed[SYSRESET_POWER_OFF] = true;
memset(&state->wdt, '\0', sizeof(state->wdt));
memset(state->spi, '\0', sizeof(state->spi));
/*
* Set up the memory tag list. Use the top of emulated SDRAM for the
* first tag number, since that address offset is outside the legal
* range, and can be assumed to be a tag.
*/
INIT_LIST_HEAD(&state->mapmem_head);
state->next_tag = state->ram_size;
}
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);
state_reset_for_test(state);
/*
* 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) {
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;
}
}
/* Remove old memory file if required */
if (state->ram_buf_rm && state->ram_buf_fname)
os_unlink(state->ram_buf_fname);
/* 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;
}
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* 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.
*/
SECTIONS
{
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
__u_boot_sandbox_option_start = .;
_u_boot_sandbox_getopt : { KEEP(*(.u_boot_sandbox_getopt)) }
__u_boot_sandbox_option_end = .;
__bss_start = .;
}
INSERT BEFORE .data;
@@ -0,0 +1,51 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* 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.
*/
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 = .;
.__efi_runtime_start : {
*(.__efi_runtime_start)
}
.efi_runtime : {
*(efi_runtime_text)
*(efi_runtime_data)
}
.__efi_runtime_stop : {
*(.__efi_runtime_stop)
}
.efi_runtime_rel_start :
{
*(.__efi_runtime_rel_start)
}
.efi_runtime_rel : {
*(.relefi_runtime_text)
*(.relefi_runtime_data)
}
.efi_runtime_rel_stop :
{
*(.__efi_runtime_rel_stop)
}
__bss_start = .;
}
INSERT BEFORE .data;
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: GPL-2.0+
ifdef CONFIG_SANDBOX64
dtb-$(CONFIG_SANDBOX) += sandbox64.dtb
else
dtb-$(CONFIG_SANDBOX) += sandbox.dtb
endif
dtb-$(CONFIG_UT_DM) += test.dtb
targets += $(dtb-y)
DTC_FLAGS += -R 4 -p 0x1000
PHONY += dtbs
dtbs: $(addprefix $(obj)/, $(dtb-y))
@:
clean-files := *.dtb
@@ -0,0 +1,105 @@
/*
* Keyboard dts fragment for devices that use cros-ec-keyboard
*
* Copyright (c) 2014 Google, Inc
*
* 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.
*/
#include <dt-bindings/input/input.h>
&cros_ec {
keyboard-controller {
compatible = "google,cros-ec-keyb";
keypad,num-rows = <8>;
keypad,num-columns = <13>;
google,needs-ghost-filter;
linux,keymap = <
MATRIX_KEY(0x00, 0x01, KEY_LEFTMETA)
MATRIX_KEY(0x00, 0x02, KEY_F1)
MATRIX_KEY(0x00, 0x03, KEY_B)
MATRIX_KEY(0x00, 0x04, KEY_F10)
MATRIX_KEY(0x00, 0x06, KEY_N)
MATRIX_KEY(0x00, 0x08, KEY_EQUAL)
MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT)
MATRIX_KEY(0x01, 0x01, KEY_ESC)
MATRIX_KEY(0x01, 0x02, KEY_F4)
MATRIX_KEY(0x01, 0x03, KEY_G)
MATRIX_KEY(0x01, 0x04, KEY_F7)
MATRIX_KEY(0x01, 0x06, KEY_H)
MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE)
MATRIX_KEY(0x01, 0x09, KEY_F9)
MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE)
MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL)
MATRIX_KEY(0x02, 0x01, KEY_TAB)
MATRIX_KEY(0x02, 0x02, KEY_F3)
MATRIX_KEY(0x02, 0x03, KEY_T)
MATRIX_KEY(0x02, 0x04, KEY_F6)
MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE)
MATRIX_KEY(0x02, 0x06, KEY_Y)
MATRIX_KEY(0x02, 0x07, KEY_102ND)
MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE)
MATRIX_KEY(0x02, 0x09, KEY_F8)
MATRIX_KEY(0x03, 0x01, KEY_GRAVE)
MATRIX_KEY(0x03, 0x02, KEY_F2)
MATRIX_KEY(0x03, 0x03, KEY_5)
MATRIX_KEY(0x03, 0x04, KEY_F5)
MATRIX_KEY(0x03, 0x06, KEY_6)
MATRIX_KEY(0x03, 0x08, KEY_MINUS)
MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH)
MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL)
MATRIX_KEY(0x04, 0x01, KEY_A)
MATRIX_KEY(0x04, 0x02, KEY_D)
MATRIX_KEY(0x04, 0x03, KEY_F)
MATRIX_KEY(0x04, 0x04, KEY_S)
MATRIX_KEY(0x04, 0x05, KEY_K)
MATRIX_KEY(0x04, 0x06, KEY_J)
MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON)
MATRIX_KEY(0x04, 0x09, KEY_L)
MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH)
MATRIX_KEY(0x04, 0x0b, KEY_ENTER)
MATRIX_KEY(0x05, 0x01, KEY_Z)
MATRIX_KEY(0x05, 0x02, KEY_C)
MATRIX_KEY(0x05, 0x03, KEY_V)
MATRIX_KEY(0x05, 0x04, KEY_X)
MATRIX_KEY(0x05, 0x05, KEY_COMMA)
MATRIX_KEY(0x05, 0x06, KEY_M)
MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT)
MATRIX_KEY(0x05, 0x08, KEY_SLASH)
MATRIX_KEY(0x05, 0x09, KEY_DOT)
MATRIX_KEY(0x05, 0x0b, KEY_SPACE)
MATRIX_KEY(0x06, 0x01, KEY_1)
MATRIX_KEY(0x06, 0x02, KEY_3)
MATRIX_KEY(0x06, 0x03, KEY_4)
MATRIX_KEY(0x06, 0x04, KEY_2)
MATRIX_KEY(0x06, 0x05, KEY_8)
MATRIX_KEY(0x06, 0x06, KEY_7)
MATRIX_KEY(0x06, 0x08, KEY_0)
MATRIX_KEY(0x06, 0x09, KEY_9)
MATRIX_KEY(0x06, 0x0a, KEY_LEFTALT)
MATRIX_KEY(0x06, 0x0b, KEY_DOWN)
MATRIX_KEY(0x06, 0x0c, KEY_RIGHT)
MATRIX_KEY(0x07, 0x01, KEY_Q)
MATRIX_KEY(0x07, 0x02, KEY_E)
MATRIX_KEY(0x07, 0x03, KEY_R)
MATRIX_KEY(0x07, 0x04, KEY_W)
MATRIX_KEY(0x07, 0x05, KEY_I)
MATRIX_KEY(0x07, 0x06, KEY_U)
MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT)
MATRIX_KEY(0x07, 0x08, KEY_P)
MATRIX_KEY(0x07, 0x09, KEY_O)
MATRIX_KEY(0x07, 0x0b, KEY_UP)
MATRIX_KEY(0x07, 0x0c, KEY_LEFT)
>;
};
};
@@ -0,0 +1 @@
../../../../include/dt-bindings
@@ -0,0 +1,75 @@
/dts-v1/;
#include <config.h>
/ {
#address-cells = <1>;
#size-cells = <1>;
model = "sandbox";
aliases {
i2c0 = &i2c_0;
pci0 = &pci;
rtc0 = &rtc_0;
axi0 = &axi;
spi0 = &spi;
};
memory {
reg = <0 CONFIG_SYS_SDRAM_SIZE>;
};
cros_ec: cros-ec {
reg = <0 0>;
u-boot,dm-pre-reloc;
compatible = "google,cros-ec-sandbox";
};
dsi_host: dsi_host {
compatible = "sandbox,dsi-host";
status = "okay";
};
ethrawbus {
compatible = "sandbox,eth-raw-bus";
skip-localhost = <0>;
};
eth@10002000 {
compatible = "sandbox,eth";
reg = <0x10002000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 00];
};
i2c_0: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0>;
compatible = "sandbox,i2c";
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
};
pci: pci-controller {
compatible = "sandbox,pci";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
0x01000000 0 0x20000000 0x20000000 0 0x2000>;
};
spi: spi@0 {
u-boot,dm-pre-reloc;
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0>;
compatible = "sandbox,spi";
cs-gpios = <0>, <&gpio_a 0>;
};
};
#include "sandbox.dtsi"
#include "cros-ec-keyboard.dtsi"
#include "sandbox_pmic.dtsi"
@@ -0,0 +1,369 @@
/*
* This is the common sandbox device-tree nodes. This is shared between sandbox
* and sandbox64 builds.
*/
#define USB_CLASS_HUB 9
/ {
chosen {
stdout-path = "/serial";
};
audio: audio-codec {
compatible = "sandbox,audio-codec";
#sound-dai-cells = <1>;
};
gpio_a: gpios@0 {
u-boot,dm-pre-reloc;
gpio-controller;
compatible = "sandbox,gpio";
#gpio-cells = <1>;
gpio-bank-name = "a";
sandbox,gpio-count = <20>;
};
gpio_b: gpios@1 {
u-boot,dm-pre-reloc;
gpio-controller;
compatible = "sandbox,gpio";
#gpio-cells = <2>;
gpio-bank-name = "b";
sandbox,gpio-count = <10>;
};
hexagon {
compatible = "demo-simple";
colour = "white";
sides = <6>;
};
i2c_0: i2c@0 {
eeprom@2c {
reg = <0x2c>;
compatible = "i2c-eeprom";
sandbox,emul = <&emul_eeprom>;
};
rtc_0: rtc@43 {
reg = <0x43>;
compatible = "sandbox-rtc";
sandbox,emul = <&emul0>;
};
sandbox_pmic: sandbox_pmic {
reg = <0x40>;
};
mc34708: pmic@41 {
reg = <0x41>;
};
i2c_emul: emul {
reg = <0xff>;
compatible = "sandbox,i2c-emul-parent";
emul_eeprom: emul-eeprom {
compatible = "sandbox,i2c-eeprom";
sandbox,filename = "i2c.bin";
sandbox,size = <256>;
};
emul0: emul0 {
compatible = "sandbox,i2c-rtc";
};
};
};
i2s: i2s {
compatible = "sandbox,i2s";
#sound-dai-cells = <1>;
};
lcd {
u-boot,dm-pre-reloc;
compatible = "sandbox,lcd-sdl";
xres = <1366>;
yres = <768>;
};
leds {
compatible = "gpio-leds";
iracibble {
gpios = <&gpio_a 1 0>;
label = "sandbox:red";
};
martinet {
gpios = <&gpio_a 2 0>;
label = "sandbox:green";
};
};
pci-controller {
pci@1f,0 {
compatible = "pci-generic";
reg = <0xf800 0 0 0 0>;
sandbox,emul = <&swap_case_emul>;
};
};
emul {
compatible = "sandbox,pci-emul-parent";
swap_case_emul: emul@1f,0 {
compatible = "sandbox,swap-case";
};
};
pinctrl {
compatible = "sandbox,pinctrl";
status = "okay";
pinctrl_i2c0: i2c0 {
groups = "i2c";
function = "i2c";
bias-pull-up;
};
pinctrl_serial0: uart0 {
groups = "serial_a";
function = "serial";
};
pinctrl_onewire0: onewire0 {
groups = "w1";
function = "w1";
bias-pull-up;
};
};
reset@1 {
compatible = "sandbox,reset";
};
sound {
compatible = "sandbox,sound";
cpu {
sound-dai = <&i2s 0>;
};
codec {
sound-dai = <&audio 0>;
};
};
spi@0 {
firmware_storage_spi: flash@0 {
u-boot,dm-pre-reloc;
reg = <0>;
compatible = "spansion,m25p16", "jedec,spi-nor";
spi-max-frequency = <40000000>;
sandbox,filename = "spi.bin";
};
};
spl-test {
u-boot,dm-pre-reloc;
compatible = "sandbox,spl-test";
boolval;
intval = <1>;
intarray = <2 3 4>;
byteval = [05];
bytearray = [06];
longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
stringval = "message";
stringarray = "multi-word", "message";
};
spl-test2 {
u-boot,dm-pre-reloc;
compatible = "sandbox,spl-test";
intval = <3>;
intarray = <5>;
byteval = [08];
bytearray = [01 23 34];
longbytearray = [09 0a 0b 0c];
stringval = "message2";
stringarray = "another", "multi-word", "message";
};
spl-test3 {
u-boot,dm-pre-reloc;
compatible = "sandbox,spl-test";
stringarray = "one";
};
spl-test4 {
u-boot,dm-pre-reloc;
compatible = "sandbox,spl-test.2";
};
spl-test5 {
u-boot,dm-tpl;
compatible = "sandbox,spl-test";
stringarray = "tpl";
};
spl-test6 {
u-boot,dm-pre-proper;
compatible = "sandbox,spl-test";
stringarray = "pre-proper";
};
spl-test7 {
u-boot,dm-spl;
compatible = "sandbox,spl-test";
stringarray = "spl";
};
square {
compatible = "demo-shape";
colour = "blue";
sides = <4>;
};
timer {
compatible = "sandbox,timer";
clock-frequency = <1000000>;
};
tpm {
u-boot,dm-pre-reloc;
compatible = "google,sandbox-tpm";
};
tpm2 {
compatible = "sandbox,tpm2";
};
triangle {
compatible = "demo-shape";
colour = "cyan";
sides = <3>;
character = <83>;
light-gpios = <&gpio_a 2>, <&gpio_b 6 0>;
};
/* Needs to be available prior to relocation */
uart0: serial {
u-boot,dm-spl;
compatible = "sandbox,serial";
sandbox,text-colour = "cyan";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_serial0>;
};
usb@0 {
compatible = "sandbox,usb";
status = "disabled";
hub {
compatible = "sandbox,usb-hub";
#address-cells = <1>;
#size-cells = <0>;
flash-stick {
reg = <0>;
compatible = "sandbox,usb-flash";
};
};
};
usb@1 {
compatible = "sandbox,usb";
hub {
compatible = "usb-hub";
usb,device-class = <USB_CLASS_HUB>;
hub-emul {
compatible = "sandbox,usb-hub";
#address-cells = <1>;
#size-cells = <0>;
flash-stick {
reg = <0>;
compatible = "sandbox,usb-flash";
sandbox,filepath = "flash.bin";
};
};
};
};
usb@2 {
compatible = "sandbox,usb";
status = "disabled";
};
spmi: spmi@0 {
compatible = "sandbox,spmi";
#address-cells = <0x1>;
#size-cells = <0x1>;
pm8916@0 {
compatible = "qcom,spmi-pmic";
reg = <0x0 0x1>;
#address-cells = <0x1>;
#size-cells = <0x1>;
spmi_gpios: gpios@c000 {
compatible = "qcom,pm8916-gpio";
reg = <0xc000 0x400>;
gpio-controller;
gpio-count = <4>;
#gpio-cells = <2>;
gpio-bank-name="spmi";
};
};
};
axi: axi@0 {
compatible = "sandbox,axi";
#address-cells = <0x1>;
#size-cells = <0x1>;
store@0 {
compatible = "sandbox,sandbox_store";
reg = <0x0 0x400>;
};
};
onewire0: onewire {
compatible = "w1-gpio";
gpios = <&gpio_a 8>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_onewire0>;
status = "okay";
sandbox_eeprom0: sandbox_eeprom@0 {
compatible = "sandbox,w1-eeprom";
status = "okay";
};
};
sandbox_tee {
compatible = "sandbox,tee";
};
};
&cros_ec {
/*
* This describes the flash memory within the EC. Note
* that the STM32L flash erases to 0, not 0xff.
*/
flash {
image-pos = <0x08000000>;
size = <0x20000>;
erase-value = <0>;
/* Information for sandbox */
ro {
image-pos = <0>;
size = <0xf000>;
};
wp-ro {
image-pos = <0xf000>;
size = <0x1000>;
};
rw {
image-pos = <0x10000>;
size = <0x10000>;
};
};
keyboard-controller {
u-boot,dm-pre-reloc;
};
};
@@ -0,0 +1,71 @@
/dts-v1/;
#include <config.h>
/ {
#address-cells = <2>;
#size-cells = <2>;
model = "sandbox";
aliases {
i2c0 = &i2c_0;
pci0 = &pci;
rtc0 = &rtc_0;
axi0 = &axi;
spi0 = &spi;
};
memory {
reg = /bits/ 64 <0 CONFIG_SYS_SDRAM_SIZE>;
};
cros_ec: cros-ec {
reg = <0 0 0 0>;
u-boot,dm-pre-reloc;
compatible = "google,cros-ec-sandbox";
};
ethrawbus {
compatible = "sandbox,eth-raw-bus";
skip-localhost = <1>;
};
eth@10002000 {
compatible = "sandbox,eth";
reg = <0x0 0x10002000 0x0 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 00];
};
i2c_0: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0 0 0>;
compatible = "sandbox,i2c";
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
};
pci: pci-controller {
compatible = "sandbox,pci";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0 0x10000000 0 0x10000000 0 0x2000
0x01000000 0 0x20000000 0 0x20000000 0 0x2000>;
};
spi: spi@0 {
u-boot,dm-pre-reloc;
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0 0 0>;
compatible = "sandbox,spi";
cs-gpios = <0>, <&gpio_a 0>;
};
};
#include "sandbox.dtsi"
#include "cros-ec-keyboard.dtsi"
#include "sandbox_pmic.dtsi"
@@ -0,0 +1,117 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Sandbox PMIC dts node
*
* Copyright (C) 2015 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*/
#include <dt-bindings/pmic/sandbox_pmic.h>
&sandbox_pmic {
compatible = "sandbox,pmic";
buck1 {
regulator-name = "SUPPLY_1.2V";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-min-microamp = <200000>;
regulator-max-microamp = <200000>;
regulator-always-on;
};
buck2: buck2 {
regulator-name = "SUPPLY_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
ldo_1: ldo1 {
regulator-name = "VDD_EMMC_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-min-microamp = <100000>;
regulator-max-microamp = <100000>;
regulator-boot-on;
};
ldo2 {
regulator-name = "VDD_LCD_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
no_match_by_nodename {
regulator-name = "buck_SUPPLY_1.5V";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
};
};
&mc34708 {
compatible = "fsl,mc34708";
};
&i2c_emul {
emul_pmic0: pmic-emul0 {
compatible = "sandbox,i2c-pmic";
/*
* Default PMICs register values are set by macro
* VAL2REG(min, step, value) [uV/uA]
* VAL2OMREG(mode id)
* reg-defaults - byte array
*/
reg-defaults = /bits/ 8 <
/* BUCK1 */
VAL2REG(800000, 25000, 1000000)
VAL2REG(150000, 25000, 150000)
VAL2OMREG(BUCK_OM_OFF)
/* BUCK2 */
VAL2REG(750000, 50000, 3000000)
VAL2REG(150000, 25000, 150000)
VAL2OMREG(0)
/* LDO1 */
VAL2REG(800000, 25000, 1600000)
VAL2REG(100000, 50000, 150000)
VAL2OMREG(LDO_OM_OFF)
/* LDO2 */
VAL2REG(750000, 50000, 3000000)
VAL2REG(150000, 25000, 150000)
VAL2OMREG(0)
/* reg[12:15] - not used */
0x00
0x00
0x00
0x00
>;
};
emul_pmic1: pmic-emul1 {
compatible = "sandbox,i2c-pmic";
reg-defaults = /bits/ 8 <
0x00 0x80 0x08 0xff 0xff 0xff 0x2e 0x01 0x08
0x40 0x80 0x81 0x5f 0xff 0xfb 0x1e 0x80 0x18
0x00 0x00 0x0e 0x00 0x00 0x14 0x00 0x00 0x00
0x00 0x00 0x20 0x00 0x01 0x3a 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x40 0x00 0x00 0x00
0x42 0x21 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x30 0x5f
0x01 0xff 0xff 0x00 0x00 0x00 0x00 0x7f 0xff
0x92 0x49 0x24 0x59 0x6d 0x34 0x18 0xc1 0x8c
0x00 0x60 0x18 0x51 0x48 0x45 0x14 0x51 0x45
0x00 0x06 0x32 0x00 0x00 0x00 0x06 0x9c 0x99
0x00 0x38 0x0a 0x00 0x38 0x0a 0x00 0x38 0x0a
0x00 0x38 0x0a 0x84 0x00 0x00 0x00 0x00 0x00
0x80 0x90 0x8f 0xf8 0x00 0x04 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x01 0x31 0x7e 0x2b 0x03 0xfd 0xc0 0x36 0x1b
0x60 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00
>;
};
};
@@ -0,0 +1,894 @@
/dts-v1/;
/ {
model = "sandbox";
compatible = "sandbox";
#address-cells = <1>;
#size-cells = <1>;
aliases {
console = &uart0;
eth0 = "/eth@10002000";
eth3 = &eth_3;
eth5 = &eth_5;
gpio1 = &gpio_a;
gpio2 = &gpio_b;
i2c0 = "/i2c@0";
mmc0 = "/mmc0";
mmc1 = "/mmc1";
pci0 = &pci0;
pci1 = &pci1;
pci2 = &pci2;
remoteproc1 = &rproc_1;
remoteproc2 = &rproc_2;
rtc0 = &rtc_0;
rtc1 = &rtc_1;
spi0 = "/spi@0";
testfdt6 = "/e-test";
testbus3 = "/some-bus";
testfdt0 = "/some-bus/c-test@0";
testfdt1 = "/some-bus/c-test@1";
testfdt3 = "/b-test";
testfdt5 = "/some-bus/c-test@5";
testfdt8 = "/a-test";
fdt-dummy0 = "/translation-test@8000/dev@0,0";
fdt-dummy1 = "/translation-test@8000/dev@1,100";
fdt-dummy2 = "/translation-test@8000/dev@2,200";
fdt-dummy3 = "/translation-test@8000/noxlatebus@3,300/dev@42";
usb0 = &usb_0;
usb1 = &usb_1;
usb2 = &usb_2;
axi0 = &axi;
osd0 = "/osd";
};
audio: audio-codec {
compatible = "sandbox,audio-codec";
#sound-dai-cells = <1>;
};
cros_ec: cros-ec {
reg = <0 0>;
compatible = "google,cros-ec-sandbox";
/*
* This describes the flash memory within the EC. Note
* that the STM32L flash erases to 0, not 0xff.
*/
flash {
image-pos = <0x08000000>;
size = <0x20000>;
erase-value = <0>;
/* Information for sandbox */
ro {
image-pos = <0>;
size = <0xf000>;
};
wp-ro {
image-pos = <0xf000>;
size = <0x1000>;
};
rw {
image-pos = <0x10000>;
size = <0x10000>;
};
};
};
dsi_host: dsi_host {
compatible = "sandbox,dsi-host";
};
a-test {
reg = <0 1>;
compatible = "denx,u-boot-fdt-test";
ping-expect = <0>;
ping-add = <0>;
u-boot,dm-pre-reloc;
test-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 5 0 3 2 1>,
<0>, <&gpio_a 12>;
test2-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 6 1 3 2 1>,
<&gpio_b 7 2 3 2 1>, <&gpio_b 8 4 3 2 1>,
<&gpio_b 9 0xc 3 2 1>;
int-value = <1234>;
uint-value = <(-1234)>;
};
junk {
reg = <1 1>;
compatible = "not,compatible";
};
no-compatible {
reg = <2 1>;
};
backlight: backlight {
compatible = "pwm-backlight";
enable-gpios = <&gpio_a 1>;
power-supply = <&ldo_1>;
pwms = <&pwm 0 1000>;
default-brightness-level = <5>;
brightness-levels = <0 16 32 64 128 170 202 234 255>;
};
bind-test {
bind-test-child1 {
compatible = "sandbox,phy";
#phy-cells = <1>;
};
bind-test-child2 {
compatible = "simple-bus";
};
};
b-test {
reg = <3 1>;
compatible = "denx,u-boot-fdt-test";
ping-expect = <3>;
ping-add = <3>;
};
phy_provider0: gen_phy@0 {
compatible = "sandbox,phy";
#phy-cells = <1>;
};
phy_provider1: gen_phy@1 {
compatible = "sandbox,phy";
#phy-cells = <0>;
broken;
};
gen_phy_user: gen_phy_user {
compatible = "simple-bus";
phys = <&phy_provider0 0>, <&phy_provider0 1>, <&phy_provider1>;
phy-names = "phy1", "phy2", "phy3";
};
some-bus {
#address-cells = <1>;
#size-cells = <0>;
compatible = "denx,u-boot-test-bus";
reg = <3 1>;
ping-expect = <4>;
ping-add = <4>;
c-test@5 {
compatible = "denx,u-boot-fdt-test";
reg = <5>;
ping-expect = <5>;
ping-add = <5>;
};
c-test@0 {
compatible = "denx,u-boot-fdt-test";
reg = <0>;
ping-expect = <6>;
ping-add = <6>;
};
c-test@1 {
compatible = "denx,u-boot-fdt-test";
reg = <1>;
ping-expect = <7>;
ping-add = <7>;
};
};
d-test {
reg = <3 1>;
ping-expect = <6>;
ping-add = <6>;
compatible = "google,another-fdt-test";
};
e-test {
reg = <3 1>;
ping-expect = <6>;
ping-add = <6>;
compatible = "google,another-fdt-test";
};
f-test {
compatible = "denx,u-boot-fdt-test";
};
g-test {
compatible = "denx,u-boot-fdt-test";
};
h-test {
compatible = "denx,u-boot-fdt-test1";
};
clocks {
clk_fixed: clk-fixed {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1234>;
};
clk_fixed_factor: clk-fixed-factor {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <3>;
clock-mult = <2>;
clocks = <&clk_fixed>;
};
osc {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <20000000>;
};
};
clk_sandbox: clk-sbox {
compatible = "sandbox,clk";
#clock-cells = <1>;
assigned-clocks = <&clk_sandbox 3>;
assigned-clock-rates = <321>;
};
clk-test {
compatible = "sandbox,clk-test";
clocks = <&clk_fixed>,
<&clk_sandbox 1>,
<&clk_sandbox 0>,
<&clk_sandbox 3>,
<&clk_sandbox 2>;
clock-names = "fixed", "i2c", "spi", "uart2", "uart1";
};
ccf: clk-ccf {
compatible = "sandbox,clk-ccf";
};
eth@10002000 {
compatible = "sandbox,eth";
reg = <0x10002000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 00];
};
eth_5: eth@10003000 {
compatible = "sandbox,eth";
reg = <0x10003000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 11];
};
eth_3: sbe5 {
compatible = "sandbox,eth";
reg = <0x10005000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 33];
};
eth@10004000 {
compatible = "sandbox,eth";
reg = <0x10004000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 22];
};
firmware {
sandbox_firmware: sandbox-firmware {
compatible = "sandbox,firmware";
};
};
gpio_a: base-gpios {
compatible = "sandbox,gpio";
gpio-controller;
#gpio-cells = <1>;
gpio-bank-name = "a";
sandbox,gpio-count = <20>;
};
gpio_b: extra-gpios {
compatible = "sandbox,gpio";
gpio-controller;
#gpio-cells = <5>;
gpio-bank-name = "b";
sandbox,gpio-count = <10>;
};
i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0 1>;
compatible = "sandbox,i2c";
clock-frequency = <100000>;
eeprom@2c {
reg = <0x2c>;
compatible = "i2c-eeprom";
sandbox,emul = <&emul_eeprom>;
};
rtc_0: rtc@43 {
reg = <0x43>;
compatible = "sandbox-rtc";
sandbox,emul = <&emul0>;
};
rtc_1: rtc@61 {
reg = <0x61>;
compatible = "sandbox-rtc";
sandbox,emul = <&emul1>;
};
i2c_emul: emul {
reg = <0xff>;
compatible = "sandbox,i2c-emul-parent";
emul_eeprom: emul-eeprom {
compatible = "sandbox,i2c-eeprom";
sandbox,filename = "i2c.bin";
sandbox,size = <256>;
};
emul0: emul0 {
compatible = "sandbox,i2c-rtc";
};
emul1: emull {
compatible = "sandbox,i2c-rtc";
};
};
sandbox_pmic: sandbox_pmic {
reg = <0x40>;
sandbox,emul = <&emul_pmic0>;
};
mc34708: pmic@41 {
reg = <0x41>;
sandbox,emul = <&emul_pmic1>;
};
};
bootcount@0 {
compatible = "u-boot,bootcount-rtc";
rtc = <&rtc_1>;
offset = <0x13>;
};
adc@0 {
compatible = "sandbox,adc";
vdd-supply = <&buck2>;
vss-microvolts = <0>;
};
lcd {
u-boot,dm-pre-reloc;
compatible = "sandbox,lcd-sdl";
xres = <1366>;
yres = <768>;
};
leds {
compatible = "gpio-leds";
iracibble {
gpios = <&gpio_a 1 0>;
label = "sandbox:red";
};
martinet {
gpios = <&gpio_a 2 0>;
label = "sandbox:green";
};
default_on {
gpios = <&gpio_a 5 0>;
label = "sandbox:default_on";
default-state = "on";
};
default_off {
gpios = <&gpio_a 6 0>;
label = "sandbox:default_off";
default-state = "off";
};
};
mbox: mbox {
compatible = "sandbox,mbox";
#mbox-cells = <1>;
};
mbox-test {
compatible = "sandbox,mbox-test";
mboxes = <&mbox 100>, <&mbox 1>;
mbox-names = "other", "test";
};
cpus {
cpu-test1 {
compatible = "sandbox,cpu_sandbox";
u-boot,dm-pre-reloc;
};
cpu-test2 {
compatible = "sandbox,cpu_sandbox";
u-boot,dm-pre-reloc;
};
cpu-test3 {
compatible = "sandbox,cpu_sandbox";
u-boot,dm-pre-reloc;
};
};
i2s: i2s {
compatible = "sandbox,i2s";
#sound-dai-cells = <1>;
sandbox,silent; /* Don't emit sounds while testing */
};
nop-test_0 {
compatible = "sandbox,nop_sandbox1";
nop-test_1 {
compatible = "sandbox,nop_sandbox2";
bind = "True";
};
nop-test_2 {
compatible = "sandbox,nop_sandbox2";
bind = "False";
};
};
misc-test {
compatible = "sandbox,misc_sandbox";
};
mmc2 {
compatible = "sandbox,mmc";
};
mmc1 {
compatible = "sandbox,mmc";
};
mmc0 {
compatible = "sandbox,mmc";
};
pch {
compatible = "sandbox,pch";
};
pci0: pci-controller0 {
compatible = "sandbox,pci";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000000
0x01000000 0 0x20000000 0x20000000 0 0x2000>;
pci@0,0 {
compatible = "pci-generic";
reg = <0x0000 0 0 0 0>;
sandbox,emul = <&swap_case_emul0_0>;
};
pci@1,0 {
compatible = "pci-generic";
/* reg 0 is at 0x14, using FDT_PCI_SPACE_MEM32 */
reg = <0x02000814 0 0 0 0
0x01000810 0 0 0 0>;
sandbox,emul = <&swap_case_emul0_1>;
};
pci@1f,0 {
compatible = "pci-generic";
/* reg 0 is at 0x10, using FDT_PCI_SPACE_IO */
reg = <0x0100f810 0 0 0 0>;
sandbox,emul = <&swap_case_emul0_1f>;
};
};
pci-emul0 {
compatible = "sandbox,pci-emul-parent";
swap_case_emul0_0: emul0@0,0 {
compatible = "sandbox,swap-case";
};
swap_case_emul0_1: emul0@1,0 {
compatible = "sandbox,swap-case";
use-ea;
};
swap_case_emul0_1f: emul0@1f,0 {
compatible = "sandbox,swap-case";
};
};
pci1: pci-controller1 {
compatible = "sandbox,pci";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0 0x30000000 0x30000000 0 0x2000
0x01000000 0 0x40000000 0x40000000 0 0x2000>;
sandbox,dev-info = <0x08 0x00 0x1234 0x5678
0x0c 0x00 0x1234 0x5678
0x10 0x00 0x1234 0x5678>;
pci@10,0 {
reg = <0x8000 0 0 0 0>;
};
};
pci2: pci-controller2 {
compatible = "sandbox,pci";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0 0x50000000 0x50000000 0 0x2000
0x01000000 0 0x60000000 0x60000000 0 0x2000>;
sandbox,dev-info = <0x08 0x00 0x1234 0x5678>;
pci@1f,0 {
compatible = "pci-generic";
reg = <0xf800 0 0 0 0>;
sandbox,emul = <&swap_case_emul2_1f>;
};
};
pci-emul2 {
compatible = "sandbox,pci-emul-parent";
swap_case_emul2_1f: emul2@1f,0 {
compatible = "sandbox,swap-case";
};
};
pci_ep: pci_ep {
compatible = "sandbox,pci_ep";
};
probing {
compatible = "simple-bus";
test1 {
compatible = "denx,u-boot-probe-test";
};
test2 {
compatible = "denx,u-boot-probe-test";
};
test3 {
compatible = "denx,u-boot-probe-test";
};
test4 {
compatible = "denx,u-boot-probe-test";
first-syscon = <&syscon0>;
second-sys-ctrl = <&another_system_controller>;
third-syscon = <&syscon2>;
};
};
pwrdom: power-domain {
compatible = "sandbox,power-domain";
#power-domain-cells = <1>;
};
power-domain-test {
compatible = "sandbox,power-domain-test";
power-domains = <&pwrdom 2>;
};
pwm: pwm {
compatible = "sandbox,pwm";
#pwm-cells = <2>;
};
pwm2 {
compatible = "sandbox,pwm";
#pwm-cells = <2>;
};
ram {
compatible = "sandbox,ram";
};
reset@0 {
compatible = "sandbox,warm-reset";
};
reset@1 {
compatible = "sandbox,reset";
};
resetc: reset-ctl {
compatible = "sandbox,reset-ctl";
#reset-cells = <1>;
};
reset-ctl-test {
compatible = "sandbox,reset-ctl-test";
resets = <&resetc 100>, <&resetc 2>;
reset-names = "other", "test";
};
rproc_1: rproc@1 {
compatible = "sandbox,test-processor";
remoteproc-name = "remoteproc-test-dev1";
};
rproc_2: rproc@2 {
compatible = "sandbox,test-processor";
internal-memory-mapped;
remoteproc-name = "remoteproc-test-dev2";
};
panel {
compatible = "simple-panel";
backlight = <&backlight 0 100>;
};
smem@0 {
compatible = "sandbox,smem";
};
sound {
compatible = "sandbox,sound";
cpu {
sound-dai = <&i2s 0>;
};
codec {
sound-dai = <&audio 0>;
};
};
spi@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0 1>;
compatible = "sandbox,spi";
cs-gpios = <0>, <&gpio_a 0>;
spi.bin@0 {
reg = <0>;
compatible = "spansion,m25p16", "jedec,spi-nor";
spi-max-frequency = <40000000>;
sandbox,filename = "spi.bin";
};
};
syscon0: syscon@0 {
compatible = "sandbox,syscon0";
reg = <0x10 16>;
};
another_system_controller: syscon@1 {
compatible = "sandbox,syscon1";
reg = <0x20 5
0x28 6
0x30 7
0x38 8>;
};
syscon2: syscon@2 {
compatible = "simple-mfd", "syscon";
reg = <0x40 5
0x48 6
0x50 7
0x58 8>;
};
timer {
compatible = "sandbox,timer";
clock-frequency = <1000000>;
};
tpm2 {
compatible = "sandbox,tpm2";
};
uart0: serial {
compatible = "sandbox,serial";
u-boot,dm-pre-reloc;
};
usb_0: usb@0 {
compatible = "sandbox,usb";
status = "disabled";
hub {
compatible = "sandbox,usb-hub";
#address-cells = <1>;
#size-cells = <0>;
flash-stick {
reg = <0>;
compatible = "sandbox,usb-flash";
};
};
};
usb_1: usb@1 {
compatible = "sandbox,usb";
hub {
compatible = "usb-hub";
usb,device-class = <9>;
hub-emul {
compatible = "sandbox,usb-hub";
#address-cells = <1>;
#size-cells = <0>;
flash-stick@0 {
reg = <0>;
compatible = "sandbox,usb-flash";
sandbox,filepath = "testflash.bin";
};
flash-stick@1 {
reg = <1>;
compatible = "sandbox,usb-flash";
sandbox,filepath = "testflash1.bin";
};
flash-stick@2 {
reg = <2>;
compatible = "sandbox,usb-flash";
sandbox,filepath = "testflash2.bin";
};
keyb@3 {
reg = <3>;
compatible = "sandbox,usb-keyb";
};
};
};
};
usb_2: usb@2 {
compatible = "sandbox,usb";
status = "disabled";
};
spmi: spmi@0 {
compatible = "sandbox,spmi";
#address-cells = <0x1>;
#size-cells = <0x1>;
ranges;
pm8916@0 {
compatible = "qcom,spmi-pmic";
reg = <0x0 0x1>;
#address-cells = <0x1>;
#size-cells = <0x1>;
ranges;
spmi_gpios: gpios@c000 {
compatible = "qcom,pm8916-gpio";
reg = <0xc000 0x400>;
gpio-controller;
gpio-count = <4>;
#gpio-cells = <2>;
gpio-bank-name="spmi";
};
};
};
wdt0: wdt@0 {
compatible = "sandbox,wdt";
};
axi: axi@0 {
compatible = "sandbox,axi";
#address-cells = <0x1>;
#size-cells = <0x1>;
store@0 {
compatible = "sandbox,sandbox_store";
reg = <0x0 0x400>;
};
};
chosen {
#address-cells = <1>;
#size-cells = <1>;
chosen-test {
compatible = "denx,u-boot-fdt-test";
reg = <9 1>;
};
};
translation-test@8000 {
compatible = "simple-bus";
reg = <0x8000 0x4000>;
#address-cells = <0x2>;
#size-cells = <0x1>;
ranges = <0 0x0 0x8000 0x1000
1 0x100 0x9000 0x1000
2 0x200 0xA000 0x1000
3 0x300 0xB000 0x1000
>;
dma-ranges = <0 0x000 0x10000000 0x1000
1 0x100 0x20000000 0x1000
>;
dev@0,0 {
compatible = "denx,u-boot-fdt-dummy";
reg = <0 0x0 0x1000>;
reg-names = "sandbox-dummy-0";
};
dev@1,100 {
compatible = "denx,u-boot-fdt-dummy";
reg = <1 0x100 0x1000>;
};
dev@2,200 {
compatible = "denx,u-boot-fdt-dummy";
reg = <2 0x200 0x1000>;
};
noxlatebus@3,300 {
compatible = "simple-bus";
reg = <3 0x300 0x1000>;
#address-cells = <0x1>;
#size-cells = <0x0>;
dev@42 {
compatible = "denx,u-boot-fdt-dummy";
reg = <0x42>;
};
};
};
osd {
compatible = "sandbox,sandbox_osd";
};
board {
compatible = "sandbox,board_sandbox";
};
sandbox_tee {
compatible = "sandbox,tee";
};
sandbox_virtio1 {
compatible = "sandbox,virtio1";
};
sandbox_virtio2 {
compatible = "sandbox,virtio2";
};
pinctrl {
compatible = "sandbox,pinctrl";
};
hwspinlock@0 {
compatible = "sandbox,hwspinlock";
};
dma: dma {
compatible = "sandbox,dma";
#dma-cells = <1>;
dmas = <&dma 0>, <&dma 1>, <&dma 2>;
dma-names = "m2m", "tx0", "rx0";
};
/*
* keep mdio-mux ahead of mdio so that the mux is removed first at the
* end of the test. If parent mdio is removed first, clean-up of the
* mux will trigger a 2nd probe of parent-mdio, leaving parent-mdio
* active at the end of the test. That it turn doesn't allow the mdio
* class to be destroyed, triggering an error.
*/
mdio-mux-test {
compatible = "sandbox,mdio-mux";
#address-cells = <1>;
#size-cells = <0>;
mdio-parent-bus = <&mdio>;
mdio-ch-test@0 {
reg = <0>;
};
mdio-ch-test@1 {
reg = <1>;
};
};
mdio: mdio-test {
compatible = "sandbox,mdio";
};
};
#include "sandbox_pmic.dtsi"
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2018
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
*/
#ifndef __asm_axi_h
#define __asm_axi_h
#define axi_emul_get_ops(dev) ((struct axi_emul_ops *)(dev)->driver->ops)
/**
* axi_sandbox_get_emul() - Retrieve a pointer to a AXI emulation device
* @bus: The AXI bus from which to retrieve a emulation device
* @address: The address of a transfer that should be handled by a emulation
* device
* @length: The data width of a transfer that should be handled by a emulation
* device
* @emulp: Pointer to a buffer receiving the emulation device that handles
* the transfer specified by the address and length parameters
*
* To test the AXI uclass, we implement a simple AXI emulation device, which is
* a virtual device on a AXI bus that exposes a simple storage interface: When
* reading and writing from the device, the addresses are translated to offsets
* within the device's storage. For write accesses the data is written to the
* specified storage offset, and for read accesses the data is read from the
* specified storage offset.
*
* A DTS entry might look like this:
*
* axi: axi@0 {
* compatible = "sandbox,axi";
* #address-cells = <0x1>;
* #size-cells = <0x1>;
* store@0 {
* compatible = "sandbox,sandbox_store";
* reg = <0x0 0x400>;
* };
* };
*
* This function may then be used to retrieve the pointer to the sandbox_store
* emulation device given the AXI bus device, and the data (address, data
* width) of a AXI transfer which should be handled by a emulation device.
*
* Return: 0 of OK, -ENODEV if no device capable of handling the specified
* transfer exists or the device could not be retrieved
*/
int axi_sandbox_get_emul(struct udevice *bus, ulong address, uint length,
struct udevice **emulp);
/**
* axi_get_store() - Get address of internal storage of a emulated AXI device
* @dev: Emulated AXI device to get the pointer of the internal storage
* for.
* @storep: Pointer to the internal storage of the emulated AXI device.
*
* To preset or read back the contents internal storage of the emulated AXI
* device, this function returns the pointer to the storage. Changes to the
* contents of the storage are reflected when using the AXI read/write API
* methods, and vice versa, so by using this method expected read data can be
* set up in advance, and written data can be checked in unit tests.
*
* Return: 0 if OK, -ve on error.
*/
int axi_get_store(struct udevice *dev, u8 **storep);
#endif /* __asm_axi_h */
@@ -0,0 +1,169 @@
/*
* Copyright (c) 2011 The Chromium OS Authors.
*
* Modified from Linux arch/arm/include/asm/bitops.h
*
* 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 <linux/compiler.h>
#include <asm/system.h>
#include <asm-generic/bitops/fls.h>
#include <asm-generic/bitops/__fls.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/__ffs.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 __always_unused 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 __always_unused 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 */
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#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
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#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.
* This is however GCC specific so if we don't have that available
* assume that 16 is large enough.
*/
#ifdef __BIGGEST_ALIGNMENT__
#define ARCH_DMA_MINALIGN __BIGGEST_ALIGNMENT__
#else
#define ARCH_DMA_MINALIGN 16
#endif
#define CONFIG_SYS_CACHELINE_SIZE ARCH_DMA_MINALIGN
#endif /* __SANDBOX_CACHE_H__ */
@@ -0,0 +1,183 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*/
#ifndef __SANDBOX_CLK_H
#define __SANDBOX_CLK_H
#include <common.h>
struct udevice;
/**
* enum sandbox_clk_id - Identity of clocks implemented by the sandbox clock
* provider.
*
* These IDs are within/relative-to the clock provider.
*/
enum sandbox_clk_id {
SANDBOX_CLK_ID_SPI,
SANDBOX_CLK_ID_I2C,
SANDBOX_CLK_ID_UART1,
SANDBOX_CLK_ID_UART2,
SANDBOX_CLK_ID_COUNT,
};
/**
* enum sandbox_clk_test_id - Identity of the clocks consumed by the sandbox
* clock test device.
*
* These are the IDs the clock consumer knows the clocks as.
*/
enum sandbox_clk_test_id {
SANDBOX_CLK_TEST_ID_FIXED,
SANDBOX_CLK_TEST_ID_SPI,
SANDBOX_CLK_TEST_ID_I2C,
SANDBOX_CLK_TEST_ID_DEVM1,
SANDBOX_CLK_TEST_ID_DEVM2,
SANDBOX_CLK_TEST_ID_DEVM_NULL,
SANDBOX_CLK_TEST_ID_COUNT,
};
#define SANDBOX_CLK_TEST_NON_DEVM_COUNT SANDBOX_CLK_TEST_ID_DEVM1
/**
* sandbox_clk_query_rate - Query the current rate of a sandbox clock.
*
* @dev: The sandbox clock provider device.
* @id: The clock to query.
* @return: The rate of the clock.
*/
ulong sandbox_clk_query_rate(struct udevice *dev, int id);
/**
* sandbox_clk_query_enable - Query the enable state of a sandbox clock.
*
* @dev: The sandbox clock provider device.
* @id: The clock to query.
* @return: The rate of the clock.
*/
int sandbox_clk_query_enable(struct udevice *dev, int id);
/**
* sandbox_clk_query_requested - Query the requested state of a sandbox clock.
*
* @dev: The sandbox clock provider device.
* @id: The clock to query.
* @return: The rate of the clock.
*/
int sandbox_clk_query_requested(struct udevice *dev, int id);
/**
* sandbox_clk_test_get - Ask the sandbox clock test device to request its
* clocks.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_get(struct udevice *dev);
/**
* sandbox_clk_test_devm_get - Ask the sandbox clock test device to request its
* clocks using the managed API.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_devm_get(struct udevice *dev);
/**
* sandbox_clk_test_get_bulk - Ask the sandbox clock test device to request its
* clocks with the bulk clk API.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_get_bulk(struct udevice *dev);
/**
* sandbox_clk_test_get_rate - Ask the sandbox clock test device to query a
* clock's rate.
*
* @dev: The sandbox clock test (client) devivce.
* @id: The test device's clock ID to query.
* @return: The rate of the clock.
*/
ulong sandbox_clk_test_get_rate(struct udevice *dev, int id);
/**
* sandbox_clk_test_set_rate - Ask the sandbox clock test device to set a
* clock's rate.
*
* @dev: The sandbox clock test (client) devivce.
* @id: The test device's clock ID to configure.
* @return: The new rate of the clock.
*/
ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate);
/**
* sandbox_clk_test_enable - Ask the sandbox clock test device to enable a
* clock.
*
* @dev: The sandbox clock test (client) devivce.
* @id: The test device's clock ID to configure.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_enable(struct udevice *dev, int id);
/**
* sandbox_clk_test_enable_bulk - Ask the sandbox clock test device to enable
* all clocks in it's clock bulk struct.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_enable_bulk(struct udevice *dev);
/**
* sandbox_clk_test_disable - Ask the sandbox clock test device to disable a
* clock.
*
* @dev: The sandbox clock test (client) devivce.
* @id: The test device's clock ID to configure.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_disable(struct udevice *dev, int id);
/**
* sandbox_clk_test_disable_bulk - Ask the sandbox clock test device to disable
* all clocks in it's clock bulk struct.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_disable_bulk(struct udevice *dev);
/**
* sandbox_clk_test_free - Ask the sandbox clock test device to free its
* clocks.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_free(struct udevice *dev);
/**
* sandbox_clk_test_release_bulk - Ask the sandbox clock test device to release
* all clocks in it's clock bulk struct.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_release_bulk(struct udevice *dev);
/**
* sandbox_clk_test_valid - Ask the sandbox clock test device to check its
* clocks are valid.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
int sandbox_clk_test_valid(struct udevice *dev);
/**
* sandbox_clk_test_valid - Ask the sandbox clock test device to check its
* clocks are valid.
*
* @dev: The sandbox clock test (client) devivce.
* @return: 0 if OK, or a negative error code.
*/
struct clk *sandbox_clk_test_get_devm_clk(struct udevice *dev, int id);
#endif
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#ifndef _ASM_CONFIG_H_
#define _ASM_CONFIG_H_
#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
@@ -0,0 +1,73 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2015 National Instruments
*
* (C) Copyright 2015
* Joe Hershberger <joe.hershberger@ni.com>
*/
#ifndef __ETH_RAW_OS_H
#define __ETH_RAW_OS_H
#define IFNAMSIZ 16
/**
* struct eth_sandbox_raw_priv - raw socket session
*
* sd: socket descriptor - the open socket during a session
* host_ifname: interface name on the host to use for sending our packets
* host_ifindex: interface index number on the host
* device: struct sockaddr_ll - the host interface packets move to/from
* local: 1 or 0 to select the local interface ('lo') or not
* local_bindsd: socket descriptor to prevent the kernel from sending
* a message to the server claiming the port is
* unreachable
* local_bind_udp_port: The UDP port number that we bound to
*/
struct eth_sandbox_raw_priv {
int sd;
char host_ifname[IFNAMSIZ];
unsigned int host_ifindex;
void *device;
int local;
int local_bind_sd;
unsigned short local_bind_udp_port;
};
/* A struct to mimic if_nameindex but that does not depend on Linux headers */
struct sandbox_eth_raw_if_nameindex {
unsigned int if_index; /* Index of interface (1, 2, ...) */
char *if_name; /* Null-terminated name ("eth0", etc.) */
};
/* Enumerate host network interfaces */
struct sandbox_eth_raw_if_nameindex *sandbox_eth_raw_if_nameindex(void);
/* Free the data structure of enumerated network interfaces */
void sandbox_eth_raw_if_freenameindex(struct sandbox_eth_raw_if_nameindex *ptr);
/*
* Check if the interface named "ifname" is a localhost interface or not.
* ifname - the interface name on the host to check
*
* returns - 0 if real interface, 1 if local, negative if error
*/
int sandbox_eth_raw_os_is_local(const char *ifname);
/*
* Look up the name of the interface based on the ifindex populated in priv.
*
* Overwrite the host_ifname member in priv based on looking up host_ifindex
*
* returns - 0 if success, negative if error
*/
int sandbox_eth_raw_os_idx_to_name(struct eth_sandbox_raw_priv *priv);
int sandbox_eth_raw_os_start(struct eth_sandbox_raw_priv *priv,
unsigned char *ethmac);
int sandbox_eth_raw_os_send(void *packet, int length,
struct eth_sandbox_raw_priv *priv);
int sandbox_eth_raw_os_recv(void *packet, int *length,
const struct eth_sandbox_raw_priv *priv);
void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv);
#endif /* __ETH_RAW_OS_H */
@@ -0,0 +1,109 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2015 National Instruments
*
* (C) Copyright 2015
* Joe Hershberger <joe.hershberger@ni.com>
*/
#ifndef __ETH_H
#define __ETH_H
void sandbox_eth_disable_response(int index, bool disable);
void sandbox_eth_skip_timeout(void);
/*
* sandbox_eth_arp_req_to_reply()
*
* Check for an arp request to be sent. If so, inject a reply
*
* @dev: device that received the packet
* @packet: pointer to the received pacaket buffer
* @len: length of received packet
* @return 0 if injected, -EAGAIN if not
*/
int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet,
unsigned int len);
/*
* sandbox_eth_ping_req_to_reply()
*
* Check for a ping request to be sent. If so, inject a reply
*
* @dev: device that received the packet
* @packet: pointer to the received pacaket buffer
* @len: length of received packet
* @return 0 if injected, -EAGAIN if not
*/
int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
unsigned int len);
/*
* sandbox_eth_recv_arp_req()
*
* Inject an ARP request for this target
*
* @dev: device that received the packet
* @return 0 if injected, -EOVERFLOW if not
*/
int sandbox_eth_recv_arp_req(struct udevice *dev);
/*
* sandbox_eth_recv_ping_req()
*
* Inject a ping request for this target
*
* @dev: device that received the packet
* @return 0 if injected, -EOVERFLOW if not
*/
int sandbox_eth_recv_ping_req(struct udevice *dev);
/**
* A packet handler
*
* dev - device pointer
* pkt - pointer to the "sent" packet
* len - packet length
*/
typedef int sandbox_eth_tx_hand_f(struct udevice *dev, void *pkt,
unsigned int len);
/**
* struct eth_sandbox_priv - memory for sandbox mock driver
*
* fake_host_hwaddr - MAC address of mocked machine
* fake_host_ipaddr - IP address of mocked machine
* disabled - Will not respond
* recv_packet_buffer - buffers of the packet returned as received
* recv_packet_length - lengths of the packet returned as received
* recv_packets - number of packets returned
* tx_handler - function to generate responses to sent packets
* priv - a pointer to some structure a test may want to keep track of
*/
struct eth_sandbox_priv {
uchar fake_host_hwaddr[ARP_HLEN];
struct in_addr fake_host_ipaddr;
bool disabled;
uchar * recv_packet_buffer[PKTBUFSRX];
int recv_packet_length[PKTBUFSRX];
int recv_packets;
sandbox_eth_tx_hand_f *tx_handler;
void *priv;
};
/*
* Set packet handler
*
* handler - The func ptr to call on send. If NULL, set to default handler
*/
void sandbox_eth_set_tx_handler(int index, sandbox_eth_tx_hand_f *handler);
/*
* Set priv ptr
*
* priv - priv void ptr to store in the device
*/
void sandbox_eth_set_priv(int index, void *priv);
#endif /* __ETH_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
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*
* (C) Copyright 2002-2010
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#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 */
void *text_base; /* pointer to base of text region */
};
#include <asm-generic/global_data.h>
#define DECLARE_GLOBAL_DATA_PTR extern gd_t *gd
#endif /* __ASM_GBL_DATA_H */
@@ -0,0 +1,85 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* 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.
*/
#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 dev device to use
* @param offset GPIO offset within bank
* @return -1 on error, 0 if GPIO is low, >0 if high
*/
int sandbox_gpio_get_value(struct udevice *dev, unsigned int offset);
/**
* Set the simulated value of a GPIO (used only in sandbox test code)
*
* @param dev device to use
* @param offset GPIO offset within bank
* @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 udevice *dev, unsigned int offset, int value);
/**
* Set or reset the simulated open drain mode of a GPIO (used only in sandbox
* test code)
*
* @param gp GPIO number
* @param value value to set (0 for enabled open drain mode, non-zero for
* disabled)
* @return -1 on error, 0 if ok
*/
int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value);
/**
* Return the state of the simulated open drain mode 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_open_drain(struct udevice *dev, unsigned offset);
/**
* Return the simulated direction of a GPIO (used only in sandbox test code)
*
* @param dev device to use
* @param offset GPIO offset within bank
* @return -1 on error, 0 if GPIO is input, >0 if output
*/
int sandbox_gpio_get_direction(struct udevice *dev, unsigned int offset);
/**
* Set the simulated direction of a GPIO (used only in sandbox test code)
*
* @param dev device to use
* @param offset GPIO offset within bank
* @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 udevice *dev, unsigned int offset,
int output);
#endif
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Architecture-specific SPL handoff information for sandbox
*
* Copyright 2018 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __handoff_h
#define __handoff_h
#define TEST_HANDOFF_MAGIC 0x14f93c7b
struct arch_spl_handoff {
ulong magic; /* Used for testing */
};
#endif
@@ -0,0 +1,233 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#ifndef __SANDBOX_ASM_IO_H
#define __SANDBOX_ASM_IO_H
enum sandboxio_size_t {
SB_SIZE_8,
SB_SIZE_16,
SB_SIZE_32,
SB_SIZE_64,
};
void *phys_to_virt(phys_addr_t paddr);
#define phys_to_virt phys_to_virt
phys_addr_t virt_to_phys(void *vaddr);
#define virt_to_phys virt_to_phys
void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags);
#define map_physmem map_physmem
/*
* Take down a mapping set up by map_physmem().
*/
void unmap_physmem(const void *vaddr, unsigned long flags);
#define unmap_physmem unmap_physmem
#include <asm-generic/io.h>
/* 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);
}
/* Remove a previous mapping */
static inline void unmap_sysmem(const void *vaddr)
{
unmap_physmem(vaddr, MAP_WRBACK);
}
/* Map from a pointer to our RAM buffer */
phys_addr_t map_to_sysmem(const void *ptr);
unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size);
void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size);
#define readb(addr) sandbox_read((const void *)addr, SB_SIZE_8)
#define readw(addr) sandbox_read((const void *)addr, SB_SIZE_16)
#define readl(addr) sandbox_read((const void *)addr, SB_SIZE_32)
#ifdef CONFIG_SANDBOX64
#define readq(addr) sandbox_read((const void *)addr, SB_SIZE_64)
#endif
#define writeb(v, addr) sandbox_write((void *)addr, v, SB_SIZE_8)
#define writew(v, addr) sandbox_write((void *)addr, v, SB_SIZE_16)
#define writel(v, addr) sandbox_write((void *)addr, v, SB_SIZE_32)
#ifdef CONFIG_SANDBOX64
#define writeq(v, addr) sandbox_write((void *)addr, v, SB_SIZE_64)
#endif
/*
* Clear and set bits in one shot. These macros can be used to clear and
* set multiple bits in a register using a single call. These macros can
* also be used to set a multiple-bit bit pattern using a mask, by
* specifying the mask in the 'clear' parameter and the new bit pattern
* in the 'set' parameter.
*/
#define out_arch(type,endian,a,v) write##type(cpu_to_##endian(v),a)
#define in_arch(type,endian,a) endian##_to_cpu(read##type(a))
#define out_le64(a,v) out_arch(q,le64,a,v)
#define out_le32(a,v) out_arch(l,le32,a,v)
#define out_le16(a,v) out_arch(w,le16,a,v)
#define in_le64(a) in_arch(q,le64,a)
#define in_le32(a) in_arch(l,le32,a)
#define in_le16(a) in_arch(w,le16,a)
#define out_be32(a,v) out_arch(l,be32,a,v)
#define out_be16(a,v) out_arch(w,be16,a,v)
#define in_be32(a) in_arch(l,be32,a)
#define in_be16(a) in_arch(w,be16,a)
#define out_8(a,v) writeb(v,a)
#define in_8(a) readb(a)
#define clrbits(type, addr, clear) \
out_##type((addr), in_##type(addr) & ~(clear))
#define setbits(type, addr, set) \
out_##type((addr), in_##type(addr) | (set))
#define clrsetbits(type, addr, clear, set) \
out_##type((addr), (in_##type(addr) & ~(clear)) | (set))
#define clrbits_be32(addr, clear) clrbits(be32, addr, clear)
#define setbits_be32(addr, set) setbits(be32, addr, set)
#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set)
#define clrbits_le32(addr, clear) clrbits(le32, addr, clear)
#define setbits_le32(addr, set) setbits(le32, addr, set)
#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)
#define clrbits_be16(addr, clear) clrbits(be16, addr, clear)
#define setbits_be16(addr, set) setbits(be16, addr, set)
#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set)
#define clrbits_le16(addr, clear) clrbits(le16, addr, clear)
#define setbits_le16(addr, set) setbits(le16, addr, set)
#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set)
#define clrbits_8(addr, clear) clrbits(8, addr, clear)
#define setbits_8(addr, set) setbits(8, addr, set)
#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
/* I/O access functions */
int _inl(unsigned int addr);
int _inw(unsigned int addr);
int _inb(unsigned int addr);
void _outl(unsigned int value, unsigned int addr);
void _outw(unsigned int value, unsigned int addr);
void _outb(unsigned int value, unsigned int addr);
#define inb(port) _inb((uintptr_t)(port))
#define inw(port) _inw((uintptr_t)(port))
#define inl(port) _inl((uintptr_t)(port))
#define outb(val, port) _outb(val, (uintptr_t)(port))
#define outw(val, port) _outw(val, (uintptr_t)(port))
#define outl(val, port) _outl(val, (uintptr_t)(port))
#define out_arch(type,endian,a,v) write##type(cpu_to_##endian(v),a)
#define in_arch(type,endian,a) endian##_to_cpu(read##type(a))
#define out_le32(a,v) out_arch(l,le32,a,v)
#define out_le16(a,v) out_arch(w,le16,a,v)
#define in_le32(a) in_arch(l,le32,a)
#define in_le16(a) in_arch(w,le16,a)
#define out_be32(a,v) out_arch(l,be32,a,v)
#define out_be16(a,v) out_arch(w,be16,a,v)
#define in_be32(a) in_arch(l,be32,a)
#define in_be16(a) in_arch(w,be16,a)
#define out_8(a,v) writeb(v,a)
#define in_8(a) readb(a)
#define clrbits(type, addr, clear) \
out_##type((addr), in_##type(addr) & ~(clear))
#define setbits(type, addr, set) \
out_##type((addr), in_##type(addr) | (set))
#define clrsetbits(type, addr, clear, set) \
out_##type((addr), (in_##type(addr) & ~(clear)) | (set))
#define clrbits_be32(addr, clear) clrbits(be32, addr, clear)
#define setbits_be32(addr, set) setbits(be32, addr, set)
#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set)
#define clrbits_le32(addr, clear) clrbits(le32, addr, clear)
#define setbits_le32(addr, set) setbits(le32, addr, set)
#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)
#define clrbits_be16(addr, clear) clrbits(be16, addr, clear)
#define setbits_be16(addr, set) setbits(be16, addr, set)
#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set)
#define clrbits_le16(addr, clear) clrbits(le16, addr, clear)
#define setbits_le16(addr, set) setbits(le16, addr, set)
#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set)
#define clrbits_8(addr, clear) clrbits(8, addr, clear)
#define setbits_8(addr, set) setbits(8, addr, set)
#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
static inline void _insw(volatile u16 *port, void *buf, int ns)
{
}
static inline void _outsw(volatile u16 *port, const void *buf, int ns)
{
}
static inline void memset_io(volatile void *addr, unsigned char val, int count)
{
}
static inline void memcpy_fromio(void *dst, const volatile void *src, int count)
{
}
static inline void memcpy_toio(volatile void *dst, const void *src, int count)
{
}
#define insw(port, buf, ns) _insw((u16 *)port, buf, ns)
#define outsw(port, buf, ns) _outsw((u16 *)port, buf, ns)
/* IO space accessors */
#define clrio(type, addr, clear) \
out##type(in##type(addr) & ~(clear), (addr))
#define setio(type, addr, set) \
out##type(in##type(addr) | (set), (addr))
#define clrsetio(type, addr, clear, set) \
out##type((in##type(addr) & ~(clear)) | (set), (addr))
#define clrio_32(addr, clear) clrio(l, addr, clear)
#define clrio_16(addr, clear) clrio(w, addr, clear)
#define clrio_8(addr, clear) clrio(b, addr, clear)
#define setio_32(addr, set) setio(l, addr, set)
#define setio_16(addr, set) setio(w, addr, set)
#define setio_8(addr, set) setio(b, addr, set)
#define clrsetio_32(addr, clear, set) clrsetio(l, addr, clear, set)
#define clrsetio_16(addr, clear, set) clrsetio(w, addr, clear, set)
#define clrsetio_8(addr, clear, set) clrsetio(b, addr, clear, set)
#include <iotrace.h>
#include <asm/types.h>
#endif
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*/
#ifndef __SANDBOX_MBOX_H
#define __SANDBOX_MBOX_H
#include <common.h>
#define SANDBOX_MBOX_PING_XOR 0x12345678
struct udevice;
int sandbox_mbox_test_get(struct udevice *dev);
int sandbox_mbox_test_send(struct udevice *dev, uint32_t msg);
int sandbox_mbox_test_recv(struct udevice *dev, uint32_t *msg);
int sandbox_mbox_test_free(struct udevice *dev);
#endif
@@ -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
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*/
#ifndef __SANDBOX_POWER_DOMAIN_H
#define __SANDBOX_POWER_DOMAIN_H
#include <common.h>
struct udevice;
int sandbox_power_domain_query(struct udevice *dev, unsigned long id);
int sandbox_power_domain_test_get(struct udevice *dev);
int sandbox_power_domain_test_on(struct udevice *dev);
int sandbox_power_domain_test_off(struct udevice *dev);
int sandbox_power_domain_test_free(struct udevice *dev);
#endif
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2014 Google, Inc
*/
#ifndef _ASM_PROCESSOR_H
#define _ASM_PROCESSOR_H
/* This file is required for PCI */
#endif
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#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
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*/
#ifndef __SANDBOX_RESET_H
#define __SANDBOX_RESET_H
#include <common.h>
struct udevice;
int sandbox_reset_query(struct udevice *dev, unsigned long id);
int sandbox_reset_test_get(struct udevice *dev);
int sandbox_reset_test_get_bulk(struct udevice *dev);
int sandbox_reset_test_assert(struct udevice *dev);
int sandbox_reset_test_assert_bulk(struct udevice *dev);
int sandbox_reset_test_deassert(struct udevice *dev);
int sandbox_reset_test_deassert_bulk(struct udevice *dev);
int sandbox_reset_test_free(struct udevice *dev);
int sandbox_reset_test_release_bulk(struct udevice *dev);
#endif
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Simulate an I2C real time clock
*
* Copyright (c) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __asm_rtc_h
#define __asm_rtc_h
/* Register numbers in the sandbox RTC */
enum {
REG_SEC = 5,
REG_MIN,
REG_HOUR,
REG_MDAY,
REG_MON,
REG_YEAR,
REG_WDAY,
REG_RESET = 0x20,
REG_COUNT = 0x80,
};
#endif
@@ -0,0 +1,124 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2013 Google, Inc
*/
#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_play() - Play a sound
*
* @data: Data to play (typically 16-bit)
* @count: Number of bytes in data
*/
int sandbox_sdl_sound_play(const void *data, uint count);
/**
* 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
*
* @rate: Sample rate to use
* @channels: Number of channels to use (1=mono, 2=stereo)
* @return 0 if OK, -ENODEV if no sound is available
*/
int sandbox_sdl_sound_init(int rate, int channels);
#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_play(const void *data, uint count)
{
return -ENODEV;
}
static inline int sandbox_sdl_sound_stop(void)
{
return -ENODEV;
}
static inline int sandbox_sdl_sound_init(int rate, int channels)
{
return -ENODEV;
}
#endif
#endif
@@ -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
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) 2018 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef _SETJMP_H_
#define _SETJMP_H_
struct jmp_buf_data {
/*
* We're not sure how long this should be:
*
* amd64: 200 bytes
* arm64: 392 bytes
* armhf: 392 bytes
*
* So allow space for all of those, plus some extra.
* We don't need to worry about 16-byte alignment, since this does not
* run on Windows.
*/
ulong data[128];
};
typedef struct jmp_buf_data jmp_buf[1];
/*
* We have to directly link with the system versions of
* setjmp/longjmp, because setjmp must not return as otherwise
* the stack may become invalid.
*/
int setjmp(jmp_buf jmp);
__noreturn void longjmp(jmp_buf jmp, int ret);
#endif /* _SETJMP_H_ */
@@ -0,0 +1,45 @@
/*
* Simulate a SPI port and clients (see doc/arch/sandbox.rst 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);
};
/*
* 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
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2016 Google, Inc
*/
#ifndef __asm_spl_h
#define __asm_spl_h
#define CONFIG_SPL_BOARD_LOAD_IMAGE
enum {
BOOT_DEVICE_BOARD,
};
#endif
@@ -0,0 +1,277 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011-2012 The Chromium OS Authors.
*/
#ifndef __SANDBOX_STATE_H
#define __SANDBOX_STATE_H
#include <config.h>
#include <sysreset.h>
#include <stdbool.h>
#include <linux/list.h>
#include <linux/stringify.h>
/**
* 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 {
struct udevice *emul;
};
struct sandbox_wdt_info {
unsigned long long counter;
uint reset_count;
bool running;
};
/**
* struct sandbox_mapmem_entry - maps pointers to/from U-Boot addresses
*
* When map_to_sysmem() is called with an address outside sandbox's emulated
* RAM, a record is created with a tag that can be used to reference that
* pointer. When map_sysmem() is called later with that tag, the pointer will
* be returned, just as it would for a normal sandbox address.
*
* @tag: Address tag (a value which U-Boot uses to refer to the address)
* @ptr: Associated pointer for that tag
*/
struct sandbox_mapmem_entry {
ulong tag;
void *ptr;
struct list_head sibling_node;
};
/* The complete state of the test system */
struct sandbox_state {
const char *cmd; /* Command to execute */
bool interactive; /* Enable cmdline after execute */
bool run_distro_boot; /* Automatically run distro bootcommands */
const char *fdt_fname; /* Filename of FDT binary */
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 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 */
bool skip_delays; /* Ignore any time delays (for test) */
bool show_test_output; /* Don't suppress stdout in tests */
int default_log_level; /* Default log level for sandbox */
bool show_of_platdata; /* Show of-platdata in SPL */
bool ram_buf_read; /* true if we read the RAM buffer */
/* Pointer to information for each SPI bus/cs */
struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
[CONFIG_SANDBOX_SPI_MAX_CS];
/* Information about Watchdog */
struct sandbox_wdt_info wdt;
ulong next_tag; /* Next address tag to allocate */
struct list_head mapmem_head; /* struct sandbox_mapmem_entry */
bool hwspinlock; /* Hardware Spinlock status */
bool allow_memio; /* Allow readl() etc. to work */
/*
* This struct is getting large.
*
* Consider putting test data in driver-private structs, like
* sandbox_pch.c.
*
* If you add new members, please put them above this comment.
*/
};
/* 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, \
}
/**
* 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);
/**
* Control skipping of time delays
*
* Some tests have unnecessay time delays (e.g. USB). Allow these to be
* skipped to speed up testing
*
* @param skip_delays true to skip delays from now on, false to honour delay
* requests
*/
void state_set_skip_delays(bool skip_delays);
/**
* See if delays should be skipped
*
* @return true if delays should be skipped, false if they should be honoured
*/
bool state_get_skip_delays(void);
/**
* state_reset_for_test() - Reset ready to re-run tests
*
* This clears out any test state ready for another test run.
*/
void state_reset_for_test(struct sandbox_state *state);
/**
* state_show() - Show information about the sandbox state
*
* @param state Sandbox state to show
*/
void state_show(struct sandbox_state *state);
/**
* 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
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#include <linux/string.h>
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#ifndef __ASM_SANDBOX_SYSTEM_H
#define __ASM_SANDBOX_SYSTEM_H
/* Define this as nops for sandbox architecture */
#define local_irq_save(x)
#define local_irq_enable()
#define local_irq_disable()
#define local_save_flags(x)
#define local_irq_restore(x)
#endif
@@ -0,0 +1,227 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Test-related constants for sandbox
*
* Copyright (c) 2014 Google, Inc
*/
#ifndef __ASM_TEST_H
#define __ASM_TEST_H
/* The sandbox driver always permits an I2C device with this address */
#define SANDBOX_I2C_TEST_ADDR 0x59
#define SANDBOX_PCI_VENDOR_ID 0x1234
#define SANDBOX_PCI_SWAP_CASE_EMUL_ID 0x5678
#define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
#define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
#define PCI_CAP_ID_PM_OFFSET 0x50
#define PCI_CAP_ID_EXP_OFFSET 0x60
#define PCI_CAP_ID_MSIX_OFFSET 0x70
#define PCI_CAP_ID_EA_OFFSET 0x80
#define PCI_EXT_CAP_ID_ERR_OFFSET 0x100
#define PCI_EXT_CAP_ID_VC_OFFSET 0x200
#define PCI_EXT_CAP_ID_DSN_OFFSET 0x300
/* Useful for PCI_VDEVICE() macro */
#define PCI_VENDOR_ID_SANDBOX SANDBOX_PCI_VENDOR_ID
#define SWAP_CASE_DRV_DATA 0x55aa
#define SANDBOX_CLK_RATE 32768
/* Macros used to test PCI EA capability structure */
#define PCI_CAP_EA_BASE_LO0 0x00100000
#define PCI_CAP_EA_BASE_LO1 0x00110000
#define PCI_CAP_EA_BASE_LO2 0x00120000
#define PCI_CAP_EA_BASE_LO4 0x00140000
#define PCI_CAP_EA_BASE_HI2 0x00020000ULL
#define PCI_CAP_EA_BASE_HI4 0x00040000ULL
#define PCI_CAP_EA_SIZE_LO 0x0000ffff
#define PCI_CAP_EA_SIZE_HI 0x00000010ULL
#define PCI_EA_BAR2_MAGIC 0x72727272
#define PCI_EA_BAR4_MAGIC 0x74747474
/* System controller driver data */
enum {
SYSCON0 = 32,
SYSCON1,
SYSCON_COUNT
};
/**
* sandbox_i2c_set_test_mode() - set test mode for running unit tests
*
* See sandbox_i2c_xfer() for the behaviour changes.
*
* @bus: sandbox I2C bus to adjust
* @test_mode: true to select test mode, false to run normally
*/
void sandbox_i2c_set_test_mode(struct udevice *bus, bool test_mode);
enum sandbox_i2c_eeprom_test_mode {
SIE_TEST_MODE_NONE,
/* Permits read/write of only one byte per I2C transaction */
SIE_TEST_MODE_SINGLE_BYTE,
};
void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
enum sandbox_i2c_eeprom_test_mode mode);
void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len);
/**
* sandbox_i2c_rtc_set_offset() - set the time offset from system/base time
*
* @dev: RTC device to adjust
* @use_system_time: true to use system time, false to use @base_time
* @offset: RTC offset from current system/base time (-1 for no
* change)
* @return old value of RTC offset
*/
long sandbox_i2c_rtc_set_offset(struct udevice *dev, bool use_system_time,
int offset);
/**
* sandbox_i2c_rtc_get_set_base_time() - get and set the base time
*
* @dev: RTC device to adjust
* @base_time: New base system time (set to -1 for no change)
* @return old base time
*/
long sandbox_i2c_rtc_get_set_base_time(struct udevice *dev, long base_time);
int sandbox_usb_keyb_add_string(struct udevice *dev, const char *str);
/**
* sandbox_osd_get_mem() - get the internal memory of a sandbox OSD
*
* @dev: OSD device for which to access the internal memory for
* @buf: pointer to buffer to receive the OSD memory data
* @buflen: length of buffer in bytes
*/
int sandbox_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen);
/**
* sandbox_pwm_get_config() - get the PWM config for a channel
*
* @dev: Device to check
* @channel: Channel number to check
* @period_ns: Period of the PWM in nanoseconds
* @duty_ns: Current duty cycle of the PWM in nanoseconds
* @enable: true if the PWM is enabled
* @polarity: true if the PWM polarity is active high
* @return 0 if OK, -ENOSPC if the PWM number is invalid
*/
int sandbox_pwm_get_config(struct udevice *dev, uint channel, uint *period_nsp,
uint *duty_nsp, bool *enablep, bool *polarityp);
/**
* sandbox_sf_set_block_protect() - Set the BP bits of the status register
*
* @dev: Device to update
* @bp_mask: BP bits to set (bits 2:0, so a value of 0 to 7)
*/
void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask);
/**
* sandbox_get_codec_params() - Read back codec parameters
*
* This reads back the parameters set by audio_codec_set_params() for the
* sandbox audio driver. Arguments are as for that function.
*/
void sandbox_get_codec_params(struct udevice *dev, int *interfacep, int *ratep,
int *mclk_freqp, int *bits_per_samplep,
uint *channelsp);
/**
* sandbox_get_i2s_sum() - Read back the sum of the audio data so far
*
* This data is provided to the sandbox driver by the I2S tx_data() method.
*
* @dev: Device to check
* @return sum of audio data
*/
int sandbox_get_i2s_sum(struct udevice *dev);
/**
* sandbox_get_setup_called() - Returns the number of times setup(*) was called
*
* This is used in the sound test
*
* @dev: Device to check
* @return call count for the setup() method
*/
int sandbox_get_setup_called(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.
*
* @dev: Device to check
* @return sum of audio data
*/
int sandbox_get_sound_sum(struct udevice *dev);
/**
* sandbox_set_allow_beep() - Set whether the 'beep' interface is supported
*
* @dev: Device to update
* @allow: true to allow the start_beep() method, false to disallow it
*/
void sandbox_set_allow_beep(struct udevice *dev, bool allow);
/**
* sandbox_get_beep_frequency() - Get the frequency of the current beep
*
* @dev: Device to check
* @return frequency of beep, if there is an active beep, else 0
*/
int sandbox_get_beep_frequency(struct udevice *dev);
/**
* sandbox_get_pch_spi_protect() - Get the PCI SPI protection status
*
* @dev: Device to check
* @return 0 if not protected, 1 if protected
*/
int sandbox_get_pch_spi_protect(struct udevice *dev);
/**
* sandbox_get_pci_ep_irq_count() - Get the PCI EP IRQ count
*
* @dev: Device to check
* @return irq count
*/
int sandbox_get_pci_ep_irq_count(struct udevice *dev);
/**
* sandbox_pci_read_bar() - Read the BAR value for a read_config operation
*
* This is used in PCI emulators to read a base address reset. This has special
* rules because when the register is set to 0xffffffff it can be used to
* discover the type and size of the BAR.
*
* @barval: Current value of the BAR
* @type: Type of BAR (PCI_BASE_ADDRESS_SPACE_IO or
* PCI_BASE_ADDRESS_MEM_TYPE_32)
* @size: Size of BAR in bytes
* @return BAR value to return from emulator
*/
uint sandbox_pci_read_bar(u32 barval, int type, uint size);
/**
* sandbox_set_enable_memio() - Enable readl/writel() for sandbox
*
* Normally these I/O functions do nothing with sandbox. Certain tests need them
* to work as for other architectures, so this function can be used to enable
* them.
*
* @enable: true to enable, false to disable
*/
void sandbox_set_enable_memio(bool enable);
#endif
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#ifndef __ASM_SANDBOX_TYPES_H
#define __ASM_SANDBOX_TYPES_H
#include <asm-generic/int-ll64.h>
typedef unsigned short umode_t;
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
#ifdef __KERNEL__
/*
* Number of bits in a C 'long' on this architecture.
*/
#ifdef CONFIG_PHYS_64BIT
#define BITS_PER_LONG 64
#else /* CONFIG_PHYS_64BIT */
#define BITS_PER_LONG 32
#endif /* CONFIG_PHYS_64BIT */
#ifdef CONFIG_PHYS_64BIT
typedef unsigned long long dma_addr_t;
typedef u64 phys_addr_t;
typedef u64 phys_size_t;
#else /* CONFIG_PHYS_64BIT */
typedef unsigned long dma_addr_t;
typedef u32 phys_addr_t;
typedef u32 phys_size_t;
#endif /* CONFIG_PHYS_64BIT */
#endif /* __KERNEL__ */
#endif
@@ -0,0 +1,90 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* 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>
*/
#ifndef _U_BOOT_SANDBOX_H_
#define _U_BOOT_SANDBOX_H_
/* board/.../... */
int board_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);
struct udevice;
/**
* pci_map_physmem() - map a PCI device into memory
*
* This is used on sandbox to map a device into memory so that it can be
* used with normal memory access. After this call, some part of the device's
* internal structure becomes visible.
*
* This function is normally called from sandbox's map_sysmem() automatically.
*
* @paddr: Physical memory address, normally corresponding to a PCI BAR
* @lenp: On entry, the size of the area to map, On exit it is updated
* to the size actually mapped, which may be less if the device
* has less space
* @devp: Returns the device which mapped into this space
* @ptrp: Returns a pointer to the mapped address. The device's space
* can be accessed as @lenp bytes starting here
* @return 0 if OK, -ve on error
*/
int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
struct udevice **devp, void **ptrp);
/**
* pci_unmap_physmem() - undo a memory mapping
*
* This must be called after pci_map_physmem() to undo the mapping.
*
* @paddr: Physical memory address, as passed to pci_map_physmem()
* @len: Size of area mapped, as returned by pci_map_physmem()
* @dev: Device to unmap, as returned by pci_map_physmem()
* @return 0 if OK, -ve on error
*/
int pci_unmap_physmem(const void *addr, unsigned long len,
struct udevice *dev);
/**
* sandbox_set_enable_pci_map() - Enable / disable PCI address mapping
*
* Since address mapping involves calling every driver, provide a way to
* enable and disable this. It can be handled automatically by the emulator
* uclass, which knows if any emulators are currently active.
*
* If this is disabled, pci_map_physmem() will not be called from
* map_sysmem().
*
* @enable: 0 to disable, 1 to enable
*/
void sandbox_set_enable_pci_map(int enable);
/**
* sandbox_read_fdt_from_file() - Read a device tree from a file
*
* Read a device tree file from a host file and set it up for use as the
* control FDT.
*/
int sandbox_read_fdt_from_file(void);
/* Exit sandbox (quit U-Boot) */
void sandbox_exit(void);
#endif /* _U_BOOT_SANDBOX_H_ */
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (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>
*
********************************************************************
* 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>
#include <asm/u-boot-sandbox.h>
/* For image.h:image_check_target_arch() */
#define IH_ARCH_DEFAULT IH_ARCH_SANDBOX
#endif /* _U_BOOT_H_ */
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#include <asm-generic/unaligned.h>
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2011 The Chromium OS Authors.
#
# (C) Copyright 2002-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
obj-y += interrupts.o sections.o
obj-$(CONFIG_PCI) += pci_io.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2011 The Chromium OS Authors.
* Copyright (c) 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
*/
#include <common.h>
#include <asm/io.h>
#define LINUX_ARM_ZIMAGE_MAGIC 0x016f2818
struct arm_z_header {
uint32_t code[9];
uint32_t zi_magic;
uint32_t zi_start;
uint32_t zi_end;
} __attribute__ ((__packed__));
int bootz_setup(ulong image, ulong *start, ulong *end)
{
uint8_t *zimage = map_sysmem(image, 0);
struct arm_z_header *arm_hdr = (struct arm_z_header *)zimage;
int ret = 0;
if (memcmp(zimage + 0x202, "HdrS", 4) == 0) {
uint8_t setup_sects = *(zimage + 0x1f1);
uint32_t syssize =
le32_to_cpu(*(uint32_t *)(zimage + 0x1f4));
*start = 0;
*end = (setup_sects + 1) * 512 + syssize * 16;
printf("setting up X86 zImage [ %ld - %ld ]\n",
*start, *end);
} else if (le32_to_cpu(arm_hdr->zi_magic) == LINUX_ARM_ZIMAGE_MAGIC) {
*start = le32_to_cpu(arm_hdr->zi_start);
*end = le32_to_cpu(arm_hdr->zi_end);
printf("setting up ARM zImage [ %ld - %ld ]\n",
*start, *end);
} else {
printf("Unrecognized zImage\n");
ret = 1;
}
unmap_sysmem((void *)image);
return ret;
}
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);
printf("sandbox: continuing, as we cannot run Linux\n");
}
return 0;
}
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* PE/COFF header for EFI applications
*
* Copyright (c) 2019 Heinrich Schuchardt
*/
#include <host_arch.h>
#if HOST_ARCH == HOST_ARCH_X86_64
#include "../../../arch/x86/lib/crt0_x86_64_efi.S"
#endif
#if HOST_ARCH == HOST_ARCH_X86
#include "../../../arch/x86/lib/crt0_ia32_efi.S"
#endif
#if HOST_ARCH == HOST_ARCH_AARCH64
#include "../../../arch/arm/lib/crt0_aarch64_efi.S"
#endif
#if HOST_ARCH == HOST_ARCH_ARM
#include "../../../arch/arm/lib/crt0_arm_efi.S"
#endif
#if HOST_ARCH == HOST_ARCH_RISCV32
#include "../../../arch/riscv/lib/crt0_riscv_efi.S"
#endif
#if HOST_ARCH == HOST_ARCH_RISCV64
#include "../../../arch/riscv/lib/crt0_riscv_efi.S"
#endif
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* 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.
*/
#include <common.h>
#include <irq_func.h>
int interrupt_init(void)
{
return 0;
}
void enable_interrupts(void)
{
return;
}
int disable_interrupts(void)
{
return 0;
}
@@ -0,0 +1,137 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2014 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*/
/*
* IO space access commands.
*/
#include <common.h>
#include <command.h>
#include <dm.h>
#include <asm/io.h>
int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
struct udevice **devp, void **ptrp)
{
struct udevice *dev;
int ret;
*ptrp = 0;
for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
dev;
uclass_next_device(&dev)) {
struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
if (!ops || !ops->map_physmem)
continue;
ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
if (ret)
continue;
*devp = dev;
return 0;
}
debug("%s: failed: addr=%pap\n", __func__, &paddr);
return -ENOSYS;
}
int pci_unmap_physmem(const void *vaddr, unsigned long len,
struct udevice *dev)
{
struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
if (!ops || !ops->unmap_physmem)
return -ENOSYS;
return (ops->unmap_physmem)(dev, vaddr, len);
}
static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
{
struct udevice *dev;
int ret;
*valuep = pci_get_ff(size);
for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
dev;
uclass_next_device(&dev)) {
struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
if (ops && ops->read_io) {
ret = (ops->read_io)(dev, addr, valuep, size);
if (!ret)
return 0;
}
}
debug("%s: failed: addr=%x\n", __func__, addr);
return -ENOSYS;
}
static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
{
struct udevice *dev;
int ret;
for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
dev;
uclass_next_device(&dev)) {
struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
if (ops && ops->write_io) {
ret = (ops->write_io)(dev, addr, value, size);
if (!ret)
return 0;
}
}
debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
return -ENOSYS;
}
int _inl(unsigned int addr)
{
unsigned long value;
int ret;
ret = pci_io_read(addr, &value, PCI_SIZE_32);
return ret ? 0 : value;
}
int _inw(unsigned int addr)
{
unsigned long value;
int ret;
ret = pci_io_read(addr, &value, PCI_SIZE_16);
return ret ? 0 : value;
}
int _inb(unsigned int addr)
{
unsigned long value;
int ret;
ret = pci_io_read(addr, &value, PCI_SIZE_8);
return ret ? 0 : value;
}
void _outl(unsigned int value, unsigned int addr)
{
pci_io_write(addr, value, PCI_SIZE_32);
}
void _outw(unsigned int value, unsigned int addr)
{
pci_io_write(addr, value, PCI_SIZE_16);
}
void _outb(unsigned int value, unsigned int addr)
{
pci_io_write(addr, value, PCI_SIZE_8);
}
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* position independent shared object relocator
*
* Copyright (c) 2019 Heinrich Schuchardt
*/
#include <host_arch.h>
#if HOST_ARCH == HOST_ARCH_X86_64
#include "../../../arch/x86/lib/reloc_x86_64_efi.c"
#endif
#if HOST_ARCH == HOST_ARCH_X86
#include "../../../arch/x86/lib/reloc_ia32_efi.c"
#endif
#if HOST_ARCH == HOST_ARCH_AARCH64
#include "../../../arch/arm/lib/reloc_aarch64_efi.c"
#endif
#if HOST_ARCH == HOST_ARCH_ARM
#include "../../../arch/arm/lib/reloc_arm_efi.c"
#endif
#if HOST_ARCH == HOST_ARCH_RISCV32
#include "../../../arch/riscv/lib/reloc_riscv_efi.c"
#endif
#if HOST_ARCH == HOST_ARCH_RISCV64
#include "../../../arch/riscv/lib/reloc_riscv_efi.c"
#endif
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
*
*/
char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start")));
char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop")));
char __efi_runtime_rel_start[0]
__attribute__((section(".__efi_runtime_rel_start")));
char __efi_runtime_rel_stop[0]
__attribute__((section(".__efi_runtime_rel_stop")));