diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/arch/sandbox | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot/arch/sandbox')
72 files changed, 8743 insertions, 0 deletions
diff --git a/roms/u-boot/arch/sandbox/Kconfig b/roms/u-boot/arch/sandbox/Kconfig new file mode 100644 index 000000000..f83282d9d --- /dev/null +++ b/roms/u-boot/arch/sandbox/Kconfig @@ -0,0 +1,68 @@ +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_RAM_SIZE_MB + int "RAM size in MiB" + default 128 + range 64 4095 if !SANDBOX64 + range 64 268435456 if SANDBOX64 + help + Memory size of the sandbox in MiB. The default value is 128 MiB. + The minimum value is 64 MiB. The maximum value is 4095 MiB for the + 32bit sandbox. + +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_CRASH_RESET + bool "Reset on crash" + help + If an illegal instruction or an illegal memory access occurs, the + sandbox by default writes a crash dump and exits. If you set this + flag, the sandbox is reset instead. This may be useful when running + test suites like the UEFI self certification test which continue + with the next test after a crash. + +config SANDBOX_BITS_PER_LONG + int + default 32 if HOST_32BIT + default 64 if HOST_64BIT + +endmenu diff --git a/roms/u-boot/arch/sandbox/Makefile b/roms/u-boot/arch/sandbox/Makefile new file mode 100644 index 000000000..f6cf859f2 --- /dev/null +++ b/roms/u-boot/arch/sandbox/Makefile @@ -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/ diff --git a/roms/u-boot/arch/sandbox/config.mk b/roms/u-boot/arch/sandbox/config.mk new file mode 100644 index 000000000..1f8cb61c8 --- /dev/null +++ b/roms/u-boot/arch/sandbox/config.mk @@ -0,0 +1,65 @@ +# 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 ?= sdl2-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) \ + $(LTO_FINAL_LDFLAGS) \ + -Wl,--whole-archive \ + $(u-boot-main) \ + $(u-boot-keep-syms-lto) \ + -Wl,--no-whole-archive \ + $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map + +cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \ + $(LTO_FINAL_LDFLAGS) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ + -Wl,--whole-archive \ + $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-keep-syms-lto)) \ + -Wl,--no-whole-archive \ + $(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)" diff --git a/roms/u-boot/arch/sandbox/cpu/Makefile b/roms/u-boot/arch/sandbox/cpu/Makefile new file mode 100644 index 000000000..de7fe7f39 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/Makefile @@ -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 := cache.o 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) diff --git a/roms/u-boot/arch/sandbox/cpu/cache.c b/roms/u-boot/arch/sandbox/cpu/cache.c new file mode 100644 index 000000000..46c62c0b4 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/cache.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> + */ + +#include <common.h> +#include <cpu_func.h> +#include <asm/state.h> + +void flush_cache(unsigned long addr, unsigned long size) +{ + /* Clang uses (char *) parameters, GCC (void *) */ + __builtin___clear_cache((void *)addr, (void *)(addr + size)); +} + +void invalidate_icache_all(void) +{ + struct sandbox_state *state = state_get_current(); + + /* Clang uses (char *) parameters, GCC (void *) */ + __builtin___clear_cache((void *)state->ram_buf, + (void *)(state->ram_buf + state->ram_size)); +} diff --git a/roms/u-boot/arch/sandbox/cpu/cpu.c b/roms/u-boot/arch/sandbox/cpu/cpu.c new file mode 100644 index 000000000..48636ab63 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/cpu.c @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2011 The Chromium OS Authors. + */ + +#include <common.h> +#include <bootstage.h> +#include <cpu_func.h> +#include <errno.h> +#include <log.h> +#include <asm/global_data.h> +#include <linux/delay.h> +#include <linux/libfdt.h> +#include <os.h> +#include <asm/io.h> +#include <asm/malloc.h> +#include <asm/setjmp.h> +#include <asm/state.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); + + /* 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; +} diff --git a/roms/u-boot/arch/sandbox/cpu/eth-raw-os.c b/roms/u-boot/arch/sandbox/cpu/eth-raw-os.c new file mode 100644 index 000000000..6a8d80975 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/eth-raw-os.c @@ -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: + os_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 = 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 = 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) + os_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) +{ + free(priv->device); + priv->device = NULL; + os_close(priv->sd); + priv->sd = -1; + if (priv->local) { + if (priv->local_bind_sd != -1) + os_close(priv->local_bind_sd); + priv->local_bind_sd = -1; + priv->local_bind_udp_port = 0; + } +} diff --git a/roms/u-boot/arch/sandbox/cpu/os.c b/roms/u-boot/arch/sandbox/cpu/os.c new file mode 100644 index 000000000..0d21827e1 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/os.c @@ -0,0 +1,956 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2011 The Chromium OS Authors. + */ + +#define _GNU_SOURCE + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <time.h> +#include <ucontext.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <linux/compiler_attributes.h> +#include <linux/types.h> + +#include <asm/getopt.h> +#include <asm/sections.h> +#include <asm/state.h> +#include <os.h> +#include <rtc_def.h> + +/* Environment variable for time offset */ +#define ENV_TIME_OFFSET "UBOOT_SB_TIME_OFFSET" + +/* 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; + /* + * During a cold reset execv() is used to relaunch the U-Boot binary. + * We must ensure that all files are closed in this case. + */ + flags |= O_CLOEXEC; + + return open(pathname, flags, 0777); +} + +int os_close(int fd) +{ + /* Do not close the console input */ + if (fd) + return close(fd); + return -1; +} + +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; + } +} + +static void os_sigint_handler(int sig) +{ + os_fd_restore(); + signal(SIGINT, SIG_DFL); + raise(SIGINT); +} + +static void os_signal_handler(int sig, siginfo_t *info, void *con) +{ + ucontext_t __maybe_unused *context = con; + unsigned long pc; + +#if defined(__x86_64__) + pc = context->uc_mcontext.gregs[REG_RIP]; +#elif defined(__aarch64__) + pc = context->uc_mcontext.pc; +#elif defined(__riscv) + pc = context->uc_mcontext.__gregs[REG_PC]; +#else + const char msg[] = + "\nUnsupported architecture, cannot read program counter\n"; + + os_write(1, msg, sizeof(msg)); + pc = 0; +#endif + + os_signal_action(sig, pc); +} + +int os_setup_signal_handlers(void) +{ + struct sigaction act; + + act.sa_sigaction = os_signal_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO | SA_NODEFER; + if (sigaction(SIGILL, &act, NULL) || + sigaction(SIGBUS, &act, NULL) || + sigaction(SIGSEGV, &act, NULL)) + return -1; + return 0; +} + +/* 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); + signal(SIGINT, os_sigint_handler); +} + +/* + * Provide our own malloc so we don't use space in the sandbox ram_buf for + * allocations that are internal to sandbox, or need to be done before U-Boot's + * malloc() is ready. + */ +void *os_malloc(size_t length) +{ + int page_size = getpagesize(); + struct os_mem_hdr *hdr; + + if (!length) + return NULL; + /* + * 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); + } +} + +/* These macros are from kernel.h but not accessible in this file */ +#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a) - 1) +#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) + +/* + * Provide our own malloc so we don't use space in the sandbox ram_buf for + * allocations that are internal to sandbox, or need to be done before U-Boot's + * malloc() is ready. + */ +void *os_realloc(void *ptr, size_t length) +{ + int page_size = getpagesize(); + struct os_mem_hdr *hdr; + void *new_ptr; + + /* Reallocating a NULL pointer is just an alloc */ + if (!ptr) + return os_malloc(length); + + /* Changing a length to 0 is just a free */ + if (length) { + os_free(ptr); + return NULL; + } + + /* + * If the new size is the same number of pages as the old, nothing to + * do. There isn't much point in shrinking things + */ + hdr = ptr - page_size; + if (ALIGN(length, page_size) <= ALIGN(hdr->length, page_size)) + return ptr; + + /* We have to grow it, so allocate something new */ + new_ptr = os_malloc(length); + memcpy(new_ptr, ptr, hdr->length); + os_free(ptr); + + return new_ptr; +} + +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 + 1)); + 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; + + memset(&long_opts[num_options], '\0', sizeof(*long_opts)); + /* + * walk all of the options the user gave us on the command line, + * figure out what u-boot option structure they belong to (via + * 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, bool delete_it) +{ + 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(); + + argc = 0; + if (delete_it) { + extra_args[argc++] = "-j"; + extra_args[argc++] = (char *)fname; + } + extra_args[argc++] = "-m"; + extra_args[argc++] = mem_fname; + 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; + } + + if (delete_it) + return unlink(fname); + + return -EFAULT; +} + +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, true); +} + +int os_find_u_boot(char *fname, int maxlen, bool use_img) +{ + 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-spl' in the spl/ directory */ + p = strstr(fname, "/spl/"); + 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); + if (use_img) + strcat(p, ".img"); + fd = os_open(fname, O_RDONLY); + if (fd >= 0) { + close(fd); + return 0; + } + } + + return -ENOENT; +} + +int os_spl_to_uboot(const char *fname) +{ + struct sandbox_state *state = state_get_current(); + + /* U-Boot will delete ram buffer after read: "--rm_memory"*/ + state->ram_buf_rm = true; + + return os_jump_to_file(fname, false); +} + +long os_get_time_offset(void) +{ + const char *offset; + + offset = getenv(ENV_TIME_OFFSET); + if (offset) + return strtol(offset, NULL, 0); + return 0; +} + +void os_set_time_offset(long offset) +{ + char buf[21]; + int ret; + + snprintf(buf, sizeof(buf), "%ld", offset); + ret = setenv(ENV_TIME_OFFSET, buf, true); + if (ret) + printf("Could not set environment variable %s\n", + ENV_TIME_OFFSET); +} + +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; +} + +void os_relaunch(char *argv[]) +{ + execv(argv[0], argv); + os_exit(1); +} diff --git a/roms/u-boot/arch/sandbox/cpu/sdl.c b/roms/u-boot/arch/sandbox/cpu/sdl.c new file mode 100644 index 000000000..8102649be --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/sdl.c @@ -0,0 +1,473 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2013 Google, Inc + */ + +#include <errno.h> +#include <unistd.h> +#include <stdbool.h> +#include <linux/input.h> +#include <SDL2/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; +}; + +/** + * struct sdl_info - Information about our use of the SDL library + * + * @width: Width of simulated LCD display + * @height: Height of simulated LCD display + * @vis_width: Visible width (may be larger to allow for scaling up) + * @vis_height: Visible height (may be larger to allow for scaling up) + * @depth: Depth of the display in bits per pixel (16 or 32) + * @pitch: Number of bytes per line of the display + * @sample_rate: Current sample rate for audio + * @audio_active: true if audio can be used + * @inited: true if this module is initialised + * @cur_buf: Current audio buffer being used by sandbox_sdl_fill_audio (0 or 1) + * @buf: The two available audio buffers. SDL can be reading from one while we + * are setting up the next + * @running: true if audio is running + * @stopping: true if audio will stop once it runs out of data + * @texture: SDL texture to use for U-Boot display contents + * @renderer: SDL renderer to use + */ +static struct sdl_info { + int width; + int height; + int vis_width; + int vis_height; + int depth; + int pitch; + uint sample_rate; + bool audio_active; + bool inited; + int cur_buf; + struct buf_info buf[2]; + bool running; + bool stopping; + SDL_Texture *texture; + SDL_Renderer *renderer; +} sdl; + +static void sandbox_sdl_poll_events(void) +{ + /* + * 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(void); + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + puts("LCD window closed - quitting\n"); + reset_cpu(); + break; + } + } +} + +static int sandbox_sdl_ensure_init(void) +{ + if (!sdl.inited) { + if (SDL_Init(0) < 0) { + printf("Unable to initialise 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, + bool double_size) +{ + 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 initialise SDL LCD: %s\n", SDL_GetError()); + return -EPERM; + } + sdl.width = width; + sdl.height = height; + if (double_size) { + sdl.vis_width = sdl.width * 2; + sdl.vis_height = sdl.height * 2; + } else { + sdl.vis_width = sdl.width; + sdl.vis_height = sdl.height; + } + + sdl.depth = 1 << log2_bpp; + sdl.pitch = sdl.width * sdl.depth / 8; + SDL_Window *screen = SDL_CreateWindow("U-Boot", SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + sdl.vis_width, sdl.vis_height, + SDL_WINDOW_RESIZABLE); + if (!screen) { + printf("Unable to initialise SDL screen: %s\n", + SDL_GetError()); + return -EIO; + } + if (log2_bpp != 4 && log2_bpp != 5) { + printf("U-Boot SDL does not support depth %d\n", log2_bpp); + return -EINVAL; + } + sdl.renderer = SDL_CreateRenderer(screen, -1, + SDL_RENDERER_ACCELERATED | + SDL_RENDERER_PRESENTVSYNC); + if (!sdl.renderer) { + printf("Unable to initialise SDL renderer: %s\n", + SDL_GetError()); + return -EIO; + } + + sdl.texture = SDL_CreateTexture(sdl.renderer, log2_bpp == 4 ? + SDL_PIXELFORMAT_RGB565 : + SDL_PIXELFORMAT_RGB888, + SDL_TEXTUREACCESS_STREAMING, + width, height); + if (!sdl.texture) { + printf("Unable to initialise SDL texture: %s\n", + SDL_GetError()); + return -EBADF; + } + sandbox_sdl_poll_events(); + + return 0; +} + +int sandbox_sdl_sync(void *lcd_base) +{ + SDL_UpdateTexture(sdl.texture, NULL, lcd_base, sdl.pitch); + SDL_RenderCopy(sdl.renderer, sdl.texture, NULL, NULL); + SDL_RenderPresent(sdl.renderer); + sandbox_sdl_poll_events(); + + return 0; +} + +static const unsigned short sdl_to_keycode[SDL_NUM_SCANCODES] = { + [SDL_SCANCODE_ESCAPE] = KEY_ESC, + [SDL_SCANCODE_1] = KEY_1, + [SDL_SCANCODE_2] = KEY_2, + [SDL_SCANCODE_3] = KEY_3, + [SDL_SCANCODE_4] = KEY_4, + [SDL_SCANCODE_5] = KEY_5, + [SDL_SCANCODE_6] = KEY_6, + [SDL_SCANCODE_7] = KEY_7, + [SDL_SCANCODE_8] = KEY_8, + [SDL_SCANCODE_9] = KEY_9, + [SDL_SCANCODE_0] = KEY_0, + [SDL_SCANCODE_MINUS] = KEY_MINUS, + [SDL_SCANCODE_EQUALS] = KEY_EQUAL, + [SDL_SCANCODE_BACKSPACE] = KEY_BACKSPACE, + [SDL_SCANCODE_TAB] = KEY_TAB, + [SDL_SCANCODE_Q] = KEY_Q, + [SDL_SCANCODE_W] = KEY_W, + [SDL_SCANCODE_E] = KEY_E, + [SDL_SCANCODE_R] = KEY_R, + [SDL_SCANCODE_T] = KEY_T, + [SDL_SCANCODE_Y] = KEY_Y, + [SDL_SCANCODE_U] = KEY_U, + [SDL_SCANCODE_I] = KEY_I, + [SDL_SCANCODE_O] = KEY_O, + [SDL_SCANCODE_P] = KEY_P, + [SDL_SCANCODE_LEFTBRACKET] = KEY_LEFTBRACE, + [SDL_SCANCODE_RIGHTBRACKET] = KEY_RIGHTBRACE, + [SDL_SCANCODE_RETURN] = KEY_ENTER, + [SDL_SCANCODE_LCTRL] = KEY_LEFTCTRL, + [SDL_SCANCODE_A] = KEY_A, + [SDL_SCANCODE_S] = KEY_S, + [SDL_SCANCODE_D] = KEY_D, + [SDL_SCANCODE_F] = KEY_F, + [SDL_SCANCODE_G] = KEY_G, + [SDL_SCANCODE_H] = KEY_H, + [SDL_SCANCODE_J] = KEY_J, + [SDL_SCANCODE_K] = KEY_K, + [SDL_SCANCODE_L] = KEY_L, + [SDL_SCANCODE_SEMICOLON] = KEY_SEMICOLON, + [SDL_SCANCODE_APOSTROPHE] = KEY_APOSTROPHE, + [SDL_SCANCODE_GRAVE] = KEY_GRAVE, + [SDL_SCANCODE_LSHIFT] = KEY_LEFTSHIFT, + [SDL_SCANCODE_BACKSLASH] = KEY_BACKSLASH, + [SDL_SCANCODE_Z] = KEY_Z, + [SDL_SCANCODE_X] = KEY_X, + [SDL_SCANCODE_C] = KEY_C, + [SDL_SCANCODE_V] = KEY_V, + [SDL_SCANCODE_B] = KEY_B, + [SDL_SCANCODE_N] = KEY_N, + [SDL_SCANCODE_M] = KEY_M, + [SDL_SCANCODE_COMMA] = KEY_COMMA, + [SDL_SCANCODE_PERIOD] = KEY_DOT, + [SDL_SCANCODE_SLASH] = KEY_SLASH, + [SDL_SCANCODE_RSHIFT] = KEY_RIGHTSHIFT, + [SDL_SCANCODE_KP_MULTIPLY] = KEY_KPASTERISK, + [SDL_SCANCODE_LALT] = KEY_LEFTALT, + [SDL_SCANCODE_SPACE] = KEY_SPACE, + [SDL_SCANCODE_CAPSLOCK] = KEY_CAPSLOCK, + [SDL_SCANCODE_F1] = KEY_F1, + [SDL_SCANCODE_F2] = KEY_F2, + [SDL_SCANCODE_F3] = KEY_F3, + [SDL_SCANCODE_F4] = KEY_F4, + [SDL_SCANCODE_F5] = KEY_F5, + [SDL_SCANCODE_F6] = KEY_F6, + [SDL_SCANCODE_F7] = KEY_F7, + [SDL_SCANCODE_F8] = KEY_F8, + [SDL_SCANCODE_F9] = KEY_F9, + [SDL_SCANCODE_F10] = KEY_F10, + [SDL_SCANCODE_NUMLOCKCLEAR] = KEY_NUMLOCK, + [SDL_SCANCODE_SCROLLLOCK] = KEY_SCROLLLOCK, + [SDL_SCANCODE_KP_7] = KEY_KP7, + [SDL_SCANCODE_KP_8] = KEY_KP8, + [SDL_SCANCODE_KP_9] = KEY_KP9, + [SDL_SCANCODE_KP_MINUS] = KEY_KPMINUS, + [SDL_SCANCODE_KP_4] = KEY_KP4, + [SDL_SCANCODE_KP_5] = KEY_KP5, + [SDL_SCANCODE_KP_6] = KEY_KP6, + [SDL_SCANCODE_KP_PLUS] = KEY_KPPLUS, + [SDL_SCANCODE_KP_1] = KEY_KP1, + [SDL_SCANCODE_KP_2] = KEY_KP2, + [SDL_SCANCODE_KP_3] = KEY_KP3, + [SDL_SCANCODE_KP_0] = KEY_KP0, + [SDL_SCANCODE_KP_PERIOD] = KEY_KPDOT, + /* key 84 does not exist linux_input.h */ + [SDL_SCANCODE_LANG5] = KEY_ZENKAKUHANKAKU, + [SDL_SCANCODE_NONUSBACKSLASH] = KEY_102ND, + [SDL_SCANCODE_F11] = KEY_F11, + [SDL_SCANCODE_F12] = KEY_F12, + [SDL_SCANCODE_INTERNATIONAL1] = KEY_RO, + [SDL_SCANCODE_LANG3] = KEY_KATAKANA, + [SDL_SCANCODE_LANG4] = KEY_HIRAGANA, + [SDL_SCANCODE_INTERNATIONAL4] = KEY_HENKAN, + [SDL_SCANCODE_INTERNATIONAL2] = KEY_KATAKANAHIRAGANA, + [SDL_SCANCODE_INTERNATIONAL5] = KEY_MUHENKAN, + /* [SDL_SCANCODE_INTERNATIONAL5] -> [KEY_KPJPCOMMA] */ + [SDL_SCANCODE_KP_ENTER] = KEY_KPENTER, + [SDL_SCANCODE_RCTRL] = KEY_RIGHTCTRL, + [SDL_SCANCODE_KP_DIVIDE] = KEY_KPSLASH, + [SDL_SCANCODE_SYSREQ] = KEY_SYSRQ, + [SDL_SCANCODE_RALT] = KEY_RIGHTALT, + /* KEY_LINEFEED */ + [SDL_SCANCODE_HOME] = KEY_HOME, + [SDL_SCANCODE_UP] = KEY_UP, + [SDL_SCANCODE_PAGEUP] = KEY_PAGEUP, + [SDL_SCANCODE_LEFT] = KEY_LEFT, + [SDL_SCANCODE_RIGHT] = KEY_RIGHT, + [SDL_SCANCODE_END] = KEY_END, + [SDL_SCANCODE_DOWN] = KEY_DOWN, + [SDL_SCANCODE_PAGEDOWN] = KEY_PAGEDOWN, + [SDL_SCANCODE_INSERT] = KEY_INSERT, + [SDL_SCANCODE_DELETE] = KEY_DELETE, + /* KEY_MACRO */ + [SDL_SCANCODE_MUTE] = KEY_MUTE, + [SDL_SCANCODE_VOLUMEDOWN] = KEY_VOLUMEDOWN, + [SDL_SCANCODE_VOLUMEUP] = KEY_VOLUMEUP, + [SDL_SCANCODE_POWER] = KEY_POWER, + [SDL_SCANCODE_KP_EQUALS] = KEY_KPEQUAL, + [SDL_SCANCODE_KP_PLUSMINUS] = KEY_KPPLUSMINUS, + [SDL_SCANCODE_PAUSE] = KEY_PAUSE, + /* KEY_SCALE */ + [SDL_SCANCODE_KP_COMMA] = KEY_KPCOMMA, + [SDL_SCANCODE_LANG1] = KEY_HANGUEL, + [SDL_SCANCODE_LANG2] = KEY_HANJA, + [SDL_SCANCODE_INTERNATIONAL3] = KEY_YEN, + [SDL_SCANCODE_LGUI] = KEY_LEFTMETA, + [SDL_SCANCODE_RGUI] = KEY_RIGHTMETA, + [SDL_SCANCODE_APPLICATION] = KEY_COMPOSE, +}; + +int sandbox_sdl_scan_keys(int key[], int max_keys) +{ + const Uint8 *keystate; + int num_keys; + int i, count; + + sandbox_sdl_poll_events(); + keystate = SDL_GetKeyboardState(&num_keys); + for (i = count = 0; i < num_keys; i++) { + if (count < max_keys && keystate[i]) { + int keycode = sdl_to_keycode[i]; + + if (keycode) + key[count++] = keycode; + } + } + + return count; +} + +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; + bool have_data = false; + 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; + have_data = true; + + 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; + } + sdl.stopping = !have_data; +} + +int sandbox_sdl_sound_init(int rate, int channels) +{ + SDL_AudioSpec wanted, have; + 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 initialise SDL audio: %s\n", SDL_GetError()); + goto err; + } + + /* Open the audio device, forcing the desired format */ + if (SDL_OpenAudio(&wanted, &have) < 0) { + printf("Couldn't open audio: %s\n", SDL_GetError()); + goto err; + } + if (have.format != wanted.format) { + printf("Couldn't select required audio format\n"); + goto err; + } + sdl.audio_active = true; + sdl.sample_rate = wanted.freq; + sdl.cur_buf = 0; + sdl.running = false; + + 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 = true; + sdl.stopping = false; + } + + return 0; +} + +int sandbox_sdl_sound_stop(void) +{ + if (sdl.running) { + while (!sdl.stopping) + SDL_Delay(100); + + SDL_PauseAudio(1); + sdl.running = 0; + sdl.stopping = false; + } + + return 0; +} diff --git a/roms/u-boot/arch/sandbox/cpu/spl.c b/roms/u-boot/arch/sandbox/cpu/spl.c new file mode 100644 index 000000000..f82b0d3de --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/spl.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2016 Google, Inc + */ + +#include <common.h> +#include <dm.h> +#include <hang.h> +#include <init.h> +#include <log.h> +#include <os.h> +#include <spl.h> +#include <asm/global_data.h> +#include <asm/spl.h> +#include <asm/state.h> +#include <test/ut.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), false); + 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(). Allocate this + * outsdide the RAM buffer (i.e. don't use strdup()). + */ + spl_image->arg = os_malloc(strlen(fname) + 1); + if (!spl_image->arg) + return log_msg_ret("exec", -ENOMEM); + strcpy(spl_image->arg, fname); + + 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(); + + preloader_console_init(); + + if (state->run_unittests) { + struct unit_test *tests = UNIT_TEST_ALL_START(); + const int count = UNIT_TEST_ALL_COUNT(); + int ret; + + ret = ut_run_list("spl", NULL, tests, count, + state->select_unittests); + /* continue execution into U-Boot */ + } +} + +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; +} diff --git a/roms/u-boot/arch/sandbox/cpu/start.c b/roms/u-boot/arch/sandbox/cpu/start.c new file mode 100644 index 000000000..6bb94473f --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/start.c @@ -0,0 +1,511 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + */ + +#include <common.h> +#include <command.h> +#include <dm/root.h> +#include <efi_loader.h> +#include <errno.h> +#include <init.h> +#include <log.h> +#include <os.h> +#include <cli.h> +#include <sort.h> +#include <asm/getopt.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/malloc.h> +#include <asm/sections.h> +#include <asm/state.h> +#include <linux/ctype.h> + +DECLARE_GLOBAL_DATA_PTR; + +static char **os_argv; + +/* Compare two options so that they can be sorted into alphabetical order */ +static int h_compare_opt(const void *p1, const void *p2) +{ + const struct sandbox_cmdline_option *opt1 = p1; + const struct sandbox_cmdline_option *opt2 = p2; + const char *str1, *str2; + char flag1[2], flag2[2]; + + opt1 = *(struct sandbox_cmdline_option **)p1; + opt2 = *(struct sandbox_cmdline_option **)p2; + flag1[1] = '\0'; + flag2[1] = '\0'; + + *flag1 = opt1->flag_short < 0x100 ? opt1->flag_short : '\0'; + *flag2 = opt2->flag_short < 0x100 ? opt2->flag_short : '\0'; + + str1 = *flag1 ? flag1 : opt1->flag; + str2 = *flag2 ? flag2 : opt2->flag; + + /* + * Force lower-case flags to come before upper-case ones. We only + * support upper-case for short flags. + */ + if (isalpha(*str1) && isalpha(*str2) && + tolower(*str1) == tolower(*str2)) + return isupper(*str1) - isupper(*str2); + + return strcasecmp(str1, str2); +} + +int sandbox_early_getopt_check(void) +{ + struct sandbox_state *state = state_get_current(); + 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; + struct sandbox_cmdline_option **sorted_opt; + int size; + + /* 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; + + /* Sort the options */ + size = sizeof(*sorted_opt) * num_options; + sorted_opt = os_malloc(size); + if (!sorted_opt) { + printf("No memory to sort options\n"); + os_exit(1); + } + memcpy(sorted_opt, sb_opt, size); + qsort(sorted_opt, num_options, sizeof(*sorted_opt), h_compare_opt); + + for (i = 0; i < num_options; ++i) { + struct sandbox_cmdline_option *opt = sorted_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); + 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 int sandbox_cmdline_cb_double_lcd(struct sandbox_state *state, + const char *arg) +{ + state->double_lcd = true; + + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(double_lcd, 'K', 0, + "Double the LCD display size in each direction"); + +static const char *term_args[STATE_TERM_COUNT] = { + "raw-with-sigs", + "raw", + "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_unittests(struct sandbox_state *state, + const char *arg) +{ + state->run_unittests = true; + + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(unittests, 'u', 0, "Run unit tests"); + +static int sandbox_cmdline_cb_select_unittests(struct sandbox_state *state, + const char *arg) +{ + state->select_unittests = arg; + + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(select_unittests, 'k', 1, "Select unit tests to run"); + +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"); +} + +void __efi_runtime EFIAPI efi_reset_system( + enum efi_reset_type reset_type, + efi_status_t reset_status, + unsigned long data_size, void *reset_data) +{ + os_fd_restore(); + os_relaunch(os_argv); +} + +void sandbox_reset(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); + + /* Restart U-Boot */ + os_relaunch(os_argv); +} + +int main(int argc, char *argv[]) +{ + struct sandbox_state *state; + void * text_base; + gd_t data; + int size; + int ret; + + text_base = os_find_text_base(); + + /* + * Copy argv[] so that we can pass the arguments in the original + * sequence when resetting the sandbox. + */ + size = sizeof(char *) * (argc + 1); + os_argv = os_malloc(size); + if (!os_argv) + os_exit(1); + memcpy(os_argv, argv, size); + + memset(&data, '\0', sizeof(data)); + gd = &data; + gd->arch.text_base = text_base; + + ret = state_init(); + if (ret) + goto err; + + state = state_get_current(); + if (os_parse_args(state, argc, argv)) + return 1; + + /* Remove old memory file if required */ + if (state->ram_buf_rm && state->ram_buf_fname) { + os_unlink(state->ram_buf_fname); + state->write_ram_buf = false; + state->ram_buf_fname = NULL; + } + + ret = sandbox_read_state(state, state->state_fname); + if (ret) + goto err; + + ret = os_setup_signal_handlers(); + 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; + + /* sandbox test: log functions called before log_init in board_init_f */ + log_debug("debug: %s\n", __func__); + + /* Do pre- and post-relocation init */ + board_init_f(0); + + board_init_r(gd->new_gd, 0); + + /* NOTREACHED - board_init_r() does not return */ + return 0; + +err: + printf("Error %d\n", ret); + return 1; +} diff --git a/roms/u-boot/arch/sandbox/cpu/state.c b/roms/u-boot/arch/sandbox/cpu/state.c new file mode 100644 index 000000000..f63cfd38e --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/state.c @@ -0,0 +1,432 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + */ + +#include <common.h> +#include <bloblist.h> +#include <errno.h> +#include <fdtdec.h> +#include <log.h> +#include <os.h> +#include <asm/malloc.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_bytes; + void *buf; + int ret; + + used = fdt_off_dt_strings(blob) + fdt_size_dt_strings(blob); + size = fdt_totalsize(blob); + free_bytes = size - used; + if (free_bytes > 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; + state->sysreset_allowed[SYSRESET_COLD] = true; + state->allow_memio = false; + + 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); + if (!state->ram_buf) { + printf("Out of memory\n"); + os_exit(1); + } + + 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; + + log_info("Writing sandbox state\n"); + state = &main_state; + + /* Finish the bloblist, so that it is correct before writing memory */ + bloblist_finish(); + + 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; + } + } + + /* Delete this at the last moment so as not to upset gdb too much */ + if (state->jumped_fname) + os_unlink(state->jumped_fname); + + os_free(state->state_fdt); + os_free(state->ram_buf); + memset(state, '\0', sizeof(*state)); + + return 0; +} diff --git a/roms/u-boot/arch/sandbox/cpu/u-boot-spl.lds b/roms/u-boot/arch/sandbox/cpu/u-boot-spl.lds new file mode 100644 index 000000000..6754f4ef6 --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/u-boot-spl.lds @@ -0,0 +1,31 @@ +/* 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*))); + } + + /* Private data for devices with OF_PLATDATA_RT */ + . = ALIGN(4); + .priv_data : { + __priv_data_start = .; + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.priv_data*))) + __priv_data_end = .; + } + + _u_boot_sandbox_getopt : { + *(.u_boot_sandbox_getopt_start) + KEEP(*(.u_boot_sandbox_getopt)) + *(.u_boot_sandbox_getopt_end) + } +} + +INSERT AFTER .data; diff --git a/roms/u-boot/arch/sandbox/cpu/u-boot.lds b/roms/u-boot/arch/sandbox/cpu/u-boot.lds new file mode 100644 index 000000000..6d710618f --- /dev/null +++ b/roms/u-boot/arch/sandbox/cpu/u-boot.lds @@ -0,0 +1,58 @@ +/* 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_getopt : { + *(.u_boot_sandbox_getopt_start) + *(.u_boot_sandbox_getopt) + *(.u_boot_sandbox_getopt_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) + } + + .dynsym : + { + __dyn_sym_start = .; + *(.dynsym) + __dyn_sym_end = .; + } +} + +INSERT BEFORE .data; diff --git a/roms/u-boot/arch/sandbox/dts/Makefile b/roms/u-boot/arch/sandbox/dts/Makefile new file mode 100644 index 000000000..3e5dc67d5 --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/Makefile @@ -0,0 +1,19 @@ +# 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 +dtb-$(CONFIG_CMD_EXTENSION) += overlay0.dtbo overlay1.dtbo + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb diff --git a/roms/u-boot/arch/sandbox/dts/cros-ec-keyboard.dtsi b/roms/u-boot/arch/sandbox/dts/cros-ec-keyboard.dtsi new file mode 100644 index 000000000..d885a5ecd --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/cros-ec-keyboard.dtsi @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Keyboard dts fragment for devices that use cros-ec-keyboard + * + * Copyright (c) 2014 Google, Inc + * + * This file is taken from Linux + * arch/arm/boot/dts/cros-ec-keyboard.dtsi. + * + * A duplicate KEY_BACKSLASH key had to be removed. + */ + +#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, 0x05, KEY_RO) + 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(0x01, 0x0c, KEY_HENKAN) + + 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(0x02, 0x0a, KEY_YEN) + + 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, 0x09, KEY_F13) + MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH) + MATRIX_KEY(0x03, 0x0c, KEY_MUHENKAN) + + 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) + /* + * Do not map any key twice + * 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) + >; + }; +}; diff --git a/roms/u-boot/arch/sandbox/dts/include/dt-bindings b/roms/u-boot/arch/sandbox/dts/include/dt-bindings new file mode 120000 index 000000000..0cecb3d08 --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/include/dt-bindings @@ -0,0 +1 @@ +../../../../include/dt-bindings
\ No newline at end of file diff --git a/roms/u-boot/arch/sandbox/dts/overlay0.dts b/roms/u-boot/arch/sandbox/dts/overlay0.dts new file mode 100644 index 000000000..70c6cf77a --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/overlay0.dts @@ -0,0 +1,9 @@ +/dts-v1/; +/plugin/; + +&{/buttons} { + btn3 { + gpios = <&gpio_a 5 0>; + label = "button3"; + }; +}; diff --git a/roms/u-boot/arch/sandbox/dts/overlay1.dts b/roms/u-boot/arch/sandbox/dts/overlay1.dts new file mode 100644 index 000000000..51621b311 --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/overlay1.dts @@ -0,0 +1,9 @@ +/dts-v1/; +/plugin/; + +&{/buttons} { + btn4 { + gpios = <&gpio_a 5 0>; + label = "button4"; + }; +}; diff --git a/roms/u-boot/arch/sandbox/dts/sandbox.dts b/roms/u-boot/arch/sandbox/dts/sandbox.dts new file mode 100644 index 000000000..a8938a3ac --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/sandbox.dts @@ -0,0 +1,97 @@ +/dts-v1/; + +#include <config.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "sandbox"; + compatible = "sandbox"; + + aliases { + i2c0 = &i2c_0; + pci0 = &pcic; + rtc0 = &rtc_0; + axi0 = &axi; + spi0 = &spi; + }; + + memory { + reg = <0 CONFIG_SYS_SDRAM_SIZE>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + reservation_test0 { + size = <0x4000>; + alignment = <0x2000>; + }; + + reservation_test1: restest@a000 { + reg = <0x00d0a000 0x2000>; + }; + + reservation_test2: restest@7000 { + reg = <0x00d07000 0x1000>; + }; + }; + + cros_ec: cros-ec { + reg = <0 0>; + u-boot,dm-pre-proper; + 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>; + u-boot,dm-pre-reloc; + }; + + pcic: pci@0 { + compatible = "sandbox,pci"; + device_type = "pci"; + bus-range = <0x00 0xff>; + #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-proper; + #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" diff --git a/roms/u-boot/arch/sandbox/dts/sandbox.dtsi b/roms/u-boot/arch/sandbox/dts/sandbox.dtsi new file mode 100644 index 000000000..31db50db3 --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/sandbox.dtsi @@ -0,0 +1,427 @@ +/* + * 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>; + }; + + buttons { + compatible = "gpio-keys"; + + btn1 { + gpios = <&gpio_a 3 0>; + label = "button1"; + }; + + btn2 { + gpios = <&gpio_a 4 0>; + label = "button2"; + }; + }; + + clk_fixed: clk-fixed { + u-boot,dm-pre-reloc; + compatible = "sandbox,fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1234>; + }; + + clk_sandbox: clk-sbox { + u-boot,dm-pre-reloc; + compatible = "sandbox,clk"; + #clock-cells = <1>; + assigned-clocks = <&clk_sandbox 3>; + assigned-clock-rates = <321>; + }; + + clk-test { + u-boot,dm-pre-reloc; + 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"; + }; + + gpio_a: gpios@0 { + u-boot,dm-pre-proper; + gpio-controller; + compatible = "sandbox,gpio"; + #gpio-cells = <1>; + gpio-bank-name = "a"; + sandbox,gpio-count = <20>; + }; + + gpio_b: gpios@1 { + u-boot,dm-pre-proper; + 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>; + u-boot,dm-pre-reloc; + }; + sandbox_pmic: sandbox_pmic { + reg = <0x40>; + }; + + mc34708: pmic@41 { + reg = <0x41>; + }; + + i2c_emul: emul { + u-boot,dm-pre-reloc; + reg = <0xff>; + compatible = "sandbox,i2c-emul-parent"; + emul_eeprom: emul-eeprom { + compatible = "sandbox,i2c-eeprom"; + sandbox,filename = "i2c.bin"; + sandbox,size = <256>; + #emul-cells = <0>; + }; + emul0: emul0 { + u-boot,dm-pre-reloc; + compatible = "sandbox,i2c-rtc-emul"; + #emul-cells = <0>; + }; + }; + }; + + i2s: i2s { + compatible = "sandbox,i2s"; + #sound-dai-cells = <1>; + }; + + lcd { + u-boot,dm-pre-proper; + compatible = "sandbox,lcd-sdl"; + xres = <1366>; + yres = <768>; + log2-depth = <5>; + }; + + leds { + compatible = "gpio-leds"; + + iracibble { + gpios = <&gpio_a 1 0>; + label = "sandbox:red"; + }; + + martinet { + gpios = <&gpio_a 2 0>; + label = "sandbox:green"; + }; + }; + + pci@0 { + pci@1e,0 { + compatible = "sandbox,pmc"; + reg = <0xf000 0 0 0 0>; + sandbox,emul = <&pmc_emul>; + gpe0-dwx-mask = <0xf>; + gpe0-dwx-shift-base = <4>; + gpe0-dw = <6 7 9>; + gpe0-sts = <0x20>; + gpe0-en = <0x30>; + }; + + pci@1f,0 { + compatible = "pci-generic"; + reg = <0xf800 0 0 0 0>; + sandbox,emul = <&swap_case_emul>; + }; + }; + + emul { + compatible = "sandbox,pci-emul-parent"; + pmc_emul: emul@1e,0 { + compatible = "sandbox,pmc-emul"; + }; + 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"; + }; + + rng { + compatible = "sandbox,sandbox-rng"; + }; + + 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-proper; + 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-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 { + 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-proper; + }; +}; diff --git a/roms/u-boot/arch/sandbox/dts/sandbox64.dts b/roms/u-boot/arch/sandbox/dts/sandbox64.dts new file mode 100644 index 000000000..a39f94fee --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/sandbox64.dts @@ -0,0 +1,93 @@ +/dts-v1/; + +#include <config.h> + +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "sandbox"; + compatible = "sandbox"; + + aliases { + i2c0 = &i2c_0; + pci0 = &pcic; + rtc0 = &rtc_0; + axi0 = &axi; + spi0 = &spi; + }; + + memory { + reg = /bits/ 64 <0 CONFIG_SYS_SDRAM_SIZE>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + reservation_test_size { + size = <0 0x4000>; + alignment = <0 0x2000>; + }; + + reservation_test@a000 { + reg = <0 0x00d0a000 0 0x2000>; + }; + + reservation_test@7000 { + reg = <0 0x00d07000 0 0x1000>; + }; + }; + + /* ... */ + 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>; + }; + + pcic: pci@0 { + compatible = "sandbox,pci"; + device_type = "pci"; + bus-range = <0x00 0xff>; + #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" diff --git a/roms/u-boot/arch/sandbox/dts/sandbox_pmic.dtsi b/roms/u-boot/arch/sandbox/dts/sandbox_pmic.dtsi new file mode 100644 index 000000000..565c382ed --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/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 + >; + }; +}; diff --git a/roms/u-boot/arch/sandbox/dts/test.dts b/roms/u-boot/arch/sandbox/dts/test.dts new file mode 100644 index 000000000..8e7eaf2d1 --- /dev/null +++ b/roms/u-boot/arch/sandbox/dts/test.dts @@ -0,0 +1,1537 @@ +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/gpio/sandbox-gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/pinctrl/sandbox-pinmux.h> +#include <dt-bindings/mux/mux.h> + +/ { + model = "sandbox"; + compatible = "sandbox"; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + console = &uart0; + ethernet0 = "/eth@10002000"; + ethernet2 = &swp_0; + ethernet3 = ð_3; + ethernet4 = &dsa_eth0; + ethernet5 = ð_5; + gpio1 = &gpio_a; + gpio2 = &gpio_b; + gpio3 = &gpio_c; + i2c0 = "/i2c@0"; + mmc0 = "/mmc0"; + mmc1 = "/mmc1"; + pci0 = &pci0; + pci1 = &pci1; + pci2 = &pci2; + remoteproc0 = &rproc_1; + remoteproc1 = &rproc_2; + rtc0 = &rtc_0; + rtc1 = &rtc_1; + spi0 = "/spi@0"; + testfdt6 = "/e-test"; + testbus3 = "/some-bus"; + testfdt0 = "/some-bus/c-test@0"; + testfdt12 = "/some-bus/c-test@1"; + testfdt3 = "/b-test"; + testfdt5 = "/some-bus/c-test@5"; + testfdt8 = "/a-test"; + testfdtm1 = &testfdtm1; + 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"; + }; + + config { + environment { + from_fdt = "yes"; + fdt_env_path = ""; + }; + }; + + audio: audio-codec { + compatible = "sandbox,audio-codec"; + #sound-dai-cells = <1>; + }; + + buttons { + compatible = "gpio-keys"; + + btn1 { + gpios = <&gpio_a 3 0>; + label = "button1"; + }; + + btn2 { + gpios = <&gpio_a 4 0>; + label = "button2"; + }; + }; + + buttons2 { + compatible = "adc-keys"; + io-channels = <&adc 3>; + keyup-threshold-microvolt = <3000000>; + + button-up { + label = "button3"; + linux,code = <KEY_F3>; + press-threshold-microvolt = <1500000>; + }; + + button-down { + label = "button4"; + linux,code = <KEY_F4>; + press-threshold-microvolt = <1000000>; + }; + + button-enter { + label = "button5"; + linux,code = <KEY_F5>; + press-threshold-microvolt = <500000>; + }; + }; + + 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>; + used = <0x884>; + compress = "lz4"; + uncomp-size = <0xcf8>; + hash { + algo = "sha256"; + value = [00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f + 10 11 12 13 14 15 16 17 + 18 19 1a 1b 1c 1d 1e 1f]; + }; + }; + 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 GPIO_ACTIVE_HIGH 3 2 1>, + <0>, <&gpio_a 12>; + test2-gpios = <&gpio_a 1>, <&gpio_a 4>, + <&gpio_b 6 GPIO_ACTIVE_LOW 3 2 1>, + <&gpio_b 7 GPIO_IN 3 2 1>, + <&gpio_b 8 GPIO_OUT 3 2 1>, + <&gpio_b 9 (GPIO_OUT|GPIO_OUT_ACTIVE) 3 2 1>; + test3-gpios = + <&gpio_c 0 (GPIO_OUT|GPIO_OPEN_DRAIN)>, + <&gpio_c 1 (GPIO_OUT|GPIO_OPEN_SOURCE)>, + <&gpio_c 2 GPIO_OUT>, + <&gpio_c 3 (GPIO_IN|GPIO_PULL_UP)>, + <&gpio_c 4 (GPIO_IN|GPIO_PULL_DOWN)>, + <&gpio_c 5 GPIO_IN>, + <&gpio_c 6 (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN)>, + <&gpio_c 7 (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_SOURCE)>; + test4-gpios = <&gpio_a 14>, <&gpio_b 4 1 3 2 1>; + test5-gpios = <&gpio_a 19>; + + int-value = <1234>; + uint-value = <(-1234)>; + int64-value = /bits/ 64 <0x1111222233334444>; + int-array = <5678 9123 4567>; + str-value = "test string"; + interrupts-extended = <&irq 3 0>; + acpi,name = "GHIJ"; + phandle-value = <&gpio_c 10>, <0xFFFFFFFF 20>, <&gpio_a 30>; + + mux-controls = <&muxcontroller0 0>, <&muxcontroller0 1>, + <&muxcontroller0 2>, <&muxcontroller0 3>, + <&muxcontroller1>; + mux-control-names = "mux0", "mux1", "mux2", "mux3", "mux4"; + mux-syscon = <&syscon3>; + display-timings { + timing0: 240x320 { + clock-frequency = <6500000>; + hactive = <240>; + vactive = <320>; + hfront-porch = <6>; + hback-porch = <7>; + hsync-len = <1>; + vback-porch = <5>; + vfront-porch = <8>; + vsync-len = <2>; + hsync-active = <1>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + interlaced; + doublescan; + doubleclk; + }; + timing1: 480x800 { + clock-frequency = <9000000>; + hactive = <480>; + vactive = <800>; + hfront-porch = <10>; + hback-porch = <59>; + hsync-len = <12>; + vback-porch = <15>; + vfront-porch = <17>; + vsync-len = <16>; + hsync-active = <0>; + vsync-active = <1>; + de-active = <0>; + pixelclk-active = <0>; + }; + timing2: 800x480 { + clock-frequency = <33500000>; + hactive = <800>; + vactive = <480>; + hback-porch = <89>; + hfront-porch = <164>; + vback-porch = <23>; + vfront-porch = <10>; + hsync-len = <11>; + vsync-len = <13>; + }; + }; + }; + + 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 { + compatible = "simple-bus"; + 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>; + + mux-controls = <&muxcontroller0 0>; + mux-control-names = "mux0"; + }; + + phy_provider0: gen_phy@0 { + compatible = "sandbox,phy"; + #phy-cells = <1>; + }; + + phy_provider1: gen_phy@1 { + compatible = "sandbox,phy"; + #phy-cells = <0>; + broken; + }; + + phy_provider2: gen_phy@2 { + compatible = "sandbox,phy"; + #phy-cells = <0>; + }; + + gen_phy_user: gen_phy_user { + compatible = "simple-bus"; + phys = <&phy_provider0 0>, <&phy_provider0 1>, <&phy_provider1>; + phy-names = "phy1", "phy2", "phy3"; + }; + + gen_phy_user1: gen_phy_user1 { + compatible = "simple-bus"; + phys = <&phy_provider0 0>, <&phy_provider2>; + phy-names = "phy1", "phy2"; + }; + + 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"; + }; + + i-test { + compatible = "mediatek,u-boot-fdt-test"; + #address-cells = <1>; + #size-cells = <0>; + + subnode@0 { + reg = <0>; + }; + + subnode@1 { + reg = <1>; + }; + + subnode@2 { + reg = <2>; + }; + }; + + devres-test { + compatible = "denx,u-boot-devres-test"; + }; + + another-test { + reg = <0 2>; + compatible = "denx,u-boot-fdt-test"; + test4-gpios = <&gpio_a 14>, <&gpio_b 4 1 3 2 1>; + test5-gpios = <&gpio_a 19>; + }; + + mmio-bus@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "denx,u-boot-test-bus"; + dma-ranges = <0x10000000 0x00000000 0x00040000>; + + subnode@0 { + compatible = "denx,u-boot-fdt-test"; + }; + }; + + mmio-bus@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "denx,u-boot-test-bus"; + + subnode@0 { + compatible = "denx,u-boot-fdt-test"; + }; + }; + + acpi_test1: acpi-test { + compatible = "denx,u-boot-acpi-test"; + acpi-ssdt-test-data = "ab"; + acpi-dsdt-test-data = "hi"; + child { + compatible = "denx,u-boot-acpi-test"; + }; + }; + + acpi_test2: acpi-test2 { + compatible = "denx,u-boot-acpi-test"; + acpi-ssdt-test-data = "cd"; + acpi-dsdt-test-data = "jk"; + }; + + 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]; + }; + + dsa_eth0: dsa-test-eth { + compatible = "sandbox,eth"; + reg = <0x10006000 0x1000>; + fake-host-hwaddr = [00 00 66 44 22 66]; + }; + + dsa-test { + compatible = "sandbox,dsa"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + swp_0: port@0 { + reg = <0>; + label = "lan0"; + phy-mode = "rgmii-rxid"; + + fixed-link { + speed = <100>; + full-duplex; + }; + }; + + swp_1: port@1 { + reg = <1>; + label = "lan1"; + phy-mode = "rgmii-txid"; + fixed-link = <0 1 100 0 0>; + }; + + port@2 { + reg = <2>; + ethernet = <&dsa_eth0>; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + + firmware { + sandbox_firmware: sandbox-firmware { + compatible = "sandbox,firmware"; + }; + + sandbox-scmi-agent@0 { + compatible = "sandbox,scmi-agent"; + #address-cells = <1>; + #size-cells = <0>; + + clk_scmi0: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + + reset_scmi0: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + + protocol@17 { + reg = <0x17>; + + regulators { + #address-cells = <1>; + #size-cells = <0>; + + regul0_scmi0: reg@0 { + reg = <0>; + regulator-name = "sandbox-voltd0"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <3300000>; + }; + regul1_scmi0: reg@1 { + reg = <0x1>; + regulator-name = "sandbox-voltd1"; + regulator-min-microvolt = <1800000>; + }; + }; + }; + }; + + sandbox-scmi-agent@1 { + compatible = "sandbox,scmi-agent"; + #address-cells = <1>; + #size-cells = <0>; + + clk_scmi1: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + + protocol@10 { + reg = <0x10>; + }; + }; + }; + + pinctrl-gpio { + compatible = "sandbox,pinctrl-gpio"; + + gpio_a: base-gpios { + compatible = "sandbox,gpio"; + gpio-controller; + #gpio-cells = <1>; + gpio-bank-name = "a"; + sandbox,gpio-count = <20>; + hog_input_active_low { + gpio-hog; + input; + gpios = <10 GPIO_ACTIVE_LOW>; + }; + hog_input_active_high { + gpio-hog; + input; + gpios = <11 GPIO_ACTIVE_HIGH>; + }; + hog_output_low { + gpio-hog; + output-low; + gpios = <12 GPIO_ACTIVE_HIGH>; + }; + hog_output_high { + gpio-hog; + output-high; + gpios = <13 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio_b: extra-gpios { + compatible = "sandbox,gpio"; + gpio-controller; + #gpio-cells = <5>; + gpio-bank-name = "b"; + sandbox,gpio-count = <10>; + }; + + gpio_c: pinmux-gpios { + compatible = "sandbox,gpio"; + gpio-controller; + #gpio-cells = <2>; + gpio-bank-name = "c"; + sandbox,gpio-count = <10>; + }; + }; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0 1>; + compatible = "sandbox,i2c"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_i2c0_pins>; + + eeprom@2c { + reg = <0x2c>; + compatible = "i2c-eeprom"; + sandbox,emul = <&emul_eeprom>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + bootcount_i2c: bootcount@10 { + reg = <10 2>; + }; + }; + }; + + 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-emul"; + }; + emul1: emull { + compatible = "sandbox,i2c-rtc-emul"; + }; + }; + + 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>; + }; + + bootcount { + compatible = "u-boot,bootcount-i2c-eeprom"; + i2c-eeprom = <&bootcount_i2c>; + }; + + adc: adc@0 { + compatible = "sandbox,adc"; + #io-channel-cells = <1>; + vdd-supply = <&buck2>; + vss-microvolts = <0>; + }; + + irq: irq { + compatible = "sandbox,irq"; + interrupt-controller; + #interrupt-cells = <2>; + }; + + lcd { + u-boot,dm-pre-reloc; + compatible = "sandbox,lcd-sdl"; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_lcd_pins>; + 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 intentionally omitted */ + 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 { + timebase-frequency = <2000000>; + cpu-test1 { + timebase-frequency = <3000000>; + 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; + }; + }; + + chipid: chipid { + compatible = "sandbox,soc"; + }; + + 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@0 { + compatible = "sandbox,pci"; + device_type = "pci"; + bus-range = <0x00 0xff>; + #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>; + }; + p2sb-pci@2,0 { + compatible = "sandbox,p2sb"; + reg = <0x02001010 0 0 0 0>; + sandbox,emul = <&p2sb_emul>; + + adder { + intel,p2sb-port-id = <3>; + compatible = "sandbox,adder"; + }; + }; + pci@1e,0 { + compatible = "sandbox,pmc"; + reg = <0xf000 0 0 0 0>; + sandbox,emul = <&pmc_emul1e>; + acpi-base = <0x400>; + gpe0-dwx-mask = <0xf>; + gpe0-dwx-shift-base = <4>; + gpe0-dw = <6 7 9>; + gpe0-sts = <0x20>; + gpe0-en = <0x30>; + }; + 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"; + }; + p2sb_emul: emul@2,0 { + compatible = "sandbox,p2sb-emul"; + }; + pmc_emul1e: emul@1e,0 { + compatible = "sandbox,pmc-emul"; + }; + }; + + pci1: pci@1 { + compatible = "sandbox,pci"; + device_type = "pci"; + bus-range = <0x00 0xff>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x02000000 0 0x30000000 0x30000000 0 0x2000 // MEM0 + 0x02000000 0 0x31000000 0x31000000 0 0x2000 // MEM1 + 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@2 { + compatible = "sandbox,pci"; + device_type = "pci"; + bus-range = <0x00 0xff>; + #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>; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_pwm_pins>; + }; + + 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>, <&resetc 20>, <&resetc 40>; + reset-names = "other", "test", "test2", "test3"; + }; + + rng { + compatible = "sandbox,sandbox-rng"; + }; + + 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>, <0>, <&gpio_a 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_spi0_pins>; + + spi.bin@0 { + reg = <0>; + compatible = "spansion,m25p16", "jedec,spi-nor"; + spi-max-frequency = <40000000>; + sandbox,filename = "spi.bin"; + }; + spi.bin@1 { + reg = <1>; + compatible = "spansion,m25p16", "jedec,spi-nor"; + spi-max-frequency = <50000000>; + sandbox,filename = "spi.bin"; + spi-cpol; + spi-cpha; + }; + }; + + 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>; + }; + + syscon3: syscon@3 { + compatible = "simple-mfd", "syscon"; + reg = <0x000100 0x10>; + + muxcontroller0: a-mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + + mux-reg-masks = <0x0 0x30>, /* 0: reg 0x0, bits 5:4 */ + <0xc 0x1E>, /* 1: reg 0xc, bits 4:1 */ + <0x4 0xFF>; /* 2: reg 0x4, bits 7:0 */ + idle-states = <MUX_IDLE_AS_IS>, <0x02>, <0x73>; + u-boot,mux-autoprobe; + }; + }; + + muxcontroller1: emul-mux-controller { + compatible = "mux-emul"; + #mux-control-cells = <0>; + u-boot,mux-autoprobe; + idle-state = <0xabcd>; + }; + + testfdtm0 { + compatible = "denx,u-boot-fdtm-test"; + }; + + testfdtm1: testfdtm1 { + compatible = "denx,u-boot-fdtm-test"; + }; + + testfdtm2 { + compatible = "denx,u-boot-fdtm-test"; + }; + + timer@0 { + compatible = "sandbox,timer"; + clock-frequency = <1000000>; + }; + + timer@1 { + compatible = "sandbox,timer"; + sandbox,timebase-frequency-fallback; + }; + + tpm2 { + compatible = "sandbox,tpm2"; + }; + + uart0: serial { + compatible = "sandbox,serial"; + u-boot,dm-pre-reloc; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_uart0_pins>; + }; + + 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>; + #address-cells = <1>; + #size-cells = <0>; + 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"; + }; + + }; + + usbstor@1 { + reg = <1>; + }; + usbstor@3 { + reg = <3>; + }; + }; + }; + + 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>; + setting = "sunrise ohoka"; + other-node = "/some-bus/c-test@5"; + int-values = <0x1937 72993>; + u-boot,acpi-ssdt-order = <&acpi_test2 &acpi_test1>; + 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"; + }; + + sandbox_tee { + compatible = "sandbox,tee"; + }; + + sandbox_virtio1 { + compatible = "sandbox,virtio1"; + }; + + sandbox_virtio2 { + compatible = "sandbox,virtio2"; + }; + + sandbox_scmi { + compatible = "sandbox,scmi-devices"; + clocks = <&clk_scmi0 7>, <&clk_scmi0 3>, <&clk_scmi1 1>; + resets = <&reset_scmi0 3>; + regul0-supply = <®ul0_scmi0>; + regul1-supply = <®ul1_scmi0>; + }; + + pinctrl { + compatible = "sandbox,pinctrl"; + + pinctrl-names = "default", "alternate"; + pinctrl-0 = <&pinctrl_gpios>, <&pinctrl_i2s>; + pinctrl-1 = <&pinctrl_spi>, <&pinctrl_i2c>; + + pinctrl_gpios: gpios { + gpio0 { + pins = "P5"; + function = "GPIO"; + bias-pull-up; + input-disable; + }; + gpio1 { + pins = "P6"; + function = "GPIO"; + output-high; + drive-open-drain; + }; + gpio2 { + pinmux = <SANDBOX_PINMUX(7, SANDBOX_PINMUX_GPIO)>; + bias-pull-down; + input-enable; + }; + gpio3 { + pinmux = <SANDBOX_PINMUX(8, SANDBOX_PINMUX_GPIO)>; + bias-disable; + }; + }; + + pinctrl_i2c: i2c { + groups { + groups = "I2C_UART"; + function = "I2C"; + }; + + pins { + pins = "P0", "P1"; + drive-open-drain; + }; + }; + + pinctrl_i2s: i2s { + groups = "SPI_I2S"; + function = "I2S"; + }; + + pinctrl_spi: spi { + groups = "SPI_I2S"; + function = "SPI"; + + cs { + pinmux = <SANDBOX_PINMUX(5, SANDBOX_PINMUX_CS)>, + <SANDBOX_PINMUX(6, SANDBOX_PINMUX_CS)>; + }; + }; + }; + + pinctrl-single-no-width { + compatible = "pinctrl-single"; + reg = <0x0000 0x238>; + #pinctrl-cells = <1>; + pinctrl-single,function-mask = <0x7f>; + }; + + pinctrl-single-pins { + compatible = "pinctrl-single"; + reg = <0x0000 0x238>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0x7f>; + + pinmux_pwm_pins: pinmux_pwm_pins { + pinctrl-single,pins = < 0x48 0x06 >; + }; + + pinmux_spi0_pins: pinmux_spi0_pins { + pinctrl-single,pins = < + 0x190 0x0c + 0x194 0x0c + 0x198 0x23 + 0x19c 0x0c + >; + }; + + pinmux_uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x70 0x30 + 0x74 0x00 + >; + }; + }; + + pinctrl-single-bits { + compatible = "pinctrl-single"; + reg = <0x0000 0x50>; + #pinctrl-cells = <2>; + pinctrl-single,bit-per-mux; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xf>; + + pinmux_i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,bits = < + 0x10 0x00002200 0x0000ff00 + >; + }; + + pinmux_lcd_pins: pinmux_lcd_pins { + pinctrl-single,bits = < + 0x40 0x22222200 0xffffff00 + 0x44 0x22222222 0xffffffff + 0x48 0x00000022 0x000000ff + 0x48 0x02000000 0x0f000000 + 0x4c 0x02000022 0x0f0000ff + >; + }; + }; + + 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"; + }; + + pm-bus-test { + compatible = "simple-pm-bus"; + clocks = <&clk_sandbox 4>; + power-domains = <&pwrdom 1>; + }; + + resetc2: syscon-reset { + compatible = "syscon-reset"; + #reset-cells = <1>; + regmap = <&syscon0>; + offset = <1>; + mask = <0x27FFFFFF>; + assert-high = <0>; + }; + + syscon-reset-test { + compatible = "sandbox,misc_sandbox"; + resets = <&resetc2 15>, <&resetc2 30>, <&resetc2 60>; + reset-names = "valid", "no_mask", "out_of_range"; + }; + + sysinfo { + compatible = "sandbox,sysinfo-sandbox"; + }; + + sysinfo-gpio { + compatible = "gpio-sysinfo"; + gpios = <&gpio_a 15>, <&gpio_a 16>, <&gpio_a 17>; + revisions = <19>, <5>; + names = "rev_a", "foo"; + }; + + some_regmapped-bus { + #address-cells = <0x1>; + #size-cells = <0x1>; + + ranges = <0x0 0x0 0x10>; + compatible = "simple-bus"; + + regmap-test_0 { + reg = <0 0x10>; + compatible = "sandbox,regmap_test"; + }; + }; +}; + +#include "sandbox_pmic.dtsi" +#include "cros-ec-keyboard.dtsi" diff --git a/roms/u-boot/arch/sandbox/include/asm/acpi_table.h b/roms/u-boot/arch/sandbox/include/asm/acpi_table.h new file mode 100644 index 000000000..921c7f420 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/acpi_table.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef __ASM_ACPI_TABLE_H__ +#define __ASM_ACPI_TABLE_H__ + +#endif /* __ASM_ACPI_TABLE_H__ */ diff --git a/roms/u-boot/arch/sandbox/include/asm/axi.h b/roms/u-boot/arch/sandbox/include/asm/axi.h new file mode 100644 index 000000000..d483f7b65 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/axi.h @@ -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 */ diff --git a/roms/u-boot/arch/sandbox/include/asm/bitops.h b/roms/u-boot/arch/sandbox/include/asm/bitops.h new file mode 100644 index 000000000..f27d5e98c --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/bitops.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 */ diff --git a/roms/u-boot/arch/sandbox/include/asm/byteorder.h b/roms/u-boot/arch/sandbox/include/asm/byteorder.h new file mode 100644 index 000000000..70b4c078a --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/byteorder.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 diff --git a/roms/u-boot/arch/sandbox/include/asm/cache.h b/roms/u-boot/arch/sandbox/include/asm/cache.h new file mode 100644 index 000000000..9348a13e7 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/cache.h @@ -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__ */ diff --git a/roms/u-boot/arch/sandbox/include/asm/clk.h b/roms/u-boot/arch/sandbox/include/asm/clk.h new file mode 100644 index 000000000..df7156fe3 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/clk.h @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. + */ + +#ifndef __SANDBOX_CLK_H +#define __SANDBOX_CLK_H + +#include <common.h> +#include <clk.h> +#include <dt-structs.h> +#include <linux/clk-provider.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_BUS, + + 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 + +struct sandbox_clk_priv { + bool probed; + ulong rate[SANDBOX_CLK_ID_COUNT]; + bool enabled[SANDBOX_CLK_ID_COUNT]; + bool requested[SANDBOX_CLK_ID_COUNT]; +}; + +struct sandbox_clk_test { + struct clk clks[SANDBOX_CLK_TEST_NON_DEVM_COUNT]; + struct clk *clkps[SANDBOX_CLK_TEST_ID_COUNT]; + struct clk_bulk bulk; +}; + +/* Platform data for the sandbox fixed-rate clock driver */ +struct sandbox_clk_fixed_rate_plat { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_sandbox_fixed_clock dtplat; +#endif + struct clk_fixed_rate fixed; +}; + +/** + * 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) device. + * @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) device. + * @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) device. + * @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) device. + * @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_round_rate - Ask the sandbox clock test device to round a + * clock's rate. + * + * @dev: The sandbox clock test (client) device. + * @id: The test device's clock ID to configure. + * @return: The rounded rate of the clock. + */ +ulong sandbox_clk_test_round_rate(struct udevice *dev, int id, ulong rate); +/** + * sandbox_clk_test_set_rate - Ask the sandbox clock test device to set a + * clock's rate. + * + * @dev: The sandbox clock test (client) device. + * @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) device. + * @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) device. + * @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) device. + * @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) device. + * @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) device. + * @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) device. + * @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) device. + * @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) device. + * @return: 0 if OK, or a negative error code. + */ +struct clk *sandbox_clk_test_get_devm_clk(struct udevice *dev, int id); + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/config.h b/roms/u-boot/arch/sandbox/include/asm/config.h new file mode 100644 index 000000000..50215b35d --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/config.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/cpu.h b/roms/u-boot/arch/sandbox/include/asm/cpu.h new file mode 100644 index 000000000..c97ac7ba9 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/cpu.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com> + */ + +#ifndef __SANDBOX_CPU_H +#define __SANDBOX_CPU_H + +void cpu_sandbox_set_current(const char *name); + +#endif /* __SANDBOX_CPU_H */ diff --git a/roms/u-boot/arch/sandbox/include/asm/dma-mapping.h b/roms/u-boot/arch/sandbox/include/asm/dma-mapping.h new file mode 100644 index 000000000..853b0877b --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/dma-mapping.h @@ -0,0 +1 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/roms/u-boot/arch/sandbox/include/asm/eth-raw-os.h b/roms/u-boot/arch/sandbox/include/asm/eth-raw-os.h new file mode 100644 index 000000000..0b511db70 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/eth-raw-os.h @@ -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 */ diff --git a/roms/u-boot/arch/sandbox/include/asm/eth.h b/roms/u-boot/arch/sandbox/include/asm/eth.h new file mode 100644 index 000000000..b313bf57c --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/eth.h @@ -0,0 +1,111 @@ +/* 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 + +#include <net.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 */ diff --git a/roms/u-boot/arch/sandbox/include/asm/getopt.h b/roms/u-boot/arch/sandbox/include/asm/getopt.h new file mode 100644 index 000000000..d2145ad6e --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/getopt.h @@ -0,0 +1,72 @@ +/* + * Code for setting up command line flags like `./u-boot --help` + * + * Copyright (c) 2011 The Chromium OS Authors. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __SANDBOX_GETOPT_H +#define __SANDBOX_GETOPT_H + +struct sandbox_state; + +/* + * Internal structure for storing details about the flag. + * Most people should not have to dig around in this as + * it only gets parsed by the core sandbox code. End + * consumer code should focus on the macros below and + * the callback function. + */ +struct sandbox_cmdline_option { + /* The long flag name: "help" for "--help" */ + const char *flag; + /* The (optional) short flag name: "h" for "-h" */ + int flag_short; + /* The help string shown to the user when processing --help */ + const char *help; + /* Whether this flag takes an argument */ + int has_arg; + /* Callback into the end consumer code with the option */ + int (*callback)(struct sandbox_state *state, const char *opt); +}; + +/* + * Internal macro to expand the lower macros into the necessary + * magic junk that makes this all work. + */ +#define _SANDBOX_CMDLINE_OPT(f, s, ha, h) \ + static struct sandbox_cmdline_option sandbox_cmdline_option_##f = { \ + .flag = #f, \ + .flag_short = s, \ + .help = h, \ + .has_arg = ha, \ + .callback = sandbox_cmdline_cb_##f, \ + }; \ + /* Ppointer to the struct in a special section for the linker script */ \ + static __used __section(".u_boot_sandbox_getopt") \ + struct sandbox_cmdline_option \ + *sandbox_cmdline_option_##f##_ptr = \ + &sandbox_cmdline_option_##f + +/** + * Macros for end code to declare new command line flags. + * + * @param f The long flag name e.g. help + * @param ha Does the flag have an argument e.g. 0/1 + * @param h The help string displayed when showing --help + * + * This invocation: + * SANDBOX_CMDLINE_OPT(foo, 0, "The foo arg"); + * Will create a new flag named "--foo" (no short option) that takes + * no argument. If the user specifies "--foo", then the callback func + * sandbox_cmdline_cb_foo() will automatically be called. + */ +#define SANDBOX_CMDLINE_OPT(f, ha, h) _SANDBOX_CMDLINE_OPT(f, 0, ha, h) +/* + * Same as above, but @s is used to specify a short flag e.g. + * SANDBOX_CMDLINE_OPT(foo, 'f', 0, "The foo arg"); + */ +#define SANDBOX_CMDLINE_OPT_SHORT(f, s, ha, h) _SANDBOX_CMDLINE_OPT(f, s, ha, h) + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/global_data.h b/roms/u-boot/arch/sandbox/include/asm/global_data.h new file mode 100644 index 000000000..f95ddb058 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/global_data.h @@ -0,0 +1,23 @@ +/* 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 */ + ulong acpi_start; /* Start address of ACPI tables */ +}; + +#include <asm-generic/global_data.h> + +#define DECLARE_GLOBAL_DATA_PTR extern gd_t *gd + +#endif /* __ASM_GBL_DATA_H */ diff --git a/roms/u-boot/arch/sandbox/include/asm/gpio.h b/roms/u-boot/arch/sandbox/include/asm/gpio.h new file mode 100644 index 000000000..9e1005266 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/gpio.h @@ -0,0 +1,94 @@ +/* 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> + +/* Our own private GPIO flags, which musn't conflict with GPIOD_... */ +#define GPIOD_EXT_HIGH BIT(31) /* external source is high (else low) */ +#define GPIOD_EXT_DRIVEN BIT(30) /* external source is driven */ +#define GPIOD_EXT_PULL_UP BIT(29) /* GPIO has external pull-up */ +#define GPIOD_EXT_PULL_DOWN BIT(28) /* GPIO has external pull-down */ + +#define GPIOD_EXT_PULL (BIT(28) | BIT(29)) +#define GPIOD_SANDBOX_MASK GENMASK(31, 28) + +/** + * 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); + +/** + * 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); + +/** + * Return the simulated flags of a GPIO (used only in sandbox test code) + * + * @param dev device to use + * @param offset GPIO offset within bank + * @return dir_flags: bitfield accesses by GPIOD_ defines + */ +ulong sandbox_gpio_get_flags(struct udevice *dev, unsigned int offset); + +/** + * Set the simulated flags of a GPIO (used only in sandbox test code) + * + * @param dev device to use + * @param offset GPIO offset within bank + * @param flags bitfield accesses by GPIOD_ defines + * @return -1 on error, 0 if ok + */ +int sandbox_gpio_set_flags(struct udevice *dev, unsigned int offset, + ulong flags); + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/handoff.h b/roms/u-boot/arch/sandbox/include/asm/handoff.h new file mode 100644 index 000000000..be4e7b0fa --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/handoff.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/i2c.h b/roms/u-boot/arch/sandbox/include/asm/i2c.h new file mode 100644 index 000000000..4fc190be4 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/i2c.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __asn_i2c_h +#define __asn_i2c_h + +struct sandbox_i2c_priv { + bool test_mode; +}; + +/** + * struct i2c_emul_uc_plat - information about the emulator for this device + * + * This is used by devices in UCLASS_I2C_EMUL to record information about the + * device being emulated. It is accessible with dev_get_uclass_plat() + * + * @dev: Device being emulated + * @idx: of-platdata index, set up by the device's bind() method if of-platdata + * is in use + */ +struct i2c_emul_uc_plat { + struct udevice *dev; + int idx; +}; + +#endif /* __asn_i2c_h */ diff --git a/roms/u-boot/arch/sandbox/include/asm/io.h b/roms/u-boot/arch/sandbox/include/asm/io.h new file mode 100644 index 000000000..ad6c29a4e --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/io.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/linkage.h b/roms/u-boot/arch/sandbox/include/asm/linkage.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/linkage.h diff --git a/roms/u-boot/arch/sandbox/include/asm/malloc.h b/roms/u-boot/arch/sandbox/include/asm/malloc.h new file mode 100644 index 000000000..a1467b5ea --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/malloc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Sandbox access to system malloc (i.e. not U-Boot's) + * + * Copyright 2020 Google LLC + */ + +#ifndef __ASM_MALLOC_H + +void *malloc(size_t size); +void free(void *ptr); +void *calloc(size_t nmemb, size_t size); +void *realloc(void *ptr, size_t size); +void *reallocarray(void *ptr, size_t nmemb, size_t size); + +/* + * This header allows calling the system allocation routines. It makes no + * sense to also include U-Boot's malloc.h since that redfines malloc to + * have a 'dl' prefix. These two implementations cannot be mixed and matched + * in the same file. + */ +#ifdef __MALLOC_H__ +#error "This sandbox header file cannot be included with malloc.h" +#endif + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/mbox.h b/roms/u-boot/arch/sandbox/include/asm/mbox.h new file mode 100644 index 000000000..70f36d7af --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/mbox.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/posix_types.h b/roms/u-boot/arch/sandbox/include/asm/posix_types.h new file mode 100644 index 000000000..ec18ed7e3 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/posix_types.h @@ -0,0 +1,57 @@ +/* + * linux/include/asm-arm/posix_types.h + * + * Copyright (C) 1996-1998 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 27-06-1996 RMK Created + */ +#ifndef __ARCH_ARM_POSIX_TYPES_H +#define __ARCH_ARM_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +#if CONFIG_SANDBOX_BITS_PER_LONG == 32 +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +#else +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +#endif +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char *__kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/power-domain.h b/roms/u-boot/arch/sandbox/include/asm/power-domain.h new file mode 100644 index 000000000..1845bc8d3 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/power-domain.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/processor.h b/roms/u-boot/arch/sandbox/include/asm/processor.h new file mode 100644 index 000000000..8dced6006 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/processor.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/ptrace.h b/roms/u-boot/arch/sandbox/include/asm/ptrace.h new file mode 100644 index 000000000..78e58173f --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/ptrace.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/reset.h b/roms/u-boot/arch/sandbox/include/asm/reset.h new file mode 100644 index 000000000..40d3e61c1 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/reset.h @@ -0,0 +1,27 @@ +/* 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_is_requested(struct udevice *dev, unsigned long id); + +int sandbox_reset_test_get(struct udevice *dev); +int sandbox_reset_test_get_devm(struct udevice *dev); +int sandbox_reset_test_get_bulk(struct udevice *dev); +int sandbox_reset_test_get_bulk_devm(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 diff --git a/roms/u-boot/arch/sandbox/include/asm/rtc.h b/roms/u-boot/arch/sandbox/include/asm/rtc.h new file mode 100644 index 000000000..025cd6c67 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/rtc.h @@ -0,0 +1,56 @@ +/* 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 + +#include <dt-structs.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_AUX0 = 0x30, + REG_AUX1, + REG_AUX2, + REG_AUX3, + + REG_COUNT = 0x80, +}; + +/** + * struct sandbox_i2c_rtc_plat_data - platform data for the RTC + * + * @base_time: Base system time when RTC device was bound + * @offset: RTC offset from current system time + * @use_system_time: true to use system time, false to use @base_time + * @reg: Register values + */ +struct sandbox_i2c_rtc_plat_data { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_sandbox_i2c_rtc_emul dtplat; +#endif + long base_time; + long offset; + bool use_system_time; + u8 reg[REG_COUNT]; +}; + +struct sandbox_i2c_rtc { + unsigned int offset_secs; +}; + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/scmi_test.h b/roms/u-boot/arch/sandbox/include/asm/scmi_test.h new file mode 100644 index 000000000..2930e686d --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/scmi_test.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020, Linaro Limited + */ + +#ifndef __SANDBOX_SCMI_TEST_H +#define __SANDBOX_SCMI_TEST_H + +struct udevice; +struct sandbox_scmi_agent; +struct sandbox_scmi_service; + +/** + * struct sandbox_scmi_clk - Simulated clock exposed by SCMI + * @id: Identifier of the clock used in the SCMI protocol + * @enabled: Clock state: true if enabled, false if disabled + * @rate: Clock rate in Hertz + */ +struct sandbox_scmi_clk { + uint id; + bool enabled; + ulong rate; +}; + +/** + * struct sandbox_scmi_reset - Simulated reset controller exposed by SCMI + * @id: Identifier of the reset controller used in the SCMI protocol + * @asserted: Reset control state: true if asserted, false if desasserted + */ +struct sandbox_scmi_reset { + uint id; + bool asserted; +}; + +/** + * struct sandbox_scmi_voltd - Simulated voltage regulator exposed by SCMI + * @id: Identifier of the voltage domain used in the SCMI protocol + * @enabled: Regulator state: true if on, false if off + * @voltage_uv: Regulator current voltage in microvoltd (uV) + */ +struct sandbox_scmi_voltd { + uint id; + bool enabled; + int voltage_uv; +}; + +/** + * struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent + * @idx: Identifier for the SCMI agent, its index + * @clk: Simulated clocks + * @clk_count: Simulated clocks array size + * @reset: Simulated reset domains + * @reset_count: Simulated reset domains array size + * @voltd: Simulated voltage domains (regulators) + * @voltd_count: Simulated voltage domains array size + */ +struct sandbox_scmi_agent { + uint idx; + struct sandbox_scmi_clk *clk; + size_t clk_count; + struct sandbox_scmi_reset *reset; + size_t reset_count; + struct sandbox_scmi_voltd *voltd; + size_t voltd_count; +}; + +/** + * struct sandbox_scmi_service - Reference to simutaed SCMI agents/services + * @agent: Pointer to SCMI sandbox agent pointers array + * @agent_count: Number of emulated agents exposed in array @agent. + */ +struct sandbox_scmi_service { + struct sandbox_scmi_agent **agent; + size_t agent_count; +}; + +/** + * struct sandbox_scmi_devices - Reference to devices probed through SCMI + * @clk: Array the clock devices + * @clk_count: Number of clock devices probed + * @reset: Array the reset controller devices + * @reset_count: Number of reset controller devices probed + * @regul: Array regulator devices + * @regul_count: Number of regulator devices probed + */ +struct sandbox_scmi_devices { + struct clk *clk; + size_t clk_count; + struct reset_ctl *reset; + size_t reset_count; + struct udevice **regul; + size_t regul_count; +}; + +#ifdef CONFIG_SCMI_FIRMWARE +/** + * sandbox_scmi_service_context - Get the simulated SCMI services context + * @return: Reference to backend simulated resources state + */ +struct sandbox_scmi_service *sandbox_scmi_service_ctx(void); + +/** + * sandbox_scmi_devices_get_ref - Get references to devices accessed through SCMI + * @dev: Reference to the test device used get test resources + * @return: Reference to the devices probed by the SCMI test + */ +struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev); +#else +static inline struct sandbox_scmi_service *sandbox_scmi_service_ctx(void) +{ + return NULL; +} + +static inline +struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev) +{ + return NULL; +} +#endif /* CONFIG_SCMI_FIRMWARE */ +#endif /* __SANDBOX_SCMI_TEST_H */ diff --git a/roms/u-boot/arch/sandbox/include/asm/sdl.h b/roms/u-boot/arch/sandbox/include/asm/sdl.h new file mode 100644 index 000000000..47fc4889d --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/sdl.h @@ -0,0 +1,127 @@ +/* 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 + * @double_size: true to double the visible size in each direction for high-DPI + * displays + * @return 0 if OK, -ENODEV if no device, -EIO if SDL failed to initialize + * and -EPERM if the video failed to come up. + */ +int sandbox_sdl_init_display(int width, int height, int log2_bpp, + bool double_size); + +/** + * 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, + bool double_size) +{ + 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 diff --git a/roms/u-boot/arch/sandbox/include/asm/sections.h b/roms/u-boot/arch/sandbox/include/asm/sections.h new file mode 100644 index 000000000..f4351ae7d --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/sections.h @@ -0,0 +1,39 @@ +/* + * 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; + +static inline struct sandbox_cmdline_option ** +__u_boot_sandbox_option_start(void) +{ + static char start[0] __aligned(4) __attribute__((unused)) + __section(".u_boot_sandbox_getopt_start"); + + return (struct sandbox_cmdline_option **)&start; +} + +static inline struct sandbox_cmdline_option ** +__u_boot_sandbox_option_end(void) +{ + static char end[0] __aligned(4) __attribute__((unused)) + __section(".u_boot_sandbox_getopt_end"); + + return (struct sandbox_cmdline_option **)&end; +} + +static inline size_t __u_boot_sandbox_option_count(void) +{ + return __u_boot_sandbox_option_end() - __u_boot_sandbox_option_start(); +} + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/serial.h b/roms/u-boot/arch/sandbox/include/asm/serial.h new file mode 100644 index 000000000..bc82aebd0 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/serial.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __asm_serial_h +#define __asm_serial_h + +#include <dt-structs.h> + +struct sandbox_serial_plat { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_sandbox_serial dtplat; +#endif + int colour; /* Text colour to use for output, -1 for none */ +}; + +/** + * struct sandbox_serial_priv - Private data for this driver + * + * @buf: holds input characters available to be read by this driver + */ +struct sandbox_serial_priv { + struct membuff buf; + char serial_buf[16]; + bool start_of_line; +}; + +#endif /* __asm_serial_h */ diff --git a/roms/u-boot/arch/sandbox/include/asm/setjmp.h b/roms/u-boot/arch/sandbox/include/asm/setjmp.h new file mode 100644 index 000000000..001c7ea32 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/setjmp.h @@ -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_ */ diff --git a/roms/u-boot/arch/sandbox/include/asm/spi.h b/roms/u-boot/arch/sandbox/include/asm/spi.h new file mode 100644 index 000000000..e8268bbe0 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/spi.h @@ -0,0 +1,35 @@ +/* + * 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); +}; + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/spl.h b/roms/u-boot/arch/sandbox/include/asm/spl.h new file mode 100644 index 000000000..51e9d95d5 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/spl.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/state.h b/roms/u-boot/arch/sandbox/include/asm/state.h new file mode 100644 index 000000000..bca130698 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/state.h @@ -0,0 +1,279 @@ +/* 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 long 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 */ + bool double_lcd; /* Double display size for high-DPI */ + enum sysreset_t last_sysreset; /* Last system reset type */ + bool sysreset_allowed[SYSRESET_COUNT]; /* Allowed system reset types */ + enum state_terminal_raw term_raw; /* Terminal raw/cooked */ + 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 ram_buf_read; /* true if we read the RAM buffer */ + bool run_unittests; /* Run unit tests */ + const char *select_unittests; /* Unit test to run */ + + /* 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 diff --git a/roms/u-boot/arch/sandbox/include/asm/string.h b/roms/u-boot/arch/sandbox/include/asm/string.h new file mode 100644 index 000000000..32685b317 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/string.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2011 The Chromium OS Authors. + */ + +#include <linux/string.h> diff --git a/roms/u-boot/arch/sandbox/include/asm/system.h b/roms/u-boot/arch/sandbox/include/asm/system.h new file mode 100644 index 000000000..7933b6292 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/system.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 diff --git a/roms/u-boot/arch/sandbox/include/asm/test.h b/roms/u-boot/arch/sandbox/include/asm/test.h new file mode 100644 index 000000000..1cb960ac2 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/test.h @@ -0,0 +1,278 @@ +/* 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_PMC_EMUL_ID 0x5677 +#define SANDBOX_PCI_P2SB_EMUL_ID 0x5676 +#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 + +enum { + SANDBOX_IRQN_PEND = 1, /* Interrupt number for 'pending' test */ +}; + +/* System controller driver data */ +enum { + SYSCON0 = 32, + SYSCON1, + + SYSCON_COUNT +}; + +/** + */ +enum cros_ec_test_t { + CROSECT_BREAK_HELLO = BIT(1), + CROSECT_LID_OPEN = BIT(2), +}; + +/** + * 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); + +void sandbox_i2c_eeprom_set_chip_addr_offset_mask(struct udevice *dev, + uint mask); + +uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev); + +uint sanbox_i2c_eeprom_get_prev_offset(struct udevice *dev); + +/** + * 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_active() - Returns whether sound play is in progress + * + * @return true if active, false if not + */ +int sandbox_get_sound_active(struct udevice *dev); + +/** + * sandbox_get_sound_sum() - Read back the sum of the sound data so far + * + * This data is provided to the sandbox driver by the sound play() method. + * + * @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_spi_get_speed() - Get current speed setting of a sandbox spi bus + * + * @dev: Device to check + * @return current bus speed + */ +uint sandbox_spi_get_speed(struct udevice *dev); + +/** + * sandbox_spi_get_mode() - Get current mode setting of a sandbox spi bus + * + * @dev: Device to check + * @return current mode + */ +uint sandbox_spi_get_mode(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); + +/** + * sandbox_cros_ec_set_test_flags() - Set behaviour for testing purposes + * + * @dev: Device to check + * @flags: Flags to control behaviour (CROSECT_...) + */ +void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags); + +#endif diff --git a/roms/u-boot/arch/sandbox/include/asm/types.h b/roms/u-boot/arch/sandbox/include/asm/types.h new file mode 100644 index 000000000..c1a5d2af8 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/types.h @@ -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 diff --git a/roms/u-boot/arch/sandbox/include/asm/u-boot-sandbox.h b/roms/u-boot/arch/sandbox/include/asm/u-boot-sandbox.h new file mode 100644 index 000000000..73b189719 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/u-boot-sandbox.h @@ -0,0 +1,100 @@ +/* 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); + +/** + * sandbox_reset() - reset sandbox + * + * This functions implements the cold reboot of the sandbox. It relaunches the + * U-Boot binary with the same command line parameters as the original call. + * The PID of the process stays the same. All file descriptors that have not + * been opened with O_CLOEXEC stay open including stdin, stdout, stderr. + */ +void sandbox_reset(void); + +/* Exit sandbox (quit U-Boot) */ +void sandbox_exit(void); + +#endif /* _U_BOOT_SANDBOX_H_ */ diff --git a/roms/u-boot/arch/sandbox/include/asm/u-boot.h b/roms/u-boot/arch/sandbox/include/asm/u-boot.h new file mode 100644 index 000000000..34fcb7149 --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/u-boot.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_ */ diff --git a/roms/u-boot/arch/sandbox/include/asm/unaligned.h b/roms/u-boot/arch/sandbox/include/asm/unaligned.h new file mode 100644 index 000000000..2cb2a17fa --- /dev/null +++ b/roms/u-boot/arch/sandbox/include/asm/unaligned.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2011 The Chromium OS Authors. + */ + +#include <asm-generic/unaligned.h> diff --git a/roms/u-boot/arch/sandbox/lib/Makefile b/roms/u-boot/arch/sandbox/lib/Makefile new file mode 100644 index 000000000..b4ff717e7 --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/Makefile @@ -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 diff --git a/roms/u-boot/arch/sandbox/lib/bootm.c b/roms/u-boot/arch/sandbox/lib/bootm.c new file mode 100644 index 000000000..d1d460b84 --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/bootm.c @@ -0,0 +1,63 @@ +// 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 <bootstage.h> +#include <image.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; +} diff --git a/roms/u-boot/arch/sandbox/lib/crt0_sandbox_efi.S b/roms/u-boot/arch/sandbox/lib/crt0_sandbox_efi.S new file mode 100644 index 000000000..88537345d --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/crt0_sandbox_efi.S @@ -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 diff --git a/roms/u-boot/arch/sandbox/lib/interrupts.c b/roms/u-boot/arch/sandbox/lib/interrupts.c new file mode 100644 index 000000000..4d7cbff80 --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/interrupts.c @@ -0,0 +1,59 @@ +// 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 <efi_loader.h> +#include <irq_func.h> +#include <os.h> +#include <asm/global_data.h> +#include <asm-generic/signal.h> +#include <asm/u-boot-sandbox.h> + +DECLARE_GLOBAL_DATA_PTR; + +int interrupt_init(void) +{ + return 0; +} + +void enable_interrupts(void) +{ + return; +} +int disable_interrupts(void) +{ + return 0; +} + +void os_signal_action(int sig, unsigned long pc) +{ + efi_restore_gd(); + + switch (sig) { + case SIGILL: + printf("\nIllegal instruction\n"); + break; + case SIGBUS: + printf("\nBus error\n"); + break; + case SIGSEGV: + printf("\nSegmentation violation\n"); + break; + default: + break; + } + printf("pc = 0x%lx, ", pc); + printf("pc_reloc = 0x%lx\n\n", pc - gd->reloc_off); + efi_print_image_infos((void *)pc); + + if (IS_ENABLED(CONFIG_SANDBOX_CRASH_RESET)) { + printf("resetting ...\n\n"); + sandbox_reset(); + } else { + sandbox_exit(); + } +} diff --git a/roms/u-boot/arch/sandbox/lib/pci_io.c b/roms/u-boot/arch/sandbox/lib/pci_io.c new file mode 100644 index 000000000..203814194 --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/pci_io.c @@ -0,0 +1,138 @@ +// 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 <log.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); +} diff --git a/roms/u-boot/arch/sandbox/lib/reloc_sandbox_efi.c b/roms/u-boot/arch/sandbox/lib/reloc_sandbox_efi.c new file mode 100644 index 000000000..a21e6757c --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/reloc_sandbox_efi.c @@ -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 diff --git a/roms/u-boot/arch/sandbox/lib/sections.c b/roms/u-boot/arch/sandbox/lib/sections.c new file mode 100644 index 000000000..2559eeea3 --- /dev/null +++ b/roms/u-boot/arch/sandbox/lib/sections.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2013 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + */ +#include <linux/compiler.h> + +char __efi_runtime_start[0] __section(".__efi_runtime_start"); +char __efi_runtime_stop[0] __section(".__efi_runtime_stop"); +char __efi_runtime_rel_start[0] + __section(".__efi_runtime_rel_start"); +char __efi_runtime_rel_stop[0] + __section(".__efi_runtime_rel_stop"); |