diff --git a/Ubiquitous/XiZi_AIoT/.config b/Ubiquitous/XiZi_AIoT/.config new file mode 100644 index 000000000..307c2f4c0 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/.config @@ -0,0 +1,18 @@ +# +# Automatically generated file; DO NOT EDIT. +# XiZi_AIoT Project Configuration +# +CONFIG_BOARD_IMX6Q_SABRELITE_EVB=y +CONFIG_ARCH_ARM=y + +# +# imx6q sabrelite feature +# + +# +# Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y +# CONFIG_LIB_MUSLLIB is not set diff --git a/Ubiquitous/XiZi_AIoT/Kconfig b/Ubiquitous/XiZi_AIoT/Kconfig index e69de29bb..41ca9e96c 100644 --- a/Ubiquitous/XiZi_AIoT/Kconfig +++ b/Ubiquitous/XiZi_AIoT/Kconfig @@ -0,0 +1,6 @@ + +source "$KERNEL_DIR/services/Kconfig" +source "$KERNEL_DIR/softkernel/Kconfig" +source "$KERNEL_DIR/support/Kconfig" +source "$KERNEL_DIR/testing/Kconfig" + diff --git a/Ubiquitous/XiZi_AIoT/Makefile b/Ubiquitous/XiZi_AIoT/Makefile index e69de29bb..dfe98fe0d 100755 --- a/Ubiquitous/XiZi_AIoT/Makefile +++ b/Ubiquitous/XiZi_AIoT/Makefile @@ -0,0 +1,144 @@ +MAKEFLAGS += --no-print-directory + +.PHONY:all clean distclean show_info menuconfig +.PHONY:COMPILE_APP COMPILE_KERNEL + +riscv_support := +arm_support += imx6q-sabrelite +emulator_support += +support := $(riscv_support) $(arm_support) $(emulator_support) +SRC_DIR := + +export BOARD ?=imx6q-sabrelite +# This is the environment variable for kconfig-mconf +export KCONFIG_CONFIG ?= .config + +ifeq ($(filter $(BOARD),$(support)),) +$(warning "You should choose board like this: make BOARD=imx6q-sabrelite") +$(warning "This is what we support:") +$(warning "RISCV EVB: $(riscv_support)") +$(warning "ARM EVB: $(arm_support)") +$(warning "EMULATORS: $(emulator_support)") +# $(warning "$(support)") +$(error "break" ) +endif + +export TARGET +export COMPILE_TYPE +export KERNEL_ROOT ?=$(strip $(shell pwd)) + +MAKEFILES =$(KERNEL_ROOT)/.config +-include $(KERNEL_ROOT)/.config + +export BSP_ROOT ?= $(KERNEL_ROOT)/services/boards/$(BOARD) +export UBIQUITOUS_ROOT ?= .. +include services/boards/$(BOARD)/config.mk +export BSP_BUILD_DIR := boards/$(BOARD) +export HOSTTOOLS_DIR ?= $(KERNEL_ROOT)/services/tools/hosttools +export CONFIG2H_EXE ?= $(HOSTTOOLS_DIR)/xsconfig.sh + +export CPPPATHS +export SRC_APP_DIR := ../../APP_Framework +export SRC_KERNEL_DIR := hardkernel services softkernel support testing +# export SRC_DIR:= $(SRC_APP_DIR) $(SRC_KERNEL_DIR) +export SRC_DIR:= $(SRC_KERNEL_DIR) +export LIBCC +export MUSL_DIR := $(KERNEL_ROOT)/services/lib/musllib + +PART:= + +all: +ifeq ($(CONFIG_COMPILER_APP)_$(CONFIG_COMPILER_KERNEL),y_) +PART += COMPILE_APP + +else ifeq ($(CONFIG_COMPILER_APP)_$(CONFIG_COMPILER_KERNEL),_y) +PART += COMPILE_KERNEL + +else ifeq ($(CONFIG_COMPILER_APP)_$(CONFIG_COMPILER_KERNEL),y_y) +PART := COMPILE_APP COMPILE_KERNEL + +else + +ifeq ($(CONFIG_LIB_MUSLLIB), y) +PART += COMPILE_MUSL +endif + +PART += COMPILE_ALL +endif + + +all: $(PART) + + +COMPILE_ALL: + @for dir in $(SRC_DIR);do \ + $(MAKE) -C $$dir; \ + done + @cp link.mk build/Makefile + @$(MAKE) -C build TARGET=XiZi-$(BOARD).elf LINK_FLAGS=LFLAGS + @rm build/Makefile build/make.obj + +COMPILE_MUSL: + @for dir in $(MUSL_DIR);do \ + $(MAKE) -C $$dir COMPILE_TYPE=$@ CONFIG_RESOURCES_LWIP=n; \ + done + @cp link_libc.mk build/Makefile + @$(MAKE) -C build TARGET=libmusl.a LINK_FLAGS=LFLAGS + @cp build/libmusl.a $(KERNEL_ROOT)/lib/musllib/libmusl.a + @rm build/Makefile build/make.obj + +COMPILE_KERNEL: + @for dir in $(SRC_KERNEL_DIR);do \ + $(MAKE) -C $$dir; \ + done + @cp link.mk build/Makefile + @$(MAKE) -C build COMPILE_TYPE="_kernel" TARGET=XiZi-$(BOARD)_kernel.elf LINK_FLAGS=LFLAGS + @rm build/Makefile build/make.obj + +COMPILE_APP: + @echo $(SRC_APP_DIR) + @for dir in $(SRC_APP_DIR);do \ + $(MAKE) -C $$dir USE_APP_INCLUDEPATH=y; \ + done + @cp link.mk build/Makefile + @$(MAKE) -C build COMPILE_TYPE="_app" TARGET=XiZi-$(BOARD)_app.elf LINK_FLAGS=APPLFLAGS + @rm build/Makefile build/make.obj + +show_info: + @echo "CONFIG_COMPILER_APP is :" $(CONFIG_COMPILER_APP) + @echo "CONFIG_COMPILER_KERNEL is :" $(CONFIG_COMPILER_KERNEL) + @echo "KERNELPATHS is :" $(KERNELPATHS) + @echo "TARGET is :" $(TARGET) + @echo "VPATH is :" $(VPATH) + @echo "BSP_ROOT is :" $(BSP_ROOT) + @echo "KERNEL_ROOT is :" $(KERNEL_ROOT) + @echo "CPPPATHS is :" $(CPPPATHS) + @echo "SRC_DIR is :" $(SRC_DIR) + @echo "BUILD_DIR is :" $(BUILD_DIR) + @echo "BSP_BUILD_DIR is :" $(BSP_BUILD_DIR) + @echo "OBJS is :" $(OBJS) + @for f in $(CPPPATHS); do \ + echo $$f; \ + done + +menuconfig: + @if [ -f "$(BSP_ROOT)/.config" ]; then \ + cp $(BSP_ROOT)/.config $(KERNEL_ROOT)/.config; \ + else if [ -f "$(BSP_ROOT)/.defconfig" ]; then \ + cp $(BSP_ROOT)/.defconfig $(KERNEL_ROOT)/.config ;\ + fi ;fi + @kconfig-mconf $(BSP_ROOT)/Kconfig + @$(CONFIG2H_EXE) .config + @cp $(KERNEL_ROOT)/.config $(BSP_ROOT)/.config + +clean: + @echo Clean target and build_dir + @rm -rf build + @rm -rf temp.txt + +distclean: + @echo Clean all configuration + @make clean + @rm -f .config* + @rm -f $(KERNEL_ROOT)/lib/musllib/libmusl.a + @rm -f $(KERNEL_ROOT)/board/*/.config diff --git a/Ubiquitous/XiZi_AIoT/compiler.mk b/Ubiquitous/XiZi_AIoT/compiler.mk new file mode 100644 index 000000000..f217a06b0 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/compiler.mk @@ -0,0 +1,127 @@ +ifeq ($(COMPILE_TYPE), COMPILE_MUSL) +SRC_DIR_TEMP := $(MUSL_DIR) +else ifeq ($(COMPILE_TYPE), COMPILE_LWIP) +SRC_DIR_TEMP := $(LWIP_DIR) +else +SRC_DIR_TEMP := $(SRC_DIR) +endif + +SRC_DIR := +MUSL_DIR := +LWIP_DIR := + +ifeq ($(USE_APP_INCLUDEPATH), y) + include $(KERNEL_ROOT)/path_app.mk +else + include $(KERNEL_ROOT)/path_kernel.mk +endif +export CPPPATHS := $(KERNELPATHS) + +CUR_DIR :=$(shell pwd) + +CFLAGS += $(CPPPATHS) +AFLAGS += $(CPPPATHS) +CXXFLAGS += $(CPPPATHS) + +CFLAGS += $(DEFINES) +AFLAGS += $(DEFINES) +CXXFLAGS += $(DEFINES) +BUILD_DIR := $(KERNEL_ROOT)/build +APP_DIR := Ubiquitous/XiZi + + +.PHONY:COMPILER +COMPILER: + @if [ "${SRC_DIR_TEMP}" != "" ]; then \ + for dir in $(SRC_DIR_TEMP);do \ + $(MAKE) -C $$dir; \ + done; \ + fi + @/bin/echo -n $(OBJS) " " >> $(KERNEL_ROOT)/build/make.obj + + +################################################ +define add_c_file +$(eval COBJ := $(1:%.c=%.o)) \ +$(eval COBJ := $(subst $(subst $(APP_DIR),,$(KERNEL_ROOT)),,$(COBJ))) \ +$(eval LOCALC := $(addprefix $(BUILD_DIR)/,$(COBJ))) \ +$(eval OBJS += $(LOCALC)) \ +$(if $(strip $(LOCALC)),$(eval $(LOCALC): $(1) + @if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi + @echo cc $$< + @/bin/echo -n $(dir $(LOCALC)) >>$(KERNEL_ROOT)/build/make.dep + @($(CROSS_COMPILE)gcc -MM $$(CFLAGS) -c $$<) >>$(KERNEL_ROOT)/build/make.dep + @$(CROSS_COMPILE)gcc $$(CFLAGS) -c $$< -o $$@)) +endef + +define add_cpp_file +$(eval COBJ := $(1:%.cpp=%.o)) \ +$(eval COBJ := $(subst $(subst $(APP_DIR),,$(KERNEL_ROOT)),,$(COBJ))) \ +$(eval LOCALCPP := $(addprefix $(BUILD_DIR)/,$(COBJ))) \ +$(eval OBJS += $(LOCALCPP)) \ +$(if $(strip $(LOCALCPP)),$(eval $(LOCALCPP): $(1) + @if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi + @echo cc $$< + @/bin/echo -n $(dir $(LOCALCPP)) >>$(KERNEL_ROOT)/build/make.dep + @$(CROSS_COMPILE)g++ -MM $$(CXXFLAGS) -c $$< >>$(KERNEL_ROOT)/build/make.dep + @$(CROSS_COMPILE)g++ $$(CXXFLAGS) -c $$< -o $$@)) +endef + +define add_cc_file +$(eval COBJ := $(1:%.cc=%.o)) \ +$(eval COBJ := $(subst $(subst $(APP_DIR),,$(KERNEL_ROOT)),,$(COBJ))) \ +$(eval LOCALCPP := $(addprefix $(BUILD_DIR)/,$(COBJ))) \ +$(eval OBJS += $(LOCALCPP)) \ +$(if $(strip $(LOCALCPP)),$(eval $(LOCALCPP): $(1) + @if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi + @echo cc $$< + @/bin/echo -n $(dir $(LOCALCPP)) >>$(KERNEL_ROOT)/build/make.dep + @$(CROSS_COMPILE)g++ -MM $$(CXXFLAGS) -c $$< >>$(KERNEL_ROOT)/build/make.dep + @$(CROSS_COMPILE)g++ $$(CXXFLAGS) -c $$< -o $$@)) +endef + +define add_S_file +$(eval SOBJ := $(1:%.S=%.o)) \ +$(eval SOBJ := $(subst $(subst $(APP_DIR),,$(KERNEL_ROOT)),,$(SOBJ))) \ +$(eval LOCALS := $(addprefix $(BUILD_DIR)/,$(SOBJ))) \ +$(eval OBJS += $(LOCALS)) \ +$(if $(strip $(LOCALS)),$(eval $(LOCALS): $(1) + @if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi + @echo cc $$< + @/bin/echo -n $(dir $(LOCALC)) >>$(KERNEL_ROOT)/build/make.dep + @$(CROSS_COMPILE)gcc -MM $$(CFLAGS) -c $$< >>$(KERNEL_ROOT)/build/make.dep + @$(CROSS_COMPILE)gcc $$(AFLAGS) -c $$< -o $$@)) +endef + +define add_a_file +$(eval SOBJ := $(1:%.a=%.a)) \ +$(eval SOBJ := $(subst $(subst $(APP_DIR),,$(KERNEL_ROOT)),,$(SOBJ))) \ +$(eval LOCALA := $(addprefix $(BUILD_DIR)/,$(SOBJ))) \ +$(eval OBJS += $(LOCALA)) \ +$(if $(strip $(LOCALA)),$(eval $(LOCALA): $(1) + @if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi + @echo cp $$< + @cp $$< $$@)) +endef + + +SRCS := $(strip $(filter %.c,$(SRC_FILES))) +$(if $(SRCS),$(foreach f,$(SRCS),$(call add_c_file,$(addprefix $(CUR_DIR)/,$(f))))) + +SRCS := $(strip $(filter %.cpp,$(SRC_FILES))) +$(if $(SRCS),$(foreach f,$(SRCS),$(call add_cpp_file,$(addprefix $(CUR_DIR)/,$(f))))) + +SRCS := $(strip $(filter %.cc,$(SRC_FILES))) +$(if $(SRCS),$(foreach f,$(SRCS),$(call add_cc_file,$(addprefix $(CUR_DIR)/,$(f))))) + +SRCS := $(strip $(filter %.S,$(SRC_FILES))) +$(if $(SRCS),$(foreach f,$(SRCS),$(call add_S_file,$(addprefix $(CUR_DIR)/,$(f))))) + +SRCS := $(strip $(filter %.a,$(SRC_FILES))) +$(if $(SRCS),$(foreach f,$(SRCS),$(call add_a_file,$(addprefix $(CUR_DIR)/,$(f))))) + +COMPILER:$(OBJS) + + + +-include $(KERNEL_ROOT)/build/make.dep diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/Makefile new file mode 100644 index 000000000..f4c927675 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := arch abstraction + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/Makefile new file mode 100644 index 000000000..262587f99 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := cache.c isr.c mmu.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/isr.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/isr.c new file mode 100644 index 000000000..54804bfac --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/isr.c @@ -0,0 +1,215 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: isr.c +* @brief: the general management of system isr +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2020/3/15 +* +*/ +#include +#include "isr.h" + +struct InterruptServiceRoutines isrManager = {0} ; + +#ifdef ARCH_SMP +extern int GetCpuId(void); +#endif +/** + * This functionwill get the isr nest level. + * + * @return isr nest level + */ +static uint16_t GetIsrCounter() +{ + uint16_t ret = 0; + +#ifdef ARCH_SMP + ret = isrManager.isr_count[GetCpuId()]; +#else + ret = isrManager.isr_count; +#endif + return ret; +} + +static void IncIsrCounter() +{ +#ifdef ARCH_SMP + isrManager.isr_count[GetCpuId()] ++ ; +#else + isrManager.isr_count ++; +#endif + return ; +} + +static void DecIsrCounter() +{ + +#ifdef ARCH_SMP + isrManager.isr_count[GetCpuId()] -- ; +#else + isrManager.isr_count --; +#endif + return ; +} + +bool IsInIsr() +{ +#ifdef ARCH_SMP + return ( isrManager.isr_count[GetCpuId()] != 0 ? TRUE : FALSE ) ; +#else + return ( isrManager.isr_count != 0 ? TRUE : FALSE ) ; +#endif + +} +/** + * This function will register a new irq. + * + * @param irq_num the number of the irq + * @param handler the callback of the interrupt + * @param arg param of thge callback + * + * @return 0 on success; -1 on failure + */ +static int32_t RegisterHwIrq(uint32_t irq_num, IsrHandlerType handler, void *arg) +{ + if (irq_num >= ARCH_MAX_IRQ_NUM ) + return -1; + + struct IrqDesc *desc = &isrManager.irq_table[irq_num]; + + desc->handler = handler; + desc->param = arg; + + return 0; +} +/** + * This function will free a irq. + * + * @param irq_num the number of the irq + * + * @return 0 on success; -1 on failure + */ +static int32_t FreeHwIrq(uint32_t irq_num) +{ + if (irq_num >= ARCH_MAX_IRQ_NUM ) + return -1; + + memset(&isrManager.irq_table[irq_num], 0, sizeof(struct IrqDesc)); + + return 0; +} + +/** + * This function will enable a irq. + * + * @param irq_num the number of the irq + * + * @return 0 on success; -1 on failure + */ +static int32_t EnableHwIrq(uint32_t irq_num) +{ + if (irq_num >= ARCH_MAX_IRQ_NUM ) + return -1; + + return ArchEnableHwIrq(irq_num); +} +/** + * This function will disable a irq. + * + * @param irq_num the number of the irq + * + * @return 0 on success; -1 on failure + */ + +static int32_t DisableHwIrq(uint32_t irq_num) +{ + if (irq_num >= ARCH_MAX_IRQ_NUM ) + return -1; + + return ArchDisableHwIrq(irq_num); +} + +/* called from arch-specific ISR wrapper */ +static void IsrCommon(uint32_t irq_num) +{ + struct IrqDesc *desc = &isrManager.irq_table[irq_num]; + + if (desc->handler == NULL) { + // SYS_KDEBUG_LOG(KDBG_IRQ, ("Spurious interrupt: IRQ No. %d\n", irq_num)); + while (1) {} + } + desc->handler(irq_num, desc->param); + +} + +static void SetIsrSwitchTrigerFlag() +{ + +#ifdef ARCH_SMP + isrManager.isr_switch_trigger_flag[GetCpuId()] = 1; +#else + isrManager.isr_switch_trigger_flag = 1; +#endif +} + +static void ClearIsrSwitchTrigerFlag() +{ + +#ifdef ARCH_SMP + isrManager.isr_switch_trigger_flag[GetCpuId()] = 0; +#else + isrManager.isr_switch_trigger_flag = 0; +#endif +} + +static uint8_t GetIsrSwitchTrigerFlag() +{ + +#ifdef ARCH_SMP + return isrManager.isr_switch_trigger_flag[GetCpuId()]; +#else + return isrManager.isr_switch_trigger_flag ; +#endif +} + +struct IsrDone isrDone = { + IsInIsr, + RegisterHwIrq , + FreeHwIrq, + EnableHwIrq, + DisableHwIrq, + IsrCommon, + GetIsrCounter, + IncIsrCounter, + DecIsrCounter, + GetIsrSwitchTrigerFlag, + SetIsrSwitchTrigerFlag, + ClearIsrSwitchTrigerFlag +}; + +void SysInitIsrManager() +{ + extern int __isrtbl_idx_start; + extern int __isrtbl_start; + extern int __isrtbl_end; + memset(&isrManager,0,sizeof(struct InterruptServiceRoutines)); + isrManager.done = &isrDone; + + uint32_t *index = (uint32_t *)&__isrtbl_idx_start; + struct IrqDesc *desc = (struct IrqDesc *)&__isrtbl_start; + + while (desc != (struct IrqDesc *)&__isrtbl_end) + isrManager.irq_table[*index++] = *desc++; +} diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/isr.h b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/isr.h new file mode 100644 index 000000000..584e9b578 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/isr.h @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: isr.h +* @brief: function declaration and structure defintion of isr +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2020/3/10 +* +*/ + +#ifndef __ISR_H__ +#define __ISR_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define DECLARE_HW_IRQ(_irq_num, _handler, _arg) \ + const uint32_t __irq_desc_idx_##_handler SECTION(".isrtbl.idx") = _irq_num + ARCH_IRQ_NUM_OFFSET ; \ + const struct IrqDesc __irq_desc_##_handler SECTION(".isrtbl") = { \ + .handler = _handler, \ + .param = _arg, \ + } + +typedef void (*IsrHandlerType)(int vector, void *param); + +struct IrqDesc +{ + IsrHandlerType handler; + void *param; + +#ifdef CONFIG_INTERRUPT_INFO + char name[NAME_NUM_MAX]; + uint32_t counter; +#endif +}; + +struct IsrDone +{ + bool (*isInIsr)(); + int32_t (*registerIrq)(uint32_t irq_num, IsrHandlerType handler, void *arg); + int32_t (*freeIrq)(uint32_t irq_num); + int32_t (*enableIrq)(uint32_t irq_num); + int32_t (*disableIrq)(uint32_t irq_num); + void (*handleIrq)(uint32_t irq_num); + uint16_t (*getCounter)() ; + void (*incCounter)(); + void (*decCounter)(); + uint8_t (*getSwitchTrigerFlag)(); + void (*setSwitchTrigerFlag)(); + void (*clearSwitchTrigerFlag)(); +}; + +struct InterruptServiceRoutines { + +#ifdef ARCH_SMP + volatile uint16_t isr_count[CPU_NUMBERS]; + volatile uint8_t isr_switch_trigger_flag[CPU_NUMBERS]; +#else + volatile uint16_t isr_count ; + volatile uint8_t isr_switch_trigger_flag; +#endif + struct IrqDesc irq_table[ARCH_MAX_IRQ_NUM]; + struct IsrDone *done; +}; + +extern struct InterruptServiceRoutines isrManager ; + +uint32_t DisableLocalInterrupt(); +void EnableLocalInterrupt(unsigned long level); + +#define DISABLE_INTERRUPT DisableLocalInterrupt +#define ENABLE_INTERRUPT EnableLocalInterrupt + +void SysInitIsrManager(); +void InitHwinterrupt(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/Kconfig b/Ubiquitous/XiZi_AIoT/hardkernel/arch/Kconfig new file mode 100644 index 000000000..42e27ec53 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/Kconfig @@ -0,0 +1,13 @@ +config ARCH_CPU_64BIT + bool + +config ARCH_RISCV + bool + +config ARCH_ARM + bool + +config ARCH_RISCV64 + select ARCH_RISCV + select ARCH_CPU_64BIT + bool \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/arch/Makefile new file mode 100644 index 000000000..f629b85ec --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := $(ARCH) + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/Makefile new file mode 100644 index 000000000..c064ef38b --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/Makefile @@ -0,0 +1,4 @@ +# The following three platforms support compatiable instructions. +SRC_DIR := $(ARCH_ARMV) + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/Makefile new file mode 100644 index 000000000..ed2a80a34 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/Makefile @@ -0,0 +1,8 @@ +# The following three platforms support compatiable instructions. + +ifeq ($(CONFIG_BOARD_IMX6Q_SABRELITE_EVB),y) +SRC_DIR := cortex-a9 +endif + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/boot.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/boot.S index e69de29bb..95fdb6a2a 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/boot.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/boot.S @@ -0,0 +1,87 @@ + +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + +.equ STACK_SIZE, 0x00000100 + +.globl _start + +_start: + /* set the cpu to SVC32 mode and disable interrupt */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0x13 + msr cpsr_c, r0 + + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1 << 12) /* i cache */ + bic r0, #(1 << 2) /* d cache */ + bic r0, #(1 << 0) /* mmu */ + mcr p15, 0, r0, c1, c0, 0 + + ldr r0, =stack_top + + @ Set the startup stack for svc + mov sp, r0 + + @ Enter Undefined Instruction Mode and set its Stack Pointer + msr cpsr_c, #Mode_UND|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #STACK_SIZE + + @ Enter Abort Mode and set its Stack Pointer + msr cpsr_c, #Mode_ABT|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #STACK_SIZE + + @ Enter FIQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #STACK_SIZE + + @ Enter IRQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #STACK_SIZE + + /* come back to SVC mode */ + msr cpsr_c, #Mode_SVC|I_Bit|F_Bit + + /* clear .bss */ + mov r0, #0 /* get a zero */ + ldr r1,=BSS_START /* bss start */ + ldr r2,=BSS_END /* bss end */ + +bss_loop: + cmp r1,r2 /* check if data to clear */ + strlo r0,[r1],#4 /* clear 4 bytes */ + blo bss_loop /* loop until done */ + + /* call C++ constructors of global objects */ + ldr r0, =__ctors_start__ + ldr r1, =__ctors_end__ +bss_end: + +ctor_loop: + cmp r0, r1 + beq ctor_end + ldr r2, [r0], #4 + stmfd sp!, {r0-r1} + mov lr, pc + bx r2 + ldmfd sp!, {r0-r1} + b ctor_loop +ctor_end: + + bl start_kernel + +_loop_here: + b _loop_here \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/exception.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/exception.S index e69de29bb..c1c7f5a90 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/exception.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/exception.S @@ -0,0 +1,66 @@ +.section .vectors, "ax" +.code 32 + +.globl ExceptionVectors +ExceptionVectors: + ldr pc, _ResetException + ldr pc, _UndefInstrException + ldr pc, _SwiException + ldr pc, _PrefetchAbortException + ldr pc, _DataAbortAbortException + ldr pc, _ResvException + ldr pc, _IrqException + ldr pc, _FiqException + +.globl Reset_Handler +.globl UndefInstrExceptionHandle +.globl SwiExceptionHandle +.globl PrefetchAbortExceptionHandle +.globl DataAbortExceptionHandle +.globl ResvExceptionHandle +.globl ExceptionIsrEntry +.globl FiqExceptionHandle + +_ResetException: + .word Reset_Handler +_UndefInstrException: + .word UndefInstrExceptionHandle +_SwiException: + .word SwiExceptionHandle +_PrefetchAbortException: + .word PrefetchAbortExceptionHandle +_DataAbortAbortException: + .word DataAbortExceptionHandle +_ResvException: + .word ResvExceptionHandle +_IrqException: + .word ExceptionIsrEntry +_FiqException: + .word FiqExceptionHandle + +.globl _start +Reset_Handler: + b _start + +UndefInstrExceptionHandle: + b UndefInstrIsrEntry + +SwiExceptionHandle: + b SvcIsrEntry + +PrefetchAbortExceptionHandle: + b PrefetchAbortIsrEntry + +DataAbortExceptionHandle: + b UndefInstrIsrEntry + +ResvExceptionHandle: + b DataAbortIsrEntry + +ExceptionIsrEntry: + stmfd sp!, {r0-r12,lr} + + bl IsrEntry + +FiqExceptionHandle: + b FiqIsrEntry diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/Makefile new file mode 100644 index 000000000..7fc4ffac4 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := boot.S cache.S exception.S cortexA9.S gic.c interrupt.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/arch_interrupt.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/arch_interrupt.h new file mode 100644 index 000000000..b26d3e80c --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/arch_interrupt.h @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +#ifndef ARCH_INTERRUPT_H__ +#define ARCH_INTERRUPT_H__ + +#include +#include +#include "gic.h" + +#define ARCH_MAX_IRQ_NUM PLATFORM_MAX_IRQ_NR + +int32_t ArchEnableHwIrq(uint32_t irq_num); +int32_t ArchDisableHwIrq(uint32_t irq_num); + +//! @brief +typedef enum { + CPU_0, + CPU_1, + CPU_2, + CPU_3, +} cpuid_e; + +struct ExceptionStackRegister +{ + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t r13_sp; + uint32_t r14_lr; + uint32_t r15_pc; + uint32_t cpsr; +}; + +#endif diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/boot.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/boot.S index e69de29bb..49d0d456f 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/boot.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/boot.S @@ -0,0 +1,92 @@ +#include + +.global ExceptionVectors + +.section ".startup","ax" +.globl _reset + +_reset: + + /* set the cpu to SVC32 mode and disable interrupt */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0x13 + msr cpsr_c, r0 + + /* disable i/d cache mmu*/ + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1 << 12) /* i cache */ + bic r0, #(1 << 2) /* d cache */ + bic r0, #(1 << 0) /* mmu */ + mcr p15, 0, r0, c1, c0, 0 + + ldr r0, =stack_top + + @ Set the startup stack for svc + mov sp, r0 + + @ Enter Undefined Instruction Mode and set its Stack Pointer + msr cpsr_c, #MODE_UND|I_BIT|F_BIT + mov sp, r0 + sub r0, r0, #EXCEPTION_STACK_SIZE + + @ Enter Abort Mode and set its Stack Pointer + msr cpsr_c, #MODE_ABT|I_BIT|F_BIT + mov sp, r0 + sub r0, r0, #EXCEPTION_STACK_SIZE + + @ Enter FIQ Mode and set its Stack Pointer + msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT + mov sp, r0 + sub r0, r0, #EXCEPTION_STACK_SIZE + + @ Enter IRQ Mode and set its Stack Pointer + msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT + mov sp, r0 + sub r0, r0, #EXCEPTION_STACK_SIZE + + /* come back to SVC mode */ + msr cpsr_c, #MODE_SVC|I_BIT|F_BIT + + /* + * copy the vector table into the RAM vectors + * this assumes that the RAM vectors size is divisible by 3 words (12 bytes) + */ + ldr r1,=__ram_vectors_start + ldr r2,=__ram_vectors_end + ldr r3,=ExceptionVectors +1: cmp r1,r2 + ldmlt r3!,{r4,r5,r6} + stmlt r1!,{r4,r5,r6} + blt 1b + + /* clear .bss */ + mov r0, #0 /* get a zero */ + ldr r1,=__bss_start /* bss start */ + ldr r2,=__bss_end /* bss end */ + +bss_loop: + cmp r1,r2 /* check if data to clear */ + strlo r0,[r1],#4 /* clear 4 bytes */ + blo bss_loop /* loop until done */ + + /* call C++ constructors of global objects */ + ldr r0, =__ctors_start__ + ldr r1, =__ctors_end__ +bss_end: + +ctor_loop: + cmp r0, r1 + beq ctor_end + ldr r2, [r0], #4 + stmfd sp!, {r0-r1} + mov lr, pc + bx r2 + ldmfd sp!, {r0-r1} + b ctor_loop +ctor_end: + + bl start_kernel + +_loop_here: + b _loop_here \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/cortexA9.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/cortexA9.S new file mode 100755 index 000000000..ce34242fc --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/cortexA9.S @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2010-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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. + */ + +/*! + * @file cortexA9.s + * @brief This file contains cortexA9 functions + * + */ + + .code 32 + .section ".text","ax" + +/* + * bool arm_set_interrupt_state(bool enable) + */ + .global arm_set_interrupt_state + .func arm_set_interrupt_state +arm_set_interrupt_state: + mrs r2,CPSR @ read CPSR (Current Program Status Register) + teq r0,#0 + bicne r1,r2,#0xc0 @ disable IRQ and FIQ + orreq r1,r2,#0xc0 @ enable IRQ and FIQ + msr CPSR_c,r1 + tst r2,#0x80 + movne r0,#0 + moveq r0,#1 + bx lr + .endfunc + + .global cpu_get_current + @ int cpu_get_current(void)@ + @ get current CPU ID + .func cpu_get_current +cpu_get_current: + mrc p15, 0, r0, c0, c0, 5 + and r0, r0, #3 + BX lr + .endfunc @cpu_get_current()@ + + .global enable_neon_fpu + .func enable_neon_fpu +enable_neon_fpu: + /* set NSACR, both Secure and Non-secure access are allowed to NEON */ + MRC p15, 0, r0, c1, c1, 2 + ORR r0, r0, #(0x3<<10) @ enable fpu/neon + MCR p15, 0, r0, c1, c1, 2 + /* Set the CPACR for access to CP10 and CP11*/ + LDR r0, =0xF00000 + MCR p15, 0, r0, c1, c0, 2 + /* Set the FPEXC EN bit to enable the FPU */ + MOV r3, #0x40000000 + @VMSR FPEXC, r3 + MCR p10, 7, r3, c8, c0, 0 + .endfunc + + .global disable_strict_align_check + .func disable_strict_align_check +disable_strict_align_check: + /*Ray's note: disable strict alignment fault checking. + without disabling this, data abort will happen when accessing + the BPB structure of file system since it is packed.*/ + + push {r0, lr} + + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(0x1<<1) @clear A bit of SCTLR + mcr p15, 0, r0, c1, c0, 0 + + pop {r0, pc} + .endfunc + + .global disable_L1_cache + .func disable_L1_cache +disable_L1_cache: + push {r0-r6, lr} + + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(0x1<<12) + bic r0, r0, #(0x1<<11) + bic r0, r0, #(0x1<<2) + bic r0, r0, #(0x1<<0) + mcr p15, 0, r0, c1, c0, 0 + + pop {r0-r6, pc} + + .endfunc + + .global get_arm_private_peripheral_base + @ uint32_t get_arm_private_peripheral_base(void)@ + .func get_arm_private_peripheral_base +get_arm_private_peripheral_base: + + @ Get base address of private perpherial space + mrc p15, 4, r0, c15, c0, 0 @ Read periph base address + bx lr + + .endfunc @get_arm_private_peripheral_base()@ + +@ ------------------------------------------------------------ +@ TLB +@ ------------------------------------------------------------ + + .global arm_unified_tlb_invalidate + @ void arm_unified_tlb_invalidate(void)@ + .func arm_unified_tlb_invalidate +arm_unified_tlb_invalidate: + mov r0, #1 + mcr p15, 0, r0, c8, c7, 0 @ TLBIALL - Invalidate entire unified TLB + dsb + bx lr + .endfunc + + .global arm_unified_tlb_invalidate_is + @ void arm_unified_tlb_invalidate_is(void)@ + .func arm_unified_tlb_invalidate_is +arm_unified_tlb_invalidate_is: + mov r0, #1 + mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS - Invalidate entire unified TLB Inner Shareable + dsb + bx lr + .endfunc + +@ ------------------------------------------------------------ +@ Branch Prediction +@ ------------------------------------------------------------ + + .global arm_branch_prediction_enable + @ void arm_branch_prediction_enable(void) + .func arm_branch_prediction_enable +arm_branch_prediction_enable: + mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR + orr r0, r0, #(1 << 11) @ Set the Z bit (bit 11) + mcr p15, 0,r0, c1, c0, 0 @ Write SCTLR + bx lr + .endfunc + + .global arm_branch_prediction_disable + @ void arm_branch_prediction_disable(void) + .func arm_branch_prediction_disable +arm_branch_prediction_disable: + mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR + bic r0, r0, #(1 << 11) @ Clear the Z bit (bit 11) + mcr p15, 0,r0, c1, c0, 0 @ Write SCTLR + bx lr + .endfunc + + .global arm_branch_target_cache_invalidate + @ void arm_branch_target_cache_invalidate(void) + .func arm_branch_target_cache_invalidate +arm_branch_target_cache_invalidate: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 6 @ BPIALL - Invalidate entire branch predictor array + bx lr + .endfunc + + .global arm_branch_target_cache_invalidate_is + @ void arm_branch_target_cache_invalidate_is(void) + .func arm_branch_target_cache_invalidate_is +arm_branch_target_cache_invalidate_is: + mov r0, #0 + mcr p15, 0, r0, c7, c1, 6 @ BPIALLIS - Invalidate entire branch predictor array Inner Shareable + bx lr + .endfunc + +@ ------------------------------------------------------------ +@ SCU +@ ------------------------------------------------------------ + + @ SCU offset from base of private peripheral space --> 0x000 + + .global scu_enable + @ void scu_enable(void) + @ Enables the SCU + .func scu_enable +scu_enable: + + mrc p15, 4, r0, c15, c0, 0 @ Read periph base address + + ldr r1, [r0, #0x0] @ Read the SCU Control Register + orr r1, r1, #0x1 @ Set bit 0 (The Enable bit) + str r1, [r0, #0x0] @ Write back modifed value + + bx lr + .endfunc + +@ ------------------------------------------------------------ + + .global scu_join_smp + @ void scu_join_smp(void) + @ Set this CPU as participating in SMP + .func scu_join_smp +scu_join_smp: + + @ SMP status is controlled by bit 6 of the CP15 Aux Ctrl Reg + + mrc p15, 0, r0, c1, c0, 1 @ Read ACTLR + orr r0, r0, #0x040 @ Set bit 6 + mcr p15, 0, r0, c1, c0, 1 @ Write ACTLR + + bx lr + .endfunc + +@ ------------------------------------------------------------ + + .global scu_leave_smp + @ void scu_leave_smp(void) + @ Set this CPU as NOT participating in SMP + .func scu_leave_smp +scu_leave_smp: + + @ SMP status is controlled by bit 6 of the CP15 Aux Ctrl Reg + + mrc p15, 0, r0, c1, c0, 1 @ Read ACTLR + bic r0, r0, #0x040 @ Clear bit 6 + mcr p15, 0, r0, c1, c0, 1 @ Write ACTLR + + bx lr + .endfunc + +@ ------------------------------------------------------------ + + .global scu_get_cpus_in_smp + @ unsigned int scu_get_cpus_in_smp(void) + @ The return value is 1 bit per core: + @ bit 0 - CPU 0 + @ bit 1 - CPU 1 + @ etc... + .func scu_get_cpus_in_smp +scu_get_cpus_in_smp: + + mrc p15, 4, r0, c15, c0, 0 @ Read periph base address + + ldr r0, [r0, #0x004] @ Read SCU Configuration register + mov r0, r0, lsr #4 @ Bits 7:4 gives the cores in SMP mode, shift then mask + and r0, r0, #0x0F + + bx lr + .endfunc + +@ ------------------------------------------------------------ + + .global scu_enable_maintenance_broadcast + @ void scu_enable_maintenance_broadcast(void) + @ Enable the broadcasting of cache & TLB maintenance operations + @ When enabled AND in SMP, broadcast all "inner sharable" + @ cache and TLM maintenance operations to other SMP cores + .func scu_enable_maintenance_broadcast +scu_enable_maintenance_broadcast: + mrc p15, 0, r0, c1, c0, 1 @ Read Aux Ctrl register + orr r0, r0, #0x01 @ Set the FW bit (bit 0) + mcr p15, 0, r0, c1, c0, 1 @ Write Aux Ctrl register + + bx lr + .endfunc + +@ ------------------------------------------------------------ + + .global scu_disable_maintenance_broadcast + @ void scu_disable_maintenance_broadcast(void) + @ Disable the broadcasting of cache & TLB maintenance operations + .func scu_disable_maintenance_broadcast +scu_disable_maintenance_broadcast: + mrc p15, 0, r0, c1, c0, 1 @ Read Aux Ctrl register + bic r0, r0, #0x01 @ Clear the FW bit (bit 0) + mcr p15, 0, r0, c1, c0, 1 @ Write Aux Ctrl register + + bx lr + .endfunc + +@ ------------------------------------------------------------ + + .global scu_secure_invalidate + @ void scu_secure_invalidate(unsigned int cpu, unsigned int ways) + @ cpu: 0x0=CPU 0 0x1=CPU 1 etc... + @ This function invalidates the SCU copy of the tag rams + @ for the specified core. typically only done at start-up. + @ Possible flow: + @ - Invalidate L1 caches + @ - Invalidate SCU copy of TAG RAMs + @ - Join SMP + .func scu_secure_invalidate +scu_secure_invalidate: + and r0, r0, #0x03 @ Mask off unused bits of CPU ID + mov r0, r0, lsl #2 @ Convert into bit offset (four bits per core) + + and r1, r1, #0x0F @ Mask off unused bits of ways + mov r1, r1, lsl r0 @ Shift ways into the correct CPU field + + mrc p15, 4, r2, c15, c0, 0 @ Read periph base address + + str r1, [r2, #0x0C] @ Write to SCU Invalidate All in Secure State + + bx lr + + .endfunc + +@ ------------------------------------------------------------ +@ End of cortexA9.s +@ ------------------------------------------------------------ + .end diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/cortex_a9.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/cortex_a9.h new file mode 100755 index 000000000..c445e4fb4 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/cortex_a9.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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. + */ +#if !defined(__CORTEX_A9_H__) +#define __CORTEX_A9_H__ + +#include +#include +#include + +//! @addtogroup cortexa9 +//! @{ + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +//! @name Instruction macros +//@{ +#define _ARM_NOP() asm volatile ("nop\n\t") +#define _ARM_WFI() asm volatile ("wfi\n\t") +#define _ARM_WFE() asm volatile ("wfe\n\t") +#define _ARM_SEV() asm volatile ("sev\n\t") +#define _ARM_DSB() asm volatile ("dsb\n\t") +#define _ARM_ISB() asm volatile ("isb\n\t") + +#define _ARM_MRC(coproc, opcode1, Rt, CRn, CRm, opcode2) \ + asm volatile ("mrc p" #coproc ", " #opcode1 ", %[output], c" #CRn ", c" #CRm ", " #opcode2 "\n" : [output] "=r" (Rt)) + +#define _ARM_MCR(coproc, opcode1, Rt, CRn, CRm, opcode2) \ + asm volatile ("mcr p" #coproc ", " #opcode1 ", %[input], c" #CRn ", c" #CRm ", " #opcode2 "\n" :: [input] "r" (Rt)) +//@} + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__cplusplus) +extern "C" { +#endif + +//! @name Misc +//@{ +//! @brief Enable or disable the IRQ and FIQ state. +bool arm_set_interrupt_state(bool enable); + +//! @brief Get current CPU ID. +int cpu_get_current(void); + +//! @brief Enable the NEON MPE. +void enable_neon_fpu(void); + +//! @brief Disable aborts on unaligned accesses. +void disable_strict_align_check(void); + +//! @brief Get base address of private perpherial space. +//! +//! @return The address of the ARM CPU's private peripherals. +uint32_t get_arm_private_peripheral_base(void); +//@} + + +//! @name Data cache operations +//@{ + +//! @brief Check if dcache is enabled or disabled. +int arm_dcache_state_query(); + +//! @brief Enables data cache at any available cache level. +//! +//! Works only if MMU is enabled! +void arm_dcache_enable(); + +//! @brief Disables the data cache at any available cache level. +void arm_dcache_disable(); + +//! @brief Invalidates the entire data cache. +void arm_dcache_invalidate(); + +//! @brief Invalidate a line of data cache. +void arm_dcache_invalidate_line(const void * addr); + +//! @brief Invalidate a number of lines of data cache. +//! +//! Number of lines depends on length parameter and size of line. +//! Size of line for A9 L1 cache is 32B. +void arm_dcache_invalidate_mlines(const void * addr, size_t length); + +//! @brief Flush (clean) all lines of cache (all sets in all ways). +void arm_dcache_flush(); + +//! @brief Flush (clean) one line of cache. +void arm_dcache_flush_line(const void * addr); + +// @brief Flush (clean) multiple lines of cache. +//! +//! Number of lines depends on length parameter and size of line. +void arm_dcache_flush_mlines(const void * addr, size_t length); +//@} + +//! @name Instrution cache operations +//@{ + +//! @brief Check if icache is enabled or disabled. +int arm_icache_state_query(); + +//! @brief Enables instruction cache at any available cache level. +//! +//! Works without enabled MMU too! +void arm_icache_enable(); + +//! @brief Disables the instruction cache at any available cache level. +void arm_icache_disable(); + +//! @brief Invalidates the entire instruction cache. +void arm_icache_invalidate(); + +//! @brief Invalidates the entire instruction cache inner shareable. +void arm_icache_invalidate_is(); + +//! @brief Invalidate a line of the instruction cache. +void arm_icache_invalidate_line(const void * addr); + +//! @brief Invalidate a number of lines of instruction cache. +//! +//! Number of lines depends on length parameter and size of line. +void arm_icache_invalidate_mlines(const void * addr, size_t length); +//@} + +//! @name TLB operations +//@{ +//! @brief Invalidate entire unified TLB. +void arm_unified_tlb_invalidate(void); + +//! @brief Invalidate entire unified TLB Inner Shareable. +void arm_unified_tlb_invalidate_is(void); +//@} + +//! @name Branch predictor operations +//@{ +//! @brief Enable branch prediction. +void arm_branch_prediction_enable(void); + +//! @brief Disable branch prediction. +void arm_branch_prediction_disable(void); + +//! @brief Invalidate entire branch predictor array. +void arm_branch_target_cache_invalidate(void); + +//! @brief Invalidate entire branch predictor array Inner Shareable +void arm_branch_target_cache_invalidate_is(void); +//@} + +//! @name SCU +//@{ +//! @brief Enables the SCU. +void scu_enable(void); + +//! @brief Set this CPU as participating in SMP. +void scu_join_smp(void); + +//! @brief Set this CPU as not participating in SMP. +void scu_leave_smp(void); + +//! @brief Determine which CPUs are participating in SMP. +//! +//! The return value is 1 bit per core: +//! - bit 0 - CPU 0 +//! - bit 1 - CPU 1 +//! - etc... +unsigned int scu_get_cpus_in_smp(void); + +//! @brief Enable the broadcasting of cache & TLB maintenance operations. +//! +//! When enabled AND in SMP, broadcast all "inner sharable" +//! cache and TLM maintenance operations to other SMP cores +void scu_enable_maintenance_broadcast(void); + +//! @brief Disable the broadcasting of cache & TLB maintenance operations. +void scu_disable_maintenance_broadcast(void); + +//! @brief Invalidates the SCU copy of the tag rams for the specified core. +//! +//! Typically only done at start-up. +//! Possible flow: +//! - Invalidate L1 caches +//! - Invalidate SCU copy of TAG RAMs +//! - Join SMP +//! +//! @param cpu 0x0=CPU 0, 0x1=CPU 1, etc... +//! @param ways The ways to invalidate. Pass 0xf to invalidate all ways. +void scu_secure_invalidate(unsigned int cpu, unsigned int ways); +//@} + +#if defined(__cplusplus) +} +#endif + +//! @} + +#endif // __CORTEX_A9_H__ +//////////////////////////////////////////////////////////////////////////////// +// EOF +//////////////////////////////////////////////////////////////////////////////// diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/exception.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/exception.S new file mode 100644 index 000000000..bc9a68213 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/exception.S @@ -0,0 +1,145 @@ +#include + +.section .text.vectors, "ax" +.code 32 + +.globl ExceptionVectors +ExceptionVectors: + ldr pc, _ResetException + ldr pc, _UndefInstrException + ldr pc, _SwiException + ldr pc, _PrefetchAbortException + ldr pc, _DataAbortAbortException + ldr pc, _ResvException + ldr pc, _IrqException + ldr pc, _FiqException + +.globl _reset +.globl UndefInstrExceptionHandle +.globl SwiExceptionHandle +.globl PrefetchAbortExceptionHandle +.globl DataAbortExceptionHandle +.globl ResvExceptionHandle +.globl ExceptionIsrEntry +.globl FiqExceptionHandle + +_ResetException: + .word _reset +_UndefInstrException: + .word UndefInstrExceptionHandle +_SwiException: + .word SwiExceptionHandle +_PrefetchAbortException: + .word PrefetchAbortExceptionHandle +_DataAbortAbortException: + .word DataAbortExceptionHandle +_ResvException: + .word ResvExceptionHandle +_IrqException: + .word ExceptionIsrEntry +_FiqException: + .word FiqExceptionHandle + + .word 0 // extra word in RAM vectors + + +.macro push_svc_reg + sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + mov r0, sp + mrs r6, spsr @/* Save CPSR */ + str lr, [r0, #15*4] @/* Push PC */ + str r6, [r0, #16*4] @/* Push CPSR */ + cps #MODE_SVC + str sp, [r0, #13*4] @/* Save calling SP */ + str lr, [r0, #14*4] @/* Save calling PC */ +.endm + +.align 5 +.globl UndefInstrExceptionHandle +UndefInstrExceptionHandle: +1: + b 1b + +.align 5 +.globl SwiExceptionHandle +SwiExceptionHandle: + push_svc_reg + bl DoSvcCallProcess + b . + +.align 5 +.globl PrefetchAbortExceptionHandle +PrefetchAbortExceptionHandle: +1: + b 1b + +.align 5 +.globl DataAbortExceptionHandle +DataAbortExceptionHandle: +1: + b 1b + +.align 5 +.globl ResvExceptionHandle +ResvExceptionHandle: +1: + b 1b + +.section .text.isr, "ax" +.align 5 +.globl ExceptionIsrEntry +ExceptionIsrEntry: + + stmfd sp!, {r0-r12,lr} + + bl DoIrqProcess + + @ ldr r0, =rt_thread_switch_interrupt_flag + @ ldr r1, [r0] + @ cmp r1, #1 + @ beq rt_hw_context_switch_interrupt_do + + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + +@ rt_hw_context_switch_interrupt_do: +@ mov r1, #0 @ clear flag +@ str r1, [r0] + +@ mov r1, sp @ r1 point to {r0-r3} in stack +@ add sp, sp, #4*4 +@ ldmfd sp!, {r4-r12,lr}@ reload saved registers +@ mrs r0, spsr @ get cpsr of interrupt thread +@ sub r2, lr, #4 @ save old task's pc to r2 + +@ @ Switch to SVC mode with no interrupt. If the usr mode guest is +@ @ interrupted, this will just switch to the stack of kernel space. +@ @ save the registers in kernel space won't trigger data abort. +@ msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + +@ stmfd sp!, {r2} @ push old task's pc +@ stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 +@ ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread +@ stmfd sp!, {r1-r4} @ push old task's r0-r3 +@ stmfd sp!, {r0} @ push old task's cpsr + +@ ldr r4, =rt_interrupt_from_thread +@ ldr r5, [r4] +@ str sp, [r5] @ store sp in preempted tasks's TCB + +@ ldr r6, =rt_interrupt_to_thread +@ ldr r6, [r6] +@ ldr sp, [r6] @ get new task's stack pointer + +@ ldmfd sp!, {r4} @ pop new task's cpsr to spsr +@ msr spsr_cxsf, r4 + +@ ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr + + +.align 5 +.globl FiqExceptionHandle +FiqExceptionHandle: +1: + b 1b diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic.c b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic.c new file mode 100644 index 000000000..82b337331 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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 +#include "gic.h" +#include "gic_registers.h" +#include "cortex_a9.h" + +//////////////////////////////////////////////////////////////////////////////// +// Prototypes +//////////////////////////////////////////////////////////////////////////////// + +static inline gicd_t * gic_get_gicd(void); +static inline gicc_t * gic_get_gicc(void); +static inline uint32_t irq_get_register_offset(uint32_t irqID); +static inline uint32_t irq_get_bit_offset(uint32_t irqID); +static inline uint32_t irq_get_bit_mask(uint32_t irqID); + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +static inline gicd_t * gic_get_gicd(void) +{ + uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset; + return (gicd_t *)base; +} + +static inline gicc_t * gic_get_gicc(void) +{ + uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset; + return (gicc_t *)base; +} + +static inline uint32_t irq_get_register_offset(uint32_t irqID) +{ + return irqID / 32; +} + +static inline uint32_t irq_get_bit_offset(uint32_t irqID) +{ + return irqID & 0x1f; +} + +static inline uint32_t irq_get_bit_mask(uint32_t irqID) +{ + return 1 << irq_get_bit_offset(irqID); +} + +void gic_enable(bool enableIt) +{ + gicd_t * gicd = gic_get_gicd(); + + if (enableIt) + { + // Enable both secure and non-secure. + gicd->CTLR |= kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1; + } + else + { + // Clear the enable bits. + gicd->CTLR &= ~(kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1); + } +} + +void gic_set_irq_security(uint32_t irqID, bool isSecure) +{ + gicd_t * gicd = gic_get_gicd(); + + uint32_t reg = irq_get_register_offset(irqID); + uint32_t mask = irq_get_bit_mask(irqID); + + uint32_t value = gicd->IGROUPRn[reg]; + if (!isSecure) + { + value &= ~mask; + } + else + { + value |= mask; + } + gicd->IGROUPRn[reg] = value; +} + +void gic_enable_irq(uint32_t irqID, bool isEnabled) +{ + gicd_t * gicd = gic_get_gicd(); + + uint32_t reg = irq_get_register_offset(irqID); + uint32_t mask = irq_get_bit_mask(irqID); + + // Select set-enable or clear-enable register based on enable flag. + if (isEnabled) + { + gicd->ISENABLERn[reg] = mask; + } + else + { + gicd->ICENABLERn[reg] = mask; + } +} + +void gic_set_irq_priority(uint32_t ID, uint32_t priority) +{ + gicd_t * gicd = gic_get_gicd(); + + // Update the priority register. The priority registers are byte accessible, and the register + // struct has the priority registers as a byte array, so we can just index directly by the + // interrupt ID. + gicd->IPRIORITYRn[ID] = priority & 0xff; +} + +void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt) +{ + // Make sure the CPU number is valid. + assert(cpuNumber <= 7); + + gicd_t * gicd = gic_get_gicd(); + uint8_t cpuMask = 1 << cpuNumber; + + // Like the priority registers, the target registers are byte accessible, and the register + // struct has the them as a byte array, so we can just index directly by the + // interrupt ID. + if (enableIt) + { + gicd->ITARGETSRn[irqID] |= (cpuMask & 0xff); + } + else + { + gicd->ITARGETSRn[irqID] &= ~(cpuMask & 0xff); + } +} + +void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list) +{ + gicd_t * gicd = gic_get_gicd(); + + gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter) + | (target_list << kBP_GICD_SGIR_CPUTargetList) + | (irqID & 0xf); +} + +void gic_cpu_enable(bool enableIt) +{ + gicc_t * gicc = gic_get_gicc(); + + if (enableIt) + { + gicc->CTLR |= kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS; + } + else + { + gicc->CTLR &= ~(kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS); + } +} + +void gic_set_cpu_priority_mask(uint32_t priority) +{ + gicc_t * gicc = gic_get_gicc(); + gicc->PMR = priority & 0xff; +} + +uint32_t gic_read_irq_ack(void) +{ + gicc_t * gicc = gic_get_gicc(); + return gicc->IAR; +} + +void gic_write_end_of_irq(uint32_t irqID) +{ + gicc_t * gicc = gic_get_gicc(); + gicc->EOIR = irqID; +} + +void gic_init(void) +{ + gicd_t * gicd = gic_get_gicd(); + + // First disable the distributor. + gic_enable(false); + + // Clear all pending interrupts. + int i; + for (i = 0; i < 32; ++i) + { + gicd->ICPENDRn[i] = 0xffffffff; + } + + // Set all interrupts to secure. + for (i = 0; i < 8; ++i) + { + gicd->IGROUPRn[i] = 0; + } + + // Init the GIC CPU interface. + gic_init_cpu(); + + // Now enable the distributor. + gic_enable(true); +} + +void gic_init_cpu(void) +{ + // Init the GIC CPU interface. + gic_set_cpu_priority_mask(0xff); + + // Disable preemption. + gicc_t * gicc = gic_get_gicc(); + gicc->BPR = 7; + + // Enable signaling the CPU. + gic_cpu_enable(true); +} + +//////////////////////////////////////////////////////////////////////////////// +// EOF +//////////////////////////////////////////////////////////////////////////////// diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic.h new file mode 100644 index 000000000..f3eee8499 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2011-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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 __GIC_H__ +#define __GIC_H__ + +#include "sdk_types.h" + +//! @addtogroup gic +//! @{ + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +//! @brief Options for sending a software generated interrupt. +//! +//! These options are used for the @a filter_list parameter of the gic_send_sgi() +//! function. They control how to select which CPUs that the interrupt is +//! sent to. +enum _gicd_sgi_filter +{ + //! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter. + kGicSgiFilter_UseTargetList = 0, + + //! Forward the interrupt to all CPU interfaces except that of the processor that requested + //! the interrupt. + kGicSgiFilter_AllOtherCPUs = 1, + + //! Forward the interrupt only to the CPU interface of the processor that requested the + //! interrupt. + kGicSgiFilter_OnlyThisCPU = 2 +}; + +//////////////////////////////////////////////////////////////////////////////// +// API +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__cplusplus) +extern "C" { +#endif + +//! @name Initialization +//@{ +//! @brief Init interrupt handling. +//! +//! This function is intended to be called only by the primary CPU init code, so it will +//! only be called once during system bootup. +//! +//! Also inits the current CPU. You don't need to call gic_init_cpu() separately. +//! +//! @post The interrupt distributor and the current CPU interface are enabled. All interrupts +//! that were pending are cleared, and all interrupts are made secure (group 0). +void gic_init(void); + +//! @brief Init the current CPU's GIC interface. +//! +//! @post Enables the CPU interface and sets the priority mask to 255. Interrupt preemption +//! is disabled by setting the Binary Point to a value of 7. +void gic_init_cpu(void); +//@} + +//! @name GIC Interrupt Distributor Functions +//@{ +//! @brief Enable or disable the GIC Distributor. +//! +//! Enables or disables the GIC distributor passing both secure (group 0) and non-secure +//! (group 1) interrupts to the CPU interfaces. +//! +//! @param enableIt Pass true to enable or false to disable. +void gic_enable(bool enableIt); + +//! @brief Set the security mode for an interrupt. +//! +//! @param irqID The interrupt number. +//! @param isSecure Whether the interrupt is taken to secure mode. +void gic_set_irq_security(uint32_t irqID, bool isSecure); + +//! @brief Enable or disable an interrupt. +//! +//! @param irqID The number of the interrupt to control. +//! @param isEnabled Pass true to enable or false to disable. +void gic_enable_irq(uint32_t irqID, bool isEnabled); + +//! @brief Set whether a CPU will receive a particular interrupt. +//! +//! @param irqID The interrupt number. +//! @param cpuNumber The CPU number. The first CPU core is 0. +//! @param enableIt Whether to send the interrupt to the specified CPU. Pass true to enable +//! or false to disable. +void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt); + +//! @brief Set an interrupt's priority. +//! +//! @param irq_id The interrupt number. +//! @param priority The priority for the interrupt. In the range of 0 through 0xff, with +//! 0 being the highest priority. +void gic_set_irq_priority(uint32_t irq_id, uint32_t priority); + +//! @brief Send a software generated interrupt to a specific CPU. +//! +//! @param irq_id The interrupt number to send. +//! @param target_list Each bit indicates a CPU to which the interrupt will be forwarded. +//! Bit 0 is CPU 0, bit 1 is CPU 1, and so on. If the value is 0, then the interrupt +//! will not be forwarded to any CPUs. This parameter is only used if @a filter_list +//! is set to #kGicSgiFilter_UseTargetList. +//! @param filter_list One of the enums of the #_gicd_sgi_filter enumeration. The selected +//! option determines which CPUs the interrupt will be sent to. If the value +//! is #kGicSgiFilter_UseTargetList, then the @a target_list parameter is used. +void gic_send_sgi(uint32_t irq_id, uint32_t target_list, uint32_t filter_list); +//@} + +//! @name GIC CPU Interface Functions +//@{ +//! @brief Enable or disable the interface to the GIC for the current CPU. +//! +//! @param enableIt Pass true to enable or false to disable. +void gic_cpu_enable(bool enableIt); + +//! @brief Set the mask of which interrupt priorities the CPU will receive. +//! +//! @param priority The lowest priority that will be passed to the current CPU. Pass 0xff to +//! allow all priority interrupts to signal the CPU. +void gic_set_cpu_priority_mask(uint32_t priority); + +//! @brief Acknowledge starting of interrupt handling and get the interrupt number. +//! +//! Normally, this function is called at the beginning of the IRQ handler. It tells the GIC +//! that you are starting to handle an interupt, and returns the number of the interrupt you +//! need to handle. After the interrupt is handled, you should call gic_write_end_of_irq() +//! to signal that the interrupt is completely handled. +//! +//! In some cases, a spurious interrupt might happen. One possibility is if another CPU handles +//! the interrupt. When a spurious interrupt occurs, the end of the interrupt should be indicated +//! but nothing else. +//! +//! @return The number for the highest priority interrupt available for the calling CPU. If +//! the return value is 1022 or 1023, a spurious interrupt has occurred. +uint32_t gic_read_irq_ack(void); + +//! @brief Signal the end of handling an interrupt. +//! +//! @param irq_id The number of the interrupt for which handling has finished. +void gic_write_end_of_irq(uint32_t irq_id); +//@} + + +#if defined(__cplusplus) +} +#endif + +//! @} + +#endif // __GIC_H__ +//////////////////////////////////////////////////////////////////////////////// +// EOF +//////////////////////////////////////////////////////////////////////////////// diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic_registers.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic_registers.h new file mode 100644 index 000000000..bf9a11851 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/gic_registers.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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 "sdk_types.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +//! @brief Offsets to the GIC registers. +enum _gic_base_offsets +{ + kGICDBaseOffset = 0x1000, //!< GIC distributor offset. + kGICCBaseOffset = 0x100 //!< GIC CPU interface offset. +}; + +//! @brief GIC distributor registers. +//! +//! Uses the GICv2 register names, but does not include GICv2 registers. +//! +//! The IPRIORITYRn and ITARGETSRn registers are byte accessible, so their types are uint8_t +//! instead of uint32_t to reflect this. These members are indexed directly with the interrupt +//! number. +struct _gicd_registers +{ + uint32_t CTLR; //!< Distributor Control Register. + uint32_t TYPER; //!< Interrupt Controller Type Register. + uint32_t IIDR; //!< Distributor Implementer Identification Register. + uint32_t _reserved0[29]; + uint32_t IGROUPRn[8]; //!< Interrupt Group Registers. + uint32_t _reserved1[24]; + uint32_t ISENABLERn[32]; //!< Interrupt Set-Enable Registers. + uint32_t ICENABLERn[32]; //!< Interrupt Clear-Enable Registers. + uint32_t ISPENDRn[32]; //!< Interrupt Set-Pending Registers. + uint32_t ICPENDRn[32]; //!< Interrupt Clear-Pending Registers. + uint32_t ICDABRn[32]; //!< Active Bit Registers. + uint32_t _reserved2[32]; + uint8_t IPRIORITYRn[255 * sizeof(uint32_t)]; //!< Interrupt Priority Registers. (Byte accessible) + uint32_t _reserved3; + uint8_t ITARGETSRn[255 * sizeof(uint32_t)]; //!< Interrupt Processor Targets Registers. (Byte accessible) + uint32_t _reserved4; + uint32_t ICFGRn[64]; //!< Interrupt Configuration Registers. + uint32_t _reserved5[128]; + uint32_t SGIR; //!< Software Generated Interrupt Register +}; + +//! @brief Bitfields constants for the GICD_CTLR register. +enum _gicd_ctlr_fields +{ + kBM_GICD_CTLR_EnableGrp1 = (1 << 1), + kBM_GICD_CTLR_EnableGrp0 = (1 << 0) +}; + +//! @brief Bitfields constants for the GICD_SGIR register. +enum _gicd_sgir_fields +{ + kBP_GICD_SGIR_TargetListFilter = 24, + kBM_GICD_SGIR_TargetListFilter = (0x3 << kBP_GICD_SGIR_TargetListFilter), + + kBP_GICD_SGIR_CPUTargetList = 16, + kBM_GICD_SGIR_CPUTargetList = (0xff << kBP_GICD_SGIR_CPUTargetList), + + kBP_GICD_SGIR_NSATT = 15, + kBM_GICD_SGIR_NSATT = (1 << kBP_GICD_SGIR_NSATT), + + kBP_GICD_SGIR_SGIINTID = 0, + kBM_GICD_SGIR_SGIINTID = 0xf +}; + +//! @brief GIC CPU interface registers. +//! +//! Uses the GICv2 register names. Does not include GICv2 registers. +struct _gicc_registers +{ + uint32_t CTLR; //!< CPU Interface Control Register. + uint32_t PMR; //!< Interrupt Priority Mask Register. + uint32_t BPR; //!< Binary Point Register. + uint32_t IAR; //!< Interrupt Acknowledge Register. + uint32_t EOIR; //!< End of Interrupt Register. + uint32_t RPR; //!< Running Priority Register. + uint32_t HPPIR; //!< Highest Priority Pending Interrupt Register. + uint32_t ABPR; //!< Aliased Binary Point Register. (only visible with a secure access) + uint32_t _reserved[56]; + uint32_t IIDR; //!< CPU Interface Identification Register. +}; + +//! @brief Bitfields constants for the GICC_CTLR register. +enum _gicc_ctlr_fields +{ + kBP_GICC_CTLR_EnableS = 0, + kBM_GICC_CTLR_EnableS = (1 << 0), + + kBP_GICC_CTLR_EnableNS = 1, + kBM_GICC_CTLR_EnableNS = (1 << 1), + + kBP_GICC_CTLR_AckCtl = 2, + kBM_GICC_CTLR_AckCtl = (1 << 2), + + kBP_GICC_CTLR_FIQEn = 3, + kBM_GICC_CTLR_FIQEn = (1 << 3), + + kBP_GICC_CTLR_SBPR = 4, + kBM_GICC_CTLR_SBPR = (1 << 4) +}; + +//! @brier Type for the GIC distributor registers. +typedef volatile struct _gicd_registers gicd_t; + +//! @brier Type for the GIC CPU interface registers. +typedef volatile struct _gicc_registers gicc_t; + +//////////////////////////////////////////////////////////////////////////////// +// EOF +//////////////////////////////////////////////////////////////////////////////// diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/interrupt.c b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/interrupt.c new file mode 100755 index 000000000..3105805d1 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/interrupt.c @@ -0,0 +1,111 @@ +// extern void _svcall(uintptr_t* contex); +#include +#include +#include + +uint32_t DisableLocalInterrupt(void) +{ + uint32_t intSave; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "cpsid if " + : "=r"(intSave) + : + : "memory"); + return intSave; +} + +void EnableLocalInterrupt(unsigned long level) +{ + uint32_t intSave; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "cpsie if " + : "=r"(intSave) + : + : "memory"); + return; +} + +int32_t ArchEnableHwIrq(uint32_t irq_num) +{ + // gic_set_irq_priority(irq_num, priority); + gic_set_irq_security(irq_num, false); // set IRQ as non-secure + // gic_set_cpu_target(irq_num, CPU_0, true); + gic_enable_irq(irq_num, true); + return 0; +} + +int32_t ArchDisableHwIrq(uint32_t irq_num) +{ + gic_enable_irq(irq_num, false); + // gic_set_cpu_target(irq_num, CPU_0, false); + return 0; +} + +extern void KTaskOsAssignAfterIrq(void *context); + +void IsrEntry(uint32_t irq_num) +{ + isrManager.done->incCounter(); + isrManager.done->handleIrq(irq_num); + // KTaskOsAssignAfterIrq(NULL); + isrManager.done->decCounter(); + +} + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ +void PrintStackFrame(struct ExceptionStackRegister *regs) +{ + // KPrintf("Execption:\n"); + // KPrintf("r0: 0x%08x\n", regs->r0); + // KPrintf("r1: 0x%08x\n", regs->r1); + // KPrintf("r2: 0x%08x\n", regs->r2); + // KPrintf("r3: 0x%08x\n", regs->r3); + // KPrintf("r4: 0x%08x\n", regs->r4); + // KPrintf("r5: 0x%08x\n", regs->r5); + // KPrintf("r6: 0x%08x\n", regs->r6); + // KPrintf("r7: 0x%08x\n", regs->r7); + // KPrintf("r8: 0x%08x\n", regs->r8); + // KPrintf("r9: 0x%08x\n", regs->r9); + // KPrintf("r10: 0x%08x\n", regs->r10); + // KPrintf("r11: 0x%08x\n", regs->r11); + // KPrintf("r12: 0x%08x\n", regs->r12); + // KPrintf("r13_sp: 0x%08x\n", regs->r13_sp); + // KPrintf("r14_lr: 0x%08x\n", regs->r14_lr); + // KPrintf("r15_pc: 0x%08x\n", regs->r15_pc); + // KPrintf("cpsr: 0x%08x\n", regs->cpsr); +} + + +void DoSvcCallProcess(struct ExceptionStackRegister *regs) +{ + +} + +void DoIrqProcess(void) +{ + uint32_t iar = gic_read_irq_ack(); + uint32_t irq_num = iar & 0x3ff; + + if(irq_num >= ARCH_MAX_IRQ_NUM) + { + gic_write_end_of_irq(irq_num); + return; + } + + IsrEntry(irq_num); + + gic_write_end_of_irq(irq_num); +} +// uintptr_t *Svcall(unsigned int ipsr, uintptr_t* contex ) +// { +// #ifdef TASK_ISOLATION +// _svcall(contex); +// #endif +// return contex; +// } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/link.mk b/Ubiquitous/XiZi_AIoT/link.mk new file mode 100644 index 000000000..f0ed846ef --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/link.mk @@ -0,0 +1,10 @@ +OBJS := $(shell cat make.obj) + +$(TARGET): $(OBJS) + @echo ------------------------------------------------ + @echo link $(TARGET) + @$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_MUSLLIB) $(LIBCC) + @echo ------------------------------------------------ + @$(CROSS_COMPILE)objcopy -O binary $@ XiZi-$(BOARD)$(COMPILE_TYPE).bin + @$(CROSS_COMPILE)objcopy -O ihex $@ XiZi-$(BOARD)$(COMPILE_TYPE).hex + @$(CROSS_COMPILE)size $@ \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/path_kernel.mk b/Ubiquitous/XiZi_AIoT/path_kernel.mk new file mode 100755 index 000000000..701bf39a9 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/path_kernel.mk @@ -0,0 +1,51 @@ + +export KERNELPATHS:= -I$(BSP_ROOT) + +ifeq ($(CONFIG_LIB_MUSLLIB), y) +KERNELPATHS += -I$(KERNEL_ROOT)/services/lib/musllib/src/include \ + -I$(KERNEL_ROOT)/services/lib/musllib/include \ + -I$(KERNEL_ROOT)/services/lib/musllib/src/internal # +# chose arch for musl +ifeq ($(ARCH), arm) +KERNELPATHS += -I$(KERNEL_ROOT)/services/lib/musllib/arch/arm +endif +ifeq ($(ARCH), risc-v) +KERNELPATHS += -I$(KERNEL_ROOT)/services/lib/musllib/arch/riscv64 +endif + +endif # end of musl include path + +ifeq ($(CONFIG_LIB_NEWLIB),y) +KERNELPATHS += -I$(KERNEL_ROOT)/services/lib/newlib/include # +endif + +ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/services/boards/imx6q-sabrelite) +KERNELPATHS += \ + -I$(KERNEL_ROOT)/hardkernel/arch/arm/armv7-a/cortex-a9 \ + -I$(KERNEL_ROOT)/hardkernel/abstraction \ + -I$(KERNEL_ROOT)/include \ + -I$(BSP_ROOT)/include + +ifeq ($(CONFIG_RESOURCES_LWIP),y) +KERNELPATHS += \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/compat \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/netif \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/apps \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/priv \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/prot \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/arch +endif +endif + +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Applications/general_functions/list # + +ifeq ($(ARCH), arm) +KERNELPATHS +=-I$(KERNEL_ROOT)/arch/arm/shared \ + -I$(KERNEL_ROOT)/lib/comlibc/common # +endif + +KERNELPATHS += -I$(KERNEL_ROOT)/kernel/include # + diff --git a/Ubiquitous/XiZi_AIoT/services/Kconfig b/Ubiquitous/XiZi_AIoT/services/Kconfig new file mode 100644 index 000000000..ee3478bcb --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/Kconfig @@ -0,0 +1,4 @@ +source "$KERNEL_DIR/services/drivers/Kconfig" +source "$KERNEL_DIR/services/fs/Kconfig" +source "$KERNEL_DIR/services/lib/Kconfig" + diff --git a/Ubiquitous/XiZi_AIoT/services/Makefile b/Ubiquitous/XiZi_AIoT/services/Makefile new file mode 100644 index 000000000..d3d247fa7 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/Makefile @@ -0,0 +1,6 @@ + +SRC_DIR := boards drivers lib + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/services/boards/Makefile b/Ubiquitous/XiZi_AIoT/services/boards/Makefile new file mode 100644 index 000000000..702a453b6 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/Makefile @@ -0,0 +1,4 @@ + +SRC_DIR := $(BOARD) + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/.config b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/.config new file mode 100644 index 000000000..307c2f4c0 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/.config @@ -0,0 +1,18 @@ +# +# Automatically generated file; DO NOT EDIT. +# XiZi_AIoT Project Configuration +# +CONFIG_BOARD_IMX6Q_SABRELITE_EVB=y +CONFIG_ARCH_ARM=y + +# +# imx6q sabrelite feature +# + +# +# Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y +# CONFIG_LIB_MUSLLIB is not set diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Kconfig b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Kconfig new file mode 100644 index 000000000..68adb4a56 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Kconfig @@ -0,0 +1,26 @@ +mainmenu "XiZi_AIoT Project Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config KERNEL_DIR + string + option env="KERNEL_ROOT" + default "../.." + +config BOARD_IMX6Q_SABRELITE_EVB + bool + select ARCH_ARM + default y + +source "$KERNEL_DIR/hardkernel/arch/Kconfig" + +menu "imx6q sabrelite feature" + source "$BSP_DIR/third_party_driver/Kconfig" + +endmenu + + +source "$KERNEL_DIR/Kconfig" diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile new file mode 100644 index 000000000..e929933ca --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile @@ -0,0 +1,8 @@ +SRC_FILES := board.c ivt.c + +SRC_DIR := third_party_driver + + + + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/board.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/board.c new file mode 100644 index 000000000..6de1c0977 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/board.c @@ -0,0 +1,4 @@ +void start_kernel() +{ + +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/board.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/board.h new file mode 100644 index 000000000..db7269dc6 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/board.h @@ -0,0 +1,6 @@ +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#define PLATFORM_MAX_IRQ_NR 160 // imx6q max support 160 irq + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/config.mk b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/config.mk new file mode 100644 index 000000000..d36fb19fe --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/config.mk @@ -0,0 +1,23 @@ +export CROSS_COMPILE ?=/usr/bin/arm-none-eabi- +export DEVICE = -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16 -ftree-vectorize -ffast-math -mfloat-abi=softfp +export CFLAGS := $(DEVICE) -Wall -O0 -g -gdwarf-2 +export AFLAGS := -c $(DEVICE) -x assembler-with-cpp -D__ASSEMBLY__ -gdwarf-2 +export LFLAGS := $(DEVICE) -Wl,--gc-sections,-Map=XiZi-imx6q-sabrelite.map,-cref,-u,ExceptionVectors -T $(BSP_ROOT)/link.lds +export CXXFLAGS := + +ifeq ($(CONFIG_LIB_MUSLLIB), y) +export LFLAGS += -nostdlib -nostdinc -fno-builtin -nodefaultlibs +export LIBCC := -lgcc +export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a +endif + +# ifeq ($(CONFIG_RESOURCES_LWIP), y) +# export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a +# endif + +export DEFINES := -DHAVE_CCONFIG_H + +export USING_NEWLIB =1 +export USING_VFS = 1 +export ARCH = arm +export ARCH_ARMV = armv7-a diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/hab_defines.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/hab_defines.h new file mode 100755 index 000000000..1fcf5d544 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/hab_defines.h @@ -0,0 +1,2222 @@ +/* + * Copyright (c) 2008-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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. + */ + +/*! + * @file hab_defines.h + * @brief defines for data structures and macros used for enabling secure boot + * + * @ingroup diag_init + */ +#ifndef HAB_DEFINES_H +#define HAB_DEFINES_H +/*=========================================================================== + INCLUDE FILES +=============================================================================*/ +#include /* for integer types */ +#include /* for bool type */ +#include /* for NULL and offsetof() */ +/*=========================================================================== + CONSTANTS +=============================================================================*/ +/** @addtogroup struct + * @{ + */ + +#define HDR_BYTES 4 /* cannot use sizeof(hab_hdr_t) in preprocessor */ + +/** @name External data structure tags + * @anchor dat_tag + * + * Tag values 0x00 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff + * are available for custom use. + */ +/*@{*/ +#define HAB_TAG_IVT 0xd1 /**< Image Vector Table */ +#define HAB_TAG_DCD 0xd2 /**< Device Configuration Data */ +#define HAB_TAG_CSF 0xd4 /**< Command Sequence File */ +#define HAB_TAG_CRT 0xd7 /**< Certificate */ +#define HAB_TAG_SIG 0xd8 /**< Signature */ +#define HAB_TAG_EVT 0xdb /**< Event */ +#define HAB_TAG_RVT 0xdd /**< ROM Vector Table */ +#define HAB_TAG_WRP 0x81 /**< Wrapped Key */ +#define HAB_TAG_MAC 0xac /**< Message Authentication Code */ +/* Values 00 ... 7e reserved for internal use. Values b0 ... cf reserved for + * CSF commands. Values e0 ... ef reserved for key types. + * + * Available values: 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, + * 9c, 9f, a0, a3, a5, a6, a9, aa, af + * + * Custom values: f0, f3, f5, f6, f9, fa, fc, ff + */ +/*@}*/ + +/** @name HAB version */ +/*@{*/ +#define HAB_MAJOR_VERSION 4 /**< Major version of this HAB release */ +#define HAB_MINOR_VERSION 1 /**< Minor version of this HAB release */ +#define HAB_VER_MAJ_WIDTH 4 /**< Major version field width */ +#define HAB_VER_MAJ_SHIFT 4 /**< Major version field offset */ +#define HAB_VER_MIN_WIDTH 4 /**< Minor version field width */ +#define HAB_VER_MIN_SHIFT 0 /**< Minor version field offset */ +/** Full version of this HAB release @hideinitializer */ +#define HAB_VERSION HAB_VER(HAB_MAJOR_VERSION, HAB_MINOR_VERSION) +/** Base version for this HAB release @hideinitializer */ +#define HAB_BASE_VERSION HAB_VER(HAB_MAJOR_VERSION, 0) + +/*@}*/ + +/* @} struct */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup cmd + * @{ + */ + +/** @name Command tags + * @anchor cmd_tag + * + * Tag values 0xb0 .. 0xcf are reserved for HAB. Values 0xf0 .. 0xff + * are available for custom use. + */ +/*@{*/ +#define HAB_CMD_SET 0xb1 /**< Set */ +#define HAB_CMD_INS_KEY 0xbe /**< Install Key */ +#define HAB_CMD_AUT_DAT 0xca /**< Authenticate Data */ +#define HAB_CMD_WRT_DAT 0xcc /**< Write Data */ +#define HAB_CMD_CHK_DAT 0xcf /**< Check Data */ +#define HAB_CMD_NOP 0xc0 /**< No Operation */ +#define HAB_CMD_INIT 0xb4 /**< Initialise */ +#define HAB_CMD_UNLK 0xb2 /**< Unlock */ +#ifdef HAB_FUTURE +#define HAB_CMD_RMV_KEY /**< Remove Key */ +#define HAB_CMD_INS_REF /**< Install Reference Data */ +#define HAB_CMD_INS_PLG /**< Install Plugin */ +#define HAB_CMD_RMV_PLG /**< Remove Plugin */ +#define HAB_CMD_CHK_VER /**< Check SW Version */ +#endif +/* Remaining values: b7, b8, bb, bd, c3, c5, c6, c9 */ +/*@}*/ + +/* @} cmd */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup pcl + * @{ + */ + +/** @name Protocol tags + * @anchor pcl_tag + * + * Tag values 0x00 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff are + * available for custom use. + */ +/*@{*/ +#define HAB_PCL_SRK 0x03 /**< SRK certificate format */ +#define HAB_PCL_X509 0x09 /**< X.509v3 certificate format */ +#define HAB_PCL_CMS 0xc5 /**< CMS/PKCS#7 signature format */ +#define HAB_PCL_BLOB 0xbb /**< SHW-specific wrapped key format */ +#define HAB_PCL_AEAD 0xa3 /**< Proprietary AEAD MAC format */ +#ifdef HAB_FUTURE +#define HAB_PCL_WTLS 0x05 /**< OMA WTLS certificate format */ +#define HAB_PCL_FSL 0x0f /**< FSL bound signature protocol */ +#define HAB_PCL_HMAC 0x30 /**< NIST HMAC message authentication */ +#define HAB_PCL_CBCMAC 0x33 /**< CBC-MAC message authentication */ +#endif +/*@}*/ + +/* Available values: 06, 0a, 0c, 11, 12, 14, 17, 18, 1b, 1d, 1e, 21, 22, 24, + * 27, 28, 2b, 2d, 2e, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b, 4d, 4e, + * 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71, 72, 74, + * 77, 78, 7b, 7d, 7e, 81, 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, + * 9c, 9f, a0, a5, a6, a9, aa, ac, af, b1, b2, b4, b7, b8, bd, be, c0, c3, c6, + * c9, ca, cc, cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7, e8, eb, ed, + * ee + * + * Custom values: f0, f3, f5, f6, f9, fa, fc, ff + */ + +/* @} pcl */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup alg + * @{ + */ + +/** @name Algorithm types + * @anchor alg_typ + * + * The most-significant nibble of an algorithm ID denotes the algorithm + * type. Algorithms of the same type share the same interface. + * + * Types 0x0 .. 0xc are reserved for HAB. Types 0xd .. 0xf are available for + * custom use. Within each reserved type N in 0 .. c, tag values 0xN0 .. 0xNc + * are reserved for HAB. Values 0xNd .. 0xNf are available for custom use. + */ +/*@{*/ +#define HAB_ALG_ANY 0x0 /**< Algorithm type ANY */ +#define HAB_ALG_HASH 0x1 /**< Hash algorithm type */ +#define HAB_ALG_SIG 0x2 /**< Signature algorithm type */ +#define HAB_ALG_FF 0x3 /**< Finite field arithmetic */ +#define HAB_ALG_EC 0x4 /**< Elliptic curve arithmetic */ +#define HAB_ALG_CIPHER 0x5 /**< Cipher algorithm type */ +#define HAB_ALG_MODE 0x6 /**< Cipher/hash modes */ +#define HAB_ALG_WRAP 0x7 /**< Key wrap algorithm type */ +/*@}*/ + +/** @name Algorithm type ANY + * + * Algorithms of type ANY have no common interface: the protocol must know + * what to do. + */ +/*@{*/ +#ifdef HAB_FUTURE +#define HAB_ALG_RANDOM /**< Random number generation */ +#endif +/* Available values: 03, 05, 06, 09, 0a, 0c, 0f + */ +/*@}*/ + +/** @name Hash algorithms */ +/*@{*/ +#define HAB_ALG_SHA1 0x11 /**< SHA-1 algorithm ID */ +#define HAB_ALG_SHA256 0x17 /**< SHA-256 algorithm ID */ +#define HAB_ALG_SHA512 0x1b /**< SHA-512 algorithm ID */ +/* Available values: 0x14, 0x12, 18, 1d, 1e + */ +/*@}*/ + +/** @name Signature algorithms */ +/*@{*/ +#define HAB_ALG_PKCS1 0x21 /**< PKCS#1 RSA signature algorithm */ +#ifdef HAB_FUTURE +#define HAB_ALG_DSA /**< NIST DSA signature algorithm */ +#define HAB_ALG_ECDSA /**< NIST ECDSA signature algorithm */ +#endif +/* Available values: 22, 24, 27, 28, 2b, 2d, 2e + */ +/*@}*/ + +/** @name Cipher algorithms */ +/*@{*/ +#define HAB_ALG_AES 0x55 /**< AES algorithm ID */ +/* Available values: 50, 53, 56, 59, 5a, 5c, 5f + */ +/*@}*/ + +/** @name Cipher or hash modes */ +/*@{*/ +#define HAB_MODE_CCM 0x66 /**< Counter with CBC-MAC */ +#ifdef HAB_FUTURE +#define HAB_MODE_HMAC /**< HMAC hash mode */ +#endif +/* Available values: 60, 63, 65, 69, 6a, 6c, 6f + */ +/*@}*/ + +/** @name Key wrap algorithms */ +/*@{*/ +#define HAB_ALG_BLOB 0x71 /**< SHW-specific key wrap */ +/* Available values: 72, 74, 77, 78, 7b, 7d, 7e + */ +/*@}*/ + +/* Available values: 81, 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, + * 9c, 9f, a0, a3, a5, a6, a9, aa, ac, af, b1, b2, b4, b7, b8, bb, bd, be, c0, + * c3, c5, c6, c9, ca, cc, cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7, + * e8, eb, ed, ee, f0, f3, f5, f6, f9, fa, fc, ff + */ + +/* @} alg */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup eng + * @{ + */ + +/** @name Engine plugin tags + * @anchor eng_tag + * + * Tag values 0x00 .. 0xef and 0xff are reserved for HAB. Values 0xf0 .. 0xfe + * are available for custom use. + */ +/*@{*/ +#define HAB_ENG_ANY 0x00 /**< First compatible engine will be + * selected automatically (no engine + * configuration parameters are allowed). + */ +#define HAB_ENG_SCC 0x03 /**< Security controller */ +#define HAB_ENG_RTIC 0x05 /**< Run-time integrity checker */ +#define HAB_ENG_SAHARA 0x06 /**< Crypto accelerator */ +#define HAB_ENG_CSU 0x0a /**< Central Security Unit */ +#define HAB_ENG_SRTC 0x0c /**< Secure clock */ +#ifdef HAB_FUTURE +#define HAB_ENG_RNG 0x09 /**< Standalone random number generator */ +#define HAB_ENG_SJC 0x0f /**< Secure JTAG controller */ +#define HAB_ENG_WDOG 0x11 /**< Watchdog timer */ +#define HAB_ENG_SRC 0x12 /**< System Reset Controller */ +#define HAB_ENG_SPBA 0x14 /**< Shared Peripheral Bus Arbiter */ +#define HAB_ENG_IIM 0x17 /**< Fuse controller */ +#define HAB_ENG_IOMUX 0x18 /**< IO multiplexer */ +#endif +#define HAB_ENG_DCP 0x1b /**< Data Co-Processor */ +#define HAB_ENG_CAAM 0x1d /**< Cryptographic Acceleration and + Assurance Module */ +#define HAB_ENG_SNVS 0x1e /**< Secure Non-Volatile Storage */ +#define HAB_ENG_OCOTP 0x21 /**< Fuse controller */ +/** @cond rom */ +#define HAB_ENG_DTCP 0x22 /**< DTCP co-processor */ +#define HAB_ENG_ROM 0x36 /**< Protected ROM area */ +#define HAB_ENG_HDCP 0x24 /**< HDCP co-processor */ +#define HAB_ENG_RTL 0x77 /**< @rom RTL simulation engine */ +/** @endcond */ +#define HAB_ENG_SW 0xff /**< Software engine */ +/* Available values: 27, 28, 2b, 2d, 2e, 30, 33, 35, + * 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b, 4d, 4e, 50, 53, 55, 56, 59, 5a, + * 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71, 72, 74, 78, 7b, 7d, 7e, 81, + * 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, 9c, 9f, a0, a3, a5, a6, + * a9, aa, ac, af, b1, b2, b4, b7, b8, bb, bd, be, c0, c3, c5, c6, c9, ca, cc, + * cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7, e8, eb, ed, ee + * + * Custom values: f0, f3, f5, f6, f9, fa, fc + */ +/*@}*/ + +/* @} eng */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup sah + * @{ + */ + +/** Maximum data blocks in a single hash */ +#define HAB_SAHARA_BLOCK_MAX 12 + +/** @cond rom */ +/** @rom DMA storage requirement + * + * This figure is derived in several parts: + * - each hash operation needs a 6-word descriptor structure + * - each data block needs a 3-word link structure + * - the result needs a 3-word link structure + * - at least 40 bytes are required for SHA-256 result and memory manager + * overhead: 64 bytes allows some small overhead. + */ +#define HAB_SAHARA_DMA_MIN_BYTES (24 + HAB_SAHARA_BLOCK_MAX * 12 + 12 + 64) +/** @endcond */ + +/* @} sah */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup dcp + * @{ + */ + +/** Maximum data blocks in a single hash */ +#define HAB_DCP_BLOCK_MAX 6 + +/** @cond rom */ +/** @rom DMA storage requirement + * + * This figure is derived in two parts: + * - each data block needs an 8-word work packet (descriptor) + * - at least 40 bytes are required for SHA-256 result and memory manager + * overhead: 64 bytes allows some small overhead. + */ +#define HAB_DCP_DMA_MIN_BYTES (64 + HAB_DCP_BLOCK_MAX * 32) +/** @endcond */ + +/* @} dcp */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup rtic + * @{ + */ + +/** Maximum data blocks in a single hash */ +#define HAB_RTIC_BLOCK_MAX 2 + +/* @} rtic */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup scc + * @{ + */ + +/** @cond rom */ +/** @rom DMA storage requirement + * + * This figure is derived in several stages, and assumes plaintext and + * ciphertext buffers are both allocated in the DMA region : + * - 4 blocks of plaintext required + * - 4 blocks of ciphertext required + * - each block is 16 bytes long + * - the plaintext address must be block-aligned (up to 15 bytes overhead) + * - the ciphertext address must be block-aligned (up to 3 bytes overhead) + * - at least 8 bytes of memory manager overhead: allow 32 for comfort + */ +#define HAB_SCC_DMA_MIN_BYTES ( (4+4)*16 + 15 + 3 + 32) +/** @endcond */ + +/* @} scc */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup caam + * @{ + */ + +/** Maximum data blocks in an @ref cmd_aut_dat command */ +#define HAB_CAAM_BLOCK_MAX 8 + +/** @cond rom */ +/** @rom Hash DMA storage requirement + * + * This figure is derived in several parts: + * - each hash operation needs + * - a 7-word descriptor, and + * - a 32-byte result buffer (for SHA-256), + * - giving a base requirement of (7*4 + 32) = 60 bytes + * - each data block needs a 4-word link structure + * - memory manager overhead is at least 8 bytes: 16 bytes allows flexibility + */ +#define HAB_CAAM_HSH_DMA_MIN_BYTES (60 + HAB_CAAM_BLOCK_MAX * 16 + 16) + +/** @rom AEAD DMA storage requirement + * + * This figure is derived in several parts: + * - each AEAD operation needs + * - a 16-word descriptor, + * - a 32-byte initial context value (B0 and CTR0), and + * - a 16-byte MAC value, + * - giving a base requirement of (16*4 + 32 + 16) = 112 bytes + * - each data block needs a 4-word link structure + * - memory manager overhead is at least 8 bytes: 16 bytes allows flexibility + */ +#define HAB_CAAM_CCM_DMA_MIN_BYTES (112 + HAB_CAAM_BLOCK_MAX * 16 + 16) + +/** @rom RNG DMA storage requirement + * + * This figure is derived in several parts: + * - each DRNG test operation allocates a DMA area with + * - a 1-word header, and + * - a 3-word job ring area, and + * - a 54-word descriptor, + * - requiring a total 58*4 = 232 bytes + * - each DRNG test operation also allocates a DMA area with + * - a 1-word header, and + * - a 32-byte result buffer + * - requiring a total 4 + 32 = 36 bytes + */ +#define HAB_CAAM_RNG_DMA_MIN_BYTES (232 + 32) +/** @endcond */ + +/* @} caam */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup key + * @{ + */ + +/** @name Key types + * @anchor key_types + * + * Tag values 0xe0 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff + * are available for custom use. + */ +/*@{*/ +#define HAB_KEY_PUBLIC 0xe1 /**< Public key type: data present */ +#define HAB_KEY_SECRET 0xe2 /**< Secret key type: data present */ +#define HAB_KEY_MASTER 0xed /**< Master KEK type */ +#define HAB_KEY_HASH 0xee /**< Any key type: hash only */ +/* Available values: e4, e7, e8, eb + * + * Custom values: f0, f3, f5, f6, f9, fa, fc, ff + */ +/*@}*/ + +/** @name Public key store indices */ +/*@{*/ +#define HAB_IDX_SRK 0 /**< Super-Root Key index */ +#define HAB_IDX_CSFK 1 /**< CSF key index */ +/*@}*/ + +/** @name Key Counts */ +/*@{*/ +#define HAB_SRK_MIN 1 /**< Minimum Super-Root Key count */ +#define HAB_SRK_MAX 4 /**< Maximum Super-Root Key count */ +#define HAB_KEY_PUBLIC_MAX 5 /**< Maximum installed public key count + * (incl Super-Root Key) + */ +#define HAB_KEY_SECRET_MAX 4 /**< Maximum installed secret key count + * (excl Master KEKs) + */ +/*@}*/ + +/* @} key */ + +/*---------------------------------------------------------------------------*/ + +#ifdef HAB_FUTURE +/** @addtogroup key_ecdsa + * @{ + */ + +/** @name Bitfield definitions */ +/*@{*/ +#define HAB_KEY_ECDSA_FLG_WIDTH 8 /**< Width of @a flg field */ +#define HAB_KEY_ECDSA_FLG_SHIFT 0 /**< Offset of @a flg field */ +#define HAB_KEY_ECDSA_TYP_WIDTH 8 /**< Width of @a typ field */ +#define HAB_KEY_ECDSA_TYP_SHIFT 24 /**< Offset of @a typ field */ +#define HAB_KEY_ECDSA_SIZ_WIDTH 8 /**< Width of @a siz field */ +#define HAB_KEY_ECDSA_SIZ_SHIFT 16 /**< Offset of @a siz field */ +#define HAB_KEY_ECDSA_REDBITS_WIDTH 16 /**< Width of @a red_bits field */ +#define HAB_KEY_ECDSA_REDBITS_SHIFT 0 /**< Offset of @a red_bits field */ +/*@}*/ + +/* @} key_ecdsa */ +#endif + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup key_pkcs1 + * @{ + */ + +/** @name Bitfield definitions */ +/*@{*/ +#define HAB_KEY_PKCS1_FLG_WIDTH 8 /**< Width of @a flg field */ +#define HAB_KEY_PKCS1_FLG_SHIFT 0 /**< Offset of @a flg field */ +#define HAB_KEY_PKCS1_MODBYTES_WIDTH 16 /**< Width of mod_bytes field */ +#define HAB_KEY_PKCS1_MODBYTES_SHIFT 16 /**< Offset of mod_bytes field */ +#define HAB_KEY_PKCS1_EXPBYTES_WIDTH 16 /**< Width of exp_bytes field */ +#define HAB_KEY_PKCS1_EXPBYTES_SHIFT 0 /**< Offset of exp_bytes field */ +/*@}*/ + +/** @name Binding flag bitfield definitions */ +/*@}*/ +#define HAB_KEY_BND_FLG_WIDTH 5 /**< Width of binding flags */ +#define HAB_KEY_BND_FLG_SHIFT 2 /**< Offset of binding flags */ +/*@}*/ + +/* @} key_pkcs1 */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup cmd_wrt_dat + * @{ + */ + +/** @name Parameter bitfield definitions. + * + * Apply to both @ref cmd_wrt_dat and @ref cmd_chk_dat commands. */ +/*@{*/ +#define HAB_CMD_WRT_DAT_FLAGS_WIDTH 5 /**< @a flags field width */ +#define HAB_CMD_WRT_DAT_FLAGS_SHIFT 3 /**< @a flags field offset */ +#define HAB_CMD_WRT_DAT_BYTES_WIDTH 3 /**< @a bytes field width */ +#define HAB_CMD_WRT_DAT_BYTES_SHIFT 0 /**< @a bytes field offset */ +/*@}*/ + +/* @} cmd_wrt_dat */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup bnd_obj + * @{ + */ + +/** @name Binding object IDs + * @anchor bnd_ids + * + * The ASN.1 object identifiers used to identify HAB binding attributes are + * defined in the following arc: + * +@verbatim + id-fsl OBJECT IDENTIFIER ::= { + joint-iso-itu-t(2) country(16) us(840) organization(1) fsl(123456) } + + id-habBnd OBJECT IDENTIFIER ::= { + id-fsl hab(32) binding-objects(16) } + + id-habBnd-dat OBJECT IDENTIFIER ::= { + id-habBnd dat(1) } + + id-habBnd-cfg OBJECT IDENTIFIER ::= { + id-habBnd cfg(3) } + + id-habBnd-fid OBJECT IDENTIFIER ::= { + id-habBnd fid(5) } + + id-habBnd-mid OBJECT IDENTIFIER ::= { + id-habBnd mid(6) } + + id-habBnd-cid OBJECT IDENTIFIER ::= { + id-habBnd cid(9) } +@endverbatim + * + * The ASN.1 object identifiers used to identify HAB binding attributes are + * single component extensions of id-habBnd using a component value less than + * 128 (so that the component can be DER-encoded in a single byte). + * + * The DER encoding of an object identifier in this arc is the concatenation + * of the DER prefix with the single byte identifier for the required binding + * object. Binding object attribute values are encoded as an ASN.1 SET with + * a single OCTET STRING member. + */ +/*@{*/ + +/** DER prefix + * + * @todo update description and encoding of binding object identifiers with + * real fsl value instead of fsl(123456) encoded as 0x87, 0xc4, 0x40, and + * confirm chosen values for hab(32) and binding-objects(16). + */ +#define HAB_BND_DER_PREFIX \ + {0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x87, 0xc4, 0x40, 0x20, 0x10} +#define HAB_BND_DAT 0x01 /**< Data type (mandatory) */ +#define HAB_BND_CFG 0x03 /**< Security configuration */ +#define HAB_BND_FID 0x05 /**< Fabrication UID */ +#define HAB_BND_MID 0x06 /**< Manufacturing ID */ +#define HAB_BND_CID 0x09 /**< Caller ID */ +/* Available values: 0a, 0c, 0f, 11, 12, 14, 17, 18, 1b, 1d, 1e, 21, 22, 24, + * 27, 28, 2b, 2d, 2e, 30, 33, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b, + * 4d, 4e, 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71, + * 72, 74, 77, 78, 7b, 7d, 7e + */ +/*@}*/ + + +/** @name Caller IDs + * + * Only the ROM caller ID is defined, but other caller IDs may be defined by + * later boot stages. + */ +/*@{*/ +#define HAB_CID_ROM 0 /**< ROM Caller ID */ +/*@}*/ + +/* @} bnd_obj */ + +#ifdef HAB_FUTURE +/** @addtogroup sig_fsl + * @{ + */ + +#define HAB_BND_DAT_BYTES 512 /**< Maximum binding data size */ + +/* @} sig_fsl */ +#endif + +/*=========================================================================== + MACROS +=============================================================================*/ +/* + * Helper macros + */ +#define HAB_CMD_UNS 0xff + +#define DEFAULT_IMG_KEY_IDX 2 + +#define GEN_MASK(width) \ + ((1UL << (width)) - 1) + +#define GEN_FIELD(f, width, shift) \ + (((f) & GEN_MASK(width)) << (shift)) + +#define PACK_UINT32(a, b, c, d) \ + ((uint32_t) ( (((uint32_t)(a) & 0xFF) << 24) \ + |(((uint32_t)(b) & 0xFF) << 16) \ + |(((uint32_t)(c) & 0xFF) << 8) \ + |(((uint32_t)(d) & 0xFF)) ) ) + +#define EXPAND_UINT32(w) \ + (uint8_t)((w)>>24), (uint8_t)((w)>>16), (uint8_t)((w)>>8), (uint8_t)(w) + +#define EXPAND_UINT16(w) \ + (uint8_t)((w)>>8), (uint8_t)(w) + +#define HDR(tag, bytes, par) \ + (uint8_t)(tag), (uint8_t)((bytes)>>8), (uint8_t)(bytes), (uint8_t)(par) + +#define HAB_VER(maj, min) \ + (GEN_FIELD((maj), HAB_VER_MAJ_WIDTH, HAB_VER_MAJ_SHIFT) \ + | GEN_FIELD((min), HAB_VER_MIN_WIDTH, HAB_VER_MIN_SHIFT)) + +#define DCD_DATA(addr, data) EXPAND_UINT32(addr), EXPAND_UINT32(data) + +/* + * CSF header + */ + +#define CSF_HDR(bytes, HABVER) \ + HDR(HAB_TAG_CSF, (bytes), HABVER) + + +/* + * DCD header + */ + +#define DCD_HDR(bytes, HABVER) \ + HDR(HAB_TAG_DCD, (bytes), HABVER) + +/* + * IVT header (goes in the struct's hab_hdr_t field, not a byte array) + */ +#define IVT_HDR(bytes, HABVER) \ + {HAB_TAG_IVT, {(uint8_t)((bytes)>>8), (uint8_t)(bytes)}, HABVER} + +/* + * Write Data + */ + +#define WRT_DAT(flags, bytes, address, val_msk) \ + HDR(HAB_CMD_WRT_DAT, WRT_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \ + EXPAND_UINT32(address), \ + EXPAND_UINT32(val_msk) + +#define WRT_DAT_BYTES 12 + +#define MULTI_WRT_DAT(flags, bytes, address1, val_msk1, address2, \ + val_msk2, address3, val_msk3) \ + HDR(HAB_CMD_WRT_DAT, MULTI_WRT_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \ + EXPAND_UINT32(address1), \ + EXPAND_UINT32(val_msk1), \ + EXPAND_UINT32(address2), \ + EXPAND_UINT32(val_msk2), \ + EXPAND_UINT32(address3), \ + EXPAND_UINT32(val_msk3) + +#define MULTI_WRT_DAT_BYTES 28 + +#define WRT_DAT_PAR(flags, bytes) \ + (GEN_FIELD((flags), \ + HAB_CMD_WRT_DAT_FLAGS_WIDTH, \ + HAB_CMD_WRT_DAT_FLAGS_SHIFT) \ + | GEN_FIELD((bytes), \ + HAB_CMD_WRT_DAT_BYTES_WIDTH, \ + HAB_CMD_WRT_DAT_BYTES_SHIFT)) + +/* + * Check Data (forever) + */ + +#define CHK_DAT_FOREVER(flags, bytes, address, mask) \ + HDR(HAB_CMD_CHK_DAT, CHK_DAT_FOREVER_BYTES, WRT_DAT_PAR((flags), (bytes))), \ + EXPAND_UINT32(address), \ + EXPAND_UINT32(mask) + +#define CHK_DAT_FOREVER_BYTES 12 + +/* + * Check Data (polled) + */ +#define HAB_CMD_CHK_DAT_COUNT 100 + +#define CHK_DAT(flags, bytes, address, mask, count) \ + HDR(HAB_CMD_CHK_DAT, CHK_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \ + EXPAND_UINT32(address), \ + EXPAND_UINT32(mask), \ + EXPAND_UINT32(count) + +#define CHK_DAT_BYTES 16 + +/* + * Set (generic - used internally only, or to generate invalid commands) + */ + +#define SET(bytes, itm, value) \ + HDR(HAB_CMD_SET, (bytes), (itm)), \ + EXPAND_UINT32(value) + +/* + * Set (MID location) + */ + +#define SET_MID(bank, row, bit, fuses) \ + HDR(HAB_CMD_SET, SET_MID_BYTES, HAB_VAR_CFG_ITM_MID), \ + (bank), (row), (bit), (fuses) + +#define SET_MID_BYTES 8 + +/* + * Set (default ENG) + */ + +#define SET_ENG(alg, eng, cfg) \ + HDR(HAB_CMD_SET, SET_ENG_BYTES, HAB_VAR_CFG_ITM_ENG), \ + 0, (alg), (eng), (cfg) + +#define SET_ENG_BYTES 8 + +/* + * Init (engine) + */ + +#define INIT(eng) \ + HDR(HAB_CMD_INIT, INIT_BYTES, (eng)) + +#define INIT_BYTES 4 + +/* + * Unlk (engine) + */ + +#define UNLK(eng, ...) \ + UNLK_ ## eng(__VA_ARGS__) + +#define UNLK_BYTES(eng, ...) \ + UNLK_BYTES_ ## eng(__VA_ARGS__) + +#define UNLK_HDR(eng, ...) \ + HDR(HAB_CMD_UNLK, UNLK_BYTES_ ## eng(__VA_ARGS__), eng) + +#define UNLK_FLG(flg) \ + 0, 0, 0, (uint8_t)(flg) + +#define UNLK_FLG_BYTES 4 + +#define UNLK_HAB_ENG_SRTC(dnc) UNLK_HDR(HAB_ENG_SRTC) +#define UNLK_BYTES_HAB_ENG_SRTC(dnc) HDR_BYTES + +#define UNLK_HAB_ENG_SNVS(flg) UNLK_HDR(HAB_ENG_SNVS), UNLK_FLG(flg) +#define UNLK_BYTES_HAB_ENG_SNVS(flg) (HDR_BYTES + UNLK_FLG_BYTES) + +#define UNLK_HAB_ENG_CAAM(flg) UNLK_HDR(HAB_ENG_CAAM), UNLK_FLG(flg) +#define UNLK_BYTES_HAB_ENG_CAAM(flg) (HDR_BYTES + UNLK_FLG_BYTES) + +/* The next definition uses a GCC extension employing ## to swallow the + * trailing comma in case the macro is called with only the fixed arguments + * (i.e. flg here). This extension appears to work in the GNU compatible mode + * of RVDS and GHS compilers. + */ +#define UNLK_HAB_ENG_OCOTP(flg, ...) \ + UNLK_HDR(HAB_ENG_OCOTP, flg), UNLK_FLG(flg), ## __VA_ARGS__ + +#define UNLK_BYTES_HAB_ENG_OCOTP(flg, ...) \ + (HDR_BYTES + UNLK_FLG_BYTES \ + + ( ((flg) & (HAB_OCOTP_UNLOCK_FIELD_RETURN \ + |HAB_OCOTP_UNLOCK_JTAG \ + |HAB_OCOTP_UNLOCK_SCS)) \ + ? STUB_FAB_UID_BYTES \ + : 0 )) + +#if 0 +/* Note: no comma after HDR(). Supplied by _VAL macro if needed */ +#define UNLK(eng, val) \ + HDR(HAB_CMD_UNLK, UNLK_BYTES_ ## eng, (eng)) \ + UNLK_VAL_ ## eng(val) + +#define UNLK_BYTES(eng) \ + UNLK_BYTES_ ## eng + +#define UNLK_BYTES_HAB_ENG_SRTC HDR_BYTES +#define UNLK_VAL_HAB_ENG_SRTC(val) /* no val field */ +#define UNLK_BYTES_HAB_ENG_SNVS (HDR_BYTES + 4) +#define UNLK_VAL_HAB_ENG_SNVS(val) ,0,0,0,((val)&0xff) +#define UNLK_BYTES_HAB_ENG_CAAM (HDR_BYTES + 4) +#define UNLK_VAL_HAB_ENG_CAAM(val) ,0,0,0,((val)&0xff) +#endif + +/* + * NOP + */ + +#define NOP() \ + HDR(HAB_CMD_NOP, NOP_BYTES, 0xae) /* third param is ignored */ + +#define NOP_BYTES 4 + +/* + * Install Key (generic - used internally only) + */ + +#define INS_KEY(bytes, flg, pcl, alg, src, tgt, crt) \ + HDR(HAB_CMD_INS_KEY, (bytes), (flg)), \ + (pcl), (alg), (src), (tgt), \ + EXPAND_UINT32(crt) + +#define INS_KEY_BASE_BYTES 12 + +/* + * Install Key (SRK) + */ + +#define INS_SRK(flg, alg, src, crt) \ + INS_KEY(INS_SRK_BYTES, (flg), \ + HAB_PCL_SRK, (alg), (src), HAB_IDX_SRK, \ + (crt)) + +#define INS_SRK_BYTES INS_KEY_BASE_BYTES + +/* + * Install Key (CSFK) + */ + +#define INS_CSFK(flg, pcl, crt) \ + INS_KEY(INS_CSFK_BYTES, (flg) | HAB_CMD_INS_KEY_CSF, \ + (pcl), HAB_ALG_ANY, HAB_IDX_SRK, HAB_IDX_CSFK, \ + (crt)) + +#define INS_CSFK_BYTES INS_KEY_BASE_BYTES + +/* + * Install Key (IMGK - no hash) + */ + +#define INS_IMGK(flg, pcl, src, tgt, crt) \ + INS_KEY(INS_IMGK_BYTES, (flg), \ + (pcl), HAB_ALG_ANY, (src), (tgt), \ + (crt)) + +#define INS_IMGK_BYTES INS_KEY_BASE_BYTES + + +/* + * Install Key (IMGK - with hash). Must be followed by the crt_hsh contents + * (e.g. using #include). The length field depends on using one of the + * standard HAB algorithm names, with no adornments like casts or + * parentheses. Note that the length macro cannot be used here: the ## + * must appear in the body of this macro to prevent the alg parameter from + * being expanded first. + */ + +#define INS_IMGK_HASH(flg, pcl, alg, src, tgt, crt) \ + INS_KEY(INS_KEY_BASE_BYTES + BYTES_ ## alg, (flg) | HAB_CMD_INS_KEY_HSH, \ + (pcl), (alg), (src), (tgt), \ + (crt)) + +/* + * Same as above but the hash length is fixed to the length of SHA1, + * but the algorithm remains unchanged. + */ +#define INS_IMGK_INV_HASH(flg, pcl, alg, src, tgt, crt) \ + INS_KEY(INS_IMGK_HASH_BYTES(HAB_ALG_SHA1), (flg) | HAB_CMD_INS_KEY_HSH, \ + (pcl), (alg), (src), (tgt), \ + (crt)) + + +#define INS_IMGK_HASH_BYTES(alg) \ + (INS_KEY_BASE_BYTES + BYTES_ ## alg) + +#define BYTES_HAB_ALG_SHA1 20 +#define BYTES_HAB_ALG_SHA256 32 +#define BYTES_HAB_ALG_SHA512 64 +/* dummy value for invalid hash alg - same as default hash algorithm */ +#define DEFAULT_HASH_ALG_BYTES BYTES_HAB_ALG_SHA256 +#define BYTES_HAB_ALG_PKCS1 DEFAULT_HASH_ALG_BYTES + +/* + * Authenticate Data (generic - used internally only) + */ + +#define AUT_DAT(bytes, flg, key, pcl, eng, cfg, sig_start) \ + HDR(HAB_CMD_AUT_DAT, (bytes), (flg)), \ + (key), (pcl), (eng), (cfg), \ + EXPAND_UINT32(sig_start) + +#define AUT_DAT_BASE_BYTES 12 + +/* + * Authenticate Data (CSF) + */ + +#define AUT_CSF(flg, pcl, eng, cfg, sig_start) \ + AUT_DAT(AUT_CSF_BYTES, (flg), \ + HAB_IDX_CSFK, (pcl), (eng), (cfg), \ + (sig_start)) + +#define AUT_CSF_BYTES AUT_DAT_BASE_BYTES + +/* + * Authenticate Data (Image) + */ + +#define AUT_IMG(blocks, flg, key, pcl, eng, cfg, sig_start) \ + AUT_DAT(AUT_IMG_BYTES(blocks), (flg), \ + (key), (pcl), (eng), (cfg), \ + (sig_start)) + +#define AUT_IMG_BYTES(blocks) \ + (AUT_DAT_BASE_BYTES + 8*(blocks)) + +/** Supported widths of data commands. + * @ingroup cmd_wrt_dat + */ +typedef enum hab_data_width +{ + HAB_DATA_WIDTH_BYTE = 1, /**< 8-bit value */ + HAB_DATA_WIDTH_HALF = 2, /**< 16-bit value */ + HAB_DATA_WIDTH_WORD = 4 /**< 32-bit value */ +} hab_data_width_t; + + +/** Flags for Write Data commands. + * @ingroup cmd_wrt_dat + */ +typedef enum hab_cmd_wrt_dat_flg +{ + HAB_CMD_WRT_DAT_MSK = 1, /**< Mask/value flag: if set, only specific + * bits may be overwritten at target address + * (otherwise all bits may be overwritten) + */ + HAB_CMD_WRT_DAT_SET = 2 /**< Set/clear flag: if #HAB_CMD_WRT_DAT_MSK + * set, bits at the target address overwritten + * with this flag (otherwise it is ignored) + */ +} hab_cmd_wrt_dat_flg_t; + +/** Flags for Check Data commands. + * @ingroup cmd_chk_dat + */ +typedef enum hab_cmd_chk_dat_flg +{ + HAB_CMD_CHK_DAT_SET = 2, /**< Set/clear flag: bits set in mask must + * match this flag + */ + HAB_CMD_CHK_DAT_ANY = 4 /**< Any/all flag: if clear, all bits set in + * mask must match (otherwise any bit + * suffices) + */ +} hab_cmd_chk_dat_flg_t; + +/** Flags for Authenticate Data commands. + * @ingroup cmd_aut_dat + */ +typedef enum hab_cmd_aut_dat_flg +{ + HAB_CMD_AUT_DAT_CLR = 0, /**< No flags set */ + HAB_CMD_AUT_DAT_ABS = 1 /**< Absolute signature address */ +} hab_cmd_aut_dat_flg_t; + +/** Flags for Install Key commands. + * @ingroup cmd_ins_key + */ +typedef enum hab_cmd_ins_key_flg +{ + HAB_CMD_INS_KEY_CLR = 0, /**< No flags set */ + HAB_CMD_INS_KEY_ABS = 1, /**< Absolute certificate address */ + HAB_CMD_INS_KEY_CSF = 2, /**< Install CSF key */ + HAB_CMD_INS_KEY_DAT = 4, /**< Key binds to Data Type */ + HAB_CMD_INS_KEY_CFG = 8, /**< Key binds to Configuration */ + HAB_CMD_INS_KEY_FID = 16, /**< Key binds to Fabrication UID */ + HAB_CMD_INS_KEY_MID = 32, /**< Key binds to Manufacturing ID */ + HAB_CMD_INS_KEY_CID = 64, /**< Key binds to Caller ID */ + HAB_CMD_INS_KEY_HSH = 128 /**< Certificate hash present */ +} hab_cmd_ins_key_flg_t; + +/** Key flags. + * @ingroup key_pkcs1 + * + * @ifrom + * + * The binding flags given here align with those in #hab_cmd_ins_key_flg + * + * @endrom + * + */ +typedef enum hab_key_flg +{ + /* Two more flag values available */ + HAB_KEY_FLG_DAT = 4, /**< Key binds to Data Type */ + HAB_KEY_FLG_CFG = 8, /**< Key binds to Configuration */ + HAB_KEY_FLG_FID = 16, /**< Key binds to Fabrication UID */ + HAB_KEY_FLG_MID = 32, /**< Key binds to Manufacturing ID */ + HAB_KEY_FLG_CID = 64, /**< Key binds to Caller ID */ + HAB_KEY_FLG_CA = 128 /**< CA key */ +} hab_key_flg_t; + +/** Secret key flags. + * @ingroup crt_blob + */ +typedef enum hab_key_secret_flg +{ + /* Seven more flag values available */ + HAB_KEY_FLG_KEK = 128 /**< KEK */ +} hab_key_secret_flg_t; + +/** Binding data types + * @ingroup bnd_obj + */ +typedef enum hab_dat { + HAB_DAT_CSF = 0x0f, /**< CSF signature */ + HAB_DAT_IMG = 0x33, /**< Image signature */ +#ifdef HAB_FUTURE + HAB_DAT_PLG = 0x3c, /**< Plugin signature */ +#endif + HAB_DAT_MAX +} hab_dat_t; + +/* Available values: 55, 5a, 66, 69, 96, 99, a5, aa, c3, cc, f0, ff + */ + +/** Target check types + * @ingroup chk_tgt + */ +typedef enum hab_target { + HAB_TGT_MEMORY = 0x0f, /**< Check memory white list */ + HAB_TGT_PERIPHERAL = 0xf0, /**< Check peripheral white list */ + HAB_TGT_ANY = 0x55, /**< Check memory & peripheral white list */ + HAB_TGT_MAX +} hab_target_t; + +/** Security configuration types + * @ingroup status + */ +typedef enum hab_config { +/** @cond rom */ + HAB_CFG_FAB = 0x00, /**< @rom Un-programmed IC */ +/** @endcond */ + HAB_CFG_RETURN = 0x33, /**< Field Return IC */ + HAB_CFG_OPEN = 0xf0, /**< Non-secure IC */ + HAB_CFG_CLOSED = 0xcc /**< Secure IC */ +} hab_config_t; +/* Available values: 0f, 3c, 55, 5a, 66, 69, 96, 99, a5, aa, ff + */ + +/** Security state types + * @ingroup status + */ +typedef enum hab_state { + HAB_STATE_INITIAL = 0x33, /**< Initialising state (transitory) */ + HAB_STATE_CHECK = 0x55, /**< Check state (non-secure) */ + HAB_STATE_NONSECURE = 0x66, /**< Non-secure state */ + HAB_STATE_TRUSTED = 0x99, /**< Trusted state */ + HAB_STATE_SECURE = 0xaa, /**< Secure state */ + HAB_STATE_FAIL_SOFT = 0xcc, /**< Soft fail state */ + HAB_STATE_FAIL_HARD = 0xff, /**< Hard fail state (terminal) */ + HAB_STATE_NONE = 0xf0, /**< No security state machine */ + HAB_STATE_MAX +} hab_state_t; +/* Available values: 00, 0f, 3c, 5a, 69, 96, a5, c3 + */ + +/** HAB status types + * @ingroup status + */ +typedef enum hab_status { + HAB_STS_ANY = 0x00, /**< Match any status in + * hab_rvt.report_event() + */ + HAB_FAILURE = 0x33, /**< Operation failed */ + HAB_WARNING = 0x69, /**< Operation completed with warning */ + HAB_SUCCESS = 0xf0, /**< Operation completed successfully */ + HAB_STS_MAX +} hab_status_t; + +/** Failure or warning reasons + * @ingroup evt + * + * Values 0x80 ... 0xff are reserved for internal use. + */ +typedef enum hab_reason { + HAB_RSN_ANY = 0x00, /**< Match any reason in + * hab_rvt.report_event() + */ + HAB_ENG_FAIL = 0x30, /**< Engine failure. */ + HAB_INV_ADDRESS = 0x22, /**< Invalid address: access denied. */ + HAB_INV_ASSERTION = 0x0c, /**< Invalid assertion. */ + HAB_INV_CALL = 0x28, /**< Function called out of sequence. */ + HAB_INV_CERTIFICATE = 0x21, /**< Invalid certificate. */ + HAB_INV_COMMAND = 0x06, /**< Invalid command: command malformed. */ + HAB_INV_CSF = 0x11, /**< Invalid @ref csf. */ + HAB_INV_DCD = 0x27, /**< Invalid @ref dcd. */ + HAB_INV_INDEX = 0x0f, /**< Invalid index: access denied. */ + HAB_INV_IVT = 0x05, /**< Invalid @ref ivt. */ + HAB_INV_KEY = 0x1d, /**< Invalid key. */ + HAB_INV_RETURN = 0x1e, /**< Failed callback function. */ + HAB_INV_SIGNATURE = 0x18, /**< Invalid signature. */ + HAB_INV_SIZE = 0x17, /**< Invalid data size. */ + HAB_MEM_FAIL = 0x2e, /**< Memory failure. */ + HAB_OVR_COUNT = 0x2b, /**< Expired poll count. */ + HAB_OVR_STORAGE = 0x2d, /**< Exhausted storage region. */ + HAB_UNS_ALGORITHM = 0x12, /**< Unsupported algorithm. */ + HAB_UNS_COMMAND = 0x03, /**< Unsupported command. */ + HAB_UNS_ENGINE = 0x0a, /**< Unsupported engine. */ + HAB_UNS_ITEM = 0x24, /**< Unsupported configuration item. */ + HAB_UNS_KEY = 0x1b, /**< Unsupported key type or parameters. */ + HAB_UNS_PROTOCOL = 0x14, /**< Unsupported protocol. */ + HAB_UNS_STATE = 0x09, /**< Unsuitable state. */ + HAB_RSN_MAX +} hab_reason_t; +/* Available values: 33, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44, + * 47, 48, 4b, 4d, 4e, 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a, + * 6c, 6f, 71, 72, 74, 77, 78, 7b, 7d, 7e + */ + +/** Audit logging contexts. + * @ingroup evt + * + * This list is sorted in order of increasing priority: where two contexts + * might apply, the latter one is used. + * + * Values 0x40 .. 0x5f are reserved for internal use. + */ +typedef enum hab_context { + HAB_CTX_ANY = 0x00, /**< Match any context in + * hab_rvt.report_event() + */ +/** @cond rom */ + HAB_CTX_FAB = 0xff, /**< @rom Event logged in hab_fab_test() */ +/** @endcond */ + HAB_CTX_ENTRY = 0xe1, /**< Event logged in hab_rvt.entry() */ + HAB_CTX_TARGET = 0x33, /**< Event logged in hab_rvt.check_target() */ + HAB_CTX_AUTHENTICATE = 0x0a, /**< Event logged in + * hab_rvt.authenticate_image() + */ + HAB_CTX_DCD = 0xdd, /**< Event logged in hab_rvt.run_dcd() */ + HAB_CTX_CSF = 0xcf, /**< Event logged in hab_rvt.run_csf() */ + HAB_CTX_COMMAND = 0xc0, /**< Event logged executing @ref csf or @ref + * dcd command + */ + HAB_CTX_AUT_DAT = 0xdb, /**< Authenticated data block */ + HAB_CTX_ASSERT = 0xa0, /**< Event logged in hab_rvt.assert() */ + HAB_CTX_EXIT = 0xee, /**< Event logged in hab_rvt.exit() */ + HAB_CTX_MAX +} hab_context_t; + +/** Assertion types. + * @ingroup assert + */ +typedef enum hab_assertion { + HAB_ASSERT_BLOCK = 0, /**< Assert that a memory block was authenticated */ + HAB_ASSERT_MAX +} hab_assertion_t; + +/** RTIC configuration flags + * @ingroup rtic + */ +typedef enum hab_rtic_config { + HAB_RTIC_IN_SWAP8 = 0x01, /**< Set BYTE SWAP bit (reverse bytes within + * word on input to RTIC) */ + HAB_RTIC_IN_SWAP16 = 0x02, /**< Set HALF WORD SWAP bit (reverse + * half-words within word on input to + * RTIC) */ + HAB_RTIC_OUT_SWAP8 = 0x08, /**< Set HASH RESULT BYTE SWAP bit (reverse + * bytes within word on output from RTIC) */ + HAB_RTIC_KEEP = 0x80 /**< Retain reference hash value for later + * monitoring */ +} hab_rtic_config_t; + +/** SAHARA configuration flags + * @ingroup sah + */ +typedef enum hab_sahara_config { + HAB_SAHARA_IN_SWAP8 = 0x01, /**< Set MESS BYTE SWAP bit (reverse message + * bytes within word on input to + * SAHARA) */ + HAB_SAHARA_IN_SWAP16 = 0x02, /**< Set MESS HALF WORD SWAP bit (reverse + * message half-words within word on input + * to SAHARA) */ + /* no SWAP32 for SAHARA message - leave 0x04 value unassigned */ + /* no SWAP8 for SAHARA descriptors/links - leave 0x08 value unassigned */ + HAB_SAHARA_DSC_BE8_16 = 0x10, /**< Interpret descriptors and links as for + * BE-8 16-bit memory. */ + HAB_SAHARA_DSC_BE8_32 = 0x20 /**< Interpret descriptors and links as for + * BE-8 32-bit memory. */ +} hab_sahara_config_t; + +/** CAAM configuration flags + * @ingroup caam + */ +typedef enum hab_caam_config { + HAB_CAAM_IN_SWAP8 = 0x01, /**< Set Message Byte Swap Input bit (reverse + * message bytes within word on input to + * CAAM) */ + HAB_CAAM_IN_SWAP16 = 0x02, /**< Set Message Half Word Swap Input bit + * (reverse message half-words within word + * on input to CAAM) */ + /* no SWAP32 for CAAM message - leave 0x04 value unassigned */ + HAB_CAAM_OUT_SWAP8 = 0x08, /**< Set Message Byte Swap Output bit + * (reverse message bytes within word on + * output from CAAM) */ + HAB_CAAM_OUT_SWAP16 = 0x10, /**< Set Message Half Word Swap Output bit + * (reverse message half-words within word + * on output from CAAM) */ + /* no SWAP32 for CAAM message - leave 0x20 value unassigned */ + HAB_CAAM_DSC_SWAP8 = 0x40, /**< Set Control Byte Swap Input/Output bits + * (reverse descriptor/link bytes within + * word on input to or output from CAAM) */ + HAB_CAAM_DSC_SWAP16 = 0x80 /**< Set Control Half Word Swap Input/Output + * bits (reverse descriptor/link half-words + * within word on input to or output from + * CAAM) */ +} hab_caam_config_t; + +/** CAAM unlock flags + * @ingroup caam + */ +typedef enum hab_caam_unlock_flag { + HAB_CAAM_UNLOCK_MID = 0x01, /**< Leave Job Ring and DECO master ID + * registers unlocked */ + HAB_CAAM_UNLOCK_RNG = 0x02 /**< Leave RNG state handle 0 + * uninstantiated, do not generate + * descriptor keys, do not set AES DPA + * mask, do not block state handle 0 test + * instantiation */ +} hab_caam_unlock_flag_t; + +/** SNVS unlock flags + * @ingroup snvs + */ +typedef enum hab_snvs_unlock_flag { + HAB_SNVS_UNLOCK_LP_SWR = 0x01, /**< Leave LP SW reset unlocked */ + HAB_SNVS_UNLOCK_ZMK_WRITE = 0x02 /**< Leave Zeroisable Master Key write + * unlocked */ +} hab_snvs_unlock_flag_t; + +/** SNVS master keys + * @ingroup snvs + * + * @remark Note that the first two master key selections are completely + * interchangeable. + */ +typedef enum hab_snvs_keys { + HAB_SNVS_OTPMK = 0, /**< OTP master key */ + HAB_SNVS_OTPMK_ALIAS = 1, /**< OTP master key (alias) */ + HAB_SNVS_ZMK = 2, /**< Zeroisable master key */ + HAB_SNVS_CMK = 3 /**< Combined master key */ +} hab_snvs_keys_t; + + +/** OCOTP unlock flags + * @ingroup ocotp + */ +typedef enum hab_ocotp_unlock_flag { + HAB_OCOTP_UNLOCK_FIELD_RETURN = 0x01, /**< Leave Field Return activation + * unlocked */ + HAB_OCOTP_UNLOCK_SRK_REVOKE = 0x02, /**< Leave SRK revocation unlocked */ + HAB_OCOTP_UNLOCK_SCS = 0x04, /**< Leave SCS register unlocked */ + HAB_OCOTP_UNLOCK_JTAG = 0x08 /**< Unlock JTAG using SCS HAB_JDE + * bit */ +} hab_ocotp_unlock_flag_t; + +/** DCP configuration flags + * @ingroup dcp + * + * @warning The byte-swapping controls produce unpredictable results unless + * the input data block lengths are multiples of 4 bytes. + */ +typedef enum hab_dcp_config { + HAB_DCP_IN_SWAP8 = 0x01, /**< Set INPUT BYTE SWAP bit (reverse bytes + * within words on input to DCP) */ + /* no SWAP16 for DCP - leave 0x02 value unassigned */ + HAB_DCP_IN_SWAP32 = 0x04, /**< Set INPUT WORD SWAP bit (ignored for + * hashing) */ + HAB_DCP_OUT_SWAP8 = 0x08, /**< Set OUPUT BYTE SWAP bit (reverse bytes + * within words on output from DCP) */ + /* no SWAP16 for DCP - leave 0x10 value unassigned */ + HAB_DCP_OUT_SWAP32 = 0x20 /**< Set OUTPUT WORD SWAP bit (ignored for + * hashing) */ +} hab_dcp_config_t; + +#ifdef HAB_FUTURE +/** EC key specification types. + * @ingroup key_ecdsa + */ +typedef enum hab_ec_spec { + /** Named curve specification. The curve specification is a DER-encoded + * object identifier. Supported object identifiers are listed under @ref + * key_ecdsa_profile "ECDSA key profile". + */ + HAB_EC_SPEC_NAMED_CURVE = 0x01 +} hab_ec_spec_t; +#endif + +/** Variable configuration items + * @ingroup cmd_set + */ +typedef enum hab_var_cfg_itm { + HAB_VAR_CFG_ITM_MID = 0x01, /**< Manufacturing ID (MID) fuse locations */ + HAB_VAR_CFG_ITM_ENG = 0x03 /**< Preferred engine for a given algorithm */ +} hab_var_cfg_itm_t; + +/*=========================================================================== + ENUMS +=============================================================================*/ + +/*=========================================================================== + STRUCTURES AND OTHER TYPEDEFS +=============================================================================*/ + +/** Header field components + * @ingroup hdr + */ +typedef struct hab_hdr { + uint8_t tag; /**< Tag field */ + uint8_t len[2]; /**< Length field in bytes (big-endian) */ + uint8_t par; /**< Parameters field */ +} hab_hdr_t; + +/** Loader callback. + * @ingroup auth_img + * + * @par Purpose + * + * This function must be supplied by the library caller if required. It is + * intended to finalise image loading in those boot modes where only a portion + * of the image is loaded to a temporary initial location prior to device + * configuration. + * + * @par Operation + * + * This function is called during hab_rvt.authenticate_image() between running + * the @ref dcd and @ref csf. The operation of this function is defined by + * the caller. + * + * @param[in,out] start Initial (possibly partial) image load address on + * entry. Final image load address on exit. + * + * @param[in,out] bytes Initial (possibly partial) image size on entry. Final + * image size on exit. + * + * @param[in] boot_data Initial @ref ivt Boot Data load address. + * + * @remark The interpretation of the Boot Data is defined by the caller. + * Different boot components or modes may use different boot data, or even + * different loader callback functions. + * + * @warning It should not be assumed by this function that the Boot Data is + * valid or authentic. + * + * @warning It is the responsibility of the loader callback to check the final + * image load addresses using hab_rvt.check_target() prior to copying any image + * data. + * + * @pre The (possibly partial) image has been loaded in the initial load + * address, and the Boot Data is within the initial image. + * + * @pre The @ref dcd has been run, if provided. + * + * @post The final image load addresses pass hab_rvt.check_target(). + * + * @retval #HAB_SUCCESS if all operations completed successfully, + * + * @retval #HAB_FAILURE otherwise. + */ +typedef hab_status_t (*hab_loader_callback_f)( + void** start, + size_t* bytes, + const void* boot_data); + +/*---------------------------------------------------------------------------*/ + +/** Image entry function prototype + * @ingroup rvt + * + * This typedef serves as the return type for hab_rvt.authenticate_image(). It + * specifies a void-void function pointer, but can be cast to another function + * pointer type if required. + */ +typedef void (*hab_image_entry_f)(void); + +/*---------------------------------------------------------------------------*/ + +/** @ref rvt structure + * @ingroup rvt + * + * @par Format + * + * The @ref rvt consists of a @ref hdr followed by a list of addresses as + * described further below. + */ +struct hab_rvt { + + /** @ref hdr with tag #HAB_TAG_RVT, length and HAB version fields + * (see @ref data) + */ + hab_hdr_t hdr; + + /** Enter and initialise HAB library. + * @ingroup entry + * + * @par Purpose + * + * This function initialises the HAB library and @ref shw plugins. It is + * intended for use by post-ROM boot stage components, via the @ref rvt, + * prior to calling any other HAB functions other than + * hab_rvt.report_event() and hab_rvt.report_status(). + * + * @ifrom It is also intended for use by the boot ROM via hab_rvt.entry(). + * @endrom + * + * @par Operation + * + * This function performs the following operations every time it is called: + * + * - Initialise the HAB library internal state + * - Initialise the internal secret key store (cleared at the next + * hab_rvt.exit()) + * - Run the entry sequence of each available @ref shw plugin + * + * When first called from boot ROM, this function also performs the + * following operations prior to those given above: + * + * - Initialise the internal public key store (persists beyond + * hab_rvt.exit()) + * - Run the self-test sequence of each available @ref shw plugin + * - If a state machine is present and enabled, change the security state + * as follows: + * - If the IC is configured as #HAB_CFG_OPEN or #HAB_CFG_RETURN, move to + * #HAB_STATE_NONSECURE + * - If the IC is configured as #HAB_CFG_CLOSED, move to + * #HAB_STATE_TRUSTED + * - Otherwise, leave the security state unchanged + * + * If any failure occurs in the operations above: + * + * - An audit event is logged + * - All remaining operations are abandoned (except that all @ref shw + * self-test and entry sequences are still executed) + * - If a state machine is present and enabled, the security state is set + * as follows: + * - @ifrom Unless the IC is configured as #HAB_CFG_FAB,@endrom move to + * #HAB_STATE_NONSECURE. Note that if a security violation has been + * detected by the HW, the final state will be #HAB_STATE_FAIL_SOFT or + * #HAB_STATE_FAIL_HARD depending on the HW configuration. + * + * @warning Boot sequences may comprise several images with each launching + * the next as well as alternative images should one boot device or boot + * image be unavailable or unusable. The authentication of each image in + * a boot sequence must be bracketed by its own hab_rvt.entry() + * ... hab_rvt.exit() pair in order to ensure that security state + * information gathered for one image cannot be misapplied to another + * image. + * + * @ifrom + * + * @warning This applies to each boot path in boot ROM as well, except for + * the fabrication test path. + * + * @endrom + * + * @post HAB library internal state is initialised. + * + * @post Available @ref shw plugins are initialised. + * + * @post If a failure or warning occurs during @ref shw plugin + * initialisation, an audit event is logged with the relevant @ref eng + * tag. The status and reason logged are described in the relevant @ref + * shw plugin documentation. + * + * @post Security state is initialised, if a state machine is present and + * enabled. + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if all commands completed + * without failure (even if warnings were generated), + * + * @retval #HAB_FAILURE otherwise. + */ + hab_status_t (*entry)(void); + + /** Finalise and exit HAB library. + * @ingroup exit + * + * @par Purpose + * + * This function finalises the HAB library and @ref shw plugins. It is + * intended for use by post-ROM boot stage components, via the @ref rvt, + * after calling other HAB functions and prior to launching the next boot + * stage or switching to another boot path. + * + * @ifrom It is also intended for use by the boot ROM via hab_rvt.exit(). + * @endrom + * + * @par Operation + * + * This function performs the following operations: + * + * - Finalise the HAB library internal state + * - Clear the internal secret key store + * - Run the finalisation sequence of each available @ref shw plugin + * + * If any failure occurs, an audit event is logged and all remaining + * operations are abandoned (except that all @ref shw exit sequences are + * still executed). + * + * @warning See warnings for hab_rvt.entry(). + * + * @post #HAB_ASSERT_BLOCK records are cleared from audit log. Note that + * other event records are not cleared. + * + * @post Any public keys installed by @ref csf commands remain active. + * + * @post Any secret keys installed by @ref csf commands are deleted. + * + * @post Available @ref shw plugins are in their final state as described + * in the relevant sections. + * + * @post If a failure or warning occurs, an audit event is logged with the + * @ref eng tag of the @ref shw plugin concerned. The status and reason + * logged are described in the relevant @ref shw plugin documentation. + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if all commands completed + * without failure (even if warnings were generated), + * + * @retval #HAB_FAILURE otherwise. + */ + hab_status_t (*exit)(void); + + /** Check target address + * @ingroup chk_tgt + * + * @par Purpose + * + * This function reports whether or not a given target region is allowed + * for either peripheral configuration or image loading in memory. It is + * intended for use by post-ROM boot stage components, via the @ref rvt, + * in order to avoid configuring security-sensitive peripherals, or + * loading images over sensitive memory regions or outside recognised + * memory devices in the address map. + * + * @ifrom It is also available for use by the boot ROM, both directly via + * hab_rvt.check_target() and indirectly via hab_rvt.authenticate_image(). + * @endrom + * + * @par Operation + * + * The lists of allowed target regions vary by IC and core, and should be + * taken from the @ref ref_rug. + * + * @ifrom The allowed register sets for peripheral configuration and memory + * regions for image loading are defined in the @ref hal by + * #hab_hal_peripheral and #hab_hal_memory respectively. @endrom + * + * @param[in] type Type of target (memory, peripheral or any in which both + * the memory and peripheral regions are checked) + * + * @param[in] start Address of target region + * + * @param[in] bytes Size of target region + * + * @post if the given target region goes beyond the allowed regions, an + * audit event is logged with status #HAB_FAILURE and reason + * #HAB_INV_ADDRESS, together with the call parameters. See the @ref evt + * record documentation for details. + * + * @post For successful commands, no audit event is logged. + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS if the given target region lies wholly within the + * allowed regions for the requested type of target. + * + * @retval #HAB_FAILURE otherwise + */ + hab_status_t (*check_target)(hab_target_t type, + const void* start, + size_t bytes); + + /** Authenticate image. + * @ingroup auth_img + * + * @par Purpose + * + * This function combines DCD, CSF and Assert functions in a standard + * sequence in order to authenticate a loaded image. It is intended for + * use by post-ROM boot stage components, via the @ref rvt. Support for + * images partially loaded to an initial location is provided via a + * callback function. + * + * @ifrom It is also available for use by the boot ROM via + * hab_rvt.authenticate_image(). @endrom + * + * @par Operation + * + * This function performs the following sequence of operations: + * - Check that the initial image load addresses pass + * hab_rvt.check_target(). + * - Check that the IVT offset lies within the initial image bounds. + * - Check that the @ref ivt @a self and @a entry pointers are not NULL + * - Check the @ref ivt header for consistency and compatability. + * - If provided in the @ref ivt, calculate the @ref dcd initial location, + * check that it lies within the initial image bounds, and run the @ref + * dcd commands. + * - If provided in the @ref ivt, calculate the Boot Data initial location + * and check that it lies within the initial image bounds. + * - If provided in the parameters, invoke the callback function with the + * initial image bounds and initial location of the @ref ivt Boot Data. + * + * From this point on, the full image is assumed to be in its final + * location. The following operations will be performed on all IC + * configurations (#hab_config), but will be only enforced on an IC + * configured as #HAB_CFG_CLOSED: + * - Check that the final image load addresses pass hab_rvt.check_target(). + * - Check that the CSF lies within the image bounds, and run the CSF + * commands. + * - Check that all of the following data have been authenticated (using + * their final locations): + * - IVT; + * - DCD (if provided); + * - Boot Data (initial byte if provided); + * - Entry point (initial word). + * + * @param[in] cid Caller ID, used to identify which SW issued this call. + * + * @param[in] ivt_offset Offset in bytes of the IVT from the image start + * address. + * + * @param[in,out] start Initial (possibly partial) image load address on + * entry. Final image load address on exit. + * + * @param[in,out] bytes Initial (possibly partial) image size on entry. + * Final image size on exit. + * + * @param[in] loader Callback function to load the full image to its final + * load address. Set to NULL if not required. + * + * @remark Caller ID may be bound to signatures verified using keys + * installed with #HAB_CMD_INS_KEY_CID flag. See @ref cmd_ins_key and @ref + * bnd_obj for details. + * + * @remark A @a loader callback function may be supplied even if the image + * is already loaded to its final location on entry. + * + * @remark Boot Data (boot_data in @ref ivt) will be ignored if the + * @a loader callback function point is set to Null. + * + * @warning The @a loader callback function should lie within existing + * authenticated areas. @ifrom Or within the ROM. @endrom + * + * @warning It is the responsibility of the caller to check the initial + * image load addresses using hab_rvt.check_target() prior to loading the + * initial image and calling this function. + * + * @warning After completion of hab_rvt.authenticate_image(), the caller + * should test using hab_rvt.assert() that the Boot Data was + * authenticated. + * + * @post The post-conditions of the functions hab_rvt.check_target(), + * hab_rvt.run_dcd(), hab_rvt.run_csf() and hab_rvt.assert() apply also to + * this function. In particular, any audit events logged within the given + * functions have the context field appropriate to that function rather + * than #HAB_CTX_AUTHENTICATE. In addition, the side-effects and + * post-conditions of any callback function supplied apply. + * + * @post If a failure or warning occurs outside these contexts, an audit + * event is logged with status: + * - #HAB_FAILURE, with further reasons: + * - #HAB_INV_ADDRESS: initial or final image addresses outside allowed + * regions + * - #HAB_INV_ADDRESS: IVT, DCD, Boot Data or CSF outside image bounds + * - #HAB_INV_ADDRESS: IVT @a self or @a entry pointer is NULL + * - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call + * - #HAB_INV_IVT: IVT malformed + * - #HAB_INV_IVT: IVT version number is less than HAB library version + * - #HAB_INV_RETURN: Callback function failed + * + * @retval entry field from @ref ivt on an IC not configured as + * #HAB_CFG_CLOSED provided that the following conditions are met + * (other unsuccessful operations will generate audit log events): + * - the @a start pointer and the pointer it locates are not NULL + * - the initial @ref ivt location is not NULL + * - the @ref ivt @ref hdr (given in the @a hdr field) is valid + * - the final @ref ivt location (given by the @a self field) is not NULL + * - any loader callback completed successfully, + * + * @retval entry field from @ref ivt on other ICs if all operations + * completed without failure (even if warnings were generated), + * + * @retval NULL otherwise. + */ + hab_image_entry_f (*authenticate_image)(uint8_t cid, + ptrdiff_t ivt_offset, + void** start, + size_t* bytes, + hab_loader_callback_f loader); + + /** Execute a boot configuration script. + * @ingroup run_dcd + * + * @par Purpose + * + * This function configures the IC based upon a @ref dcd table. It is + * intended for use by post-ROM boot stage components, via the @ref rvt. + * This function may be invoked as often as required for each boot stage. + * + * @ifrom It is also intended for use by the boot ROM, both directly via + * hab_rvt.run_dcd() and indirectly via hab_rvt.authenticate_image(). + * @endrom + * + * The difference between the configuration functionality in this function + * and hab_rvt.run_csf() arises because the @ref dcd table is not + * authenticated prior to running the commands. Hence, there is a more + * limited range of commands allowed, and a limited range of parameters to + * allowed commands. + * + * @par Operation + * + * This function performs the following operations: + * - Checks the @ref hdr for compatibility and consistency + * - Makes an internal copy of the @ref dcd table + * - Executes the commands in sequence from the internal copy of the @ref + * dcd + * + * If any failure occurs, an audit event is logged and all remaining + * operations are abandoned. + * + * @param[in] dcd Address of the @ref dcd. + * + * @warning It is the responsibility of the caller to ensure that the @a + * dcd parameter points to a valid memory location. + * + * @warning The @ref dcd must be authenticated by a subsequent @ref csf + * command prior to launching the next boot image, in order to avoid + * unauthorised configurations which may subvert secure operation. + * Although the content of the next boot stage's CSF may be out of scope + * for the hab_rvt.run_dcd() caller, it is possible to enforce this + * constraint by using hab_rvt.assert() to ensure that both the DCD and + * any pointers used to locate it have been authenticated. + * + * @warning Each invocation of hab_rvt.run_dcd() must occur between a pair + * of hab_rvt.entry() and hab_rvt.exit() calls, although multiple + * hab_rvt.run_dcd() calls (and other HAB calls) may be made in one + * bracket. This constraint applies whether hab_rvt.run_dcd() is + * successful or not: a subsequent call to hab_rvt.exit() is required + * prior to launching the authenticated image or switching to another boot + * target. + * + * @post Many commands may cause side-effects. See the @ref dcd + * documentation. + * + * @post If a failure or warning occurs within a command handler, an audit + * event is logged with the offending command, copied from the DCD. The + * status and reason logged are described in the relevant command + * documentation. + * + * @post For other failures or warning, the status logged is: + * - #HAB_WARNING, with further reasons: + * - #HAB_UNS_COMMAND: unsupported command encountered, where DCD + * version and HAB library version differ + * - #HAB_FAILURE, with further reasons: + * - #HAB_INV_ADDRESS: NULL @a dcd parameter + * - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call + * - #HAB_INV_COMMAND: command not allowed in DCD + * - #HAB_UNS_COMMAND: unrecognised command encountered, where DCD + * version and HAB library version match + * - #HAB_INV_DCD: DCD malformed or too large + * - #HAB_INV_DCD: DCD version number is less than HAB library version + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if all commands completed + * without failure (even if warnings were generated), + * + * @retval #HAB_FAILURE otherwise. + */ + hab_status_t (*run_dcd)(const uint8_t* dcd); + + /** Execute an authentication script. + * @ingroup run_csf + * + * @par Purpose + * + * This function authenticates SW images and configures the IC based upon + * a @ref csf. It is intended for use by post-ROM boot stage components, + * via the @ref rvt. This function may be invoked as often as required + * for each boot stage. + * + * @ifrom It is also available for use by the boot ROM via hab_rvt.run_csf, + * although it is anticipated that the boot ROM will mostly call this + * function indirectly via hab_rvt.authenticate_image(). @endrom + * + * @par Operation + * + * This function performs the following operations: + * - Checks the @ref hdr for compatibility and consistency + * - Makes an internal copy of the @ref csf + * - Executes the commands in sequence from the internal copy of the @ref + * csf + * + * The internal copy of the @ref csf is authenticated by an explicit + * command in the sequence. Prior to authentication, a limited set of + * commands is available to: + * - Install a Super-Root key (unless previously installed) + * - Install a CSF key (unless previously installed) + * - Specify any variable configuration items + * - Authenticate the CSF + * + * Subsequent to CSF authentication, the full set of commands is available. + * + * If any failure occurs, an audit event is logged and all remaining + * operations are abandoned. + * + * @param[in] csf Address of the @ref csf. + * + * @param[in] cid Caller ID, used to identify which SW issued this call. + * + * @remark Caller ID may be bound to signatures verified using keys + * installed with #HAB_CMD_INS_KEY_CID flag. See @ref cmd_ins_key and @ref + * bnd_obj for details. + * + * @warning It is the responsibility of the caller to ensure that the @a + * csf parameter points to a valid memory location. + * + * @warning Each invocation of hab_rvt.run_csf() must occur between a pair + * of hab_rvt.entry() and hab_rvt.exit() calls, although multiple + * hab_rvt.run_csf() calls (and other HAB calls) may be made in one + * bracket. This constraint applies whether hab_rvt.run_csf() is + * successful or not: a subsequent call to hab_rvt.exit() is required + * prior to launching the authenticated image or switching to another boot + * target. + * + * @post Many commands may cause side-effects. See the @ref csf + * documentation. In particular, note that keys installed by the @ref csf + * remain available for use in subsequent operations. + * + * @post If a failure or warning occurs within a command handler, an audit + * event is logged with the offending command, copied from the CSF. The + * status and reason logged are described in the relevant command + * documentation. + * + * @post For other failures or warning, the status logged is: + * - #HAB_WARNING, with further reasons: + * - #HAB_UNS_COMMAND: unsupported command encountered, where CSF + * version and HAB library version differ + * - #HAB_FAILURE, with further reasons: + * - #HAB_INV_ADDRESS: NULL @a csf parameter + * - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call + * - #HAB_INV_COMMAND: command not allowed prior to CSF authentication + * - #HAB_UNS_COMMAND: unrecognised command encountered, where CSF + * version and HAB library version match + * - #HAB_INV_CSF: CSF not authenticated + * - #HAB_INV_CSF: CSF malformed or too large + * - #HAB_INV_CSF: CSF version number is less than HAB library version + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if all commands completed + * without failure (even if warnings were generated), + * + * @retval #HAB_FAILURE otherwise. + */ + hab_status_t (*run_csf)(const uint8_t* csf, + uint8_t cid); + + /** Test an assertion against the audit log. + * @ingroup assert + * + * @par Purpose + * + * This function allows the audit log to be interrogated. It is intended + * for use by post-ROM boot stage components, via the @ref rvt, to + * determine the state of authentication operations. This function may be + * invoked as often as required for each boot stage. + * + * @ifrom It is also available for use by the boot ROM, both directly via + * hab_rvt.assert() and indirectly via hab_rvt.authenticate_image(). + * @endrom + * + * @par Operation + * + * This function checks the required assertion as detailed below. + * + * @param[in] type Assertion type. + * + * @param[in] data Assertion data. + * + * @param[in] count Data size or count. + * + * @par Memory block authentication: + * For #HAB_ASSERT_BLOCK assertion type, hab_rvt.assert() checks that the + * given memory block has been authenticated after running a CSF. The + * parameters are interpreted as follows: + * + * @par + * - @a data: memory block starting address + * - @a count: memory block size (in bytes) + * + * @par + * + * A simple interpretation of "memory block has been authenticated" is + * taken, such that the given block must lie wholly within a single + * contiguous block authenticated while running a CSF. A given memory + * block covered by the union of several neighboring or overlapping + * authenticated blocks could fail the test with this interpretation, but + * it is assumed that such cases will not arise in practice. + * + * @post If the assertion fails, an audit event is logged with status + * #HAB_FAILURE and reason #HAB_INV_ASSERTION, together with the call + * parameters. See the @ref evt record documentation for details. + * + * @post For successful commands, no audit event is logged. + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if the assertion is confirmed + * + * @retval #HAB_FAILURE otherwise + */ + hab_status_t (*assert)(hab_assertion_t type, + const void* data, + uint32_t count); + + /** Report an event from the audit log. + * @ingroup event + * + * @par Purpose + * + * This function allows the audit log to be interrogated. It is intended + * for use by post-ROM boot stage components, via the @ref rvt, to + * determine the state of authentication operations. This function may + * be called outside an hab_rvt.entry() / hab_rvt.exit() pair. + * + * @ifrom It is also available for use by the boot ROM, where it may be + * used to report boot failures as part of a tethered boot + * protocol. @endrom + * + * @par Operation + * + * This function performs the following operations: + * - Scans the audit log for a matching event + * - Copies the required details to the output parameters (if found) + * + * @param[in] status Status level of required event. + * + * @param[in] index Index of required event at given status level. + * + * @param[out] event @ref evt record. + * + * @param[in,out] bytes Size of @a event buffer on entry, size of event + * record on exit. + * + * @remark Use @a status = #HAB_STS_ANY to match any logged event, + * regardless of the status value logged. + * + * @remark Use @a index = 0 to return the first matching event, @a index = + * 1 to return the second matching event, and so on. + * + * @remark The data logged with each event is context-dependent. Refer to + * @ref evt record documentation. + * + * @warning Parameter @a bytes may not be NULL. + * + * @warning If the @a event buffer is a NULL pointer or too small to fit + * the event record, the required size is written to @a bytes, but no + * part of the event record is copied to the output buffer. + * + * @retval #HAB_SUCCESS if the required event is found, and the event + * record is copied to the output buffer. + * + * @retval #HAB_SUCCESS if the required event is found and @a event buffer + * passed is a NULL pointer. + * + * @retval #HAB_FAILURE otherwise + */ + hab_status_t (*report_event)(hab_status_t status, + uint32_t index, + uint8_t* event, + size_t* bytes); + + /** Report security status. + * @ingroup status + * + * @par Purpose + * + * This function reports the security configuration and state of the IC as + * well as searching the audit log to determine the status of the boot + * process. It is intended for use by post-ROM boot stage components, via + * the @ref rvt. This function may be called outside an + * hab_rvt.entry() / hab_rvt.exit() pair. + * + * @ifrom It is also available for use by the boot ROM, and should be used + * rather than the HAL function hab_hal_read_sec_cfg(). @endrom + * + * @par Operation + * + * This function reads the fuses which indicate the security + * configuration. The fusemap varies by IC, and should be taken from the + * @ref ref_rug. It also uses the @ref shw state machine, if present and + * enabled, to report on the security state. + * + * @param[out] config Security configuration, NULL if not required + * + * @param[out] state Security state, NULL if not required + * + * @remark If no @ref shw state machine is present and enabled, the state + * #HAB_STATE_NONE will be output. + * + * @retval #HAB_SUCCESS if no warning or failure audit events have been + * logged. + * + * @retval #HAB_WARNING otherwise, if only warning events have been logged. + * + * @retval #HAB_FAILURE otherwise + */ + hab_status_t (*report_status)(hab_config_t* config, hab_state_t* state); + + /** Enter failsafe boot mode. + * @ingroup safe + * + * @par Purpose + * + * This function provides a safe path when image authentication has failed + * and all possible boot paths have been exhausted. It is intended for + * use by post-ROM boot stage components, via the @ref rvt. + * + * @ifrom It is also available for use by the boot ROM via + * hab_rvt.failsafe(). @endrom + * + * @par Operation + * + * The precise details of this function vary by IC and core, and should be + * taken from @ref ref_rug. + * + * @warning This function does not return. + * + * @remark Since this function does not return, it implicitly performs the + * functionality of hab_rvt.exit() in order to ensure an appropriate + * configuration of the @ref shw plugins. + * + * @remark Two typical implementations are: + * - a low-level provisioning protocol in which an image is downloaded to + * RAM from an external host, authenticated and launched. The downloaded + * image may communicate with tools on the external host to report the + * reasons for boot failure, and may re-provision the end-product with + * authentic boot images. + * - a failsafe boot mode which does not allow execution to leave the ROM + * until the IC is reset. + */ + void (*failsafe)(void); +}; + +/** @ref rvt type + * @ingroup rvt + */ +typedef struct hab_rvt hab_rvt_t; + +/*---------------------------------------------------------------------------*/ + +/** @ref ivt structure + * @ingroup ivt + * + * @par Format + * + * An @ref ivt consists of a @ref hdr followed by a list of addresses as + * described further below. + * + * @warning The @a entry address may not be NULL. + * + * @warning On an IC not configured as #HAB_CFG_CLOSED, the + * @a csf address may be NULL. If it is not NULL, the @ref csf will be + * processed, but any failures should be non-fatal. + * + * @warning On an IC configured as #HAB_CFG_CLOSED, the @a + * csf address may not be NULL, and @ref csf failures are typically fatal. + * + * @remark The Boot Data located using the @a boot_data field is interpreted + * by the HAB caller in a boot-mode specific manner. This may be used by the + * boot ROM as to determine the load address and boot device configuration for + * images loaded from block devices (see @ref ref_rug for details). + * + * @remark All addresses given in the IVT, including the Boot Data (if + * present) are those for the final load location. + * + * @anchor ila + * + * @par Initial load addresses + * + * The @a self field is used to calculate addresses in boot modes where an + * initial portion of the image is loaded to an initial location. In such + * cases, the IVT, Boot Data (if present) and DCD (if present) are used in + * configuring the IC and loading the full image to its final location. Only + * the IVT, Boot Data (if present) and DCD (if present) are required to be + * within the initial image portion. + * + * The method for calculating an initial load address for the DCD is + * illustrated in the following C fragment. Similar calculations apply to + * other fields. + * +@verbatim + hab_ivt_t* ivt_initial = ; + const void* dcd_initial = ivt_initial->dcd; + if (ivt_initial->dcd != NULL) + dcd_initial = (const uint8_t*)ivt_initial + + (ivt_initial->dcd - ivt_initial->self) +@endverbatim + */ +struct hab_ivt { + /** @ref hdr with tag #HAB_TAG_IVT, length and HAB version fields + * (see @ref data) + */ + hab_hdr_t hdr; + /** Absolute address of the first instruction to execute from the + * image + */ + hab_image_entry_f entry; + /** Reserved in this version of HAB: should be NULL. */ + const void* reserved1; + /** Absolute address of the image DCD: may be NULL. */ + const void* dcd; + /** Absolute address of the Boot Data: may be NULL, but not interpreted + * any further by HAB + */ + const void* boot_data; + /** Absolute address of the IVT.*/ + const void* self; + /** Absolute address of the image CSF.*/ + const void* csf; + /** Reserved in this version of HAB: should be zero. */ + uint32_t reserved2; +}; + +/** @ref ivt type + * @ingroup ivt + */ +typedef struct hab_ivt hab_ivt_t; + +/*=========================================================================== + FUNCTION PROTOTYPES +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* HAB_DEFINES_H */ diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/asm_defines.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/asm_defines.h new file mode 100644 index 000000000..beee15cb1 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/asm_defines.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2008-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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. + */ + +/*! + * @file asm_defines.h + * @brief defines for startup assembly code + * + * @ingroup diag_util + */ + +#ifndef _ASM_DEFINES_H_ +#define _ASM_DEFINES_H_ + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +//! @name CPSR fields +//@{ +#define CPSR_N (1 << 31) //!< Negative +#define CPSR_Z (1 << 30) //!< Zero +#define CPSR_C (1 << 29) //!< Carry +#define CPSR_V (1 << 28) //!< Overflow +#define CPSR_Q (1 << 27) //!< Saturation +#define CPSR_E (1 << 9) //!< Endianness +#define CPSR_A (1 << 8) //!< Async abort mask +#define CPSR_I (1 << 7) //!< IRQ mask +#define CPSR_F (1 << 6) //!< FIQ mask +#define CPSR_T (1 << 5) //!< Thumb mode +#define CPSR_MODE (0x1f) //!< Current processor mode +//@} + +//! @name Mode bits in CPSR +//@{ +#define MODE_USR 0x10 //!< User mode +#define MODE_FIQ 0x11 //!< FIQ mode +#define MODE_IRQ 0x12 //!< IRQ mode +#define MODE_SVC 0x13 //!< Supervisor mode +#define MODE_ABT 0x17 //!< Abort exception mode +#define MODE_UND 0x1B //!< Undefined instruction exception mode +#define MODE_SYS 0x1F //!< System mode +//@} + +//! @name Interrupt enable bits in CPSR +//@{ +#define I_BIT 0x80 //!< When I bit is set, IRQ is disabled +#define F_BIT 0x40 //!< When F bit is set, FIQ is disabled +//@} + +//! @name Stack sizes +//@{ + +//! @brief Size of stacks for exceptions. +#define EXCEPTION_STACK_SIZE 2048 + +//! @brief Supervisor mode stack size. +//! +//! This stack is much larger because most application code runs in +//! Supervisor mode. +#define SVC_STACK_SIZE 8192 + +//@} + +#endif /*_ASM_DEFINES_H_ */ +//////////////////////////////////////////////////////////////////////////////// +// EOF +//////////////////////////////////////////////////////////////////////////////// diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/hab_defines.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/hab_defines.h new file mode 100755 index 000000000..1fcf5d544 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/hab_defines.h @@ -0,0 +1,2222 @@ +/* + * Copyright (c) 2008-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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. + */ + +/*! + * @file hab_defines.h + * @brief defines for data structures and macros used for enabling secure boot + * + * @ingroup diag_init + */ +#ifndef HAB_DEFINES_H +#define HAB_DEFINES_H +/*=========================================================================== + INCLUDE FILES +=============================================================================*/ +#include /* for integer types */ +#include /* for bool type */ +#include /* for NULL and offsetof() */ +/*=========================================================================== + CONSTANTS +=============================================================================*/ +/** @addtogroup struct + * @{ + */ + +#define HDR_BYTES 4 /* cannot use sizeof(hab_hdr_t) in preprocessor */ + +/** @name External data structure tags + * @anchor dat_tag + * + * Tag values 0x00 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff + * are available for custom use. + */ +/*@{*/ +#define HAB_TAG_IVT 0xd1 /**< Image Vector Table */ +#define HAB_TAG_DCD 0xd2 /**< Device Configuration Data */ +#define HAB_TAG_CSF 0xd4 /**< Command Sequence File */ +#define HAB_TAG_CRT 0xd7 /**< Certificate */ +#define HAB_TAG_SIG 0xd8 /**< Signature */ +#define HAB_TAG_EVT 0xdb /**< Event */ +#define HAB_TAG_RVT 0xdd /**< ROM Vector Table */ +#define HAB_TAG_WRP 0x81 /**< Wrapped Key */ +#define HAB_TAG_MAC 0xac /**< Message Authentication Code */ +/* Values 00 ... 7e reserved for internal use. Values b0 ... cf reserved for + * CSF commands. Values e0 ... ef reserved for key types. + * + * Available values: 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, + * 9c, 9f, a0, a3, a5, a6, a9, aa, af + * + * Custom values: f0, f3, f5, f6, f9, fa, fc, ff + */ +/*@}*/ + +/** @name HAB version */ +/*@{*/ +#define HAB_MAJOR_VERSION 4 /**< Major version of this HAB release */ +#define HAB_MINOR_VERSION 1 /**< Minor version of this HAB release */ +#define HAB_VER_MAJ_WIDTH 4 /**< Major version field width */ +#define HAB_VER_MAJ_SHIFT 4 /**< Major version field offset */ +#define HAB_VER_MIN_WIDTH 4 /**< Minor version field width */ +#define HAB_VER_MIN_SHIFT 0 /**< Minor version field offset */ +/** Full version of this HAB release @hideinitializer */ +#define HAB_VERSION HAB_VER(HAB_MAJOR_VERSION, HAB_MINOR_VERSION) +/** Base version for this HAB release @hideinitializer */ +#define HAB_BASE_VERSION HAB_VER(HAB_MAJOR_VERSION, 0) + +/*@}*/ + +/* @} struct */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup cmd + * @{ + */ + +/** @name Command tags + * @anchor cmd_tag + * + * Tag values 0xb0 .. 0xcf are reserved for HAB. Values 0xf0 .. 0xff + * are available for custom use. + */ +/*@{*/ +#define HAB_CMD_SET 0xb1 /**< Set */ +#define HAB_CMD_INS_KEY 0xbe /**< Install Key */ +#define HAB_CMD_AUT_DAT 0xca /**< Authenticate Data */ +#define HAB_CMD_WRT_DAT 0xcc /**< Write Data */ +#define HAB_CMD_CHK_DAT 0xcf /**< Check Data */ +#define HAB_CMD_NOP 0xc0 /**< No Operation */ +#define HAB_CMD_INIT 0xb4 /**< Initialise */ +#define HAB_CMD_UNLK 0xb2 /**< Unlock */ +#ifdef HAB_FUTURE +#define HAB_CMD_RMV_KEY /**< Remove Key */ +#define HAB_CMD_INS_REF /**< Install Reference Data */ +#define HAB_CMD_INS_PLG /**< Install Plugin */ +#define HAB_CMD_RMV_PLG /**< Remove Plugin */ +#define HAB_CMD_CHK_VER /**< Check SW Version */ +#endif +/* Remaining values: b7, b8, bb, bd, c3, c5, c6, c9 */ +/*@}*/ + +/* @} cmd */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup pcl + * @{ + */ + +/** @name Protocol tags + * @anchor pcl_tag + * + * Tag values 0x00 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff are + * available for custom use. + */ +/*@{*/ +#define HAB_PCL_SRK 0x03 /**< SRK certificate format */ +#define HAB_PCL_X509 0x09 /**< X.509v3 certificate format */ +#define HAB_PCL_CMS 0xc5 /**< CMS/PKCS#7 signature format */ +#define HAB_PCL_BLOB 0xbb /**< SHW-specific wrapped key format */ +#define HAB_PCL_AEAD 0xa3 /**< Proprietary AEAD MAC format */ +#ifdef HAB_FUTURE +#define HAB_PCL_WTLS 0x05 /**< OMA WTLS certificate format */ +#define HAB_PCL_FSL 0x0f /**< FSL bound signature protocol */ +#define HAB_PCL_HMAC 0x30 /**< NIST HMAC message authentication */ +#define HAB_PCL_CBCMAC 0x33 /**< CBC-MAC message authentication */ +#endif +/*@}*/ + +/* Available values: 06, 0a, 0c, 11, 12, 14, 17, 18, 1b, 1d, 1e, 21, 22, 24, + * 27, 28, 2b, 2d, 2e, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b, 4d, 4e, + * 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71, 72, 74, + * 77, 78, 7b, 7d, 7e, 81, 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, + * 9c, 9f, a0, a5, a6, a9, aa, ac, af, b1, b2, b4, b7, b8, bd, be, c0, c3, c6, + * c9, ca, cc, cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7, e8, eb, ed, + * ee + * + * Custom values: f0, f3, f5, f6, f9, fa, fc, ff + */ + +/* @} pcl */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup alg + * @{ + */ + +/** @name Algorithm types + * @anchor alg_typ + * + * The most-significant nibble of an algorithm ID denotes the algorithm + * type. Algorithms of the same type share the same interface. + * + * Types 0x0 .. 0xc are reserved for HAB. Types 0xd .. 0xf are available for + * custom use. Within each reserved type N in 0 .. c, tag values 0xN0 .. 0xNc + * are reserved for HAB. Values 0xNd .. 0xNf are available for custom use. + */ +/*@{*/ +#define HAB_ALG_ANY 0x0 /**< Algorithm type ANY */ +#define HAB_ALG_HASH 0x1 /**< Hash algorithm type */ +#define HAB_ALG_SIG 0x2 /**< Signature algorithm type */ +#define HAB_ALG_FF 0x3 /**< Finite field arithmetic */ +#define HAB_ALG_EC 0x4 /**< Elliptic curve arithmetic */ +#define HAB_ALG_CIPHER 0x5 /**< Cipher algorithm type */ +#define HAB_ALG_MODE 0x6 /**< Cipher/hash modes */ +#define HAB_ALG_WRAP 0x7 /**< Key wrap algorithm type */ +/*@}*/ + +/** @name Algorithm type ANY + * + * Algorithms of type ANY have no common interface: the protocol must know + * what to do. + */ +/*@{*/ +#ifdef HAB_FUTURE +#define HAB_ALG_RANDOM /**< Random number generation */ +#endif +/* Available values: 03, 05, 06, 09, 0a, 0c, 0f + */ +/*@}*/ + +/** @name Hash algorithms */ +/*@{*/ +#define HAB_ALG_SHA1 0x11 /**< SHA-1 algorithm ID */ +#define HAB_ALG_SHA256 0x17 /**< SHA-256 algorithm ID */ +#define HAB_ALG_SHA512 0x1b /**< SHA-512 algorithm ID */ +/* Available values: 0x14, 0x12, 18, 1d, 1e + */ +/*@}*/ + +/** @name Signature algorithms */ +/*@{*/ +#define HAB_ALG_PKCS1 0x21 /**< PKCS#1 RSA signature algorithm */ +#ifdef HAB_FUTURE +#define HAB_ALG_DSA /**< NIST DSA signature algorithm */ +#define HAB_ALG_ECDSA /**< NIST ECDSA signature algorithm */ +#endif +/* Available values: 22, 24, 27, 28, 2b, 2d, 2e + */ +/*@}*/ + +/** @name Cipher algorithms */ +/*@{*/ +#define HAB_ALG_AES 0x55 /**< AES algorithm ID */ +/* Available values: 50, 53, 56, 59, 5a, 5c, 5f + */ +/*@}*/ + +/** @name Cipher or hash modes */ +/*@{*/ +#define HAB_MODE_CCM 0x66 /**< Counter with CBC-MAC */ +#ifdef HAB_FUTURE +#define HAB_MODE_HMAC /**< HMAC hash mode */ +#endif +/* Available values: 60, 63, 65, 69, 6a, 6c, 6f + */ +/*@}*/ + +/** @name Key wrap algorithms */ +/*@{*/ +#define HAB_ALG_BLOB 0x71 /**< SHW-specific key wrap */ +/* Available values: 72, 74, 77, 78, 7b, 7d, 7e + */ +/*@}*/ + +/* Available values: 81, 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, + * 9c, 9f, a0, a3, a5, a6, a9, aa, ac, af, b1, b2, b4, b7, b8, bb, bd, be, c0, + * c3, c5, c6, c9, ca, cc, cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7, + * e8, eb, ed, ee, f0, f3, f5, f6, f9, fa, fc, ff + */ + +/* @} alg */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup eng + * @{ + */ + +/** @name Engine plugin tags + * @anchor eng_tag + * + * Tag values 0x00 .. 0xef and 0xff are reserved for HAB. Values 0xf0 .. 0xfe + * are available for custom use. + */ +/*@{*/ +#define HAB_ENG_ANY 0x00 /**< First compatible engine will be + * selected automatically (no engine + * configuration parameters are allowed). + */ +#define HAB_ENG_SCC 0x03 /**< Security controller */ +#define HAB_ENG_RTIC 0x05 /**< Run-time integrity checker */ +#define HAB_ENG_SAHARA 0x06 /**< Crypto accelerator */ +#define HAB_ENG_CSU 0x0a /**< Central Security Unit */ +#define HAB_ENG_SRTC 0x0c /**< Secure clock */ +#ifdef HAB_FUTURE +#define HAB_ENG_RNG 0x09 /**< Standalone random number generator */ +#define HAB_ENG_SJC 0x0f /**< Secure JTAG controller */ +#define HAB_ENG_WDOG 0x11 /**< Watchdog timer */ +#define HAB_ENG_SRC 0x12 /**< System Reset Controller */ +#define HAB_ENG_SPBA 0x14 /**< Shared Peripheral Bus Arbiter */ +#define HAB_ENG_IIM 0x17 /**< Fuse controller */ +#define HAB_ENG_IOMUX 0x18 /**< IO multiplexer */ +#endif +#define HAB_ENG_DCP 0x1b /**< Data Co-Processor */ +#define HAB_ENG_CAAM 0x1d /**< Cryptographic Acceleration and + Assurance Module */ +#define HAB_ENG_SNVS 0x1e /**< Secure Non-Volatile Storage */ +#define HAB_ENG_OCOTP 0x21 /**< Fuse controller */ +/** @cond rom */ +#define HAB_ENG_DTCP 0x22 /**< DTCP co-processor */ +#define HAB_ENG_ROM 0x36 /**< Protected ROM area */ +#define HAB_ENG_HDCP 0x24 /**< HDCP co-processor */ +#define HAB_ENG_RTL 0x77 /**< @rom RTL simulation engine */ +/** @endcond */ +#define HAB_ENG_SW 0xff /**< Software engine */ +/* Available values: 27, 28, 2b, 2d, 2e, 30, 33, 35, + * 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b, 4d, 4e, 50, 53, 55, 56, 59, 5a, + * 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71, 72, 74, 78, 7b, 7d, 7e, 81, + * 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, 9c, 9f, a0, a3, a5, a6, + * a9, aa, ac, af, b1, b2, b4, b7, b8, bb, bd, be, c0, c3, c5, c6, c9, ca, cc, + * cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7, e8, eb, ed, ee + * + * Custom values: f0, f3, f5, f6, f9, fa, fc + */ +/*@}*/ + +/* @} eng */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup sah + * @{ + */ + +/** Maximum data blocks in a single hash */ +#define HAB_SAHARA_BLOCK_MAX 12 + +/** @cond rom */ +/** @rom DMA storage requirement + * + * This figure is derived in several parts: + * - each hash operation needs a 6-word descriptor structure + * - each data block needs a 3-word link structure + * - the result needs a 3-word link structure + * - at least 40 bytes are required for SHA-256 result and memory manager + * overhead: 64 bytes allows some small overhead. + */ +#define HAB_SAHARA_DMA_MIN_BYTES (24 + HAB_SAHARA_BLOCK_MAX * 12 + 12 + 64) +/** @endcond */ + +/* @} sah */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup dcp + * @{ + */ + +/** Maximum data blocks in a single hash */ +#define HAB_DCP_BLOCK_MAX 6 + +/** @cond rom */ +/** @rom DMA storage requirement + * + * This figure is derived in two parts: + * - each data block needs an 8-word work packet (descriptor) + * - at least 40 bytes are required for SHA-256 result and memory manager + * overhead: 64 bytes allows some small overhead. + */ +#define HAB_DCP_DMA_MIN_BYTES (64 + HAB_DCP_BLOCK_MAX * 32) +/** @endcond */ + +/* @} dcp */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup rtic + * @{ + */ + +/** Maximum data blocks in a single hash */ +#define HAB_RTIC_BLOCK_MAX 2 + +/* @} rtic */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup scc + * @{ + */ + +/** @cond rom */ +/** @rom DMA storage requirement + * + * This figure is derived in several stages, and assumes plaintext and + * ciphertext buffers are both allocated in the DMA region : + * - 4 blocks of plaintext required + * - 4 blocks of ciphertext required + * - each block is 16 bytes long + * - the plaintext address must be block-aligned (up to 15 bytes overhead) + * - the ciphertext address must be block-aligned (up to 3 bytes overhead) + * - at least 8 bytes of memory manager overhead: allow 32 for comfort + */ +#define HAB_SCC_DMA_MIN_BYTES ( (4+4)*16 + 15 + 3 + 32) +/** @endcond */ + +/* @} scc */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup caam + * @{ + */ + +/** Maximum data blocks in an @ref cmd_aut_dat command */ +#define HAB_CAAM_BLOCK_MAX 8 + +/** @cond rom */ +/** @rom Hash DMA storage requirement + * + * This figure is derived in several parts: + * - each hash operation needs + * - a 7-word descriptor, and + * - a 32-byte result buffer (for SHA-256), + * - giving a base requirement of (7*4 + 32) = 60 bytes + * - each data block needs a 4-word link structure + * - memory manager overhead is at least 8 bytes: 16 bytes allows flexibility + */ +#define HAB_CAAM_HSH_DMA_MIN_BYTES (60 + HAB_CAAM_BLOCK_MAX * 16 + 16) + +/** @rom AEAD DMA storage requirement + * + * This figure is derived in several parts: + * - each AEAD operation needs + * - a 16-word descriptor, + * - a 32-byte initial context value (B0 and CTR0), and + * - a 16-byte MAC value, + * - giving a base requirement of (16*4 + 32 + 16) = 112 bytes + * - each data block needs a 4-word link structure + * - memory manager overhead is at least 8 bytes: 16 bytes allows flexibility + */ +#define HAB_CAAM_CCM_DMA_MIN_BYTES (112 + HAB_CAAM_BLOCK_MAX * 16 + 16) + +/** @rom RNG DMA storage requirement + * + * This figure is derived in several parts: + * - each DRNG test operation allocates a DMA area with + * - a 1-word header, and + * - a 3-word job ring area, and + * - a 54-word descriptor, + * - requiring a total 58*4 = 232 bytes + * - each DRNG test operation also allocates a DMA area with + * - a 1-word header, and + * - a 32-byte result buffer + * - requiring a total 4 + 32 = 36 bytes + */ +#define HAB_CAAM_RNG_DMA_MIN_BYTES (232 + 32) +/** @endcond */ + +/* @} caam */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup key + * @{ + */ + +/** @name Key types + * @anchor key_types + * + * Tag values 0xe0 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff + * are available for custom use. + */ +/*@{*/ +#define HAB_KEY_PUBLIC 0xe1 /**< Public key type: data present */ +#define HAB_KEY_SECRET 0xe2 /**< Secret key type: data present */ +#define HAB_KEY_MASTER 0xed /**< Master KEK type */ +#define HAB_KEY_HASH 0xee /**< Any key type: hash only */ +/* Available values: e4, e7, e8, eb + * + * Custom values: f0, f3, f5, f6, f9, fa, fc, ff + */ +/*@}*/ + +/** @name Public key store indices */ +/*@{*/ +#define HAB_IDX_SRK 0 /**< Super-Root Key index */ +#define HAB_IDX_CSFK 1 /**< CSF key index */ +/*@}*/ + +/** @name Key Counts */ +/*@{*/ +#define HAB_SRK_MIN 1 /**< Minimum Super-Root Key count */ +#define HAB_SRK_MAX 4 /**< Maximum Super-Root Key count */ +#define HAB_KEY_PUBLIC_MAX 5 /**< Maximum installed public key count + * (incl Super-Root Key) + */ +#define HAB_KEY_SECRET_MAX 4 /**< Maximum installed secret key count + * (excl Master KEKs) + */ +/*@}*/ + +/* @} key */ + +/*---------------------------------------------------------------------------*/ + +#ifdef HAB_FUTURE +/** @addtogroup key_ecdsa + * @{ + */ + +/** @name Bitfield definitions */ +/*@{*/ +#define HAB_KEY_ECDSA_FLG_WIDTH 8 /**< Width of @a flg field */ +#define HAB_KEY_ECDSA_FLG_SHIFT 0 /**< Offset of @a flg field */ +#define HAB_KEY_ECDSA_TYP_WIDTH 8 /**< Width of @a typ field */ +#define HAB_KEY_ECDSA_TYP_SHIFT 24 /**< Offset of @a typ field */ +#define HAB_KEY_ECDSA_SIZ_WIDTH 8 /**< Width of @a siz field */ +#define HAB_KEY_ECDSA_SIZ_SHIFT 16 /**< Offset of @a siz field */ +#define HAB_KEY_ECDSA_REDBITS_WIDTH 16 /**< Width of @a red_bits field */ +#define HAB_KEY_ECDSA_REDBITS_SHIFT 0 /**< Offset of @a red_bits field */ +/*@}*/ + +/* @} key_ecdsa */ +#endif + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup key_pkcs1 + * @{ + */ + +/** @name Bitfield definitions */ +/*@{*/ +#define HAB_KEY_PKCS1_FLG_WIDTH 8 /**< Width of @a flg field */ +#define HAB_KEY_PKCS1_FLG_SHIFT 0 /**< Offset of @a flg field */ +#define HAB_KEY_PKCS1_MODBYTES_WIDTH 16 /**< Width of mod_bytes field */ +#define HAB_KEY_PKCS1_MODBYTES_SHIFT 16 /**< Offset of mod_bytes field */ +#define HAB_KEY_PKCS1_EXPBYTES_WIDTH 16 /**< Width of exp_bytes field */ +#define HAB_KEY_PKCS1_EXPBYTES_SHIFT 0 /**< Offset of exp_bytes field */ +/*@}*/ + +/** @name Binding flag bitfield definitions */ +/*@}*/ +#define HAB_KEY_BND_FLG_WIDTH 5 /**< Width of binding flags */ +#define HAB_KEY_BND_FLG_SHIFT 2 /**< Offset of binding flags */ +/*@}*/ + +/* @} key_pkcs1 */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup cmd_wrt_dat + * @{ + */ + +/** @name Parameter bitfield definitions. + * + * Apply to both @ref cmd_wrt_dat and @ref cmd_chk_dat commands. */ +/*@{*/ +#define HAB_CMD_WRT_DAT_FLAGS_WIDTH 5 /**< @a flags field width */ +#define HAB_CMD_WRT_DAT_FLAGS_SHIFT 3 /**< @a flags field offset */ +#define HAB_CMD_WRT_DAT_BYTES_WIDTH 3 /**< @a bytes field width */ +#define HAB_CMD_WRT_DAT_BYTES_SHIFT 0 /**< @a bytes field offset */ +/*@}*/ + +/* @} cmd_wrt_dat */ + +/*---------------------------------------------------------------------------*/ + +/** @addtogroup bnd_obj + * @{ + */ + +/** @name Binding object IDs + * @anchor bnd_ids + * + * The ASN.1 object identifiers used to identify HAB binding attributes are + * defined in the following arc: + * +@verbatim + id-fsl OBJECT IDENTIFIER ::= { + joint-iso-itu-t(2) country(16) us(840) organization(1) fsl(123456) } + + id-habBnd OBJECT IDENTIFIER ::= { + id-fsl hab(32) binding-objects(16) } + + id-habBnd-dat OBJECT IDENTIFIER ::= { + id-habBnd dat(1) } + + id-habBnd-cfg OBJECT IDENTIFIER ::= { + id-habBnd cfg(3) } + + id-habBnd-fid OBJECT IDENTIFIER ::= { + id-habBnd fid(5) } + + id-habBnd-mid OBJECT IDENTIFIER ::= { + id-habBnd mid(6) } + + id-habBnd-cid OBJECT IDENTIFIER ::= { + id-habBnd cid(9) } +@endverbatim + * + * The ASN.1 object identifiers used to identify HAB binding attributes are + * single component extensions of id-habBnd using a component value less than + * 128 (so that the component can be DER-encoded in a single byte). + * + * The DER encoding of an object identifier in this arc is the concatenation + * of the DER prefix with the single byte identifier for the required binding + * object. Binding object attribute values are encoded as an ASN.1 SET with + * a single OCTET STRING member. + */ +/*@{*/ + +/** DER prefix + * + * @todo update description and encoding of binding object identifiers with + * real fsl value instead of fsl(123456) encoded as 0x87, 0xc4, 0x40, and + * confirm chosen values for hab(32) and binding-objects(16). + */ +#define HAB_BND_DER_PREFIX \ + {0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x87, 0xc4, 0x40, 0x20, 0x10} +#define HAB_BND_DAT 0x01 /**< Data type (mandatory) */ +#define HAB_BND_CFG 0x03 /**< Security configuration */ +#define HAB_BND_FID 0x05 /**< Fabrication UID */ +#define HAB_BND_MID 0x06 /**< Manufacturing ID */ +#define HAB_BND_CID 0x09 /**< Caller ID */ +/* Available values: 0a, 0c, 0f, 11, 12, 14, 17, 18, 1b, 1d, 1e, 21, 22, 24, + * 27, 28, 2b, 2d, 2e, 30, 33, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b, + * 4d, 4e, 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71, + * 72, 74, 77, 78, 7b, 7d, 7e + */ +/*@}*/ + + +/** @name Caller IDs + * + * Only the ROM caller ID is defined, but other caller IDs may be defined by + * later boot stages. + */ +/*@{*/ +#define HAB_CID_ROM 0 /**< ROM Caller ID */ +/*@}*/ + +/* @} bnd_obj */ + +#ifdef HAB_FUTURE +/** @addtogroup sig_fsl + * @{ + */ + +#define HAB_BND_DAT_BYTES 512 /**< Maximum binding data size */ + +/* @} sig_fsl */ +#endif + +/*=========================================================================== + MACROS +=============================================================================*/ +/* + * Helper macros + */ +#define HAB_CMD_UNS 0xff + +#define DEFAULT_IMG_KEY_IDX 2 + +#define GEN_MASK(width) \ + ((1UL << (width)) - 1) + +#define GEN_FIELD(f, width, shift) \ + (((f) & GEN_MASK(width)) << (shift)) + +#define PACK_UINT32(a, b, c, d) \ + ((uint32_t) ( (((uint32_t)(a) & 0xFF) << 24) \ + |(((uint32_t)(b) & 0xFF) << 16) \ + |(((uint32_t)(c) & 0xFF) << 8) \ + |(((uint32_t)(d) & 0xFF)) ) ) + +#define EXPAND_UINT32(w) \ + (uint8_t)((w)>>24), (uint8_t)((w)>>16), (uint8_t)((w)>>8), (uint8_t)(w) + +#define EXPAND_UINT16(w) \ + (uint8_t)((w)>>8), (uint8_t)(w) + +#define HDR(tag, bytes, par) \ + (uint8_t)(tag), (uint8_t)((bytes)>>8), (uint8_t)(bytes), (uint8_t)(par) + +#define HAB_VER(maj, min) \ + (GEN_FIELD((maj), HAB_VER_MAJ_WIDTH, HAB_VER_MAJ_SHIFT) \ + | GEN_FIELD((min), HAB_VER_MIN_WIDTH, HAB_VER_MIN_SHIFT)) + +#define DCD_DATA(addr, data) EXPAND_UINT32(addr), EXPAND_UINT32(data) + +/* + * CSF header + */ + +#define CSF_HDR(bytes, HABVER) \ + HDR(HAB_TAG_CSF, (bytes), HABVER) + + +/* + * DCD header + */ + +#define DCD_HDR(bytes, HABVER) \ + HDR(HAB_TAG_DCD, (bytes), HABVER) + +/* + * IVT header (goes in the struct's hab_hdr_t field, not a byte array) + */ +#define IVT_HDR(bytes, HABVER) \ + {HAB_TAG_IVT, {(uint8_t)((bytes)>>8), (uint8_t)(bytes)}, HABVER} + +/* + * Write Data + */ + +#define WRT_DAT(flags, bytes, address, val_msk) \ + HDR(HAB_CMD_WRT_DAT, WRT_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \ + EXPAND_UINT32(address), \ + EXPAND_UINT32(val_msk) + +#define WRT_DAT_BYTES 12 + +#define MULTI_WRT_DAT(flags, bytes, address1, val_msk1, address2, \ + val_msk2, address3, val_msk3) \ + HDR(HAB_CMD_WRT_DAT, MULTI_WRT_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \ + EXPAND_UINT32(address1), \ + EXPAND_UINT32(val_msk1), \ + EXPAND_UINT32(address2), \ + EXPAND_UINT32(val_msk2), \ + EXPAND_UINT32(address3), \ + EXPAND_UINT32(val_msk3) + +#define MULTI_WRT_DAT_BYTES 28 + +#define WRT_DAT_PAR(flags, bytes) \ + (GEN_FIELD((flags), \ + HAB_CMD_WRT_DAT_FLAGS_WIDTH, \ + HAB_CMD_WRT_DAT_FLAGS_SHIFT) \ + | GEN_FIELD((bytes), \ + HAB_CMD_WRT_DAT_BYTES_WIDTH, \ + HAB_CMD_WRT_DAT_BYTES_SHIFT)) + +/* + * Check Data (forever) + */ + +#define CHK_DAT_FOREVER(flags, bytes, address, mask) \ + HDR(HAB_CMD_CHK_DAT, CHK_DAT_FOREVER_BYTES, WRT_DAT_PAR((flags), (bytes))), \ + EXPAND_UINT32(address), \ + EXPAND_UINT32(mask) + +#define CHK_DAT_FOREVER_BYTES 12 + +/* + * Check Data (polled) + */ +#define HAB_CMD_CHK_DAT_COUNT 100 + +#define CHK_DAT(flags, bytes, address, mask, count) \ + HDR(HAB_CMD_CHK_DAT, CHK_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \ + EXPAND_UINT32(address), \ + EXPAND_UINT32(mask), \ + EXPAND_UINT32(count) + +#define CHK_DAT_BYTES 16 + +/* + * Set (generic - used internally only, or to generate invalid commands) + */ + +#define SET(bytes, itm, value) \ + HDR(HAB_CMD_SET, (bytes), (itm)), \ + EXPAND_UINT32(value) + +/* + * Set (MID location) + */ + +#define SET_MID(bank, row, bit, fuses) \ + HDR(HAB_CMD_SET, SET_MID_BYTES, HAB_VAR_CFG_ITM_MID), \ + (bank), (row), (bit), (fuses) + +#define SET_MID_BYTES 8 + +/* + * Set (default ENG) + */ + +#define SET_ENG(alg, eng, cfg) \ + HDR(HAB_CMD_SET, SET_ENG_BYTES, HAB_VAR_CFG_ITM_ENG), \ + 0, (alg), (eng), (cfg) + +#define SET_ENG_BYTES 8 + +/* + * Init (engine) + */ + +#define INIT(eng) \ + HDR(HAB_CMD_INIT, INIT_BYTES, (eng)) + +#define INIT_BYTES 4 + +/* + * Unlk (engine) + */ + +#define UNLK(eng, ...) \ + UNLK_ ## eng(__VA_ARGS__) + +#define UNLK_BYTES(eng, ...) \ + UNLK_BYTES_ ## eng(__VA_ARGS__) + +#define UNLK_HDR(eng, ...) \ + HDR(HAB_CMD_UNLK, UNLK_BYTES_ ## eng(__VA_ARGS__), eng) + +#define UNLK_FLG(flg) \ + 0, 0, 0, (uint8_t)(flg) + +#define UNLK_FLG_BYTES 4 + +#define UNLK_HAB_ENG_SRTC(dnc) UNLK_HDR(HAB_ENG_SRTC) +#define UNLK_BYTES_HAB_ENG_SRTC(dnc) HDR_BYTES + +#define UNLK_HAB_ENG_SNVS(flg) UNLK_HDR(HAB_ENG_SNVS), UNLK_FLG(flg) +#define UNLK_BYTES_HAB_ENG_SNVS(flg) (HDR_BYTES + UNLK_FLG_BYTES) + +#define UNLK_HAB_ENG_CAAM(flg) UNLK_HDR(HAB_ENG_CAAM), UNLK_FLG(flg) +#define UNLK_BYTES_HAB_ENG_CAAM(flg) (HDR_BYTES + UNLK_FLG_BYTES) + +/* The next definition uses a GCC extension employing ## to swallow the + * trailing comma in case the macro is called with only the fixed arguments + * (i.e. flg here). This extension appears to work in the GNU compatible mode + * of RVDS and GHS compilers. + */ +#define UNLK_HAB_ENG_OCOTP(flg, ...) \ + UNLK_HDR(HAB_ENG_OCOTP, flg), UNLK_FLG(flg), ## __VA_ARGS__ + +#define UNLK_BYTES_HAB_ENG_OCOTP(flg, ...) \ + (HDR_BYTES + UNLK_FLG_BYTES \ + + ( ((flg) & (HAB_OCOTP_UNLOCK_FIELD_RETURN \ + |HAB_OCOTP_UNLOCK_JTAG \ + |HAB_OCOTP_UNLOCK_SCS)) \ + ? STUB_FAB_UID_BYTES \ + : 0 )) + +#if 0 +/* Note: no comma after HDR(). Supplied by _VAL macro if needed */ +#define UNLK(eng, val) \ + HDR(HAB_CMD_UNLK, UNLK_BYTES_ ## eng, (eng)) \ + UNLK_VAL_ ## eng(val) + +#define UNLK_BYTES(eng) \ + UNLK_BYTES_ ## eng + +#define UNLK_BYTES_HAB_ENG_SRTC HDR_BYTES +#define UNLK_VAL_HAB_ENG_SRTC(val) /* no val field */ +#define UNLK_BYTES_HAB_ENG_SNVS (HDR_BYTES + 4) +#define UNLK_VAL_HAB_ENG_SNVS(val) ,0,0,0,((val)&0xff) +#define UNLK_BYTES_HAB_ENG_CAAM (HDR_BYTES + 4) +#define UNLK_VAL_HAB_ENG_CAAM(val) ,0,0,0,((val)&0xff) +#endif + +/* + * NOP + */ + +#define NOP() \ + HDR(HAB_CMD_NOP, NOP_BYTES, 0xae) /* third param is ignored */ + +#define NOP_BYTES 4 + +/* + * Install Key (generic - used internally only) + */ + +#define INS_KEY(bytes, flg, pcl, alg, src, tgt, crt) \ + HDR(HAB_CMD_INS_KEY, (bytes), (flg)), \ + (pcl), (alg), (src), (tgt), \ + EXPAND_UINT32(crt) + +#define INS_KEY_BASE_BYTES 12 + +/* + * Install Key (SRK) + */ + +#define INS_SRK(flg, alg, src, crt) \ + INS_KEY(INS_SRK_BYTES, (flg), \ + HAB_PCL_SRK, (alg), (src), HAB_IDX_SRK, \ + (crt)) + +#define INS_SRK_BYTES INS_KEY_BASE_BYTES + +/* + * Install Key (CSFK) + */ + +#define INS_CSFK(flg, pcl, crt) \ + INS_KEY(INS_CSFK_BYTES, (flg) | HAB_CMD_INS_KEY_CSF, \ + (pcl), HAB_ALG_ANY, HAB_IDX_SRK, HAB_IDX_CSFK, \ + (crt)) + +#define INS_CSFK_BYTES INS_KEY_BASE_BYTES + +/* + * Install Key (IMGK - no hash) + */ + +#define INS_IMGK(flg, pcl, src, tgt, crt) \ + INS_KEY(INS_IMGK_BYTES, (flg), \ + (pcl), HAB_ALG_ANY, (src), (tgt), \ + (crt)) + +#define INS_IMGK_BYTES INS_KEY_BASE_BYTES + + +/* + * Install Key (IMGK - with hash). Must be followed by the crt_hsh contents + * (e.g. using #include). The length field depends on using one of the + * standard HAB algorithm names, with no adornments like casts or + * parentheses. Note that the length macro cannot be used here: the ## + * must appear in the body of this macro to prevent the alg parameter from + * being expanded first. + */ + +#define INS_IMGK_HASH(flg, pcl, alg, src, tgt, crt) \ + INS_KEY(INS_KEY_BASE_BYTES + BYTES_ ## alg, (flg) | HAB_CMD_INS_KEY_HSH, \ + (pcl), (alg), (src), (tgt), \ + (crt)) + +/* + * Same as above but the hash length is fixed to the length of SHA1, + * but the algorithm remains unchanged. + */ +#define INS_IMGK_INV_HASH(flg, pcl, alg, src, tgt, crt) \ + INS_KEY(INS_IMGK_HASH_BYTES(HAB_ALG_SHA1), (flg) | HAB_CMD_INS_KEY_HSH, \ + (pcl), (alg), (src), (tgt), \ + (crt)) + + +#define INS_IMGK_HASH_BYTES(alg) \ + (INS_KEY_BASE_BYTES + BYTES_ ## alg) + +#define BYTES_HAB_ALG_SHA1 20 +#define BYTES_HAB_ALG_SHA256 32 +#define BYTES_HAB_ALG_SHA512 64 +/* dummy value for invalid hash alg - same as default hash algorithm */ +#define DEFAULT_HASH_ALG_BYTES BYTES_HAB_ALG_SHA256 +#define BYTES_HAB_ALG_PKCS1 DEFAULT_HASH_ALG_BYTES + +/* + * Authenticate Data (generic - used internally only) + */ + +#define AUT_DAT(bytes, flg, key, pcl, eng, cfg, sig_start) \ + HDR(HAB_CMD_AUT_DAT, (bytes), (flg)), \ + (key), (pcl), (eng), (cfg), \ + EXPAND_UINT32(sig_start) + +#define AUT_DAT_BASE_BYTES 12 + +/* + * Authenticate Data (CSF) + */ + +#define AUT_CSF(flg, pcl, eng, cfg, sig_start) \ + AUT_DAT(AUT_CSF_BYTES, (flg), \ + HAB_IDX_CSFK, (pcl), (eng), (cfg), \ + (sig_start)) + +#define AUT_CSF_BYTES AUT_DAT_BASE_BYTES + +/* + * Authenticate Data (Image) + */ + +#define AUT_IMG(blocks, flg, key, pcl, eng, cfg, sig_start) \ + AUT_DAT(AUT_IMG_BYTES(blocks), (flg), \ + (key), (pcl), (eng), (cfg), \ + (sig_start)) + +#define AUT_IMG_BYTES(blocks) \ + (AUT_DAT_BASE_BYTES + 8*(blocks)) + +/** Supported widths of data commands. + * @ingroup cmd_wrt_dat + */ +typedef enum hab_data_width +{ + HAB_DATA_WIDTH_BYTE = 1, /**< 8-bit value */ + HAB_DATA_WIDTH_HALF = 2, /**< 16-bit value */ + HAB_DATA_WIDTH_WORD = 4 /**< 32-bit value */ +} hab_data_width_t; + + +/** Flags for Write Data commands. + * @ingroup cmd_wrt_dat + */ +typedef enum hab_cmd_wrt_dat_flg +{ + HAB_CMD_WRT_DAT_MSK = 1, /**< Mask/value flag: if set, only specific + * bits may be overwritten at target address + * (otherwise all bits may be overwritten) + */ + HAB_CMD_WRT_DAT_SET = 2 /**< Set/clear flag: if #HAB_CMD_WRT_DAT_MSK + * set, bits at the target address overwritten + * with this flag (otherwise it is ignored) + */ +} hab_cmd_wrt_dat_flg_t; + +/** Flags for Check Data commands. + * @ingroup cmd_chk_dat + */ +typedef enum hab_cmd_chk_dat_flg +{ + HAB_CMD_CHK_DAT_SET = 2, /**< Set/clear flag: bits set in mask must + * match this flag + */ + HAB_CMD_CHK_DAT_ANY = 4 /**< Any/all flag: if clear, all bits set in + * mask must match (otherwise any bit + * suffices) + */ +} hab_cmd_chk_dat_flg_t; + +/** Flags for Authenticate Data commands. + * @ingroup cmd_aut_dat + */ +typedef enum hab_cmd_aut_dat_flg +{ + HAB_CMD_AUT_DAT_CLR = 0, /**< No flags set */ + HAB_CMD_AUT_DAT_ABS = 1 /**< Absolute signature address */ +} hab_cmd_aut_dat_flg_t; + +/** Flags for Install Key commands. + * @ingroup cmd_ins_key + */ +typedef enum hab_cmd_ins_key_flg +{ + HAB_CMD_INS_KEY_CLR = 0, /**< No flags set */ + HAB_CMD_INS_KEY_ABS = 1, /**< Absolute certificate address */ + HAB_CMD_INS_KEY_CSF = 2, /**< Install CSF key */ + HAB_CMD_INS_KEY_DAT = 4, /**< Key binds to Data Type */ + HAB_CMD_INS_KEY_CFG = 8, /**< Key binds to Configuration */ + HAB_CMD_INS_KEY_FID = 16, /**< Key binds to Fabrication UID */ + HAB_CMD_INS_KEY_MID = 32, /**< Key binds to Manufacturing ID */ + HAB_CMD_INS_KEY_CID = 64, /**< Key binds to Caller ID */ + HAB_CMD_INS_KEY_HSH = 128 /**< Certificate hash present */ +} hab_cmd_ins_key_flg_t; + +/** Key flags. + * @ingroup key_pkcs1 + * + * @ifrom + * + * The binding flags given here align with those in #hab_cmd_ins_key_flg + * + * @endrom + * + */ +typedef enum hab_key_flg +{ + /* Two more flag values available */ + HAB_KEY_FLG_DAT = 4, /**< Key binds to Data Type */ + HAB_KEY_FLG_CFG = 8, /**< Key binds to Configuration */ + HAB_KEY_FLG_FID = 16, /**< Key binds to Fabrication UID */ + HAB_KEY_FLG_MID = 32, /**< Key binds to Manufacturing ID */ + HAB_KEY_FLG_CID = 64, /**< Key binds to Caller ID */ + HAB_KEY_FLG_CA = 128 /**< CA key */ +} hab_key_flg_t; + +/** Secret key flags. + * @ingroup crt_blob + */ +typedef enum hab_key_secret_flg +{ + /* Seven more flag values available */ + HAB_KEY_FLG_KEK = 128 /**< KEK */ +} hab_key_secret_flg_t; + +/** Binding data types + * @ingroup bnd_obj + */ +typedef enum hab_dat { + HAB_DAT_CSF = 0x0f, /**< CSF signature */ + HAB_DAT_IMG = 0x33, /**< Image signature */ +#ifdef HAB_FUTURE + HAB_DAT_PLG = 0x3c, /**< Plugin signature */ +#endif + HAB_DAT_MAX +} hab_dat_t; + +/* Available values: 55, 5a, 66, 69, 96, 99, a5, aa, c3, cc, f0, ff + */ + +/** Target check types + * @ingroup chk_tgt + */ +typedef enum hab_target { + HAB_TGT_MEMORY = 0x0f, /**< Check memory white list */ + HAB_TGT_PERIPHERAL = 0xf0, /**< Check peripheral white list */ + HAB_TGT_ANY = 0x55, /**< Check memory & peripheral white list */ + HAB_TGT_MAX +} hab_target_t; + +/** Security configuration types + * @ingroup status + */ +typedef enum hab_config { +/** @cond rom */ + HAB_CFG_FAB = 0x00, /**< @rom Un-programmed IC */ +/** @endcond */ + HAB_CFG_RETURN = 0x33, /**< Field Return IC */ + HAB_CFG_OPEN = 0xf0, /**< Non-secure IC */ + HAB_CFG_CLOSED = 0xcc /**< Secure IC */ +} hab_config_t; +/* Available values: 0f, 3c, 55, 5a, 66, 69, 96, 99, a5, aa, ff + */ + +/** Security state types + * @ingroup status + */ +typedef enum hab_state { + HAB_STATE_INITIAL = 0x33, /**< Initialising state (transitory) */ + HAB_STATE_CHECK = 0x55, /**< Check state (non-secure) */ + HAB_STATE_NONSECURE = 0x66, /**< Non-secure state */ + HAB_STATE_TRUSTED = 0x99, /**< Trusted state */ + HAB_STATE_SECURE = 0xaa, /**< Secure state */ + HAB_STATE_FAIL_SOFT = 0xcc, /**< Soft fail state */ + HAB_STATE_FAIL_HARD = 0xff, /**< Hard fail state (terminal) */ + HAB_STATE_NONE = 0xf0, /**< No security state machine */ + HAB_STATE_MAX +} hab_state_t; +/* Available values: 00, 0f, 3c, 5a, 69, 96, a5, c3 + */ + +/** HAB status types + * @ingroup status + */ +typedef enum hab_status { + HAB_STS_ANY = 0x00, /**< Match any status in + * hab_rvt.report_event() + */ + HAB_FAILURE = 0x33, /**< Operation failed */ + HAB_WARNING = 0x69, /**< Operation completed with warning */ + HAB_SUCCESS = 0xf0, /**< Operation completed successfully */ + HAB_STS_MAX +} hab_status_t; + +/** Failure or warning reasons + * @ingroup evt + * + * Values 0x80 ... 0xff are reserved for internal use. + */ +typedef enum hab_reason { + HAB_RSN_ANY = 0x00, /**< Match any reason in + * hab_rvt.report_event() + */ + HAB_ENG_FAIL = 0x30, /**< Engine failure. */ + HAB_INV_ADDRESS = 0x22, /**< Invalid address: access denied. */ + HAB_INV_ASSERTION = 0x0c, /**< Invalid assertion. */ + HAB_INV_CALL = 0x28, /**< Function called out of sequence. */ + HAB_INV_CERTIFICATE = 0x21, /**< Invalid certificate. */ + HAB_INV_COMMAND = 0x06, /**< Invalid command: command malformed. */ + HAB_INV_CSF = 0x11, /**< Invalid @ref csf. */ + HAB_INV_DCD = 0x27, /**< Invalid @ref dcd. */ + HAB_INV_INDEX = 0x0f, /**< Invalid index: access denied. */ + HAB_INV_IVT = 0x05, /**< Invalid @ref ivt. */ + HAB_INV_KEY = 0x1d, /**< Invalid key. */ + HAB_INV_RETURN = 0x1e, /**< Failed callback function. */ + HAB_INV_SIGNATURE = 0x18, /**< Invalid signature. */ + HAB_INV_SIZE = 0x17, /**< Invalid data size. */ + HAB_MEM_FAIL = 0x2e, /**< Memory failure. */ + HAB_OVR_COUNT = 0x2b, /**< Expired poll count. */ + HAB_OVR_STORAGE = 0x2d, /**< Exhausted storage region. */ + HAB_UNS_ALGORITHM = 0x12, /**< Unsupported algorithm. */ + HAB_UNS_COMMAND = 0x03, /**< Unsupported command. */ + HAB_UNS_ENGINE = 0x0a, /**< Unsupported engine. */ + HAB_UNS_ITEM = 0x24, /**< Unsupported configuration item. */ + HAB_UNS_KEY = 0x1b, /**< Unsupported key type or parameters. */ + HAB_UNS_PROTOCOL = 0x14, /**< Unsupported protocol. */ + HAB_UNS_STATE = 0x09, /**< Unsuitable state. */ + HAB_RSN_MAX +} hab_reason_t; +/* Available values: 33, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44, + * 47, 48, 4b, 4d, 4e, 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a, + * 6c, 6f, 71, 72, 74, 77, 78, 7b, 7d, 7e + */ + +/** Audit logging contexts. + * @ingroup evt + * + * This list is sorted in order of increasing priority: where two contexts + * might apply, the latter one is used. + * + * Values 0x40 .. 0x5f are reserved for internal use. + */ +typedef enum hab_context { + HAB_CTX_ANY = 0x00, /**< Match any context in + * hab_rvt.report_event() + */ +/** @cond rom */ + HAB_CTX_FAB = 0xff, /**< @rom Event logged in hab_fab_test() */ +/** @endcond */ + HAB_CTX_ENTRY = 0xe1, /**< Event logged in hab_rvt.entry() */ + HAB_CTX_TARGET = 0x33, /**< Event logged in hab_rvt.check_target() */ + HAB_CTX_AUTHENTICATE = 0x0a, /**< Event logged in + * hab_rvt.authenticate_image() + */ + HAB_CTX_DCD = 0xdd, /**< Event logged in hab_rvt.run_dcd() */ + HAB_CTX_CSF = 0xcf, /**< Event logged in hab_rvt.run_csf() */ + HAB_CTX_COMMAND = 0xc0, /**< Event logged executing @ref csf or @ref + * dcd command + */ + HAB_CTX_AUT_DAT = 0xdb, /**< Authenticated data block */ + HAB_CTX_ASSERT = 0xa0, /**< Event logged in hab_rvt.assert() */ + HAB_CTX_EXIT = 0xee, /**< Event logged in hab_rvt.exit() */ + HAB_CTX_MAX +} hab_context_t; + +/** Assertion types. + * @ingroup assert + */ +typedef enum hab_assertion { + HAB_ASSERT_BLOCK = 0, /**< Assert that a memory block was authenticated */ + HAB_ASSERT_MAX +} hab_assertion_t; + +/** RTIC configuration flags + * @ingroup rtic + */ +typedef enum hab_rtic_config { + HAB_RTIC_IN_SWAP8 = 0x01, /**< Set BYTE SWAP bit (reverse bytes within + * word on input to RTIC) */ + HAB_RTIC_IN_SWAP16 = 0x02, /**< Set HALF WORD SWAP bit (reverse + * half-words within word on input to + * RTIC) */ + HAB_RTIC_OUT_SWAP8 = 0x08, /**< Set HASH RESULT BYTE SWAP bit (reverse + * bytes within word on output from RTIC) */ + HAB_RTIC_KEEP = 0x80 /**< Retain reference hash value for later + * monitoring */ +} hab_rtic_config_t; + +/** SAHARA configuration flags + * @ingroup sah + */ +typedef enum hab_sahara_config { + HAB_SAHARA_IN_SWAP8 = 0x01, /**< Set MESS BYTE SWAP bit (reverse message + * bytes within word on input to + * SAHARA) */ + HAB_SAHARA_IN_SWAP16 = 0x02, /**< Set MESS HALF WORD SWAP bit (reverse + * message half-words within word on input + * to SAHARA) */ + /* no SWAP32 for SAHARA message - leave 0x04 value unassigned */ + /* no SWAP8 for SAHARA descriptors/links - leave 0x08 value unassigned */ + HAB_SAHARA_DSC_BE8_16 = 0x10, /**< Interpret descriptors and links as for + * BE-8 16-bit memory. */ + HAB_SAHARA_DSC_BE8_32 = 0x20 /**< Interpret descriptors and links as for + * BE-8 32-bit memory. */ +} hab_sahara_config_t; + +/** CAAM configuration flags + * @ingroup caam + */ +typedef enum hab_caam_config { + HAB_CAAM_IN_SWAP8 = 0x01, /**< Set Message Byte Swap Input bit (reverse + * message bytes within word on input to + * CAAM) */ + HAB_CAAM_IN_SWAP16 = 0x02, /**< Set Message Half Word Swap Input bit + * (reverse message half-words within word + * on input to CAAM) */ + /* no SWAP32 for CAAM message - leave 0x04 value unassigned */ + HAB_CAAM_OUT_SWAP8 = 0x08, /**< Set Message Byte Swap Output bit + * (reverse message bytes within word on + * output from CAAM) */ + HAB_CAAM_OUT_SWAP16 = 0x10, /**< Set Message Half Word Swap Output bit + * (reverse message half-words within word + * on output from CAAM) */ + /* no SWAP32 for CAAM message - leave 0x20 value unassigned */ + HAB_CAAM_DSC_SWAP8 = 0x40, /**< Set Control Byte Swap Input/Output bits + * (reverse descriptor/link bytes within + * word on input to or output from CAAM) */ + HAB_CAAM_DSC_SWAP16 = 0x80 /**< Set Control Half Word Swap Input/Output + * bits (reverse descriptor/link half-words + * within word on input to or output from + * CAAM) */ +} hab_caam_config_t; + +/** CAAM unlock flags + * @ingroup caam + */ +typedef enum hab_caam_unlock_flag { + HAB_CAAM_UNLOCK_MID = 0x01, /**< Leave Job Ring and DECO master ID + * registers unlocked */ + HAB_CAAM_UNLOCK_RNG = 0x02 /**< Leave RNG state handle 0 + * uninstantiated, do not generate + * descriptor keys, do not set AES DPA + * mask, do not block state handle 0 test + * instantiation */ +} hab_caam_unlock_flag_t; + +/** SNVS unlock flags + * @ingroup snvs + */ +typedef enum hab_snvs_unlock_flag { + HAB_SNVS_UNLOCK_LP_SWR = 0x01, /**< Leave LP SW reset unlocked */ + HAB_SNVS_UNLOCK_ZMK_WRITE = 0x02 /**< Leave Zeroisable Master Key write + * unlocked */ +} hab_snvs_unlock_flag_t; + +/** SNVS master keys + * @ingroup snvs + * + * @remark Note that the first two master key selections are completely + * interchangeable. + */ +typedef enum hab_snvs_keys { + HAB_SNVS_OTPMK = 0, /**< OTP master key */ + HAB_SNVS_OTPMK_ALIAS = 1, /**< OTP master key (alias) */ + HAB_SNVS_ZMK = 2, /**< Zeroisable master key */ + HAB_SNVS_CMK = 3 /**< Combined master key */ +} hab_snvs_keys_t; + + +/** OCOTP unlock flags + * @ingroup ocotp + */ +typedef enum hab_ocotp_unlock_flag { + HAB_OCOTP_UNLOCK_FIELD_RETURN = 0x01, /**< Leave Field Return activation + * unlocked */ + HAB_OCOTP_UNLOCK_SRK_REVOKE = 0x02, /**< Leave SRK revocation unlocked */ + HAB_OCOTP_UNLOCK_SCS = 0x04, /**< Leave SCS register unlocked */ + HAB_OCOTP_UNLOCK_JTAG = 0x08 /**< Unlock JTAG using SCS HAB_JDE + * bit */ +} hab_ocotp_unlock_flag_t; + +/** DCP configuration flags + * @ingroup dcp + * + * @warning The byte-swapping controls produce unpredictable results unless + * the input data block lengths are multiples of 4 bytes. + */ +typedef enum hab_dcp_config { + HAB_DCP_IN_SWAP8 = 0x01, /**< Set INPUT BYTE SWAP bit (reverse bytes + * within words on input to DCP) */ + /* no SWAP16 for DCP - leave 0x02 value unassigned */ + HAB_DCP_IN_SWAP32 = 0x04, /**< Set INPUT WORD SWAP bit (ignored for + * hashing) */ + HAB_DCP_OUT_SWAP8 = 0x08, /**< Set OUPUT BYTE SWAP bit (reverse bytes + * within words on output from DCP) */ + /* no SWAP16 for DCP - leave 0x10 value unassigned */ + HAB_DCP_OUT_SWAP32 = 0x20 /**< Set OUTPUT WORD SWAP bit (ignored for + * hashing) */ +} hab_dcp_config_t; + +#ifdef HAB_FUTURE +/** EC key specification types. + * @ingroup key_ecdsa + */ +typedef enum hab_ec_spec { + /** Named curve specification. The curve specification is a DER-encoded + * object identifier. Supported object identifiers are listed under @ref + * key_ecdsa_profile "ECDSA key profile". + */ + HAB_EC_SPEC_NAMED_CURVE = 0x01 +} hab_ec_spec_t; +#endif + +/** Variable configuration items + * @ingroup cmd_set + */ +typedef enum hab_var_cfg_itm { + HAB_VAR_CFG_ITM_MID = 0x01, /**< Manufacturing ID (MID) fuse locations */ + HAB_VAR_CFG_ITM_ENG = 0x03 /**< Preferred engine for a given algorithm */ +} hab_var_cfg_itm_t; + +/*=========================================================================== + ENUMS +=============================================================================*/ + +/*=========================================================================== + STRUCTURES AND OTHER TYPEDEFS +=============================================================================*/ + +/** Header field components + * @ingroup hdr + */ +typedef struct hab_hdr { + uint8_t tag; /**< Tag field */ + uint8_t len[2]; /**< Length field in bytes (big-endian) */ + uint8_t par; /**< Parameters field */ +} hab_hdr_t; + +/** Loader callback. + * @ingroup auth_img + * + * @par Purpose + * + * This function must be supplied by the library caller if required. It is + * intended to finalise image loading in those boot modes where only a portion + * of the image is loaded to a temporary initial location prior to device + * configuration. + * + * @par Operation + * + * This function is called during hab_rvt.authenticate_image() between running + * the @ref dcd and @ref csf. The operation of this function is defined by + * the caller. + * + * @param[in,out] start Initial (possibly partial) image load address on + * entry. Final image load address on exit. + * + * @param[in,out] bytes Initial (possibly partial) image size on entry. Final + * image size on exit. + * + * @param[in] boot_data Initial @ref ivt Boot Data load address. + * + * @remark The interpretation of the Boot Data is defined by the caller. + * Different boot components or modes may use different boot data, or even + * different loader callback functions. + * + * @warning It should not be assumed by this function that the Boot Data is + * valid or authentic. + * + * @warning It is the responsibility of the loader callback to check the final + * image load addresses using hab_rvt.check_target() prior to copying any image + * data. + * + * @pre The (possibly partial) image has been loaded in the initial load + * address, and the Boot Data is within the initial image. + * + * @pre The @ref dcd has been run, if provided. + * + * @post The final image load addresses pass hab_rvt.check_target(). + * + * @retval #HAB_SUCCESS if all operations completed successfully, + * + * @retval #HAB_FAILURE otherwise. + */ +typedef hab_status_t (*hab_loader_callback_f)( + void** start, + size_t* bytes, + const void* boot_data); + +/*---------------------------------------------------------------------------*/ + +/** Image entry function prototype + * @ingroup rvt + * + * This typedef serves as the return type for hab_rvt.authenticate_image(). It + * specifies a void-void function pointer, but can be cast to another function + * pointer type if required. + */ +typedef void (*hab_image_entry_f)(void); + +/*---------------------------------------------------------------------------*/ + +/** @ref rvt structure + * @ingroup rvt + * + * @par Format + * + * The @ref rvt consists of a @ref hdr followed by a list of addresses as + * described further below. + */ +struct hab_rvt { + + /** @ref hdr with tag #HAB_TAG_RVT, length and HAB version fields + * (see @ref data) + */ + hab_hdr_t hdr; + + /** Enter and initialise HAB library. + * @ingroup entry + * + * @par Purpose + * + * This function initialises the HAB library and @ref shw plugins. It is + * intended for use by post-ROM boot stage components, via the @ref rvt, + * prior to calling any other HAB functions other than + * hab_rvt.report_event() and hab_rvt.report_status(). + * + * @ifrom It is also intended for use by the boot ROM via hab_rvt.entry(). + * @endrom + * + * @par Operation + * + * This function performs the following operations every time it is called: + * + * - Initialise the HAB library internal state + * - Initialise the internal secret key store (cleared at the next + * hab_rvt.exit()) + * - Run the entry sequence of each available @ref shw plugin + * + * When first called from boot ROM, this function also performs the + * following operations prior to those given above: + * + * - Initialise the internal public key store (persists beyond + * hab_rvt.exit()) + * - Run the self-test sequence of each available @ref shw plugin + * - If a state machine is present and enabled, change the security state + * as follows: + * - If the IC is configured as #HAB_CFG_OPEN or #HAB_CFG_RETURN, move to + * #HAB_STATE_NONSECURE + * - If the IC is configured as #HAB_CFG_CLOSED, move to + * #HAB_STATE_TRUSTED + * - Otherwise, leave the security state unchanged + * + * If any failure occurs in the operations above: + * + * - An audit event is logged + * - All remaining operations are abandoned (except that all @ref shw + * self-test and entry sequences are still executed) + * - If a state machine is present and enabled, the security state is set + * as follows: + * - @ifrom Unless the IC is configured as #HAB_CFG_FAB,@endrom move to + * #HAB_STATE_NONSECURE. Note that if a security violation has been + * detected by the HW, the final state will be #HAB_STATE_FAIL_SOFT or + * #HAB_STATE_FAIL_HARD depending on the HW configuration. + * + * @warning Boot sequences may comprise several images with each launching + * the next as well as alternative images should one boot device or boot + * image be unavailable or unusable. The authentication of each image in + * a boot sequence must be bracketed by its own hab_rvt.entry() + * ... hab_rvt.exit() pair in order to ensure that security state + * information gathered for one image cannot be misapplied to another + * image. + * + * @ifrom + * + * @warning This applies to each boot path in boot ROM as well, except for + * the fabrication test path. + * + * @endrom + * + * @post HAB library internal state is initialised. + * + * @post Available @ref shw plugins are initialised. + * + * @post If a failure or warning occurs during @ref shw plugin + * initialisation, an audit event is logged with the relevant @ref eng + * tag. The status and reason logged are described in the relevant @ref + * shw plugin documentation. + * + * @post Security state is initialised, if a state machine is present and + * enabled. + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if all commands completed + * without failure (even if warnings were generated), + * + * @retval #HAB_FAILURE otherwise. + */ + hab_status_t (*entry)(void); + + /** Finalise and exit HAB library. + * @ingroup exit + * + * @par Purpose + * + * This function finalises the HAB library and @ref shw plugins. It is + * intended for use by post-ROM boot stage components, via the @ref rvt, + * after calling other HAB functions and prior to launching the next boot + * stage or switching to another boot path. + * + * @ifrom It is also intended for use by the boot ROM via hab_rvt.exit(). + * @endrom + * + * @par Operation + * + * This function performs the following operations: + * + * - Finalise the HAB library internal state + * - Clear the internal secret key store + * - Run the finalisation sequence of each available @ref shw plugin + * + * If any failure occurs, an audit event is logged and all remaining + * operations are abandoned (except that all @ref shw exit sequences are + * still executed). + * + * @warning See warnings for hab_rvt.entry(). + * + * @post #HAB_ASSERT_BLOCK records are cleared from audit log. Note that + * other event records are not cleared. + * + * @post Any public keys installed by @ref csf commands remain active. + * + * @post Any secret keys installed by @ref csf commands are deleted. + * + * @post Available @ref shw plugins are in their final state as described + * in the relevant sections. + * + * @post If a failure or warning occurs, an audit event is logged with the + * @ref eng tag of the @ref shw plugin concerned. The status and reason + * logged are described in the relevant @ref shw plugin documentation. + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if all commands completed + * without failure (even if warnings were generated), + * + * @retval #HAB_FAILURE otherwise. + */ + hab_status_t (*exit)(void); + + /** Check target address + * @ingroup chk_tgt + * + * @par Purpose + * + * This function reports whether or not a given target region is allowed + * for either peripheral configuration or image loading in memory. It is + * intended for use by post-ROM boot stage components, via the @ref rvt, + * in order to avoid configuring security-sensitive peripherals, or + * loading images over sensitive memory regions or outside recognised + * memory devices in the address map. + * + * @ifrom It is also available for use by the boot ROM, both directly via + * hab_rvt.check_target() and indirectly via hab_rvt.authenticate_image(). + * @endrom + * + * @par Operation + * + * The lists of allowed target regions vary by IC and core, and should be + * taken from the @ref ref_rug. + * + * @ifrom The allowed register sets for peripheral configuration and memory + * regions for image loading are defined in the @ref hal by + * #hab_hal_peripheral and #hab_hal_memory respectively. @endrom + * + * @param[in] type Type of target (memory, peripheral or any in which both + * the memory and peripheral regions are checked) + * + * @param[in] start Address of target region + * + * @param[in] bytes Size of target region + * + * @post if the given target region goes beyond the allowed regions, an + * audit event is logged with status #HAB_FAILURE and reason + * #HAB_INV_ADDRESS, together with the call parameters. See the @ref evt + * record documentation for details. + * + * @post For successful commands, no audit event is logged. + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS if the given target region lies wholly within the + * allowed regions for the requested type of target. + * + * @retval #HAB_FAILURE otherwise + */ + hab_status_t (*check_target)(hab_target_t type, + const void* start, + size_t bytes); + + /** Authenticate image. + * @ingroup auth_img + * + * @par Purpose + * + * This function combines DCD, CSF and Assert functions in a standard + * sequence in order to authenticate a loaded image. It is intended for + * use by post-ROM boot stage components, via the @ref rvt. Support for + * images partially loaded to an initial location is provided via a + * callback function. + * + * @ifrom It is also available for use by the boot ROM via + * hab_rvt.authenticate_image(). @endrom + * + * @par Operation + * + * This function performs the following sequence of operations: + * - Check that the initial image load addresses pass + * hab_rvt.check_target(). + * - Check that the IVT offset lies within the initial image bounds. + * - Check that the @ref ivt @a self and @a entry pointers are not NULL + * - Check the @ref ivt header for consistency and compatability. + * - If provided in the @ref ivt, calculate the @ref dcd initial location, + * check that it lies within the initial image bounds, and run the @ref + * dcd commands. + * - If provided in the @ref ivt, calculate the Boot Data initial location + * and check that it lies within the initial image bounds. + * - If provided in the parameters, invoke the callback function with the + * initial image bounds and initial location of the @ref ivt Boot Data. + * + * From this point on, the full image is assumed to be in its final + * location. The following operations will be performed on all IC + * configurations (#hab_config), but will be only enforced on an IC + * configured as #HAB_CFG_CLOSED: + * - Check that the final image load addresses pass hab_rvt.check_target(). + * - Check that the CSF lies within the image bounds, and run the CSF + * commands. + * - Check that all of the following data have been authenticated (using + * their final locations): + * - IVT; + * - DCD (if provided); + * - Boot Data (initial byte if provided); + * - Entry point (initial word). + * + * @param[in] cid Caller ID, used to identify which SW issued this call. + * + * @param[in] ivt_offset Offset in bytes of the IVT from the image start + * address. + * + * @param[in,out] start Initial (possibly partial) image load address on + * entry. Final image load address on exit. + * + * @param[in,out] bytes Initial (possibly partial) image size on entry. + * Final image size on exit. + * + * @param[in] loader Callback function to load the full image to its final + * load address. Set to NULL if not required. + * + * @remark Caller ID may be bound to signatures verified using keys + * installed with #HAB_CMD_INS_KEY_CID flag. See @ref cmd_ins_key and @ref + * bnd_obj for details. + * + * @remark A @a loader callback function may be supplied even if the image + * is already loaded to its final location on entry. + * + * @remark Boot Data (boot_data in @ref ivt) will be ignored if the + * @a loader callback function point is set to Null. + * + * @warning The @a loader callback function should lie within existing + * authenticated areas. @ifrom Or within the ROM. @endrom + * + * @warning It is the responsibility of the caller to check the initial + * image load addresses using hab_rvt.check_target() prior to loading the + * initial image and calling this function. + * + * @warning After completion of hab_rvt.authenticate_image(), the caller + * should test using hab_rvt.assert() that the Boot Data was + * authenticated. + * + * @post The post-conditions of the functions hab_rvt.check_target(), + * hab_rvt.run_dcd(), hab_rvt.run_csf() and hab_rvt.assert() apply also to + * this function. In particular, any audit events logged within the given + * functions have the context field appropriate to that function rather + * than #HAB_CTX_AUTHENTICATE. In addition, the side-effects and + * post-conditions of any callback function supplied apply. + * + * @post If a failure or warning occurs outside these contexts, an audit + * event is logged with status: + * - #HAB_FAILURE, with further reasons: + * - #HAB_INV_ADDRESS: initial or final image addresses outside allowed + * regions + * - #HAB_INV_ADDRESS: IVT, DCD, Boot Data or CSF outside image bounds + * - #HAB_INV_ADDRESS: IVT @a self or @a entry pointer is NULL + * - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call + * - #HAB_INV_IVT: IVT malformed + * - #HAB_INV_IVT: IVT version number is less than HAB library version + * - #HAB_INV_RETURN: Callback function failed + * + * @retval entry field from @ref ivt on an IC not configured as + * #HAB_CFG_CLOSED provided that the following conditions are met + * (other unsuccessful operations will generate audit log events): + * - the @a start pointer and the pointer it locates are not NULL + * - the initial @ref ivt location is not NULL + * - the @ref ivt @ref hdr (given in the @a hdr field) is valid + * - the final @ref ivt location (given by the @a self field) is not NULL + * - any loader callback completed successfully, + * + * @retval entry field from @ref ivt on other ICs if all operations + * completed without failure (even if warnings were generated), + * + * @retval NULL otherwise. + */ + hab_image_entry_f (*authenticate_image)(uint8_t cid, + ptrdiff_t ivt_offset, + void** start, + size_t* bytes, + hab_loader_callback_f loader); + + /** Execute a boot configuration script. + * @ingroup run_dcd + * + * @par Purpose + * + * This function configures the IC based upon a @ref dcd table. It is + * intended for use by post-ROM boot stage components, via the @ref rvt. + * This function may be invoked as often as required for each boot stage. + * + * @ifrom It is also intended for use by the boot ROM, both directly via + * hab_rvt.run_dcd() and indirectly via hab_rvt.authenticate_image(). + * @endrom + * + * The difference between the configuration functionality in this function + * and hab_rvt.run_csf() arises because the @ref dcd table is not + * authenticated prior to running the commands. Hence, there is a more + * limited range of commands allowed, and a limited range of parameters to + * allowed commands. + * + * @par Operation + * + * This function performs the following operations: + * - Checks the @ref hdr for compatibility and consistency + * - Makes an internal copy of the @ref dcd table + * - Executes the commands in sequence from the internal copy of the @ref + * dcd + * + * If any failure occurs, an audit event is logged and all remaining + * operations are abandoned. + * + * @param[in] dcd Address of the @ref dcd. + * + * @warning It is the responsibility of the caller to ensure that the @a + * dcd parameter points to a valid memory location. + * + * @warning The @ref dcd must be authenticated by a subsequent @ref csf + * command prior to launching the next boot image, in order to avoid + * unauthorised configurations which may subvert secure operation. + * Although the content of the next boot stage's CSF may be out of scope + * for the hab_rvt.run_dcd() caller, it is possible to enforce this + * constraint by using hab_rvt.assert() to ensure that both the DCD and + * any pointers used to locate it have been authenticated. + * + * @warning Each invocation of hab_rvt.run_dcd() must occur between a pair + * of hab_rvt.entry() and hab_rvt.exit() calls, although multiple + * hab_rvt.run_dcd() calls (and other HAB calls) may be made in one + * bracket. This constraint applies whether hab_rvt.run_dcd() is + * successful or not: a subsequent call to hab_rvt.exit() is required + * prior to launching the authenticated image or switching to another boot + * target. + * + * @post Many commands may cause side-effects. See the @ref dcd + * documentation. + * + * @post If a failure or warning occurs within a command handler, an audit + * event is logged with the offending command, copied from the DCD. The + * status and reason logged are described in the relevant command + * documentation. + * + * @post For other failures or warning, the status logged is: + * - #HAB_WARNING, with further reasons: + * - #HAB_UNS_COMMAND: unsupported command encountered, where DCD + * version and HAB library version differ + * - #HAB_FAILURE, with further reasons: + * - #HAB_INV_ADDRESS: NULL @a dcd parameter + * - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call + * - #HAB_INV_COMMAND: command not allowed in DCD + * - #HAB_UNS_COMMAND: unrecognised command encountered, where DCD + * version and HAB library version match + * - #HAB_INV_DCD: DCD malformed or too large + * - #HAB_INV_DCD: DCD version number is less than HAB library version + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if all commands completed + * without failure (even if warnings were generated), + * + * @retval #HAB_FAILURE otherwise. + */ + hab_status_t (*run_dcd)(const uint8_t* dcd); + + /** Execute an authentication script. + * @ingroup run_csf + * + * @par Purpose + * + * This function authenticates SW images and configures the IC based upon + * a @ref csf. It is intended for use by post-ROM boot stage components, + * via the @ref rvt. This function may be invoked as often as required + * for each boot stage. + * + * @ifrom It is also available for use by the boot ROM via hab_rvt.run_csf, + * although it is anticipated that the boot ROM will mostly call this + * function indirectly via hab_rvt.authenticate_image(). @endrom + * + * @par Operation + * + * This function performs the following operations: + * - Checks the @ref hdr for compatibility and consistency + * - Makes an internal copy of the @ref csf + * - Executes the commands in sequence from the internal copy of the @ref + * csf + * + * The internal copy of the @ref csf is authenticated by an explicit + * command in the sequence. Prior to authentication, a limited set of + * commands is available to: + * - Install a Super-Root key (unless previously installed) + * - Install a CSF key (unless previously installed) + * - Specify any variable configuration items + * - Authenticate the CSF + * + * Subsequent to CSF authentication, the full set of commands is available. + * + * If any failure occurs, an audit event is logged and all remaining + * operations are abandoned. + * + * @param[in] csf Address of the @ref csf. + * + * @param[in] cid Caller ID, used to identify which SW issued this call. + * + * @remark Caller ID may be bound to signatures verified using keys + * installed with #HAB_CMD_INS_KEY_CID flag. See @ref cmd_ins_key and @ref + * bnd_obj for details. + * + * @warning It is the responsibility of the caller to ensure that the @a + * csf parameter points to a valid memory location. + * + * @warning Each invocation of hab_rvt.run_csf() must occur between a pair + * of hab_rvt.entry() and hab_rvt.exit() calls, although multiple + * hab_rvt.run_csf() calls (and other HAB calls) may be made in one + * bracket. This constraint applies whether hab_rvt.run_csf() is + * successful or not: a subsequent call to hab_rvt.exit() is required + * prior to launching the authenticated image or switching to another boot + * target. + * + * @post Many commands may cause side-effects. See the @ref csf + * documentation. In particular, note that keys installed by the @ref csf + * remain available for use in subsequent operations. + * + * @post If a failure or warning occurs within a command handler, an audit + * event is logged with the offending command, copied from the CSF. The + * status and reason logged are described in the relevant command + * documentation. + * + * @post For other failures or warning, the status logged is: + * - #HAB_WARNING, with further reasons: + * - #HAB_UNS_COMMAND: unsupported command encountered, where CSF + * version and HAB library version differ + * - #HAB_FAILURE, with further reasons: + * - #HAB_INV_ADDRESS: NULL @a csf parameter + * - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call + * - #HAB_INV_COMMAND: command not allowed prior to CSF authentication + * - #HAB_UNS_COMMAND: unrecognised command encountered, where CSF + * version and HAB library version match + * - #HAB_INV_CSF: CSF not authenticated + * - #HAB_INV_CSF: CSF malformed or too large + * - #HAB_INV_CSF: CSF version number is less than HAB library version + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if all commands completed + * without failure (even if warnings were generated), + * + * @retval #HAB_FAILURE otherwise. + */ + hab_status_t (*run_csf)(const uint8_t* csf, + uint8_t cid); + + /** Test an assertion against the audit log. + * @ingroup assert + * + * @par Purpose + * + * This function allows the audit log to be interrogated. It is intended + * for use by post-ROM boot stage components, via the @ref rvt, to + * determine the state of authentication operations. This function may be + * invoked as often as required for each boot stage. + * + * @ifrom It is also available for use by the boot ROM, both directly via + * hab_rvt.assert() and indirectly via hab_rvt.authenticate_image(). + * @endrom + * + * @par Operation + * + * This function checks the required assertion as detailed below. + * + * @param[in] type Assertion type. + * + * @param[in] data Assertion data. + * + * @param[in] count Data size or count. + * + * @par Memory block authentication: + * For #HAB_ASSERT_BLOCK assertion type, hab_rvt.assert() checks that the + * given memory block has been authenticated after running a CSF. The + * parameters are interpreted as follows: + * + * @par + * - @a data: memory block starting address + * - @a count: memory block size (in bytes) + * + * @par + * + * A simple interpretation of "memory block has been authenticated" is + * taken, such that the given block must lie wholly within a single + * contiguous block authenticated while running a CSF. A given memory + * block covered by the union of several neighboring or overlapping + * authenticated blocks could fail the test with this interpretation, but + * it is assumed that such cases will not arise in practice. + * + * @post If the assertion fails, an audit event is logged with status + * #HAB_FAILURE and reason #HAB_INV_ASSERTION, together with the call + * parameters. See the @ref evt record documentation for details. + * + * @post For successful commands, no audit event is logged. + * + * @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED, + * although unsuccessful operations will still generate audit log events, + * + * @retval #HAB_SUCCESS on other ICs if the assertion is confirmed + * + * @retval #HAB_FAILURE otherwise + */ + hab_status_t (*assert)(hab_assertion_t type, + const void* data, + uint32_t count); + + /** Report an event from the audit log. + * @ingroup event + * + * @par Purpose + * + * This function allows the audit log to be interrogated. It is intended + * for use by post-ROM boot stage components, via the @ref rvt, to + * determine the state of authentication operations. This function may + * be called outside an hab_rvt.entry() / hab_rvt.exit() pair. + * + * @ifrom It is also available for use by the boot ROM, where it may be + * used to report boot failures as part of a tethered boot + * protocol. @endrom + * + * @par Operation + * + * This function performs the following operations: + * - Scans the audit log for a matching event + * - Copies the required details to the output parameters (if found) + * + * @param[in] status Status level of required event. + * + * @param[in] index Index of required event at given status level. + * + * @param[out] event @ref evt record. + * + * @param[in,out] bytes Size of @a event buffer on entry, size of event + * record on exit. + * + * @remark Use @a status = #HAB_STS_ANY to match any logged event, + * regardless of the status value logged. + * + * @remark Use @a index = 0 to return the first matching event, @a index = + * 1 to return the second matching event, and so on. + * + * @remark The data logged with each event is context-dependent. Refer to + * @ref evt record documentation. + * + * @warning Parameter @a bytes may not be NULL. + * + * @warning If the @a event buffer is a NULL pointer or too small to fit + * the event record, the required size is written to @a bytes, but no + * part of the event record is copied to the output buffer. + * + * @retval #HAB_SUCCESS if the required event is found, and the event + * record is copied to the output buffer. + * + * @retval #HAB_SUCCESS if the required event is found and @a event buffer + * passed is a NULL pointer. + * + * @retval #HAB_FAILURE otherwise + */ + hab_status_t (*report_event)(hab_status_t status, + uint32_t index, + uint8_t* event, + size_t* bytes); + + /** Report security status. + * @ingroup status + * + * @par Purpose + * + * This function reports the security configuration and state of the IC as + * well as searching the audit log to determine the status of the boot + * process. It is intended for use by post-ROM boot stage components, via + * the @ref rvt. This function may be called outside an + * hab_rvt.entry() / hab_rvt.exit() pair. + * + * @ifrom It is also available for use by the boot ROM, and should be used + * rather than the HAL function hab_hal_read_sec_cfg(). @endrom + * + * @par Operation + * + * This function reads the fuses which indicate the security + * configuration. The fusemap varies by IC, and should be taken from the + * @ref ref_rug. It also uses the @ref shw state machine, if present and + * enabled, to report on the security state. + * + * @param[out] config Security configuration, NULL if not required + * + * @param[out] state Security state, NULL if not required + * + * @remark If no @ref shw state machine is present and enabled, the state + * #HAB_STATE_NONE will be output. + * + * @retval #HAB_SUCCESS if no warning or failure audit events have been + * logged. + * + * @retval #HAB_WARNING otherwise, if only warning events have been logged. + * + * @retval #HAB_FAILURE otherwise + */ + hab_status_t (*report_status)(hab_config_t* config, hab_state_t* state); + + /** Enter failsafe boot mode. + * @ingroup safe + * + * @par Purpose + * + * This function provides a safe path when image authentication has failed + * and all possible boot paths have been exhausted. It is intended for + * use by post-ROM boot stage components, via the @ref rvt. + * + * @ifrom It is also available for use by the boot ROM via + * hab_rvt.failsafe(). @endrom + * + * @par Operation + * + * The precise details of this function vary by IC and core, and should be + * taken from @ref ref_rug. + * + * @warning This function does not return. + * + * @remark Since this function does not return, it implicitly performs the + * functionality of hab_rvt.exit() in order to ensure an appropriate + * configuration of the @ref shw plugins. + * + * @remark Two typical implementations are: + * - a low-level provisioning protocol in which an image is downloaded to + * RAM from an external host, authenticated and launched. The downloaded + * image may communicate with tools on the external host to report the + * reasons for boot failure, and may re-provision the end-product with + * authentic boot images. + * - a failsafe boot mode which does not allow execution to leave the ROM + * until the IC is reset. + */ + void (*failsafe)(void); +}; + +/** @ref rvt type + * @ingroup rvt + */ +typedef struct hab_rvt hab_rvt_t; + +/*---------------------------------------------------------------------------*/ + +/** @ref ivt structure + * @ingroup ivt + * + * @par Format + * + * An @ref ivt consists of a @ref hdr followed by a list of addresses as + * described further below. + * + * @warning The @a entry address may not be NULL. + * + * @warning On an IC not configured as #HAB_CFG_CLOSED, the + * @a csf address may be NULL. If it is not NULL, the @ref csf will be + * processed, but any failures should be non-fatal. + * + * @warning On an IC configured as #HAB_CFG_CLOSED, the @a + * csf address may not be NULL, and @ref csf failures are typically fatal. + * + * @remark The Boot Data located using the @a boot_data field is interpreted + * by the HAB caller in a boot-mode specific manner. This may be used by the + * boot ROM as to determine the load address and boot device configuration for + * images loaded from block devices (see @ref ref_rug for details). + * + * @remark All addresses given in the IVT, including the Boot Data (if + * present) are those for the final load location. + * + * @anchor ila + * + * @par Initial load addresses + * + * The @a self field is used to calculate addresses in boot modes where an + * initial portion of the image is loaded to an initial location. In such + * cases, the IVT, Boot Data (if present) and DCD (if present) are used in + * configuring the IC and loading the full image to its final location. Only + * the IVT, Boot Data (if present) and DCD (if present) are required to be + * within the initial image portion. + * + * The method for calculating an initial load address for the DCD is + * illustrated in the following C fragment. Similar calculations apply to + * other fields. + * +@verbatim + hab_ivt_t* ivt_initial = ; + const void* dcd_initial = ivt_initial->dcd; + if (ivt_initial->dcd != NULL) + dcd_initial = (const uint8_t*)ivt_initial + + (ivt_initial->dcd - ivt_initial->self) +@endverbatim + */ +struct hab_ivt { + /** @ref hdr with tag #HAB_TAG_IVT, length and HAB version fields + * (see @ref data) + */ + hab_hdr_t hdr; + /** Absolute address of the first instruction to execute from the + * image + */ + hab_image_entry_f entry; + /** Reserved in this version of HAB: should be NULL. */ + const void* reserved1; + /** Absolute address of the image DCD: may be NULL. */ + const void* dcd; + /** Absolute address of the Boot Data: may be NULL, but not interpreted + * any further by HAB + */ + const void* boot_data; + /** Absolute address of the IVT.*/ + const void* self; + /** Absolute address of the image CSF.*/ + const void* csf; + /** Reserved in this version of HAB: should be zero. */ + uint32_t reserved2; +}; + +/** @ref ivt type + * @ingroup ivt + */ +typedef struct hab_ivt hab_ivt_t; + +/*=========================================================================== + FUNCTION PROTOTYPES +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* HAB_DEFINES_H */ diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/sdk_types.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/sdk_types.h new file mode 100644 index 000000000..0b7bc4b76 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/include/sdk_types.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2008-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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 __SDK_TYPES_H__ +#define __SDK_TYPES_H__ + +//! @addtogroup sdk_common +//! @{ + +/*! + * @file sdk_types.h + * @brief Basic types used throughout the SDK. + */ + +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +//! @name Alternate Boolean constants +//@{ +#define TRUE 1 +#define FALSE 0 +//@} + +//! @brief +#define NONE_CHAR (0xFF) + +//! @brief A parameter was out of range or otherwise invalid. +#define INVALID_PARAMETER (-1) + +//! @name Min/max macros +//@{ +#if !defined(MIN) + #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#if !defined(MAX) + #define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +//@} + +//! @brief Computes the number of elements in an array. +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +//! @brief Debug print utility. +//! +//! This print function will only output text when the @a DEBUG macro is defined. +static inline void debug_printf(const char * format, ...) +{ +#if defined(DEBUG) + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +#endif +} + +//! @name Test results +typedef enum _test_return +{ + TEST_NOT_STARTED = -3, // present in the menu, but not run + TEST_NOT_IMPLEMENTED = -2, // present in the menu, but not functional + TEST_FAILED = -1, + TEST_PASSED = 0, + TEST_BYPASSED = 2, // user elected to exit the test before it was run + TEST_NOT_PRESENT = 3, // not present in the menu. + TEST_CONTINUE = 4 // proceed with the test. opposite of TEST_BYPASSED +} test_return_t; + +//! @name Return codes +//@{ +#define SUCCESS (0) +#define FAIL (1) +#define ERROR_GENERIC (-1) +#define ERROR_OUT_OF_MEMORY (-2) +//@} + +//! @brief Possible types of displays. +enum display_type { + DISP_DEV_NULL = 0, + DISP_DEV_TFTLCD, + DISP_DEV_LVDS, + DISP_DEV_VGA, + DISP_DEV_HDMI, + DISP_DEV_TV, + DISP_DEV_MIPI, +}; + +//! @} + +#endif // __SDK_TYPES_H__ +//////////////////////////////////////////////////////////////////////////////// +// EOF +//////////////////////////////////////////////////////////////////////////////// diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/ivt.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/ivt.c new file mode 100755 index 000000000..e49b865c9 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/ivt.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2010-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 HOLDER 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 + +extern unsigned * _start_image_add; +extern unsigned * __start_boot_data; +extern unsigned * _image_size; + +extern unsigned * __hab_data; + +extern uint8_t input_dcd_hdr[]; + +extern void _reset(void); + +struct hab_ivt input_ivt __attribute__ ((section (".ivt"))) ={ + /** @ref hdr word with tag #HAB_TAG_IVT, length and HAB version fields + * (see @ref data) + */ + IVT_HDR(sizeof(struct hab_ivt), HAB_VER(4, 0)), + /** Absolute address of the first instruction to execute from the + * image + */ + (hab_image_entry_f)_reset, + + /** Reserved in this version of HAB: should be NULL. */ + NULL, + /** Absolute address of the image DCD: may be NULL. */ + &input_dcd_hdr, + /** Absolute address of the Boot Data: may be NULL, but not interpreted + * any further by HAB + */ + &__start_boot_data, + /** Absolute address of the IVT.*/ + (const void*) (&input_ivt), + + /** Absolute address of the image CSF.*/ + (const void*) &__hab_data, + + /** Reserved in this version of HAB: should be zero. */ + 0 +}; + +typedef struct { + uint32_t start; /**< Start address of the image */ + uint32_t size; /**< Size of the image */ + uint32_t plugin; /**< Plugin flag */ +} boot_data_t; + +boot_data_t bd __attribute__ ((section (".boot_data"))) ={ + (uint32_t) &_start_image_add, + (uint32_t) &_image_size, + 0, +}; + diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/link.lds b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/link.lds new file mode 100644 index 000000000..67abbe98d --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/link.lds @@ -0,0 +1,170 @@ + + +STACK_SIZE = 48*1024; +L1_PAGE_TABLE_SIZE = 16K; +RAM_VECTORS_SIZE = 72; + +OUTPUT_FORMAT("elf32-littlearm") +OUTPUT_ARCH(arm) + +MEMORY +{ + OCRAM (rwx) : ORIGIN = 0x00900000, LENGTH = 256K + DDR (rwx) : ORIGIN = 0x10000000, LENGTH = 2048M +} + +SECTIONS +{ +/* + * -- OCRAM -- + * + * Nothing in OCRAM can be loaded at boot, because the boot image must be a contiguous + * region of memory. + */ + /* MMU L1 page table */ + .l1_page_table (NOLOAD) : + { + __l1_page_table_start = .; + . += L1_PAGE_TABLE_SIZE; + } > OCRAM + + /* allocate a heap in ocram */ + .heap.ocram (NOLOAD) : ALIGN(4) + { + __heap_ocram_start = .; + . += LENGTH(OCRAM) - L1_PAGE_TABLE_SIZE - RAM_VECTORS_SIZE ; + __heap_ocram_end = .; + } > OCRAM + + /* RAM vector table comes at the end of OCRAM */ + .ram_vectors (ORIGIN(OCRAM) + LENGTH(OCRAM) - RAM_VECTORS_SIZE) (NOLOAD) : + { + __ram_vectors_start = .; + . += RAM_VECTORS_SIZE; + __ram_vectors_end = .; + } > OCRAM + +/* + * -- DDR -- + */ + + /* -- read-only sections -- */ + + _start_image_add = ORIGIN(DDR); + + .ivt (ORIGIN(DDR)) : + { + . = . + 0x400; + *(.ivt) + } > DDR + + .boot_data : + { + __start_boot_data = .; + *(.boot_data) + } > DDR + + /* aligned to ease the hexdump read of generated binary */ + .dcd_hdr : ALIGN(16) + { + __start_dcd = .; + *(.dcd_hdr) + } > DDR + .dcd_wrt_cmd : + { + *(.dcd_wrt_cmd) + } > DDR + .dcd_data : + { + *(.dcd_data) + } > DDR + + __text_start = .; + .text : + { + *(.startup) + *(.text) + *(.text.*) + + /* section information for finsh shell */ + . = ALIGN(4); + __isrtbl_idx_start = .; + KEEP(*(.isrtbl.idx)) + __isrtbl_start = .; + KEEP(*(.isrtbl)) + __isrtbl_end = .; + . = ALIGN(4); + } > DDR + __text_end = .; + + __rodata_start = .; + .rodata : + { + *(.rodata) *(.rodata.*) + } > DDR + __rodata_end = .; + + . = ALIGN(4); + .ctors : + { + PROVIDE(__ctors_start__ = .); + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + } > DDR + + .dtors : + { + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } > DDR + + /* . = ALIGN(16 * 1024); + .l1_page_table : + { + __l1_page_table_start = .; + . += 16K; + } */ + + . = ALIGN(8); + __data_start = .; + .data : + { + *(.data) + *(.data.*) + } > DDR + __data_end = .; + + . = ALIGN(8); + __bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + } > DDR + . = ALIGN(4); + __bss_end = .; + + .stacks : + { + __stacks_start = .; + . += STACK_SIZE; + __stacks_end = .; + stack_top = .; + } > DDR + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + _end = .; +} diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/interrupt.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/third_party_driver/Kconfig old mode 100755 new mode 100644 similarity index 100% rename from Ubiquitous/XiZi_AIoT/hardkernel/abstraction/interrupt.c rename to Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/third_party_driver/Kconfig diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/third_party_driver/Makefile b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/third_party_driver/Makefile new file mode 100644 index 000000000..f11fc06ee --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/third_party_driver/Makefile @@ -0,0 +1,4 @@ + +SRC_DIR := + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/xsconfig.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/xsconfig.h new file mode 100644 index 000000000..656db7dbe --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/xsconfig.h @@ -0,0 +1,18 @@ +#ifndef XS_CONFIG_H__ +#define XS_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* XiZi_AIoT Project Configuration */ + +#define BOARD_IMX6Q_SABRELITE_EVB +#define ARCH_ARM + +/* imx6q sabrelite feature */ + +/* Lib */ + +#define LIB +#define LIB_POSIX +#define LIB_NEWLIB + +#endif diff --git a/Ubiquitous/XiZi_AIoT/services/lib/xxx.c b/Ubiquitous/XiZi_AIoT/services/drivers/Kconfig similarity index 100% rename from Ubiquitous/XiZi_AIoT/services/lib/xxx.c rename to Ubiquitous/XiZi_AIoT/services/drivers/Kconfig diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/Makefile b/Ubiquitous/XiZi_AIoT/services/drivers/Makefile new file mode 100644 index 000000000..f11fc06ee --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/drivers/Makefile @@ -0,0 +1,4 @@ + +SRC_DIR := + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/services/fs/Kconfig b/Ubiquitous/XiZi_AIoT/services/fs/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/Ubiquitous/XiZi_AIoT/services/lib/Kconfig b/Ubiquitous/XiZi_AIoT/services/lib/Kconfig new file mode 100644 index 000000000..0727350e2 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/Kconfig @@ -0,0 +1,23 @@ +menu "Lib" + +menuconfig LIB + bool "Enable libc APIs from toolchain" + default y + + if LIB + config LIB_POSIX + bool "Enable POSIX layer for poll/select, stdin etc" + default y + choice + prompt "select libc" + default LIB_NEWLIB + + config LIB_NEWLIB + bool "use newlib as libc realization." + + config LIB_MUSLLIB + bool "use musllib as libc realization." + endchoice + endif + +endmenu diff --git a/Ubiquitous/XiZi_AIoT/services/lib/Makefile b/Ubiquitous/XiZi_AIoT/services/lib/Makefile new file mode 100644 index 000000000..39648fd33 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/Makefile @@ -0,0 +1,14 @@ +SRC_DIR := +MUSL_DIR := + +ifeq ($(CONFIG_LIB_NEWLIB),y) +SRC_DIR += newlib +endif + +ifeq ($(CONFIG_LIB_MUSLLIB), y) +# SRC_DIR += musllib +# MUSL_DIR += musllib +endif + +include $(KERNEL_ROOT)/compiler.mk + diff --git a/Ubiquitous/XiZi_AIoT/services/lib/newlib/Kconfig b/Ubiquitous/XiZi_AIoT/services/lib/newlib/Kconfig new file mode 100644 index 000000000..c587e3962 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/newlib/Kconfig @@ -0,0 +1,6 @@ +menu LIB_NEWLIB + bool "Enable Newlib " + default y +endmenu + + diff --git a/Ubiquitous/XiZi_AIoT/services/lib/newlib/Makefile b/Ubiquitous/XiZi_AIoT/services/lib/newlib/Makefile new file mode 100644 index 000000000..04e094528 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/newlib/Makefile @@ -0,0 +1,5 @@ +SRC_FILES := fs_syscalls.c time_syscalls.c mem_syscalls.c task_syscalls.c + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/services/lib/newlib/fs_syscalls.c b/Ubiquitous/XiZi_AIoT/services/lib/newlib/fs_syscalls.c new file mode 100644 index 000000000..67bd6c368 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/newlib/fs_syscalls.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +/** +* @file fs_syscalls.c +* @brief support newlib file system +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2020-09-23 +*/ + +/************************************************* +File name: fs_syscalls.c +Description: support newlib file system +Others: take RT-Thread v4.0.2/components/libc/compilers/newlib/syscalls.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2020-09-23 +Author: AIIT XUOS Lab +Modification: Use file system functions +*************************************************/ + +#include +#include +#include +/* wwg debug here */ +// #include + +int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +int _link_r(struct _reent *ptr, const char *old, const char *new) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +void * _sbrk_r(struct _reent *ptr, ptrdiff_t incr) +{ + return NULL; +} + +int _wait_r(struct _reent *ptr, int *status) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +#ifdef FS_VFS + +#include + +int _close_r(struct _reent *ptr, int fd) +{ + return close(fd); +} + +int _isatty_r(struct _reent *ptr, int fd) +{ + if (fd >=0 && fd < 3) + return 1; + + ptr->_errno = ENOTSUP; + return -1; +} + +_off_t _lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence) +{ + return lseek(fd, pos, whence); +} + +int _open_r(struct _reent *ptr, const char *file, int flags, int mode) +{ + return open(file, flags, mode); +} + +_ssize_t _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes) +{ + return read(fd, buf, nbytes); +} + +int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat) +{ + return stat(file, pstat); +} + +int _unlink_r(struct _reent *ptr, const char *file) +{ + return unlink(file); +} + +_ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes) +{ + return write(fd, buf, nbytes); +} + +#else /* FS_VFS */ + +int _close_r(struct _reent *ptr, int fd) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +int _isatty_r(struct _reent *ptr, int fd) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +_off_t _lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +int _open_r(struct _reent *ptr, const char *file, int flags, int mode) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +_ssize_t _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +int _unlink_r(struct _reent *ptr, const char *file) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +_ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes) +{ + ptr->_errno = ENOTSUP; + return -1; +} + +#endif /* FS_VFS */ diff --git a/Ubiquitous/XiZi_AIoT/services/lib/newlib/include/libc.h b/Ubiquitous/XiZi_AIoT/services/lib/newlib/include/libc.h new file mode 100644 index 000000000..223bf0f64 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/newlib/include/libc.h @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file libc.h +* @brief using newlib need include +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2020-09-23 +*/ + +#ifndef _LIBC_H__ +#define _LIBC_H__ + +#include +#include +#include + +#endif + diff --git a/Ubiquitous/XiZi_AIoT/services/lib/newlib/mem_syscalls.c b/Ubiquitous/XiZi_AIoT/services/lib/newlib/mem_syscalls.c new file mode 100644 index 000000000..4a82eb6f0 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/newlib/mem_syscalls.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +/** +* @file mem_syscalls.c +* @brief support newlib memory +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2020-09-23 +*/ + +/************************************************* +File name: mem_syscalls.c +Description: support newlib memory +Others: take RT-Thread v4.0.2/components/libc/compilers/newlib/syscalls.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2020-09-23 +Author: AIIT XUOS Lab +Modification: Use malloc, realloc, calloc and free functions +*************************************************/ +/* wwg debug here */ +// #include +#include + +void *_malloc_r (struct _reent *ptr, size_t size) +{ + /* wwg debug here */ + // void* result = (void*)x_malloc(size); + void* result = NULL; + + if (result == NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void *_realloc_r (struct _reent *ptr, void *old, size_t newlen) +{ + /* wwg debug here */ + // void* result = (void*)x_realloc(old, newlen); + void* result = NULL; + + if (result == NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void *_calloc_r (struct _reent *ptr, size_t size, size_t len) +{ + /* wwg debug here */ + // void* result = (void*)x_calloc(size, len); + void* result = NULL; + + if (result == NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void _free_r (struct _reent *ptr, void *address) +{ + /* wwg debug here */ + // x_free (address); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/lib/newlib/stdio.c b/Ubiquitous/XiZi_AIoT/services/lib/newlib/stdio.c new file mode 100644 index 000000000..6ae393a96 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/newlib/stdio.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017/10/15 bernard the first version + */ + +/** +* @file stdio.c +* @brief support newlib stdio +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2020-09-23 +*/ + +/************************************************* +File name: stdio.c +Description: support newlib stdio +Others: take RT-Thread v4.0.2/components/libc/compilers/newlib/stdio.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2020-09-23 +Author: AIIT XUOS Lab +Modification: Use set and get console functions +*************************************************/ + +#include +#include +#include +#include + +#define STDIO_DEVICE_NAME_MAX 32 + +static FILE* std_console = NULL; + +/** + * This function will set system console device. + * + * @param device_name the name of device + * @param mode the mode + * + * @return file number on success; or -1 on failure + */ +int LibcStdioSetConsole(const char* device_name, int mode) +{ + FILE *fp; + char name[STDIO_DEVICE_NAME_MAX] = {0}; + char *file_mode; + + snprintf(name, strlen(device_name) + 6, "/dev/%s", device_name); + name[STDIO_DEVICE_NAME_MAX - 1] = '\0'; + + switch (mode) + { + case O_RDWR: + file_mode = "r+"; + break; + + case O_WRONLY: + file_mode = "wb"; + break; + + default: + file_mode = "rb"; + break; + } + + /* try to open file */ + fp = fopen(name, file_mode); + if (fp) + { + /* set the fp buffer */ + setvbuf(fp, NULL, _IONBF, 0); + + if (std_console) + /* try to close console device */ + fclose(std_console); + std_console = fp; + + if (mode == O_RDWR) + { + /* set _stdin as std_console */ + _GLOBAL_REENT->_stdin = std_console; + } + else + { + /* set NULL */ + _GLOBAL_REENT->_stdin = NULL; + } + + if (mode == O_RDONLY) + { + /* set the _stdout as NULL */ + _GLOBAL_REENT->_stdout = NULL; + /* set the _stderr as NULL */ + _GLOBAL_REENT->_stderr = NULL; + } + else + { + /* set the _stdout as std_console */ + _GLOBAL_REENT->_stdout = std_console; + /* set the _stderr as std_console */ + _GLOBAL_REENT->_stderr = std_console; + } + /* set the __sdidinit as 1 */ + _GLOBAL_REENT->__sdidinit = 1; + } + + if (std_console) + /* return the file number */ + return fileno(std_console); + /* failure and return -1 */ + return -1; +} + +/** + * This function will get system console device. + * + * @return file number on success; or -1 on failure + */ +int LibcStdioGetConsole(void) { + if (std_console) + /* return the file number */ + return fileno(std_console); + else + /* failure and return -1 */ + return -1; +} + +/** + * This function will initialize the c library system. + * + * @return 0 + */ +int LibcSystemInit(void) +{ +#if defined(KERNEL_CONSOLE) + HardwareDevType console; + /* try to get console device */ + console = ObtainConsole(); + if (console) + { +#if defined(LIB_POSIX) + /* set console device mode */ + LibcStdioSetConsole(console->dev_name, O_RDWR); +#else + /* set console device mode */ + LibcStdioSetConsole(console->dev_name, O_WRONLY); +#endif + } +#endif + return 0; +} diff --git a/Ubiquitous/XiZi_AIoT/services/lib/newlib/task_syscalls.c b/Ubiquitous/XiZi_AIoT/services/lib/newlib/task_syscalls.c new file mode 100644 index 000000000..14011491e --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/newlib/task_syscalls.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +/** +* @file task_syscalls.c +* @brief support newlib abort +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2020-09-23 +*/ + +/************************************************* +File name: task_syscalls.c +Description: support newlib abort +Others: take RT-Thread v4.0.2/components/libc/compilers/newlib/syscalls.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2020-09-23 +Author: AIIT XUOS Lab +Modification: Use abort function +*************************************************/ +/* wwg debug here */ +// #include + +void abort(void) +{ + // KTaskDescriptorType current = GetKTaskDescriptor(); + // if (current) + // { + // KPrintf("Task:%-8.*s will be aborted!\n", NAME_NUM_MAX, current->task_base_info.name); + // /* pend current task */ + // SuspendKTask(current->id.id); + // /* schedule */ + // DO_KTASK_ASSIGN; + // } + + while (1); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/lib/newlib/time_syscalls.c b/Ubiquitous/XiZi_AIoT/services/lib/newlib/time_syscalls.c new file mode 100644 index 000000000..2696d108b --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/newlib/time_syscalls.c @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +#include +// #include +// #include + +// time_t time(time_t *t) +// { +// NULL_PARAM_CHECK(t); +// time_t current = 0; + +// #ifdef RESOURCES_RTC +// struct RtcSetParam rtc_set_param; +// rtc_set_param.rtc_set_cmd = OPER_RTC_GET_TIME; +// rtc_set_param.time = ¤t; + +// RtcDrvSetFunction(RTC_DRV_NAME, &rtc_set_param); +// #endif + +// *t = current; + +// return current; +// } + +time_t time(time_t *t) +{ + time_t current = 0; + + *t = current; + + return current; +} diff --git a/Ubiquitous/XiZi_AIoT/services/tools/hosttools/xsconfig.sh b/Ubiquitous/XiZi_AIoT/services/tools/hosttools/xsconfig.sh new file mode 100755 index 000000000..b51a159aa --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/tools/hosttools/xsconfig.sh @@ -0,0 +1,91 @@ +#!/bin/bash +# Tring to create rtcnofig.h from .config +HEADER_STR=XS_CONFIG_H__ + + +function is_pkg_special_config() +{ + echo -ne $1 | egrep '^PKG_|_PATH$|_VER$' >/dev/null 2>/dev/null +} + +function is_config() +{ + echo -ne $1 | egrep '^XS_' >/dev/null 2>/dev/null +} + +function make_config_h() +{ + local CONFIG_NAME=${1} + + # destination file using file descriptor 8 + exec 8>${2} + + echo -ne "#ifndef ${HEADER_STR}\n" >&8 + echo -ne "#define ${HEADER_STR}\n\n" >&8 + + EMPTY_LINE='true' + + while read LN + do + LINE=`echo $LN | sed 's/[ \t\r\n]*$//g'` + + if [ -z "$LINE" ]; then + continue + fi + + if [ '#' = ${LINE:0:1} ]; then + if [ ${#LINE} -eq 1 ]; then + if $EMPTY_LINE; then + continue + fi + echo >&8 + EMPTY_LINE='true' + continue + fi + + if echo -ne "$LINE" | egrep '^# CONFIG_' >/dev/null 2>/dev/null; then + LINE=`printf ' %s' ${LINE:9}` + else + LINE=${LINE:1} + echo -ne "/* ${LINE} */\n" >&8 + fi + + EMPTY_LINE='false' + else + EMPTY_LINE='false' + + OLD_IFS="$IFS" + IFS='=' + SETTINGS=($LINE) + IFS="$OLD_IFS" + + if [ ${#SETTINGS[@]} -ge 2 ]; then + if echo -ne "$SETTINGS[0]" | egrep '^CONFIG_' >/dev/null 2>/dev/null; then + SETTINGS[0]="${SETTINGS[0]:7}" + fi + + if is_pkg_special_config "${SETTINGS[0]}"; then + continue + fi + +# echo "DBG---: ${SETTINGS[@]}, ${SETTINGS[*]}" + if [ "${SETTINGS[1]}" = 'y' ]; then + echo -ne "#define ${SETTINGS[0]}\n" >&8 + else + echo -ne "#define ${SETTINGS[0]} ${LINE#*=}\n" >&8 + fi + fi + fi + + done < $CONFIG_NAME + + if [ -f xsconfig_project.h ]; then + echo -ne "#include \"xsconfig_project.h\"\n" >&8 + fi + + echo -ne "\n#endif\n" >&8 + exec 8<&- +} + +make_config_h $1 $BSP_ROOT/xsconfig.h + diff --git a/Ubiquitous/XiZi_AIoT/softkernel/Kconfig b/Ubiquitous/XiZi_AIoT/softkernel/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/Ubiquitous/XiZi_AIoT/softkernel/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/Makefile new file mode 100644 index 000000000..77a92fa1d --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/Makefile @@ -0,0 +1,4 @@ + +SRC_DIR := task + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile new file mode 100644 index 000000000..4ca20e597 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := task.c schedule.c ipc.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/support/Kconfig b/Ubiquitous/XiZi_AIoT/support/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/Ubiquitous/XiZi_AIoT/support/Makefile b/Ubiquitous/XiZi_AIoT/support/Makefile new file mode 100644 index 000000000..f11fc06ee --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/support/Makefile @@ -0,0 +1,4 @@ + +SRC_DIR := + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/testing/Kconfig b/Ubiquitous/XiZi_AIoT/testing/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/Ubiquitous/XiZi_AIoT/testing/Makefile b/Ubiquitous/XiZi_AIoT/testing/Makefile new file mode 100644 index 000000000..f11fc06ee --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/testing/Makefile @@ -0,0 +1,4 @@ + +SRC_DIR := + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/link.lds b/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/link.lds index 5b0d78cbb..ce211a026 100644 --- a/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/link.lds +++ b/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/link.lds @@ -79,7 +79,7 @@ MEMORY sram_oc_ecc2 (rwx) : ORIGIN = 0x20350000, LENGTH = 0x10000 /* 64K bytes (alias RAM7) */ /* define extern sdram 32MB*/ - board_sdram (rwx) : ORIGIN = 0x80000000, LENGTH = 0x2000000 /* 64M bytes (alias RAM8) */ + board_sdram (rwx) : ORIGIN = 0x80000000, LENGTH = 0x2000000 /* 32M bytes (alias RAM8) */ }