summaryrefslogtreecommitdiff
path: root/payloads
diff options
context:
space:
mode:
Diffstat (limited to 'payloads')
-rw-r--r--payloads/libpayload/Kconfig10
-rw-r--r--payloads/libpayload/Makefile41
-rw-r--r--payloads/libpayload/Makefile.inc1
-rw-r--r--payloads/libpayload/arch/mock/Kconfig16
-rw-r--r--payloads/libpayload/arch/mock/Makefile.inc7
-rw-r--r--payloads/libpayload/arch/mock/head.c3
-rw-r--r--payloads/libpayload/arch/mock/libpayload.ldscript3
-rw-r--r--payloads/libpayload/arch/mock/mock_media.c10
-rw-r--r--payloads/libpayload/arch/mock/virtual.c10
-rwxr-xr-xpayloads/libpayload/bin/lpgcc13
-rw-r--r--payloads/libpayload/include/mock/arch/barrier.h13
-rw-r--r--payloads/libpayload/include/mock/arch/cache.h18
-rw-r--r--payloads/libpayload/include/mock/arch/io.h29
-rw-r--r--payloads/libpayload/include/mock/arch/types.h33
-rw-r--r--payloads/libpayload/include/mock/arch/virtual.h15
-rw-r--r--payloads/libpayload/sample/Makefile5
-rw-r--r--payloads/libpayload/sample/arch_mock/Makefile48
-rw-r--r--payloads/libpayload/sample/arch_mock/hello.c13
-rw-r--r--payloads/libpayload/sample/arch_mock/hello_mocks.c43
19 files changed, 329 insertions, 2 deletions
diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig
index f7d78e069d..382f5af751 100644
--- a/payloads/libpayload/Kconfig
+++ b/payloads/libpayload/Kconfig
@@ -121,6 +121,14 @@ config ARCH_ARM64
help
Support the ARM64 architecture
+config ARCH_MOCK
+ bool "Mock architecture (for unit tests)"
+ help
+ This enables the mock architecture (for unit tests) that is intended
+ to be used for testing purposes, to either test payloads or libpayload itself.
+ It provides necessary headers, but requires mocking (providing implementation
+ for) arch-specific functions.
+
endchoice
config MULTIBOOT
@@ -150,6 +158,7 @@ config BASE_ADDRESS
default 0x04000000 if ARCH_ARM
default 0x80100000 if ARCH_ARM64
default 0x00100000 if ARCH_X86
+ default 0x00000000 if ARCH_MOCK
help
This is the base address for the payload.
@@ -480,3 +489,4 @@ config IO_ADDRESS_SPACE
source "arch/arm/Kconfig"
source "arch/arm64/Kconfig"
source "arch/x86/Kconfig"
+source "arch/mock/Kconfig"
diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile
index 90f6b23836..923106248c 100644
--- a/payloads/libpayload/Makefile
+++ b/payloads/libpayload/Makefile
@@ -74,6 +74,14 @@ HOSTCC = gcc
HOSTCXX = g++
HOSTCFLAGS := -I$(srck) -I$(objk) -g
HOSTCXXFLAGS := -I$(srck) -I$(objk)
+HOSTAS ?= as
+HOSTLD ?= ld
+HOSTNM ?= nm
+HOSTOBJCOPY ?= objcopy
+HOSTOBJDUMP ?= objdump
+HOSTREADELF ?= readelf
+HOSTSTRIP ?= strip
+HOSTAR ?= ar
DOXYGEN := doxygen
DOXYGEN_OUTPUT_DIR := doxygen
@@ -95,6 +103,7 @@ include $(HAVE_DOTCONFIG)
ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm
ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64
ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86
+ARCHDIR-$(CONFIG_LP_ARCH_MOCK) := mock
ARCH-y := $(ARCHDIR-y)
@@ -103,6 +112,7 @@ ARCH-y := $(ARCHDIR-y)
ARCH-$(CONFIG_LP_ARCH_ARM) := arm
ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64
ARCH-$(CONFIG_LP_ARCH_X86) := x86_32
+ARCH-$(CONFIG_LP_ARCH_MOCK) := mock
# Three cases where we don't need fully populated $(obj) lists:
# 1. when no .config exists
@@ -129,6 +139,31 @@ real-all: config
else
+ifeq ($(CONFIG_LP_ARCH_MOCK),y)
+
+# Create empty xcompile to satisfy install script
+$(shell echo '' > $(xcompile))
+
+CC := $(HOSTCC)
+CC-mock := $(HOSTCC)
+AS := $(HOSTAS)
+AS-mock := $(HOSTAS)
+LD := $(HOSTLD)
+LD-mock := $(HOSTLD)
+NM := $(HOSTNM)
+NM-mock := $(HOSTNM)
+OBJCOPY := $(HOSTOBJCOPY)
+OBJCOPY-mock := $(HOSTOBJCOPY)
+OBJDUMP := $(HOSTOBJDUMP)
+OBJDUMP-mock := $(HOSTOBJDUMP)
+READELF := $(HOSTREADELF)
+READELF-mock := $(HOSTEADELF)
+STRIP := $(HOSTSTRIP)
+STRIP-mock := $(HOSTSTRIP)
+AR := $(HOSTAR)
+AR-mock := $(HOSTAR)
+else
+
# in addition to the dependency below, create the file if it doesn't exist
# to silence stupid warnings about a file that would be generated anyway.
$(if $(wildcard $(xcompile)),,$(shell \
@@ -152,12 +187,16 @@ OBJDUMP := $(OBJDUMP_$(ARCH-y))
READELF := $(READELF_$(ARCH-y))
STRIP := $(STRIP_$(ARCH-y))
AR := $(AR_$(ARCH-y))
+endif
CFLAGS += -std=gnu11 $(CFLAGS_$(ARCH-y))
ifneq ($(INNER_SCANBUILD),y)
ifeq ($(CONFIG_LP_COMPILER_LLVM_CLANG),y)
-CC:=clang -m32
+CC:=clang
+ifneq ($(CONFIG_LP_ARCH_MOCK),y)
+CC += -m32
+endif
HOSTCC:=clang
endif
endif
diff --git a/payloads/libpayload/Makefile.inc b/payloads/libpayload/Makefile.inc
index a67ba77b67..df0f14298f 100644
--- a/payloads/libpayload/Makefile.inc
+++ b/payloads/libpayload/Makefile.inc
@@ -33,6 +33,7 @@ export KERNELVERSION := 0.2.0
ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm
ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64
ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86
+ARCHDIR-$(CONFIG_LP_ARCH_MOCK) := mock
DESTDIR ?= install
real-target: lib
diff --git a/payloads/libpayload/arch/mock/Kconfig b/payloads/libpayload/arch/mock/Kconfig
new file mode 100644
index 0000000000..3903a76005
--- /dev/null
+++ b/payloads/libpayload/arch/mock/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+if ARCH_MOCK
+
+config ARCH_MOCK_BIG_ENDIAN
+ bool "Use big-endian for mock architecture"
+ default n
+ help
+ This option enables big-endinan support in the code.
+
+config ARCH_SPECIFIC_OPTIONS
+ def_bool y
+ select LITTLE_ENDIAN if !ARCH_MOCK_BIG_ENDIAN
+ select BIG_ENDIAN if ARCH_MOCK_BIG_ENDIAN
+
+endif
diff --git a/payloads/libpayload/arch/mock/Makefile.inc b/payloads/libpayload/arch/mock/Makefile.inc
new file mode 100644
index 0000000000..f15f0f9f1d
--- /dev/null
+++ b/payloads/libpayload/arch/mock/Makefile.inc
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+head.o-y += head.c
+
+libc-y += virtual.c
+
+libcbfs-$(CONFIG_LP_CBFS) += mock_media.c
diff --git a/payloads/libpayload/arch/mock/head.c b/payloads/libpayload/arch/mock/head.c
new file mode 100644
index 0000000000..55a691f910
--- /dev/null
+++ b/payloads/libpayload/arch/mock/head.c
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* This file is empty on purpose. It should not be used. */
diff --git a/payloads/libpayload/arch/mock/libpayload.ldscript b/payloads/libpayload/arch/mock/libpayload.ldscript
new file mode 100644
index 0000000000..6842c9ad5c
--- /dev/null
+++ b/payloads/libpayload/arch/mock/libpayload.ldscript
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* This file is empty on purpose. It is present only to satisfy install script */
diff --git a/payloads/libpayload/arch/mock/mock_media.c b/payloads/libpayload/arch/mock/mock_media.c
new file mode 100644
index 0000000000..2bb06edc29
--- /dev/null
+++ b/payloads/libpayload/arch/mock/mock_media.c
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <cbfs.h>
+
+int libpayload_init_default_cbfs_media(struct cbfs_media *media);
+
+__attribute__((weak)) int libpayload_init_default_cbfs_media(struct cbfs_media *media)
+{
+ return -1;
+}
diff --git a/payloads/libpayload/arch/mock/virtual.c b/payloads/libpayload/arch/mock/virtual.c
new file mode 100644
index 0000000000..6f369d2dcb
--- /dev/null
+++ b/payloads/libpayload/arch/mock/virtual.c
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <unistd.h>
+
+unsigned long virtual_offset = 0;
+
+int getpagesize(void)
+{
+ return 4096;
+}
diff --git a/payloads/libpayload/bin/lpgcc b/payloads/libpayload/bin/lpgcc
index c0fe56adf5..3a76f13d17 100755
--- a/payloads/libpayload/bin/lpgcc
+++ b/payloads/libpayload/bin/lpgcc
@@ -91,13 +91,24 @@ if [ "$CONFIG_LP_ARCH_X86" = "y" ]; then
_ARCHEXTRA="-m32 "
_ARCH=x86
fi
+if [ "$CONFIG_LP_ARCH_MOCK" = "y" ]; then
+ _ARCHINCDIR=$_INCDIR/mock
+ _ARCHLIBDIR=$_LIBDIR/mock
+ _ARCHEXTRA=""
+ _ARCH=mock
+fi
if [ -f $_LIBDIR/libpayload.ldscript ]; then
_LDDIR=$_LIBDIR
elif [ -f $BASE/../arch/$_ARCH/libpayload.ldscript ]; then
_LDDIR=$BASE/../arch/$_ARCH
fi
-_LDSCRIPT="-Wl,-T,$_LDDIR/libpayload.ldscript"
+# Host arch should youse default linker script
+if [ "$CONFIG_LP_ARCH_MOCK" = "y" ]; then
+ _LDSCRIPT=""
+else
+ _LDSCRIPT="-Wl,-T,$_LDDIR/libpayload.ldscript"
+fi
trygccoption() {
$DEFAULT_CC $1 -S -xc /dev/null -o /dev/null &> /dev/null
diff --git a/payloads/libpayload/include/mock/arch/barrier.h b/payloads/libpayload/include/mock/arch/barrier.h
new file mode 100644
index 0000000000..aed115bb64
--- /dev/null
+++ b/payloads/libpayload/include/mock/arch/barrier.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ARCH_BARRIER_H__
+#define __ARCH_BARRIER_H__
+
+/* No memory barrier on mock build */
+#define mb()
+/* No read memory barrier on mock build */
+#define rmb()
+/* No write memory barrier on mock build */
+#define wmb()
+
+#endif /* __ARCH_BARRIER_H__ */
diff --git a/payloads/libpayload/include/mock/arch/cache.h b/payloads/libpayload/include/mock/arch/cache.h
new file mode 100644
index 0000000000..1e71d5e0e2
--- /dev/null
+++ b/payloads/libpayload/include/mock/arch/cache.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ARCH_CACHE_H__
+#define __ARCH_CACHE_H__
+
+/* No support for cache in the mock architecture */
+
+#define dmb()
+#define dsb()
+#define dcache_clean_all()
+#define dcache_clean_by_mva(addr, len)
+#define dcache_invalidate_all()
+#define dcache_invalidate_by_mva(addr, len)
+#define dcache_clean_invalidate_all()
+#define dcache_clean_invalidate_by_mva(addr, len)
+#define cache_sync_instructions()
+
+#endif /* __ARCH_CACHE_H__ */
diff --git a/payloads/libpayload/include/mock/arch/io.h b/payloads/libpayload/include/mock/arch/io.h
new file mode 100644
index 0000000000..2bb625562e
--- /dev/null
+++ b/payloads/libpayload/include/mock/arch/io.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _ARCH_IO_H
+#define _ARCH_IO_H
+
+#include <inttypes.h>
+
+/* Functions in this file are unimplemented by default. Tests are expected to implement
+ mocks for these functions, if tests will call functions using functions listed below. */
+
+uint8_t readb(volatile const void *_a);
+uint16_t readw(volatile const void *_a);
+uint32_t readl(volatile const void *_a);
+
+void writeb(uint8_t _v, volatile void *_a);
+void writew(uint16_t _v, volatile void *_a);
+void writel(uint32_t _v, volatile void *_a);
+
+uint8_t read8(volatile const void *addr);
+uint16_t read16(volatile const void *addr);
+uint32_t read32(volatile const void *addr);
+uint64_t read64(volatile const void *addr);
+
+void write8(volatile void *addr, uint8_t val);
+void write16(volatile void *addr, uint16_t val);
+void write32(volatile void *addr, uint32_t val);
+void write64(volatile void *addr, uint64_t val);
+
+#endif /* _ARCH_IO_H */
diff --git a/payloads/libpayload/include/mock/arch/types.h b/payloads/libpayload/include/mock/arch/types.h
new file mode 100644
index 0000000000..8f090caa9b
--- /dev/null
+++ b/payloads/libpayload/include/mock/arch/types.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _ARCH_TYPES_H
+#define _ARCH_TYPES_H
+
+typedef unsigned char uint8_t;
+typedef unsigned char u8;
+typedef signed char int8_t;
+typedef signed char s8;
+
+typedef unsigned short uint16_t;
+typedef unsigned short u16;
+typedef signed short int16_t;
+typedef signed short s16;
+
+typedef unsigned int uint32_t;
+typedef unsigned int u32;
+typedef signed int int32_t;
+typedef signed int s32;
+
+typedef unsigned long long uint64_t;
+typedef unsigned long long u64;
+typedef signed long long int64_t;
+typedef signed long long s64;
+
+typedef long time_t;
+typedef long suseconds_t;
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#endif /* _ARCH_TYPES_H */
diff --git a/payloads/libpayload/include/mock/arch/virtual.h b/payloads/libpayload/include/mock/arch/virtual.h
new file mode 100644
index 0000000000..bf786d5256
--- /dev/null
+++ b/payloads/libpayload/include/mock/arch/virtual.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _ARCH_VIRTUAL_H
+#define _ARCH_VIRTUAL_H
+
+/* virtual_offset has to be declared if used */
+extern unsigned long virtual_offset;
+
+#define virt_to_phys(virt) ((unsigned long)(virt) + virtual_offset)
+#define phys_to_virt(phys) ((void *)((unsigned long)(phys) - virtual_offset))
+
+#define virt_to_bus(addr) virt_to_phys(addr)
+#define bus_to_virt(addr) phys_to_virt(addr)
+
+#endif
diff --git a/payloads/libpayload/sample/Makefile b/payloads/libpayload/sample/Makefile
index 637e45dee1..1249e9a017 100644
--- a/payloads/libpayload/sample/Makefile
+++ b/payloads/libpayload/sample/Makefile
@@ -26,8 +26,13 @@
## SUCH DAMAGE.
##
+
# Sample libpayload Makefile.
include ../.config
+ifeq ($(CONFIG_LP_ARCH_MOCK),y)
+$(error This sample program does not support ARCH_MOCK. Use sample/arch_mock instead)
+endif
+
include ../build/xcompile
ARCH-$(CONFIG_LP_ARCH_ARM) := arm
diff --git a/payloads/libpayload/sample/arch_mock/Makefile b/payloads/libpayload/sample/arch_mock/Makefile
new file mode 100644
index 0000000000..a1e748111e
--- /dev/null
+++ b/payloads/libpayload/sample/arch_mock/Makefile
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Sample libpayload Makefile for ARCH_MOCK
+# ARCH_MOCK is not intended to be used with xcompile
+include ../../.config
+
+ifneq ($(CONFIG_LP_ARCH_MOCK),y)
+$(error This example supports ARCH_MOCK only.)
+endif
+
+CC := gcc
+AS := as
+OBJCOPY := objcopy
+LIBPAYLOAD_DIR := ../../install/libpayload
+CFLAGS := -fno-builtin -Wall -Werror -Os \
+ -include $(LIBPAYLOAD_DIR)/include/kconfig.h \
+ -include $(LIBPAYLOAD_DIR)/include/compiler.h \
+ -I $(LIBPAYLOAD_DIR)/include \
+ -I $(LIBPAYLOAD_DIR)/include/mock \
+ -ffunction-sections \
+ -fdata-sections -g3
+LDFLAGS := -Wl,--gc-sections
+TARGET := hello
+OBJS := $(TARGET).o
+OBJS-mock := $(TARGET)_mocks.o
+LIBPAYLOAD-local := libpayload.a
+mocks := console_write
+
+all: $(TARGET).elf
+
+$(TARGET).elf: $(OBJS) $(OBJS-mock) $(LIBPAYLOAD-local)
+ $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBPAYLOAD-local) \
+ -Wl,--exclude-libs,ALL -lc $(OBJS-mock)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+%.S.o: %.S
+ $(AS) --32 -o $@ $<
+
+# Copy libpayload and weaken all mocked symbols
+$(LIBPAYLOAD-local): $(LIBPAYLOAD_DIR)/lib/libpayload.a
+ $(OBJCOPY) $(foreach mock,$(mocks),--weaken-symbol=$(mock)) $< $@
+
+clean:
+ rm -f $(TARGET).elf *.o $(LIBPAYLOAD-local)
+
+distclean: clean
diff --git a/payloads/libpayload/sample/arch_mock/hello.c b/payloads/libpayload/sample/arch_mock/hello.c
new file mode 100644
index 0000000000..5a96e42e75
--- /dev/null
+++ b/payloads/libpayload/sample/arch_mock/hello.c
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* Example file for libpayload. */
+
+#include <libpayload-config.h>
+#include <libpayload.h>
+
+int main(void)
+{
+ printf("Hello world!\n");
+ halt();
+ return 0;
+}
diff --git a/payloads/libpayload/sample/arch_mock/hello_mocks.c b/payloads/libpayload/sample/arch_mock/hello_mocks.c
new file mode 100644
index 0000000000..84e86ff257
--- /dev/null
+++ b/payloads/libpayload/sample/arch_mock/hello_mocks.c
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <libpayload-config.h>
+#include <arch/types.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdio.h>
+
+/* Use libc version. calling exit() or abort() would cause infinite recursion */
+__attribute__((noreturn))
+void _exit(int);
+
+__attribute__((noreturn))
+void halt(void)
+{
+ _exit(0);
+}
+
+#define TEST_SYMBOL(symbol, value) asm(".set " #symbol ", " #value "\n\t.globl " #symbol)
+
+#define TEST_REGION(region, size) uint8_t _##region[size]; \
+ TEST_SYMBOL(_e##region, _##region + size); \
+ TEST_SYMBOL(_##region##_size, size)
+
+TEST_REGION(heap, CONFIG_LP_HEAP_SIZE);
+
+uint64_t timer_raw_value(void)
+{
+ return 0;
+}
+
+uint64_t timer_hz(void)
+{
+ return 0;
+}
+
+/* Not present in libpayload. Can be used to write to real stdout. */
+ssize_t write(int fildes, const void *buf, size_t nbyte);
+
+void console_write(const void *buffer, size_t count)
+{
+ write(1, buffer, count);
+}