Merge pull request #1169 from antonio-nino-diaz-arm/an/spm-fixes
SPM fixes
diff --git a/Makefile b/Makefile
index 9ab37ac..d186e8b 100644
--- a/Makefile
+++ b/Makefile
@@ -126,20 +126,28 @@
NM := ${CROSS_COMPILE}nm
PP := ${CROSS_COMPILE}gcc -E
+ifeq (${ARM_ARCH_MAJOR},7)
+target32-directive = -target arm-none-eabi
+# Will set march32-directive from platform configuration
+else
+target32-directive = -target armv8a-none-eabi
+march32-directive = -march armv8-a
+endif
+
ifeq ($(notdir $(CC)),armclang)
-TF_CFLAGS_aarch32 = -target arm-arm-none-eabi -march=armv8-a
+TF_CFLAGS_aarch32 = -target arm-arm-none-eabi $(march32-directive)
TF_CFLAGS_aarch64 = -target aarch64-arm-none-eabi -march=armv8-a
else ifneq ($(findstring clang,$(notdir $(CC))),)
-TF_CFLAGS_aarch32 = -target armv8a-none-eabi
+TF_CFLAGS_aarch32 = $(target32-directive)
TF_CFLAGS_aarch64 = -target aarch64-elf
else
-TF_CFLAGS_aarch32 = -march=armv8-a
+TF_CFLAGS_aarch32 = $(march32-directive)
TF_CFLAGS_aarch64 = -march=armv8-a
endif
TF_CFLAGS_aarch64 += -mgeneral-regs-only -mstrict-align
-ASFLAGS_aarch32 = -march=armv8-a
+ASFLAGS_aarch32 = $(march32-directive)
ASFLAGS_aarch64 = -march=armv8-a
CPPFLAGS = ${DEFINES} ${INCLUDES} -nostdinc \
@@ -189,6 +197,7 @@
-Iinclude/lib/cpus/${ARCH} \
-Iinclude/lib/el3_runtime \
-Iinclude/lib/el3_runtime/${ARCH} \
+ -Iinclude/lib/extensions \
-Iinclude/lib/pmf \
-Iinclude/lib/psci \
-Iinclude/lib/xlat_tables \
@@ -262,6 +271,10 @@
$(eval $(call MAKE_PREREQ_DIR,${BUILD_PLAT}))
+ifeq (${ARM_ARCH_MAJOR},7)
+include make_helpers/armv7-a-cpus.mk
+endif
+
# Platform compatibility is not supported in AArch32
ifneq (${ARCH},aarch32)
# If the platform has not defined ENABLE_PLAT_COMPAT, then enable it by default
diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S
index 34e4dcd..cf32b31 100644
--- a/bl31/aarch64/crash_reporting.S
+++ b/bl31/aarch64/crash_reporting.S
@@ -46,8 +46,7 @@
"tpidrro_el0", "dacr32_el2", "ifsr32_el2", "par_el1",\
"mpidr_el1", "afsr0_el1", "afsr1_el1", "contextidr_el1",\
"vbar_el1", "cntp_ctl_el0", "cntp_cval_el0", "cntv_ctl_el0",\
- "cntv_cval_el0", "cntkctl_el1", "fpexc32_el2", "sp_el0",\
- "isr_el1", ""
+ "cntv_cval_el0", "cntkctl_el1", "sp_el0", "isr_el1", ""
panic_msg:
.asciz "PANIC in EL3 at x30 = 0x"
@@ -313,9 +312,8 @@
mrs x15, cntv_cval_el0
bl str_in_crash_buf_print
mrs x8, cntkctl_el1
- mrs x9, fpexc32_el2
- mrs x10, sp_el0
- mrs x11, isr_el1
+ mrs x9, sp_el0
+ mrs x10, isr_el1
bl str_in_crash_buf_print
/* Get the cpu specific registers to report */
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 336c295..fccdc8a 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -46,6 +46,10 @@
services/std_svc/sdei/sdei_state.c
endif
+ifeq (${ENABLE_SPE_FOR_LOWER_ELS},1)
+BL31_SOURCES += lib/extensions/spe/spe.c
+endif
+
BL31_LINKERFILE := bl31/bl31.ld.S
# Flag used to indicate if Crash reporting via console should be included
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index cd9fe5c..b2b7953 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -30,6 +30,16 @@
stcopr \reg, SCR
.endm
+ .macro clrex_on_monitor_entry
+#if (ARM_ARCH_MAJOR == 7)
+ /*
+ * ARMv7 architectures need to clear the exclusive access when
+ * entering Monitor mode.
+ */
+ clrex
+#endif
+ .endm
+
vector_base sp_min_vector_table
b sp_min_entrypoint
b plat_panic_handler /* Undef */
@@ -147,6 +157,8 @@
smcc_save_gp_mode_regs
+ clrex_on_monitor_entry
+
/*
* `sp` still points to `smc_ctx_t`. Save it to a register
* and restore the C runtime stack pointer to `sp`.
@@ -203,11 +215,7 @@
smcc_save_gp_mode_regs
- /*
- * AArch32 architectures need to clear the exclusive access when
- * entering Monitor mode.
- */
- clrex
+ clrex_on_monitor_entry
/* load run-time stack */
mov r2, sp
diff --git a/common/aarch32/debug.S b/common/aarch32/debug.S
index 583ee4a..f506356 100644
--- a/common/aarch32/debug.S
+++ b/common/aarch32/debug.S
@@ -71,7 +71,15 @@
assert_msg1:
.asciz "ASSERT: File "
assert_msg2:
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+ /******************************************************************
+ * Virtualization comes with the UDIV/SDIV instructions. If missing
+ * write file line number in hexadecimal format.
+ ******************************************************************/
+ .asciz " Line 0x"
+#else
.asciz " Line "
+#endif
/* ---------------------------------------------------------------------------
* Assertion support in assembly.
@@ -113,6 +121,13 @@
bne 1f
mov r4, r6
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+ /******************************************************************
+ * Virtualization comes with the UDIV/SDIV instructions. If missing
+ * write file line number in hexadecimal format.
+ ******************************************************************/
+ bl asm_print_hex
+#else
/* Print line number in decimal */
mov r6, #10 /* Divide by 10 after every loop iteration */
ldr r5, =MAX_DEC_DIVISOR
@@ -124,6 +139,7 @@
udiv r5, r5, r6 /* Reduce divisor */
cmp r5, #0
bne dec_print_loop
+#endif
bl plat_crash_console_flush
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index 7cc1970..405964d 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -1144,7 +1144,6 @@
cntv_ctl_el0 :0x0000000000000000
cntv_cval_el0 :0x0000000000000000
cntkctl_el1 :0x0000000000000000
- fpexc32_el2 :0x0000000004000700
sp_el0 :0x0000000004010780
Guidelines for Reset Handlers
@@ -2520,6 +2519,35 @@
table entries for a given stage of translation for a particular translation
regime.
+ARMv7
+~~~~~
+
+This Architecture Extension is targeted when ``ARM_ARCH_MAJOR`` == 7.
+
+There are several ARMv7 extensions available. Obviously the TrustZone
+extension is mandatory to support the ARM Trusted Firmware bootloader
+and runtime services.
+
+Platform implementing an ARMv7 system can to define from its target
+Cortex-A architecture through ``ARM_CORTEX_A<X> = yes`` in their
+``plaform.mk`` script. For example ``ARM_CORTEX_A15=yes`` for a
+Cortex-A15 target.
+
+Platform can also set ``ARM_WITH_NEON=yes`` to enable neon support.
+Note that using neon at runtime has constraints on non secure wolrd context.
+The trusted firmware does not yet provide VFP context management.
+
+Directive ``ARM_CORTEX_A<x>`` and ``ARM_WITH_NEON`` are used to set
+the toolchain target architecture directive.
+
+Platform may choose to not define straight the toolchain target architecture
+directive by defining ``MARCH32_DIRECTIVE``.
+I.e:
+
+::
+
+ MARCH32_DIRECTIVE := -mach=armv7-a
+
Code Structure
--------------
diff --git a/docs/plantuml/sdei_explicit_dispatch.puml b/docs/plantuml/sdei_explicit_dispatch.puml
index 51214f5..c80fcd1 100644
--- a/docs/plantuml/sdei_explicit_dispatch.puml
+++ b/docs/plantuml/sdei_explicit_dispatch.puml
@@ -9,7 +9,7 @@
autonumber "<b>[#]</b>"
participant "SDEI client" as EL2
participant EL3
-participant SEL1
+participant "Secure Partition" as SP
activate EL2
EL2->EL3: **SDEI_EVENT_REGISTER**(ev, handler, ...)
@@ -24,11 +24,11 @@
EL3<--]: **CRITICAL EVENT**
activate EL3 #red
note over EL3: Critical event triage
-EL3->SEL1: dispatch
-activate SEL1 #salmon
-note over SEL1: Critical event handling
-SEL1->EL3: done
-deactivate SEL1
+EL3->SP: dispatch
+activate SP #salmon
+note over SP: Critical event handling
+SP->EL3: done
+deactivate SP
EL3-->EL3: sdei_dispatch_event(ev)
note over EL3: Prepare SDEI dispatch
EL3->EL2: dispatch
diff --git a/docs/plantuml/sdei_explicit_dispatch.svg b/docs/plantuml/sdei_explicit_dispatch.svg
index b33944e..182df0a 100644
--- a/docs/plantuml/sdei_explicit_dispatch.svg
+++ b/docs/plantuml/sdei_explicit_dispatch.svg
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="767px" preserveAspectRatio="none" style="width:692px;height:767px;" version="1.1" viewBox="0 0 692 767" width="692px" zoomAndPan="magnify"><defs><filter height="300%" id="f13jg8eb0anesb" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="174.7969" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="66.5" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="412.5938" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="263.8984" y2="676.4922"/><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="1" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="717.2969" y2="718.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="717.2969" y2="718.2969"/><rect fill="#FA8072" filter="url(#f13jg8eb0anesb)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="61.5" y="531.8281"/><rect fill="#FF0000" filter="url(#f13jg8eb0anesb)" height="383.4609" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="375.5" y="284.8984"/><rect fill="#FA8072" filter="url(#f13jg8eb0anesb)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="588.5" y="353.1641"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="61" x2="61" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="61" x2="61" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="717.2969" y2="727.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="380" x2="380" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="380" x2="380" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="717.2969" y2="727.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593.5" x2="593.5" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="593.5" x2="593.5" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593.5" x2="593.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="593.5" x2="593.5" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593.5" x2="593.5" y1="717.2969" y2="727.2969"/><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="87" x="16" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="23" y="22.9951">SDEI client</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="87" x="16" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="23" y="746.292">SDEI client</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="39" x="359" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="25" x="366" y="22.9951">EL3</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="39" x="359" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="25" x="366" y="746.292">EL3</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="48" x="567.5" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="34" x="574.5" y="22.9951">SEL1</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="48" x="567.5" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="34" x="574.5" y="746.292">SEL1</text><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="174.7969" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="66.5" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="412.5938" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="263.8984" y2="676.4922"/><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="1" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="717.2969" y2="718.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="717.2969" y2="718.2969"/><rect fill="#FA8072" filter="url(#f13jg8eb0anesb)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="61.5" y="531.8281"/><rect fill="#FF0000" filter="url(#f13jg8eb0anesb)" height="383.4609" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="375.5" y="284.8984"/><rect fill="#FA8072" filter="url(#f13jg8eb0anesb)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="588.5" y="353.1641"/><polygon fill="#A80036" points="368.5,65.2969,378.5,69.2969,368.5,73.2969,372.5,69.2969" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="69.2969" y2="69.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="64.3638">[1]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="164" x="98.5" y="64.3638">SDEI_EVENT_REGISTER</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="101" x="262.5" y="64.3638">(ev, handler, ...)</text><polygon fill="#A80036" points="77.5,94.4297,67.5,98.4297,77.5,102.4297,73.5,98.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="98.4297" y2="98.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="93.4966">[2]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="51" x="108.5" y="93.4966">success</text><polygon fill="#A80036" points="368.5,123.5625,378.5,127.5625,368.5,131.5625,372.5,127.5625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="127.5625" y2="127.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="122.6294">[3]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="151" x="98.5" y="122.6294">SDEI_EVENT_ENABLE</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="25" x="249.5" y="122.6294">(ev)</text><polygon fill="#A80036" points="77.5,152.6953,67.5,156.6953,77.5,160.6953,73.5,156.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="156.6953" y2="156.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="151.7622">[4]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="51" x="108.5" y="151.7622">success</text><polygon fill="#A80036" points="368.5,181.8281,378.5,185.8281,368.5,189.8281,372.5,185.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="185.8281" y2="185.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="180.895">[5]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="129" x="98.5" y="180.895">SDEI_PE_UNMASK</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="10" x="227.5" y="180.895">()</text><polygon fill="#A80036" points="77.5,210.9609,67.5,214.9609,77.5,218.9609,73.5,214.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="214.9609" y2="214.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="210.0278">[6]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="8" x="108.5" y="210.0278">1</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="142" x="256.5" y="247.3042"><<Business as usual>></text><polygon fill="#A80036" points="396.5,280.8984,386.5,284.8984,396.5,288.8984,392.5,284.8984" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="390.5" x2="680" y1="284.8984" y2="284.8984"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="402.5" y="279.9653">[7]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="116" x="427.5" y="279.9653">CRITICAL EVENT</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="306,298.0313,306,323.0313,451,323.0313,451,308.0313,441,298.0313,306,298.0313" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="441" x2="441" y1="298.0313" y2="308.0313"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="451" x2="441" y1="308.0313" y2="308.0313"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="124" x="312" y="315.0981">Critical event triage</text><polygon fill="#A80036" points="576.5,349.1641,586.5,353.1641,576.5,357.1641,580.5,353.1641" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="385.5" x2="582.5" y1="353.1641" y2="353.1641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="392.5" y="348.231">[8]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="417.5" y="348.231">dispatch</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="510,366.2969,510,391.2969,672,391.2969,672,376.2969,662,366.2969,510,366.2969" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="662" x2="662" y1="366.2969" y2="376.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="672" x2="662" y1="376.2969" y2="376.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="516" y="383.3638">Critical event handling</text><polygon fill="#A80036" points="396.5,417.4297,386.5,421.4297,396.5,425.4297,392.5,421.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="390.5" x2="592.5" y1="421.4297" y2="421.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="402.5" y="416.4966">[9]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="32" x="427.5" y="416.4966">done</text><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="385.5" x2="427.5" y1="450.6953" y2="450.6953"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="427.5" x2="427.5" y1="450.6953" y2="463.6953"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="386.5" x2="427.5" y1="463.6953" y2="463.6953"/><polygon fill="#A80036" points="396.5,459.6953,386.5,463.6953,396.5,467.6953,392.5,463.6953" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="392.5" y="445.6294">[10]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="155" x="426.5" y="445.6294">sdei_dispatch_event(ev)</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="297,476.6953,297,501.6953,460,501.6953,460,486.6953,450,476.6953,297,476.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="450" x2="450" y1="476.6953" y2="486.6953"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="460" x2="450" y1="486.6953" y2="486.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="142" x="303" y="493.7622">Prepare SDEI dispatch</text><polygon fill="#A80036" points="82.5,527.8281,72.5,531.8281,82.5,535.8281,78.5,531.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="76.5" x2="374.5" y1="531.8281" y2="531.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="88.5" y="526.895">[11]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="122.5" y="526.895">dispatch</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="8,544.9609,8,569.9609,111,569.9609,111,554.9609,101,544.9609,8,544.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="101" x2="101" y1="544.9609" y2="554.9609"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="111" x2="101" y1="554.9609" y2="554.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="82" x="14" y="562.0278">SDEI handler</text><polygon fill="#A80036" points="363.5,596.0938,373.5,600.0938,363.5,604.0938,367.5,600.0938" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="369.5" y1="600.0938" y2="600.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="73.5" y="595.1606">[12]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="184" x="107.5" y="595.1606">SDEI_EVENT_COMPLETE()</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="291,613.2266,291,638.2266,466,638.2266,466,623.2266,456,613.2266,291,613.2266" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="456" x2="456" y1="613.2266" y2="623.2266"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="466" x2="456" y1="623.2266" y2="623.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="154" x="297" y="630.2935">Complete SDEI dispatch</text><polygon fill="#A80036" points="77.5,664.3594,67.5,668.3594,77.5,672.3594,73.5,668.3594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="668.3594" y2="668.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="83.5" y="663.4263">[13]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="197" x="117.5" y="663.4263">resumes preempted execution</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="190" x="232.5" y="700.7026"><<Normal execution resumes>></text></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="767px" preserveAspectRatio="none" style="width:692px;height:767px;" version="1.1" viewBox="0 0 692 767" width="692px" zoomAndPan="magnify"><defs><filter height="300%" id="fueepysa066oi" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="174.7969" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="66.5" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="412.5938" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="263.8984" y2="676.4922"/><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="1" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="717.2969" y2="718.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="717.2969" y2="718.2969"/><rect fill="#FA8072" filter="url(#fueepysa066oi)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="61.5" y="531.8281"/><rect fill="#FF0000" filter="url(#fueepysa066oi)" height="383.4609" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="375.5" y="284.8984"/><rect fill="#FA8072" filter="url(#fueepysa066oi)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="588.5" y="353.1641"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="61" x2="61" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="61" x2="61" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="717.2969" y2="727.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="380" x2="380" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="380" x2="380" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="717.2969" y2="727.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593" x2="593" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="593" x2="593" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593" x2="593" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="593" x2="593" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593" x2="593" y1="717.2969" y2="727.2969"/><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="87" x="16" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="23" y="22.9951">SDEI client</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="87" x="16" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="23" y="746.292">SDEI client</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="39" x="359" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="25" x="366" y="22.9951">EL3</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="39" x="359" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="25" x="366" y="746.292">EL3</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="123" x="530" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="109" x="537" y="22.9951">Secure Partition</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="123" x="530" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="109" x="537" y="746.292">Secure Partition</text><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="174.7969" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="66.5" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="412.5938" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="263.8984" y2="676.4922"/><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="1" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="717.2969" y2="718.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="717.2969" y2="718.2969"/><rect fill="#FA8072" filter="url(#fueepysa066oi)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="61.5" y="531.8281"/><rect fill="#FF0000" filter="url(#fueepysa066oi)" height="383.4609" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="375.5" y="284.8984"/><rect fill="#FA8072" filter="url(#fueepysa066oi)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="588.5" y="353.1641"/><polygon fill="#A80036" points="368.5,65.2969,378.5,69.2969,368.5,73.2969,372.5,69.2969" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="69.2969" y2="69.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="64.3638">[1]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="164" x="98.5" y="64.3638">SDEI_EVENT_REGISTER</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="101" x="262.5" y="64.3638">(ev, handler, ...)</text><polygon fill="#A80036" points="77.5,94.4297,67.5,98.4297,77.5,102.4297,73.5,98.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="98.4297" y2="98.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="93.4966">[2]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="51" x="108.5" y="93.4966">success</text><polygon fill="#A80036" points="368.5,123.5625,378.5,127.5625,368.5,131.5625,372.5,127.5625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="127.5625" y2="127.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="122.6294">[3]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="151" x="98.5" y="122.6294">SDEI_EVENT_ENABLE</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="25" x="249.5" y="122.6294">(ev)</text><polygon fill="#A80036" points="77.5,152.6953,67.5,156.6953,77.5,160.6953,73.5,156.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="156.6953" y2="156.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="151.7622">[4]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="51" x="108.5" y="151.7622">success</text><polygon fill="#A80036" points="368.5,181.8281,378.5,185.8281,368.5,189.8281,372.5,185.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="185.8281" y2="185.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="180.895">[5]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="129" x="98.5" y="180.895">SDEI_PE_UNMASK</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="10" x="227.5" y="180.895">()</text><polygon fill="#A80036" points="77.5,210.9609,67.5,214.9609,77.5,218.9609,73.5,214.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="214.9609" y2="214.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="210.0278">[6]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="8" x="108.5" y="210.0278">1</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="142" x="256.5" y="247.3042"><<Business as usual>></text><polygon fill="#A80036" points="396.5,280.8984,386.5,284.8984,396.5,288.8984,392.5,284.8984" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="390.5" x2="680" y1="284.8984" y2="284.8984"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="402.5" y="279.9653">[7]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="116" x="427.5" y="279.9653">CRITICAL EVENT</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="306,298.0313,306,323.0313,451,323.0313,451,308.0313,441,298.0313,306,298.0313" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="441" x2="441" y1="298.0313" y2="308.0313"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="451" x2="441" y1="308.0313" y2="308.0313"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="124" x="312" y="315.0981">Critical event triage</text><polygon fill="#A80036" points="576.5,349.1641,586.5,353.1641,576.5,357.1641,580.5,353.1641" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="385.5" x2="582.5" y1="353.1641" y2="353.1641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="392.5" y="348.231">[8]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="417.5" y="348.231">dispatch</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="510,366.2969,510,391.2969,672,391.2969,672,376.2969,662,366.2969,510,366.2969" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="662" x2="662" y1="366.2969" y2="376.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="672" x2="662" y1="376.2969" y2="376.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="516" y="383.3638">Critical event handling</text><polygon fill="#A80036" points="396.5,417.4297,386.5,421.4297,396.5,425.4297,392.5,421.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="390.5" x2="592.5" y1="421.4297" y2="421.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="402.5" y="416.4966">[9]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="32" x="427.5" y="416.4966">done</text><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="385.5" x2="427.5" y1="450.6953" y2="450.6953"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="427.5" x2="427.5" y1="450.6953" y2="463.6953"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="386.5" x2="427.5" y1="463.6953" y2="463.6953"/><polygon fill="#A80036" points="396.5,459.6953,386.5,463.6953,396.5,467.6953,392.5,463.6953" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="392.5" y="445.6294">[10]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="155" x="426.5" y="445.6294">sdei_dispatch_event(ev)</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="297,476.6953,297,501.6953,460,501.6953,460,486.6953,450,476.6953,297,476.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="450" x2="450" y1="476.6953" y2="486.6953"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="460" x2="450" y1="486.6953" y2="486.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="142" x="303" y="493.7622">Prepare SDEI dispatch</text><polygon fill="#A80036" points="82.5,527.8281,72.5,531.8281,82.5,535.8281,78.5,531.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="76.5" x2="374.5" y1="531.8281" y2="531.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="88.5" y="526.895">[11]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="122.5" y="526.895">dispatch</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="8,544.9609,8,569.9609,111,569.9609,111,554.9609,101,544.9609,8,544.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="101" x2="101" y1="544.9609" y2="554.9609"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="111" x2="101" y1="554.9609" y2="554.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="82" x="14" y="562.0278">SDEI handler</text><polygon fill="#A80036" points="363.5,596.0938,373.5,600.0938,363.5,604.0938,367.5,600.0938" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="369.5" y1="600.0938" y2="600.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="73.5" y="595.1606">[12]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="184" x="107.5" y="595.1606">SDEI_EVENT_COMPLETE()</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="291,613.2266,291,638.2266,466,638.2266,466,623.2266,456,613.2266,291,613.2266" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="456" x2="456" y1="613.2266" y2="623.2266"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="466" x2="456" y1="623.2266" y2="623.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="154" x="297" y="630.2935">Complete SDEI dispatch</text><polygon fill="#A80036" points="77.5,664.3594,67.5,668.3594,77.5,672.3594,73.5,668.3594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="668.3594" y2="668.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="83.5" y="663.4263">[13]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="197" x="117.5" y="663.4263">resumes preempted execution</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="190" x="232.5" y="700.7026"><<Normal execution resumes>></text></g></svg>
\ No newline at end of file
diff --git a/docs/sdei.rst b/docs/sdei.rst
index 0731a5a..a67b724 100644
--- a/docs/sdei.rst
+++ b/docs/sdei.rst
@@ -232,13 +232,20 @@
At a later point in time, a critical event [#critical-event]_ is trapped into
EL3 [7]. EL3 performs a first-level triage of the event, and decides to dispatch
-to Secure EL1 for further handling [8]. The dispatch completes, but intends to
-involve Non-secure world in further handling, and therefore decides to
-explicitly dispatch an event [10] (which the client had already registered for
-[1]). The rest of the sequence is similar to that in the `general SDEI
-dispatch`_: the requested event is dispatched to the client (assuming all the
-conditions are met), and when the handler completes, the preempted execution
-resumes.
+to a Secure Partition [#secpart]_ for further handling [8]. The dispatch
+completes, but intends to involve Non-secure world in further handling, and
+therefore decides to explicitly dispatch an event [10] (which the client had
+already registered for [1]). The rest of the sequence is similar to that in the
+`general SDEI dispatch`_: the requested event is dispatched to the client
+(assuming all the conditions are met), and when the handler completes, the
+preempted execution resumes.
+
+.. [#critical-event] Examples of critical event are *SError*, *Synchronous
+ External Abort*, *Fault Handling interrupt*, or *Error
+ Recovery interrupt* from one of RAS nodes in the system.
+
+.. [#secpart] Dispatching to Secure Partition involves *Secure Partition
+ Manager*, which isn't depicted in the sequence.
Conditions for event dispatch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -295,10 +302,6 @@
context is resumed (as indicated by the ``preempted_sec_state`` parameter of
the API).
-.. [#critical-event] Examples of critical event are *SError*, *Synchronous
- External Abort*, *Fault Handling interrupt*, or *Error
- Recovery interrupt* from one of RAS nodes in the system.
-
Porting requirements
--------------------
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 172e793..95fa22e 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -219,7 +219,8 @@
- ``ARM_ARCH_MAJOR``: The major version of ARM Architecture to target when
compiling ARM Trusted Firmware. Its value must be numeric, and defaults to
- 8 . See also, *ARMv8 Architecture Extensions* in `Firmware Design`_.
+ 8 . See also, *ARMv8 Architecture Extensions* and
+ *ARMv7 Architecture Extensions* in `Firmware Design`_.
- ``ARM_ARCH_MINOR``: The minor version of ARM Architecture to target when
compiling ARM Trusted Firmware. Its value must be a numeric, and defaults
@@ -344,9 +345,9 @@
the ``ENABLE_PMF`` build option as well. Default is 0.
- ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
- extensions. This is an optional architectural feature available only for
- AArch64 8.2 onwards. This option defaults to 1 but is automatically
- disabled when the target architecture is AArch32 or AArch64 8.0/8.1.
+ extensions. This is an optional architectural feature for AArch64.
+ The default is 1 but is automatically disabled when the target architecture
+ is AArch32.
- ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
checks in GCC. Allowed values are "all", "strong" and "0" (default).
@@ -425,11 +426,15 @@
- ``KEY_ALG``: This build flag enables the user to select the algorithm to be
used for generating the PKCS keys and subsequent signing of the certificate.
- It accepts 3 values viz ``rsa``, ``rsa_1_5``, ``ecdsa``. The ``rsa_1_5`` is
+ It accepts 3 values viz. ``rsa``, ``rsa_1_5``, ``ecdsa``. The ``rsa_1_5`` is
the legacy PKCS#1 RSA 1.5 algorithm which is not TBBR compliant and is
retained only for compatibility. The default value of this flag is ``rsa``
which is the TBBR compliant PKCS#1 RSA 2.1 scheme.
+- ``HASH_ALG``: This build flag enables the user to select the secure hash
+ algorithm. It accepts 3 values viz. ``sha256``, ``sha384``, ``sha512``.
+ The default value of this flag is ``sha256``.
+
- ``LDFLAGS``: Extra user options appended to the linkers' command line in
addition to the one set by the build system.
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c
index 72f15cd..8798659 100644
--- a/drivers/arm/gic/v2/gicv2_main.c
+++ b/drivers/arm/gic/v2/gicv2_main.c
@@ -176,7 +176,19 @@
gic_version = gicd_read_pidr2(plat_driver_data->gicd_base);
gic_version = (gic_version >> PIDR2_ARCH_REV_SHIFT)
& PIDR2_ARCH_REV_MASK;
- assert(gic_version == ARCH_REV_GICV2);
+
+ /*
+ * GICv1 with security extension complies with trusted firmware
+ * GICv2 driver as far as virtualization and few tricky power
+ * features are not used. GICv2 features that are not supported
+ * by GICv1 with Security Extensions are:
+ * - virtual interrupt support.
+ * - wake up events.
+ * - writeable GIC state register (for power sequences)
+ * - interrupt priority drop.
+ * - interrupt signal bypass.
+ */
+ assert(gic_version == ARCH_REV_GICV2 || gic_version == ARCH_REV_GICV1);
driver_data = plat_driver_data;
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index d8810d6..bc9ed3a 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,7 @@
#include <crypto_mod.h>
#include <debug.h>
#include <mbedtls_common.h>
+#include <mbedtls_config.h>
#include <stddef.h>
#include <string.h>
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk
index d6fc7eb..8eb4873 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.mk
+++ b/drivers/auth/mbedtls/mbedtls_crypto.mk
@@ -37,9 +37,30 @@
pk_wrap.c \
pkparse.c \
pkwrite.c \
- sha256.c \
)
+ifeq (${HASH_ALG}, sha384)
+ MBEDTLS_CRYPTO_SOURCES += \
+ $(addprefix ${MBEDTLS_DIR}/library/, \
+ sha256.c \
+ sha512.c \
+ )
+ TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384
+else ifeq (${HASH_ALG}, sha512)
+ MBEDTLS_CRYPTO_SOURCES += \
+ $(addprefix ${MBEDTLS_DIR}/library/, \
+ sha256.c \
+ sha512.c \
+ )
+ TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512
+else
+ MBEDTLS_CRYPTO_SOURCES += \
+ $(addprefix ${MBEDTLS_DIR}/library/, \
+ sha256.c \
+ )
+ TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256
+endif
+
# Key algorithm specific files
MBEDTLS_ECDSA_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \
ecdsa.c \
@@ -67,6 +88,7 @@
# Needs to be set to drive mbed TLS configuration correctly
$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
+$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
BL1_SOURCES += ${MBEDTLS_CRYPTO_SOURCES}
BL2_SOURCES += ${MBEDTLS_CRYPTO_SOURCES}
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index 4aaab39..01d6fb5 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -19,7 +19,7 @@
* Maximum key and hash sizes (in DER format)
*/
#define PK_DER_LEN 294
-#define HASH_DER_LEN 51
+#define HASH_DER_LEN 83
/*
* The platform must allocate buffers to store the authentication parameters
diff --git a/include/common/aarch32/asm_macros.S b/include/common/aarch32/asm_macros.S
index f573744..7432222 100644
--- a/include/common/aarch32/asm_macros.S
+++ b/include/common/aarch32/asm_macros.S
@@ -79,6 +79,25 @@
ldr r0, =(\_name + \_size)
.endm
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+ /*
+ * ARMv7 cores without Virtualization extension do not support the
+ * eret instruction.
+ */
+ .macro eret
+ movs pc, lr
+ .endm
+#endif
+
+#if (ARM_ARCH_MAJOR == 7)
+ /* ARMv7 does not support stl instruction */
+ .macro stl _reg, _write_lock
+ dmb
+ str \_reg, \_write_lock
+ dsb
+ .endm
+#endif
+
/*
* Helper macro to generate the best mov/movw/movt combinations
* according to the value to be moved.
diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S
index 6fc00dd..59e99f8 100644
--- a/include/common/aarch32/el3_common_macros.S
+++ b/include/common/aarch32/el3_common_macros.S
@@ -107,6 +107,7 @@
vmsr FPEXC, r0
isb
+#if (ARM_ARCH_MAJOR > 7)
/* ---------------------------------------------------------------------
* Initialise SDCR, setting all the fields rather than relying on hw.
*
@@ -116,6 +117,7 @@
*/
ldr r0, =(SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE))
stcopr r0, SDCR
+#endif
.endm
diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S
index 34fdaee..ed35df8 100644
--- a/include/common/aarch64/el3_common_macros.S
+++ b/include/common/aarch64/el3_common_macros.S
@@ -95,10 +95,6 @@
* MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
* privileged debug from S-EL1.
*
- * MDCR_EL3.NSPB (ARM v8.2): SPE enabled in non-secure state and
- * disabled in secure state. Accesses to SPE registers at SEL1 generate
- * trap exceptions to EL3.
- *
* MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
* access to the powerdown debug registers do not trap to EL3.
*
@@ -112,19 +108,6 @@
*/
mov_imm x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | MDCR_SPD32(MDCR_SPD32_DISABLE)) \
& ~(MDCR_TDOSA_BIT | MDCR_TDA_BIT | MDCR_TPM_BIT))
-
-#if ENABLE_SPE_FOR_LOWER_ELS
- /* Detect if SPE is implemented */
- mrs x1, id_aa64dfr0_el1
- ubfx x1, x1, #ID_AA64DFR0_PMS_SHIFT, #ID_AA64DFR0_PMS_LENGTH
- cmp x1, #0x1
- b.ne 1f
-
- /* Enable SPE for use by normal world */
- orr x0, x0, #MDCR_NSPB(MDCR_NSPB_EL1)
-1:
-#endif
-
msr mdcr_el3, x0
/* ---------------------------------------------------------------------
diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h
index efa9703..001f573 100644
--- a/include/drivers/arm/gic_common.h
+++ b/include/drivers/arm/gic_common.h
@@ -72,6 +72,8 @@
#define ARCH_REV_GICV3 0x3
/* GICv2 revision as reported by the PIDR2 register */
#define ARCH_REV_GICV2 0x2
+/* GICv1 revision as reported by the PIDR2 register */
+#define ARCH_REV_GICV1 0x1
#define IGROUPR_SHIFT 5
#define ISENABLER_SHIFT 5
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h
index 96587ac..f8f2608 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config.h
@@ -14,6 +14,13 @@
#define TF_MBEDTLS_RSA_AND_ECDSA 3
/*
+ * Hash algorithms currently supported on mbed TLS libraries
+ */
+#define TF_MBEDTLS_SHA256 1
+#define TF_MBEDTLS_SHA384 2
+#define TF_MBEDTLS_SHA512 3
+
+/*
* Configuration file to build mbed TLS with the required features for
* Trusted Boot
*/
@@ -66,6 +73,9 @@
#endif
#define MBEDTLS_SHA256_C
+#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
+#define MBEDTLS_SHA512_C
+#endif
#define MBEDTLS_VERSION_C
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index 3846bec..c894030 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -87,15 +87,21 @@
#define ID_PFR1_GIC_MASK 0xf
/* SCTLR definitions */
-#define SCTLR_RES1 ((1 << 23) | (1 << 22) | (1 << 11) | (1 << 4) | \
- (1 << 3))
+#define SCTLR_RES1_DEF ((1 << 23) | (1 << 22) | (1 << 4) | (1 << 3))
+#if ARM_ARCH_MAJOR == 7
+#define SCTLR_RES1 SCTLR_RES1_DEF
+#else
+#define SCTLR_RES1 (SCTLR_RES1_DEF | (1 << 11))
+#endif
#define SCTLR_M_BIT (1 << 0)
#define SCTLR_A_BIT (1 << 1)
#define SCTLR_C_BIT (1 << 2)
#define SCTLR_CP15BEN_BIT (1 << 5)
#define SCTLR_ITD_BIT (1 << 7)
+#define SCTLR_Z_BIT (1 << 11)
#define SCTLR_I_BIT (1 << 12)
#define SCTLR_V_BIT (1 << 13)
+#define SCTLR_RR_BIT (1 << 14)
#define SCTLR_NTWI_BIT (1 << 16)
#define SCTLR_NTWE_BIT (1 << 18)
#define SCTLR_WXN_BIT (1 << 19)
@@ -385,6 +391,7 @@
/* System register defines The format is: coproc, opt1, CRn, CRm, opt2 */
#define SCR p15, 0, c1, c1, 0
#define SCTLR p15, 0, c1, c0, 0
+#define ACTLR p15, 0, c1, c0, 1
#define SDCR p15, 0, c1, c3, 1
#define MPIDR p15, 0, c0, c0, 5
#define MIDR p15, 0, c0, c0, 0
@@ -431,6 +438,11 @@
#define PMCR p15, 0, c9, c12, 0
#define CNTHP_CTL p15, 4, c14, c2, 1
+/* AArch32 coproc registers for 32bit MMU descriptor support */
+#define PRRR p15, 0, c10, c2, 0
+#define NMRR p15, 0, c10, c2, 1
+#define DACR p15, 0, c3, c0, 0
+
/* GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
#define ICC_IAR1 p15, 0, c12, c12, 0
#define ICC_IAR0 p15, 0, c12, c8, 0
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
index 469e9b0..42309d5 100644
--- a/include/lib/aarch32/arch_helpers.h
+++ b/include/lib/aarch32/arch_helpers.h
@@ -235,6 +235,7 @@
DEFINE_COPROCR_RW_FUNCS(scr, SCR)
DEFINE_COPROCR_RW_FUNCS(ctr, CTR)
DEFINE_COPROCR_RW_FUNCS(sctlr, SCTLR)
+DEFINE_COPROCR_RW_FUNCS(actlr, ACTLR)
DEFINE_COPROCR_RW_FUNCS(hsctlr, HSCTLR)
DEFINE_COPROCR_RW_FUNCS(hcr, HCR)
DEFINE_COPROCR_RW_FUNCS(hcptr, HCPTR)
@@ -273,6 +274,13 @@
DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
+DEFINE_COPROCR_RW_FUNCS(nsacr, NSACR)
+
+/* AArch32 coproc registers for 32bit MMU descriptor support */
+DEFINE_COPROCR_RW_FUNCS(prrr, PRRR)
+DEFINE_COPROCR_RW_FUNCS(nmrr, NMRR)
+DEFINE_COPROCR_RW_FUNCS(dacr, DACR)
+
/*
* TLBI operation prototypes
*/
@@ -296,6 +304,7 @@
/* Previously defined accessor functions with incomplete register names */
#define dsb() dsbsy()
+#define dmb() dmbsy()
#define IS_IN_SECURE() \
(GET_NS_BIT(read_scr()) == 0)
diff --git a/include/lib/aarch32/smcc_macros.S b/include/lib/aarch32/smcc_macros.S
index cf26175..93f211f 100644
--- a/include/lib/aarch32/smcc_macros.S
+++ b/include/lib/aarch32/smcc_macros.S
@@ -22,6 +22,44 @@
mov r0, sp
add r0, r0, #SMC_CTX_SP_USR
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+ /* Must be in secure state to restore Monitor mode */
+ ldcopr r4, SCR
+ bic r2, r4, #SCR_NS_BIT
+ stcopr r2, SCR
+ isb
+
+ cps #MODE32_sys
+ stm r0!, {sp, lr}
+
+ cps #MODE32_irq
+ mrs r2, spsr
+ stm r0!, {r2, sp, lr}
+
+ cps #MODE32_fiq
+ mrs r2, spsr
+ stm r0!, {r2, sp, lr}
+
+ cps #MODE32_svc
+ mrs r2, spsr
+ stm r0!, {r2, sp, lr}
+
+ cps #MODE32_abt
+ mrs r2, spsr
+ stm r0!, {r2, sp, lr}
+
+ cps #MODE32_und
+ mrs r2, spsr
+ stm r0!, {r2, sp, lr}
+
+ /* lr_mon is already saved by caller */
+ cps #MODE32_mon
+ mrs r2, spsr
+ stm r0!, {r2}
+
+ stcopr r4, SCR
+ isb
+#else
/* Save the banked registers including the current SPSR and LR */
mrs r4, sp_usr
mrs r5, lr_usr
@@ -44,9 +82,10 @@
mrs r11, lr_und
mrs r12, spsr
stm r0!, {r4-r12}
-
/* lr_mon is already saved by caller */
+
ldcopr r4, SCR
+#endif
str r4, [sp, #SMC_CTX_SCR]
ldcopr r4, PMCR
str r4, [sp, #SMC_CTX_PMCR]
@@ -82,6 +121,44 @@
/* Restore the banked registers including the current SPSR */
add r1, r0, #SMC_CTX_SP_USR
+
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+ /* Must be in secure state to restore Monitor mode */
+ ldcopr r4, SCR
+ bic r2, r4, #SCR_NS_BIT
+ stcopr r2, SCR
+ isb
+
+ cps #MODE32_sys
+ ldm r1!, {sp, lr}
+
+ cps #MODE32_irq
+ ldm r1!, {r2, sp, lr}
+ msr spsr_fsxc, r2
+
+ cps #MODE32_fiq
+ ldm r1!, {r2, sp, lr}
+ msr spsr_fsxc, r2
+
+ cps #MODE32_svc
+ ldm r1!, {r2, sp, lr}
+ msr spsr_fsxc, r2
+
+ cps #MODE32_abt
+ ldm r1!, {r2, sp, lr}
+ msr spsr_fsxc, r2
+
+ cps #MODE32_und
+ ldm r1!, {r2, sp, lr}
+ msr spsr_fsxc, r2
+
+ cps #MODE32_mon
+ ldm r1!, {r2}
+ msr spsr_fsxc, r2
+
+ stcopr r4, SCR
+ isb
+#else
ldm r1!, {r4-r12}
msr sp_usr, r4
msr lr_usr, r5
@@ -109,6 +186,7 @@
* f->[31:24] and c->[7:0] bits of SPSR.
*/
msr spsr_fsxc, r12
+#endif
/* Restore the LR */
ldr lr, [r0, #SMC_CTX_LR_MON]
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index cb7dab7..4b31f16 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -135,6 +135,7 @@
#define PARANGE_0011 U(42)
#define PARANGE_0100 U(44)
#define PARANGE_0101 U(48)
+#define PARANGE_0110 U(52)
#define ID_AA64MMFR0_EL1_TGRAN4_SHIFT U(28)
#define ID_AA64MMFR0_EL1_TGRAN4_MASK U(0xf)
@@ -604,4 +605,9 @@
#define PAR_ADDR_SHIFT 12
#define PAR_ADDR_MASK (BIT(40) - 1) /* 40-bits-wide page address */
+/*******************************************************************************
+ * Definitions for system register interface to SPE
+ ******************************************************************************/
+#define PMBLIMITR_EL1 S3_0_C9_C10_0
+
#endif /* __ARCH_H__ */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 782343d..46d9a1c 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -197,6 +197,7 @@
DEFINE_SYSOP_TYPE_FUNC(dmb, st)
DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
+DEFINE_SYSOP_TYPE_FUNC(dsb, nsh)
DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
@@ -301,6 +302,7 @@
DEFINE_SYSREG_READ_FUNC(ctr_el0)
DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
+DEFINE_SYSREG_RW_FUNCS(mdcr_el3)
DEFINE_SYSREG_RW_FUNCS(hstr_el2)
DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2)
DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
@@ -320,6 +322,7 @@
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1)
#define IS_IN_EL(x) \
(GET_EL(read_CurrentEl()) == MODE_EL##x)
diff --git a/include/lib/cpus/aarch32/cortex_a12.h b/include/lib/cpus/aarch32/cortex_a12.h
new file mode 100644
index 0000000..3068a41
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a12.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A12_H__
+#define __CORTEX_A12_H__
+
+/*******************************************************************************
+ * Cortex-A12 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A12_MIDR 0x410FC0C0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A12_ACTLR_SMP_BIT (1 << 6)
+
+#endif /* __CORTEX_A12_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a15.h b/include/lib/cpus/aarch32/cortex_a15.h
new file mode 100644
index 0000000..905c139
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a15.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A15_H__
+#define __CORTEX_A15_H__
+
+/*******************************************************************************
+ * Cortex-A15 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A15_MIDR 0x410FC0F0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A15_ACTLR_SMP_BIT (1 << 6)
+
+#endif /* __CORTEX_A15_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a17.h b/include/lib/cpus/aarch32/cortex_a17.h
new file mode 100644
index 0000000..d2ca91c
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a17.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A17_H__
+#define __CORTEX_A17_H__
+
+/*******************************************************************************
+ * Cortex-A17 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A17_MIDR 0x410FC0E0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A17_ACTLR_SMP_BIT (1 << 6)
+
+#endif /* __CORTEX_A17_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a5.h b/include/lib/cpus/aarch32/cortex_a5.h
new file mode 100644
index 0000000..0a0b7ff
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a5.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A5_H__
+#define __CORTEX_A5_H__
+
+/*******************************************************************************
+ * Cortex-A8 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A5_MIDR 0x410FC050
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A5_ACTLR_SMP_BIT (1 << 6)
+
+#endif /* __CORTEX_A5_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a7.h b/include/lib/cpus/aarch32/cortex_a7.h
new file mode 100644
index 0000000..61b0d00
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a7.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A7_H__
+#define __CORTEX_A7_H__
+
+/*******************************************************************************
+ * Cortex-A7 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A7_MIDR 0x410FC070
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A7_ACTLR_SMP_BIT (1 << 6)
+
+#endif /* __CORTEX_A7_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a9.h b/include/lib/cpus/aarch32/cortex_a9.h
new file mode 100644
index 0000000..be85f9b
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a9.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A9_H__
+#define __CORTEX_A9_H__
+
+/*******************************************************************************
+ * Cortex-A9 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A9_MIDR 0x410FC090
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A9_ACTLR_SMP_BIT (1 << 6)
+#define CORTEX_A9_ACTLR_FLZW_BIT (1 << 3)
+
+/*******************************************************************************
+ * CPU Power Control Register
+ ******************************************************************************/
+#define PCR p15, 0, c15, c0, 0
+
+#ifndef __ASSEMBLY__
+#include <arch_helpers.h>
+DEFINE_COPROCR_RW_FUNCS(pcr, PCR)
+#endif
+
+#endif /* __CORTEX_A9_H__ */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index a89468d..5889904 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -100,8 +100,7 @@
#define CTX_SPSR_FIQ U(0xd8)
#define CTX_DACR32_EL2 U(0xe0)
#define CTX_IFSR32_EL2 U(0xe8)
-#define CTX_FP_FPEXC32_EL2 U(0xf0)
-#define CTX_TIMER_SYSREGS_OFF U(0x100) /* Align to the next 16 byte boundary */
+#define CTX_TIMER_SYSREGS_OFF U(0xf0) /* Align to the next 16 byte boundary */
#else
#define CTX_TIMER_SYSREGS_OFF U(0xc0) /* Align to the next 16 byte boundary */
#endif /* __CTX_INCLUDE_AARCH32_REGS__ */
@@ -161,7 +160,12 @@
#define CTX_FP_Q31 U(0x1f0)
#define CTX_FP_FPSR U(0x200)
#define CTX_FP_FPCR U(0x208)
-#define CTX_FPREGS_END U(0x210)
+#if CTX_INCLUDE_AARCH32_REGS
+#define CTX_FP_FPEXC32_EL2 U(0x210)
+#define CTX_FPREGS_END U(0x220) /* Align to the next 16 byte boundary */
+#else
+#define CTX_FPREGS_END U(0x210) /* Align to the next 16 byte boundary */
+#endif
#endif
#ifndef __ASSEMBLY__
@@ -309,7 +313,6 @@
* Function prototypes
******************************************************************************/
void el1_sysregs_context_save(el1_sys_regs_t *regs);
-void el1_sysregs_context_save_post_ops(void);
void el1_sysregs_context_restore(el1_sys_regs_t *regs);
#if CTX_INCLUDE_FPREGS
void fpregs_context_save(fp_regs_t *regs);
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
new file mode 100644
index 0000000..8a74127
--- /dev/null
+++ b/include/lib/extensions/spe.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SPE_H__
+#define __SPE_H__
+
+void spe_enable(int el2_unused);
+void spe_disable(void);
+
+#endif /* __SPE_H__ */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index a28a903..abd7395 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -227,7 +227,4 @@
uint32_t cookie_lo,
void *handle);
-/* Disable Statistical Profiling Extensions helper */
-void arm_disable_spe(void);
-
#endif /* __PLAT_ARM_H__ */
diff --git a/include/services/sdei.h b/include/services/sdei.h
index b07e93b..ce9a008 100644
--- a/include/services/sdei.h
+++ b/include/services/sdei.h
@@ -154,7 +154,7 @@
int32_t ev_num; /* Event number */
unsigned int intr; /* Physical interrupt number for a bound map */
unsigned int map_flags; /* Mapping flags, see SDEI_MAPF_* */
- unsigned int reg_count; /* Registration count */
+ int reg_count; /* Registration count */
spinlock_t lock; /* Per-event lock */
} sdei_ev_map_t;
diff --git a/lib/aarch32/arm32_aeabi_divmod.c b/lib/aarch32/arm32_aeabi_divmod.c
new file mode 100644
index 0000000..a8f2e74
--- /dev/null
+++ b/lib/aarch32/arm32_aeabi_divmod.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Form ABI specifications:
+ * int __aeabi_idiv(int numerator, int denominator);
+ * unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
+ *
+ * typedef struct { int quot; int rem; } idiv_return;
+ * typedef struct { unsigned quot; unsigned rem; } uidiv_return;
+ *
+ * __value_in_regs idiv_return __aeabi_idivmod(int numerator,
+ * int *denominator);
+ * __value_in_regs uidiv_return __aeabi_uidivmod(unsigned *numerator,
+ * unsigned denominator);
+ */
+
+/* struct qr - stores qutient/remainder to handle divmod EABI interfaces. */
+struct qr {
+ unsigned int q; /* computed quotient */
+ unsigned int r; /* computed remainder */
+ unsigned int q_n; /* specficies if quotient shall be negative */
+ unsigned int r_n; /* specficies if remainder shall be negative */
+};
+
+static void uint_div_qr(unsigned int numerator, unsigned int denominator,
+ struct qr *qr);
+
+/* returns in R0 and R1 by tail calling an asm function */
+unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator);
+
+unsigned int __aeabi_uidiv(unsigned int numerator, unsigned int denominator);
+unsigned int __aeabi_uimod(unsigned int numerator, unsigned int denominator);
+
+/* returns in R0 and R1 by tail calling an asm function */
+signed int __aeabi_idivmod(signed int numerator, signed int denominator);
+
+signed int __aeabi_idiv(signed int numerator, signed int denominator);
+signed int __aeabi_imod(signed int numerator, signed int denominator);
+
+/*
+ * __ste_idivmod_ret_t __aeabi_idivmod(signed numerator, signed denominator)
+ * Numerator and Denominator are received in R0 and R1.
+ * Where __ste_idivmod_ret_t is returned in R0 and R1.
+ *
+ * __ste_uidivmod_ret_t __aeabi_uidivmod(unsigned numerator,
+ * unsigned denominator)
+ * Numerator and Denominator are received in R0 and R1.
+ * Where __ste_uidivmod_ret_t is returned in R0 and R1.
+ */
+#ifdef __GNUC__
+signed int ret_idivmod_values(signed int quotient, signed int remainder);
+unsigned int ret_uidivmod_values(unsigned int quotient, unsigned int remainder);
+#else
+#error "Compiler not supported"
+#endif
+
+static void division_qr(unsigned int n, unsigned int p, struct qr *qr)
+{
+ unsigned int i = 1, q = 0;
+
+ if (p == 0) {
+ qr->r = 0xFFFFFFFF; /* division by 0 */
+ return;
+ }
+
+ while ((p >> 31) == 0) {
+ i = i << 1; /* count the max division steps */
+ p = p << 1; /* increase p until it has maximum size*/
+ }
+
+ while (i > 0) {
+ q = q << 1; /* write bit in q at index (size-1) */
+ if (n >= p) {
+ n -= p;
+ q++;
+ }
+ p = p >> 1; /* decrease p */
+ i = i >> 1; /* decrease remaining size in q */
+ }
+ qr->r = n;
+ qr->q = q;
+}
+
+static void uint_div_qr(unsigned int numerator, unsigned int denominator,
+ struct qr *qr)
+{
+ division_qr(numerator, denominator, qr);
+
+ /* negate quotient and/or remainder according to requester */
+ if (qr->q_n)
+ qr->q = -qr->q;
+ if (qr->r_n)
+ qr->r = -qr->r;
+}
+
+unsigned int __aeabi_uidiv(unsigned int numerator, unsigned int denominator)
+{
+ struct qr qr = { .q_n = 0, .r_n = 0 };
+
+ uint_div_qr(numerator, denominator, &qr);
+
+ return qr.q;
+}
+
+unsigned int __aeabi_uimod(unsigned int numerator, unsigned int denominator)
+{
+ struct qr qr = { .q_n = 0, .r_n = 0 };
+
+ uint_div_qr(numerator, denominator, &qr);
+
+ return qr.r;
+}
+
+unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator)
+{
+ struct qr qr = { .q_n = 0, .r_n = 0 };
+
+ uint_div_qr(numerator, denominator, &qr);
+
+ return ret_uidivmod_values(qr.q, qr.r);
+}
+
+signed int __aeabi_idiv(signed int numerator, signed int denominator)
+{
+ struct qr qr = { .q_n = 0, .r_n = 0 };
+
+ if (((numerator < 0) && (denominator > 0)) ||
+ ((numerator > 0) && (denominator < 0)))
+ qr.q_n = 1; /* quotient shall be negate */
+
+ if (numerator < 0) {
+ numerator = -numerator;
+ qr.r_n = 1; /* remainder shall be negate */
+ }
+
+ if (denominator < 0)
+ denominator = -denominator;
+
+ uint_div_qr(numerator, denominator, &qr);
+
+ return qr.q;
+}
+
+signed int __aeabi_imod(signed int numerator, signed int denominator)
+{
+ signed int s;
+ signed int i;
+ signed int j;
+ signed int h;
+ struct qr qr = { .q_n = 0, .r_n = 0 };
+
+ /* in case modulo of a power of 2 */
+ for (i = 0, j = 0, h = 0, s = denominator; (s != 0) || (h > 1); i++) {
+ if (s & 1) {
+ j = i;
+ h++;
+ }
+ s = s >> 1;
+ }
+ if (h == 1)
+ return numerator >> j;
+
+ if (((numerator < 0) && (denominator > 0)) ||
+ ((numerator > 0) && (denominator < 0)))
+ qr.q_n = 1; /* quotient shall be negate */
+
+ if (numerator < 0) {
+ numerator = -numerator;
+ qr.r_n = 1; /* remainder shall be negate */
+ }
+
+ if (denominator < 0)
+ denominator = -denominator;
+
+ uint_div_qr(numerator, denominator, &qr);
+
+ return qr.r;
+}
+
+signed int __aeabi_idivmod(signed int numerator, signed int denominator)
+{
+ struct qr qr = { .q_n = 0, .r_n = 0 };
+
+ if (((numerator < 0) && (denominator > 0)) ||
+ ((numerator > 0) && (denominator < 0)))
+ qr.q_n = 1; /* quotient shall be negate */
+
+ if (numerator < 0) {
+ numerator = -numerator;
+ qr.r_n = 1; /* remainder shall be negate */
+ }
+
+ if (denominator < 0)
+ denominator = -denominator;
+
+ uint_div_qr(numerator, denominator, &qr);
+
+ return ret_idivmod_values(qr.q, qr.r);
+}
diff --git a/lib/aarch32/arm32_aeabi_divmod_a32.S b/lib/aarch32/arm32_aeabi_divmod_a32.S
new file mode 100644
index 0000000..6915dcd
--- /dev/null
+++ b/lib/aarch32/arm32_aeabi_divmod_a32.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+/*
+ * EABI wrappers from the udivmod and idivmod functions
+ */
+
+ .globl ret_uidivmod_values
+ .globl ret_idivmod_values
+
+/*
+ * signed ret_idivmod_values(signed quot, signed rem);
+ * return quotient and remaining the EABI way (regs r0,r1)
+ */
+func ret_idivmod_values
+ bx lr
+endfunc ret_idivmod_values
+
+/*
+ * unsigned ret_uidivmod_values(unsigned quot, unsigned rem);
+ * return quotient and remaining the EABI way (regs r0,r1)
+ */
+func ret_uidivmod_values
+ bx lr
+endfunc ret_uidivmod_values
diff --git a/lib/cpus/aarch32/cortex_a12.S b/lib/cpus/aarch32/cortex_a12.S
new file mode 100644
index 0000000..73c9750
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a12.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a12.h>
+#include <cpu_macros.S>
+
+ .macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+ ldcopr r0, SCTLR
+ tst r0, #SCTLR_C_BIT
+ ASM_ASSERT(eq)
+#endif
+ .endm
+
+func cortex_a12_disable_smp
+ ldcopr r0, ACTLR
+ bic r0, #CORTEX_A12_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ dsb sy
+ bx lr
+endfunc cortex_a12_disable_smp
+
+func cortex_a12_enable_smp
+ ldcopr r0, ACTLR
+ orr r0, #CORTEX_A12_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ bx lr
+endfunc cortex_a12_enable_smp
+
+func cortex_a12_reset_func
+ b cortex_a12_enable_smp
+endfunc cortex_a12_reset_func
+
+func cortex_a12_core_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 cache */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a12_disable_smp
+endfunc cortex_a12_core_pwr_dwn
+
+func cortex_a12_cluster_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 caches */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ bl plat_disable_acp
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a12_disable_smp
+endfunc cortex_a12_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a12, CORTEX_A12_MIDR, \
+ cortex_a12_reset_func, \
+ cortex_a12_core_pwr_dwn, \
+ cortex_a12_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a15.S b/lib/cpus/aarch32/cortex_a15.S
new file mode 100644
index 0000000..0d5a116
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a15.S
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a15.h>
+#include <cpu_macros.S>
+
+/*
+ * Cortex-A15 support LPAE and Virtualization Extensions.
+ * Don't care if confiugration uses or not LPAE and VE.
+ * Therefore, where we don't check ARCH_IS_ARMV7_WITH_LPAE/VE
+ */
+
+ .macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+ ldcopr r0, SCTLR
+ tst r0, #SCTLR_C_BIT
+ ASM_ASSERT(eq)
+#endif
+ .endm
+
+func cortex_a15_disable_smp
+ ldcopr r0, ACTLR
+ bic r0, #CORTEX_A15_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ dsb sy
+ bx lr
+endfunc cortex_a15_disable_smp
+
+func cortex_a15_enable_smp
+ ldcopr r0, ACTLR
+ orr r0, #CORTEX_A15_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ bx lr
+endfunc cortex_a15_enable_smp
+
+func cortex_a15_reset_func
+ b cortex_a15_enable_smp
+endfunc cortex_a15_reset_func
+
+func cortex_a15_core_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 cache */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a15_disable_smp
+endfunc cortex_a15_core_pwr_dwn
+
+func cortex_a15_cluster_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 caches */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ bl plat_disable_acp
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a15_disable_smp
+endfunc cortex_a15_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a15, CORTEX_A15_MIDR, \
+ cortex_a15_reset_func, \
+ cortex_a15_core_pwr_dwn, \
+ cortex_a15_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a17.S b/lib/cpus/aarch32/cortex_a17.S
new file mode 100644
index 0000000..316d4f0
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a17.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a17.h>
+#include <cpu_macros.S>
+
+ .macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+ ldcopr r0, SCTLR
+ tst r0, #SCTLR_C_BIT
+ ASM_ASSERT(eq)
+#endif
+ .endm
+
+func cortex_a17_disable_smp
+ ldcopr r0, ACTLR
+ bic r0, #CORTEX_A17_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ dsb sy
+ bx lr
+endfunc cortex_a17_disable_smp
+
+func cortex_a17_enable_smp
+ ldcopr r0, ACTLR
+ orr r0, #CORTEX_A17_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ bx lr
+endfunc cortex_a17_enable_smp
+
+func cortex_a17_reset_func
+ b cortex_a17_enable_smp
+endfunc cortex_a17_reset_func
+
+func cortex_a17_core_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 cache */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a17_disable_smp
+endfunc cortex_a17_core_pwr_dwn
+
+func cortex_a17_cluster_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 caches */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ bl plat_disable_acp
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a17_disable_smp
+endfunc cortex_a17_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a17, CORTEX_A17_MIDR, \
+ cortex_a17_reset_func, \
+ cortex_a17_core_pwr_dwn, \
+ cortex_a17_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a5.S b/lib/cpus/aarch32/cortex_a5.S
new file mode 100644
index 0000000..c07c13e
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a5.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a5.h>
+#include <cpu_macros.S>
+
+ .macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+ ldcopr r0, SCTLR
+ tst r0, #SCTLR_C_BIT
+ ASM_ASSERT(eq)
+#endif
+ .endm
+
+func cortex_a5_disable_smp
+ ldcopr r0, ACTLR
+ bic r0, #CORTEX_A5_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ dsb sy
+ bx lr
+endfunc cortex_a5_disable_smp
+
+func cortex_a5_enable_smp
+ ldcopr r0, ACTLR
+ orr r0, #CORTEX_A5_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ bx lr
+endfunc cortex_a5_enable_smp
+
+func cortex_a5_reset_func
+ b cortex_a5_enable_smp
+endfunc cortex_a5_reset_func
+
+func cortex_a5_core_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 cache */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a5_disable_smp
+endfunc cortex_a5_core_pwr_dwn
+
+func cortex_a5_cluster_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 caches */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ bl plat_disable_acp
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a5_disable_smp
+endfunc cortex_a5_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a5, CORTEX_A5_MIDR, \
+ cortex_a5_reset_func, \
+ cortex_a5_core_pwr_dwn, \
+ cortex_a5_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a7.S b/lib/cpus/aarch32/cortex_a7.S
new file mode 100644
index 0000000..0278d1f
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a7.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a7.h>
+#include <cpu_macros.S>
+
+ .macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+ ldcopr r0, SCTLR
+ tst r0, #SCTLR_C_BIT
+ ASM_ASSERT(eq)
+#endif
+ .endm
+
+func cortex_a7_disable_smp
+ ldcopr r0, ACTLR
+ bic r0, #CORTEX_A7_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ dsb sy
+ bx lr
+endfunc cortex_a7_disable_smp
+
+func cortex_a7_enable_smp
+ ldcopr r0, ACTLR
+ orr r0, #CORTEX_A7_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ bx lr
+endfunc cortex_a7_enable_smp
+
+func cortex_a7_reset_func
+ b cortex_a7_enable_smp
+endfunc cortex_a7_reset_func
+
+func cortex_a7_core_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 cache */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a7_disable_smp
+endfunc cortex_a7_core_pwr_dwn
+
+func cortex_a7_cluster_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 caches */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ bl plat_disable_acp
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a7_disable_smp
+endfunc cortex_a7_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a7, CORTEX_A7_MIDR, \
+ cortex_a7_reset_func, \
+ cortex_a7_core_pwr_dwn, \
+ cortex_a7_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a9.S b/lib/cpus/aarch32/cortex_a9.S
new file mode 100644
index 0000000..4f30f84
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a9.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a9.h>
+#include <cpu_macros.S>
+
+ .macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+ ldcopr r0, SCTLR
+ tst r0, #SCTLR_C_BIT
+ ASM_ASSERT(eq)
+#endif
+ .endm
+
+func cortex_a9_disable_smp
+ ldcopr r0, ACTLR
+ bic r0, #CORTEX_A9_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ dsb sy
+ bx lr
+endfunc cortex_a9_disable_smp
+
+func cortex_a9_enable_smp
+ ldcopr r0, ACTLR
+ orr r0, #CORTEX_A9_ACTLR_SMP_BIT
+ stcopr r0, ACTLR
+ isb
+ bx lr
+endfunc cortex_a9_enable_smp
+
+func cortex_a9_reset_func
+ b cortex_a9_enable_smp
+endfunc cortex_a9_reset_func
+
+func cortex_a9_core_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 cache */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a9_disable_smp
+endfunc cortex_a9_core_pwr_dwn
+
+func cortex_a9_cluster_pwr_dwn
+ push {r12, lr}
+
+ assert_cache_enabled
+
+ /* Flush L1 caches */
+ mov r0, #DC_OP_CISW
+ bl dcsw_op_level1
+
+ bl plat_disable_acp
+
+ /* Exit cluster coherency */
+ pop {r12, lr}
+ b cortex_a9_disable_smp
+endfunc cortex_a9_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a9, CORTEX_A9_MIDR, \
+ cortex_a9_reset_func, \
+ cortex_a9_core_pwr_dwn, \
+ cortex_a9_cluster_pwr_dwn
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 3e7a5b7..a8672d6 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -125,6 +125,17 @@
}
/*******************************************************************************
+ * Enable architecture extensions on first entry to Non-secure world.
+ * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
+ * it is zero.
+ ******************************************************************************/
+static void enable_extensions_nonsecure(int el2_unused)
+{
+#if IMAGE_BL32
+#endif
+}
+
+/*******************************************************************************
* The following function initializes the cpu_context for a CPU specified by
* its `cpu_idx` for first use, and sets the initial entrypoint state as
* specified by the entry_point_info structure.
@@ -161,6 +172,7 @@
{
uint32_t hsctlr, scr;
cpu_context_t *ctx = cm_get_context(security_state);
+ int el2_unused = 0;
assert(ctx);
@@ -185,6 +197,8 @@
isb();
} else if (read_id_pfr1() &
(ID_PFR1_VIRTEXT_MASK << ID_PFR1_VIRTEXT_SHIFT)) {
+ el2_unused = 1;
+
/*
* Set the NS bit to access NS copies of certain banked
* registers
@@ -283,5 +297,6 @@
write_scr(read_scr() & ~SCR_NS_BIT);
isb();
}
+ enable_extensions_nonsecure(el2_unused);
}
}
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index db16a9f..620ec16 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -9,7 +9,6 @@
#include <context.h>
.global el1_sysregs_context_save
- .global el1_sysregs_context_save_post_ops
.global el1_sysregs_context_restore
#if CTX_INCLUDE_FPREGS
.global fpregs_context_save
@@ -90,9 +89,6 @@
mrs x15, dacr32_el2
mrs x16, ifsr32_el2
stp x15, x16, [x0, #CTX_DACR32_EL2]
-
- mrs x17, fpexc32_el2
- str x17, [x0, #CTX_FP_FPEXC32_EL2]
#endif
/* Save NS timer registers if the build has instructed so */
@@ -115,36 +111,6 @@
/* -----------------------------------------------------
* The following function strictly follows the AArch64
* PCS to use x9-x17 (temporary caller-saved registers)
- * to do post operations after saving the EL1 system
- * register context.
- * -----------------------------------------------------
- */
-func el1_sysregs_context_save_post_ops
-#if ENABLE_SPE_FOR_LOWER_ELS
- /* Detect if SPE is implemented */
- mrs x9, id_aa64dfr0_el1
- ubfx x9, x9, #ID_AA64DFR0_PMS_SHIFT, #ID_AA64DFR0_PMS_LENGTH
- cmp x9, #0x1
- b.ne 1f
-
- /*
- * Before switching from normal world to secure world
- * the profiling buffers need to be drained out to memory. This is
- * required to avoid an invalid memory access when TTBR is switched
- * for entry to SEL1.
- */
- .arch armv8.2-a+profile
- psb csync
- dsb nsh
- .arch armv8-a
-1:
-#endif
- ret
-endfunc el1_sysregs_context_save_post_ops
-
-/* -----------------------------------------------------
- * The following function strictly follows the AArch64
- * PCS to use x9-x17 (temporary caller-saved registers)
* to restore EL1 system register context. It assumes
* that 'x0' is pointing to a 'el1_sys_regs' structure
* from where the register context will be restored
@@ -212,9 +178,6 @@
ldp x15, x16, [x0, #CTX_DACR32_EL2]
msr dacr32_el2, x15
msr ifsr32_el2, x16
-
- ldr x17, [x0, #CTX_FP_FPEXC32_EL2]
- msr fpexc32_el2, x17
#endif
/* Restore NS timer registers if the build has instructed so */
#if NS_TIMER_SWITCH
@@ -275,6 +238,10 @@
mrs x10, fpcr
str x10, [x0, #CTX_FP_FPCR]
+#if CTX_INCLUDE_AARCH32_REGS
+ mrs x11, fpexc32_el2
+ str x11, [x0, #CTX_FP_FPEXC32_EL2]
+#endif
ret
endfunc fpregs_context_save
@@ -318,6 +285,10 @@
ldr x10, [x0, #CTX_FP_FPCR]
msr fpcr, x10
+#if CTX_INCLUDE_AARCH32_REGS
+ ldr x11, [x0, #CTX_FP_FPEXC32_EL2]
+ msr fpexc32_el2, x11
+#endif
/*
* No explict ISB required here as ERET to
* switch to secure EL1 or non-secure world
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index c8232df..8f1523f 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -15,6 +15,7 @@
#include <platform_def.h>
#include <pubsub_events.h>
#include <smcc_helpers.h>
+#include <spe.h>
#include <string.h>
#include <utils.h>
@@ -209,6 +210,20 @@
}
/*******************************************************************************
+ * Enable architecture extensions on first entry to Non-secure world.
+ * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
+ * it is zero.
+ ******************************************************************************/
+static void enable_extensions_nonsecure(int el2_unused)
+{
+#if IMAGE_BL31
+#if ENABLE_SPE_FOR_LOWER_ELS
+ spe_enable(el2_unused);
+#endif
+#endif
+}
+
+/*******************************************************************************
* The following function initializes the cpu_context for a CPU specified by
* its `cpu_idx` for first use, and sets the initial entrypoint state as
* specified by the entry_point_info structure.
@@ -245,6 +260,7 @@
{
uint32_t sctlr_elx, scr_el3, mdcr_el2;
cpu_context_t *ctx = cm_get_context(security_state);
+ int el2_unused = 0;
assert(ctx);
@@ -258,6 +274,8 @@
sctlr_elx |= SCTLR_EL2_RES1;
write_sctlr_el2(sctlr_elx);
} else if (EL_IMPLEMENTED(2)) {
+ el2_unused = 1;
+
/*
* EL2 present but unused, need to disable safely.
* SCTLR_EL2 can be ignored in this case.
@@ -340,13 +358,6 @@
* relying on hw. Some fields are architecturally
* UNKNOWN on reset.
*
- * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
- * profiling controls to EL2.
- *
- * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in non-secure
- * state. Accesses to profiling buffer controls at
- * non-secure EL1 are not trapped to EL2.
- *
* MDCR_EL2.TDRA: Set to zero so that Non-secure EL0 and
* EL1 System register accesses to the Debug ROM
* registers are not trapped to EL2.
@@ -383,22 +394,6 @@
| MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT
| MDCR_EL2_TPMCR_BIT));
-#if ENABLE_SPE_FOR_LOWER_ELS
- uint64_t id_aa64dfr0_el1;
-
- /* Detect if SPE is implemented */
- id_aa64dfr0_el1 = read_id_aa64dfr0_el1() >>
- ID_AA64DFR0_PMS_SHIFT;
- if ((id_aa64dfr0_el1 & ID_AA64DFR0_PMS_MASK) == 1) {
- /*
- * Make sure traps to EL2 are not generated if
- * EL2 is implemented but not used.
- */
- mdcr_el2 &= ~MDCR_EL2_TPMS;
- mdcr_el2 |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
- }
-#endif
-
write_mdcr_el2(mdcr_el2);
/*
@@ -420,6 +415,7 @@
write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
~(CNTHP_CTL_ENABLE_BIT));
}
+ enable_extensions_nonsecure(el2_unused);
}
cm_el1_sysregs_context_restore(security_state);
@@ -439,7 +435,6 @@
assert(ctx);
el1_sysregs_context_save(get_sysregs_ctx(ctx));
- el1_sysregs_context_save_post_ops();
#if IMAGE_BL31
if (security_state == SECURE)
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
new file mode 100644
index 0000000..3b297f2
--- /dev/null
+++ b/lib/extensions/spe/spe.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <pubsub.h>
+
+/*
+ * The assembler does not yet understand the psb csync mnemonic
+ * so use the equivalent hint instruction.
+ */
+#define psb_csync() asm volatile("hint #17")
+
+void spe_enable(int el2_unused)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
+ if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
+ uint64_t v;
+
+ if (el2_unused) {
+ /*
+ * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
+ * profiling controls to EL2.
+ *
+ * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure
+ * state. Accesses to profiling buffer controls at
+ * Non-secure EL1 are not trapped to EL2.
+ */
+ v = read_mdcr_el2();
+ v &= ~MDCR_EL2_TPMS;
+ v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
+ write_mdcr_el2(v);
+ }
+
+ /*
+ * MDCR_EL2.NSPB (ARM v8.2): SPE enabled in Non-secure state
+ * and disabled in secure state. Accesses to SPE registers at
+ * S-EL1 generate trap exceptions to EL3.
+ */
+ v = read_mdcr_el3();
+ v |= MDCR_NSPB(MDCR_NSPB_EL1);
+ write_mdcr_el3(v);
+ }
+}
+
+void spe_disable(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
+ if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
+ uint64_t v;
+
+ /* Drain buffered data */
+ psb_csync();
+ dsbnsh();
+
+ /* Disable profiling buffer */
+ v = read_pmblimitr_el1();
+ v &= ~(1ULL << 0);
+ write_pmblimitr_el1(v);
+ isb();
+ }
+}
+
+static void *spe_drain_buffers_hook(const void *arg)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
+ if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
+ /* Drain buffered data */
+ psb_csync();
+ dsbnsh();
+ }
+
+ return 0;
+}
+
+SUBSCRIBE_TO_EVENT(cm_entering_secure_world, spe_drain_buffers_hook);
diff --git a/lib/locks/exclusive/aarch32/spinlock.S b/lib/locks/exclusive/aarch32/spinlock.S
index bc77bc9..9492cc0 100644
--- a/lib/locks/exclusive/aarch32/spinlock.S
+++ b/lib/locks/exclusive/aarch32/spinlock.S
@@ -9,6 +9,17 @@
.globl spin_lock
.globl spin_unlock
+#if ARM_ARCH_AT_LEAST(8, 0)
+/*
+ * According to the ARMv8-A Architecture Reference Manual, "when the global
+ * monitor for a PE changes from Exclusive Access state to Open Access state,
+ * an event is generated.". This applies to both AArch32 and AArch64 modes of
+ * ARMv8-A. As a result, no explicit SEV with unlock is required.
+ */
+#define COND_SEV()
+#else
+#define COND_SEV() sev
+#endif
func spin_lock
mov r2, #1
@@ -27,5 +38,6 @@
func spin_unlock
mov r1, #0
stl r1, [r0]
+ COND_SEV()
bx lr
endfunc spin_unlock
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 4105e63..8e41cf0 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -220,6 +220,23 @@
if (target_idx == -1)
return PSCI_E_INVALID_PARAMS;
+ /*
+ * Generic management:
+ * Perform cache maintanence ahead of reading the target CPU state to
+ * ensure that the data is not stale.
+ * There is a theoretical edge case where the cache may contain stale
+ * data for the target CPU data - this can occur under the following
+ * conditions:
+ * - the target CPU is in another cluster from the current
+ * - the target CPU was the last CPU to shutdown on its cluster
+ * - the cluster was removed from coherency as part of the CPU shutdown
+ *
+ * In this case the cache maintenace that was performed as part of the
+ * target CPUs shutdown was not seen by the current CPU's cluster. And
+ * so the cache may contain stale data for the target CPU.
+ */
+ flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+
return psci_get_aff_info_state_by_idx(target_idx);
}
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index a841dda..c00bd94 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -266,8 +266,10 @@
******************************************************************************/
void psci_arch_setup(void)
{
+#if ARM_ARCH_MAJOR > 7 || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
/* Program the counter frequency */
write_cntfrq_el0(plat_get_syscnt_freq2());
+#endif
/* Initialize the cpu_ops pointer. */
init_cpu_ops();
diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c
index c7e34f2..720d446 100644
--- a/lib/xlat_tables/aarch32/xlat_tables.c
+++ b/lib/xlat_tables/aarch32/xlat_tables.c
@@ -13,6 +13,10 @@
#include <xlat_tables.h>
#include "../xlat_tables_private.h"
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)
+#error ARMv7 target does not support LPAE MMU descriptors
+#endif
+
#define XLAT_TABLE_LEVEL_BASE \
GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE)
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 28ae1f7..eabc3df 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -60,7 +60,10 @@
/* Physical Address ranges supported in the AArch64 Memory Model */
static const unsigned int pa_range_bits_arr[] = {
PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
- PARANGE_0101
+ PARANGE_0101,
+#if ARM_ARCH_AT_LEAST(8, 2)
+ PARANGE_0110,
+#endif
};
static unsigned long long get_max_supported_pa(void)
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 642f799..fc7ca46 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -14,6 +14,10 @@
#include <xlat_tables_v2.h>
#include "../xlat_tables_private.h"
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)
+#error ARMv7 target does not support LPAE MMU descriptors
+#endif
+
#if ENABLE_ASSERTIONS
unsigned long long xlat_arch_get_max_supported_pa(void)
{
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 4331107..aa5b9e5 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -48,7 +48,10 @@
/* Physical Address ranges supported in the AArch64 Memory Model */
static const unsigned int pa_range_bits_arr[] = {
PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
- PARANGE_0101
+ PARANGE_0101,
+#if ARM_ARCH_AT_LEAST(8, 2)
+ PARANGE_0110,
+#endif
};
unsigned long long xlat_arch_get_max_supported_pa(void)
diff --git a/maintainers.rst b/maintainers.rst
index 388073e..701ea17 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -91,6 +91,11 @@
- docs/plat/xilinx-zynqmp.md
- plat/xilinx/\*
+ARMv7 architecture sub-maintainer
+---------------------------------
+
+Etienne Carriere (etienne.carriere@linaro.org, `etienne-lms`_)
+
.. _danh-arm: https://github.com/danh-arm
.. _davidcunado-arm: https://github.com/davidcunado-arm
.. _jenswi-linaro: https://github.com/jenswi-linaro
@@ -100,3 +105,4 @@
.. _TonyXie06: https://github.com/TonyXie06
.. _rkchrome: https://github.com/rkchrome
.. _sorenb-xlnx: https://github.com/sorenb-xlnx
+.. _etienne-lms: https://github.com/etienne-lms
diff --git a/make_helpers/armv7-a-cpus.mk b/make_helpers/armv7-a-cpus.mk
new file mode 100644
index 0000000..20e7ec5
--- /dev/null
+++ b/make_helpers/armv7-a-cpus.mk
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch32)
+$(error ARM_ARCH_MAJOR=7 mandates ARCH=aarch32)
+endif
+
+# For ARMv7, set march32 from platform directive ARMV7_CORTEX_Ax=yes
+# and ARM_WITH_NEON=yes/no.
+#
+# GCC and Clang require -march=armv7-a for C-A9 and -march=armv7ve for C-A15.
+# armClang requires -march=armv7-a for all ARMv7 Cortex-A. To comply with
+# all, just drop -march and supply only -mcpu.
+
+# Platform can override march32-directive through MARCH32_DIRECTIVE
+ifdef MARCH32_DIRECTIVE
+march32-directive := $(MARCH32_DIRECTIVE)
+else
+march32-set-${ARM_CORTEX_A5} := -mcpu=cortex-a5
+march32-set-${ARM_CORTEX_A7} := -mcpu=cortex-a7
+march32-set-${ARM_CORTEX_A9} := -mcpu=cortex-a9
+march32-set-${ARM_CORTEX_A12} := -mcpu=cortex-a12
+march32-set-${ARM_CORTEX_A15} := -mcpu=cortex-a15
+march32-set-${ARM_CORTEX_A17} := -mcpu=cortex-a17
+march32-neon-$(ARM_WITH_NEON) := -mfpu=neon
+
+# default to -march=armv7-a as target directive
+march32-set-yes ?= -march=armv7-a
+march32-directive := ${march32-set-yes} ${march32-neon-yes}
+endif
+
+# Platform may override these extension support directives:
+#
+# ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING
+# Defined if core supports the Large Page Addressing extension.
+#
+# ARMV7_SUPPORTS_VIRTUALIZATION
+# Defined if ARMv7 core supports the Virtualization extension.
+#
+# ARMV7_SUPPORTS_GENERIC_TIMER
+# Defined if ARMv7 core supports the Generic Timer extension.
+
+ifeq ($(filter yes,$(ARM_CORTEX_A7) $(ARM_CORTEX_A12) $(ARM_CORTEX_A15) $(ARM_CORTEX_A17)),yes)
+$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
+$(eval $(call add_define,ARMV7_SUPPORTS_VIRTUALIZATION))
+$(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER))
+endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 660e54e..b7ce051 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -149,19 +149,10 @@
# platforms).
WARMBOOT_ENABLE_DCACHE_EARLY := 0
-# By default, enable Statistical Profiling Extensions.
-# The top level Makefile will disable this feature depending on
-# the target architecture and version number.
+# Build option to enable/disable the Statistical Profiling Extensions
ENABLE_SPE_FOR_LOWER_ELS := 1
-# SPE is enabled by default but only supported on AArch64 8.2 onwards.
-# Disable it in all other cases.
+# SPE is only supported on AArch64 so disable it on AArch32.
ifeq (${ARCH},aarch32)
override ENABLE_SPE_FOR_LOWER_ELS := 0
-else
- ifeq (${ARM_ARCH_MAJOR},8)
- ifeq ($(ARM_ARCH_MINOR),$(filter $(ARM_ARCH_MINOR),0 1))
- ENABLE_SPE_FOR_LOWER_ELS := 0
- endif
- endif
endif
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index 712fa6f..b13afe4 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -54,6 +54,7 @@
# packed in the FIP). Developers can use their own keys by specifying the proper
# build option in the command line when building the Trusted Firmware
$(if ${KEY_ALG},$(eval $(call CERT_ADD_CMD_OPT,${KEY_ALG},--key-alg)))
+$(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg)))
$(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key)))
$(if ${ROT_KEY},$(eval $(call FWU_CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key)))
$(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key)))
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 0ab5b82..13bd8f2 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -14,6 +14,7 @@
#include <plat_arm.h>
#include <platform.h>
#include <psci.h>
+#include <spe.h>
#include <v2m_def.h>
#include "drivers/pwrc/fvp_pwrc.h"
#include "fvp_def.h"
@@ -57,7 +58,7 @@
* On power down we need to disable statistical profiling extensions
* before exiting coherency.
*/
- arm_disable_spe();
+ spe_disable();
#endif
/* Disable coherency if this cluster is to be turned off */
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index b53e60d..9d3a108 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -12,7 +12,6 @@
.globl plat_crash_console_putc
.globl plat_crash_console_flush
.globl platform_mem_init
- .globl arm_disable_spe
/* -----------------------------------------------------
@@ -88,34 +87,6 @@
ret
endfunc platform_mem_init
- /* -----------------------------------------------------
- * void arm_disable_spe (void);
- * -----------------------------------------------------
- */
-#if ENABLE_SPE_FOR_LOWER_ELS
-func arm_disable_spe
- /* Detect if SPE is implemented */
- mrs x0, id_aa64dfr0_el1
- ubfx x0, x0, #ID_AA64DFR0_PMS_SHIFT, #ID_AA64DFR0_PMS_LENGTH
- cmp x0, #0x1
- b.ne 1f
-
- /* Drain buffered data */
- .arch armv8.2-a+profile
- psb csync
- dsb nsh
-
- /* Disable Profiling Buffer */
- mrs x0, pmblimitr_el1
- bic x0, x0, #1
- msr pmblimitr_el1, x0
- isb
- .arch armv8-a
-1:
- ret
-endfunc arm_disable_spe
-#endif
-
/*
* Need to use coherent stack when ARM Cryptocell is used to autheticate images
* since Cryptocell uses DMA to transfer data and it is not coherent with the
diff --git a/plat/common/aarch32/platform_helpers.S b/plat/common/aarch32/platform_helpers.S
index 61d21ab..0a0e927 100644
--- a/plat/common/aarch32/platform_helpers.S
+++ b/plat/common/aarch32/platform_helpers.S
@@ -7,12 +7,15 @@
#include <arch.h>
#include <asm_macros.S>
+ .weak plat_report_exception
.weak plat_crash_console_init
.weak plat_crash_console_putc
.weak plat_crash_console_flush
.weak plat_reset_handler
.weak plat_disable_acp
+ .weak bl1_plat_prepare_exit
.weak platform_mem_init
+ .weak plat_error_handler
.weak plat_panic_handler
.weak bl2_plat_preload_setup
.weak plat_try_next_boot_source
@@ -22,6 +25,15 @@
* each platform.
* -----------------------------------------------------
*/
+func plat_report_exception
+ bx lr
+endfunc plat_report_exception
+
+ /* -----------------------------------------------------
+ * Placeholder function which should be redefined by
+ * each platform.
+ * -----------------------------------------------------
+ */
func plat_crash_console_init
mov r0, #0
bx lr
@@ -74,6 +86,25 @@
endfunc platform_mem_init
/* -----------------------------------------------------
+ * void bl1_plat_prepare_exit(entry_point_info_t *ep_info);
+ * Called before exiting BL1. Default: do nothing
+ * -----------------------------------------------------
+ */
+func bl1_plat_prepare_exit
+ bx lr
+endfunc bl1_plat_prepare_exit
+
+ /* -----------------------------------------------------
+ * void plat_error_handler(int err) __dead2;
+ * Endless loop by default.
+ * -----------------------------------------------------
+ */
+func plat_error_handler
+ wfi
+ b plat_error_handler
+endfunc plat_error_handler
+
+ /* -----------------------------------------------------
* void plat_panic_handler(void) __dead2;
* Endless loop by default.
* -----------------------------------------------------
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 4551a8b..42bf46d 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -475,8 +475,10 @@
sdei_cpu_state_t *state;
/* Validate preempted security state */
- if ((preempted_sec_state != SECURE) || (preempted_sec_state != NON_SECURE))
+ if ((preempted_sec_state != SECURE) &&
+ (preempted_sec_state != NON_SECURE)) {
return -1;
+ }
/* Can't dispatch if events are masked on this PE */
state = sdei_get_this_pe_state();
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 4fe990a..2f08c8b 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -120,6 +120,7 @@
/* Platform events are always bound, so set the bound flag */
if (is_map_dynamic(map)) {
assert(map->intr == SDEI_DYN_IRQ);
+ assert(is_event_normal(map));
num_dyn_shrd_slots++;
} else {
/* Shared mappings must be bound to shared interrupt */
@@ -171,6 +172,7 @@
if (map->ev_num != SDEI_EVENT_0) {
if (is_map_dynamic(map)) {
assert(map->intr == SDEI_DYN_IRQ);
+ assert(is_event_normal(map));
num_dyn_priv_slots++;
} else {
/*
diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h
index 256e7af..9b4ef5a 100644
--- a/tools/cert_create/include/cert.h
+++ b/tools/cert_create/include/cert.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -48,7 +48,13 @@
int cert_init(void);
cert_t *cert_get_by_opt(const char *opt);
int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value);
-int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk);
+int cert_new(
+ int key_alg,
+ int md_alg,
+ cert_t *cert,
+ int days,
+ int ca,
+ STACK_OF(X509_EXTENSION) * sk);
/* Macro to register the certificates used in the CoT */
#define REGISTER_COT(_certs) \
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index 304fa61..1a253cc 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,6 +30,13 @@
KEY_ALG_MAX_NUM
};
+/* Supported hash algorithms */
+enum{
+ HASH_ALG_SHA256,
+ HASH_ALG_SHA384,
+ HASH_ALG_SHA512,
+};
+
/*
* This structure contains the relevant information to create the keys
* required to sign the certificates.
diff --git a/tools/cert_create/include/sha.h b/tools/cert_create/include/sha.h
index 6907fa1..4d07a1e 100644
--- a/tools/cert_create/include/sha.h
+++ b/tools/cert_create/include/sha.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,6 @@
#ifndef SHA_H_
#define SHA_H_
-int sha_file(const char *filename, unsigned char *md);
+int sha_file(int md_alg, const char *filename, unsigned char *md);
#endif /* SHA_H_ */
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
index 3f0b4d3..8e8aee6 100644
--- a/tools/cert_create/src/cert.c
+++ b/tools/cert_create/src/cert.c
@@ -56,6 +56,19 @@
return ret;
}
+const EVP_MD *get_digest(int alg)
+{
+ switch (alg) {
+ case HASH_ALG_SHA256:
+ return EVP_sha256();
+ case HASH_ALG_SHA384:
+ return EVP_sha384();
+ case HASH_ALG_SHA512:
+ return EVP_sha512();
+ default:
+ return NULL;
+ }
+}
int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value)
{
@@ -79,7 +92,13 @@
return 1;
}
-int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk)
+int cert_new(
+ int key_alg,
+ int md_alg,
+ cert_t *cert,
+ int days,
+ int ca,
+ STACK_OF(X509_EXTENSION) * sk)
{
EVP_PKEY *pkey = keys[cert->key].key;
cert_t *issuer_cert = &certs[cert->issuer];
@@ -118,7 +137,7 @@
}
/* Sign the certificate with the issuer key */
- if (!EVP_DigestSignInit(mdCtx, &pKeyCtx, EVP_sha256(), NULL, ikey)) {
+ if (!EVP_DigestSignInit(mdCtx, &pKeyCtx, get_digest(md_alg), NULL, ikey)) {
ERR_print_errors_fp(stdout);
goto END;
}
@@ -138,7 +157,7 @@
goto END;
}
- if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, EVP_sha256())) {
+ if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, get_digest(md_alg))) {
ERR_print_errors_fp(stdout);
goto END;
}
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index 741242f..4abfe6d 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -68,6 +68,7 @@
/* Global options */
static int key_alg;
+static int hash_alg;
static int new_keys;
static int save_keys;
static int print_cert;
@@ -95,6 +96,12 @@
#endif /* OPENSSL_NO_EC */
};
+static const char *hash_algs_str[] = {
+ [HASH_ALG_SHA256] = "sha256",
+ [HASH_ALG_SHA384] = "sha384",
+ [HASH_ALG_SHA512] = "sha512",
+};
+
static void print_help(const char *cmd, const struct option *long_opt)
{
int rem, i = 0;
@@ -150,6 +157,19 @@
return -1;
}
+static int get_hash_alg(const char *hash_alg_str)
+{
+ int i;
+
+ for (i = 0 ; i < NUM_ELEM(hash_algs_str) ; i++) {
+ if (0 == strcmp(hash_alg_str, hash_algs_str[i])) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
static void check_cmd_params(void)
{
cert_t *cert;
@@ -228,6 +248,10 @@
PKCS#1 v2.1, 'rsa_1_5' - RSA PKCS#1 v1.5, 'ecdsa'"
},
{
+ { "hash-alg", required_argument, NULL, 's' },
+ "Hash algorithm : 'sha256' (default), 'sha384', 'sha512'"
+ },
+ {
{ "save-keys", no_argument, NULL, 'k' },
"Save key pairs into files. Filenames must be provided"
},
@@ -254,7 +278,8 @@
const struct option *cmd_opt;
const char *cur_opt;
unsigned int err_code;
- unsigned char md[SHA256_DIGEST_LENGTH];
+ unsigned char md[SHA512_DIGEST_LENGTH];
+ unsigned int md_len;
const EVP_MD *md_info;
NOTICE("CoT Generation Tool: %s\n", build_msg);
@@ -262,6 +287,7 @@
/* Set default options */
key_alg = KEY_ALG_RSA;
+ hash_alg = HASH_ALG_SHA256;
/* Add common command line options */
for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) {
@@ -291,7 +317,7 @@
while (1) {
/* getopt_long stores the option index here. */
- c = getopt_long(argc, argv, "a:hknp", cmd_opt, &opt_idx);
+ c = getopt_long(argc, argv, "a:hknps:", cmd_opt, &opt_idx);
/* Detect the end of the options. */
if (c == -1) {
@@ -318,6 +344,13 @@
case 'p':
print_cert = 1;
break;
+ case 's':
+ hash_alg = get_hash_alg(optarg);
+ if (hash_alg < 0) {
+ ERROR("Invalid hash algorithm '%s'\n", optarg);
+ exit(1);
+ }
+ break;
case CMD_OPT_EXT:
cur_opt = cmd_opt_get_name(opt_idx);
ext = ext_get_by_opt(cur_opt);
@@ -343,9 +376,18 @@
/* Check command line arguments */
check_cmd_params();
- /* Indicate SHA256 as image hash algorithm in the certificate
+ /* Indicate SHA as image hash algorithm in the certificate
* extension */
- md_info = EVP_sha256();
+ if (hash_alg == HASH_ALG_SHA384) {
+ md_info = EVP_sha384();
+ md_len = SHA384_DIGEST_LENGTH;
+ } else if (hash_alg == HASH_ALG_SHA512) {
+ md_info = EVP_sha512();
+ md_len = SHA512_DIGEST_LENGTH;
+ } else {
+ md_info = EVP_sha256();
+ md_len = SHA256_DIGEST_LENGTH;
+ }
/* Load private keys from files (or generate new ones) */
for (i = 0 ; i < num_keys ; i++) {
@@ -421,14 +463,14 @@
if (ext->arg == NULL) {
if (ext->optional) {
/* Include a hash filled with zeros */
- memset(md, 0x0, SHA256_DIGEST_LENGTH);
+ memset(md, 0x0, SHA512_DIGEST_LENGTH);
} else {
/* Do not include this hash in the certificate */
break;
}
} else {
/* Calculate the hash of the file */
- if (!sha_file(ext->arg, md)) {
+ if (!sha_file(hash_alg, ext->arg, md)) {
ERROR("Cannot calculate hash of %s\n",
ext->arg);
exit(1);
@@ -436,7 +478,7 @@
}
CHECK_NULL(cert_ext, ext_new_hash(ext_nid,
EXT_CRIT, md_info, md,
- SHA256_DIGEST_LENGTH));
+ md_len));
break;
case EXT_TYPE_PKEY:
CHECK_NULL(cert_ext, ext_new_key(ext_nid,
@@ -453,7 +495,7 @@
}
/* Create certificate. Signed with corresponding key */
- if (cert->fn && !cert_new(key_alg, cert, VAL_DAYS, 0, sk)) {
+ if (cert->fn && !cert_new(key_alg, hash_alg, cert, VAL_DAYS, 0, sk)) {
ERROR("Cannot create %s\n", cert->cn);
exit(1);
}
diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c
index 2971593..3d977fb 100644
--- a/tools/cert_create/src/sha.c
+++ b/tools/cert_create/src/sha.c
@@ -1,20 +1,21 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <openssl/sha.h>
#include <stdio.h>
-
#include "debug.h"
+#include "key.h"
#define BUFFER_SIZE 256
-int sha_file(const char *filename, unsigned char *md)
+int sha_file(int md_alg, const char *filename, unsigned char *md)
{
FILE *inFile;
SHA256_CTX shaContext;
+ SHA512_CTX sha512Context;
int bytes;
unsigned char data[BUFFER_SIZE];
@@ -29,11 +30,25 @@
return 0;
}
- SHA256_Init(&shaContext);
- while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
- SHA256_Update(&shaContext, data, bytes);
+ if (md_alg == HASH_ALG_SHA384) {
+ SHA384_Init(&sha512Context);
+ while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+ SHA384_Update(&sha512Context, data, bytes);
+ }
+ SHA384_Final(md, &sha512Context);
+ } else if (md_alg == HASH_ALG_SHA512) {
+ SHA512_Init(&sha512Context);
+ while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+ SHA512_Update(&sha512Context, data, bytes);
+ }
+ SHA512_Final(md, &sha512Context);
+ } else {
+ SHA256_Init(&shaContext);
+ while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+ SHA256_Update(&shaContext, data, bytes);
+ }
+ SHA256_Final(md, &shaContext);
}
- SHA256_Final(md, &shaContext);
fclose(inFile);
return 1;