aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Bellows <greg.bellows@linaro.org>2014-12-17 15:54:24 -0600
committerGreg Bellows <greg.bellows@linaro.org>2014-12-17 15:58:14 -0600
commiteaa27adbcb66c26a4741c0be640730ec062e9fb0 (patch)
tree84d0ca5fe878abd136a981cb779d08a5683a0b0d
parent452005de0650d686567acd1e2cfdda41bf9ffc09 (diff)
parent46745a4031d369881f0a9ec9b4483f7c37a113fa (diff)
Merge branch 'shrink'
Signed-off-by: Greg Bellows <greg.bellows@linaro.org> Conflicts: arm/tztest_common.c arm/tztest_mmu.c arm/tztest_mmu.h arm/tztest_nonsecure_svc.c arm/tztest_secure_svc.c
-rw-r--r--Makefile58
-rw-r--r--README63
-rw-r--r--arm/Makefile.tztest33
-rw-r--r--arm/arm32.h1
-rw-r--r--arm/common_defs.h (renamed from arm/tztest_asm.h)0
-rw-r--r--arm/common_mmu.c128
-rw-r--r--arm/common_mmu.h145
-rw-r--r--arm/common_svc.c42
-rw-r--r--arm/common_svc.h71
-rw-r--r--arm/monitor.c25
-rw-r--r--arm/monitor_asm.S50
-rw-r--r--arm/nonsecure_init.S22
-rw-r--r--arm/nonsecure_loader.h18
-rw-r--r--arm/nonsecure_svc.c138
-rw-r--r--arm/secure_asm.S40
-rw-r--r--arm/secure_init.S136
-rw-r--r--arm/secure_loader.h21
-rw-r--r--arm/secure_svc.c184
-rw-r--r--arm/sm_asm.S1
-rw-r--r--arm/tzboot.S35
-rw-r--r--arm/tztest.c200
-rw-r--r--arm/tztest.h131
-rw-r--r--arm/tztest_builtins.h2
-rw-r--r--arm/tztest_common.c18
-rw-r--r--arm/tztest_mmu.c32
-rw-r--r--arm/tztest_mmu.h47
-rw-r--r--arm/tztest_nonsecure.lds.S13
-rw-r--r--arm/tztest_nonsecure_svc.c153
-rw-r--r--arm/tztest_secure.lds.S102
-rw-r--r--arm/tztest_secure_svc.c206
-rwxr-xr-xconfigure19
-rw-r--r--lib/libcflat/argv.c39
-rw-r--r--lib/libcflat/arm/asm-offsets.c39
-rw-r--r--lib/libcflat/arm/asm/asm-offsets.h1
-rw-r--r--lib/libcflat/arm/asm/barrier.h18
-rw-r--r--lib/libcflat/arm/asm/cp15.h37
-rw-r--r--lib/libcflat/arm/asm/processor.h40
-rw-r--r--lib/libcflat/arm/asm/ptrace.h100
-rw-r--r--lib/libcflat/arm/asm/semihosting.h51
-rw-r--r--lib/libcflat/arm/asm/setup.h63
-rw-r--r--lib/libcflat/arm/asm/spinlock.h11
-rw-r--r--lib/libcflat/arm/io.c66
-rw-r--r--lib/libcflat/arm/processor.c115
-rw-r--r--lib/libcflat/arm/semihosting.c160
-rw-r--r--lib/libcflat/arm/setup.c149
-rw-r--r--lib/libcflat/arm/spinlock.c28
-rw-r--r--lib/libcflat/asm-generic/spinlock.h4
-rw-r--r--lib/libcflat/devicetree.c272
-rw-r--r--lib/libcflat/devicetree.h236
-rw-r--r--lib/libcflat/report.c36
-rw-r--r--lib/libcflat/virtio-testdev.c137
-rw-r--r--lib/libcflat/virtio-testdev.h18
-rw-r--r--lib/libcflat/virtio.c165
-rw-r--r--lib/libcflat/virtio.h89
-rw-r--r--lib/libfdt/Makefile.libfdt10
-rw-r--r--lib/libfdt/README4
-rw-r--r--lib/libfdt/fdt.c250
-rw-r--r--lib/libfdt/fdt.h111
-rw-r--r--lib/libfdt/fdt_empty_tree.c84
-rw-r--r--lib/libfdt/fdt_ro.c573
-rw-r--r--lib/libfdt/fdt_rw.c492
-rw-r--r--lib/libfdt/fdt_strerror.c96
-rw-r--r--lib/libfdt/fdt_sw.c256
-rw-r--r--lib/libfdt/fdt_wip.c118
-rw-r--r--lib/libfdt/libfdt.h1514
-rw-r--r--lib/libfdt/libfdt_env.h111
-rw-r--r--lib/libfdt/libfdt_internal.h95
-rw-r--r--lib/libfdt/version.lds60
-rw-r--r--libcflat/COPYRIGHT (renamed from lib/libcflat/COPYRIGHT)0
-rw-r--r--libcflat/arm/eabi_compat.c (renamed from lib/libcflat/arm/eabi_compat.c)0
-rw-r--r--libcflat/arm/include/io.h (renamed from lib/libcflat/arm/asm/io.h)1
-rw-r--r--libcflat/arm/io.c33
-rw-r--r--libcflat/arm/misc.S (renamed from lib/libcflat/arm/misc.S)0
-rw-r--r--libcflat/include/asm-generic/io.h (renamed from lib/libcflat/asm-generic/io.h)0
-rw-r--r--libcflat/include/libcflat.h (renamed from lib/libcflat/libcflat.h)0
-rw-r--r--libcflat/include/string.h (renamed from lib/libcflat/string.h)0
-rw-r--r--libcflat/printf.c (renamed from lib/libcflat/printf.c)0
-rw-r--r--libcflat/string.c (renamed from lib/libcflat/string.c)0
-rw-r--r--platform/vexpress-a15/platform.h (renamed from platform/vexpress/platform.h)0
-rw-r--r--platform/vexpress-a9/platform.h33
-rw-r--r--platform/virt/platform.h33
81 files changed, 1374 insertions, 6508 deletions
diff --git a/Makefile b/Makefile
index 8f87704..b1a687e 100644
--- a/Makefile
+++ b/Makefile
@@ -5,25 +5,24 @@ endif
include config.mak
-.PHONY: arch_clean clean distclean cscope
+.PHONY: arch_clean clean distclean
# libcflat paths
-LIBCFLAT_objdir = lib/libcflat
-LIBCFLAT_srcdir = lib/libcflat
-LIBCFLAT_archdir = lib/libcflat/$(ARCH)
+LIBCFLAT_objdir = libcflat
+LIBCFLAT_srcdir = libcflat
+LIBCFLAT_archdir = libcflat/$(ARCH)
LIBCFLAT_archive = $(LIBCFLAT_objdir)/libcflat.a
-LIBCFLAT_OBJS = \
- $(LIBCFLAT_objdir)/argv.o \
- $(LIBCFLAT_objdir)/printf.o \
- $(LIBCFLAT_objdir)/string.o \
- $(LIBCFLAT_objdir)/report.o
-
-# libfdt paths
-LIBFDT_objdir = lib/libfdt
-LIBFDT_srcdir = lib/libfdt
-LIBFDT_archive = $(LIBFDT_objdir)/libfdt.a
-LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES))
-LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION))
+LIBCFLAT_OBJS = $(LIBCFLAT_objdir)/printf.o \
+ $(LIBCFLAT_objdir)/string.o \
+ $(LIBCFLAT_archdir)/io.o \
+ $(LIBCFLAT_archdir)/misc.o
+LIBEABI_OBJS = $(LIBCFLAT_archdir)/eabi_compat.o
+
+LIBEABI = $(LIBCFLAT_archdir)/libeabi.a
+libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name)
+CFLAGS += -I$(ARCH) -DASM
+
+FLATLIBS = $(LIBCFLAT_archive) $(libgcc) $(LIBEABI)
# cc-option
# Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
@@ -31,15 +30,13 @@ LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION))
cc-option = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
-CFLAGS += -marm
-CFLAGS += -mcpu=$(PROCESSOR)
+CFLAGS += -m${ARCH} -mcpu=$(PROCESSOR)
CFLAGS += $(autodepend-flags)
CFLAGS += -std=gnu99
CFLAGS += -ffreestanding
CFLAGS += -Wextra -Werror -Wall
CFLAGS += -g -O0
-CFLAGS += -Ilib -I$(LIBFDT_srcdir) -I $(LIBCFLAT_srcdir) -I$(LIBCFLAT_archdir)
-CFLAGS += -Ilib -I/usr/arm-linux-gnueabi/include/
+CFLAGS += -Ilib -I $(LIBCFLAT_srcdir)/include -I$(LIBCFLAT_archdir)/include
CFLAGS += -Iplatform/$(PLAT)
CFLAGS += $(call cc-option, -fomit-frame-pointer, "")
CFLAGS += $(call cc-option, -fno-stack-protector, "")
@@ -55,25 +52,22 @@ include $(ARCH)/Makefile.tztest
$(LIBCFLAT_archive): $(LIBCFLAT_OBJS)
$(AR) rcs $@ $^
-include $(LIBFDT_srcdir)/Makefile.libfdt
-$(LIBFDT_archive): CFLAGS += -Wno-sign-compare
-$(LIBFDT_archive): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
- $(AR) rcs $@ $^
-
%.o: %.S
$(CC) $(CFLAGS) -c -nostdlib -o $@ $<
-include */.*.d */*/.*.d
-clean: arch_clean
- $(RM) $(LIBCFLAT_archive) $(LIBCFLAT_OBJS) $(LIBCFLAT_objdir)/.*.d
+$(LIBEABI): $(LIBEABI_OBJS)
+ $(AR) rcs $@ $^
-libfdt_clean:
- $(RM) $(LIBFDT_archive) $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS)) \
- $(LIBFDT_objdir)/.*.d
+libeabi_clean:
+ $(RM) $(LIBEABI) $(LIBEABI_OBJS)
+
+clean: arch_clean libeabi_clean
+ $(RM) $(LIBCFLAT_archive) $(LIBCFLAT_OBJS) $(LIBCFLAT_objdir)/.*.d
libcflat_clean:
$(RM) $(LIBCFLAT_archive) $(LIBCFLAT_OBJS)
-distclean: clean libfdt_clean libcflat_clean
- $(RM) config.mak ..d
+distclean: clean libcflat_clean
+ $(RM) config.mak ..d cscope.*
diff --git a/README b/README
index 134a393..8544135 100644
--- a/README
+++ b/README
@@ -1,7 +1,62 @@
-ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make
+CONFIGURE
+----------
+Configure the test using ./configure before building. Running configure
+without any options will give the default platform of vexpress-a15 with the
+default CPU cortex-a15.
-./arm-softmmu/qemu-system-arm -machine vexpress-a15 -cpu cortex-a15 -bios
-/path/to/tztest.img -serial stdio -m 1024 -semihosting
+ ./configure
-arm-linux-gnueabi-objdump -xdSt tztest
+For more options use "-?"
+ ./configure -?
+
+Other platforms/cpus can be specified as follows:
+
+ ./configure --plat=virt --cpu=cortex-a15
+
+
+BUILD
+-----
+Once configured, the test can be built my simply using make. This will produce
+an output test image that can be used with QEMU.
+
+ make
+
+The test image can also be built with debug verbosity for extended runtime
+messages by building as follows.
+
+ CFLAGS=-DDEBUG make
+
+
+RUN
+----
+Using compatible machine and cpu properties, the output test image can be run
+using the following QEMU command line:
+
+ ./arm-softmmu/qemu-system-arm -machine <plat> -cpu <cpu> -bios
+ /path/to/tztest.img -serial stdio -m 1024
+
+For example, to run the default vexpress-a15 test image on qemu:
+
+ arm-softmmu/qemu-system-arm -bios ~/git/qemu.tztest/arm/tztest.img \
+ -serial stdio -m 1024 -machine type=vexpress-a15 -cpu cortex-a15
+
+DEBUG
+-----
+A number of facilities are provided for assiting in debugging. Both secure and
+non-secure test ELF binaries are produced and made available for debugging.
+
+tztest_nonsecure.elf
+tztest_secure.elf
+
+A GDB script is provided for loading and debugging these ELF files with GDB.
+To debug, do the following:
+
+Start QEMU with GDB enabled and waiting.
+
+ ./arm-softmmu/qemu-system-arm ... -s -S
+
+Start gdb-multiarch from the root of the test directory. No options are needed
+as the supplied .gdbinit should load the ELF images at the correct addresses.
+
+ gdb-multiarch
diff --git a/arm/Makefile.tztest b/arm/Makefile.tztest
index f697256..052e2fa 100644
--- a/arm/Makefile.tztest
+++ b/arm/Makefile.tztest
@@ -7,33 +7,22 @@ TZBOOT = $(ARCH)/tzboot.o
TZSECLOAD = $(ARCH)/tztest_secure.lds
TZNSECLOAD = $(ARCH)/tztest_nonsecure.lds
TZSECOBJS = $(ARCH)/secure_init.o \
- $(ARCH)/tztest_secure_svc.o \
+ $(ARCH)/secure_svc.o \
+ $(ARCH)/secure_asm.o \
+ $(ARCH)/monitor.o \
+ $(ARCH)/monitor_asm.o \
$(ARCH)/sm_asm.o \
$(ARCH)/sm.o
TZNSECOBJS = $(ARCH)/nonsecure_init.o \
- $(ARCH)/tztest_nonsecure_svc.o \
+ $(ARCH)/nonsecure_svc.o \
$(ARCH)/tztest.o
-TZOBJS = $(ARCH)/tztest_mmu.o \
- $(ARCH)/tztest_common.o
-LIBCFLAT_OBJS += $(LIBCFLAT_objdir)/devicetree.o \
- $(LIBCFLAT_objdir)/virtio.o \
- $(LIBCFLAT_objdir)/virtio-testdev.o \
- $(LIBCFLAT_archdir)/io.o \
- $(LIBCFLAT_archdir)/misc.o \
- $(LIBCFLAT_archdir)/setup.o \
- $(LIBCFLAT_archdir)/spinlock.o \
- $(LIBCFLAT_archdir)/processor.o
+TZOBJS = $(ARCH)/common_mmu.o \
+ $(ARCH)/common_svc.o
all: $(TZTEST_IMAGE)
##################################################################
-libeabi = $(LIBCFLAT_archdir)/libeabi.a
-eabiobjs = $(LIBCFLAT_archdir)/eabi_compat.o
-libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name)
-CFLAGS += -I$(ARCH) -DASM
-
-FLATLIBS = $(LIBCFLAT_archive) $(LIBFDT_archive) $(libgcc) $(libeabi)
COMMON = $(FLATLIBS) $(TZOBJS)
$(SECTEST): $(TZSECOBJS) $(COMMON) $(TZSECLOAD) $(TZNSECLOAD) $(TZBOOT)
@@ -65,15 +54,9 @@ $(TZNSECLOAD): $(ARCH)/tztest_nonsecure.lds.S Makefile platform/$(PLAT)/
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
-$(libeabi): $(eabiobjs)
- $(AR) rcs $@ $^
-
-arch_clean: libeabi_clean
+arch_clean:
$(RM) $(TZOBJS) $(TZSECOBJS) $(TZNSECOBJS) \
$(TZSECLOAD) $(TZNSECLOAD) $(TZBOOT) \
$(SECTEST) $(SECTESTIMAGE) $(NSECTEST) $(NSECTESTIMAGE) \
$(TZTEST_IMAGE) \
$(LIBCFLAT_OBJS) $(LIBCFLAT_archdir)/.*.d $(ARCH)/.*.d
-
-libeabi_clean:
- $(RM) $(libeabi) $(eabiobjs)
diff --git a/arm/arm32.h b/arm/arm32.h
index 2c5e963..1dd46a5 100644
--- a/arm/arm32.h
+++ b/arm/arm32.h
@@ -45,6 +45,7 @@
#define CPSR_T (1 << 5)
#define CPSR_F (1 << 6)
#define CPSR_I (1 << 7)
+#define CPSR_A (1 << 8)
#define MPIDR_CPU_MASK 0xff
#define MPIDR_CLUSTER_MASK (0xff << 8)
diff --git a/arm/tztest_asm.h b/arm/common_defs.h
index de46a6b..de46a6b 100644
--- a/arm/tztest_asm.h
+++ b/arm/common_defs.h
diff --git a/arm/common_mmu.c b/arm/common_mmu.c
new file mode 100644
index 0000000..cf9fc15
--- /dev/null
+++ b/arm/common_mmu.c
@@ -0,0 +1,128 @@
+#include "common_svc.h"
+#include "common_mmu.h"
+#include "common_defs.h"
+
+void pagetable_add_section_entries(uint32_t *ttbr, pagetable_map_entry_t *pe)
+{
+ uint32_t va = pe->va;
+ uint32_t pa = pe->pa;
+ uint32_t len = pe->len;
+ uint32_t l1idx = va >> L1_INDEX_SHIFT;
+ uint32_t l1attr = SECTION;
+ uint32_t size = SECTION_SIZE;
+
+ l1attr |= IS_SET(pe, NONSECURE) ? SECTION_NS : 0;
+ l1attr |= IS_SET(pe, P0_R)
+ ? IS_SET(pe, P0_W) ? SECTION_P0_RW : SECTION_P0_RO
+ : SECTION_P0_NONE;
+ l1attr |= IS_SET(pe, P1_R)
+ ? IS_SET(pe, P1_W) ? SECTION_P1_RW : SECTION_P1_RO
+ : SECTION_P1_NONE;
+ l1attr |= IS_SET(pe, P0_X) ? 0 : SECTION_XN;
+ l1attr |= IS_SET(pe, P1_X) ? 0 : SECTION_PXN;
+ l1attr |= IS_SET(pe, NOTGLOBAL) ? (SECTION_NG) : 0;
+ l1attr |= IS_SET(pe, DEVICE)
+ ? IS_SET(pe, SHARED)
+ ? SECTION_DEVICE_SHAREABLE : SECTION_DEVICE_UNSHAREABLE
+ : IS_SET(pe, SHARED) ? (SECTION_S) : 0;
+ l1attr |= IS_SET(pe, WT_CACHED)
+ ? SECTION_WT_CACHED : IS_SET(pe, WB_CACHED)
+ ? SECTION_WB_CACHED
+ : IS_SET(pe, WBA_CACHED)
+ ? SECTION_WBA_CACHED : SECTION_UNCACHED;
+
+ /* Round up to the next segment increment */
+ len = (len + (SECTION_SIZE-1)) & ~(SECTION_SIZE-1);
+
+ for (; len > 0; va += size, pa += size, len -= size) {
+ l1idx = L1_INDEX(va);
+ ttbr[l1idx] = (pa & SECTION_PA_MASK) | l1attr;
+ DEBUG_MSG("Mapped L1 0x%x to 0x%x (%p (0x%x) = 0x%x)\n",
+ va, pa, &ttbr[l1idx], l1idx, ttbr[l1idx]);
+ }
+}
+
+void pagetable_add_page_entries(uint32_t *ttbr, pagetable_map_entry_t *pe)
+{
+ uint32_t va = pe->va;
+ uint32_t pa = pe->pa;
+ uint32_t len = pe->len;
+ uint32_t l2len = 0;;
+ uint32_t *l2base = ttbr + BYTE_TO_INT(L1_TABLE_SIZE);
+ uint32_t *l2addr;
+ uint32_t size = PAGE_SIZE(PAGE);
+ uint32_t l1attr = L1_TYPE_PAGE, l2attr = L2_TYPE(pe->type);
+ uint32_t l1idx, l2idx;
+
+ l1attr |= IS_SET(pe, NONSECURE) ? PAGE_NS : 0;
+ l1attr |= IS_SET(pe, P1_X) ? 0 : PAGE_PXN;
+
+ l2attr |= IS_SET(pe, P0_R)
+ ? IS_SET(pe, P0_W) ? PAGE_P0_RW : PAGE_P0_RO
+ : PAGE_P0_NONE;
+ l2attr |= IS_SET(pe, P1_R)
+ ? IS_SET(pe, P1_W) ? PAGE_P1_RW : PAGE_P1_RO
+ : PAGE_P1_NONE;
+ l2attr |= IS_SET(pe, P0_X) ? 0 : PAGE_XN(PAGE_SMALL);
+ l2attr |= IS_SET(pe, NOTGLOBAL) ? (PAGE_NG) : 0;
+ l2attr |= IS_SET(pe, DEVICE)
+ ? IS_SET(pe, SHARED)
+ ? PAGE_DEVICE_SHAREABLE
+ : PAGE_DEVICE_UNSHAREABLE(PAGE_SMALL)
+ : IS_SET(pe, SHARED) ? (PAGE_S) : 0;
+ l2attr |= IS_SET(pe, WT_CACHED)
+ ? PAGE_WT_CACHED
+ : IS_SET(pe, WB_CACHED)
+ ? PAGE_WB_CACHED
+ : IS_SET(pe, WBA_CACHED)
+ ? PAGE_WBA_CACHED(PAGE_SMALL)
+ : PAGE_UNCACHED(PAGE_SMALL);
+
+ /* Round up to the next page increment */
+ len = (len + (PAGE_SIZE(PAGE)-1)) & ~(PAGE_SIZE(PAGE)-1);
+
+ while (len > 0) {
+ l1idx = L1_INDEX(va);
+ l2addr = l2base + BYTE_TO_INT(L2_TABLE_SIZE * l1idx);
+ ttbr[l1idx] = (uint32_t)l2addr | l1attr;
+
+ DEBUG_MSG("Added L1 0x%x to 0x%x (ttbrn[%x] = %x)\n",
+ va, l2addr, l1idx, ttbr[l1idx]);
+
+ /* Set the level 2 page table size to the smaller of the total
+ * remaining length or the remaining length in the 1MB section.
+ */
+ l2len = L1_MAP_SIZE - (va & (L1_MAP_SIZE - 1));
+ l2len = (l2len > len) ? len : l2len;
+
+ for (; l2len > 0; va += size, pa += size, l2len -= size, len -= size) {
+ l2idx = L2_INDEX(va);
+ l2addr[l2idx] = (pa & PAGE_PA_MASK) | l2attr;
+ DEBUG_MSG("Mapped L2 0x%x to 0x%x (%p (0x%x) = 0x%x)\n",
+ va, pa, &l2addr[l2idx], l2idx, l2addr[l2idx]);
+ }
+ }
+}
+
+void pagetable_add_entries(uint32_t *ttbr, pagetable_map_entry_t *entries,
+ uint32_t count)
+{
+ uint32_t i;
+
+ for (i = 0; i < count; i++) {
+ if (entries[i].type == SECTION) {
+ pagetable_add_section_entries(ttbr, &entries[i]);
+ } else if (entries[i].type == PAGE || entries[i].type == LARGE_PAGE) {
+ pagetable_add_page_entries(ttbr, &entries[i]);
+ }
+ }
+}
+
+void pagetable_init(uint32_t *ttbr)
+{
+ int i;
+
+ for (i = 0; i < BYTE_TO_INT(L1_TABLE_SIZE); i++) {
+ ttbr[i] = 0;
+ }
+}
diff --git a/arm/common_mmu.h b/arm/common_mmu.h
new file mode 100644
index 0000000..43da031
--- /dev/null
+++ b/arm/common_mmu.h
@@ -0,0 +1,145 @@
+
+#ifndef _TZTEST_MMU_H
+#define _TZTEST_MMU_H
+
+#include "sm.h"
+
+#define LARGE_PAGE (0 << 0)
+#define PAGE (1 << 0)
+#define SECTION (1 << 1)
+#define SECURE (0 << 0)
+#define NONSECURE (1 << 0)
+#define P0_R (1 << 1)
+#define P0_W (2 << 1)
+#define P0_X (4 << 1)
+#define P0_NONE (0 << 1)
+#define P1_R (1 << 4)
+#define P1_W (2 << 4)
+#define P1_X (4 << 4)
+#define SHARED (1 << 7)
+#define NOTGLOBAL (1 << 8)
+#define DEVICE (1 << 9)
+#define UNCACHED (0 << 10)
+#define WT_CACHED (1 << 10)
+#define WB_CACHED (2 << 10)
+#define WBA_CACHED (3 << 10)
+#define DOMAIN(_d) ((_d) << 16)
+
+#define L1_TYPE_PAGE (1 << 0)
+#define L1_TYPE_SECTION ((0 << 18) | (1 << 1))
+
+#define L1_INDEX_BITS 12
+#define L1_TABLE_SIZE ((1 << L1_INDEX_BITS) << 2)
+#define L1_INDEX_SHIFT 20
+#define L1_MAP_SIZE (1 << L1_INDEX_SHIFT)
+#define L1_INDEX_MASK ((1 << L1_INDEX_BITS) - 1)
+
+#define L2_TYPE(_sz) (1 << (_sz))
+
+#define L2_INDEX_BITS 8
+#define L2_TABLE_SIZE (1 << 10)
+#define L2_INDEX_SHIFT 12
+#define L2_MAP_SIZE (1 << L2_INDEX_SHIFT)
+#define L2_INDEX_MASK ((1 << L2_INDEX_BITS) - 1)
+
+#define BYTE_TO_INT(_val) ((_val) >> 2)
+#define INT_TO_BYTE(_val) ((_val) << 2)
+#define L1_INDEX(_va) (((_va)>>L1_INDEX_SHIFT) & L1_INDEX_MASK)
+#define L2_INDEX(_va) (((_va)>>L2_INDEX_SHIFT) & L2_INDEX_MASK)
+
+#define SECTION_PXN (1 << 0)
+#define SECTION_B (1 << 2)
+#define SECTION_C (1 << 3)
+#define SECTION_XN (1 << 4)
+#define SECTION_DOMAIN(_d) ((_d) << 5)
+#define SECTION_NS (1 << 19)
+#define SECTION_TEX(v) (1 << 12)
+#define SECTION_S (1 << 16)
+#define SECTION_NG (1 << 17)
+#define SECTION_SIZE L1_MAP_SIZE
+#define SECTION_PA_SHIFT L1_INDEX_SHIFT
+#define SECTION_PA_MASK ~((1 << SECTION_PA_SHIFT) - 1)
+
+/* Fix SCTLR.AFE bit */
+
+#define SECTION_P1_RW ((0 << 15) | (1 << 10))
+#define SECTION_P1_RO ((1 << 15) | (1 << 10))
+#define SECTION_P1_NONE 0
+#define SECTION_P0_RW ((0 << 15) | (3 << 10))
+#define SECTION_P0_RO ((0 << 15) | (2 << 10))
+#define SECTION_P0_NONE ((0 << 15) | (1 << 10))
+
+/* These remap description describe the memory region if SCTLR.TRE = 0
+ * (no region atrribute remap).
+ */
+#define SECTION_DEVICE_SHAREABLE (SECTION_B)
+#define SECTION_DEVICE_UNSHAREABLE (SECTION_TEX(2))
+#define SECTION_WT_CACHED (SECTION_C)
+#define SECTION_WB_CACHED (SECTION_C | SECTION_B)
+#define SECTION_UNCACHED (SECTION_TEX(1))
+#define SECTION_WBA_CACHED (SECTION_TEX(1) | SECTION_C | SECTION_B)
+
+#define SMALL_PAGE_SIZE 0x1000
+#define LARGE_PAGE_SIZE 0x10000
+#define PAGE_SIZE(_type) ((_type == PAGE) \
+ ? SMALL_PAGE_SIZE : LARGE_PAGE_SIZE)
+
+#define PAGE_PASHIFT L2_INDEX_SHIFT
+#define PAGE_PA_MASK ~((1 << PAGE_PASHIFT) - 1)
+#define PAGE_LARGE (0 << 1)
+#define PAGE_SMALL (1 << 1)
+#define PAGE_PXN (1 << 2)
+#define PAGE_NS (1 << 3)
+#define PAGE_DOMAIN(_d) ((_d) << 5)
+#define PAGE_B (1 << 2)
+#define PAGE_C (1 << 3)
+#define PAGE_LARGE_XN (1 << 15)
+#define PAGE_SMALL_XN (1 << 0)
+#define PAGE_XN(_sz) ((PAGE_LARGE == (_sz)) \
+ ? PAGE_LARGE_XN : PAGE_SMALL_XN)
+#define PAGE_S (1 << 10)
+#define PAGE_NG (1 << 11)
+#define PAGE_LARGE_TEX(_v) ((_v) << 12)
+#define PAGE_SMALL_TEX(_v) ((_v) << 6)
+#define PAGE_TEX(_sz, _v) (PAGE_LARGE == (_sz)) \
+ ? PAGE_LARGE_TEX(_v) \
+ : PAGE_SMALL_TEX(_v)
+
+#define PAGE_P1_RW ((0 << 9) | (1 << 4))
+#define PAGE_P1_RO ((1 << 9) | (1 << 4))
+#define PAGE_P1_NONE 0
+#define PAGE_P0_RW ((0 << 9) | (3 << 4))
+#define PAGE_P0_RO ((0 << 9) | (2 << 4))
+#define PAGE_P0_NONE ((0 << 9) | (1 << 4))
+
+/* These remap description describe the memory region if SCTLR.TRE = 0
+ * (no region atrribute remap).
+ */
+#define PAGE_DEVICE_SHAREABLE (PAGE_B)
+#define PAGE_DEVICE_UNSHAREABLE(_sz) (PAGE_TEX((_sz), 2))
+#define PAGE_WT_CACHED (PAGE_C)
+#define PAGE_WB_CACHED (PAGE_C | PAGE_B)
+#define PAGE_UNCACHED(_sz) (PAGE_TEX((_sz), 1))
+#define PAGE_WBA_CACHED(_sz) (PAGE_TEX((_sz), 1) | PAGE_C | PAGE_B)
+
+typedef struct {
+ uint32_t type;
+ uint32_t va;
+ uint32_t pa;
+ uint32_t len;
+ uint32_t attr;
+} pagetable_map_entry_t;
+
+#define ENTRIES_COUNT(_ent) (sizeof(_ent)/sizeof((_ent)[0]))
+
+#define PT_ADD_ENTRIES(_tbl, _ent) \
+ pagetable_add_entries((_tbl), (_ent), ENTRIES_COUNT(_ent))
+#define IS_SET(_pe, _attr) ((_attr) == ((_pe)->attr & (_attr)))
+
+
+extern void pagetable_init(uint32_t *);
+extern void pagetable_init_common(uint32_t *table);
+extern void pagetable_add_entries(uint32_t *, pagetable_map_entry_t *,
+ uint32_t);
+
+#endif
diff --git a/arm/common_svc.c b/arm/common_svc.c
new file mode 100644
index 0000000..666bcbf
--- /dev/null
+++ b/arm/common_svc.c
@@ -0,0 +1,42 @@
+#include "common_svc.h"
+#include "common_mmu.h"
+#include "common_defs.h"
+#include "sm.h"
+
+extern uint32_t _shared_memory_heap_base;
+
+pagetable_map_entry_t uart_pagetable_entries[] = {
+ {.va = UART0_BASE, .pa = UART0_BASE, .type = PAGE, .len = 0x1000,
+ .attr = SHARED | NOTGLOBAL | UNCACHED | P1_R | P1_W | P0_R | P0_W |
+ NONSECURE },
+};
+
+pagetable_map_entry_t heap_pagetable_entries[] = {
+ {.va = (uint32_t)&_shared_memory_heap_base,
+ .pa = (uint32_t)&_shared_memory_heap_base,
+ .type = PAGE, .len = 0x1000,
+ .attr = SHARED | NOTGLOBAL | UNCACHED | P1_R | P1_W | P0_R | P0_W },
+};
+
+void pagetable_init_common(uint32_t *table)
+{
+ PT_ADD_ENTRIES(table, uart_pagetable_entries);
+ PT_ADD_ENTRIES(table, heap_pagetable_entries);
+}
+
+#ifdef DEBUG
+void validate_state(uint32_t mode, uint32_t state)
+{
+ tztest_svc_desc_t desc;
+
+ assert((_read_cpsr() & CPSR_MODE_MASK) == mode);
+
+ CLEAR_SVC_DESC(desc);
+ __svc(SVC_GET_SECURE_STATE, &desc);
+ assert(desc.secure_state.state == state);
+}
+#else
+void validate_state(__attribute__((unused)) uint32_t mode,
+ __attribute__((unused)) uint32_t state) {}
+#endif
+
diff --git a/arm/common_svc.h b/arm/common_svc.h
new file mode 100644
index 0000000..a9f19d5
--- /dev/null
+++ b/arm/common_svc.h
@@ -0,0 +1,71 @@
+#ifndef _COMMON_SVC_H
+#define _COMMON_SVC_H
+
+#include "tztest_builtins.h"
+#include "sm.h"
+#include "libcflat.h"
+
+typedef struct {
+ uint32_t (*func)(uint32_t);
+ uint32_t arg;
+ uint32_t ret;
+} tztest_dispatch_t;
+
+typedef struct {
+ union {
+ tztest_dispatch_t dispatch;
+ struct {
+ uint32_t reg;
+ uint32_t val;
+ } reg_read;
+ struct {
+ uint32_t state;
+ } secure_state;
+ };
+} tztest_svc_desc_t;
+
+#define CLEAR_SVC_DESC(_desc) memset(&(_desc), sizeof(tztest_svc_desc_t), 0)
+
+typedef struct {
+ union {
+ tztest_dispatch_t dispatch;
+ };
+} tztest_smc_desc_t;
+
+#ifdef DEBUG
+#define DEBUG_MSG(_str, ...) \
+ printf("\n[DEBUG] %s: " _str, __FUNCTION__, ##__VA_ARGS__)
+#define DEBUG_ARG
+#else
+#define DEBUG_MSG(_str, ...)
+#define DEBUG_ARG __attribute__ ((unused))
+#endif
+
+#define MODE_STR(_mode) \
+ ((_mode == MON) ? "MON" : \
+ (_mode == SVC) ? "SVC" : \
+ (_mode == SYS) ? "SYS" : \
+ (_mode == USR) ? "USR" : "Unknown")
+
+
+#define FAULT_STR(_s) \
+ ((0x01 == (_s)) ? "Alignment fault" : \
+ (0x02 == (_s)) ? "Debug event" : \
+ (0x03 == (_s)) ? "Access flag fault" : \
+ (0x04 == (_s)) ? "Instruction cache maintenance" : \
+ (0x05 == (_s)) ? "Translation fault" : \
+ (0x06 == (_s)) ? "Access flag fault" : \
+ (0x07 == (_s)) ? "Translation fault" : \
+ (0x08 == (_s)) ? "Synchronous external abort" : \
+ (0x09 == (_s)) ? "Domain fault" : \
+ (0x0b == (_s)) ? "Domain fault" : \
+ (0x0c == (_s)) ? "External abort on table walk" : \
+ (0x0d == (_s)) ? "Permisison fault" : \
+ (0x0e == (_s)) ? "Synchronous external abort" : \
+ (0x0f == (_s)) ? "Permisison fault" : \
+ (0x10 == (_s)) ? "TLB conflict abort" : \
+ (0x1c == (_s)) ? "External parity err on table walk" : \
+ (0x1e == (_s)) ? "External parity err on table walk" : \
+ "Unknown")
+
+#endif
diff --git a/arm/monitor.c b/arm/monitor.c
new file mode 100644
index 0000000..32675a8
--- /dev/null
+++ b/arm/monitor.c
@@ -0,0 +1,25 @@
+
+#include "common_svc.h"
+#include "common_defs.h"
+
+void monitor_init_ns_entry(uint32_t entry_point)
+{
+ struct sm_nsec_ctx *nsec_ctx;
+
+
+ /* Set-up the non-secure context so that the switch to nonsecure state
+ * resumes at initiallizing the nonsecure svc mode.
+ */
+ nsec_ctx = sm_get_nsec_ctx();
+ nsec_ctx->mon_lr = entry_point;
+ nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I;
+}
+
+
+void monitor_dispatch(tztest_smc_desc_t *desc)
+{
+ uint32_t (*func)(uint32_t) = desc->dispatch.func;
+ DEBUG_MSG("Entered\n");
+ desc->dispatch.ret = func(desc->dispatch.arg);
+ DEBUG_MSG("Exiting\n");
+}
diff --git a/arm/monitor_asm.S b/arm/monitor_asm.S
new file mode 100644
index 0000000..9105a68
--- /dev/null
+++ b/arm/monitor_asm.S
@@ -0,0 +1,50 @@
+
+#include "common_defs.h"
+
+.align 5
+.global monitor_vectors
+monitor_vectors:
+ b . /* Reset */
+ b . /* Undefined instruction */
+ b monitor_smc_vect /* Secure monitor call */
+ b . /* Prefetch abort */
+ b . /* Data abort */
+ b . /* Reserved */
+ b . /* IRQ */
+ b . /* FIQ */
+
+monitor_smc_vect:
+ cmp r0, #SMC_YIELD
+ bge sm_smc_entry
+ srsdb sp!, #CPSR_MODE_MON
+ cmp r0, #SMC_NOOP
+ beq 1f
+ push {r0-r3}
+ mov r0, r1
+ bl monitor_dispatch
+ pop {r0-r3}
+1: rfefd sp!
+
+.global monitor_init
+/* monitor_init(nonsecure_entrypt) */
+monitor_init:
+ push {lr}
+
+ /* Set-up the monitor stack */
+ mrs r10, cpsr
+ cps #CPSR_MODE_MON
+ ldr sp, =mon_stacktop
+ msr cpsr, r10
+
+ /* Set-up mvbar */
+ ldr r10, =monitor_vectors
+ mcr p15, 0, r10, c12, c0, 1
+
+ /* Call to set the nonsecure entry point to be the save r0 value passed in
+ * by the boot code. This will be the initial entry point on the first
+ * monitor context switch.
+ */
+ bl monitor_init_ns_entry
+
+ pop {pc}
+
diff --git a/arm/nonsecure_init.S b/arm/nonsecure_init.S
index d1d8c2c..656454e 100644
--- a/arm/nonsecure_init.S
+++ b/arm/nonsecure_init.S
@@ -1,7 +1,10 @@
-#include "tztest_asm.h"
-
-b nonsecure_vectors
+#include "common_defs.h"
+/* The nonsecure image load code must be placed at the beginning of the image
+ * as this is the starting point for the boot code to load. The loader code
+ * will pass the initial starting point back to the boot code for later
+ * execution.
+ */
nonsecure_load:
ldr r0, =_flash_nsectext_start
ldr r1, =_ram_nsectext_start
@@ -21,6 +24,7 @@ copy_nsecdata:
subs r2, r2, #1
bne copy_nsecdata
+ ldr r0, =nonsecure_init
mov pc, lr
.align 5
@@ -39,24 +43,24 @@ nonsecure_vectors:
nonsecure_undef_vec:
srsdb sp!, #CPSR_MODE_UND
- bl nsec_undef_handler
+ bl nonsecure_undef_handler
rfefd sp!
nonsecure_pabort_vec:
mrc p15, 0, r0, c5, c0, 1 /* IFSR */
mrc p15, 0, r1, c6, c0, 2 /* IFAR */
- bl nsec_pabort_handler
+ bl nonsecure_pabort_handler
b end
nonsecure_dabort_vec:
mrc p15, 0, r0, c5, c0, 0 /* DFSR */
mrc p15, 0, r1, c6, c0, 0 /* DFAR */
- bl nsec_dabort_handler
+ bl nonsecure_dabort_handler
b end
nonsecure_svc_vec:
srsdb sp!, #CPSR_MODE_SVC
- bl nsec_svc_handler
+ bl nonsecure_svc_handler
rfefd sp!
nonsecure_init:
@@ -105,12 +109,12 @@ nonsecure_mmu_init:
mcr p15, 0, r10, c3, c0, 0
/* This function will return the initialized base address */
- bl tztest_nonsecure_pagetable_init
+ bl nonsecure_pagetable_init
/* Set TTBR0 to the initialized address plus enable shareable write-back
* write-allocate.
*/
- ldr r10, =nsec_l1_page_table
+ ldr r10, =_nsec_l1_page_table
orr r10, r10, #0xB
mcr p15, 0, r10, c2, c0, 0
diff --git a/arm/nonsecure_loader.h b/arm/nonsecure_loader.h
new file mode 100644
index 0000000..f19b12f
--- /dev/null
+++ b/arm/nonsecure_loader.h
@@ -0,0 +1,18 @@
+#ifndef _NONSECURE_LOADER_H
+#define _NONSECURE_LOADER_H
+#include "sm.h"
+
+extern uint32_t _nsec_l1_page_table;
+extern uint32_t _ram_nsectext_start;
+extern uint32_t _ram_nsecdata_start;
+extern uint32_t _nsecstack_start;
+extern uint32_t _nsectext_size;
+extern uint32_t _nsecdata_size;
+extern uint32_t _nsecstack_size;
+extern uint32_t _shared_memory_heap_base;
+extern uint32_t _common_memory_heap_base;
+extern volatile int _tztest_exception;
+extern volatile int _tztest_exception_status;
+extern volatile int _tztest_exception_addr;
+
+#endif
diff --git a/arm/nonsecure_svc.c b/arm/nonsecure_svc.c
new file mode 100644
index 0000000..332dc51
--- /dev/null
+++ b/arm/nonsecure_svc.c
@@ -0,0 +1,138 @@
+#include "nonsecure_loader.h"
+#include "common_svc.h"
+#include "common_mmu.h"
+#include "common_defs.h"
+
+uint32_t nonsecure_dispatch_sec_usr_function(uint32_t (*)(uint32_t), uint32_t);
+uint32_t nonsecure_dispatch_sec_svc_function(uint32_t (*)(uint32_t), uint32_t);
+uint32_t *nsec_l1_page_table = &_nsec_l1_page_table;
+volatile int *tztest_exception = &_tztest_exception;
+volatile int *tztest_exception_addr = &_tztest_exception_addr;
+volatile int *tztest_exception_status = &_tztest_exception_status;
+uint32_t ram_nsectext_start = (uint32_t)&_ram_nsectext_start;
+uint32_t ram_nsecdata_start = (uint32_t)&_ram_nsecdata_start;
+uint32_t nsecstack_start = (uint32_t)&_nsecstack_start;
+uint32_t nsectext_size = (uint32_t)&_nsectext_size;
+uint32_t nsecdata_size = (uint32_t)&_nsecdata_size;
+uint32_t nsecstack_size = (uint32_t)&_nsecstack_size;
+tztest_smc_desc_t smc_desc;
+
+void nonsecure_svc_handler(volatile uint32_t op,
+ volatile tztest_svc_desc_t *desc)
+{
+ int ret = 0;
+ switch (op) {
+ case SVC_DISPATCH_MONITOR:
+ op = SMC_DISPATCH_MONITOR;
+ __smc(op, desc);
+ break;
+ case SVC_DISPATCH_SECURE_USR:
+ DEBUG_MSG("Dispatching secure usr function\n");
+ desc->dispatch.ret =
+ nonsecure_dispatch_sec_usr_function(desc->dispatch.func,
+ desc->dispatch.arg);
+ DEBUG_MSG("Returning from secure usr function, ret = 0x%x\n",
+ desc->dispatch.ret);
+ break;
+ case SVC_DISPATCH_SECURE_SVC:
+ DEBUG_MSG("Dispatching secure svc function\n");
+ desc->dispatch.ret =
+ nonsecure_dispatch_sec_svc_function(desc->dispatch.func,
+ desc->dispatch.arg);
+ DEBUG_MSG("Returning from secure svc function, ret = 0x%x\n",
+ desc->dispatch.ret);
+ break;
+ case SVC_DISPATCH_NONSECURE_SVC:
+ DEBUG_MSG("Dispatching nonsecure svc function\n");
+ desc->dispatch.ret = desc->dispatch.func(desc->dispatch.arg);
+ DEBUG_MSG("Returning from nonsecure svc function, ret = 0x%x\n",
+ desc->dispatch.ret);
+ break;
+ case SVC_GET_SECURE_STATE:
+ /* This SVC handler is only accessible from the nonsecure vector
+ * table, so unless something went drastically wrong with the
+ * tables, it should be safe to assume we are in a nonsecure state.
+ */
+ desc->secure_state.state = TZTEST_STATE_NONSECURE;
+ break;
+ case SVC_EXIT:
+ op = SMC_EXIT;
+ __smc(op, ret);
+ break;
+ }
+}
+
+void nonsecure_undef_handler() {
+ DEBUG_MSG("Undefined exception taken\n");
+ *tztest_exception = CPSR_MODE_UND;
+ *tztest_exception_status = 0;
+}
+
+void nonsecure_pabort_handler(int status, DEBUG_ARG int addr) {
+ DEBUG_MSG("status = 0x%x\taddress = 0x%x\n", status, addr);
+ *tztest_exception = CPSR_MODE_ABT;
+ *tztest_exception_status = status & 0x1f;
+}
+
+void nonsecure_dabort_handler(int status, DEBUG_ARG int addr) {
+ DEBUG_MSG("Data Abort: %s\n", FAULT_STR(status & 0x1f));
+ DEBUG_MSG("status = 0x%x\taddress = 0x%x\n",
+ status & 0x1f, addr);
+ *tztest_exception = CPSR_MODE_ABT;
+ *tztest_exception_status = status & 0x1f;
+}
+
+uint32_t nonsecure_dispatch_sec_usr_function(uint32_t (*func)(uint32_t),
+ uint32_t arg)
+{
+ volatile int r0 = SMC_DISPATCH_SECURE_USR;
+ tztest_smc_desc_t *desc_p = &smc_desc;
+
+ smc_desc.dispatch.func = func;
+ smc_desc.dispatch.arg = arg;
+ DEBUG_MSG("Entered\n");
+ __smc(r0, desc_p);
+ DEBUG_MSG("Exiting, func = 0x%x\n", smc_desc.dispatch.func);
+ return smc_desc.dispatch.ret;
+}
+
+uint32_t nonsecure_dispatch_sec_svc_function(uint32_t (*func)(uint32_t),
+ uint32_t arg)
+{
+ volatile int op = SMC_DISPATCH_SECURE_SVC;
+ tztest_smc_desc_t desc, *desc_p = &desc;
+
+ desc.dispatch.func = func;
+ desc.dispatch.arg = arg;
+ DEBUG_MSG("Entered op = %x\n", op);
+ __smc(op, desc_p);
+ DEBUG_MSG("Exiting\n");
+ return desc.dispatch.ret;
+}
+
+void nonsecure_pagetable_init()
+{
+ pagetable_map_entry_t nsec_pagetable_entries[] = {
+ {.va = (uint32_t)ram_nsectext_start, .pa = (uint32_t)ram_nsectext_start,
+ .type = PAGE, .len = nsectext_size,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_X | P0_R | P0_X |
+ NONSECURE },
+ {.va = (uint32_t)ram_nsecdata_start, .pa = (uint32_t)ram_nsecdata_start,
+ .type = PAGE, .len = nsecdata_size,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_W | P0_R | P0_W |
+ NONSECURE },
+ {.va = (uint32_t)nsecstack_start, .pa = (uint32_t)nsecstack_start,
+ .type = PAGE, .len = nsecstack_size,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_W | P0_R | P0_W |
+ NONSECURE },
+ {.va = (uint32_t)nsec_l1_page_table, .pa = (uint32_t)nsec_l1_page_table,
+ .type = SECTION, .len = 16*1024*1024,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_W },
+ };
+
+ pagetable_init(nsec_l1_page_table);
+
+ PT_ADD_ENTRIES(nsec_l1_page_table, nsec_pagetable_entries);
+
+ pagetable_init_common(nsec_l1_page_table);
+}
diff --git a/arm/secure_asm.S b/arm/secure_asm.S
new file mode 100644
index 0000000..9761a6c
--- /dev/null
+++ b/arm/secure_asm.S
@@ -0,0 +1,40 @@
+
+#include "common_defs.h"
+
+.global secure_dispatch_usr
+secure_dispatch_usr:
+ /* Push the LR onto the stack so we can return immediately from the svc
+ * handler on return.
+ */
+ push {lr}
+
+ /* Reset the user stack for the dispatch, so we have a clean stack */
+ cps #CPSR_MODE_SYS
+ ldr sp, =sec_usr_stacktop
+ push {r0, r1}
+ cps #CPSR_MODE_SVC
+
+ /* Return to USR mode to execute the dispatch function in r0
+ */
+ ldr r0, =dispatch_usr_wrapper
+ mov r1, #CPSR_MODE_USR
+ push {r0, r1}
+ rfefd sp!
+
+/* This is the user-side dispatch wrapper that accepts the function pointer and
+ * function arg in r0 & r1 respectively. The wrapper is simply an anstraction
+ * layer for translating the input parameters into the user function call.
+ */
+dispatch_usr_wrapper:
+ pop {r0, r1}
+ mov r2, r0
+ mov r0, r1
+ mov pc, r2
+
+.global secure_shutdown
+secure_shutdown:
+ ldr r0, =SYSREG_BASE
+ add r0, r0, #SYSREG_CFGCTRL
+ ldr r1, =SYS_SHUTDOWN
+ str r1, [r0]
+ b secure_shutdown
diff --git a/arm/secure_init.S b/arm/secure_init.S
index a911aa0..c77838f 100644
--- a/arm/secure_init.S
+++ b/arm/secure_init.S
@@ -1,8 +1,8 @@
-#include "tztest_asm.h"
+#include "common_defs.h"
.arch_extension sec
-.align 5
+.section .vectors, "ax"
secure_vectors:
b secure_init /* reset */
b secure_undef_vec /* undef */
@@ -15,19 +15,22 @@ secure_vectors:
secure_undef_vec:
srsdb sp!, #CPSR_MODE_UND
- bl sec_undef_handler
+ push {r10}
+ ldr r10, =secure_undef_handler
+ blx r10
+ pop {r10}
rfefd sp!
secure_pabort_vec:
mrc p15, 0, r0, c5, c0, 1 /* IFSR */
mrc p15, 0, r1, c6, c0, 2 /* IFAR */
- bl sec_pabort_handler
+ bl secure_pabort_handler
b end
secure_dabort_vec:
mrc p15, 0, r0, c5, c0, 0 /* DFSR */
mrc p15, 0, r1, c6, c0, 0 /* DFAR */
- bl sec_dabort_handler
+ bl secure_dabort_handler
b end
secure_svc_vec:
@@ -45,47 +48,32 @@ secure_svc_vec:
pop {pc}
1:
srsdb sp!, #CPSR_MODE_SVC
- bl sec_svc_handler
+ push {r10}
+ ldr r10, =secure_svc_handler
+ blx r10
+ pop {r10}
rfefd sp!
-.align 5
-monitor_vectors:
- b . /* Reset */
- b . /* Undefined instruction */
- b monitor_smc_vect /* Secure monitor call */
- b . /* Prefetch abort */
- b . /* Data abort */
- b . /* Reserved */
- b . /* IRQ */
- b . /* FIQ */
-
-monitor_smc_vect:
- cmp r0, #SMC_YIELD
- bge sm_smc_entry
- srsdb sp!, #CPSR_MODE_MON
- cmp r0, #SMC_NOOP
- beq 1f
- push {r0-r3}
- mov r0, r1
- bl tztest_dispatch_monitor
- pop {r0-r3}
-1: rfefd sp!
-
- .globl secure_init
+.section .text
secure_init:
+ /* We enter with R0 pointing to the nonsecure entry point. Put it in R11
+ * for now to avoid overwriting it on calls. */
+ mov r11, r0
+
/* Disable interrupts for now */
mrs r10, cpsr
- orr r10, r10, #0xc0 @ Mask IRQ and FIQ
+ orr r10, r10, #0xc0 /* Mask IRQ and FIQ */
msr cpsr, r10
- /* Make sure secure vectors are based at 0 */
+ /* During startup, before the MMU is enabled we'll set-up the vecs in low
+ * mem.
+ */
mrc p15, 0, r10, c1, c0, 0
- bic r10, r10, #0x2000 @ SCTLR.V = 0
+ bic r10, r10, #0x2000 /* SCTLR.V = 0 */
mcr p15, 0, r10, c1, c0, 0
+ ldr r10, =secure_vectors
+ mcr p15, 0, r10, c12, c0, 0 /* VBAR = secure_vectors */
- /* Set up secure VBAR */
- ldr r11, =secure_vectors
- mcr p15, 0, r11, c12, c0, 0
isb
secure_stack_init:
@@ -118,12 +106,12 @@ secure_mmu_init:
mcr p15, 0, r10, c3, c0, 0
/* Set-up the initial secure page tables */
- bl tztest_secure_pagetable_init
+ bl secure_pagetable_init
/* Set TTBR0 to the initialized address plus enable shareable write-back
* write-allocate.
*/
- ldr r10, =sec_l1_page_table
+ ldr r10, =_sec_l1_page_table
orr r10, r10, #0xB
mcr p15, 0, r10, c2, c0, 0
@@ -139,65 +127,39 @@ secure_mmu_init:
isb
dsb
-#ifdef DEBUG
+secure_remap_vecs:
+ /* Now that we have enabled the MMU, move the mapping of the secure vector
+ * table to high mem.
+ * No need to set up VBAR as we'll be using hivec */
+ mrc p15, 0, r10, c1, c0, 0
+ orr r10, r10, #0x2000 @ SCTLR.V = 1
+ mcr p15, 0, r10, c1, c0, 0
+
/* Check that are entry state makes sense before initializing the monitor
* mode.
*/
- bl check_init_mode
-#endif
+ bl secure_check_init
secure_init_monitor:
- /* Set-up the monitor stack */
- mrs r1, cpsr
- cps #CPSR_MODE_MON
- ldr sp, =mon_stacktop
- msr cpsr, r1
-
- /* Set-up mvbar */
- ldr r0, =monitor_vectors
- mcr p15, 0, r0, c12, c0, 1
-
- bl tztest_secure_svc_init_monitor
+ /* Call monitor mode initialization and pass to it the non-secure execution
+ * entry point.
+ */
+ mov r0, r11
+ bl monitor_init
+ /* Once monitor mode is set-up, we yield to non-secure execution. The
+ * non-secure entrypoint was established in monitor init.
+ */
mov r0, #SMC_YIELD
smc #0
- bl tztest_secure_svc_loop
+ /* The first return to the secure world will set us off into our
+ * secure-side monitor loop. The only way out is to issue an EXIT SMC call
+ * to the secure world.
+ */
+ bl secure_svc_loop
/* If we get here we are on the way out, poweroff the device */
end:
- ldr r0, =SYSREG_BASE
- add r0, r0, #SYSREG_CFGCTRL
- ldr r1, =SYS_SHUTDOWN
- str r1, [r0]
- b end
-
- .globl dispatch_secure_usr
-dispatch_secure_usr:
- /* Push the LR onto the stack so we can return immediately from the svc
- * handler on return.
- */
- push {lr}
+ b secure_shutdown
- /* Reset the user stack for the dispatch, so we have a clean stack */
- cps #CPSR_MODE_SYS
- ldr sp, =sec_usr_stacktop
- push {r0, r1}
- cps #CPSR_MODE_SVC
-
- /* Return to USR mode to execute the dispatch function in r0
- */
- ldr r0, =dispatch_usr_wrapper
- mov r1, #CPSR_MODE_USR
- push {r0, r1}
- rfefd sp!
-
-/* This is the user-side dispatch wrapper that accepts the function pointer and
- * function arg in r0 & r1 respectively. The wrapper is simply an anstraction
- * layer for translating the input parameters into the user function call.
- */
-dispatch_usr_wrapper:
- pop {r0, r1}
- mov r2, r0
- mov r0, r1
- mov pc, r2
diff --git a/arm/secure_loader.h b/arm/secure_loader.h
new file mode 100644
index 0000000..577d6e5
--- /dev/null
+++ b/arm/secure_loader.h
@@ -0,0 +1,21 @@
+#ifndef _SECURE_LOADER_H
+#define _SECURE_LOADER_H
+#include "sm.h"
+
+extern int _ram_nsec_base;
+extern uint32_t _sec_l1_page_table;
+extern uint32_t _ram_secvecs_start;
+extern uint32_t _ram_sectext_start;
+extern uint32_t _ram_secdata_start;
+extern uint32_t _secstack_start;
+extern uint32_t _secvecs_size;
+extern uint32_t _sectext_size;
+extern uint32_t _secdata_size;
+extern uint32_t _secstack_size;
+extern uint32_t _shared_memory_heap_base;
+extern uint32_t _common_memory_heap_base;
+extern volatile uint32_t _tztest_exception;
+extern volatile uint32_t _tztest_exception_addr;
+extern volatile uint32_t _tztest_exception_status;
+
+#endif
diff --git a/arm/secure_svc.c b/arm/secure_svc.c
new file mode 100644
index 0000000..3ba4471
--- /dev/null
+++ b/arm/secure_svc.c
@@ -0,0 +1,184 @@
+#include "secure_loader.h"
+#include "common_svc.h"
+#include "common_mmu.h"
+#include "common_defs.h"
+
+/* Make the below globals volatile as found that the compiler uses the
+ * register value ratherh than the memory value making it look like the writes
+ * actually happened.
+ */
+
+int secure_dispatch_usr(int, int);
+void secure_svc_loop(int initial_r0, int initial_r1);
+
+volatile uint32_t *exception = &_tztest_exception;
+volatile uint32_t *exception_addr = &_tztest_exception_addr;
+volatile uint32_t *exception_status = &_tztest_exception_status;
+uint32_t *sec_l1_page_table = &_sec_l1_page_table;
+uint32_t ram_secvecs_start = (uint32_t)&_ram_secvecs_start;
+uint32_t ram_sectext_start = (uint32_t)&_ram_sectext_start;
+uint32_t ram_secdata_start = (uint32_t)&_ram_secdata_start;
+uint32_t secstack_start = (uint32_t)&_secstack_start;
+uint32_t secvecs_size = (uint32_t)&_secvecs_size;
+uint32_t sectext_size = (uint32_t)&_sectext_size;
+uint32_t secdata_size = (uint32_t)&_secdata_size;
+uint32_t secstack_size = (uint32_t)&_secstack_size;
+
+pagetable_map_entry_t nsec_pagetable_entries[] = {
+ {.va = (uint32_t)&_ram_nsec_base, .pa = (uint32_t)&_ram_nsec_base,
+ .type = SECTION, .len = SECTION_SIZE * 2,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_W | P1_X | P0_R |
+ P0_W | P0_X | NONSECURE },
+};
+
+pagetable_map_entry_t sysreg_pagetable_entries[] = {
+ {.va = SYSREG_BASE, .pa = SYSREG_BASE,
+ .type = PAGE, .len = 0x1000,
+ .attr = SHARED | NOTGLOBAL | UNCACHED | P1_R | P1_W | P0_R | P0_W |
+ NONSECURE },
+};
+
+void secure_svc_handler(volatile uint32_t op, volatile tztest_svc_desc_t *desc)
+{
+ DEBUG_MSG("Entered\n");
+ switch (op) {
+ case SVC_DISPATCH_MONITOR:
+ op = SMC_DISPATCH_MONITOR;
+ __smc(op, desc);
+ break;
+ case SVC_GET_SECURE_STATE:
+ /* This SVC handler is only accessible from the secure vector
+ * table, so unless something went drastically wrong with the
+ * tables, it should be safe to assume we are in a nonsecure state.
+ */
+ desc->secure_state.state = TZTEST_STATE_SECURE;
+ break;
+ }
+ DEBUG_MSG("Exiting\n");
+ return;
+}
+
+void secure_undef_handler() {
+ DEBUG_MSG("Undefined exception taken\n");
+ *exception = CPSR_MODE_UND;
+ *exception_status = 0;
+}
+
+void secure_pabort_handler(int status, int addr) {
+ DEBUG_MSG("status = 0x%x\taddress = 0x%x\n", status, addr);
+ *exception = CPSR_MODE_ABT;
+ *exception_addr = addr;
+ *exception_status = status & 0x1f;
+}
+
+void secure_dabort_handler(int status, int addr) {
+ DEBUG_MSG("Data Abort: %s\n", FAULT_STR(status & 0x1f));
+ DEBUG_MSG("status = 0x%x\taddress = 0x%x\n",
+ status & 0x1f, addr);
+ *exception = CPSR_MODE_ABT;
+ *exception_addr = addr;
+ *exception_status = status & 0x1f;
+}
+
+void secure_check_init()
+{
+ printf("\nValidating startup state:\n");
+
+ printf("\tChecking for security extension ...");
+ int idpfr1 = 0;
+ /* Read the ID_PFR1 CP register and check that it is marked for support of
+ * the security extension.
+ */
+ __mrc(15, 0, idpfr1, 0, 1, 1);
+ if (0x10 != (idpfr1 & 0xf0)) {
+ printf("FAILED\n");
+ DEBUG_MSG("current IDPFR1 (%d) != expected IDPFR1 (%d)\n",
+ (idpfr1 & 0xf0), 0x10);
+ exit(1);
+ } else {
+ printf("PASSED\n");
+ }
+
+ printf("\tChecking initial processor mode... ");
+ if (CPSR_MODE_SVC != (_read_cpsr() & 0x1f)) {
+ printf("FAILED\n");
+ DEBUG_MSG("current CPSR (%d) != expected CPSR (%d)\n",
+ (_read_cpsr() & 0x1f), CPSR_MODE_SVC);
+ assert(CPSR_MODE_SVC == (_read_cpsr() & 0x1f));
+ } else {
+ printf("PASSED\n");
+ }
+
+ // Test: Check that on reset if sec et present, starts in sec state
+ // pg. B1-1204
+ printf("\tChecking initial security state... ");
+ if (0 != (_read_scr() & SCR_NS)) {
+ printf("Failed\n");
+ DEBUG_MSG("current SCR.NS (%d) != expected SCR.NS (%d)\n",
+ (_read_cpsr() & SCR_NS), 0);
+ assert(0 == (_read_scr() & SCR_NS));
+ } else {
+ printf("PASSED\n");
+ }
+}
+
+void secure_svc_loop(int initial_op, int initial_data)
+{
+ volatile int op = initial_op;
+ tztest_smc_desc_t *data = (tztest_smc_desc_t *)initial_data;
+ uint32_t (*func)(uint32_t);
+
+ DEBUG_MSG("Initial call\n");
+
+ while (SMC_EXIT != op) {
+ switch (op) {
+ case SMC_DISPATCH_SECURE_USR:
+ DEBUG_MSG("Dispatching secure USR function\n");
+ data->dispatch.ret =
+ secure_dispatch_usr((int)data->dispatch.func,
+ data->dispatch.arg);
+ DEBUG_MSG("Returned from secure USR dispatch\n");
+ break;
+ case SMC_DISPATCH_SECURE_SVC:
+ func = (uint32_t (*)())data->dispatch.func;
+ DEBUG_MSG("Dispatching secure SVC function\n");
+ data->dispatch.ret = func(data->dispatch.arg);
+ DEBUG_MSG("Returned from secure SVC dispatch\n");
+ break;
+ }
+ op = SMC_YIELD;
+ __smc(op, data);
+ DEBUG_MSG("Handling smc op 0x%x\n", op);
+ }
+
+ DEBUG_MSG("Exiting\n");
+}
+
+void secure_pagetable_init()
+{
+ pagetable_map_entry_t sec_pagetable_entries[] = {
+ {.va = (uint32_t)0xFFFF0000, .pa = (uint32_t)ram_secvecs_start,
+ .type = PAGE, .len = secvecs_size,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_X | P0_R | P0_X },
+ {.va = (uint32_t)ram_sectext_start, .pa = (uint32_t)ram_sectext_start,
+ .type = PAGE, .len = sectext_size,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_X | P0_R | P0_X },
+ {.va = (uint32_t)ram_secdata_start, .pa = (uint32_t)ram_secdata_start,
+ .type = PAGE, .len = secdata_size,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_W | P0_R | P0_W },
+ {.va = (uint32_t)secstack_start, .pa = (uint32_t)secstack_start,
+ .type = PAGE, .len = secstack_size,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_W | P0_R | P0_W },
+ {.va = (uint32_t)sec_l1_page_table, .pa = (uint32_t)sec_l1_page_table,
+ .type = SECTION, .len = 16*1024*1024,
+ .attr = SHARED | NOTGLOBAL | WBA_CACHED | P1_R | P1_W },
+ };
+
+ pagetable_init(sec_l1_page_table);
+
+ PT_ADD_ENTRIES(sec_l1_page_table, sysreg_pagetable_entries);
+ PT_ADD_ENTRIES(sec_l1_page_table, sec_pagetable_entries);
+ PT_ADD_ENTRIES(sec_l1_page_table, nsec_pagetable_entries);
+
+ pagetable_init_common(sec_l1_page_table);
+}
diff --git a/arm/sm_asm.S b/arm/sm_asm.S
index bcfb84a..cab7b54 100644
--- a/arm/sm_asm.S
+++ b/arm/sm_asm.S
@@ -28,7 +28,6 @@
#include <asm.S>
#include <arm32.h>
#include <arm32_macros.S>
-//#include <sm/teesmc.h>
FUNC sm_save_modes_regs , :
/* User mode registers has to be saved from system mode */
diff --git a/arm/tzboot.S b/arm/tzboot.S
index 26ae976..937561d 100644
--- a/arm/tzboot.S
+++ b/arm/tzboot.S
@@ -42,11 +42,22 @@ init_cpu:
ldr r11, =boot_vectors
mcr p15, 0, r11, c12, c0, 0
isb
-
+
/* Start by setting up the boot stack*/
ldr sp, =boot_stacktop
load_images:
+ /* First copy the vector section text into RAM */
+ ldr r0, =_flash_secvecs_start
+ ldr r1, =_ram_secvecs_start
+ ldr r2, =_secvecs_size
+copy_secvecs:
+ ldrb r10, [r0], #1
+ strb r10, [r1], #1
+ subs r2, r2, #1
+ bne copy_secvecs
+
+ /* Next copy the text section into RAM */
ldr r0, =_flash_sectext_start
ldr r1, =_ram_sectext_start
ldr r2, =_sectext_size
@@ -55,7 +66,8 @@ copy_sectext:
strb r10, [r1], #1
subs r2, r2, #1
bne copy_sectext
-
+
+ /* Last copy the text section into RAM */
ldr r0, =_flash_secdata_start
ldr r1, =_ram_secdata_start
ldr r2, =_secdata_size
@@ -64,12 +76,19 @@ copy_secdata:
strb r10, [r1], #1
subs r2, r2, #1
bne copy_secdata
-
+
+ /* Branch to the nonsecure image base. It should be set-up so that this is
+ * the image loader which returns the starting execution point.
+ */
mov r0, #FLASH_NSEC_BASE
- add r0, r0, #0x4
blx r0
-
- bl secure_init
-
-end:
+
+ /* Branch to the starting point of the secure image in RAM which should
+ * kick off initialization.
+ */
+ mov r1, #RAM_SEC_BASE
+ bx r1
+
+ /* We shouldn't get here as the secure image will shutdown */
+end:
b end
diff --git a/arm/tztest.c b/arm/tztest.c
index c79c609..5a539d8 100644
--- a/arm/tztest.c
+++ b/arm/tztest.c
@@ -1,10 +1,12 @@
#include "tztest.h"
+volatile int *tztest_fail_count = &_tztest_fail_count;
+volatile int *tztest_test_count = &_tztest_test_count;
+
/* Make the below globals volatile as found that the compiler uses the
* register value ratherh than the memory value making it look like the writes
* actually happened.
*/
-extern uint32_t _shared_memory_heap_base;
uint32_t mon_noop() { return 0; }
@@ -151,59 +153,32 @@ uint32_t P1_nonsecure_check_mask_bits()
return ret;
}
-#define TZTEST_SECURE_USR_PATTERN 0x87654321
-#define TZTEST_SECURE_SVC_PATTERN 0x12345678
-
-uint32_t tztest_secure_usr_test1(uint32_t arg)
-{
- DEBUG_MSG("Entered arg = 0x%x\n", arg);
- __svc(1,0);
- DEBUG_MSG("Exiting\n");
-
- return arg/2;
-}
-SECURE_USR_FUNC(tztest_secure_usr_test1);
-
-uint32_t tztest_secure_svc_test1(uint32_t arg)
+uint32_t MON_check_state()
{
- DEBUG_MSG("arg = 0x%x\n", arg);
- return arg*2;
-}
+ printf("\nValidating monitor mode:\n");
-uint32_t tztest_check_secure_usr_handshake()
-{
- uint32_t ret = 0;
- DISPATCH_SECURE_USR(tztest_secure_usr_test1,
- TZTEST_SECURE_USR_PATTERN, ret);
+ uint32_t cpsr = _read_cpsr();
- if (TZTEST_SECURE_USR_PATTERN/2 != ret) {
- DEBUG_MSG("\n***** Failed secure usr handshake *****\n");
- assert(TZTEST_SECURE_USR_PATTERN/2 == ret);
- }
+ printf("\tChecking monitor mode... ");
+ TEST_CONDITION(CPSR_MODE_MON == (cpsr & CPSR_MODE_MASK));
- return ret;
-}
+ // Test: Check that CPSR.A/I.F are set to 1 on exception to mon mode
+ // pg. B1-1182
+ printf("\tChecking monitor mode CPSR.F value... ");
+ TEST_CONDITION(CPSR_F == (CPSR_F & cpsr));
-uint32_t tztest_check_secure_svc_handshake()
-{
- uint32_t ret = 0;
- DISPATCH_SECURE_SVC(tztest_secure_svc_test1,
- TZTEST_SECURE_SVC_PATTERN, ret);
+ printf("\tChecking monitor mode CPSR.I value... ");
+ TEST_CONDITION(CPSR_I == (CPSR_I & cpsr));
- if (TZTEST_SECURE_SVC_PATTERN*2 != ret) {
- DEBUG_MSG("\n***** Failed secure svc handshake *****\n");
- assert(TZTEST_SECURE_SVC_PATTERN*2 == ret);
- }
+ printf("\tChecking monitor mode CPSR.A value... ");
+ TEST_CONDITION(CPSR_A == (CPSR_A & cpsr));
- return ret;
+ return 0;
}
-uint32_t MON_check_state()
+uint32_t MON_check_exceptions()
{
- printf("\nValidating monitor mode:\n");
-
- printf("\tChecking monitor mode... ");
- TEST_CONDITION(CPSR_MODE_MON == ((_read_cpsr() & CPSR_MODE_MASK)));
+ printf("\nValidating monitor mode exception:\n");
uint32_t scr = _read_scr();
@@ -212,8 +187,7 @@ uint32_t MON_check_state()
* Test: Check that an exception from mon mode, NS cleared to 0
* pg. B1-1170
*/
-
- /* Set our security state to secure */
+ /* Set our starting security state to secure */
_write_scr(scr & ~SCR_NS);
printf("\tChecking state after secure monitor... ");
TEST_FUNCTION(smc_noop(), !SCR_NS == ((_read_scr() & SCR_NS)));
@@ -250,64 +224,6 @@ uint32_t P1_nonsecure_novirt_behavior()
return ret;
}
-#define TZTEST_SVAL 0xaaaaaaaa
-#define TZTEST_NSVAL ~TZTEST_SVAL
-#define TZTEST_GET_REG_SECURE_BANK(_reg, _val) \
- do { \
- _write_scr(scr & ~SCR_NS); \
- (_val) = _read_##_reg(); \
- } while(0)
-
-#define TZTEST_GET_REG_NONSECURE_BANK(_reg, _val) \
- do { \
- _write_scr(scr | SCR_NS); \
- (_val) = _read_##_reg(); \
- } while(0)
-
-#define TZTEST_SET_REG_SECURE_BANK(_reg, _val) \
- do { \
- _write_scr(scr & ~SCR_NS); \
- _write_##_reg(_val); \
- } while(0)
-
-#define TZTEST_SET_REG_NONSECURE_BANK(_reg, _val) \
- do { \
- _write_scr(scr | SCR_NS); \
- _write_##_reg(_val); \
- } while(0)
-
-#define TZTEST_GET_REG_BANKS(_reg, _sval, _nsval) \
- do { \
- TZTEST_GET_REG_SECURE_BANK(_reg, _sval); \
- TZTEST_GET_REG_NONSECURE_BANK(_reg, _nsval);\
- } while(0)
-
-#define TZTEST_SET_REG_BANKS(_reg, _sval, _nsval) \
- do { \
- TZTEST_SET_REG_SECURE_BANK(_reg, _sval); \
- TZTEST_SET_REG_NONSECURE_BANK(_reg, _nsval);\
- } while(0)
-
-#define VERIFY_REGISTER_CUSTOM(_reg, _mask, _sval, _nsval) \
- do { \
- uint32_t sval = 0, nsval = 0; \
- uint32_t _reg[2] = {0,0}; \
- printf("\tChecking %s banks... ", #_reg); \
- TZTEST_GET_REG_BANKS(_reg, _reg[!SCR_NS], _reg[SCR_NS]); \
- TZTEST_SET_REG_BANKS(_reg, (_sval), (_nsval)); \
- TZTEST_GET_REG_SECURE_BANK(_reg, sval); \
- TZTEST_GET_REG_NONSECURE_BANK(_reg, nsval); \
- TEST_CONDITION(((sval & (_mask)) != (nsval & (_mask))) && \
- (((_sval) & (_mask)) == (sval & (_mask))) && \
- (((_nsval) & (_mask)) == (nsval & (_mask)))); \
- TZTEST_SET_REG_BANKS(_reg, _reg[!SCR_NS], _reg[SCR_NS]); \
- } while(0)
-
-#define VERIFY_REGISTER(_reg) \
- VERIFY_REGISTER_CUSTOM(_reg, 0xFFFFFFFF, TZTEST_SVAL, TZTEST_NSVAL)
-
-extern uint32_t nsec_l1_page_table;
-extern uint32_t nonsecure_vectors;
uint32_t MON_check_banked_regs()
{
uint32_t scr = _read_scr();
@@ -331,7 +247,7 @@ uint32_t MON_check_banked_regs()
* be wrong.
*/
VERIFY_REGISTER_CUSTOM(ttbr0, 0xFFF00000,
- (uint32_t)&nsec_l1_page_table, TZTEST_NSVAL);
+ (uint32_t)nsec_l1_page_table, TZTEST_NSVAL);
VERIFY_REGISTER(ttbr1);
/* Modifying TTBCR is highly disruptive, so the test is heavily restricted
@@ -369,6 +285,62 @@ uint32_t MON_check_banked_regs()
return 0;
}
+#ifdef DEBUG
+uint32_t tztest_div_by_2(uint32_t arg) {return arg/2;}
+SECURE_USR_FUNC(tztest_div_by_2);
+
+#define TZTEST_HANDSHAKE_FUNC(_name, _remote) \
+ uint32_t _name(uint32_t arg) { \
+ uint32_t ret = 0; \
+ _remote(tztest_div_by_2, arg, ret); \
+ assert(arg/2 == ret); \
+ return ret; \
+ }
+
+TZTEST_HANDSHAKE_FUNC(hs_with_ns_svc, DISPATCH_NONSECURE_SVC)
+TZTEST_HANDSHAKE_FUNC(hs_with_s_svc, DISPATCH_SECURE_SVC)
+TZTEST_HANDSHAKE_FUNC(hs_with_s_usr, DISPATCH_SECURE_USR)
+TZTEST_HANDSHAKE_FUNC(hs_with_mon, DISPATCH_MONITOR)
+
+#define CHECK_HANDSHAKE(_func) \
+ _func; \
+ if (val/2 != ret) { \
+ DEBUG_MSG("Handshake %s FAILED (0x%x != 0x%x)\n", \
+ #_func, val/2, ret); \
+ assert(val/2 == ret); \
+ } \
+
+void test_handshake()
+{
+ uint32_t ret = 0;
+ uint32_t val = TZTEST_SVAL;
+
+ /* NS_USR -> NS_SVC */
+ CHECK_HANDSHAKE(ret = hs_with_ns_svc(val));
+
+ /* NS_USR -> NS_SVC -> S_SVC */
+ CHECK_HANDSHAKE(ret = hs_with_s_svc(val));
+
+ /* NS_USR -> NS_SVC -> S_SVC -> S_USR */
+ CHECK_HANDSHAKE(ret = hs_with_s_usr(val));
+
+ /* NS_USR -> NS_SVC -> MON */
+ CHECK_HANDSHAKE(ret = hs_with_mon(val));
+
+ /* NS_SVC -> S_SVC */
+ CHECK_HANDSHAKE(DISPATCH_NONSECURE_SVC(hs_with_s_svc, val, ret));
+
+ /* NS_SVC -> S_USR */
+ CHECK_HANDSHAKE(DISPATCH_NONSECURE_SVC(hs_with_s_usr, val, ret));
+
+ /* NS_SVC -> MON */
+ CHECK_HANDSHAKE(DISPATCH_NONSECURE_SVC(hs_with_mon, val, ret));
+
+ /* S_SVC -> MON */
+ CHECK_HANDSHAKE(DISPATCH_SECURE_SVC(hs_with_mon, val, ret));
+}
+#endif
+
uint32_t tztest_nonsecure_usr_main()
{
uint32_t ret = 0;
@@ -381,13 +353,13 @@ uint32_t tztest_nonsecure_usr_main()
P0_nonsecure_check_register_access();
#ifdef DEBUG
- tztest_check_secure_usr_handshake();
- tztest_check_secure_svc_handshake();
+ test_handshake();
#endif
DISPATCH_SECURE_USR(P0_secure_check_register_access, 0, ret);
DISPATCH_MONITOR(MON_check_state, 0, ret);
+ DISPATCH_MONITOR(MON_check_exceptions, 0, ret);
DISPATCH_MONITOR(MON_check_banked_regs, 0, ret);
DISPATCH_NONSECURE_SVC(P1_nonsecure_check_mask_bits, 0, ret);
@@ -429,6 +401,10 @@ uint32_t tztest_nonsecure_usr_main()
// pg. B1-1158
// Test: Check that irq/fiq interrupts routed to mon mode use mvbar entry
// pg. B1-1168
+ // Test: Check that IRQ exceptions are routed properly
+ // figure: B1-8
+ // Test: Check that FIQ exceptions are routed properly
+ // figure: B1-9
#endif
#ifdef NONTZ_TEST
// Test: Check that mon mode is only avail if sec ext. present
@@ -462,13 +438,3 @@ uint32_t tztest_nonsecure_usr_main()
// figure: B1-6
// Test: Check that data abort exceptions are routed properly
// figure: B1-7
- // Test: Check that IRQ exceptions are routed properly
- // figure: B1-8
- // Test: Check that FIQ exceptions are routed properly
- // figure: B1-9
- // Test: Check that CPSR.A/I.F are set to 1 on exception to mon mode
- // pg. B1-1182
- // Test: Check that on reset if sec et present, starts in sec state
- // pg. B1-1204
- // Note: Unaligned access can cause abort in PMSA
- //
diff --git a/arm/tztest.h b/arm/tztest.h
index bb0d0ca..34ced86 100644
--- a/arm/tztest.h
+++ b/arm/tztest.h
@@ -1,74 +1,11 @@
#ifndef _TZTEST_H
#define _TZTEST_H
-#include "tztest_asm.h"
-#include "tztest_builtins.h"
-#include "tztest_mmu.h"
-#include "sm.h"
-#include "libcflat.h"
-
-typedef struct {
- uint32_t (*func)(uint32_t);
- uint32_t arg;
- uint32_t ret;
-} tztest_dispatch_t;
-
-typedef struct {
- union {
- tztest_dispatch_t dispatch;
- struct {
- uint32_t reg;
- uint32_t val;
- } reg_read;
- struct {
- uint32_t state;
- } secure_state;
- };
-} tztest_svc_desc_t;
-
-#define CLEAR_SVC_DESC(_desc) memset(&(_desc), sizeof(tztest_svc_desc_t), 0)
-
-typedef struct {
- union {
- tztest_dispatch_t dispatch;
- };
-} tztest_smc_desc_t;
-
-#ifdef DEBUG
-#define DEBUG_MSG(_str, ...) \
- printf("\n[DEBUG] %s: " _str, __FUNCTION__, ##__VA_ARGS__)
-#define DEBUG_ARG
-#else
-#define DEBUG_MSG(_str, ...)
-#define DEBUG_ARG __attribute__ ((unused))
-#endif
+#include "common_defs.h"
+#include "common_svc.h"
-#define MODE_STR(_mode) \
- ((_mode == MON) ? "MON" : \
- (_mode == SVC) ? "SVC" : \
- (_mode == SYS) ? "SYS" : \
- (_mode == USR) ? "USR" : "Unknown")
-
-
-#define FAULT_STR(_s) \
- ((0x01 == (_s)) ? "Alignment fault" : \
- (0x02 == (_s)) ? "Debug event" : \
- (0x03 == (_s)) ? "Access flag fault" : \
- (0x04 == (_s)) ? "Instruction cache maintenance" : \
- (0x05 == (_s)) ? "Translation fault" : \
- (0x06 == (_s)) ? "Access flag fault" : \
- (0x07 == (_s)) ? "Translation fault" : \
- (0x08 == (_s)) ? "Synchronous external abort" : \
- (0x09 == (_s)) ? "Domain fault" : \
- (0x0b == (_s)) ? "Domain fault" : \
- (0x0c == (_s)) ? "External abort on table walk" : \
- (0x0d == (_s)) ? "Permisison fault" : \
- (0x0e == (_s)) ? "Synchronous external abort" : \
- (0x0f == (_s)) ? "Permisison fault" : \
- (0x10 == (_s)) ? "TLB conflict abort" : \
- (0x1c == (_s)) ? "External parity err on table walk" : \
- (0x1e == (_s)) ? "External parity err on table walk" : \
- "Unknown")
+extern volatile int _tztest_fail_count;
+extern volatile int _tztest_test_count;
#define CALL(_f) __svc(0, _f)
#define RETURN(_r) __svc(0,(_r))
@@ -120,10 +57,70 @@ typedef struct {
*tztest_exception = 0; \
} while (0)
+#define TZTEST_SVAL 0xaaaaaaaa
+#define TZTEST_NSVAL ~TZTEST_SVAL
+#define TZTEST_GET_REG_SECURE_BANK(_reg, _val) \
+ do { \
+ _write_scr(scr & ~SCR_NS); \
+ (_val) = _read_##_reg(); \
+ } while(0)
+
+#define TZTEST_GET_REG_NONSECURE_BANK(_reg, _val) \
+ do { \
+ _write_scr(scr | SCR_NS); \
+ (_val) = _read_##_reg(); \
+ } while(0)
+
+#define TZTEST_SET_REG_SECURE_BANK(_reg, _val) \
+ do { \
+ _write_scr(scr & ~SCR_NS); \
+ _write_##_reg(_val); \
+ } while(0)
+
+#define TZTEST_SET_REG_NONSECURE_BANK(_reg, _val) \
+ do { \
+ _write_scr(scr | SCR_NS); \
+ _write_##_reg(_val); \
+ } while(0)
+
+#define TZTEST_GET_REG_BANKS(_reg, _sval, _nsval) \
+ do { \
+ TZTEST_GET_REG_SECURE_BANK(_reg, _sval); \
+ TZTEST_GET_REG_NONSECURE_BANK(_reg, _nsval);\
+ } while(0)
+
+#define TZTEST_SET_REG_BANKS(_reg, _sval, _nsval) \
+ do { \
+ TZTEST_SET_REG_SECURE_BANK(_reg, _sval); \
+ TZTEST_SET_REG_NONSECURE_BANK(_reg, _nsval);\
+ } while(0)
+
+#define VERIFY_REGISTER_CUSTOM(_reg, _mask, _sval, _nsval) \
+ do { \
+ uint32_t sval = 0, nsval = 0; \
+ uint32_t _reg[2] = {0,0}; \
+ printf("\tChecking %s banks... ", #_reg); \
+ TZTEST_GET_REG_BANKS(_reg, _reg[!SCR_NS], _reg[SCR_NS]); \
+ TZTEST_SET_REG_BANKS(_reg, (_sval), (_nsval)); \
+ TZTEST_GET_REG_SECURE_BANK(_reg, sval); \
+ TZTEST_GET_REG_NONSECURE_BANK(_reg, nsval); \
+ TEST_CONDITION(((sval & (_mask)) != (nsval & (_mask))) && \
+ (((_sval) & (_mask)) == (sval & (_mask))) && \
+ (((_nsval) & (_mask)) == (nsval & (_mask)))); \
+ TZTEST_SET_REG_BANKS(_reg, _reg[!SCR_NS], _reg[SCR_NS]); \
+ } while(0)
+
+#define VERIFY_REGISTER(_reg) \
+ VERIFY_REGISTER_CUSTOM(_reg, 0xFFFFFFFF, TZTEST_SVAL, TZTEST_NSVAL)
+
extern volatile int *tztest_exception;
+extern volatile int *tztest_exception_addr;
extern volatile int *tztest_exception_status;
extern volatile int *tztest_fail_count;
extern volatile int *tztest_test_count;
extern void validate_state(uint32_t, uint32_t);
+extern uint32_t _shared_memory_heap_base;
+extern uint32_t *nsec_l1_page_table;
+extern uint32_t *nsec_l2_page_table;
#endif
diff --git a/arm/tztest_builtins.h b/arm/tztest_builtins.h
index b5f32d3..a1f61f5 100644
--- a/arm/tztest_builtins.h
+++ b/arm/tztest_builtins.h
@@ -12,6 +12,8 @@
"mov r0, %[r0]\n" \
"mov r1, %[r1]\n" \
"smc 0\n" \
+ "mov %[r0], r0\n" \
+ "mov %[r1], r1\n" \
: [r0] "+r" (_op), [r1] "+r" (_data) \
)
diff --git a/arm/tztest_common.c b/arm/tztest_common.c
deleted file mode 100644
index 2633943..0000000
--- a/arm/tztest_common.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "tztest.h"
-
-#ifdef DEBUG
-void validate_state(uint32_t mode, uint32_t state)
-{
- tztest_svc_desc_t desc;
-
- assert((_read_cpsr() & CPSR_MODE_MASK) == mode);
-
- CLEAR_SVC_DESC(desc);
- __svc(SVC_GET_SECURE_STATE, &desc);
- assert(desc.secure_state.state == state);
-}
-#else
-void validate_state(__attribute__((unused)) uint32_t mode,
- __attribute__((unused)) uint32_t state) {}
-#endif
-
diff --git a/arm/tztest_mmu.c b/arm/tztest_mmu.c
deleted file mode 100644
index 92b0fbe..0000000
--- a/arm/tztest_mmu.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "tztest.h"
-#include "tztest_mmu.h"
-
-void pagetable_add_sections(uint32_t *ttbrn, pagetable_map_entry_t *entries,
- uint32_t count)
-{
- uint32_t num; /* Number of 1MB sections */
- uint32_t Vidx; /* 1MB Index into page table */
- uint32_t Pidx; /* 1MB Index into page table */
- uint32_t i;
- uint32_t shift = SECTION_SHIFT, size = SECTION_SIZE;
-
- for (i = 0; i < count; i++) {
- Vidx = entries[i].va >> shift;
- Pidx = entries[i].pa >> shift;
- num = ((entries[i].size + (size-1)) & ~(size-1)) >> shift;
- for (; num > 0; Vidx++, Pidx++, num--) {
- ttbrn[Vidx] = (Pidx << shift) | entries[i].attr;
- DEBUG_MSG("Mapped 0x%x to 0x%x in entry ttbrn[%x] = %x\n",
- Vidx << shift, Pidx << shift, Vidx, ttbrn[Vidx]);
- }
- }
-}
-
-void pagetable_init(uint32_t *ttbrn)
-{
- int i;
-
- for (i = 0; i < 4096; i++) {
- ttbrn[0] = 0;
- }
-}
diff --git a/arm/tztest_mmu.h b/arm/tztest_mmu.h
deleted file mode 100644
index b6f6d21..0000000
--- a/arm/tztest_mmu.h
+++ /dev/null
@@ -1,47 +0,0 @@
-
-#ifndef _TZTEST_MMU_H
-#define _TZTEST_MMU_H
-
-#include "sm.h"
-
-#define SECTION_SECTION (1 << 1)
-#define SECTION_B (1 << 2)
-#define SECTION_C (1 << 3)
-#define SECTION_NO_EXEC (1 << 4)
-#define SECTION_TEX(v) (1 << 12)
-#define SECTION_SHARED (1 << 16)
-#define SECTION_NOTGLOBAL (1 << 17)
-#define SECTION_NONSECURE (1 << 19)
-#define SECTION_SIZE 0x100000
-#define SECTION_SHIFT 20
-
-/* Fix SCTLR.AFE bit */
-
-#define SECTION_P1_RW ((0 << 15) | (1 << 10))
-#define SECTION_P1_RO ((1 << 15) | (1 << 10))
-#define SECTION_P0_RW ((0 << 15) | (3 << 10))
-#define SECTION_P0_RO ((0 << 15) | (2 << 10))
-#define SECTION_P0_NONE ((0 << 15) | (1 << 10))
-
-/* These remap description describe the memory region if SCTLR.TRE = 0
- * (no region atrribute remap).
- */
-#define SECTION_DEVICE_SHAREABLE (SECTION_B)
-#define SECTION_DEVICE_UNSHAREABLE (SECTION_TEX(2))
-#define SECTION_WT_CACHED (SECTION_C)
-#define SECTION_WB_CACHED (SECTION_C | SECTION_B)
-#define SECTION_UNCACHED (SECTION_TEX(1))
-#define SECTION_WBA_CACHED (SECTION_TEX(1) | SECTION_C | SECTION_B)
-
-typedef struct {
- uint32_t va;
- uint32_t pa;
- uint32_t size;
- uint32_t attr;
-} pagetable_map_entry_t;
-
-extern void pagetable_init(uint32_t *);
-extern void pagetable_add_sections(uint32_t *, pagetable_map_entry_t *,
- uint32_t);
-
-#endif
diff --git a/arm/tztest_nonsecure.lds.S b/arm/tztest_nonsecure.lds.S
index 85a59d8..0296c9c 100644
--- a/arm/tztest_nonsecure.lds.S
+++ b/arm/tztest_nonsecure.lds.S
@@ -39,13 +39,20 @@ SECTIONS
_nsecdata_size = _ram_nsecdata_end - _ram_nsecdata_start;
. = ALIGN(STACK_SIZE);
+ _nsecstack_start = .;
nsec_usr_stacktop = . + STACK_SIZE;
nsec_und_stacktop = nsec_usr_stacktop + STACK_SIZE;
nsec_abt_stacktop = nsec_und_stacktop + STACK_SIZE;
nsec_svc_stacktop = nsec_und_stacktop + STACK_SIZE;
+ _nsecstack_size = nsec_svc_stacktop - _nsecstack_start;
+ . += 1M;
- . = ALIGN(16M);
- nsec_l1_page_table = .;
+ . = ALIGN(1M);
+ _nsec_l1_page_table = .;
+ . += 1M;
+ . = ALIGN(1M);
+ _nsec_l2_page_table = .;
+ . += 16M;
. = TZTEST_COMMON_HEAP_BASE;
_common_memory_heap_base = .;
@@ -61,4 +68,6 @@ SECTIONS
. += 4;
_tztest_exception_status = .;
. += 4;
+ _tztest_exception_addr = .;
+ . += 4;
}
diff --git a/arm/tztest_nonsecure_svc.c b/arm/tztest_nonsecure_svc.c
deleted file mode 100644
index 7cdbcbb..0000000
--- a/arm/tztest_nonsecure_svc.c
+++ /dev/null
@@ -1,153 +0,0 @@
-#include "tztest.h"
-
-uint32_t nsec_dispatch_secure_usr_function(uint32_t (*)(uint32_t), uint32_t);
-uint32_t nsec_dispatch_secure_svc_function(uint32_t (*)(uint32_t), uint32_t);
-extern uint32_t nsec_l1_page_table;
-extern uint32_t _ram_nsectext_start;
-extern uint32_t _ram_nsecdata_start;
-extern uint32_t _shared_memory_heap_base;
-extern uint32_t _common_memory_heap_base;
-extern volatile int _tztest_test_count;
-extern volatile int _tztest_fail_count;
-volatile int *tztest_test_count = &_tztest_test_count;
-volatile int *tztest_fail_count = &_tztest_fail_count;
-extern volatile int _tztest_exception;
-extern volatile int _tztest_exception_status;
-volatile int *tztest_exception = &_tztest_exception;
-volatile int *tztest_exception_status = &_tztest_exception_status;
-
-pagetable_map_entry_t nsec_pagetable_entries[] = {
- {.va = (uint32_t)&_ram_nsectext_start, .pa = (uint32_t)&_ram_nsectext_start,
- .size = SECTION_SIZE,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_WBA_CACHED |
- SECTION_P1_RW | SECTION_P0_RW | SECTION_NONSECURE |
- SECTION_SECTION },
- {.va = (uint32_t)&_ram_nsecdata_start, .pa = (uint32_t)&_ram_nsecdata_start,
- .size = SECTION_SIZE * 2,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_WBA_CACHED |
- SECTION_P1_RW | SECTION_P0_RW | SECTION_NONSECURE |
- SECTION_SECTION },
-};
-
-pagetable_map_entry_t mmio_pagetable_entries[] = {
- {.va = UART0_BASE, .pa = UART0_BASE, .size = SECTION_SIZE,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_UNCACHED |
- SECTION_P1_RW | SECTION_P0_RW | SECTION_NONSECURE |
- SECTION_SECTION },
-};
-
-pagetable_map_entry_t heap_pagetable_entries[] = {
- {.va = (uint32_t)&_shared_memory_heap_base,
- .pa = (uint32_t)&_shared_memory_heap_base,
- .size = SECTION_SIZE,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_UNCACHED |
- SECTION_P1_RW | SECTION_P0_RW | SECTION_SECTION },
-};
-
-void nsec_svc_handler(volatile uint32_t op, volatile tztest_svc_desc_t *desc)
-{
- int ret = 0;
- switch (op) {
- case SVC_DISPATCH_MONITOR:
- op = SMC_DISPATCH_MONITOR;
- __smc(op, desc);
- break;
- case SVC_DISPATCH_SECURE_USR:
- DEBUG_MSG("Dispatching secure usr function\n");
- desc->dispatch.ret =
- nsec_dispatch_secure_usr_function(desc->dispatch.func,
- desc->dispatch.arg);
- DEBUG_MSG("Returning from secure usr function, ret = 0x%x\n",
- desc->dispatch.ret);
- break;
- case SVC_DISPATCH_SECURE_SVC:
- DEBUG_MSG("Dispatching secure svc function\n");
- desc->dispatch.ret =
- nsec_dispatch_secure_svc_function(desc->dispatch.func,
- desc->dispatch.arg);
- DEBUG_MSG("Returning from secure svc function, ret = 0x%x\n",
- desc->dispatch.ret);
- break;
- case SVC_DISPATCH_NONSECURE_SVC:
- DEBUG_MSG("Dispatching nonsecure svc function\n");
- desc->dispatch.ret = desc->dispatch.func(desc->dispatch.arg);
- DEBUG_MSG("Returning from nonsecure svc function, ret = 0x%x\n",
- desc->dispatch.ret);
- break;
- case SVC_GET_SECURE_STATE:
- /* This SVC handler is only accessible from the nonsecure vector
- * table, so unless something went drastically wrong with the
- * tables, it should be safe to assume we are in a nonsecure state.
- */
- desc->secure_state.state = TZTEST_STATE_NONSECURE;
- break;
- case SVC_EXIT:
- op = SMC_EXIT;
- __smc(op, ret);
- break;
- }
-}
-
-void nsec_undef_handler() {
- DEBUG_MSG("Undefined exception taken\n");
- *tztest_exception = CPSR_MODE_UND;
- *tztest_exception_status = 0;
-}
-
-void nsec_pabort_handler(int status, DEBUG_ARG int addr) {
- DEBUG_MSG("status = 0x%x\taddress = 0x%x\n", status, addr);
- *tztest_exception = CPSR_MODE_ABT;
- *tztest_exception_status = status & 0x1f;
-}
-
-void nsec_dabort_handler(int status, DEBUG_ARG int addr) {
- DEBUG_MSG("Data Abort: %s\n", FAULT_STR(status & 0x1f));
- DEBUG_MSG("status = 0x%x\taddress = 0x%x\n",
- status & 0x1f, addr);
- *tztest_exception = CPSR_MODE_ABT;
- *tztest_exception_status = status & 0x1f;
-}
-
-tztest_smc_desc_t smc_desc;
-uint32_t nsec_dispatch_secure_usr_function(uint32_t (*func)(uint32_t),
- uint32_t arg)
-{
- volatile int r0 = SMC_DISPATCH_SECURE_USR;
- tztest_smc_desc_t *desc_p = &smc_desc;
-
- smc_desc.dispatch.func = func;
- smc_desc.dispatch.arg = arg;
- DEBUG_MSG("Entered\n");
- __smc(r0, desc_p);
- DEBUG_MSG("Exiting, func = 0x%x\n", smc_desc.dispatch.func);
- return smc_desc.dispatch.ret;
-}
-
-uint32_t nsec_dispatch_secure_svc_function(uint32_t (*func)(uint32_t),
- uint32_t arg)
-{
- volatile int op = SMC_DISPATCH_SECURE_SVC;
- tztest_smc_desc_t desc, *desc_p = &desc;
-
- desc.dispatch.func = func;
- desc.dispatch.arg = arg;
- DEBUG_MSG("Entered op = %x\n", op);
- __smc(op, desc_p);
- DEBUG_MSG("Exiting\n");
- return desc.dispatch.ret;
-}
-
-void tztest_nonsecure_pagetable_init()
-{
- uint32_t *table = &nsec_l1_page_table;
- uint32_t count;
-
- pagetable_init(table);
-
- pagetable_add_sections(table, mmio_pagetable_entries, 1);
- count = sizeof(nsec_pagetable_entries) / sizeof(nsec_pagetable_entries[0]);
- pagetable_add_sections(table, nsec_pagetable_entries, count);
- pagetable_add_sections(table, heap_pagetable_entries, 1);
-}
-
-#endif
diff --git a/arm/tztest_secure.lds.S b/arm/tztest_secure.lds.S
index e02f7d5..6593a5f 100644
--- a/arm/tztest_secure.lds.S
+++ b/arm/tztest_secure.lds.S
@@ -17,53 +17,71 @@ _ram_nsec_base = RAM_NSEC_BASE;
SECTIONS
{
- . = FLASH_SEC_BASE;
- .boot : { arm/tzboot.o }
- _eboot = .;
+ . = FLASH_SEC_BASE;
+ .boot : { arm/tzboot.o }
+ _eboot = .;
- _flash_sectext_start = .;
- . = RAM_SEC_BASE;
- _ram_sec_base = .;
- _ram_sectext_start = .;
- .text : AT ( _flash_sectext_start ) { *(.text); }
- _ram_sectext_end = .;
- _sectext_size = SIZEOF(.text);
+ _flash_secvecs_start = .;
+ . = RAM_SEC_BASE;
+ _ram_sec_base = .;
- _flash_secdata_start = _flash_sectext_start + _sectext_size;
- . = ALIGN(1M);
- _ram_secdata_start = .;
- .rodata : AT ( _flash_secdata_start ) { *(.rodata); }
- .data : { *(.data); }
- .bss : { *(.bss); }
- _ram_secdata_end = .;
- _secdata_size = _ram_secdata_end - _ram_secdata_start;
+ /* We separate out the secure vector table and level 1 handlers, so we
+ * can map it to hivecs (0xffff0000).
+ */
+ _ram_secvecs_start = .;
+ .vectors : AT ( _flash_secvecs_start ) { *(.vectors); }
+ _ram_secvecs_end = .;
+ _secvecs_size = _ram_secvecs_end - _ram_secvecs_start;
- . = ALIGN(STACK_SIZE);
- sec_usr_stacktop = . + STACK_SIZE;
- sec_und_stacktop = sec_usr_stacktop + STACK_SIZE;
- sec_abt_stacktop = sec_und_stacktop + STACK_SIZE;
- sec_svc_stacktop = sec_und_stacktop + STACK_SIZE;
- boot_stacktop = sec_svc_stacktop;
- mon_stacktop = sec_svc_stacktop + STACK_SIZE;
+ /* Page align the text section as we map it differently than the above
+ * vector text.
+ */
+ . = ALIGN(0x1000);
+ _flash_sectext_start = _flash_secvecs_start + _secvecs_size;
+ _ram_sectext_start = .;
+ .text : AT ( _flash_sectext_start ) { *(.text); }
+ _ram_sectext_end = .;
+ _sectext_size = _ram_sectext_end - _ram_sectext_start;
- . = ALIGN(1M);
- secure_memory_heap = .;
+ _flash_secdata_start = _flash_sectext_start + _sectext_size;
+ . = ALIGN(1M);
+ _ram_secdata_start = .;
+ .rodata : AT ( _flash_secdata_start ) { *(.rodata); }
+ .data : { *(.data); }
+ .bss : { *(.bss); }
+ _ram_secdata_end = .;
+ _secdata_size = _ram_secdata_end - _ram_secdata_start;
- . = ALIGN(16M);
- sec_l1_page_table = .;
+ . = ALIGN(STACK_SIZE);
+ _secstack_start = .;
+ sec_usr_stacktop = . + STACK_SIZE;
+ sec_und_stacktop = sec_usr_stacktop + STACK_SIZE;
+ sec_abt_stacktop = sec_und_stacktop + STACK_SIZE;
+ sec_svc_stacktop = sec_und_stacktop + STACK_SIZE;
+ boot_stacktop = sec_svc_stacktop;
+ mon_stacktop = sec_svc_stacktop + STACK_SIZE;
+ _secstack_size = mon_stacktop - _secstack_start;
- . = TZTEST_COMMON_HEAP_BASE;
- _common_memory_heap_base = .;
+ . = ALIGN(1M);
+ secure_memory_heap = .;
- . = TZTEST_SHARED_HEAP_BASE;
- _shared_memory_heap_base = .;
- . += 4;
- _tztest_test_count = .;
- . += 4;
- _tztest_fail_count = .;
- . += 4;
- _tztest_exception = .;
- . += 4;
- _tztest_exception_status = .;
- . += 4;
+ . = ALIGN(16M);
+ _sec_l1_page_table = .;
+
+ . = TZTEST_COMMON_HEAP_BASE;
+ _common_memory_heap_base = .;
+
+ . = TZTEST_SHARED_HEAP_BASE;
+ _shared_memory_heap_base = .;
+ . += 4;
+ _tztest_test_count = .;
+ . += 4;
+ _tztest_fail_count = .;
+ . += 4;
+ _tztest_exception = .;
+ . += 4;
+ _tztest_exception_status = .;
+ . += 4;
+ _tztest_exception_addr = .;
+ . += 4;
}
diff --git a/arm/tztest_secure_svc.c b/arm/tztest_secure_svc.c
deleted file mode 100644
index 35db21b..0000000
--- a/arm/tztest_secure_svc.c
+++ /dev/null
@@ -1,206 +0,0 @@
-#include "tztest.h"
-
-/* Make the below globals volatile as found that the compiler uses the
- * register value ratherh than the memory value making it look like the writes
- * actually happened.
- */
-extern int _ram_nsec_base;
-
-int dispatch_secure_usr(int, int);
-void tztest_secure_svc_loop(int initial_r0, int initial_r1);
-void *sec_allocate_secure_memory(int);
-extern uint32_t sec_l1_page_table;
-extern uint32_t _ram_sectext_start;
-extern uint32_t _ram_secdata_start;
-extern uint32_t _shared_memory_heap_base;
-extern uint32_t _common_memory_heap_base;
-extern volatile int _tztest_exception;
-extern volatile int _tztest_exception_status;
-extern volatile int _tztest_test_count;
-extern volatile int _tztest_fail_count;
-volatile int *tztest_test_count = &_tztest_test_count;
-volatile int *tztest_fail_count = &_tztest_fail_count;
-volatile int *tztest_exception = &_tztest_exception;
-volatile int *tztest_exception_addr = 0;
-volatile int *tztest_exception_status = &_tztest_exception_status;
-
-pagetable_map_entry_t sec_pagetable_entries[] = {
- {.va = (uint32_t)&_ram_sectext_start, .pa = (uint32_t)&_ram_sectext_start,
- .size = SECTION_SIZE,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_WBA_CACHED |
- SECTION_P1_RO | SECTION_P0_RO | SECTION_SECTION },
- {.va = (uint32_t)&_ram_secdata_start, .pa = (uint32_t)&_ram_secdata_start,
- .size = SECTION_SIZE * 2,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_WBA_CACHED |
- SECTION_P1_RW | SECTION_P0_RW | SECTION_SECTION },
-};
-
-pagetable_map_entry_t nsec_pagetable_entries[] = {
- {.va = (uint32_t)&_ram_nsec_base, .pa = (uint32_t)&_ram_nsec_base,
- .size = SECTION_SIZE * 2,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_WBA_CACHED |
- SECTION_P1_RW | SECTION_P0_RW | SECTION_NONSECURE |
- SECTION_SECTION },
-};
-
-pagetable_map_entry_t mmio_pagetable_entries[] = {
- {.va = UART0_BASE, .pa = UART0_BASE, .size = SECTION_SIZE,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_UNCACHED |
- SECTION_P1_RW | SECTION_P0_RW | SECTION_NONSECURE |
- SECTION_SECTION },
-};
-
-pagetable_map_entry_t heap_pagetable_entries[] = {
- {.va = (uint32_t)&_shared_memory_heap_base,
- .pa = (uint32_t)&_shared_memory_heap_base,
- .size = SECTION_SIZE,
- .attr = SECTION_SHARED | SECTION_NOTGLOBAL | SECTION_UNCACHED |
- SECTION_P1_RW | SECTION_P0_RW | SECTION_SECTION },
-};
-
-void sec_svc_handler(volatile uint32_t op, volatile tztest_svc_desc_t *desc)
-{
- DEBUG_MSG("Entered\n");
- switch (op) {
- case SVC_GET_SECURE_STATE:
- /* This SVC handler is only accessible from the secure vector
- * table, so unless something went drastically wrong with the
- * tables, it should be safe to assume we are in a nonsecure state.
- */
- desc->secure_state.state = TZTEST_STATE_SECURE;
- break;
- }
- DEBUG_MSG("Exiting\n");
- return;
-}
-
-void sec_undef_handler() {
- DEBUG_MSG("Undefined exception taken\n");
- *tztest_exception = CPSR_MODE_UND;
- *tztest_exception_status = 0;
-}
-
-void sec_pabort_handler(int status, int addr) {
- DEBUG_MSG("status = 0x%x\taddress = 0x%x\n", status, addr);
- *tztest_exception = CPSR_MODE_ABT;
- *tztest_exception_addr = addr;
- *tztest_exception_status = status & 0x1f;
-}
-
-void sec_dabort_handler(int status, int addr) {
- DEBUG_MSG("Data Abort: %s\n", FAULT_STR(status & 0x1f));
- DEBUG_MSG("status = 0x%x\taddress = 0x%x\n",
- status & 0x1f, addr);
- *tztest_exception = CPSR_MODE_ABT;
- *tztest_exception_addr = addr;
- *tztest_exception_status = status & 0x1f;
-}
-
-int secure_test_var = 42;
-
-void check_init_mode()
-{
- printf("\nValidating startup state:\n");
-
- printf("\tChecking for security extension ...");
- int idpfr1 = 0;
- /* Read the ID_PFR1 CP register and check that it is marked for support of
- * the security extension.
- */
- __mrc(15, 0, idpfr1, 0, 1, 1);
- if (0x10 != (idpfr1 & 0xf0)) {
- printf("FAILED\n");
- DEBUG_MSG("current IDPFR1 (%d) != expected IDPFR1 (%d)\n",
- (idpfr1 & 0xf0), 0x10);
- assert(0x10 == (idpfr1 & 0xf0));
- } else {
- printf("PASSED\n");
- }
-
- printf("\tChecking initial processor mode... ");
- if (CPSR_MODE_SVC != (_read_cpsr() & 0x1f)) {
- printf("FAILED\n");
- DEBUG_MSG("current CPSR (%d) != expected CPSR (%d)\n",
- (_read_cpsr() & 0x1f), CPSR_MODE_SVC);
- assert(CPSR_MODE_SVC == (_read_cpsr() & 0x1f));
- } else {
- printf("PASSED\n");
- }
-
- printf("\tChecking initial security state... ");
- if (0 != (_read_scr() & SCR_NS)) {
- printf("Failed\n");
- DEBUG_MSG("current SCR.NS (%d) != expected SCR.NS (%d)\n",
- (_read_cpsr() & SCR_NS), 0);
- assert(0 == (_read_scr() & SCR_NS));
- } else {
- printf("PASSED\n");
- }
-}
-
-void tztest_secure_svc_loop(int initial_op, int initial_data)
-{
- volatile int op = initial_op;
- tztest_smc_desc_t *data = (tztest_smc_desc_t *)initial_data;
- uint32_t (*func)(uint32_t);
-
- DEBUG_MSG("Initial call\n");
-
- while (SMC_EXIT != op) {
- switch (op) {
- case SMC_DISPATCH_SECURE_USR:
- DEBUG_MSG("Dispatching secure USR function\n");
- data->dispatch.ret =
- dispatch_secure_usr((int)data->dispatch.func,
- data->dispatch.arg);
- DEBUG_MSG("Returned from secure USR dispatch\n");
- break;
- case SMC_DISPATCH_SECURE_SVC:
- func = (uint32_t (*)())data->dispatch.func;
- DEBUG_MSG("Dispatching secure SVC function\n");
- data->dispatch.ret = func(data->dispatch.arg);
- DEBUG_MSG("Returned from secure SVC dispatch\n");
- break;
- }
- __smc(op, data);
- DEBUG_MSG("Handling smc op 0x%x\n", op);
- }
-
- DEBUG_MSG("Exiting\n");
-}
-
-void tztest_secure_pagetable_init()
-{
- uint32_t *table = &sec_l1_page_table;
- uint32_t count;
-
- pagetable_init(table);
-
- pagetable_add_sections(table, mmio_pagetable_entries, 1);
- count = sizeof(sec_pagetable_entries) / sizeof(sec_pagetable_entries[0]);
- pagetable_add_sections(table, sec_pagetable_entries, count);
- count = sizeof(nsec_pagetable_entries) / sizeof(nsec_pagetable_entries[0]);
- pagetable_add_sections(table, nsec_pagetable_entries, 1);
- pagetable_add_sections(table, heap_pagetable_entries, 1);
-}
-
-void tztest_secure_svc_init_monitor()
-{
- struct sm_nsec_ctx *nsec_ctx;
-
-
- /* Set-up the non-secure context so that the switch to nonsecure state
- * resumes at initiallizing the nonsecure svc mode.
- */
- nsec_ctx = sm_get_nsec_ctx();
- nsec_ctx->mon_lr = (uint32_t)&_ram_nsec_base;
- nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I;
-}
-
-void tztest_dispatch_monitor(tztest_smc_desc_t *desc)
-{
- uint32_t (*func)(uint32_t) = desc->dispatch.func;
- DEBUG_MSG("Entered\n");
- func(desc->dispatch.arg);
- DEBUG_MSG("Exiting\n");
-}
diff --git a/configure b/configure
index 8a463ef..ca13c40 100755
--- a/configure
+++ b/configure
@@ -5,8 +5,9 @@ ld=ld
objcopy=objcopy
ar=ar
arch=arm
-plat=vexpress
-cross_prefix=
+plat=vexpress-a15
+cpu=cortex-a15
+cross_prefix=arm-linux-gnueabi-
usage() {
cat <<-EOF
@@ -15,7 +16,7 @@ usage() {
Options include:
--arch=ARCH architecture to compile for ($arch)
--plat=PLATFORM platform to compile for ($plat)
- --processor=PROCESSOR processor to compile for ($arch)
+ --cpu=PROCESSOR cpu to compile for ($arch)
--cross-prefix=PREFIX cross compiler prefix
--cc=CC c compiler to use ($cc)
--ld=LD ld linker to use ($ld)
@@ -37,8 +38,8 @@ while [[ "$1" = -* ]]; do
--plat)
plat="$arg"
;;
- --processor)
- processor="$arg"
+ --cpu)
+ cpu="$arg"
;;
--cross-prefix)
cross_prefix="$arg"
@@ -57,10 +58,10 @@ while [[ "$1" = -* ]]; do
;;
esac
done
-[ -z "$processor" ] && processor="$arch"
+[ -z "$cpu" ] && cpu="$arch"
-if [ "$processor" = "arm" ]; then
- processor="cortex-a15"
+if [ "$cpu" = "arm" ]; then
+ cpu="cortex-a15"
fi
# check for dependent 32 bit libraries
@@ -85,7 +86,7 @@ fi
cat <<EOF > config.mak
ARCH=$arch
PLAT=$plat
-PROCESSOR=$processor
+PROCESSOR=$cpu
CC=$cross_prefix$cc
LD=$cross_prefix$ld
OBJCOPY=$cross_prefix$objcopy
diff --git a/lib/libcflat/argv.c b/lib/libcflat/argv.c
deleted file mode 100644
index 078a05f..0000000
--- a/lib/libcflat/argv.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "libcflat.h"
-
-int __argc;
-char *__argv[100];
-char *__args;
-char __args_copy[1000];
-
-static bool isblank(char p)
-{
- return p == ' ' || p == '\t';
-}
-
-static char *skip_blanks(char *p)
-{
- while (isblank(*p))
- ++p;
- return p;
-}
-
-void __setup_args(void)
-{
- char *args = __args;
- char **argv = __argv;
- char *p = __args_copy;
-
- while (*(args = skip_blanks(args)) != '\0') {
- *argv++ = p;
- while (*args != '\0' && !isblank(*args))
- *p++ = *args++;
- *p++ = '\0';
- }
- __argc = argv - __argv;
-}
-
-void setup_args(char *args)
-{
- __args = args;
- __setup_args();
-}
diff --git a/lib/libcflat/arm/asm-offsets.c b/lib/libcflat/arm/asm-offsets.c
deleted file mode 100644
index a9c349d..0000000
--- a/lib/libcflat/arm/asm-offsets.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Adapted from arch/arm/kernel/asm-offsets.c
- *
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-#include "asm/ptrace.h"
-
-#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-#define OFFSET(sym, str, mem) DEFINE(sym, offsetof(struct str, mem))
-#define COMMENT(x) asm volatile("\n->#" x)
-#define BLANK() asm volatile("\n->" : : )
-
-int main(void)
-{
- OFFSET(S_R0, pt_regs, ARM_r0);
- OFFSET(S_R1, pt_regs, ARM_r1);
- OFFSET(S_R2, pt_regs, ARM_r2);
- OFFSET(S_R3, pt_regs, ARM_r3);
- OFFSET(S_R4, pt_regs, ARM_r4);
- OFFSET(S_R5, pt_regs, ARM_r5);
- OFFSET(S_R6, pt_regs, ARM_r6);
- OFFSET(S_R7, pt_regs, ARM_r7);
- OFFSET(S_R8, pt_regs, ARM_r8);
- OFFSET(S_R9, pt_regs, ARM_r9);
- OFFSET(S_R10, pt_regs, ARM_r10);
- OFFSET(S_FP, pt_regs, ARM_fp);
- OFFSET(S_IP, pt_regs, ARM_ip);
- OFFSET(S_SP, pt_regs, ARM_sp);
- OFFSET(S_LR, pt_regs, ARM_lr);
- OFFSET(S_PC, pt_regs, ARM_pc);
- OFFSET(S_PSR, pt_regs, ARM_cpsr);
- OFFSET(S_OLD_R0, pt_regs, ARM_ORIG_r0);
- DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
- return 0;
-}
diff --git a/lib/libcflat/arm/asm/asm-offsets.h b/lib/libcflat/arm/asm/asm-offsets.h
deleted file mode 100644
index c2ff2ba..0000000
--- a/lib/libcflat/arm/asm/asm-offsets.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "generated/asm-offsets.h"
diff --git a/lib/libcflat/arm/asm/barrier.h b/lib/libcflat/arm/asm/barrier.h
deleted file mode 100644
index acaeab5..0000000
--- a/lib/libcflat/arm/asm/barrier.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _ASMARM_BARRIER_H_
-#define _ASMARM_BARRIER_H_
-/*
- * Adapted form arch/arm/include/asm/barrier.h
- */
-
-#define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
-#define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
-#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
-
-#define mb() dsb()
-#define rmb() dsb()
-#define wmb() dsb(st)
-#define smp_mb() dmb(ish)
-#define smp_rmb() smp_mb()
-#define smp_wmb() dmb(ishst)
-
-#endif /* _ASMARM_BARRIER_H_ */
diff --git a/lib/libcflat/arm/asm/cp15.h b/lib/libcflat/arm/asm/cp15.h
deleted file mode 100644
index 7690a48..0000000
--- a/lib/libcflat/arm/asm/cp15.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _ASMARM_CP15_H_
-#define _ASMARM_CP15_H_
-/*
- * From the Linux kernel arch/arm/include/asm/cp15.h
- *
- * CR1 bits (CP#15 CR1)
- */
-#define CR_M (1 << 0) /* MMU enable */
-#define CR_A (1 << 1) /* Alignment abort enable */
-#define CR_C (1 << 2) /* Dcache enable */
-#define CR_W (1 << 3) /* Write buffer enable */
-#define CR_P (1 << 4) /* 32-bit exception handler */
-#define CR_D (1 << 5) /* 32-bit data address range */
-#define CR_L (1 << 6) /* Implementation defined */
-#define CR_B (1 << 7) /* Big endian */
-#define CR_S (1 << 8) /* System MMU protection */
-#define CR_R (1 << 9) /* ROM MMU protection */
-#define CR_F (1 << 10) /* Implementation defined */
-#define CR_Z (1 << 11) /* Implementation defined */
-#define CR_I (1 << 12) /* Icache enable */
-#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
-#define CR_RR (1 << 14) /* Round Robin cache replacement */
-#define CR_L4 (1 << 15) /* LDR pc can set T bit */
-#define CR_DT (1 << 16)
-#define CR_HA (1 << 17) /* Hardware management of Access Flag */
-#define CR_IT (1 << 18)
-#define CR_ST (1 << 19)
-#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */
-#define CR_U (1 << 22) /* Unaligned access operation */
-#define CR_XP (1 << 23) /* Extended page tables */
-#define CR_VE (1 << 24) /* Vectored interrupts */
-#define CR_EE (1 << 25) /* Exception (Big) Endian */
-#define CR_TRE (1 << 28) /* TEX remap enable */
-#define CR_AFE (1 << 29) /* Access flag enable */
-#define CR_TE (1 << 30) /* Thumb exception enable */
-
-#endif /* _ASMARM_CP15_H_ */
diff --git a/lib/libcflat/arm/asm/processor.h b/lib/libcflat/arm/asm/processor.h
deleted file mode 100644
index b7d3be0..0000000
--- a/lib/libcflat/arm/asm/processor.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _ASMARM_PROCESSOR_H_
-#define _ASMARM_PROCESSOR_H_
-/*
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "ptrace.h"
-
-enum vector {
- EXCPTN_RST,
- EXCPTN_UND,
- EXCPTN_SVC,
- EXCPTN_PABT,
- EXCPTN_DABT,
- EXCPTN_ADDREXCPTN,
- EXCPTN_IRQ,
- EXCPTN_FIQ,
- EXCPTN_MAX,
-};
-
-typedef void (*exception_fn)(struct pt_regs *);
-extern void install_exception_handler(enum vector v, exception_fn fn);
-
-extern void show_regs(struct pt_regs *regs);
-extern void *get_sp(void);
-
-static inline unsigned long current_cpsr(void)
-{
- unsigned long cpsr;
- asm volatile("mrs %0, cpsr" : "=r" (cpsr));
- return cpsr;
-}
-
-#define current_mode() (current_cpsr() & MODE_MASK)
-
-extern void
-phys_start_usr(size_t stacksize, void (*func)(void *arg), void *arg);
-
-#endif /* _ASMARM_PROCESSOR_H_ */
diff --git a/lib/libcflat/arm/asm/ptrace.h b/lib/libcflat/arm/asm/ptrace.h
deleted file mode 100644
index 3a4c753..0000000
--- a/lib/libcflat/arm/asm/ptrace.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef _ASMARM_PTRACE_H_
-#define _ASMARM_PTRACE_H_
-/*
- * Adapted from Linux kernel headers
- * arch/arm/include/asm/ptrace.h
- * arch/arm/include/uapi/asm/ptrace.h
- */
-
-/*
- * PSR bits
- */
-#define USR_MODE 0x00000010
-#define SVC_MODE 0x00000013
-#define FIQ_MODE 0x00000011
-#define IRQ_MODE 0x00000012
-#define ABT_MODE 0x00000017
-#define HYP_MODE 0x0000001a
-#define UND_MODE 0x0000001b
-#define SYSTEM_MODE 0x0000001f
-#define MODE32_BIT 0x00000010
-#define MODE_MASK 0x0000001f
-
-#define PSR_T_BIT 0x00000020 /* >= V4T, but not V7M */
-#define PSR_F_BIT 0x00000040 /* >= V4, but not V7M */
-#define PSR_I_BIT 0x00000080 /* >= V4, but not V7M */
-#define PSR_A_BIT 0x00000100 /* >= V6, but not V7M */
-#define PSR_E_BIT 0x00000200 /* >= V6, but not V7M */
-#define PSR_J_BIT 0x01000000 /* >= V5J, but not V7M */
-#define PSR_Q_BIT 0x08000000 /* >= V5E, including V7M */
-#define PSR_V_BIT 0x10000000
-#define PSR_C_BIT 0x20000000
-#define PSR_Z_BIT 0x40000000
-#define PSR_N_BIT 0x80000000
-
-/*
- * Groups of PSR bits
- */
-#define PSR_f 0xff000000 /* Flags */
-#define PSR_s 0x00ff0000 /* Status */
-#define PSR_x 0x0000ff00 /* Extension */
-#define PSR_c 0x000000ff /* Control */
-
-/*
- * ARMv7 groups of PSR bits
- */
-#define APSR_MASK 0xf80f0000 /* N, Z, C, V, Q and GE flags */
-#define PSR_ISET_MASK 0x01000010 /* ISA state (J, T) mask */
-#define PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
-#define PSR_ENDIAN_MASK 0x00000200 /* Endianness state mask */
-
-#ifndef __ASSEMBLY__
-#include "libcflat.h"
-
-struct pt_regs {
- unsigned long uregs[18];
-};
-
-#define ARM_cpsr uregs[16]
-#define ARM_pc uregs[15]
-#define ARM_lr uregs[14]
-#define ARM_sp uregs[13]
-#define ARM_ip uregs[12]
-#define ARM_fp uregs[11]
-#define ARM_r10 uregs[10]
-#define ARM_r9 uregs[9]
-#define ARM_r8 uregs[8]
-#define ARM_r7 uregs[7]
-#define ARM_r6 uregs[6]
-#define ARM_r5 uregs[5]
-#define ARM_r4 uregs[4]
-#define ARM_r3 uregs[3]
-#define ARM_r2 uregs[2]
-#define ARM_r1 uregs[1]
-#define ARM_r0 uregs[0]
-#define ARM_ORIG_r0 uregs[17]
-
-#define user_mode(regs) \
- (((regs)->ARM_cpsr & 0xf) == 0)
-
-#define processor_mode(regs) \
- ((regs)->ARM_cpsr & MODE_MASK)
-
-#define interrupts_enabled(regs) \
- (!((regs)->ARM_cpsr & PSR_I_BIT))
-
-#define fast_interrupts_enabled(regs) \
- (!((regs)->ARM_cpsr & PSR_F_BIT))
-
-#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))
-
-static inline unsigned long regs_get_register(struct pt_regs *regs,
- unsigned int offset)
-{
- if (offset > MAX_REG_OFFSET)
- return 0;
- return *(unsigned long *)((unsigned long)regs + offset);
-}
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASMARM_PTRACE_H_ */
diff --git a/lib/libcflat/arm/asm/semihosting.h b/lib/libcflat/arm/asm/semihosting.h
deleted file mode 100644
index ba13036..0000000
--- a/lib/libcflat/arm/asm/semihosting.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2012 Linaro Limited
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Linaro Limited nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- */
-
-#ifndef SEMIHOSTING_H
-#define SEMIHOSTING_H
-
-#define SYS_OPEN 1
-#define OPEN_RDONLY 1
-#define SYS_CLOSE 2
-#define SYS_WRITE0 4
-#define SYS_WRITE 5
-#define SYS_READ 6
-#define SYS_FLEN 0x0C
-#define SYS_GET_CMDLINE 0x15
-#define SYS_REPORTEXC 0x18
-#define REPORTEXC_REASON_APP_EXIT 0x20026
-#define SEMIHOSTING_SVC 0x123456 /* SVC comment field for semihosting */
-
-#ifndef __ASSEMBLER__
-
-int __semi_call(int id, ...);
-int semi_open(char const *filename, int mode);
-int semi_close(int fd);
-int semi_write0(char const *string);
-int semi_read(int fd, char *buffer, int length);
-int semi_flen(int fd);
-int semi_get_cmdline(char *buffer, int size, int *length);
-int semi_reportexc(int reason);
-void semi_fatal(char const *message);
-void semi_exit(void);
-/* semi_load_file: *dest is advanced to point to the end of the loaded data */
-int semi_load_file(void **dest, unsigned *size, char const *filename);
-
-#endif /* ! __ASSEMBLER__ */
-
-#endif /* ! SEMIHOSTING_H */
diff --git a/lib/libcflat/arm/asm/setup.h b/lib/libcflat/arm/asm/setup.h
deleted file mode 100644
index 8aedf6e..0000000
--- a/lib/libcflat/arm/asm/setup.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef _ASMARM_SETUP_H_
-#define _ASMARM_SETUP_H_
-/*
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-
-#define NR_CPUS 8
-extern u32 cpus[NR_CPUS];
-extern int nr_cpus;
-
-typedef u64 phys_addr_t;
-
-/*
- * memregions implement a very simple allocator which allows physical
- * memory to be partitioned into regions until all memory is allocated.
- * Also, as long as not all memory has been allocated, one region (the
- * highest indexable region) is used to represent the start and size of
- * the remaining free memory. This means that there will always be a
- * minimum of two regions: one for the unit test code, initially loaded
- * at the base of physical memory (PHYS_OFFSET), and another for the
- * remaining free memory.
- *
- * Note: This is such a simple allocator that there is no way to free
- * a memregion. For more complicated memory management a single region
- * can be allocated, but then have its memory managed by a more
- * sophisticated allocator, e.g. a page allocator.
- */
-#define NR_MEMREGIONS 16
-struct memregion {
- phys_addr_t addr;
- phys_addr_t size;
- bool free;
-};
-
-extern struct memregion memregions[NR_MEMREGIONS];
-extern int nr_memregions;
-
-/*
- * memregion_new returns a new memregion of size @size, or NULL if
- * there isn't enough free memory to satisfy the request.
- */
-extern struct memregion *memregion_new(phys_addr_t size);
-
-/*
- * memregions_show outputs all memregions with the following format
- * <start_addr>-<end_addr> [<USED|FREE>]
- */
-extern void memregions_show(void);
-
-#define PHYS_OFFSET ({ memregions[0].addr; })
-#define PHYS_SHIFT 40
-#define PHYS_SIZE (1ULL << PHYS_SHIFT)
-#define PHYS_MASK (PHYS_SIZE - 1ULL)
-
-#define PAGE_SHIFT 12
-#define PAGE_SIZE (1UL << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE - 1UL))
-#define PAGE_ALIGN(addr) (((addr) + (PAGE_SIZE-1UL)) & PAGE_MASK)
-
-#endif /* _ASMARM_SETUP_H_ */
diff --git a/lib/libcflat/arm/asm/spinlock.h b/lib/libcflat/arm/asm/spinlock.h
deleted file mode 100644
index 2118a4b..0000000
--- a/lib/libcflat/arm/asm/spinlock.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _ASMARM_SPINLOCK_H_
-#define _ASMARM_SPINLOCK_H_
-
-struct spinlock {
- int v;
-};
-
-extern void spin_lock(struct spinlock *lock);
-extern void spin_unlock(struct spinlock *lock);
-
-#endif /* _ASMARM_SPINLOCK_H_ */
diff --git a/lib/libcflat/arm/io.c b/lib/libcflat/arm/io.c
deleted file mode 100644
index f02c4a8..0000000
--- a/lib/libcflat/arm/io.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Each architecture must implement puts() and exit() with the I/O
- * devices exposed from QEMU, e.g. pl011 and virtio-testdev. That's
- * what's done here, along with initialization functions for those
- * devices.
- *
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-#include "devicetree.h"
-#include "virtio-testdev.h"
-#include "asm/spinlock.h"
-#include "asm/io.h"
-
-extern void halt(int code);
-
-/*
- * Use this guess for the pl011 base in order to make an attempt at
- * having earlier printf support. We'll overwrite it with the real
- * base address that we read from the device tree later.
- */
-//#define QEMU_MACH_VIRT_PL011_BASE 0x09000000UL
-#define QEMU_MACH_VIRT_PL011_BASE 0x1c090000UL
-
-static struct spinlock uart_lock;
-static volatile u8 *uart0_base = (u8 *)QEMU_MACH_VIRT_PL011_BASE;
-
-static void uart0_init(void)
-{
- const char *compatible = "arm,pl011";
- struct dt_pbus_reg base;
- int ret;
-
- ret = dt_pbus_get_base_compatible(compatible, &base);
- assert(ret == 0 || ret == -FDT_ERR_NOTFOUND);
-
- if (ret) {
- printf("%s: %s not found in the device tree, aborting...\n",
- __func__, compatible);
- abort();
- }
-
- uart0_base = ioremap(base.addr, base.size);
-}
-
-void io_init(void)
-{
- uart0_init();
- virtio_testdev_init();
-}
-
-void puts(const char *s)
-{
- spin_lock(&uart_lock);
- while (*s)
- writeb(*s++, uart0_base);
- spin_unlock(&uart_lock);
-}
-
-void exit(int code)
-{
- virtio_testdev_exit(code);
- halt(code);
-}
diff --git a/lib/libcflat/arm/processor.c b/lib/libcflat/arm/processor.c
deleted file mode 100644
index 47e290b..0000000
--- a/lib/libcflat/arm/processor.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * processor control and status functions
- *
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-#include "asm/setup.h"
-#include "asm/ptrace.h"
-#include "asm/processor.h"
-
-static const char *processor_modes[] = {
- "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" ,
- "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
- "UK8_26" , "UK9_26" , "UK10_26", "UK11_26",
- "UK12_26", "UK13_26", "UK14_26", "UK15_26",
- "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" ,
- "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
- "UK8_32" , "UK9_32" , "UK10_32", "UND_32" ,
- "UK12_32", "UK13_32", "UK14_32", "SYS_32"
-};
-
-static char *vector_names[] = {
- "rst", "und", "svc", "pabt", "dabt", "addrexcptn", "irq", "fiq"
-};
-
-void show_regs(struct pt_regs *regs)
-{
- unsigned long flags;
- char buf[64];
-
- printf("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n"
- "sp : %08lx ip : %08lx fp : %08lx\n",
- regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
- regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
- printf("r10: %08lx r9 : %08lx r8 : %08lx\n",
- regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
- printf("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
- regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
- printf("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
- regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
-
- flags = regs->ARM_cpsr;
- buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
- buf[1] = flags & PSR_Z_BIT ? 'Z' : 'z';
- buf[2] = flags & PSR_C_BIT ? 'C' : 'c';
- buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
- buf[4] = '\0';
-
- printf("Flags: %s IRQs o%s FIQs o%s Mode %s\n",
- buf, interrupts_enabled(regs) ? "n" : "ff",
- fast_interrupts_enabled(regs) ? "n" : "ff",
- processor_modes[processor_mode(regs)]);
-
- if (!user_mode(regs)) {
- unsigned int ctrl, transbase, dac;
- asm volatile(
- "mrc p15, 0, %0, c1, c0\n"
- "mrc p15, 0, %1, c2, c0\n"
- "mrc p15, 0, %2, c3, c0\n"
- : "=r" (ctrl), "=r" (transbase), "=r" (dac));
- printf("Control: %08x Table: %08x DAC: %08x\n",
- ctrl, transbase, dac);
- }
-}
-
-void *get_sp(void)
-{
- register unsigned long sp asm("sp");
- return (void *)sp;
-}
-
-static exception_fn exception_handlers[EXCPTN_MAX];
-
-void install_exception_handler(enum vector v, exception_fn fn)
-{
- if (v < EXCPTN_MAX)
- exception_handlers[v] = fn;
-}
-
-void do_handle_exception(enum vector v, struct pt_regs *regs)
-{
- if (v < EXCPTN_MAX && exception_handlers[v]) {
- exception_handlers[v](regs);
- return;
- }
-
- if (v < EXCPTN_MAX)
- printf("Unhandled exception %d (%s)\n", v, vector_names[v]);
- else
- printf("%s called with vector=%d\n", __func__, v);
-
- printf("Exception frame registers:\n");
- show_regs(regs);
- abort();
-}
-
-void phys_start_usr(size_t stacksize, void (*func)(void *arg), void *arg)
-{
- struct memregion *m = memregion_new(stacksize);
- unsigned long sp_usr = (unsigned long)(m->addr + m->size);
-
- sp_usr &= (~7UL); /* stack ptr needs 8-byte alignment */
-
- asm volatile(
- "mrs r0, cpsr\n"
- "bic r0, #" xstr(MODE_MASK) "\n"
- "orr r0, #" xstr(USR_MODE) "\n"
- "msr cpsr_c, r0\n"
- "mov r0, %0\n"
- "mov sp, %1\n"
- "mov pc, %2\n"
- :: "r" (arg), "r" (sp_usr), "r" (func) : "r0");
-}
diff --git a/lib/libcflat/arm/semihosting.c b/lib/libcflat/arm/semihosting.c
deleted file mode 100644
index 7b4af2b..0000000
--- a/lib/libcflat/arm/semihosting.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2012 Linaro Limited
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Linaro Limited nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- */
-
-#include "semihosting.h"
-#include "libcflat.h"
-
-int semi_open(char const *filename, int mode)
-{
- struct {
- char const *filename;
- int mode;
- int filename_length;
- } args;
-
- args.filename = filename;
- args.mode = mode;
- args.filename_length = strlen(filename);
-
- return __semi_call(SYS_OPEN, &args);
-}
-
-int semi_close(int fd)
-{
- return __semi_call(SYS_CLOSE, &fd);
-}
-
-int semi_write0(char const *string)
-{
- return __semi_call(SYS_WRITE0, string);
-}
-
-typedef struct {
- int fd;
- char *buffer;
- int length;
-} args_t;
-
-int semi_write(int fd, char *buffer, int length)
-{
- args_t args;
-
- args.fd = fd;
- args.buffer = buffer;
- args.length = length;
-
- return __semi_call(SYS_WRITE, &args);
-}
-
-int semi_read(int fd, char *buffer, int length)
-{
- struct {
- int fd;
- char *buffer;
- int length;
- } args;
-
- args.fd = fd;
- args.buffer = buffer;
- args.length = length;
-
- return __semi_call(SYS_READ, &args);
-}
-
-int semi_flen(int fd)
-{
- return __semi_call(SYS_FLEN, &fd);
-}
-
-int semi_get_cmdline(char *buffer, int size, int *length)
-{
- int result;
- struct {
- char *buffer;
- int size;
- } args;
-
- args.buffer = buffer;
- args.size = size;
-
- result = __semi_call(SYS_GET_CMDLINE, &args);
- if(result)
- return result;
-
- if(length)
- *length = args.size;
-
- return 0;
-}
-
-int semi_reportexc(int reason)
-{
- return __semi_call(SYS_REPORTEXC, (void *)reason);
-}
-
-void semi_exit(void)
-{
- semi_reportexc(REPORTEXC_REASON_APP_EXIT);
- while(1); /* should not be reached */
-}
-
-void semi_fatal(char const *message)
-{
- semi_write0(message);
- semi_exit();
-}
-
-int semi_load_file(void **dest, unsigned *size, char const *filename)
-{
- int result = -1; /* fail by default */
- int fd = -1;
- int filesize;
-
- fd = semi_open(filename, OPEN_RDONLY);
- if(fd == -1) {
- semi_write0("Cannot open file: ");
- goto out;
- }
-
- filesize = semi_flen(fd);
- if(filesize == -1) {
- semi_write0("Cannot get file size for: ");
- goto out;
- }
-
- if(semi_read(fd, *dest, filesize)) {
- semi_write0("Could not read: ");
- goto out;
- }
-
- result = 0; /* success */
- *dest = (char *)*dest + filesize;
-
-out:
- if(fd != -1)
- semi_close(fd);
-
- if(result) { /* print context for the error message */
- semi_write0(filename);
- semi_write0("\n");
- } else
- if(size)
- *size = filesize;
-
- return result;
-}
diff --git a/lib/libcflat/arm/setup.c b/lib/libcflat/arm/setup.c
deleted file mode 100644
index 68a244a..0000000
--- a/lib/libcflat/arm/setup.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Initialize machine setup information and I/O.
- *
- * After running setup() unit tests may query how many cpus they have
- * (nr_cpus), how much free memory it has, and at what physical
- * address that free memory starts (memregions[1].{addr,size}),
- * printf() and exit() will both work, and (argc, argv) are ready
- * to be passed to main().
- *
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-#include "libfdt/libfdt.h"
-#include "devicetree.h"
-#include "asm/spinlock.h"
-#include "asm/setup.h"
-
-extern unsigned long stacktop;
-extern void io_init(void);
-extern void setup_args(const char *args);
-
-u32 cpus[NR_CPUS] = { [0 ... NR_CPUS-1] = (~0UL) };
-int nr_cpus;
-
-static struct spinlock memregion_lock;
-struct memregion memregions[NR_MEMREGIONS];
-int nr_memregions;
-
-static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
-{
- assert(nr_cpus < NR_CPUS);
- cpus[nr_cpus++] = regval;
-}
-
-static void cpu_init(void)
-{
- nr_cpus = 0;
- assert(dt_for_each_cpu_node(cpu_set, NULL) == 0);
-}
-
-static void memregions_init(phys_addr_t freemem_start)
-{
- /* we only expect one membank to be defined in the DT */
- struct dt_pbus_reg regs[1];
- phys_addr_t addr, size, mem_end;
-
- nr_memregions = dt_get_memory_params(regs, 1);
-
- assert(nr_memregions > 0);
-
- addr = regs[0].addr;
- size = regs[0].size;
- mem_end = addr + size;
-
- assert(!(addr & ~PHYS_MASK) && !((mem_end-1) & ~PHYS_MASK));
-
- memregions[0].addr = PAGE_ALIGN(addr); /* PHYS_OFFSET */
-
- freemem_start = PAGE_ALIGN(freemem_start);
- assert(freemem_start >= PHYS_OFFSET && freemem_start < mem_end);
-
- memregions[0].size = freemem_start - PHYS_OFFSET;
- memregions[1].addr = freemem_start;
- memregions[1].size = mem_end - freemem_start;
- memregions[1].free = true;
- nr_memregions = 2;
-
-#ifdef __arm__
- /*
- * make sure 32-bit unit tests don't have any surprises when
- * running without virtual memory, by ensuring the initial
- * memory region uses 32-bit addresses. Other memory regions
- * may have > 32-bit addresses though, and the unit tests are
- * free to do as they wish with that.
- */
- assert(!(memregions[0].addr >> 32));
- assert(!((memregions[0].addr + memregions[0].size - 1) >> 32));
-#endif
-}
-
-struct memregion *memregion_new(phys_addr_t size)
-{
- phys_addr_t freemem_start, mem_end;
- struct memregion *mr;
-
- spin_lock(&memregion_lock);
-
- mr = &memregions[nr_memregions-1];
-
- if (!mr->free || mr->size < size) {
- printf("%s: requested=0x%llx, free=0x%llx.\n", size,
- mr->free ? mr->size : 0ULL);
- return NULL;
- }
-
- mem_end = mr->addr + mr->size;
-
- mr->size = size;
- mr->free = false;
-
- freemem_start = PAGE_ALIGN(mr->addr + size);
-
- if (freemem_start < mem_end && nr_memregions < NR_MEMREGIONS) {
- mr->size = freemem_start - mr->addr;
- memregions[nr_memregions].addr = freemem_start;
- memregions[nr_memregions].size = mem_end - freemem_start;
- memregions[nr_memregions].free = true;
- ++nr_memregions;
- }
-
- spin_unlock(&memregion_lock);
-
- return mr;
-}
-
-void memregions_show(void)
-{
- int i;
- for (i = 0; i < nr_memregions; ++i)
- printf("%016llx-%016llx [%s]\n",
- memregions[i].addr,
- memregions[i].addr + memregions[i].size - 1,
- memregions[i].free ? "FREE" : "USED");
-}
-
-void setup(unsigned long arg __unused, unsigned long id __unused,
- const void *fdt)
-{
- const char *bootargs;
- u32 fdt_size;
-
- /*
- * Move the fdt to just above the stack. The free memory
- * then starts just after the fdt.
- */
- fdt_size = fdt_totalsize(fdt);
- assert(fdt_move(fdt, &stacktop, fdt_size) == 0);
- assert(dt_init(&stacktop) == 0);
-
- memregions_init((unsigned long)&stacktop + fdt_size);
-
- io_init();
- cpu_init();
-
- assert(dt_get_bootargs(&bootargs) == 0);
- setup_args(bootargs);
-}
diff --git a/lib/libcflat/arm/spinlock.c b/lib/libcflat/arm/spinlock.c
deleted file mode 100644
index d8a6d4c..0000000
--- a/lib/libcflat/arm/spinlock.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "libcflat.h"
-#include "asm/spinlock.h"
-#include "asm/barrier.h"
-
-void spin_lock(struct spinlock *lock)
-{
- u32 val, fail;
-
- dmb();
- do {
- asm volatile(
- "1: ldrex %0, [%2]\n"
- " teq %0, #0\n"
- " bne 1b\n"
- " mov %0, #1\n"
- " strex %1, %0, [%2]\n"
- : "=&r" (val), "=&r" (fail)
- : "r" (&lock->v)
- : "cc" );
- } while (fail);
- dmb();
-}
-
-void spin_unlock(struct spinlock *lock)
-{
- lock->v = 0;
- dmb();
-}
diff --git a/lib/libcflat/asm-generic/spinlock.h b/lib/libcflat/asm-generic/spinlock.h
deleted file mode 100644
index 3141744..0000000
--- a/lib/libcflat/asm-generic/spinlock.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _ASM_GENERIC_SPINLOCK_H_
-#define _ASM_GENERIC_SPINLOCK_H_
-#error need architecture specific asm/spinlock.h
-#endif
diff --git a/lib/libcflat/devicetree.c b/lib/libcflat/devicetree.c
deleted file mode 100644
index 57e7408..0000000
--- a/lib/libcflat/devicetree.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-#include "libfdt/libfdt.h"
-#include "devicetree.h"
-
-static const void *fdt;
-static u32 root_nr_address_cells, root_nr_size_cells;
-
-const void *dt_fdt(void)
-{
- return fdt;
-}
-
-bool dt_available(void)
-{
- return fdt_check_header(fdt) == 0;
-}
-
-int dt_get_nr_cells(int fdtnode, u32 *nr_address_cells, u32 *nr_size_cells)
-{
- const struct fdt_property *prop;
- u32 *nr_cells;
- int len;
-
- prop = fdt_get_property(fdt, fdtnode, "#address-cells", &len);
- if (prop == NULL)
- return len;
-
- nr_cells = (u32 *)prop->data;
- *nr_address_cells = fdt32_to_cpu(*nr_cells);
-
- prop = fdt_get_property(fdt, fdtnode, "#size-cells", &len);
- if (prop == NULL)
- return len;
-
- nr_cells = (u32 *)prop->data;
- *nr_size_cells = fdt32_to_cpu(*nr_cells);
-
- return 0;
-}
-
-void dt_reg_init(struct dt_reg *reg, u32 nr_address_cells, u32 nr_size_cells)
-{
- memset(reg, 0, sizeof(struct dt_reg));
- reg->nr_address_cells = nr_address_cells;
- reg->nr_size_cells = nr_size_cells;
-}
-
-int dt_get_reg(int fdtnode, int regidx, struct dt_reg *reg)
-{
- const struct fdt_property *prop;
- u32 *cells, i;
- unsigned nr_tuple_cells;
- int len;
-
- prop = fdt_get_property(fdt, fdtnode, "reg", &len);
- if (prop == NULL)
- return len;
-
- cells = (u32 *)prop->data;
- nr_tuple_cells = reg->nr_address_cells + reg->nr_size_cells;
- regidx *= nr_tuple_cells;
-
- if (regidx + nr_tuple_cells > len/sizeof(u32))
- return -FDT_ERR_NOTFOUND;
-
- for (i = 0; i < reg->nr_address_cells; ++i)
- reg->address_cells[i] = fdt32_to_cpu(cells[regidx + i]);
-
- regidx += reg->nr_address_cells;
- for (i = 0; i < reg->nr_size_cells; ++i)
- reg->size_cells[i] = fdt32_to_cpu(cells[regidx + i]);
-
- return 0;
-}
-
-int dt_pbus_translate_node(int fdtnode, int regidx,
- struct dt_pbus_reg *pbus_reg)
-{
- struct dt_reg raw_reg;
- int ret;
-
- dt_reg_init(&raw_reg, root_nr_address_cells, root_nr_size_cells);
-
- ret = dt_get_reg(fdtnode, regidx, &raw_reg);
- if (ret < 0)
- return ret;
-
- pbus_reg->addr = dt_pbus_read_cells(raw_reg.nr_address_cells,
- raw_reg.address_cells);
- pbus_reg->size = dt_pbus_read_cells(raw_reg.nr_size_cells,
- raw_reg.size_cells);
-
- return 0;
-}
-
-int dt_pbus_translate(const struct dt_device *dev, int regidx,
- void *reg)
-{
- return dt_pbus_translate_node(dev->fdtnode, regidx, reg);
-}
-
-int dt_bus_match_any(const struct dt_device *dev __unused, int fdtnode)
-{
- /* matches any device with a valid node */
- return fdtnode < 0 ? fdtnode : 1;
-}
-
-static const struct dt_bus dt_default_bus = {
- .match = dt_bus_match_any,
- .translate = dt_pbus_translate,
-};
-
-void dt_bus_init_defaults(struct dt_bus *bus)
-{
- memcpy(bus, &dt_default_bus, sizeof(struct dt_bus));
-}
-
-void dt_device_init(struct dt_device *dev, const struct dt_bus *bus,
- const void *info)
-{
- memset(dev, 0, sizeof(struct dt_device));
- dev->bus = bus;
- dev->info = (void *)info;
-}
-
-int dt_device_find_compatible(const struct dt_device *dev,
- const char *compatible)
-{
- int node, ret;
-
- node = fdt_node_offset_by_compatible(fdt, -1, compatible);
- while (node >= 0) {
- ret = dev->bus->match(dev, node);
- if (ret < 0)
- return ret;
- else if (ret)
- break;
- node = fdt_node_offset_by_compatible(fdt, node, compatible);
- }
- return node;
-}
-
-int dt_pbus_get_base_compatible(const char *compatible,
- struct dt_pbus_reg *base)
-{
- struct dt_device dev;
- int node;
-
- dt_device_init(&dev, &dt_default_bus, NULL);
-
- node = dt_device_find_compatible(&dev, compatible);
- if (node < 0)
- return node;
-
- dt_device_bind_node(&dev, node);
-
- return dt_pbus_get_base(&dev, base);
-}
-
-int dt_get_memory_params(struct dt_pbus_reg *regs, int nr_regs)
-{
- const char *pn = "device_type", *pv = "memory";
- int node, ret, pl = strlen(pv) + 1, nr = 0;
- struct dt_pbus_reg reg;
-
- node = fdt_node_offset_by_prop_value(fdt, -1, pn, pv, pl);
-
- while (node >= 0) {
-
- while (nr < nr_regs) {
- ret = dt_pbus_translate_node(node, nr, &reg);
- if (ret == -FDT_ERR_NOTFOUND)
- break;
- if (ret < 0)
- return ret;
- regs[nr].addr = reg.addr;
- regs[nr].size = reg.size;
- ++nr;
- }
-
- node = fdt_node_offset_by_prop_value(fdt, node, pn, pv, pl);
- }
-
- return node != -FDT_ERR_NOTFOUND ? node : nr;
-}
-
-int dt_for_each_cpu_node(void (*func)(int fdtnode, u32 regval, void *info),
- void *info)
-{
- const struct fdt_property *prop;
- int cpus, cpu, ret, len;
- struct dt_reg raw_reg;
- u32 nac, nsc;
-
- cpus = fdt_path_offset(fdt, "/cpus");
- if (cpus < 0)
- return cpus;
-
- ret = dt_get_nr_cells(cpus, &nac, &nsc);
- if (ret < 0)
- return ret;
-
- dt_reg_init(&raw_reg, nac, nsc);
-
- dt_for_each_subnode(cpus, cpu) {
-
- prop = fdt_get_property(fdt, cpu, "device_type", &len);
- if (prop == NULL)
- return len;
-
- if (len != 4 || strcmp((char *)prop->data, "cpu"))
- continue;
-
- ret = dt_get_reg(cpu, 0, &raw_reg);
- if (ret < 0)
- return ret;
-
- func(cpu, raw_reg.address_cells[0], info);
- }
-
- return 0;
-}
-
-int dt_get_bootargs(const char **bootargs)
-{
- const struct fdt_property *prop;
- int node, len;
-
- *bootargs = NULL;
-
- node = fdt_path_offset(fdt, "/chosen");
- if (node < 0)
- return node;
-
- prop = fdt_get_property(fdt, node, "bootargs", &len);
- if (prop)
- *bootargs = (char *)prop->data;
- else if (len < 0 && len != -FDT_ERR_NOTFOUND)
- return len;
-
- return 0;
-}
-
-int dt_init(const void *fdt_ptr)
-{
- struct dt_bus *defbus = (struct dt_bus *)&dt_default_bus;
- int root, ret;
-
- ret = fdt_check_header(fdt_ptr);
- if (ret < 0)
- return ret;
- fdt = fdt_ptr;
-
- root = fdt_path_offset(fdt, "/");
- if (root < 0)
- return root;
-
- ret = dt_get_nr_cells(root, &root_nr_address_cells,
- &root_nr_size_cells);
- if (ret < 0)
- return ret;
-
- defbus->nr_address_cells = root_nr_address_cells;
- defbus->nr_size_cells = root_nr_size_cells;
-
- return 0;
-}
diff --git a/lib/libcflat/devicetree.h b/lib/libcflat/devicetree.h
deleted file mode 100644
index 7a1dc3e..0000000
--- a/lib/libcflat/devicetree.h
+++ /dev/null
@@ -1,236 +0,0 @@
-#ifndef _DEVICETREE_H_
-#define _DEVICETREE_H_
-/*
- * devicetree builds on libfdt to implement abstractions and accessors
- * for Linux required device tree content. The accessors provided are
- * common across architectures. See section III of the kernel doc
- * Documentation/devicetree/booting-without-of.txt
- *
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-#include "libfdt/libfdt.h"
-
-/**********************************************************************
- * devicetree init and libfdt helpers
- **********************************************************************/
-
-/* dt_init initializes devicetree with a pointer to an fdt, @fdt_ptr */
-extern int dt_init(const void *fdt_ptr);
-
-/* get the fdt pointer that devicetree is using */
-extern const void *dt_fdt(void);
-
-/* check for an initialized, valid devicetree */
-extern bool dt_available(void);
-
-/* traverse child nodes */
-#define dt_for_each_subnode(n, s) \
- for (s = fdt_first_subnode(dt_fdt(), n); \
- s != -FDT_ERR_NOTFOUND; \
- s = fdt_next_subnode(dt_fdt(), s))
-
-/**********************************************************************
- * Abstractions for required node types and properties
- **********************************************************************/
-
-struct dt_device {
- int fdtnode;
- const struct dt_bus *bus;
-
- /*
- * info is a pointer to device specific data, which may be
- * used by the bus match() and translate() functions
- */
- void *info;
-};
-
-struct dt_bus {
- /*
- * match a device @dev to an fdt node @fdtnode
- * returns
- * - a positive value on match
- * - zero on no match
- * - a negative FDT_ERR_* value on failure
- */
- int (*match)(const struct dt_device *dev, int fdtnode);
-
- /*
- * translate the @regidx'th "address size" tuple of
- * @dev's fdt node's "reg" property, and store the result
- * in @reg, a bus specific structure
- * returns
- * - zero on success
- * - a negative FDT_ERR_* value on failure
- */
- int (*translate)(const struct dt_device *dev, int regidx, void *reg);
-
- /* the bus #address-cells and #size-cells properties */
- u32 nr_address_cells, nr_size_cells;
-};
-
-/* dt_bus_match_any matches any fdt node, i.e. it always returns true */
-extern int dt_bus_match_any(const struct dt_device *dev, int fdtnode);
-
-/* the processor bus (pbus) address type and register tuple */
-typedef u64 dt_pbus_addr_t;
-struct dt_pbus_reg {
- dt_pbus_addr_t addr;
- dt_pbus_addr_t size;
-};
-
-static inline dt_pbus_addr_t dt_pbus_read_cells(u32 nr_cells, u32 *cells)
-{
- switch (nr_cells) {
- case 1: return cells[0];
- case 2: return ((u64)cells[0] << 32) | cells[1];
- }
- return (~0ULL);
-}
-
-/*
- * dt_pbus_translate translates device node regs for the
- * processor bus using the root node's #address-cells and
- * #size-cells and dt_pbus_read_cells()
- * returns
- * - zero on success
- * - a negative FDT_ERR_* value on failure
- */
-extern int dt_pbus_translate(const struct dt_device *dev, int regidx,
- void *reg);
-
-/*
- * dt_pbus_translate_node is the same as dt_pbus_translate but
- * operates on an fdt node instead of a dt_device
- */
-extern int dt_pbus_translate_node(int fdtnode, int regidx,
- struct dt_pbus_reg *reg);
-
-/*
- * dt_pbus_get_base is an alias for
- * dt_pbus_translate(dev, 0, base)
- * returns
- * - zero on success
- * - a negative FDT_ERR_* value on failure
- */
-static inline int dt_pbus_get_base(const struct dt_device *dev,
- struct dt_pbus_reg *base)
-{
- return dt_pbus_translate(dev, 0, base);
-}
-
-/*
- * dt_bus_init_defaults initializes @bus with
- * match <- dt_bus_match_any
- * translate <- dt_pbus_translate
- * nr_address_cells <- #address-cells of the root node
- * nr_size_cells <- #size-cells of the root node
- */
-extern void dt_bus_init_defaults(struct dt_bus *bus);
-
-/*
- * dt_device_init initializes a dt_device with the given parameters
- */
-extern void dt_device_init(struct dt_device *dev, const struct dt_bus *bus,
- const void *info);
-
-static inline void dt_device_bind_node(struct dt_device *dev, int fdtnode)
-{
- dev->fdtnode = fdtnode;
-}
-
-/*
- * dt_device_find_compatible finds a @compatible node
- * returns
- * - node (>= 0) on success
- * - a negative FDT_ERR_* value on failure
- */
-extern int dt_device_find_compatible(const struct dt_device *dev,
- const char *compatible);
-
-/*
- * dt_pbus_get_base_compatible simply bundles many functions into one.
- * It finds the first @compatible fdt node, then translates the 0th reg
- * tuple (the base) using the processor bus translation, and finally it
- * stores that result in @base.
- * returns
- * - zero on success
- * - a negative FDT_ERR_* value on failure
- */
-extern int dt_pbus_get_base_compatible(const char *compatible,
- struct dt_pbus_reg *base);
-
-/**********************************************************************
- * Low-level accessors for required node types and properties
- **********************************************************************/
-
-/*
- * dt_get_nr_cells sets @nr_address_cells and @nr_size_cells to the
- * #address-cells and #size-cells properties of @fdtnode
- * returns
- * - zero on success
- * - a negative FDT_ERR_* value on failure
- */
-extern int dt_get_nr_cells(int fdtnode, u32 *nr_address_cells,
- u32 *nr_size_cells);
-
-/* dt_reg is a structure for "raw" reg tuples */
-#define MAX_ADDRESS_CELLS 4
-#define MAX_SIZE_CELLS 4
-struct dt_reg {
- u32 nr_address_cells, nr_size_cells;
- u32 address_cells[MAX_ADDRESS_CELLS];
- u32 size_cells[MAX_SIZE_CELLS];
-};
-
-/*
- * dt_reg_init initialize a dt_reg struct to zero and sets
- * nr_address_cells and nr_size_cells to @nr_address_cells and
- * @nr_size_cells respectively.
- */
-extern void dt_reg_init(struct dt_reg *reg, u32 nr_address_cells,
- u32 nr_size_cells);
-
-/*
- * dt_get_reg gets the @regidx'th reg tuple of @fdtnode's reg property
- * and stores it in @reg. @reg must be initialized.
- * returns
- * - zero on success
- * - a negative FDT_ERR_* value on failure
- */
-extern int dt_get_reg(int fdtnode, int regidx, struct dt_reg *reg);
-
-/**********************************************************************
- * High-level accessors for required node types and properties
- **********************************************************************/
-
-/*
- * dt_get_bootargs gets a pointer to /chosen/bootargs
- * returns
- * - zero on success
- * - a negative FDT_ERR_* value on failure
- */
-extern int dt_get_bootargs(const char **bootargs);
-
-/*
- * dt_get_memory_params gets the memory parameters from the /memory node(s)
- * storing each memory region ("address size" tuple) in consecutive entries
- * of @regs, up to @nr_regs
- * returns
- * - number of memory regions found on success
- * - a negative FDT_ERR_* value on failure
- */
-extern int dt_get_memory_params(struct dt_pbus_reg *regs, int nr_regs);
-
-/*
- * dt_for_each_cpu_node runs @func on each cpu node in the /cpus node
- * passing it its fdt node, its reg property value, and @info
- * - zero on success
- * - a negative FDT_ERR_* value on failure
- */
-extern int dt_for_each_cpu_node(void (*func)(int fdtnode, u32 regval,
- void *info), void *info);
-
-#endif /* _DEVICETREE_H_ */
diff --git a/lib/libcflat/report.c b/lib/libcflat/report.c
deleted file mode 100644
index ff562a1..0000000
--- a/lib/libcflat/report.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Test result reporting
- *
- * Copyright (c) Siemens AG, 2014
- *
- * Authors:
- * Jan Kiszka <jan.kiszka@siemens.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-
-#include "libcflat.h"
-
-static unsigned int tests, failures;
-
-void report(const char *msg_fmt, bool pass, ...)
-{
- char buf[2000];
- va_list va;
-
- tests++;
- printf("%s: ", pass ? "PASS" : "FAIL");
- va_start(va, pass);
- vsnprintf(buf, sizeof(buf), msg_fmt, va);
- va_end(va);
- puts(buf);
- puts("\n");
- if (!pass)
- failures++;
-}
-
-int report_summary(void)
-{
- printf("\nSUMMARY: %d tests, %d failures\n", tests, failures);
- return failures > 0 ? 1 : 0;
-}
diff --git a/lib/libcflat/virtio-testdev.c b/lib/libcflat/virtio-testdev.c
deleted file mode 100644
index 422e0bf..0000000
--- a/lib/libcflat/virtio-testdev.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-#include "asm/spinlock.h"
-#include "virtio.h"
-
-#define TESTDEV_NAME "virtio-testdev"
-#define VIRTIO_ID_TESTDEV 0xffff
-#define TESTDEV_MAJOR_VER 1
-#define TESTDEV_MINOR_VER 1
-
-#define VIRTIO_CONFIG_SIZE 64
-
-enum {
- VERSION = 1,
- CLEAR,
- EXIT,
-};
-
-#define TOKEN_OFFSET 0x0
-#define NARGS_OFFSET 0x4
-#define NRETS_OFFSET 0x8
-#define ARG_OFFSET(n) (0xc + (n) * 4)
-#define __RET_OFFSET(nargs, n) (ARG_OFFSET(nargs) + (n) * 4)
-
-static struct spinlock lock;
-static struct virtio_device *vdev;
-
-static u32 testdev_readl(unsigned offset)
-{
- assert(offset <= (VIRTIO_CONFIG_SIZE - 4));
- return virtio_config_readl(vdev, offset);
-}
-
-static void testdev_writel(unsigned offset, u32 val)
-{
- assert(offset <= (VIRTIO_CONFIG_SIZE - 4));
- virtio_config_writel(vdev, offset, val);
-}
-
-/*
- * We have to write all args; nargs, nrets, ... first to avoid executing
- * the token's operation until all args are in place. Then issue the op,
- * and then read the return values. Reading the return values (or just
- * sanity checking by reading token) will read a zero into qemu's copy
- * of the token, which allows us to prepare additional ops without
- * re-executing the last one.
- */
-void virtio_testdev(u32 token, u32 nargs, u32 nrets, ...)
-{
- va_list va;
- unsigned off;
- u32 n;
-
- if (!vdev)
- return;
-
- spin_lock(&lock);
-
- testdev_writel(NARGS_OFFSET, nargs);
- testdev_writel(NRETS_OFFSET, nrets);
-
- va_start(va, nrets);
-
- off = ARG_OFFSET(0);
- n = nargs;
- while (n--) {
- testdev_writel(off, va_arg(va, unsigned));
- off += 4;
- }
-
- /* this runs the op, but then resets token to zero */
- testdev_writel(TOKEN_OFFSET, token);
- assert(testdev_readl(TOKEN_OFFSET) == 0);
-
- off = __RET_OFFSET(nargs, 0);
- n = nrets;
- while (n--) {
- u32 *r = va_arg(va, unsigned *);
- *r = testdev_readl(off);
- off += 4;
- }
-
- spin_unlock(&lock);
- va_end(va);
-}
-
-void virtio_testdev_version(u32 *version)
-{
- virtio_testdev(VERSION, 0, 1, version);
-}
-
-void virtio_testdev_clear(void)
-{
- virtio_testdev(CLEAR, 0, 0);
-}
-
-void virtio_testdev_exit(int code)
-{
- virtio_testdev(EXIT, 1, 0, code);
-}
-
-void virtio_testdev_init(void)
-{
- u16 major, minor;
- u32 version;
-
- vdev = virtio_bind(VIRTIO_ID_TESTDEV);
- if (vdev == NULL) {
- printf("%s: can't find " TESTDEV_NAME ". "
- "Is '-device " TESTDEV_NAME "' "
- "on the qemu command line?\n", __func__);
- abort();
- }
-
- virtio_testdev_version(&version);
- major = version >> 16;
- minor = version & 0xffff;
-
- if (major != TESTDEV_MAJOR_VER || minor < TESTDEV_MINOR_VER) {
- char *u = "qemu";
- if (major > TESTDEV_MAJOR_VER)
- u = "kvm-unit-tests";
- printf("%s: incompatible version of " TESTDEV_NAME ": "
- "major = %d, minor = %d. Update %s\n",
- __func__, major, minor, u);
- abort();
- }
-
- if (minor > TESTDEV_MINOR_VER)
- printf("%s: " TESTDEV_NAME " has new features. "
- "An update of kvm-unit-tests may be possible.\n",
- __func__);
-}
diff --git a/lib/libcflat/virtio-testdev.h b/lib/libcflat/virtio-testdev.h
deleted file mode 100644
index bed9eaf..0000000
--- a/lib/libcflat/virtio-testdev.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _VIRTIO_TESTDEV_H_
-#define _VIRTIO_TESTDEV_H_
-/*
- * virtio-testdev is a driver for the virtio-testdev qemu device.
- * The virtio-testdev device exposes a simple control interface to
- * qemu for kvm-unit-tests through virtio.
- *
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-
-extern void virtio_testdev_init(void);
-extern void virtio_testdev_version(u32 *version);
-extern void virtio_testdev_clear(void);
-extern void virtio_testdev_exit(int code);
-#endif
diff --git a/lib/libcflat/virtio.c b/lib/libcflat/virtio.c
deleted file mode 100644
index 4c597e2..0000000
--- a/lib/libcflat/virtio.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-#include "devicetree.h"
-#include "asm/spinlock.h"
-#include "asm/io.h"
-#include "virtio.h"
-
-enum virtio_hwdesc_type {
- VIRTIO_HWDESC_TYPE_DT = 0, /* device tree */
- NR_VIRTIO_HWDESC_TYPES,
-};
-
-enum virtio_bus_type {
- VIRTIO_BUS_TYPE_MMIO = 0, /* virtio-mmio */
- NR_VIRTIO_BUS_TYPES,
-};
-
-struct virtio_bind_bus {
- bool (*hwdesc_probe)(void);
- struct virtio_device *(*device_bind)(u32 devid);
-};
-
-static struct virtio_device *vm_dt_device_bind(u32 devid);
-
-static struct virtio_bind_bus
-virtio_bind_busses[NR_VIRTIO_HWDESC_TYPES][NR_VIRTIO_BUS_TYPES] = {
-
-[VIRTIO_HWDESC_TYPE_DT] = {
-
- [VIRTIO_BUS_TYPE_MMIO] = {
- .hwdesc_probe = dt_available,
- .device_bind = vm_dt_device_bind,
- },
-},
-};
-
-struct virtio_device *virtio_bind(u32 devid)
-{
- struct virtio_bind_bus *bus;
- struct virtio_device *dev;
- int i, j;
-
- for (i = 0; i < NR_VIRTIO_HWDESC_TYPES; ++i) {
- for (j = 0; j < NR_VIRTIO_BUS_TYPES; ++j) {
-
- bus = &virtio_bind_busses[i][j];
-
- if (!bus->hwdesc_probe())
- continue;
-
- dev = bus->device_bind(devid);
- if (dev)
- return dev;
- }
- }
-
- return NULL;
-}
-
-/******************************************************
- * virtio-mmio support (config space only)
- ******************************************************/
-
-static void vm_get(struct virtio_device *vdev, unsigned offset,
- void *buf, unsigned len)
-{
- struct virtio_mmio_device *vmdev = to_virtio_mmio_device(vdev);
- u8 *p = buf;
- unsigned i;
-
- for (i = 0; i < len; ++i)
- p[i] = readb(vmdev->base + VIRTIO_MMIO_CONFIG + offset + i);
-}
-
-static void vm_set(struct virtio_device *vdev, unsigned offset,
- const void *buf, unsigned len)
-{
- struct virtio_mmio_device *vmdev = to_virtio_mmio_device(vdev);
- const u8 *p = buf;
- unsigned i;
-
- for (i = 0; i < len; ++i)
- writeb(p[i], vmdev->base + VIRTIO_MMIO_CONFIG + offset + i);
-}
-
-static const struct virtio_config_ops vm_config_ops = {
- .get = vm_get,
- .set = vm_set,
-};
-
-#define NR_VM_DEVICES 32
-static struct spinlock vm_lock;
-static struct virtio_mmio_device vm_devs[NR_VM_DEVICES];
-static int nr_vm_devs;
-
-static struct virtio_mmio_device *vm_new_device(u32 devid)
-{
- struct virtio_mmio_device *vmdev;
-
- if (nr_vm_devs >= NR_VM_DEVICES)
- return NULL;
-
- spin_lock(&vm_lock);
- vmdev = &vm_devs[nr_vm_devs++];
- spin_unlock(&vm_lock);
-
- vmdev->vdev.id.device = devid;
- vmdev->vdev.id.vendor = -1;
- vmdev->vdev.config = &vm_config_ops;
-
- return vmdev;
-}
-
-/******************************************************
- * virtio-mmio device tree support
- ******************************************************/
-
-struct vm_dt_info {
- u32 devid;
- void *base;
-};
-
-static int vm_dt_match(const struct dt_device *dev, int fdtnode)
-{
- struct vm_dt_info *info = (struct vm_dt_info *)dev->info;
- struct dt_pbus_reg base;
-
- dt_device_bind_node((struct dt_device *)dev, fdtnode);
-
- assert(dt_pbus_get_base(dev, &base) == 0);
- info->base = ioremap(base.addr, base.size);
-
- return readl(info->base + VIRTIO_MMIO_DEVICE_ID) == info->devid;
-}
-
-static struct virtio_device *vm_dt_device_bind(u32 devid)
-{
- struct virtio_mmio_device *vmdev;
- struct dt_device dt_dev;
- struct dt_bus dt_bus;
- struct vm_dt_info info;
- int node;
-
- dt_bus_init_defaults(&dt_bus);
- dt_bus.match = vm_dt_match;
-
- info.devid = devid;
-
- dt_device_init(&dt_dev, &dt_bus, &info);
-
- node = dt_device_find_compatible(&dt_dev, "virtio,mmio");
- assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
-
- if (node == -FDT_ERR_NOTFOUND)
- return NULL;
-
- vmdev = vm_new_device(devid);
- vmdev->base = info.base;
-
- return &vmdev->vdev;
-}
diff --git a/lib/libcflat/virtio.h b/lib/libcflat/virtio.h
deleted file mode 100644
index 16ebe7e..0000000
--- a/lib/libcflat/virtio.h
+++ /dev/null
@@ -1,89 +0,0 @@
-#ifndef _VIRTIO_H_
-#define _VIRTIO_H_
-/*
- * A minimal implementation of virtio for virtio-mmio config space
- * access.
- *
- * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.
- */
-#include "libcflat.h"
-
-struct virtio_device_id {
- u32 device;
- u32 vendor;
-};
-
-struct virtio_device {
- struct virtio_device_id id;
- const struct virtio_config_ops *config;
-};
-
-struct virtio_config_ops {
- void (*get)(struct virtio_device *vdev, unsigned offset,
- void *buf, unsigned len);
- void (*set)(struct virtio_device *vdev, unsigned offset,
- const void *buf, unsigned len);
-};
-
-extern struct virtio_device *virtio_bind(u32 devid);
-
-static inline u8
-virtio_config_readb(struct virtio_device *vdev, unsigned offset)
-{
- u8 val;
- vdev->config->get(vdev, offset, &val, 1);
- return val;
-}
-
-static inline u16
-virtio_config_readw(struct virtio_device *vdev, unsigned offset)
-{
- u16 val;
- vdev->config->get(vdev, offset, &val, 2);
- return val;
-}
-
-static inline u32
-virtio_config_readl(struct virtio_device *vdev, unsigned offset)
-{
- u32 val;
- vdev->config->get(vdev, offset, &val, 4);
- return val;
-}
-
-static inline void
-virtio_config_writeb(struct virtio_device *vdev, unsigned offset, u8 val)
-{
- vdev->config->set(vdev, offset, &val, 1);
-}
-
-static inline void
-virtio_config_writew(struct virtio_device *vdev, unsigned offset, u16 val)
-{
- vdev->config->set(vdev, offset, &val, 2);
-}
-
-static inline void
-virtio_config_writel(struct virtio_device *vdev, unsigned offset, u32 val)
-{
- vdev->config->set(vdev, offset, &val, 4);
-}
-
-/******************************************************
- * virtio-mmio
- ******************************************************/
-
-#define VIRTIO_MMIO_DEVICE_ID 0x008
-#define VIRTIO_MMIO_CONFIG 0x100
-
-#define to_virtio_mmio_device(vdev_ptr) \
- container_of(vdev_ptr, struct virtio_mmio_device, vdev)
-
-struct virtio_mmio_device {
- struct virtio_device vdev;
- void *base;
-};
-
-#endif /* _VIRTIO_H_ */
diff --git a/lib/libfdt/Makefile.libfdt b/lib/libfdt/Makefile.libfdt
deleted file mode 100644
index 91126c0..0000000
--- a/lib/libfdt/Makefile.libfdt
+++ /dev/null
@@ -1,10 +0,0 @@
-# Makefile.libfdt
-#
-# This is not a complete Makefile of itself. Instead, it is designed to
-# be easily embeddable into other systems of Makefiles.
-#
-LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
-LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
-LIBFDT_VERSION = version.lds
-LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c
-LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
diff --git a/lib/libfdt/README b/lib/libfdt/README
deleted file mode 100644
index 24ad4fe..0000000
--- a/lib/libfdt/README
+++ /dev/null
@@ -1,4 +0,0 @@
-
-The code in this directory is originally imported from the libfdt
-directory of git://git.jdl.com/software/dtc.git - version 1.4.0.
-
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
deleted file mode 100644
index 2ce6a44..0000000
--- a/lib/libfdt/fdt.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_check_header(const void *fdt)
-{
- if (fdt_magic(fdt) == FDT_MAGIC) {
- /* Complete tree */
- if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
- /* Unfinished sequential-write blob */
- if (fdt_size_dt_struct(fdt) == 0)
- return -FDT_ERR_BADSTATE;
- } else {
- return -FDT_ERR_BADMAGIC;
- }
-
- return 0;
-}
-
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
-{
- const char *p;
-
- if (fdt_version(fdt) >= 0x11)
- if (((offset + len) < offset)
- || ((offset + len) > fdt_size_dt_struct(fdt)))
- return NULL;
-
- p = _fdt_offset_ptr(fdt, offset);
-
- if (p + len < p)
- return NULL;
- return p;
-}
-
-uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
-{
- const fdt32_t *tagp, *lenp;
- uint32_t tag;
- int offset = startoffset;
- const char *p;
-
- *nextoffset = -FDT_ERR_TRUNCATED;
- tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
- if (!tagp)
- return FDT_END; /* premature end */
- tag = fdt32_to_cpu(*tagp);
- offset += FDT_TAGSIZE;
-
- *nextoffset = -FDT_ERR_BADSTRUCTURE;
- switch (tag) {
- case FDT_BEGIN_NODE:
- /* skip name */
- do {
- p = fdt_offset_ptr(fdt, offset++, 1);
- } while (p && (*p != '\0'));
- if (!p)
- return FDT_END; /* premature end */
- break;
-
- case FDT_PROP:
- lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
- if (!lenp)
- return FDT_END; /* premature end */
- /* skip-name offset, length and value */
- offset += sizeof(struct fdt_property) - FDT_TAGSIZE
- + fdt32_to_cpu(*lenp);
- break;
-
- case FDT_END:
- case FDT_END_NODE:
- case FDT_NOP:
- break;
-
- default:
- return FDT_END;
- }
-
- if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
- return FDT_END; /* premature end */
-
- *nextoffset = FDT_TAGALIGN(offset);
- return tag;
-}
-
-int _fdt_check_node_offset(const void *fdt, int offset)
-{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
- return -FDT_ERR_BADOFFSET;
-
- return offset;
-}
-
-int _fdt_check_prop_offset(const void *fdt, int offset)
-{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
- return -FDT_ERR_BADOFFSET;
-
- return offset;
-}
-
-int fdt_next_node(const void *fdt, int offset, int *depth)
-{
- int nextoffset = 0;
- uint32_t tag;
-
- if (offset >= 0)
- if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
- return nextoffset;
-
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_PROP:
- case FDT_NOP:
- break;
-
- case FDT_BEGIN_NODE:
- if (depth)
- (*depth)++;
- break;
-
- case FDT_END_NODE:
- if (depth && ((--(*depth)) < 0))
- return nextoffset;
- break;
-
- case FDT_END:
- if ((nextoffset >= 0)
- || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
- return -FDT_ERR_NOTFOUND;
- else
- return nextoffset;
- }
- } while (tag != FDT_BEGIN_NODE);
-
- return offset;
-}
-
-int fdt_first_subnode(const void *fdt, int offset)
-{
- int depth = 0;
-
- offset = fdt_next_node(fdt, offset, &depth);
- if (offset < 0 || depth != 1)
- return -FDT_ERR_NOTFOUND;
-
- return offset;
-}
-
-int fdt_next_subnode(const void *fdt, int offset)
-{
- int depth = 1;
-
- /*
- * With respect to the parent, the depth of the next subnode will be
- * the same as the last.
- */
- do {
- offset = fdt_next_node(fdt, offset, &depth);
- if (offset < 0 || depth < 1)
- return -FDT_ERR_NOTFOUND;
- } while (depth > 1);
-
- return offset;
-}
-
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
-{
- int len = strlen(s) + 1;
- const char *last = strtab + tabsize - len;
- const char *p;
-
- for (p = strtab; p <= last; p++)
- if (memcmp(p, s, len) == 0)
- return p;
- return NULL;
-}
-
-int fdt_move(const void *fdt, void *buf, int bufsize)
-{
- FDT_CHECK_HEADER(fdt);
-
- if (fdt_totalsize(fdt) > bufsize)
- return -FDT_ERR_NOSPACE;
-
- memmove(buf, fdt, fdt_totalsize(fdt));
- return 0;
-}
diff --git a/lib/libfdt/fdt.h b/lib/libfdt/fdt.h
deleted file mode 100644
index 526aedb..0000000
--- a/lib/libfdt/fdt.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef _FDT_H
-#define _FDT_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * Copyright 2012 Kim Phillips, Freescale Semiconductor.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __ASSEMBLY__
-
-struct fdt_header {
- fdt32_t magic; /* magic word FDT_MAGIC */
- fdt32_t totalsize; /* total size of DT block */
- fdt32_t off_dt_struct; /* offset to structure */
- fdt32_t off_dt_strings; /* offset to strings */
- fdt32_t off_mem_rsvmap; /* offset to memory reserve map */
- fdt32_t version; /* format version */
- fdt32_t last_comp_version; /* last compatible version */
-
- /* version 2 fields below */
- fdt32_t boot_cpuid_phys; /* Which physical CPU id we're
- booting on */
- /* version 3 fields below */
- fdt32_t size_dt_strings; /* size of the strings block */
-
- /* version 17 fields below */
- fdt32_t size_dt_struct; /* size of the structure block */
-};
-
-struct fdt_reserve_entry {
- fdt64_t address;
- fdt64_t size;
-};
-
-struct fdt_node_header {
- fdt32_t tag;
- char name[0];
-};
-
-struct fdt_property {
- fdt32_t tag;
- fdt32_t len;
- fdt32_t nameoff;
- char data[0];
-};
-
-#endif /* !__ASSEMBLY */
-
-#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
-#define FDT_TAGSIZE sizeof(fdt32_t)
-
-#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
-#define FDT_END_NODE 0x2 /* End node */
-#define FDT_PROP 0x3 /* Property: name off,
- size, content */
-#define FDT_NOP 0x4 /* nop */
-#define FDT_END 0x9
-
-#define FDT_V1_SIZE (7*sizeof(fdt32_t))
-#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t))
-#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t))
-#define FDT_V16_SIZE FDT_V3_SIZE
-#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t))
-
-#endif /* _FDT_H */
diff --git a/lib/libfdt/fdt_empty_tree.c b/lib/libfdt/fdt_empty_tree.c
deleted file mode 100644
index f72d13b..0000000
--- a/lib/libfdt/fdt_empty_tree.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2012 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_create_empty_tree(void *buf, int bufsize)
-{
- int err;
-
- err = fdt_create(buf, bufsize);
- if (err)
- return err;
-
- err = fdt_finish_reservemap(buf);
- if (err)
- return err;
-
- err = fdt_begin_node(buf, "");
- if (err)
- return err;
-
- err = fdt_end_node(buf);
- if (err)
- return err;
-
- err = fdt_finish(buf);
- if (err)
- return err;
-
- return fdt_open_into(buf, buf, bufsize);
-}
-
diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c
deleted file mode 100644
index 50007f6..0000000
--- a/lib/libfdt/fdt_ro.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_nodename_eq(const void *fdt, int offset,
- const char *s, int len)
-{
- const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
-
- if (! p)
- /* short match */
- return 0;
-
- if (memcmp(p, s, len) != 0)
- return 0;
-
- if (p[len] == '\0')
- return 1;
- else if (!memchr(s, '@', len) && (p[len] == '@'))
- return 1;
- else
- return 0;
-}
-
-const char *fdt_string(const void *fdt, int stroffset)
-{
- return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
-}
-
-static int _fdt_string_eq(const void *fdt, int stroffset,
- const char *s, int len)
-{
- const char *p = fdt_string(fdt, stroffset);
-
- return (strlen(p) == len) && (memcmp(p, s, len) == 0);
-}
-
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
-{
- FDT_CHECK_HEADER(fdt);
- *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
- *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
- return 0;
-}
-
-int fdt_num_mem_rsv(const void *fdt)
-{
- int i = 0;
-
- while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
- i++;
- return i;
-}
-
-static int _nextprop(const void *fdt, int offset)
-{
- uint32_t tag;
- int nextoffset;
-
- do {
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_END:
- if (nextoffset >= 0)
- return -FDT_ERR_BADSTRUCTURE;
- else
- return nextoffset;
-
- case FDT_PROP:
- return offset;
- }
- offset = nextoffset;
- } while (tag == FDT_NOP);
-
- return -FDT_ERR_NOTFOUND;
-}
-
-int fdt_subnode_offset_namelen(const void *fdt, int offset,
- const char *name, int namelen)
-{
- int depth;
-
- FDT_CHECK_HEADER(fdt);
-
- for (depth = 0;
- (offset >= 0) && (depth >= 0);
- offset = fdt_next_node(fdt, offset, &depth))
- if ((depth == 1)
- && _fdt_nodename_eq(fdt, offset, name, namelen))
- return offset;
-
- if (depth < 0)
- return -FDT_ERR_NOTFOUND;
- return offset; /* error */
-}
-
-int fdt_subnode_offset(const void *fdt, int parentoffset,
- const char *name)
-{
- return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
-}
-
-int fdt_path_offset(const void *fdt, const char *path)
-{
- const char *end = path + strlen(path);
- const char *p = path;
- int offset = 0;
-
- FDT_CHECK_HEADER(fdt);
-
- /* see if we have an alias */
- if (*path != '/') {
- const char *q = strchr(path, '/');
-
- if (!q)
- q = end;
-
- p = fdt_get_alias_namelen(fdt, p, q - p);
- if (!p)
- return -FDT_ERR_BADPATH;
- offset = fdt_path_offset(fdt, p);
-
- p = q;
- }
-
- while (*p) {
- const char *q;
-
- while (*p == '/')
- p++;
- if (! *p)
- return offset;
- q = strchr(p, '/');
- if (! q)
- q = end;
-
- offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
- if (offset < 0)
- return offset;
-
- p = q;
- }
-
- return offset;
-}
-
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
-{
- const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
- int err;
-
- if (((err = fdt_check_header(fdt)) != 0)
- || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
- goto fail;
-
- if (len)
- *len = strlen(nh->name);
-
- return nh->name;
-
- fail:
- if (len)
- *len = err;
- return NULL;
-}
-
-int fdt_first_property_offset(const void *fdt, int nodeoffset)
-{
- int offset;
-
- if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
- return offset;
-
- return _nextprop(fdt, offset);
-}
-
-int fdt_next_property_offset(const void *fdt, int offset)
-{
- if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
- return offset;
-
- return _nextprop(fdt, offset);
-}
-
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
- int offset,
- int *lenp)
-{
- int err;
- const struct fdt_property *prop;
-
- if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
- if (lenp)
- *lenp = err;
- return NULL;
- }
-
- prop = _fdt_offset_ptr(fdt, offset);
-
- if (lenp)
- *lenp = fdt32_to_cpu(prop->len);
-
- return prop;
-}
-
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
- int offset,
- const char *name,
- int namelen, int *lenp)
-{
- for (offset = fdt_first_property_offset(fdt, offset);
- (offset >= 0);
- (offset = fdt_next_property_offset(fdt, offset))) {
- const struct fdt_property *prop;
-
- if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
- offset = -FDT_ERR_INTERNAL;
- break;
- }
- if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
- name, namelen))
- return prop;
- }
-
- if (lenp)
- *lenp = offset;
- return NULL;
-}
-
-const struct fdt_property *fdt_get_property(const void *fdt,
- int nodeoffset,
- const char *name, int *lenp)
-{
- return fdt_get_property_namelen(fdt, nodeoffset, name,
- strlen(name), lenp);
-}
-
-const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
- const char *name, int namelen, int *lenp)
-{
- const struct fdt_property *prop;
-
- prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
- if (! prop)
- return NULL;
-
- return prop->data;
-}
-
-const void *fdt_getprop_by_offset(const void *fdt, int offset,
- const char **namep, int *lenp)
-{
- const struct fdt_property *prop;
-
- prop = fdt_get_property_by_offset(fdt, offset, lenp);
- if (!prop)
- return NULL;
- if (namep)
- *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
- return prop->data;
-}
-
-const void *fdt_getprop(const void *fdt, int nodeoffset,
- const char *name, int *lenp)
-{
- return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
-}
-
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
-{
- const fdt32_t *php;
- int len;
-
- /* FIXME: This is a bit sub-optimal, since we potentially scan
- * over all the properties twice. */
- php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
- if (!php || (len != sizeof(*php))) {
- php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
- if (!php || (len != sizeof(*php)))
- return 0;
- }
-
- return fdt32_to_cpu(*php);
-}
-
-const char *fdt_get_alias_namelen(const void *fdt,
- const char *name, int namelen)
-{
- int aliasoffset;
-
- aliasoffset = fdt_path_offset(fdt, "/aliases");
- if (aliasoffset < 0)
- return NULL;
-
- return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
-}
-
-const char *fdt_get_alias(const void *fdt, const char *name)
-{
- return fdt_get_alias_namelen(fdt, name, strlen(name));
-}
-
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
-{
- int pdepth = 0, p = 0;
- int offset, depth, namelen;
- const char *name;
-
- FDT_CHECK_HEADER(fdt);
-
- if (buflen < 2)
- return -FDT_ERR_NOSPACE;
-
- for (offset = 0, depth = 0;
- (offset >= 0) && (offset <= nodeoffset);
- offset = fdt_next_node(fdt, offset, &depth)) {
- while (pdepth > depth) {
- do {
- p--;
- } while (buf[p-1] != '/');
- pdepth--;
- }
-
- if (pdepth >= depth) {
- name = fdt_get_name(fdt, offset, &namelen);
- if (!name)
- return namelen;
- if ((p + namelen + 1) <= buflen) {
- memcpy(buf + p, name, namelen);
- p += namelen;
- buf[p++] = '/';
- pdepth++;
- }
- }
-
- if (offset == nodeoffset) {
- if (pdepth < (depth + 1))
- return -FDT_ERR_NOSPACE;
-
- if (p > 1) /* special case so that root path is "/", not "" */
- p--;
- buf[p] = '\0';
- return 0;
- }
- }
-
- if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
- return -FDT_ERR_BADOFFSET;
- else if (offset == -FDT_ERR_BADOFFSET)
- return -FDT_ERR_BADSTRUCTURE;
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
- int supernodedepth, int *nodedepth)
-{
- int offset, depth;
- int supernodeoffset = -FDT_ERR_INTERNAL;
-
- FDT_CHECK_HEADER(fdt);
-
- if (supernodedepth < 0)
- return -FDT_ERR_NOTFOUND;
-
- for (offset = 0, depth = 0;
- (offset >= 0) && (offset <= nodeoffset);
- offset = fdt_next_node(fdt, offset, &depth)) {
- if (depth == supernodedepth)
- supernodeoffset = offset;
-
- if (offset == nodeoffset) {
- if (nodedepth)
- *nodedepth = depth;
-
- if (supernodedepth > depth)
- return -FDT_ERR_NOTFOUND;
- else
- return supernodeoffset;
- }
- }
-
- if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
- return -FDT_ERR_BADOFFSET;
- else if (offset == -FDT_ERR_BADOFFSET)
- return -FDT_ERR_BADSTRUCTURE;
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_node_depth(const void *fdt, int nodeoffset)
-{
- int nodedepth;
- int err;
-
- err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
- if (err)
- return (err < 0) ? err : -FDT_ERR_INTERNAL;
- return nodedepth;
-}
-
-int fdt_parent_offset(const void *fdt, int nodeoffset)
-{
- int nodedepth = fdt_node_depth(fdt, nodeoffset);
-
- if (nodedepth < 0)
- return nodedepth;
- return fdt_supernode_atdepth_offset(fdt, nodeoffset,
- nodedepth - 1, NULL);
-}
-
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
- const char *propname,
- const void *propval, int proplen)
-{
- int offset;
- const void *val;
- int len;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we scan each
- * property of a node in fdt_getprop(), then if that didn't
- * find what we want, we scan over them again making our way
- * to the next node. Still it's the easiest to implement
- * approach; performance can come later. */
- for (offset = fdt_next_node(fdt, startoffset, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- val = fdt_getprop(fdt, offset, propname, &len);
- if (val && (len == proplen)
- && (memcmp(val, propval, len) == 0))
- return offset;
- }
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
-{
- int offset;
-
- if ((phandle == 0) || (phandle == -1))
- return -FDT_ERR_BADPHANDLE;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we
- * potentially scan each property of a node in
- * fdt_get_phandle(), then if that didn't find what
- * we want, we scan over them again making our way to the next
- * node. Still it's the easiest to implement approach;
- * performance can come later. */
- for (offset = fdt_next_node(fdt, -1, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- if (fdt_get_phandle(fdt, offset) == phandle)
- return offset;
- }
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
-{
- int len = strlen(str);
- const char *p;
-
- while (listlen >= len) {
- if (memcmp(str, strlist, len+1) == 0)
- return 1;
- p = memchr(strlist, '\0', listlen);
- if (!p)
- return 0; /* malformed strlist.. */
- listlen -= (p-strlist) + 1;
- strlist = p + 1;
- }
- return 0;
-}
-
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
- const char *compatible)
-{
- const void *prop;
- int len;
-
- prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
- if (!prop)
- return len;
- if (fdt_stringlist_contains(prop, len, compatible))
- return 0;
- else
- return 1;
-}
-
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
- const char *compatible)
-{
- int offset, err;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we scan each
- * property of a node in fdt_node_check_compatible(), then if
- * that didn't find what we want, we scan over them again
- * making our way to the next node. Still it's the easiest to
- * implement approach; performance can come later. */
- for (offset = fdt_next_node(fdt, startoffset, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- err = fdt_node_check_compatible(fdt, offset, compatible);
- if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
- return err;
- else if (err == 0)
- return offset;
- }
-
- return offset; /* error from fdt_next_node() */
-}
diff --git a/lib/libfdt/fdt_rw.c b/lib/libfdt/fdt_rw.c
deleted file mode 100644
index fdba618..0000000
--- a/lib/libfdt/fdt_rw.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_blocks_misordered(const void *fdt,
- int mem_rsv_size, int struct_size)
-{
- return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
- || (fdt_off_dt_struct(fdt) <
- (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
- || (fdt_off_dt_strings(fdt) <
- (fdt_off_dt_struct(fdt) + struct_size))
- || (fdt_totalsize(fdt) <
- (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
-}
-
-static int _fdt_rw_check_header(void *fdt)
-{
- FDT_CHECK_HEADER(fdt);
-
- if (fdt_version(fdt) < 17)
- return -FDT_ERR_BADVERSION;
- if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
- fdt_size_dt_struct(fdt)))
- return -FDT_ERR_BADLAYOUT;
- if (fdt_version(fdt) > 17)
- fdt_set_version(fdt, 17);
-
- return 0;
-}
-
-#define FDT_RW_CHECK_HEADER(fdt) \
- { \
- int err; \
- if ((err = _fdt_rw_check_header(fdt)) != 0) \
- return err; \
- }
-
-static inline int _fdt_data_size(void *fdt)
-{
- return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
-}
-
-static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
-{
- char *p = splicepoint;
- char *end = (char *)fdt + _fdt_data_size(fdt);
-
- if (((p + oldlen) < p) || ((p + oldlen) > end))
- return -FDT_ERR_BADOFFSET;
- if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
- return -FDT_ERR_NOSPACE;
- memmove(p + newlen, p + oldlen, end - p - oldlen);
- return 0;
-}
-
-static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
- int oldn, int newn)
-{
- int delta = (newn - oldn) * sizeof(*p);
- int err;
- err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
- if (err)
- return err;
- fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
- fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
- return 0;
-}
-
-static int _fdt_splice_struct(void *fdt, void *p,
- int oldlen, int newlen)
-{
- int delta = newlen - oldlen;
- int err;
-
- if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
- return err;
-
- fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
- fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
- return 0;
-}
-
-static int _fdt_splice_string(void *fdt, int newlen)
-{
- void *p = (char *)fdt
- + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
- int err;
-
- if ((err = _fdt_splice(fdt, p, 0, newlen)))
- return err;
-
- fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
- return 0;
-}
-
-static int _fdt_find_add_string(void *fdt, const char *s)
-{
- char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
- const char *p;
- char *new;
- int len = strlen(s) + 1;
- int err;
-
- p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
- if (p)
- /* found it */
- return (p - strtab);
-
- new = strtab + fdt_size_dt_strings(fdt);
- err = _fdt_splice_string(fdt, len);
- if (err)
- return err;
-
- memcpy(new, s, len);
- return (new - strtab);
-}
-
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
-{
- struct fdt_reserve_entry *re;
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
- err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
- if (err)
- return err;
-
- re->address = cpu_to_fdt64(address);
- re->size = cpu_to_fdt64(size);
- return 0;
-}
-
-int fdt_del_mem_rsv(void *fdt, int n)
-{
- struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- if (n >= fdt_num_mem_rsv(fdt))
- return -FDT_ERR_NOTFOUND;
-
- err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
- if (err)
- return err;
- return 0;
-}
-
-static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
-{
- int oldlen;
- int err;
-
- *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (! (*prop))
- return oldlen;
-
- if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
- FDT_TAGALIGN(len))))
- return err;
-
- (*prop)->len = cpu_to_fdt32(len);
- return 0;
-}
-
-static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
-{
- int proplen;
- int nextoffset;
- int namestroff;
- int err;
-
- if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
- return nextoffset;
-
- namestroff = _fdt_find_add_string(fdt, name);
- if (namestroff < 0)
- return namestroff;
-
- *prop = _fdt_offset_ptr_w(fdt, nextoffset);
- proplen = sizeof(**prop) + FDT_TAGALIGN(len);
-
- err = _fdt_splice_struct(fdt, *prop, 0, proplen);
- if (err)
- return err;
-
- (*prop)->tag = cpu_to_fdt32(FDT_PROP);
- (*prop)->nameoff = cpu_to_fdt32(namestroff);
- (*prop)->len = cpu_to_fdt32(len);
- return 0;
-}
-
-int fdt_set_name(void *fdt, int nodeoffset, const char *name)
-{
- char *namep;
- int oldlen, newlen;
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
- if (!namep)
- return oldlen;
-
- newlen = strlen(name);
-
- err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
- FDT_TAGALIGN(newlen+1));
- if (err)
- return err;
-
- memcpy(namep, name, newlen+1);
- return 0;
-}
-
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
-{
- struct fdt_property *prop;
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
- if (err == -FDT_ERR_NOTFOUND)
- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
- if (err)
- return err;
-
- memcpy(prop->data, val, len);
- return 0;
-}
-
-int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
-{
- struct fdt_property *prop;
- int err, oldlen, newlen;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (prop) {
- newlen = len + oldlen;
- err = _fdt_splice_struct(fdt, prop->data,
- FDT_TAGALIGN(oldlen),
- FDT_TAGALIGN(newlen));
- if (err)
- return err;
- prop->len = cpu_to_fdt32(newlen);
- memcpy(prop->data + oldlen, val, len);
- } else {
- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
- if (err)
- return err;
- memcpy(prop->data, val, len);
- }
- return 0;
-}
-
-int fdt_delprop(void *fdt, int nodeoffset, const char *name)
-{
- struct fdt_property *prop;
- int len, proplen;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
- return len;
-
- proplen = sizeof(*prop) + FDT_TAGALIGN(len);
- return _fdt_splice_struct(fdt, prop, proplen, 0);
-}
-
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
- const char *name, int namelen)
-{
- struct fdt_node_header *nh;
- int offset, nextoffset;
- int nodelen;
- int err;
- uint32_t tag;
- fdt32_t *endtag;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
- if (offset >= 0)
- return -FDT_ERR_EXISTS;
- else if (offset != -FDT_ERR_NOTFOUND)
- return offset;
-
- /* Try to place the new node after the parent's properties */
- fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
- } while ((tag == FDT_PROP) || (tag == FDT_NOP));
-
- nh = _fdt_offset_ptr_w(fdt, offset);
- nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
-
- err = _fdt_splice_struct(fdt, nh, 0, nodelen);
- if (err)
- return err;
-
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
- memcpy(nh->name, name, namelen);
- endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
- *endtag = cpu_to_fdt32(FDT_END_NODE);
-
- return offset;
-}
-
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
-{
- return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
-}
-
-int fdt_del_node(void *fdt, int nodeoffset)
-{
- int endoffset;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
-
- return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
- endoffset - nodeoffset, 0);
-}
-
-static void _fdt_packblocks(const char *old, char *new,
- int mem_rsv_size, int struct_size)
-{
- int mem_rsv_off, struct_off, strings_off;
-
- mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
- struct_off = mem_rsv_off + mem_rsv_size;
- strings_off = struct_off + struct_size;
-
- memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
- fdt_set_off_mem_rsvmap(new, mem_rsv_off);
-
- memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
- fdt_set_off_dt_struct(new, struct_off);
- fdt_set_size_dt_struct(new, struct_size);
-
- memmove(new + strings_off, old + fdt_off_dt_strings(old),
- fdt_size_dt_strings(old));
- fdt_set_off_dt_strings(new, strings_off);
- fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
-}
-
-int fdt_open_into(const void *fdt, void *buf, int bufsize)
-{
- int err;
- int mem_rsv_size, struct_size;
- int newsize;
- const char *fdtstart = fdt;
- const char *fdtend = fdtstart + fdt_totalsize(fdt);
- char *tmp;
-
- FDT_CHECK_HEADER(fdt);
-
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
-
- if (fdt_version(fdt) >= 17) {
- struct_size = fdt_size_dt_struct(fdt);
- } else {
- struct_size = 0;
- while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
- ;
- if (struct_size < 0)
- return struct_size;
- }
-
- if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
- /* no further work necessary */
- err = fdt_move(fdt, buf, bufsize);
- if (err)
- return err;
- fdt_set_version(buf, 17);
- fdt_set_size_dt_struct(buf, struct_size);
- fdt_set_totalsize(buf, bufsize);
- return 0;
- }
-
- /* Need to reorder */
- newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
- + struct_size + fdt_size_dt_strings(fdt);
-
- if (bufsize < newsize)
- return -FDT_ERR_NOSPACE;
-
- /* First attempt to build converted tree at beginning of buffer */
- tmp = buf;
- /* But if that overlaps with the old tree... */
- if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
- /* Try right after the old tree instead */
- tmp = (char *)(uintptr_t)fdtend;
- if ((tmp + newsize) > ((char *)buf + bufsize))
- return -FDT_ERR_NOSPACE;
- }
-
- _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
- memmove(buf, tmp, newsize);
-
- fdt_set_magic(buf, FDT_MAGIC);
- fdt_set_totalsize(buf, bufsize);
- fdt_set_version(buf, 17);
- fdt_set_last_comp_version(buf, 16);
- fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
-
- return 0;
-}
-
-int fdt_pack(void *fdt)
-{
- int mem_rsv_size;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
- _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
- fdt_set_totalsize(fdt, _fdt_data_size(fdt));
-
- return 0;
-}
diff --git a/lib/libfdt/fdt_strerror.c b/lib/libfdt/fdt_strerror.c
deleted file mode 100644
index e6c3cee..0000000
--- a/lib/libfdt/fdt_strerror.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-struct fdt_errtabent {
- const char *str;
-};
-
-#define FDT_ERRTABENT(val) \
- [(val)] = { .str = #val, }
-
-static struct fdt_errtabent fdt_errtable[] = {
- FDT_ERRTABENT(FDT_ERR_NOTFOUND),
- FDT_ERRTABENT(FDT_ERR_EXISTS),
- FDT_ERRTABENT(FDT_ERR_NOSPACE),
-
- FDT_ERRTABENT(FDT_ERR_BADOFFSET),
- FDT_ERRTABENT(FDT_ERR_BADPATH),
- FDT_ERRTABENT(FDT_ERR_BADSTATE),
-
- FDT_ERRTABENT(FDT_ERR_TRUNCATED),
- FDT_ERRTABENT(FDT_ERR_BADMAGIC),
- FDT_ERRTABENT(FDT_ERR_BADVERSION),
- FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
- FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
-};
-#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
-
-const char *fdt_strerror(int errval)
-{
- if (errval > 0)
- return "<valid offset/length>";
- else if (errval == 0)
- return "<no error>";
- else if (errval > -FDT_ERRTABSIZE) {
- const char *s = fdt_errtable[-errval].str;
-
- if (s)
- return s;
- }
-
- return "<unknown error>";
-}
diff --git a/lib/libfdt/fdt_sw.c b/lib/libfdt/fdt_sw.c
deleted file mode 100644
index f422754..0000000
--- a/lib/libfdt/fdt_sw.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_sw_check_header(void *fdt)
-{
- if (fdt_magic(fdt) != FDT_SW_MAGIC)
- return -FDT_ERR_BADMAGIC;
- /* FIXME: should check more details about the header state */
- return 0;
-}
-
-#define FDT_SW_CHECK_HEADER(fdt) \
- { \
- int err; \
- if ((err = _fdt_sw_check_header(fdt)) != 0) \
- return err; \
- }
-
-static void *_fdt_grab_space(void *fdt, size_t len)
-{
- int offset = fdt_size_dt_struct(fdt);
- int spaceleft;
-
- spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
- - fdt_size_dt_strings(fdt);
-
- if ((offset + len < offset) || (offset + len > spaceleft))
- return NULL;
-
- fdt_set_size_dt_struct(fdt, offset + len);
- return _fdt_offset_ptr_w(fdt, offset);
-}
-
-int fdt_create(void *buf, int bufsize)
-{
- void *fdt = buf;
-
- if (bufsize < sizeof(struct fdt_header))
- return -FDT_ERR_NOSPACE;
-
- memset(buf, 0, bufsize);
-
- fdt_set_magic(fdt, FDT_SW_MAGIC);
- fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
- fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
- fdt_set_totalsize(fdt, bufsize);
-
- fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
- sizeof(struct fdt_reserve_entry)));
- fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
- fdt_set_off_dt_strings(fdt, bufsize);
-
- return 0;
-}
-
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
-{
- struct fdt_reserve_entry *re;
- int offset;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- if (fdt_size_dt_struct(fdt))
- return -FDT_ERR_BADSTATE;
-
- offset = fdt_off_dt_struct(fdt);
- if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
- return -FDT_ERR_NOSPACE;
-
- re = (struct fdt_reserve_entry *)((char *)fdt + offset);
- re->address = cpu_to_fdt64(addr);
- re->size = cpu_to_fdt64(size);
-
- fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
-
- return 0;
-}
-
-int fdt_finish_reservemap(void *fdt)
-{
- return fdt_add_reservemap_entry(fdt, 0, 0);
-}
-
-int fdt_begin_node(void *fdt, const char *name)
-{
- struct fdt_node_header *nh;
- int namelen = strlen(name) + 1;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
- if (! nh)
- return -FDT_ERR_NOSPACE;
-
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memcpy(nh->name, name, namelen);
- return 0;
-}
-
-int fdt_end_node(void *fdt)
-{
- fdt32_t *en;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- en = _fdt_grab_space(fdt, FDT_TAGSIZE);
- if (! en)
- return -FDT_ERR_NOSPACE;
-
- *en = cpu_to_fdt32(FDT_END_NODE);
- return 0;
-}
-
-static int _fdt_find_add_string(void *fdt, const char *s)
-{
- char *strtab = (char *)fdt + fdt_totalsize(fdt);
- const char *p;
- int strtabsize = fdt_size_dt_strings(fdt);
- int len = strlen(s) + 1;
- int struct_top, offset;
-
- p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
- if (p)
- return p - strtab;
-
- /* Add it */
- offset = -strtabsize - len;
- struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- if (fdt_totalsize(fdt) + offset < struct_top)
- return 0; /* no more room :( */
-
- memcpy(strtab + offset, s, len);
- fdt_set_size_dt_strings(fdt, strtabsize + len);
- return offset;
-}
-
-int fdt_property(void *fdt, const char *name, const void *val, int len)
-{
- struct fdt_property *prop;
- int nameoff;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- nameoff = _fdt_find_add_string(fdt, name);
- if (nameoff == 0)
- return -FDT_ERR_NOSPACE;
-
- prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
- if (! prop)
- return -FDT_ERR_NOSPACE;
-
- prop->tag = cpu_to_fdt32(FDT_PROP);
- prop->nameoff = cpu_to_fdt32(nameoff);
- prop->len = cpu_to_fdt32(len);
- memcpy(prop->data, val, len);
- return 0;
-}
-
-int fdt_finish(void *fdt)
-{
- char *p = (char *)fdt;
- fdt32_t *end;
- int oldstroffset, newstroffset;
- uint32_t tag;
- int offset, nextoffset;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- /* Add terminator */
- end = _fdt_grab_space(fdt, sizeof(*end));
- if (! end)
- return -FDT_ERR_NOSPACE;
- *end = cpu_to_fdt32(FDT_END);
-
- /* Relocate the string table */
- oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
- newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
- fdt_set_off_dt_strings(fdt, newstroffset);
-
- /* Walk the structure, correcting string offsets */
- offset = 0;
- while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
- if (tag == FDT_PROP) {
- struct fdt_property *prop =
- _fdt_offset_ptr_w(fdt, offset);
- int nameoff;
-
- nameoff = fdt32_to_cpu(prop->nameoff);
- nameoff += fdt_size_dt_strings(fdt);
- prop->nameoff = cpu_to_fdt32(nameoff);
- }
- offset = nextoffset;
- }
- if (nextoffset < 0)
- return nextoffset;
-
- /* Finally, adjust the header */
- fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
- fdt_set_magic(fdt, FDT_MAGIC);
- return 0;
-}
diff --git a/lib/libfdt/fdt_wip.c b/lib/libfdt/fdt_wip.c
deleted file mode 100644
index c5bbb68..0000000
--- a/lib/libfdt/fdt_wip.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
-{
- void *propval;
- int proplen;
-
- propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
- if (! propval)
- return proplen;
-
- if (proplen != len)
- return -FDT_ERR_NOSPACE;
-
- memcpy(propval, val, len);
- return 0;
-}
-
-static void _fdt_nop_region(void *start, int len)
-{
- fdt32_t *p;
-
- for (p = start; (char *)p < ((char *)start + len); p++)
- *p = cpu_to_fdt32(FDT_NOP);
-}
-
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
-{
- struct fdt_property *prop;
- int len;
-
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
- return len;
-
- _fdt_nop_region(prop, len + sizeof(*prop));
-
- return 0;
-}
-
-int _fdt_node_end_offset(void *fdt, int offset)
-{
- int depth = 0;
-
- while ((offset >= 0) && (depth >= 0))
- offset = fdt_next_node(fdt, offset, &depth);
-
- return offset;
-}
-
-int fdt_nop_node(void *fdt, int nodeoffset)
-{
- int endoffset;
-
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
-
- _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
- endoffset - nodeoffset);
- return 0;
-}
diff --git a/lib/libfdt/libfdt.h b/lib/libfdt/libfdt.h
deleted file mode 100644
index 02baa84..0000000
--- a/lib/libfdt/libfdt.h
+++ /dev/null
@@ -1,1514 +0,0 @@
-#ifndef _LIBFDT_H
-#define _LIBFDT_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <libfdt_env.h>
-#include <fdt.h>
-
-#define FDT_FIRST_SUPPORTED_VERSION 0x10
-#define FDT_LAST_SUPPORTED_VERSION 0x11
-
-/* Error codes: informative error codes */
-#define FDT_ERR_NOTFOUND 1
- /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
-#define FDT_ERR_EXISTS 2
- /* FDT_ERR_EXISTS: Attemped to create a node or property which
- * already exists */
-#define FDT_ERR_NOSPACE 3
- /* FDT_ERR_NOSPACE: Operation needed to expand the device
- * tree, but its buffer did not have sufficient space to
- * contain the expanded tree. Use fdt_open_into() to move the
- * device tree to a buffer with more space. */
-
-/* Error codes: codes for bad parameters */
-#define FDT_ERR_BADOFFSET 4
- /* FDT_ERR_BADOFFSET: Function was passed a structure block
- * offset which is out-of-bounds, or which points to an
- * unsuitable part of the structure for the operation. */
-#define FDT_ERR_BADPATH 5
- /* FDT_ERR_BADPATH: Function was passed a badly formatted path
- * (e.g. missing a leading / for a function which requires an
- * absolute path) */
-#define FDT_ERR_BADPHANDLE 6
- /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
- * value. phandle values of 0 and -1 are not permitted. */
-#define FDT_ERR_BADSTATE 7
- /* FDT_ERR_BADSTATE: Function was passed an incomplete device
- * tree created by the sequential-write functions, which is
- * not sufficiently complete for the requested operation. */
-
-/* Error codes: codes for bad device tree blobs */
-#define FDT_ERR_TRUNCATED 8
- /* FDT_ERR_TRUNCATED: Structure block of the given device tree
- * ends without an FDT_END tag. */
-#define FDT_ERR_BADMAGIC 9
- /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
- * device tree at all - it is missing the flattened device
- * tree magic number. */
-#define FDT_ERR_BADVERSION 10
- /* FDT_ERR_BADVERSION: Given device tree has a version which
- * can't be handled by the requested operation. For
- * read-write functions, this may mean that fdt_open_into() is
- * required to convert the tree to the expected version. */
-#define FDT_ERR_BADSTRUCTURE 11
- /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
- * structure block or other serious error (e.g. misnested
- * nodes, or subnodes preceding properties). */
-#define FDT_ERR_BADLAYOUT 12
- /* FDT_ERR_BADLAYOUT: For read-write functions, the given
- * device tree has it's sub-blocks in an order that the
- * function can't handle (memory reserve map, then structure,
- * then strings). Use fdt_open_into() to reorganize the tree
- * into a form suitable for the read-write operations. */
-
-/* "Can't happen" error indicating a bug in libfdt */
-#define FDT_ERR_INTERNAL 13
- /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
- * Should never be returned, if it is, it indicates a bug in
- * libfdt itself. */
-
-#define FDT_ERR_MAX 13
-
-/**********************************************************************/
-/* Low-level functions (you probably don't need these) */
-/**********************************************************************/
-
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
-static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
-{
- return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
-}
-
-uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
-
-/**********************************************************************/
-/* Traversal functions */
-/**********************************************************************/
-
-int fdt_next_node(const void *fdt, int offset, int *depth);
-
-/**
- * fdt_first_subnode() - get offset of first direct subnode
- *
- * @fdt: FDT blob
- * @offset: Offset of node to check
- * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
- */
-int fdt_first_subnode(const void *fdt, int offset);
-
-/**
- * fdt_next_subnode() - get offset of next direct subnode
- *
- * After first calling fdt_first_subnode(), call this function repeatedly to
- * get direct subnodes of a parent node.
- *
- * @fdt: FDT blob
- * @offset: Offset of previous subnode
- * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
- * subnodes
- */
-int fdt_next_subnode(const void *fdt, int offset);
-
-/**********************************************************************/
-/* General functions */
-/**********************************************************************/
-
-#define fdt_get_header(fdt, field) \
- (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
-#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
-#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
-#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
-#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
-#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
-#define fdt_version(fdt) (fdt_get_header(fdt, version))
-#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
-#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
-#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
-#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
-
-#define __fdt_set_hdr(name) \
- static inline void fdt_set_##name(void *fdt, uint32_t val) \
- { \
- struct fdt_header *fdth = (struct fdt_header*)fdt; \
- fdth->name = cpu_to_fdt32(val); \
- }
-__fdt_set_hdr(magic);
-__fdt_set_hdr(totalsize);
-__fdt_set_hdr(off_dt_struct);
-__fdt_set_hdr(off_dt_strings);
-__fdt_set_hdr(off_mem_rsvmap);
-__fdt_set_hdr(version);
-__fdt_set_hdr(last_comp_version);
-__fdt_set_hdr(boot_cpuid_phys);
-__fdt_set_hdr(size_dt_strings);
-__fdt_set_hdr(size_dt_struct);
-#undef __fdt_set_hdr
-
-/**
- * fdt_check_header - sanity check a device tree or possible device tree
- * @fdt: pointer to data which might be a flattened device tree
- *
- * fdt_check_header() checks that the given buffer contains what
- * appears to be a flattened device tree with sane information in its
- * header.
- *
- * returns:
- * 0, if the buffer appears to contain a valid device tree
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings, as above
- */
-int fdt_check_header(const void *fdt);
-
-/**
- * fdt_move - move a device tree around in memory
- * @fdt: pointer to the device tree to move
- * @buf: pointer to memory where the device is to be moved
- * @bufsize: size of the memory space at buf
- *
- * fdt_move() relocates, if possible, the device tree blob located at
- * fdt to the buffer at buf of size bufsize. The buffer may overlap
- * with the existing device tree blob at fdt. Therefore,
- * fdt_move(fdt, fdt, fdt_totalsize(fdt))
- * should always succeed.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_move(const void *fdt, void *buf, int bufsize);
-
-/**********************************************************************/
-/* Read-only functions */
-/**********************************************************************/
-
-/**
- * fdt_string - retrieve a string from the strings block of a device tree
- * @fdt: pointer to the device tree blob
- * @stroffset: offset of the string within the strings block (native endian)
- *
- * fdt_string() retrieves a pointer to a single string from the
- * strings block of the device tree blob at fdt.
- *
- * returns:
- * a pointer to the string, on success
- * NULL, if stroffset is out of bounds
- */
-const char *fdt_string(const void *fdt, int stroffset);
-
-/**
- * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
- * @fdt: pointer to the device tree blob
- *
- * Returns the number of entries in the device tree blob's memory
- * reservation map. This does not include the terminating 0,0 entry
- * or any other (0,0) entries reserved for expansion.
- *
- * returns:
- * the number of entries
- */
-int fdt_num_mem_rsv(const void *fdt);
-
-/**
- * fdt_get_mem_rsv - retrieve one memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @address, @size: pointers to 64-bit variables
- *
- * On success, *address and *size will contain the address and size of
- * the n-th reserve map entry from the device tree blob, in
- * native-endian format.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
-
-/**
- * fdt_subnode_offset_namelen - find a subnode based on substring
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- * @namelen: number of characters of name to consider
- *
- * Identical to fdt_subnode_offset(), but only examine the first
- * namelen characters of name for matching the subnode name. This is
- * useful for finding subnodes based on a portion of a larger string,
- * such as a full path.
- */
-int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
- const char *name, int namelen);
-/**
- * fdt_subnode_offset - find a subnode of a given node
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- *
- * fdt_subnode_offset() finds a subnode of the node at structure block
- * offset parentoffset with the given name. name may include a unit
- * address, in which case fdt_subnode_offset() will find the subnode
- * with that unit address, or the unit address may be omitted, in
- * which case fdt_subnode_offset() will find an arbitrary subnode
- * whose name excluding unit address matches the given name.
- *
- * returns:
- * structure block offset of the requested subnode (>=0), on success
- * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
-
-/**
- * fdt_path_offset - find a tree node by its full path
- * @fdt: pointer to the device tree blob
- * @path: full path of the node to locate
- *
- * fdt_path_offset() finds a node of a given path in the device tree.
- * Each path component may omit the unit address portion, but the
- * results of this are undefined if any such path component is
- * ambiguous (that is if there are multiple nodes at the relevant
- * level matching the given component, differentiated only by unit
- * address).
- *
- * returns:
- * structure block offset of the node with the requested path (>=0), on success
- * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
- * -FDT_ERR_NOTFOUND, if the requested node does not exist
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_path_offset(const void *fdt, const char *path);
-
-/**
- * fdt_get_name - retrieve the name of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of the starting node
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_get_name() retrieves the name (including unit address) of the
- * device tree node at structure block offset nodeoffset. If lenp is
- * non-NULL, the length of this name is also returned, in the integer
- * pointed to by lenp.
- *
- * returns:
- * pointer to the node's name, on success
- * If lenp is non-NULL, *lenp contains the length of that name (>=0)
- * NULL, on error
- * if lenp is non-NULL *lenp contains an error code (<0):
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings
- */
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
-
-/**
- * fdt_first_property_offset - find the offset of a node's first property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of a node
- *
- * fdt_first_property_offset() finds the first property of the node at
- * the given structure block offset.
- *
- * returns:
- * structure block offset of the property (>=0), on success
- * -FDT_ERR_NOTFOUND, if the requested node has no properties
- * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_first_property_offset(const void *fdt, int nodeoffset);
-
-/**
- * fdt_next_property_offset - step through a node's properties
- * @fdt: pointer to the device tree blob
- * @offset: structure block offset of a property
- *
- * fdt_next_property_offset() finds the property immediately after the
- * one at the given structure block offset. This will be a property
- * of the same node as the given property.
- *
- * returns:
- * structure block offset of the next property (>=0), on success
- * -FDT_ERR_NOTFOUND, if the given property is the last in its node
- * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_next_property_offset(const void *fdt, int offset);
-
-/**
- * fdt_get_property_by_offset - retrieve the property at a given offset
- * @fdt: pointer to the device tree blob
- * @offset: offset of the property to retrieve
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_get_property_by_offset() retrieves a pointer to the
- * fdt_property structure within the device tree blob at the given
- * offset. If lenp is non-NULL, the length of the property value is
- * also returned, in the integer pointed to by lenp.
- *
- * returns:
- * pointer to the structure representing the property
- * if lenp is non-NULL, *lenp contains the length of the property
- * value (>=0)
- * NULL, on error
- * if lenp is non-NULL, *lenp contains an error code (<0):
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
- int offset,
- int *lenp);
-
-/**
- * fdt_get_property_namelen - find a property based on substring
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @namelen: number of characters of name to consider
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * Identical to fdt_get_property_namelen(), but only examine the first
- * namelen characters of name for matching the property name.
- */
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
- int nodeoffset,
- const char *name,
- int namelen, int *lenp);
-
-/**
- * fdt_get_property - find a given property in a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_get_property() retrieves a pointer to the fdt_property
- * structure within the device tree blob corresponding to the property
- * named 'name' of the node at offset nodeoffset. If lenp is
- * non-NULL, the length of the property value is also returned, in the
- * integer pointed to by lenp.
- *
- * returns:
- * pointer to the structure representing the property
- * if lenp is non-NULL, *lenp contains the length of the property
- * value (>=0)
- * NULL, on error
- * if lenp is non-NULL, *lenp contains an error code (<0):
- * -FDT_ERR_NOTFOUND, node does not have named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
- const char *name, int *lenp);
-static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
- const char *name,
- int *lenp)
-{
- return (struct fdt_property *)(uintptr_t)
- fdt_get_property(fdt, nodeoffset, name, lenp);
-}
-
-/**
- * fdt_getprop_by_offset - retrieve the value of a property at a given offset
- * @fdt: pointer to the device tree blob
- * @ffset: offset of the property to read
- * @namep: pointer to a string variable (will be overwritten) or NULL
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_getprop_by_offset() retrieves a pointer to the value of the
- * property at structure block offset 'offset' (this will be a pointer
- * to within the device blob itself, not a copy of the value). If
- * lenp is non-NULL, the length of the property value is also
- * returned, in the integer pointed to by lenp. If namep is non-NULL,
- * the property's namne will also be returned in the char * pointed to
- * by namep (this will be a pointer to within the device tree's string
- * block, not a new copy of the name).
- *
- * returns:
- * pointer to the property's value
- * if lenp is non-NULL, *lenp contains the length of the property
- * value (>=0)
- * if namep is non-NULL *namep contiains a pointer to the property
- * name.
- * NULL, on error
- * if lenp is non-NULL, *lenp contains an error code (<0):
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-const void *fdt_getprop_by_offset(const void *fdt, int offset,
- const char **namep, int *lenp);
-
-/**
- * fdt_getprop_namelen - get property value based on substring
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @namelen: number of characters of name to consider
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * Identical to fdt_getprop(), but only examine the first namelen
- * characters of name for matching the property name.
- */
-const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
- const char *name, int namelen, int *lenp);
-
-/**
- * fdt_getprop - retrieve the value of a given property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_getprop() retrieves a pointer to the value of the property
- * named 'name' of the node at offset nodeoffset (this will be a
- * pointer to within the device blob itself, not a copy of the value).
- * If lenp is non-NULL, the length of the property value is also
- * returned, in the integer pointed to by lenp.
- *
- * returns:
- * pointer to the property's value
- * if lenp is non-NULL, *lenp contains the length of the property
- * value (>=0)
- * NULL, on error
- * if lenp is non-NULL, *lenp contains an error code (<0):
- * -FDT_ERR_NOTFOUND, node does not have named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-const void *fdt_getprop(const void *fdt, int nodeoffset,
- const char *name, int *lenp);
-static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
- const char *name, int *lenp)
-{
- return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
-}
-
-/**
- * fdt_get_phandle - retrieve the phandle of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of the node
- *
- * fdt_get_phandle() retrieves the phandle of the device tree node at
- * structure block offset nodeoffset.
- *
- * returns:
- * the phandle of the node at nodeoffset, on success (!= 0, != -1)
- * 0, if the node has no phandle, or another error occurs
- */
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
-
-/**
- * fdt_get_alias_namelen - get alias based on substring
- * @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
- * @namelen: number of characters of name to consider
- *
- * Identical to fdt_get_alias(), but only examine the first namelen
- * characters of name for matching the alias name.
- */
-const char *fdt_get_alias_namelen(const void *fdt,
- const char *name, int namelen);
-
-/**
- * fdt_get_alias - retreive the path referenced by a given alias
- * @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
- *
- * fdt_get_alias() retrieves the value of a given alias. That is, the
- * value of the property named 'name' in the node /aliases.
- *
- * returns:
- * a pointer to the expansion of the alias named 'name', if it exists
- * NULL, if the given alias or the /aliases node does not exist
- */
-const char *fdt_get_alias(const void *fdt, const char *name);
-
-/**
- * fdt_get_path - determine the full path of a node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose path to find
- * @buf: character buffer to contain the returned path (will be overwritten)
- * @buflen: size of the character buffer at buf
- *
- * fdt_get_path() computes the full path of the node at offset
- * nodeoffset, and records that path in the buffer at buf.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
- * 0, on success
- * buf contains the absolute path of the node at
- * nodeoffset, as a NUL-terminated string.
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
- * characters and will not fit in the given buffer.
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
-
-/**
- * fdt_supernode_atdepth_offset - find a specific ancestor of a node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- * @supernodedepth: depth of the ancestor to find
- * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_supernode_atdepth_offset() finds an ancestor of the given node
- * at a specific depth from the root (where the root itself has depth
- * 0, its immediate subnodes depth 1 and so forth). So
- * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
- * will always return 0, the offset of the root node. If the node at
- * nodeoffset has depth D, then:
- * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
- * will return nodeoffset itself.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
-
- * structure block offset of the node at node offset's ancestor
- * of depth supernodedepth (>=0), on success
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
-* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
- int supernodedepth, int *nodedepth);
-
-/**
- * fdt_node_depth - find the depth of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- *
- * fdt_node_depth() finds the depth of a given node. The root node
- * has depth 0, its immediate subnodes depth 1 and so forth.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
- * depth of the node at nodeoffset (>=0), on success
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_depth(const void *fdt, int nodeoffset);
-
-/**
- * fdt_parent_offset - find the parent of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- *
- * fdt_parent_offset() locates the parent node of a given node (that
- * is, it finds the offset of the node which contains the node at
- * nodeoffset as a subnode).
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset, *twice*.
- *
- * returns:
- * structure block offset of the parent of the node at nodeoffset
- * (>=0), on success
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_parent_offset(const void *fdt, int nodeoffset);
-
-/**
- * fdt_node_offset_by_prop_value - find nodes with a given property value
- * @fdt: pointer to the device tree blob
- * @startoffset: only find nodes after this offset
- * @propname: property name to check
- * @propval: property value to search for
- * @proplen: length of the value in propval
- *
- * fdt_node_offset_by_prop_value() returns the offset of the first
- * node after startoffset, which has a property named propname whose
- * value is of length proplen and has value equal to propval; or if
- * startoffset is -1, the very first such node in the tree.
- *
- * To iterate through all nodes matching the criterion, the following
- * idiom can be used:
- * offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
- * propval, proplen);
- * while (offset != -FDT_ERR_NOTFOUND) {
- * // other code here
- * offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
- * propval, proplen);
- * }
- *
- * Note the -1 in the first call to the function, if 0 is used here
- * instead, the function will never locate the root node, even if it
- * matches the criterion.
- *
- * returns:
- * structure block offset of the located node (>= 0, >startoffset),
- * on success
- * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
- * tree after startoffset
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
- const char *propname,
- const void *propval, int proplen);
-
-/**
- * fdt_node_offset_by_phandle - find the node with a given phandle
- * @fdt: pointer to the device tree blob
- * @phandle: phandle value
- *
- * fdt_node_offset_by_phandle() returns the offset of the node
- * which has the given phandle value. If there is more than one node
- * in the tree with the given phandle (an invalid tree), results are
- * undefined.
- *
- * returns:
- * structure block offset of the located node (>= 0), on success
- * -FDT_ERR_NOTFOUND, no node with that phandle exists
- * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
-
-/**
- * fdt_node_check_compatible: check a node's compatible property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of a tree node
- * @compatible: string to match against
- *
- *
- * fdt_node_check_compatible() returns 0 if the given node contains a
- * 'compatible' property with the given string as one of its elements,
- * it returns non-zero otherwise, or on error.
- *
- * returns:
- * 0, if the node has a 'compatible' property listing the given string
- * 1, if the node has a 'compatible' property, but it does not list
- * the given string
- * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
- * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
- const char *compatible);
-
-/**
- * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
- * @fdt: pointer to the device tree blob
- * @startoffset: only find nodes after this offset
- * @compatible: 'compatible' string to match against
- *
- * fdt_node_offset_by_compatible() returns the offset of the first
- * node after startoffset, which has a 'compatible' property which
- * lists the given compatible string; or if startoffset is -1, the
- * very first such node in the tree.
- *
- * To iterate through all nodes matching the criterion, the following
- * idiom can be used:
- * offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
- * while (offset != -FDT_ERR_NOTFOUND) {
- * // other code here
- * offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
- * }
- *
- * Note the -1 in the first call to the function, if 0 is used here
- * instead, the function will never locate the root node, even if it
- * matches the criterion.
- *
- * returns:
- * structure block offset of the located node (>= 0, >startoffset),
- * on success
- * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
- * tree after startoffset
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
- const char *compatible);
-
-/**
- * fdt_stringlist_contains - check a string list property for a string
- * @strlist: Property containing a list of strings to check
- * @listlen: Length of property
- * @str: String to search for
- *
- * This is a utility function provided for convenience. The list contains
- * one or more strings, each terminated by \0, as is found in a device tree
- * "compatible" property.
- *
- * @return: 1 if the string is found in the list, 0 not found, or invalid list
- */
-int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
-
-/**********************************************************************/
-/* Write-in-place functions */
-/**********************************************************************/
-
-/**
- * fdt_setprop_inplace - change a property's value, but not its size
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: pointer to data to replace the property value with
- * @len: length of the property value
- *
- * fdt_setprop_inplace() replaces the value of a given property with
- * the data in val, of length len. This function cannot change the
- * size of a property, and so will only work if len is equal to the
- * current length of the property.
- *
- * This function will alter only the bytes in the blob which contain
- * the given property value, and will not alter or move any other part
- * of the tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, if len is not equal to the property's current length
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
-
-/**
- * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 32-bit integer value to replace the property with
- *
- * fdt_setprop_inplace_u32() replaces the value of a given property
- * with the 32-bit integer value in val, converting val to big-endian
- * if necessary. This function cannot change the size of a property,
- * and so will only work if the property already exists and has length
- * 4.
- *
- * This function will alter only the bytes in the blob which contain
- * the given property value, and will not alter or move any other part
- * of the tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, if the property's length is not equal to 4
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
-{
- fdt32_t tmp = cpu_to_fdt32(val);
- return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-/**
- * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 64-bit integer value to replace the property with
- *
- * fdt_setprop_inplace_u64() replaces the value of a given property
- * with the 64-bit integer value in val, converting val to big-endian
- * if necessary. This function cannot change the size of a property,
- * and so will only work if the property already exists and has length
- * 8.
- *
- * This function will alter only the bytes in the blob which contain
- * the given property value, and will not alter or move any other part
- * of the tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, if the property's length is not equal to 8
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
- const char *name, uint64_t val)
-{
- fdt64_t tmp = cpu_to_fdt64(val);
- return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-/**
- * fdt_setprop_inplace_cell - change the value of a single-cell property
- *
- * This is an alternative name for fdt_setprop_inplace_u32()
- */
-static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
-{
- return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
-}
-
-/**
- * fdt_nop_property - replace a property with nop tags
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to nop
- * @name: name of the property to nop
- *
- * fdt_nop_property() will replace a given property's representation
- * in the blob with FDT_NOP tags, effectively removing it from the
- * tree.
- *
- * This function will alter only the bytes in the blob which contain
- * the property, and will not alter or move any other part of the
- * tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_nop_node - replace a node (subtree) with nop tags
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node to nop
- *
- * fdt_nop_node() will replace a given node's representation in the
- * blob, including all its subnodes, if any, with FDT_NOP tags,
- * effectively removing it from the tree.
- *
- * This function will alter only the bytes in the blob which contain
- * the node and its properties and subnodes, and will not alter or
- * move any other part of the tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_nop_node(void *fdt, int nodeoffset);
-
-/**********************************************************************/
-/* Sequential write functions */
-/**********************************************************************/
-
-int fdt_create(void *buf, int bufsize);
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
-int fdt_finish_reservemap(void *fdt);
-int fdt_begin_node(void *fdt, const char *name);
-int fdt_property(void *fdt, const char *name, const void *val, int len);
-static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
-{
- fdt32_t tmp = cpu_to_fdt32(val);
- return fdt_property(fdt, name, &tmp, sizeof(tmp));
-}
-static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
-{
- fdt64_t tmp = cpu_to_fdt64(val);
- return fdt_property(fdt, name, &tmp, sizeof(tmp));
-}
-static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
-{
- return fdt_property_u32(fdt, name, val);
-}
-#define fdt_property_string(fdt, name, str) \
- fdt_property(fdt, name, str, strlen(str)+1)
-int fdt_end_node(void *fdt);
-int fdt_finish(void *fdt);
-
-/**********************************************************************/
-/* Read-write functions */
-/**********************************************************************/
-
-int fdt_create_empty_tree(void *buf, int bufsize);
-int fdt_open_into(const void *fdt, void *buf, int bufsize);
-int fdt_pack(void *fdt);
-
-/**
- * fdt_add_mem_rsv - add one memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @address, @size: 64-bit values (native endian)
- *
- * Adds a reserve map entry to the given blob reserving a region at
- * address address of length size.
- *
- * This function will insert data into the reserve map and will
- * therefore change the indexes of some entries in the table.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new reservation entry
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
-
-/**
- * fdt_del_mem_rsv - remove a memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @n: entry to remove
- *
- * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
- * the blob.
- *
- * This function will delete data from the reservation table and will
- * therefore change the indexes of some entries in the table.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
- * are less than n+1 reserve map entries)
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_del_mem_rsv(void *fdt, int n);
-
-/**
- * fdt_set_name - change the name of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of a node
- * @name: name to give the node
- *
- * fdt_set_name() replaces the name (including unit address, if any)
- * of the given node with the given string. NOTE: this function can't
- * efficiently check if the new name is unique amongst the given
- * node's siblings; results are undefined if this function is invoked
- * with a name equal to one of the given node's siblings.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob
- * to contain the new name
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_set_name(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_setprop - create or change a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: pointer to data to set the property value to
- * @len: length of the property value
- *
- * fdt_setprop() sets the value of the named property in the given
- * node to the given value and length, creating the property if it
- * does not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
-
-/**
- * fdt_setprop_u32 - set a property to a 32-bit integer
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 32-bit integer value for the property (native endian)
- *
- * fdt_setprop_u32() sets the value of the named property in the given
- * node to the given 32-bit integer value (converting to big-endian if
- * necessary), or creates a new property with that value if it does
- * not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
- uint32_t val)
-{
- fdt32_t tmp = cpu_to_fdt32(val);
- return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-/**
- * fdt_setprop_u64 - set a property to a 64-bit integer
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 64-bit integer value for the property (native endian)
- *
- * fdt_setprop_u64() sets the value of the named property in the given
- * node to the given 64-bit integer value (converting to big-endian if
- * necessary), or creates a new property with that value if it does
- * not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
- uint64_t val)
-{
- fdt64_t tmp = cpu_to_fdt64(val);
- return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-/**
- * fdt_setprop_cell - set a property to a single cell value
- *
- * This is an alternative name for fdt_setprop_u32()
- */
-static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
- uint32_t val)
-{
- return fdt_setprop_u32(fdt, nodeoffset, name, val);
-}
-
-/**
- * fdt_setprop_string - set a property to a string value
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @str: string value for the property
- *
- * fdt_setprop_string() sets the value of the named property in the
- * given node to the given string value (using the length of the
- * string to determine the new length of the property), or creates a
- * new property with that value if it does not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-#define fdt_setprop_string(fdt, nodeoffset, name, str) \
- fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
-
-/**
- * fdt_appendprop - append to or create a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to append to
- * @val: pointer to data to append to the property value
- * @len: length of the data to append to the property value
- *
- * fdt_appendprop() appends the value to the named property in the
- * given node, creating the property if it does not already exist.
- *
- * This function may insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
-
-/**
- * fdt_appendprop_u32 - append a 32-bit integer value to a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 32-bit integer value to append to the property (native endian)
- *
- * fdt_appendprop_u32() appends the given 32-bit integer value
- * (converting to big-endian if necessary) to the value of the named
- * property in the given node, or creates a new property with that
- * value if it does not already exist.
- *
- * This function may insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
-{
- fdt32_t tmp = cpu_to_fdt32(val);
- return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-/**
- * fdt_appendprop_u64 - append a 64-bit integer value to a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 64-bit integer value to append to the property (native endian)
- *
- * fdt_appendprop_u64() appends the given 64-bit integer value
- * (converting to big-endian if necessary) to the value of the named
- * property in the given node, or creates a new property with that
- * value if it does not already exist.
- *
- * This function may insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
- const char *name, uint64_t val)
-{
- fdt64_t tmp = cpu_to_fdt64(val);
- return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-/**
- * fdt_appendprop_cell - append a single cell value to a property
- *
- * This is an alternative name for fdt_appendprop_u32()
- */
-static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
-{
- return fdt_appendprop_u32(fdt, nodeoffset, name, val);
-}
-
-/**
- * fdt_appendprop_string - append a string to a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @str: string value to append to the property
- *
- * fdt_appendprop_string() appends the given string to the value of
- * the named property in the given node, or creates a new property
- * with that value if it does not already exist.
- *
- * This function may insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
- fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
-
-/**
- * fdt_delprop - delete a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to nop
- * @name: name of the property to nop
- *
- * fdt_del_property() will delete the given property.
- *
- * This function will delete data from the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_delprop(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_add_subnode_namelen - creates a new node based on substring
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- * @namelen: number of characters of name to consider
- *
- * Identical to fdt_add_subnode(), but use only the first namelen
- * characters of name as the name of the new node. This is useful for
- * creating subnodes based on a portion of a larger string, such as a
- * full path.
- */
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
- const char *name, int namelen);
-
-/**
- * fdt_add_subnode - creates a new node
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- *
- * fdt_add_subnode() creates a new node as a subnode of the node at
- * structure block offset parentoffset, with the given name (which
- * should include the unit address, if any).
- *
- * This function will insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
-
- * returns:
- * structure block offset of the created nodeequested subnode (>=0), on success
- * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
- * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
- * the given name
- * -FDT_ERR_NOSPACE, if there is insufficient free space in the
- * blob to contain the new node
- * -FDT_ERR_NOSPACE
- * -FDT_ERR_BADLAYOUT
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
-
-/**
- * fdt_del_node - delete a node (subtree)
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node to nop
- *
- * fdt_del_node() will remove the given node, including all its
- * subnodes if any, from the blob.
- *
- * This function will delete data from the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_del_node(void *fdt, int nodeoffset);
-
-/**********************************************************************/
-/* Debugging / informational functions */
-/**********************************************************************/
-
-const char *fdt_strerror(int errval);
-
-#endif /* _LIBFDT_H */
diff --git a/lib/libfdt/libfdt_env.h b/lib/libfdt/libfdt_env.h
deleted file mode 100644
index 9dea97d..0000000
--- a/lib/libfdt/libfdt_env.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef _LIBFDT_ENV_H
-#define _LIBFDT_ENV_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * Copyright 2012 Kim Phillips, Freescale Semiconductor.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#ifdef __CHECKER__
-#define __force __attribute__((force))
-#define __bitwise __attribute__((bitwise))
-#else
-#define __force
-#define __bitwise
-#endif
-
-typedef uint16_t __bitwise fdt16_t;
-typedef uint32_t __bitwise fdt32_t;
-typedef uint64_t __bitwise fdt64_t;
-
-#define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n])
-#define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1))
-#define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \
- (EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3))
-#define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \
- (EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \
- (EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \
- (EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7))
-
-static inline uint16_t fdt16_to_cpu(fdt16_t x)
-{
- return (__force uint16_t)CPU_TO_FDT16(x);
-}
-static inline fdt16_t cpu_to_fdt16(uint16_t x)
-{
- return (__force fdt16_t)CPU_TO_FDT16(x);
-}
-
-static inline uint32_t fdt32_to_cpu(fdt32_t x)
-{
- return (__force uint32_t)CPU_TO_FDT32(x);
-}
-static inline fdt32_t cpu_to_fdt32(uint32_t x)
-{
- return (__force fdt32_t)CPU_TO_FDT32(x);
-}
-
-static inline uint64_t fdt64_to_cpu(fdt64_t x)
-{
- return (__force uint64_t)CPU_TO_FDT64(x);
-}
-static inline fdt64_t cpu_to_fdt64(uint64_t x)
-{
- return (__force fdt64_t)CPU_TO_FDT64(x);
-}
-#undef CPU_TO_FDT64
-#undef CPU_TO_FDT32
-#undef CPU_TO_FDT16
-#undef EXTRACT_BYTE
-
-#endif /* _LIBFDT_ENV_H */
diff --git a/lib/libfdt/libfdt_internal.h b/lib/libfdt/libfdt_internal.h
deleted file mode 100644
index 381133b..0000000
--- a/lib/libfdt/libfdt_internal.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef _LIBFDT_INTERNAL_H
-#define _LIBFDT_INTERNAL_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <fdt.h>
-
-#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
-#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
-
-#define FDT_CHECK_HEADER(fdt) \
- { \
- int err; \
- if ((err = fdt_check_header(fdt)) != 0) \
- return err; \
- }
-
-int _fdt_check_node_offset(const void *fdt, int offset);
-int _fdt_check_prop_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
-
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
-{
- return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
-}
-
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
-{
- return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
-}
-
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
-{
- const struct fdt_reserve_entry *rsv_table =
- (const struct fdt_reserve_entry *)
- ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
-
- return rsv_table + n;
-}
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
-{
- return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
-}
-
-#define FDT_SW_MAGIC (~FDT_MAGIC)
-
-#endif /* _LIBFDT_INTERNAL_H */
diff --git a/lib/libfdt/version.lds b/lib/libfdt/version.lds
deleted file mode 100644
index 80b322b..0000000
--- a/lib/libfdt/version.lds
+++ /dev/null
@@ -1,60 +0,0 @@
-LIBFDT_1.2 {
- global:
- fdt_next_node;
- fdt_check_header;
- fdt_move;
- fdt_string;
- fdt_num_mem_rsv;
- fdt_get_mem_rsv;
- fdt_subnode_offset_namelen;
- fdt_subnode_offset;
- fdt_path_offset;
- fdt_get_name;
- fdt_get_property_namelen;
- fdt_get_property;
- fdt_getprop_namelen;
- fdt_getprop;
- fdt_get_phandle;
- fdt_get_alias_namelen;
- fdt_get_alias;
- fdt_get_path;
- fdt_supernode_atdepth_offset;
- fdt_node_depth;
- fdt_parent_offset;
- fdt_node_offset_by_prop_value;
- fdt_node_offset_by_phandle;
- fdt_node_check_compatible;
- fdt_node_offset_by_compatible;
- fdt_setprop_inplace;
- fdt_nop_property;
- fdt_nop_node;
- fdt_create;
- fdt_add_reservemap_entry;
- fdt_finish_reservemap;
- fdt_begin_node;
- fdt_property;
- fdt_end_node;
- fdt_finish;
- fdt_open_into;
- fdt_pack;
- fdt_add_mem_rsv;
- fdt_del_mem_rsv;
- fdt_set_name;
- fdt_setprop;
- fdt_delprop;
- fdt_add_subnode_namelen;
- fdt_add_subnode;
- fdt_del_node;
- fdt_strerror;
- fdt_offset_ptr;
- fdt_next_tag;
- fdt_appendprop;
- fdt_create_empty_tree;
- fdt_first_property_offset;
- fdt_get_property_by_offset;
- fdt_getprop_by_offset;
- fdt_next_property_offset;
-
- local:
- *;
-};
diff --git a/lib/libcflat/COPYRIGHT b/libcflat/COPYRIGHT
index d35649c..d35649c 100644
--- a/lib/libcflat/COPYRIGHT
+++ b/libcflat/COPYRIGHT
diff --git a/lib/libcflat/arm/eabi_compat.c b/libcflat/arm/eabi_compat.c
index 59d624d..59d624d 100644
--- a/lib/libcflat/arm/eabi_compat.c
+++ b/libcflat/arm/eabi_compat.c
diff --git a/lib/libcflat/arm/asm/io.h b/libcflat/arm/include/io.h
index 1d0abb7..55f0548 100644
--- a/lib/libcflat/arm/asm/io.h
+++ b/libcflat/arm/include/io.h
@@ -1,7 +1,6 @@
#ifndef _ASMARM_IO_H_
#define _ASMARM_IO_H_
#include "libcflat.h"
-#include "asm/barrier.h"
#define __iomem
#define __force
diff --git a/libcflat/arm/io.c b/libcflat/arm/io.c
new file mode 100644
index 0000000..b7fba6b
--- /dev/null
+++ b/libcflat/arm/io.c
@@ -0,0 +1,33 @@
+/*
+ * Each architecture must implement puts() and exit() with the I/O
+ * devices exposed from QEMU, e.g. pl011 and virtio-testdev. That's
+ * what's done here, along with initialization functions for those
+ * devices.
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "io.h"
+#include "platform.h"
+
+extern void halt(int code);
+
+/*
+ * Use this guess for the pl011 base in order to make an attempt at
+ * having earlier printf support. We'll overwrite it with the real
+ * base address that we read from the device tree later.
+ */
+static volatile u8 *uart0_base = (u8 *)UART0_BASE;
+
+void puts(const char *s)
+{
+ while (*s)
+ writeb(*s++, uart0_base);
+}
+
+void exit(int code)
+{
+ halt(code);
+}
diff --git a/lib/libcflat/arm/misc.S b/libcflat/arm/misc.S
index 500d14a..500d14a 100644
--- a/lib/libcflat/arm/misc.S
+++ b/libcflat/arm/misc.S
diff --git a/lib/libcflat/asm-generic/io.h b/libcflat/include/asm-generic/io.h
index f00f4d3..f00f4d3 100644
--- a/lib/libcflat/asm-generic/io.h
+++ b/libcflat/include/asm-generic/io.h
diff --git a/lib/libcflat/libcflat.h b/libcflat/include/libcflat.h
index 404560c..404560c 100644
--- a/lib/libcflat/libcflat.h
+++ b/libcflat/include/libcflat.h
diff --git a/lib/libcflat/string.h b/libcflat/include/string.h
index dbab368..dbab368 100644
--- a/lib/libcflat/string.h
+++ b/libcflat/include/string.h
diff --git a/lib/libcflat/printf.c b/libcflat/printf.c
index 89308fb..89308fb 100644
--- a/lib/libcflat/printf.c
+++ b/libcflat/printf.c
diff --git a/lib/libcflat/string.c b/libcflat/string.c
index 026f502..026f502 100644
--- a/lib/libcflat/string.c
+++ b/libcflat/string.c
diff --git a/platform/vexpress/platform.h b/platform/vexpress-a15/platform.h
index 9ea9282..9ea9282 100644
--- a/platform/vexpress/platform.h
+++ b/platform/vexpress-a15/platform.h
diff --git a/platform/vexpress-a9/platform.h b/platform/vexpress-a9/platform.h
new file mode 100644
index 0000000..334da32
--- /dev/null
+++ b/platform/vexpress-a9/platform.h
@@ -0,0 +1,33 @@
+#ifndef _PLATFORM_H
+#define _PLATFORM_H
+
+/* NORFLASH0 on Vexpress aseries (a15) is mapped from 0x08000000 to 0x0A000000
+ * which is 32MB. It is also aliased to 0x0 (to 0x2000000).
+ * It is acceptable to have the text here as it is RO.
+ */
+#define FLASH_SEC_BASE 0x00000000
+#define FLASH_NSEC_BASE 0x00010000
+
+#define RAM_SEC_BASE 0x60000000
+#define RAM_NSEC_BASE 0x68000000
+
+#define UART0_BASE 0x10009000
+
+/* Taken from Linux vexpress support */
+#define SYSREG_BASE 0x10000000
+#define SYSREG_CFGCTRL 0xa4
+#define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20)
+#define SYS_CFGFUNC_RESET 5
+#define SYS_CFGFUNC_SHUTDOWN 8
+#define SYS_CFGCTRL_START (1 << 31)
+#define SYS_CFGCTRL_WRITE (1 << 30)
+#define SYS_SHUTDOWN (SYS_CFGCTRL_FUNC(SYS_CFGFUNC_SHUTDOWN) | \
+ SYS_CFGCTRL_START | SYS_CFGCTRL_WRITE)
+#define SYS_RESET (SYS_CFGCTRL_FUNC(SYS_CFGFUNC_SHUTDOWN) | \
+ SYS_CFGCTRL_START | SYS_CFGCTRL_WRITE)
+
+#define STACK_SIZE 0x4000
+
+#define TZTEST_COMMON_HEAP_BASE 0x69000000
+#define TZTEST_SHARED_HEAP_BASE 0x6a000000
+#endif
diff --git a/platform/virt/platform.h b/platform/virt/platform.h
new file mode 100644
index 0000000..956d819
--- /dev/null
+++ b/platform/virt/platform.h
@@ -0,0 +1,33 @@
+#ifndef _PLATFORM_H
+#define _PLATFORM_H
+
+/* NORFLASH0 on Vexpress aseries (a15) is mapped from 0x08000000 to 0x0A000000
+ * which is 32MB. It is also aliased to 0x0 (to 0x2000000).
+ * It is acceptable to have the text here as it is RO.
+ */
+#define FLASH_SEC_BASE 0x00000000
+#define FLASH_NSEC_BASE 0x00010000
+
+#define RAM_SEC_BASE 0x40000000
+#define RAM_NSEC_BASE 0x48000000
+
+#define UART0_BASE 0x09000000
+
+/* Taken from Linux vexpress support */
+#define SYSREG_BASE 0x1c010000
+#define SYSREG_CFGCTRL 0xa4
+#define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20)
+#define SYS_CFGFUNC_RESET 5
+#define SYS_CFGFUNC_SHUTDOWN 8
+#define SYS_CFGCTRL_START (1 << 31)
+#define SYS_CFGCTRL_WRITE (1 << 30)
+#define SYS_SHUTDOWN (SYS_CFGCTRL_FUNC(SYS_CFGFUNC_SHUTDOWN) | \
+ SYS_CFGCTRL_START | SYS_CFGCTRL_WRITE)
+#define SYS_RESET (SYS_CFGCTRL_FUNC(SYS_CFGFUNC_SHUTDOWN) | \
+ SYS_CFGCTRL_START | SYS_CFGCTRL_WRITE)
+
+#define STACK_SIZE 0x4000
+
+#define TZTEST_COMMON_HEAP_BASE 0x49000000
+#define TZTEST_SHARED_HEAP_BASE 0x4A000000
+#endif