Merge pull request #1679 from pangupta/master

ccn: Introduce API to set and read value of node register
diff --git a/Makefile b/Makefile
index 74d5180..c79264b 100644
--- a/Makefile
+++ b/Makefile
@@ -108,13 +108,6 @@
         LOG_LEVEL	:=	20
 endif
 
-# Enable backtrace by default in DEBUG AArch64 builds
-ifeq (${ARCH},aarch32)
-        ENABLE_BACKTRACE 	:=	0
-else
-        ENABLE_BACKTRACE 	:=	${DEBUG}
-endif
-
 # Default build string (git branch and commit)
 ifeq (${BUILD_STRING},)
         BUILD_STRING	:=	$(shell git describe --always --dirty --tags 2> /dev/null)
@@ -206,11 +199,6 @@
 
 GCC_V_OUTPUT		:=	$(shell $(CC) -v 2>&1)
 
-# Force the compiler to include the frame pointer
-ifeq (${ENABLE_BACKTRACE},1)
-TF_CFLAGS		+=	-fno-omit-frame-pointer
-endif
-
 TF_LDFLAGS		+=	--fatal-warnings -O1
 TF_LDFLAGS		+=	--gc-sections
 TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
@@ -238,10 +226,6 @@
 BL_COMMON_SOURCES	+=	lib/${ARCH}/armclang_printf.S
 endif
 
-ifeq (${ENABLE_BACKTRACE},1)
-BL_COMMON_SOURCES	+=	common/backtrace.c
-endif
-
 INCLUDES		+=	-Iinclude				\
 				-Iinclude/bl1				\
 				-Iinclude/bl2				\
@@ -270,6 +254,8 @@
 				${SPD_INCLUDES}				\
 				-Iinclude/tools_share
 
+include common/backtrace/backtrace.mk
+
 ################################################################################
 # Generic definitions
 ################################################################################
@@ -369,15 +355,6 @@
 # Check incompatible options
 ################################################################################
 
-ifeq (${ARCH},aarch32)
-        ifeq (${ENABLE_BACKTRACE},1)
-                ifneq (${AARCH32_INSTRUCTION_SET},A32)
-                        $(error Error: AARCH32_INSTRUCTION_SET=A32 is needed \
-                        for ENABLE_BACKTRACE when compiling for AArch32.)
-                endif
-        endif
-endif
-
 ifdef EL3_PAYLOAD_BASE
         ifdef PRELOADED_BL33_BASE
                 $(warning "PRELOADED_BL33_BASE and EL3_PAYLOAD_BASE are \
@@ -568,7 +545,6 @@
 $(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
 $(eval $(call assert_boolean,ENABLE_AMU))
 $(eval $(call assert_boolean,ENABLE_ASSERTIONS))
-$(eval $(call assert_boolean,ENABLE_BACKTRACE))
 $(eval $(call assert_boolean,ENABLE_MPAM_FOR_LOWER_ELS))
 $(eval $(call assert_boolean,ENABLE_PIE))
 $(eval $(call assert_boolean,ENABLE_PMF))
@@ -619,7 +595,6 @@
 $(eval $(call add_define,EL3_EXCEPTION_HANDLING))
 $(eval $(call add_define,ENABLE_AMU))
 $(eval $(call add_define,ENABLE_ASSERTIONS))
-$(eval $(call add_define,ENABLE_BACKTRACE))
 $(eval $(call add_define,ENABLE_MPAM_FOR_LOWER_ELS))
 $(eval $(call add_define,ENABLE_PIE))
 $(eval $(call add_define,ENABLE_PMF))
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 7777954..019a19e 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -8,6 +8,9 @@
 # Include SPM Makefile
 ################################################################################
 ifeq (${ENABLE_SPM},1)
+ifeq (${EL3_EXCEPTION_HANDLING},0)
+  $(error EL3_EXCEPTION_HANDLING must be 1 for SPM support)
+endif
 $(info Including SPM makefile)
 include services/std_svc/spm/spm.mk
 endif
diff --git a/common/backtrace.c b/common/backtrace/backtrace.c
similarity index 100%
rename from common/backtrace.c
rename to common/backtrace/backtrace.c
diff --git a/common/backtrace/backtrace.mk b/common/backtrace/backtrace.mk
new file mode 100644
index 0000000..e669331
--- /dev/null
+++ b/common/backtrace/backtrace.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Enable backtrace by default in DEBUG AArch64 builds
+ifeq (${ARCH},aarch32)
+        ENABLE_BACKTRACE 	:=	0
+else
+        ENABLE_BACKTRACE 	:=	${DEBUG}
+endif
+
+ifeq (${ENABLE_BACKTRACE},1)
+        # Force the compiler to include the frame pointer
+        TF_CFLAGS		+=	-fno-omit-frame-pointer
+
+        BL_COMMON_SOURCES	+=	common/backtrace/backtrace.c
+endif
+
+ifeq (${ARCH},aarch32)
+        ifeq (${ENABLE_BACKTRACE},1)
+                ifneq (${AARCH32_INSTRUCTION_SET},A32)
+                        $(error Error: AARCH32_INSTRUCTION_SET=A32 is needed \
+                        for ENABLE_BACKTRACE when compiling for AArch32.)
+                endif
+        endif
+endif
+
+$(eval $(call assert_boolean,ENABLE_BACKTRACE))
+$(eval $(call add_define,ENABLE_BACKTRACE))
diff --git a/docs/draw.io/ehf.svg b/docs/draw.io/ehf.svg
new file mode 100644
index 0000000..c98090f
--- /dev/null
+++ b/docs/draw.io/ehf.svg
@@ -0,0 +1,2 @@
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1002px" height="512px" viewBox="-0.5 -0.5 1002 512" content="&lt;mxfile userAgent=&quot;Mozilla/5.0 (X11; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0&quot; version=&quot;9.4.6&quot; editor=&quot;www.draw.io&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;5e4d6047-f7e8-a748-3faa-493b1a8db8b3&quot; name=&quot;Page-1&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><rect x="1" y="1" width="1000" height="510" fill="none" stroke="#000000" stroke-width="2" pointer-events="none"/><rect x="121.02" y="161" width="100" height="100" fill="#d4e1f5" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(122.5,189.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="95" height="41" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 95px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Interrupt Management Framework</div></div></foreignObject><text x="48" y="27" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Interrupt Management Framework</text></switch></g><path d="M 321 161.07 L 321 86 L 412.76 86" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 418.76 86 L 410.76 90 L 412.76 86 L 410.76 82 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 321.07 161 L 371.09 211 L 321.07 261 L 271.06 211 Z" fill="#d4e1f5" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(297.5,196.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="45" height="27" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 46px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div>Interrupt <br /></div><div>Type</div></div></div></foreignObject><text x="23" y="20" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><path d="M 221.02 211 L 262.83 211" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 268.83 211 L 260.83 215 L 262.83 211 L 260.83 207 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 21 211 L 112.76 211" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 118.76 211 L 110.76 215 L 112.76 211 L 110.76 207 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(50.5,195.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="41" height="11" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;background-color:#ffffff;">Interrupt</div></div></foreignObject><text x="21" y="11" fill="#000000" text-anchor="middle" font-size="11px" font-family="Helvetica">Interrupt</text></switch></g><rect x="421.1" y="61" width="75.02" height="50" fill="#dae8fc" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(449.5,79.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="17" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 18px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">NS</div></div></foreignObject><text x="9" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">NS</text></switch></g><rect x="421.1" y="186" width="75.02" height="50" fill="#dae8fc" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(440.5,204.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="34" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 35px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">S-EL1</div></div></foreignObject><text x="17" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">S-EL1</text></switch></g><path d="M 371.09 211 L 412.86 211" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 418.86 211 L 410.86 215 L 412.86 211 L 410.86 207 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="421.1" y="311" width="75.02" height="50" fill="#fff2cc" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(446.5,329.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="22" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 23px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">EL3</div></div></foreignObject><text x="11" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">EL3</text></switch></g><path d="M 321 260.93 L 321 336 L 412.76 336" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 418.76 336 L 410.76 340 L 412.76 336 L 410.76 332 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="542.38" y="61" width="100.02" height="175" fill="#ffffff" stroke="#000000" stroke-width="2" stroke-dasharray="6 6" pointer-events="none"/><g transform="translate(553.5,141.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="76" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 77px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">SPD handlers</div></div></foreignObject><text x="38" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">SPD handlers</text></switch></g><path d="M 496.12 86 L 534.14 86" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 540.14 86 L 532.14 90 L 534.14 86 L 532.14 82 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 496.12 211 L 534.14 211" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 540.14 211 L 532.14 215 L 534.14 211 L 532.14 207 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="542.38" y="348.5" width="100.02" height="112.5" fill="#fff2cc" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(543.5,383.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="95" height="41" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 95px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Exception Handling Framework</div></div></foreignObject><text x="48" y="27" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Exception Handling Framework</text></switch></g><path d="M 496.12 336 L 521 336 L 521 405 L 533.76 405" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 539.76 405 L 531.76 409 L 533.76 405 L 531.76 401 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 592 320.49 L 592 332 L 592 329 L 592 340.26" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 592 314.49 L 596 322.49 L 592 320.49 L 588 322.49 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 592 346.26 L 588 338.26 L 592 340.26 L 596 338.26 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="542.38" y="261" width="100.02" height="51.25" fill="#d5e8d4" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(565.5,279.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="51" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 52px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">GIC PMR</div></div></foreignObject><text x="26" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">GIC PMR</text></switch></g><rect x="722.42" y="411" width="100.02" height="50" fill="#fff2cc" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(758.5,429.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="25" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 26px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">RAS</div></div></foreignObject><text x="13" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">RAS</text></switch></g><rect x="722.42" y="361" width="100.02" height="50" fill="#fff2cc" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(758.5,379.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="26" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 27px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div>SPM</div></div></div></foreignObject><text x="13" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><rect x="722.42" y="311" width="100.02" height="50" fill="#fff2cc" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(736.5,329.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="69" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 70px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">SDEI Critical</div></div></foreignObject><text x="35" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">SDEI Critical</text></switch></g><rect x="722.42" y="261" width="100.02" height="50" fill="#fff2cc" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(735.5,279.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="71" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 72px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">SDEI Normal</div></div></foreignObject><text x="36" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">SDEI Normal</text></switch></g><rect x="722.42" y="61" width="100.02" height="200" fill="#f5f5f5" stroke="#666666" stroke-width="2" pointer-events="none"/><g transform="translate(737.5,154.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="67" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 68px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">NS priorities</div></div></foreignObject><text x="34" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">NS priorities</text></switch></g><path d="M 684.91 354.75 L 685 336 L 714.19 336" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 720.19 336 L 712.19 340 L 714.19 336 L 712.19 332 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 684.91 367.25 L 685 436 L 713.76 436" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 719.76 436 L 711.76 440 L 713.76 436 L 711.76 432 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><ellipse cx="685" cy="361" rx="6.25" ry="6.25" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="none"/><path d="M 642.4 405 L 662 405 L 662 361 L 679 361" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 691 361 L 709 361 L 709 386 L 713.76 386" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 719.76 386 L 711.76 390 L 713.76 386 L 711.76 382 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(826.5,60.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="27" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 28px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">0xFF</div></div></foreignObject><text x="14" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">0xFF</text></switch></g><g transform="translate(826.5,449.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="20" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 21px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div>0x0</div></div></div></foreignObject><text x="10" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><g transform="translate(642.5,312.5)rotate(-90,24,13.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="48" height="27" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 48px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div>Interrupt Priority</div></div></div></foreignObject><text x="24" y="20" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><path d="M 864.28 347.38 L 844.11 293.71" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 842 288.09 L 848.56 294.17 L 844.11 293.71 L 841.07 296.99 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 866 361.17 L 846.99 341.87" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 842.78 337.59 L 851.24 340.49 L 846.99 341.87 L 845.54 346.1 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 866 361.17 L 847.03 380.17" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 842.79 384.42 L 845.61 375.93 L 847.03 380.17 L 851.27 381.58 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 865.14 374.1 L 844.18 428.32" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 842.02 433.91 L 841.17 425.01 L 844.18 428.32 L 848.63 427.89 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 387.86 436 L 346.08 436" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 393.86 436 L 385.86 440 L 387.86 436 L 385.86 432 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="396.09" y="423.5" width="100.02" height="25" fill="#ffb570" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(419.5,429.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="52" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 53px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">EHF APIs</div></div></foreignObject><text x="26" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">EHF APIs</text></switch></g><path d="M 496.12 435.5 L 534.1 435.77" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 540.1 435.82 L 532.07 439.76 L 534.1 435.77 L 532.13 431.76 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(58.5,422.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="286" height="27" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 286px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Non-interrupt exceptions use EHF APIs to program GIC PMR to arbitrate priority levels</div></div></foreignObject><text x="143" y="20" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Non-interrupt exceptions use EHF APIs to program GIC PMR to arbitrate priority levels</text></switch></g><path d="M 940.24 461 L 940.24 69.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 940.24 63.24 L 944.24 71.24 L 940.24 69.24 L 936.24 71.24 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(871.5,254.5)rotate(-90,52,6)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="104" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 105px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Decreasing Priority</div></div></foreignObject><text x="52" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Decreasing Priority</text></switch></g><g transform="translate(820.5,348.5)rotate(-90,57.5,6)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="115" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 116px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Secure Priority levels</div></div></foreignObject><text x="58" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Secure Priority levels</text></switch></g><path d="M 685 355 L 685 286 L 713.76 286" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 719.76 286 L 711.76 290 L 713.76 286 L 711.76 282 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/></svg>
\ No newline at end of file
diff --git a/docs/draw.io/ehf.xml b/docs/draw.io/ehf.xml
new file mode 100644
index 0000000..db1f91d
--- /dev/null
+++ b/docs/draw.io/ehf.xml
@@ -0,0 +1 @@
+<mxfile userAgent="Mozilla/5.0 (X11; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0" version="9.4.6" editor="www.draw.io" type="device"><diagram id="5e4d6047-f7e8-a748-3faa-493b1a8db8b3" name="Page-1">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</diagram></mxfile>
\ No newline at end of file
diff --git a/docs/draw.io/ras.svg b/docs/draw.io/ras.svg
new file mode 100644
index 0000000..ff58198
--- /dev/null
+++ b/docs/draw.io/ras.svg
@@ -0,0 +1,2 @@
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1050px" height="392px" viewBox="-0.5 -0.5 1050 392" content="&lt;mxfile userAgent=&quot;Mozilla/5.0 (X11; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0&quot; version=&quot;9.4.6&quot; editor=&quot;www.draw.io&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;f2d74f7d-2b47-d0f0-3260-3a0b726db48c&quot; name=&quot;Page-1&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><rect x="408" y="30" width="240" height="360" fill="none" stroke="#000000" stroke-width="2" stroke-dasharray="6 6" pointer-events="none"/><path d="M 208 90 L 439.76 90" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 445.76 90 L 437.76 94 L 439.76 90 L 437.76 86 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 79.76 90 L 8 90" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 85.76 90 L 77.76 94 L 79.76 90 L 77.76 86 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(47.5,84.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="1" height="11" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;background-color:#ffffff;"><div><br /></div></div></div></foreignObject><text x="0" y="11" fill="#000000" text-anchor="middle" font-size="11px" font-family="Helvetica">&lt;div&gt;&lt;br&gt;&lt;/div&gt;</text></switch></g><rect x="88" y="70" width="120" height="40" fill="#d4e1f5" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(98.5,83.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="98" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 99px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">plat_ea_handler()</div></div></foreignObject><text x="49" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">plat_ea_handler()</text></switch></g><path d="M 608 90 L 669.76 90" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 675.76 90 L 667.76 94 L 669.76 90 L 667.76 86 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="448" y="70" width="160" height="40" fill="#d4e1f5" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(479.5,83.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="95" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 96px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">ras_ea_handler()</div></div></foreignObject><text x="48" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">ras_ea_handler()</text></switch></g><path d="M 608 329.5 L 669.76 329.5" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 675.76 329.5 L 667.76 333.5 L 669.76 329.5 L 667.76 325.5 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="448" y="309.5" width="160" height="40" fill="#ffe599" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(464.5,322.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="126" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 127px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">ras_interrupt_handler()</div></div></foreignObject><text x="63" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">ras_interrupt_handler()</text></switch></g><path d="M 79.64 326 L 48 326 L 7.88 326.25" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 85.64 326 L 77.64 330 L 79.64 326 L 77.64 322 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="87.88" y="270" width="100.02" height="112.5" fill="#ffe599" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(89.5,304.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="95" height="41" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 95px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Exception Handling Framework</div></div></foreignObject><text x="48" y="27" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Exception Handling Framework</text></switch></g><ellipse cx="227" cy="284" rx="6.25" ry="6.25" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="none"/><path d="M 187.9 326 L 208 326 L 208 284 L 221 284" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 368.95 362 L 388 362 L 388 330 L 439.76 330" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 445.76 330 L 437.76 334 L 439.76 330 L 437.76 326 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="268.92" y="338.5" width="100.02" height="50" fill="#ffe599" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(270.5,342.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="95" height="41" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 95px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div>RAS</div><div>priority level handler<br /></div></div></div></foreignObject><text x="48" y="27" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><path d="M 228 290 L 228 300 L 228 364 L 260.76 364" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 266.76 364 L 258.76 368 L 260.76 364 L 258.76 360 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 758 198.24 L 758 221.76" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="2 4" pointer-events="none"/><path d="M 758 192.24 L 762 200.24 L 758 198.24 L 754 200.24 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 758 227.76 L 754 219.76 L 758 221.76 L 762 219.76 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 758 150 L 758 118.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 758 112.24 L 762 120.24 L 758 118.24 L 754 120.24 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="678" y="150" width="160" height="40" fill="#ffe599" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(708.5,163.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="98" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 99px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">RAS error records</div></div></foreignObject><text x="49" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">RAS error records</text></switch></g><path d="M 758 270 L 758 290 L 758 301.76" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 758 307.76 L 754 299.76 L 758 301.76 L 762 299.76 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="678" y="230" width="160" height="40" fill="#ffe599" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(702.5,243.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="110" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 111px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">RAS interrupts array</div></div></foreignObject><text x="55" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">RAS interrupts array</text></switch></g><g transform="translate(485.5,3.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="85" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 86px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">RAS framework</div></div></foreignObject><text x="43" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">RAS framework</text></switch></g><path d="M 838 90 L 879.76 90" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 885.76 90 L 877.76 94 L 879.76 90 L 877.76 86 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="678" y="70" width="160" height="40" fill="#d4e1f5" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(710.5,83.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="93" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 94px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><i>Iterate and probe</i></div></div></foreignObject><text x="47" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">&lt;i&gt;Iterate and probe&lt;/i&gt;</text></switch></g><rect x="888" y="70" width="160" height="40" fill="none" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(931.5,83.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="72" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 73px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Error handler</div></div></foreignObject><text x="36" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Error handler</text></switch></g><path d="M 838 329.5 L 879.76 329.5" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 885.76 329.5 L 877.76 333.5 L 879.76 329.5 L 877.76 325.5 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="678" y="309.5" width="160" height="40" fill="#ffe599" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(708.5,322.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="97" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 98px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><i>Bisect and lookup</i></div></div></foreignObject><text x="49" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">&lt;i&gt;Bisect and lookup&lt;/i&gt;</text></switch></g><rect x="888" y="309.5" width="160" height="40" fill="none" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(931.5,322.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="72" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 73px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Error handler</div></div></foreignObject><text x="36" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Error handler</text></switch></g><path d="M 608 170 L 669.76 170" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 675.76 170 L 667.76 174 L 669.76 170 L 667.76 166 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><rect x="448" y="150" width="160" height="40" fill="#d4e1f5" stroke="#000000" stroke-width="2" pointer-events="none"/><g transform="translate(492.5,163.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="69" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 70px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">SER helpers</div></div></foreignObject><text x="35" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">SER helpers</text></switch></g><rect x="268.92" y="288" width="100.02" height="50" fill="none" stroke="#000000" stroke-width="2" stroke-dasharray="6 6" pointer-events="none"/><rect x="268.92" y="238" width="100.02" height="50" fill="none" stroke="#000000" stroke-width="2" stroke-dasharray="6 6" pointer-events="none"/><g transform="translate(24.5,56.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="46" height="27" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 46px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">External Abort</div></div></foreignObject><text x="23" y="20" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">External Abort</text></switch></g><g transform="translate(21.5,307.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="45" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 46px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div>Interrupt</div></div></div></foreignObject><text x="23" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><g transform="translate(204.5,246.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="46" height="27" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 46px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Interrupt Priority</div></div></foreignObject><text x="23" y="20" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">Interrupt Priority</text></switch></g><path d="M 138 110 L 138 150 L 138 261.76" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="none"/><path d="M 138 267.76 L 134 259.76 L 138 261.76 L 142 259.76 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(140.5,176.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="38" height="27" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 38px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">EHF APIs</div></div></foreignObject><text x="19" y="20" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">EHF APIs</text></switch></g></svg>
\ No newline at end of file
diff --git a/docs/draw.io/ras.xml b/docs/draw.io/ras.xml
new file mode 100644
index 0000000..ce6df3a
--- /dev/null
+++ b/docs/draw.io/ras.xml
@@ -0,0 +1 @@
+<mxfile userAgent="Mozilla/5.0 (X11; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0" version="9.4.6" editor="www.draw.io" type="device"><diagram id="f2d74f7d-2b47-d0f0-3260-3a0b726db48c" name="Page-1">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</diagram></mxfile>
\ No newline at end of file
diff --git a/docs/exception-handling.rst b/docs/exception-handling.rst
new file mode 100644
index 0000000..e7cb09c
--- /dev/null
+++ b/docs/exception-handling.rst
@@ -0,0 +1,636 @@
+Exception Handling Framework in Trusted Firmware-A
+==================================================
+
+
+.. section-numbering::
+    :suffix: .
+
+.. contents::
+    :depth: 2
+
+.. |EHF| replace:: Exception Handling Framework
+.. |TF-A| replace:: Trusted Firmware-A
+
+This document describes various aspects of handling exceptions by Runtime
+Firmware (BL31) that are targeted at EL3, other than SMCs. The |EHF| takes care
+of the following exceptions when targeted at EL3:
+
+-  Interrupts
+-  Synchronous External Aborts
+-  Asynchronous External Aborts
+
+|TF-A|'s handling of synchronous ``SMC`` exceptions raised from lower ELs is
+described in the `Firmware Design document`__. However, the |EHF| changes the
+semantics of `interrupt handling`__ and `synchronous exceptions`__ other than
+SMCs.
+
+.. __: firmware-design.rst#handling-an-smc
+.. __: `Interrupt handling`_
+.. __: `Effect on SMC calls`_
+
+The |EHF| is selected by setting the build option ``EL3_EXCEPTION_HANDLING`` to
+``1``, and is only available for AArch64 systems.
+
+Introduction
+------------
+
+Through various control bits in the ``SCR_EL3`` register, the Arm architecture
+allows for asynchronous exceptions to be routed to EL3. As described in the
+`Interrupt Framework Design`_ document, depending on the chosen interrupt
+routing model, TF-A appropriately sets the ``FIQ`` and ``IRQ`` bits of
+``SCR_EL3`` register to effect this routing. For most use cases, other than for
+the purpose of facilitating context switch between Normal and Secure worlds,
+FIQs and IRQs routed to EL3 are not required to be handled in EL3.
+
+However, the evolving system and standards landscape demands that various
+exceptions are targeted at and handled in EL3. For instance:
+
+-  Starting with ARMv8.2 architecture extension, many RAS features have been
+   introduced to the Arm architecture. With RAS features implemented, various
+   components of the system may use one of the asynchronous exceptions to signal
+   error conditions to PEs. These error conditions are of critical nature, and
+   it's imperative that corrective or remedial actions are taken at the earliest
+   opportunity. Therefore, a *Firmware-first Handling* approach is generally
+   followed in response to RAS events in the system.
+
+-  The Arm `SDEI specification`_ defines interfaces through which Normal world
+   interacts with the Runtime Firmware in order to request notification of
+   system events. The SDEI specification requires that these events are notified
+   even when the Normal world executes with the exceptions masked. This too
+   implies that firmware-first handling is required, where the events are first
+   received by the EL3 firmware, and then dispatched to Normal world through
+   purely software mechanism.
+
+For |TF-A|, firmware-first handling means that asynchronous exceptions are
+suitably routed to EL3, and the Runtime Firmware (BL31) is extended to include
+software components that are capable of handling those exceptions that target
+EL3. These components—referred to as *dispatchers* [#spd]_ in general—may
+choose to:
+
+.. _delegation-use-cases:
+
+-  Receive and handle exceptions entirely in EL3, meaning the exceptions
+   handling terminates in EL3.
+
+-  Receive exceptions, but handle part of the exception in EL3, and delegate the
+   rest of the handling to a dedicated software stack running at lower Secure
+   ELs. In this scheme, the handling spans various secure ELs.
+
+-  Receive exceptions, but handle part of the exception in EL3, and delegate
+   processing of the error to dedicated software stack running at lower secure
+   ELs (as above); additionally, the Normal world may also be required to
+   participate in the handling, or be notified of such events (for example, as
+   an SDEI event). In this scheme, exception handling potentially and maximally
+   spans all ELs in both Secure and Normal worlds.
+
+On any given system, all of the above handling models may be employed
+independently depending on platform choice and the nature of the exception
+received.
+
+.. [#spd] Not to be confused with `Secure Payload Dispatcher`__, which is an
+   EL3 component that operates in EL3 on behalf of Secure OS.
+
+.. __: firmware-design.rst#secure-el1-payloads-and-dispatchers
+
+The role of Exception Handling Framework
+----------------------------------------
+
+Corollary to the use cases cited above, the primary role of the |EHF| is to
+facilitate firmware-first handling of exceptions on Arm systems. The |EHF| thus
+enables multiple exception dispatchers in runtime firmware to co-exist, register
+for, and handle exceptions targeted at EL3. This section outlines the basics,
+and the rest of this document expands the various aspects of the |EHF|.
+
+In order to arbitrate exception handling among dispatchers, the |EHF| operation
+is based on a priority scheme. This priority scheme is closely tied to how the
+Arm GIC architecture defines it, although it's applied to non-interrupt
+exceptions too (SErrors, for example).
+
+The platform is required to `partition`__ the Secure priority space into
+priority levels as applicable for the Secure software stack. It then assigns the
+dispatchers to one or more priority levels. The dispatchers then register
+handlers for the priority levels at runtime. A dispatcher can register handlers
+for more than one priority level.
+
+.. __: `Partitioning priority levels`_
+
+
+.. _ehf-figure:
+
+.. image:: draw.io/ehf.svg
+
+A priority level is *active* when a handler at that priority level is currently
+executing in EL3, or has delegated the execution to a lower EL. For interrupts,
+this is implicit when an interrupt is targeted and acknowledged at EL3, and the
+priority of the acknowledged interrupt is used to match its registered handler.
+The priority level is likewise implicitly deactivated when the interrupt
+handling concludes by EOIing the interrupt.
+
+Non-interrupt exceptions (SErrors, for example) don't have a notion of priority.
+In order for the priority arbitration to work, the |EHF| provides APIs in order
+for these non-interrupt exceptions to assume a priority, and to interwork with
+interrupts. Dispatchers handling such exceptions must therefore explicitly
+activate and deactivate the respective priority level as and when they're
+handled or delegated.
+
+Because priority activation and deactivation for interrupt handling is implicit
+and involves GIC priority masking, it's impossible for a lower priority
+interrupt to preempt a higher priority one. By extension, this means that a
+lower priority dispatcher cannot preempt a higher-priority one. Priority
+activation and deactivation for non-interrupt exceptions, however, has to be
+explicit. The |EHF| therefore disallows for lower priority level to be activated
+whilst a higher priority level is active, and would result in a panic.
+Likewise, a panic would result if it's attempted to deactivate a lower priority
+level when a higher priority level is active.
+
+In essence, priority level activation and deactivation conceptually works like a
+stack—priority levels stack up in strictly increasing fashion, and need to be
+unstacked in strictly the reverse order. For interrupts, the GIC ensures this is
+the case; for non-interrupts, the |EHF| monitors and asserts this. See
+`Transition of priority levels`_.
+
+Interrupt handling
+------------------
+
+The |EHF| is a client of *Interrupt Management Framework*, and registers the
+top-level handler for interrupts that target EL3, as described in the `Interrupt
+Framework Design`_ document. This has the following implications.
+
+-  On GICv3 systems, when executing in S-EL1, pending Non-secure interrupts of
+   sufficient priority are signalled as FIQs, and therefore will be routed to
+   EL3. As a result, S-EL1 software cannot expect to handle Non-secure
+   interrupts at S-EL1. Essentially, this deprecates the routing mode described
+   as `CSS=0, TEL3=0`__.
+
+   .. __: interrupt-framework-design.rst#el3-interrupts
+
+   In order for S-EL1 software to handle Non-secure interrupts while having
+   |EHF| enabled, the dispatcher must adopt a model where Non-secure interrupts
+   are received at EL3, but are then `synchronously`__ handled over to S-EL1.
+
+   .. __: interrupt-framework-design.rst#secure-payload
+
+-  On GICv2 systems, it's required that the build option ``GICV2_G0_FOR_EL3`` is
+   set to ``1`` so that *Group 0* interrupts target EL3.
+
+-  While executing in Secure world, |EHF| sets GIC Priority Mask Register to the
+   lowest Secure priority. This means that no Non-secure interrupts can preempt
+   Secure execution. See `Effect on SMC calls`_ for more details.
+
+As mentioned above, with |EHF|, the platform is required to partition *Group 0*
+interrupts into distinct priority levels. A dispatcher that chooses to receive
+interrupts can then *own* one or more priority levels, and register interrupt
+handlers for them. A given priority level can be assigned to only one handler. A
+dispatcher may register more than one priority level.
+
+Dispatchers are assigned interrupt priority levels in two steps:
+
+Partitioning priority levels
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Interrupts are associated to dispatchers by way of grouping and assigning
+interrupts to a priority level. In other words, all interrupts that are to
+target a particular dispatcher should fall in a particular priority level. For
+priority assignment:
+
+-  Of the 8 bits of priority that Arm GIC architecture permits, bit 7 must be 0
+   (secure space).
+
+-  Depending on the number of dispatchers to support, the platform must choose
+   to use the top *n* of the 7 remaining bits to identify and assign interrupts
+   to individual dispatchers. Choosing *n* bits supports up to 2\ :sup:`n`
+   distinct dispatchers. For example, by choosing 2 additional bits (i.e., bits
+   6 and 5), the platform can partition into 4 secure priority ranges: ``0x0``,
+   ``0x20``, ``0x40``, and ``0x60``. See `Interrupt handling example`_.
+
+Note:
+
+   The Arm GIC architecture requires that a GIC implementation that supports two
+   security states must implement at least 32 priority levels; i.e., at least 5
+   upper bits of the 8 bits are writeable. In the scheme described above, when
+   choosing *n* bits for priority range assignment, the platform must ensure
+   that at least ``n+1`` top bits of GIC priority are writeable.
+
+The priority thus assigned to an interrupt is also used to determine the
+priority of delegated execution in lower ELs. Delegated execution in lower EL is
+associated with a priority level chosen with ``ehf_activate_priority()`` API
+(described `later`__). The chosen priority level also determines the interrupts
+masked while executing in a lower EL, therefore controls preemption of delegated
+execution.
+
+.. __: `ehf-apis`_
+
+The platform expresses the chosen priority levels by declaring an array of
+priority level descriptors. Each entry in the array is of type
+``ehf_pri_desc_t``, and declares a priority level, and shall be populated by the
+``EHF_PRI_DESC()`` macro.
+
+Note:
+
+   The macro ``EHF_PRI_DESC()`` installs the descriptors in the array at a
+   computed index, and not necessarily where the macro is placed in the array.
+   The size of the array might therefore be larger than what it appears to be.
+   The ``ARRAY_SIZE()`` macro therefore should be used to determine the size of
+   array.
+
+Finally, this array of descriptors is exposed to |EHF| via. the
+``EHF_REGISTER_PRIORITIES()`` macro.
+
+Refer to the `Interrupt handling example`_ for usage. See also: `Interrupt
+Prioritisation Considerations`_.
+
+Programming priority
+~~~~~~~~~~~~~~~~~~~~
+
+The text in `Partitioning priority levels`_ only describes how the platform
+expresses the required levels of priority. It however doesn't choose interrupts
+nor program the required priority in GIC.
+
+The `Firmware Design guide`__ explains methods for configuring secure
+interrupts. |EHF| requires the platform to enumerate interrupt properties (as
+opposed to just numbers) of Secure interrupts. The priority of secure interrupts
+must match that as determined in the `Partitioning priority levels`_ section above.
+
+.. __: firmware-design.rst#configuring-secure-interrupts
+
+See `Limitations`_, and also refer to `Interrupt handling example`_ for
+illustration.
+
+Registering handler
+-------------------
+
+Dispatchers register handlers for their priority levels through the following
+API:
+
+.. code:: c
+
+   int ehf_register_priority_handler(int pri, ehf_handler_t handler)
+
+The API takes two arguments:
+
+-  The priority level for which the handler is being registered;
+
+-  The handler to be registered. The handler must be aligned to 4 bytes.
+
+If a dispatcher owns more than one priority levels, it has to call the API for
+each of them.
+
+The API will succeed, and return ``0``, only if:
+
+-  There exists a descriptor with the priority level requested.
+
+-  There are no handlers already registered by a previous call to the API.
+
+Otherwise, the API returns ``-1``.
+
+The interrupt handler should have the following signature:
+
+.. code:: c
+
+   typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle,
+                   void *cookie);
+
+The parameters are as obtained from the top-level `EL3 interrupt handler`__.
+
+.. __: interrupt-framework-design.rst#el3-runtime-firmware
+
+The `SDEI dispatcher`__, for example, expects the platform to allocate two
+different priority levels—``PLAT_SDEI_CRITICAL_PRI``, and
+``PLAT_SDEI_NORMAL_PRI``—and registers the same handler to handle both levels.
+
+.. __: sdei.rst
+
+Interrupt handling example
+--------------------------
+
+The following annotated snippet demonstrates how a platform might choose to
+assign interrupts to fictitious dispatchers:
+
+.. code:: c
+
+   #include <exception_mgmt.h>
+   #include <gic_common.h>
+   #include <interrupt_props.h>
+
+   ...
+
+   /*
+    * This platform uses 2 bits for interrupt association. In total, 3 upper
+    * bits are in use.
+    *
+    *  7 6 5   3      0
+    * .-.-.-.----------.
+    * |0|b|b|  ..0..   |
+    * '-'-'-'----------'
+    */
+   #define PLAT_PRI_BITS        2
+
+   /* Priorities for individual dispatchers */
+   #define DISP0_PRIO           0x00 /* Not used */
+   #define DISP1_PRIO           0x20
+   #define DISP2_PRIO           0x40
+   #define DISP3_PRIO           0x60
+
+   /* Install priority level descriptors for each dispatcher */
+   ehf_pri_desc_t plat_exceptions[] = {
+        EHF_PRI_DESC(PLAT_PRI_BITS, DISP1_PRIO),
+        EHF_PRI_DESC(PLAT_PRI_BITS, DISP2_PRIO),
+        EHF_PRI_DESC(PLAT_PRI_BITS, DISP3_PRIO),
+   };
+
+   /* Expose priority descriptors to Exception Handling Framework */
+   EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions),
+        PLAT_PRI_BITS);
+
+   ...
+
+   /* List interrupt properties for GIC driver. All interrupts target EL3 */
+   const interrupt_prop_t plat_interrupts[] = {
+        /* Dispatcher 1 owns interrupts d1_0 and d1_1, so assigns priority DISP1_PRIO */
+        INTR_PROP_DESC(d1_0, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+        INTR_PROP_DESC(d1_1, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+
+        /* Dispatcher 2 owns interrupts d2_0 and d2_1, so assigns priority DISP2_PRIO */
+        INTR_PROP_DESC(d2_0, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+        INTR_PROP_DESC(d2_1, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+
+        /* Dispatcher 3 owns interrupts d3_0 and d3_1, so assigns priority DISP3_PRIO */
+        INTR_PROP_DESC(d3_0, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+        INTR_PROP_DESC(d3_1, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+   };
+
+   ...
+
+   /* Dispatcher 1 registers its handler */
+   ehf_register_priority_handler(DISP1_PRIO, disp1_handler);
+
+   /* Dispatcher 2 registers its handler */
+   ehf_register_priority_handler(DISP2_PRIO, disp2_handler);
+
+   /* Dispatcher 3 registers its handler */
+   ehf_register_priority_handler(DISP3_PRIO, disp3_handler);
+
+   ...
+
+See also the `Build-time flow`_ and the `Run-time flow`_.
+
+Activating and Deactivating priorities
+--------------------------------------
+
+A priority level is said to be *active* when an exception of that priority is
+being handled: for interrupts, this is implied when the interrupt is
+acknowledged; for non-interrupt exceptions, viz. SErrors or `SDEI explicit
+dispatches`__, this has to be done via. calling ``ehf_activate_priority()``. See
+`Run-time flow`_.
+
+.. __: sdei.rst#explicit-dispatch-of-events
+
+Conversely, when the dispatcher has reached a logical resolution for the cause
+of the exception, the corresponding priority level ought to be deactivated. As
+above, for interrupts, this is implied when the interrupt is EOId in the GIC;
+for other exceptions, this has to be done via. calling
+``ehf_deactivate_priority()``.
+
+Thanks to `different provisions`__ for exception delegation, there are
+potentially more than one work flow for deactivation:
+
+.. __: `delegation-use-cases`_
+
+.. _deactivation workflows:
+
+-  The dispatcher has addressed the cause of the exception, and decided to take
+   no further action. In this case, the dispatcher's handler deactivates the
+   priority level before returning to the |EHF|. Runtime firmware, upon exit
+   through an ``ERET``, resumes execution before the interrupt occurred.
+
+-  The dispatcher has to delegate the execution to lower ELs, and the cause of
+   the exception can be considered resolved only when the lower EL returns
+   signals complete (via. an ``SMC``) at a future point in time. The following
+   sequence ensues:
+
+   #. The dispatcher calls ``setjmp()`` to setup a jump point, and arranges to
+      enter a lower EL upon the next ``ERET``.
+
+   #. Through the ensuing ``ERET`` from runtime firmware, execution is delegated
+      to a lower EL.
+
+   #. The lower EL completes its execution, and signals completion via. an
+      ``SMC``.
+
+   #. The ``SMC`` is handled by the same dispatcher that handled the exception
+      previously. Noticing the conclusion of exception handling, the dispatcher
+      does ``longjmp()`` to resume beyond the previous jump point.
+
+As mentioned above, the |EHF| provides the following APIs for activating and
+deactivating interrupt:
+
+.. _ehf-apis:
+
+-  ``ehf_activate_priority()`` activates the supplied priority level, but only
+   if the current active priority is higher than the given one; otherwise
+   panics. Also, to prevent interruption by physical interrupts of lower
+   priority, the |EHF| programs the *Priority Mask Register* corresponding to
+   the PE to the priority being activated.  Dispatchers typically only need to
+   call this when handling exceptions other than interrupts, and it needs to
+   delegate execution to a lower EL at a desired priority level.
+
+-  ``ehf_deactivate_priority()`` deactivates a given priority, but only if the
+   current active priority is equal to the given one; otherwise panics. |EHF|
+   also restores the *Priority Mask Register* corresponding to the PE to the
+   priority before the call to ``ehf_activate_priority()``. Dispatchers
+   typically only need to call this after handling exceptions other than
+   interrupts.
+
+The calling of APIs are subject to allowed `transitions`__. See also the
+`Run-time flow`_.
+
+.. __: `Transition of priority levels`_
+
+Transition of priority levels
+-----------------------------
+
+The |EHF| APIs ``ehf_activate_priority()`` and ``ehf_deactivate_priority()`` can
+be called to transition the current priority level on a PE. A given sequence of
+calls to these APIs are subject to the following conditions:
+
+-  For activation, the |EHF| only allows for the priority to increase (i.e.
+   numeric value decreases);
+
+-  For deactivation, the |EHF| only allows for the priority to decrease (i.e.
+   numeric value increases). Additionally, the priority being deactivated is
+   required to be the current priority.
+
+If these are violated, a panic will result.
+
+Effect on SMC calls
+-------------------
+
+In general, Secure execution is regarded as more important than Non-secure
+execution. As discussed elsewhere in this document, EL3 execution, and any
+delegated execution thereafter, has the effect of raising GIC's priority
+mask—either implicitly by acknowledging Secure interrupts, or when dispatchers
+call ``ehf_activate_priority()``. As a result, Non-secure interrupts cannot
+preempt any Secure execution.
+
+SMCs from Non-secure world are synchronous exceptions, and are mechanisms for
+Non-secure world to request Secure services. They're broadly classified as
+*Fast* or *Yielding* (see `SMCCC`__).
+
+.. __: `http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html`
+
+-  *Fast* SMCs are atomic from the caller's point of view. I.e., they return
+   to the caller only when the Secure world has finished serving the request.
+   Any Non-secure interrupts that become pending meanwhile cannot preempt Secure
+   execution.
+
+-  *Yielding* SMCs carry the semantics of a preemptible, lower-priority request.
+   A pending Non-secure interrupt can preempt Secure execution handling a
+   Yielding SMC. I.e., the caller might observe a Yielding SMC returning when
+   either:
+
+   #. Secure world completes the request, and the caller would find ``SMC_OK``
+      as the return code.
+
+   #. A Non-secure interrupt preempts Secure execution. Non-secure interrupt is
+      handled, and Non-secure execution resumes after ``SMC`` instruction.
+
+   The dispatcher handling a Yielding SMC must provide a different return code
+   to the Non-secure caller to distinguish the latter case. This return code,
+   however, is not standardised (unlike ``SMC_UNKNOWN`` or ``SMC_OK``, for
+   example), so will vary across dispatchers that handle the request.
+
+For the latter case above, dispatchers before |EHF| expect Non-secure interrupts
+to be taken to S-EL1 [#irq]_, so would get a chance to populate the designated
+preempted error code before yielding to Non-secure world.
+
+The introduction of |EHF| changes the behaviour as described in `Interrupt
+handling`_.
+
+When |EHF| is enabled, in order to allow Non-secure interrupts to preempt
+Yielding SMC handling, the dispatcher must call ``ehf_allow_ns_preemption()``
+API. The API takes one argument, the error code to be returned to the Non-secure
+world upon getting preempted.
+
+.. [#irq] In case of GICv2, Non-secure interrupts while in S-EL1 were signalled
+          as IRQs, and in case of GICv3, FIQs.
+
+Build-time flow
+---------------
+
+Please refer to the `figure`__ above.
+
+.. __: `ehf-figure`_
+
+The build-time flow involves the following steps:
+
+#. Platform assigns priorities by installing priority level descriptors for
+   individual dispatchers, as described in `Partitioning priority levels`_.
+
+#. Platform provides interrupt properties to GIC driver, as described in
+   `Programming priority`_.
+
+#. Dispatcher calling ``ehf_register_priority_handler()`` to register an
+   interrupt handler.
+
+Also refer to the `Interrupt handling example`_.
+
+Run-time flow
+-------------
+
+.. _interrupt-flow:
+
+The following is an example flow for interrupts:
+
+#. The GIC driver, during initialization, iterates through the platform-supplied
+   interrupt properties (see `Programming priority`_), and configures the
+   interrupts. This programs the appropriate priority and group (Group 0) on
+   interrupts belonging to different dispatchers.
+
+#. The |EHF|, during its initialisation, registers a top-level interrupt handler
+   with the `Interrupt Management Framework`__ for EL3 interrupts. This also
+   results in setting the routing bits in ``SCR_EL3``.
+
+   .. __: interrupt-framework-design.rst#el3-runtime-firmware
+
+#. When an interrupt belonging to a dispatcher fires, GIC raises an EL3/Group 0
+   interrupt, and is taken to EL3.
+
+#. The top-level EL3 interrupt handler executes. The handler acknowledges the
+   interrupt, reads its *Running Priority*, and from that, determines the
+   dispatcher handler.
+
+#. The |EHF| programs the *Priority Mask Register* of the PE to the priority of
+   the interrupt received.
+
+#. The |EHF| marks that priority level *active*, and jumps to the dispatcher
+   handler.
+
+#. Once the dispatcher handler finishes its job, it has to immediately
+   *deactivate* the priority level before returning to the |EHF|. See
+   `deactivation workflows`_.
+
+.. _non-interrupt-flow:
+
+The following is an example flow for exceptions that targets EL3 other than
+interrupt:
+
+#. The platform provides handlers for the specific kind of exception.
+
+#. The exception arrives, and the corresponding handler is executed.
+
+#. The handler calls ``ehf_activate_priority()`` to activate the required
+   priority level. This also has the effect of raising GIC priority mask, thus
+   preventing interrupts of lower priority from preempting the handling. The
+   handler may choose to do the handling entirely in EL3 or delegate to a lower
+   EL.
+
+#. Once exception handling concludes, the handler calls
+   ``ehf_deactivate_priority()`` to deactivate the priority level activated
+   earlier. This also has the effect of lowering GIC priority mask to what it
+   was before.
+
+Interrupt Prioritisation Considerations
+---------------------------------------
+
+The GIC priority scheme, by design, prioritises Secure interrupts over Normal
+world ones. The platform further assigns relative priorities amongst Secure
+dispatchers through |EHF|.
+
+As mentioned in `Partitioning priority levels`_, interrupts targeting distinct
+dispatchers fall in distinct priority levels. Because they're routed via. the
+GIC, interrupt delivery to the PE is subject to GIC prioritisation rules. In
+particular, when an interrupt is being handled by the PE (i.e., the interrupt is
+in *Active* state), only interrupts of higher priority are signalled to the PE,
+even if interrupts of same or lower priority are pending. This has the side
+effect of one dispatcher being starved of interrupts by virtue of another
+dispatcher handling its (higher priority) interrupts.
+
+The |EHF| doesn't enforce a particular prioritisation policy, but the platform
+should carefully consider the assignment of priorities to dispatchers integrated
+into runtime firmware. The platform should sensibly delineate priority to
+various dispatchers according to their nature. In particular, dispatchers of
+critical nature (RAS, for example) should be assigned higher priority than
+others (SDEI, for example); and within SDEI, Critical priority SDEI should be
+assigned higher priority than Normal ones.
+
+Limitations
+-----------
+
+The |EHF| has the following limitations:
+
+-  Although there could be up to 128 Secure dispatchers supported by the GIC
+   priority scheme, the size of descriptor array exposed with
+   ``EHF_REGISTER_PRIORITIES()`` macro is currently limited to 32. This serves most
+   expected use cases. This may be expanded in the future, should use cases
+   demand so.
+
+-  The platform must ensure that the priority assigned to the dispatcher in the
+   exception descriptor and the programmed priority of interrupts handled by the
+   dispatcher match. The |EHF| cannot verify that this has been followed.
+
+----
+
+*Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _Interrupt Framework Design: interrupt-framework-design.rst
+.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index 051b92b..21a4d53 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -981,6 +981,11 @@
 On return from the handler the result registers are populated in X0-X3 before
 restoring the stack and CPU state and returning from the original SMC.
 
+Exception Handling Framework
+----------------------------
+
+Please refer to the `Exception Handling Framework`_ document.
+
 Power State Coordination Interface
 ----------------------------------
 
@@ -2641,5 +2646,6 @@
 .. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
 .. _TF-A Interrupt Management Design guide: ./interrupt-framework-design.rst
 .. _Xlat_tables design: xlat-tables-lib-v2-design.rst
+.. _Exception Handling Framework: exception-handling.rst
 
 .. |Image 1| image:: diagrams/rt-svc-descs-layout.png?raw=true
diff --git a/docs/interrupt-framework-design.rst b/docs/interrupt-framework-design.rst
index b5c7d21..4247f1f 100644
--- a/docs/interrupt-framework-design.rst
+++ b/docs/interrupt-framework-design.rst
@@ -153,7 +153,10 @@
 
    However, when ``EL3_EXCEPTION_HANDLING`` is ``1``, this routing model is
    invalid as EL3 interrupts are unconditionally routed to EL3, and EL3
-   interrupts will always preempt Secure EL1/EL0 execution.
+   interrupts will always preempt Secure EL1/EL0 execution. See `exception
+   handling`__ documentation.
+
+   .. __: exception-handling.rst#interrupt-handling
 
 #. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in
    Secure-EL1/Secure-EL0. This is a valid routing model as secure software
diff --git a/docs/plat/rpi3.rst b/docs/plat/rpi3.rst
index db47564..a22bfc6 100644
--- a/docs/plat/rpi3.rst
+++ b/docs/plat/rpi3.rst
@@ -231,6 +231,44 @@
   ``RPI3_DIRECT_LINUX_BOOT=1``. This option allows to specify the location of a
   DTB in memory.
 
+- ``RPI3_RUNTIME_UART``: Indicates whether the UART should be used at runtime
+  or disabled. ``-1`` (default) disables the runtime UART. Any other value
+  enables the default UART (currently UART1) for runtime messages.
+
+- ``RPI3_USE_UEFI_MAP``: Set to 1 to build ATF with the altername memory
+  mapping required for an UEFI firmware payload. These changes are needed
+  to be able to run Windows on ARM64. This option, which is disabled by
+  default, results in the following memory mappings:
+
+::
+
+    0x00000000 +-----------------+
+               |       ROM       | BL1
+    0x00010000 +-----------------+
+               |       DTB       | (Loaded by the VideoCore)
+    0x00020000 +-----------------+
+               |       FIP       |
+    0x00030000 +-----------------+
+               |                 |
+               |  UEFI PAYLOAD   |
+               |                 |
+    0x00200000 +-----------------+
+               |   Secure SRAM   | BL2, BL31
+    0x00300000 +-----------------+
+               |   Secure DRAM   | BL32 (Secure payload)
+    0x00400000 +-----------------+
+               |                 |
+               |                 |
+               | Non-secure DRAM | BL33
+               |                 |
+               |                 |
+    0x01000000 +-----------------+
+               |                 |
+               |       ...       |
+               |                 |
+    0x3F000000 +-----------------+
+               |       I/O       |
+
 - ``BL32``: This port can load and run OP-TEE. The OP-TEE image is optional.
   Please use the code from `here <https://github.com/OP-TEE/optee_os>`__.
   Build the Trusted Firmware with option ``BL32=tee-header_v2.bin
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index bef4af6..4f1638a 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2646,8 +2646,8 @@
 If you're trying to debug crashes in BL1, you can call the console_xx_core_flush
 function exported by some console drivers from here.
 
-Extternal Abort handling and RAS Support
-----------------------------------------
+External Abort handling and RAS Support
+---------------------------------------
 
 Function : plat_ea_handler
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/ras.rst b/docs/ras.rst
new file mode 100644
index 0000000..4c82022
--- /dev/null
+++ b/docs/ras.rst
@@ -0,0 +1,258 @@
+RAS support in Trusted Firmware-A
+=================================
+
+.. section-numbering::
+    :suffix: .
+
+.. contents::
+    :depth: 2
+
+.. |EHF| replace:: Exception Handling Framework
+.. |TF-A| replace:: Trusted Firmware-A
+
+This document describes |TF-A| support for Arm Reliability, Availability, and
+Serviceability (RAS) extensions. RAS is a mandatory extension for Armv8.2 and
+later CPUs, and also an optional extension to the base Armv8.0 architecture.
+
+In conjunction with the |EHF|, support for RAS extension enables firmware-first
+paradigm for handling platform errors, in which exceptions resulting from
+errors—viz. Synchronous External Abort (SEA), Asynchronous External Abort
+(signalled as SErrors), Fault Handling and Error Recovery interrupts are routed
+to and handled in EL3. The |EHF| document mentions various `error handling
+use-cases`__.
+
+.. __: exception-handling.rst#delegation-use-cases
+
+For the description of Arm RAS extensions, Standard Error Records, and the
+precise definition of RAS terminology, please refer to the Arm Architecture
+Reference Manual. The rest of this document assumes familiarity with
+architecture and terminology.
+
+Overview
+--------
+
+As mentioned above, the RAS support in |TF-A| enables routing to and handling of
+exceptions resulting from platform errors in EL3. It allows the platform to
+define an External Abort handler, and to register RAS nodes and interrupts. RAS
+framework also provides `helpers`__ for accessing Standard Error Records as
+introduced by the RAS extensions.
+
+.. __: `Standard Error Record helpers`_
+
+The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run
+time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST`` must also
+be set ``1``.
+
+.. _ras-figure:
+
+.. image:: draw.io/ras.svg
+
+See more on `Engaging the RAS framework`_.
+
+Platform APIs
+-------------
+
+The RAS framework allows the platform to define handlers for External Abort,
+Uncontainable Errors, Double Fault, and errors rising from EL3 execution. Please
+refer to the porting guide for the `RAS platform API descriptions`__.
+
+.. __: porting-guide.rst#external-abort-handling-and-ras-support
+
+Registering RAS error records
+-----------------------------
+
+RAS nodes are components in the system capable of signalling errors to PEs
+through one one of the notification mechanisms—SEAs, SErrors, or interrupts. RAS
+nodes contain one or more error records, which are registers through which the
+nodes advertise various properties of the signalled error. Arm recommends that
+error records are implemented in the Standard Error Record format. The RAS
+architecture allows for error records to be accessible via. system or
+memory-mapped registers.
+
+The platform should enumerate the error records providing for each of them:
+
+-  A handler to probe error records for errors;
+-  When the probing identifies an error, a handler to handle it;
+-  For memory-mapped error record, its base address and size in KB; for a system
+   register-accessed record, the start index of the record and number of
+   continuous records from that index;
+-  Any node-specific auxiliary data.
+
+With this information supplied, when the run time firmware receives one of the
+notification mechanisms, the RAS framework can iterate through and probe error
+records for error, and invoke the appropriate handler to handle it.
+
+The RAS framework provides the macros to populate error record information. The
+macros are versioned, and the latest version as of this writing is 1. These
+macros create a structure of type ``struct err_record_info`` from its arguments,
+which are later passed to probe and error handlers.
+
+For memory-mapped error records:
+
+.. code:: c
+
+    ERR_RECORD_MEMMAP_V1(base_addr, size_num_k, probe, handler, aux)
+
+And, for system register ones:
+
+.. code:: c
+
+    ERR_RECORD_SYSREG_V1(idx_start, num_idx, probe, handler, aux)
+
+The probe handler must have the following prototype:
+
+.. code:: c
+
+    typedef int (*err_record_probe_t)(const struct err_record_info *info,
+                    int *probe_data);
+
+The probe handler must return a non-zero value if an error was detected, or 0
+otherwise. The ``probe_data`` output parameter can be used to pass any useful
+information resulting from probe to the error handler (see `below`__). For
+example, it could return the index of the record.
+
+.. __: `Standard Error Record helpers`_
+
+The error handler must have the following prototype:
+
+.. code:: c
+
+    typedef int (*err_record_handler_t)(const struct err_record_info *info,
+               int probe_data, const struct err_handler_data *const data);
+
+The ``data`` constant parameter describes the various properties of the error,
+viz. the reason for the error, exception syndrome, and also ``flags``,
+``cookie``, and ``handle`` parameters from the `top-level exception handler`__.
+
+.. __: interrupt-framework-design.rst#el3-interrupts
+
+The platform is expected populate an array using the macros above, and register
+the it with the RAS framework using the macro ``REGISTER_ERR_RECORD_INFO()``,
+passing it the name of the array describing the records. Note that the macro
+must be used in the same file where the array is defined.
+
+Standard Error Record helpers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The |TF-A| RAS framework provides probe handlers for Standard Error Records, for
+both memory-mapped and System Register accesses:
+
+.. code:: c
+
+    int ras_err_ser_probe_memmap(const struct err_record_info *info,
+                int *probe_data);
+
+    int ras_err_ser_probe_sysreg(const struct err_record_info *info,
+                int *probe_data);
+
+When the platform enumerates error records, for those records in the Standard
+Error Record format, these helpers maybe used instead of rolling out their own.
+Both helpers above:
+
+-  Return non-zero value when an error is detected in a Standard Error Record;
+-  Set ``probe_data`` to the index of the error record upon detecting an error.
+
+Registering RAS interrupts
+--------------------------
+
+RAS nodes can signal errors to the PE by raising Fault Handling and/or Error
+Recovery interrupts. For the firmware-first handling paradigm for interrupts to
+work, the platform must setup and register with |EHF|. See `Interaction with
+Exception Handling Framework`_.
+
+For each RAS interrupt, the platform has to provide structure of type ``struct
+ras_interrupt``:
+
+-  Interrupt number;
+-  The associated error record information (pointer to the corresponding
+   ``struct err_record_info``);
+-  Optionally, a cookie.
+
+The platform is expected to define an array of ``struct ras_interrupt``, and
+register it with the RAS framework using the macro
+``REGISTER_RAS_INTERRUPTS()``, passing it the name of the array. Note that the
+macro must be used in the same file where the array is defined.
+
+The array of ``struct ras_interrupt`` must be sorted in the increasing order of
+interrupt number. This allows for fast look of handlers in order to service RAS
+interrupts.
+
+Double-fault handling
+---------------------
+
+A Double Fault condition arises when an error is signalled to the PE while
+handling of a previously signalled error is still underway. When a Double Fault
+condition arises, the Arm RAS extensions only require for handler to perform
+orderly shutdown of the system, as recovery may be impossible.
+
+The RAS extensions part of Armv8.4 introduced new architectural features to deal
+with Double Fault conditions, specifically, the introduction of ``NMEA`` and
+``EASE`` bits to ``SCR_EL3`` register. These were introduced to assist EL3
+software which runs part of its entry/exit routines with exceptions momentarily
+masked—meaning, in such systems, External Aborts/SErrors are not immediately
+handled when they occur, but only after the exceptions are unmasked again.
+
+|TF-A|, for legacy reasons, executes entire EL3 with all exceptions unmasked.
+This means that all exceptions routed to EL3 are handled immediately. |TF-A|
+thus is able to detect a Double Fault conditions in software, without needing
+the intended advantages of Armv8.4 Double Fault architecture extensions.
+
+Double faults are fatal, and terminate at the platform double fault handler, and
+doesn't return.
+
+Engaging the RAS framework
+--------------------------
+
+Enabling RAS support is a platform choice conjunctional of three distinct but
+related build options:
+
+-  ``RAS_EXTENSION=1`` includes the RAS framework in the run time firmware;
+
+-  ``EL3_EXCEPTION_HANDLING=1`` enables handling of exceptions at EL3. See
+   `Interaction with Exception Handling Framework`_;
+
+-  ``HANDLE_EA_EL3_FIRST=1`` enables routing of External Aborts and SErrors to
+   EL3.
+
+The RAS support in |TF-A| introduces a default implementation of
+``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_EXTENSION``
+is set to ``1``, it'll first call ``ras_ea_handler()`` function, which is the
+top-level RAS exception handler. ``ras_ea_handler`` is responsible for iterating
+to through platform-supplied error records, probe them, and when an error is
+identified, look up and invoke the corresponding error handler.
+
+Note that, if the platform chooses to override the ``plat_ea_handler`` function
+and intend to use the RAS framework, it must explicitly call
+``ras_ea_handler()`` from within.
+
+Similarly, for RAS interrupts, the framework defines
+``ras_interrupt_handler()``. The RAS framework arranges for it to be invoked
+when  a RAS interrupt taken at EL3. The function bisects the platform-supplied
+sorted array of interrupts to look up the error record information associated
+with the interrupt number. That error handler for that record is then invoked to
+handle the error.
+
+Interaction with Exception Handling Framework
+---------------------------------------------
+
+As mentioned in earlier sections, RAS framework interacts with the |EHF| to
+arbitrate handling of RAS exceptions with others that are routed to EL3. This
+means that the platform must partition a `priority level`__ for handling RAS
+exceptions. The platform must then define the macro ``PLAT_RAS_PRI`` to the
+priority level used for RAS exceptions. Platforms would typically want to
+allocate the highest secure priority for RAS handling.
+
+.. __: exception-handling.rst#partitioning-priority-levels
+
+Handling of both `interrrupt`__ and `non-interrupt`__ exceptions follow the
+sequences outlined in the |EHF| documentation. I.e., for interrupts, the
+priority management is implicit; but for non-interrupt exceptions, they're
+explicit using `EHF APIs`__.
+
+.. __: exception-handling.rst#interrupt-flow
+.. __: exception-handling.rst#non-interrupt-flow
+.. __: exception-handling.rst#activating-and-deactivating-priorities
+
+----
+
+*Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/secure-partition-manager-design.rst b/docs/secure-partition-manager-design.rst
index fec7c00..73406b2 100644
--- a/docs/secure-partition-manager-design.rst
+++ b/docs/secure-partition-manager-design.rst
@@ -125,8 +125,9 @@
 the rest of this document.
 
 To enable SPM support in TF-A, the source code must be compiled with the build
-flag ``ENABLE_SPM=1``. On Arm platforms the build option ``ARM_BL31_IN_DRAM``
-must be set to 1. Also, the location of the binary that contains the BL32 image
+flag ``ENABLE_SPM=1``, along with ``EL3_EXCEPTION_HANDLING=1``. On Arm
+platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the
+location of the binary that contains the BL32 image
 (``BL32=path/to/image.bin``) must be specified.
 
 First, build the Standalone MM Secure Partition. To build it, refer to the
diff --git a/drivers/arm/tzc/tzc_dmc620.c b/drivers/arm/tzc/tzc_dmc620.c
new file mode 100644
index 0000000..4abd080
--- /dev/null
+++ b/drivers/arm/tzc/tzc_dmc620.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <mmio.h>
+#include <tzc_dmc620.h>
+
+/* Mask to extract bit 31 to 16 */
+#define MASK_31_16 UINT64_C(0x0000ffff0000)
+/* Mask to extract bit 47 to 32 */
+#define MASK_47_32 UINT64_C(0xffff00000000)
+
+/* Helper macro for getting dmc_base addr of a dmc_inst */
+#define DMC_BASE(plat_data, dmc_inst) \
+	((uintptr_t)(plat_data->dmc_base[dmc_inst]))
+
+/* Pointer to the tzc_dmc620_config_data structure populated by the platform */
+static const tzc_dmc620_config_data_t *g_plat_config_data;
+
+#if ENABLE_ASSERTIONS
+/*
+ * Helper function to check if the DMC-620 instance is present at the
+ * base address provided by the platform and also check if at least
+ * one dmc instance is present.
+ */
+static void tzc_dmc620_validate_plat_driver_data(
+			const tzc_dmc620_driver_data_t *plat_driver_data)
+{
+	uint8_t dmc_inst, dmc_count;
+	unsigned int dmc_id;
+	uintptr_t base;
+
+	assert(plat_driver_data != NULL);
+
+	dmc_count = plat_driver_data->dmc_count;
+	assert(dmc_count > 0U);
+
+	for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
+		base = DMC_BASE(plat_driver_data, dmc_inst);
+		dmc_id = mmio_read_32(base + DMC620_PERIPHERAL_ID_0);
+		assert(dmc_id == DMC620_PERIPHERAL_ID_0_VALUE);
+	}
+}
+#endif
+
+/*
+ * Program a region with region base and region top addresses of all
+ * DMC-620 instances.
+ */
+static void tzc_dmc620_configure_region(int region_no,
+					unsigned long long region_base,
+					unsigned long long region_top,
+					unsigned int sec_attr)
+{
+	uint32_t min_31_00, min_47_32;
+	uint32_t max_31_00, max_47_32;
+	uint8_t dmc_inst, dmc_count;
+	uintptr_t base;
+	const tzc_dmc620_driver_data_t *plat_driver_data;
+
+	plat_driver_data = g_plat_config_data->plat_drv_data;
+	assert(plat_driver_data != NULL);
+
+	/* Do range checks on regions. */
+	assert((region_no >= 0U) && (region_no <= DMC620_ACC_ADDR_COUNT));
+
+	/* region_base and (region_top + 1) must be 4KB aligned */
+	assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U);
+
+	dmc_count = plat_driver_data->dmc_count;
+	for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
+		min_31_00 = (region_base & MASK_31_16) | sec_attr;
+		min_47_32 = (region_base & MASK_47_32)
+				>> DMC620_ACC_ADDR_WIDTH;
+		max_31_00 = (region_top  & MASK_31_16);
+		max_47_32 = (region_top  & MASK_47_32)
+				>> DMC620_ACC_ADDR_WIDTH;
+
+		/* Extract the base address of the DMC-620 instance */
+		base = DMC_BASE(plat_driver_data, dmc_inst);
+		/* Configure access address region registers */
+		mmio_write_32(base + DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no),
+				min_31_00);
+		mmio_write_32(base + DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no),
+				min_47_32);
+		mmio_write_32(base + DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no),
+				max_31_00);
+		mmio_write_32(base + DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no),
+				max_47_32);
+	}
+}
+
+/*
+ * Set the action value for all the DMC-620 instances.
+ */
+static void tzc_dmc620_set_action(void)
+{
+	uint8_t dmc_inst, dmc_count;
+	uintptr_t base;
+	const tzc_dmc620_driver_data_t *plat_driver_data;
+
+	plat_driver_data = g_plat_config_data->plat_drv_data;
+	dmc_count = plat_driver_data->dmc_count;
+	for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
+		/* Extract the base address of the DMC-620 instance */
+		base = DMC_BASE(plat_driver_data, dmc_inst);
+		/* Switch to READY */
+		mmio_write_32(base + DMC620_MEMC_CMD, DMC620_MEMC_CMD_GO);
+		mmio_write_32(base + DMC620_MEMC_CMD, DMC620_MEMC_CMD_EXECUTE);
+	}
+}
+
+/*
+ * Verify whether the DMC-620 configuration is complete by reading back
+ * configuration registers and comparing it with the configured value. If
+ * configuration is incomplete, loop till the configured value is reflected in
+ * the register.
+ */
+static void tzc_dmc620_verify_complete(void)
+{
+	uint8_t dmc_inst, dmc_count;
+	uintptr_t base;
+	const tzc_dmc620_driver_data_t *plat_driver_data;
+
+	plat_driver_data = g_plat_config_data->plat_drv_data;
+	dmc_count = plat_driver_data->dmc_count;
+	for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
+		/* Extract the base address of the DMC-620 instance */
+		base = DMC_BASE(plat_driver_data, dmc_inst);
+		while ((mmio_read_32(base + DMC620_MEMC_STATUS) &
+				DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO)
+			continue;
+	}
+}
+
+/*
+ * Initialize the DMC-620 TrustZone Controller using the region configuration
+ * supplied by the platform. The DMC620 controller should be enabled elsewhere
+ * before invoking this function.
+ */
+void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data)
+{
+	int i;
+
+	/* Check if valid pointer is passed */
+	assert(plat_config_data != NULL);
+
+	/*
+	 * Check if access address count passed by the platform is less than or
+	 * equal to DMC620's access address count
+	 */
+	assert(plat_config_data->acc_addr_count <= DMC620_ACC_ADDR_COUNT);
+
+#if ENABLE_ASSERTIONS
+	/* Validates the information passed by platform */
+	tzc_dmc620_validate_plat_driver_data(plat_config_data->plat_drv_data);
+#endif
+
+	g_plat_config_data = plat_config_data;
+
+	INFO("Configuring DMC-620 TZC settings\n");
+	for (i = 0U; i < g_plat_config_data->acc_addr_count; i++)
+		tzc_dmc620_configure_region(i,
+			g_plat_config_data->plat_acc_addr_data[i].region_base,
+			g_plat_config_data->plat_acc_addr_data[i].region_top,
+			g_plat_config_data->plat_acc_addr_data[i].sec_attr);
+
+	tzc_dmc620_set_action();
+	tzc_dmc620_verify_complete();
+	INFO("DMC-620 TZC setup completed\n");
+}
diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S
index 8f46a62..418810e 100644
--- a/drivers/cadence/uart/aarch64/cdns_console.S
+++ b/drivers/cadence/uart/aarch64/cdns_console.S
@@ -56,21 +56,23 @@
 	.globl console_cdns_register
 
 	/* -----------------------------------------------
-	 * int console_cdns_register(uint64_t baseaddr,
+	 * int console_cdns_register(uintptr_t baseaddr,
 	 *     uint32_t clock, uint32_t baud,
 	 *     console_cdns_t *console);
 	 * Function to initialize and register a new CDNS
 	 * console. Storage passed in for the console struct
 	 * *must* be persistent (i.e. not from the stack).
 	 * In: x0 - UART register base address
-	 *     x1 - pointer to empty console_cdns_t struct
+	 *     w1 - UART clock in Hz
+	 *     w2 - Baud rate
+	 *     x3 - pointer to empty console_16550_t struct
 	 * Out: return 1 on success, 0 on error
 	 * Clobber list : x0, x1, x2, x6, x7, x14
 	 * -----------------------------------------------
 	 */
 func console_cdns_register
 	mov	x7, x30
-	mov	x6, x1
+	mov	x6, x3
 	cbz	x6, register_fail
 	str	x0, [x6, #CONSOLE_T_CDNS_BASE]
 
@@ -78,7 +80,7 @@
 	cbz	x0, register_fail
 
 	mov	x0, x6
-	mov	x30, v7
+	mov	x30, x7
 	finish_console_register cdns putc=1, getc=1, flush=1
 
 register_fail:
diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S
index 6575af4..25c21cf 100644
--- a/drivers/marvell/uart/a3700_console.S
+++ b/drivers/marvell/uart/a3700_console.S
@@ -5,16 +5,27 @@
  * https://spdx.org/licenses
  */
 
+#include <arch.h>
 #include <asm_macros.S>
 #include <a3700_console.h>
+#define USE_FINISH_CONSOLE_REG_2
+#include <console_macros.S>
 
-	.globl	console_core_init
-	.globl	console_core_putc
-	.globl	console_core_getc
-	.globl	console_core_flush
+	/*
+	 * "core" functions are low-level implementations that don't require
+	 * writable memory and are thus safe to call in BL1 crash context.
+	 */
+	.globl console_a3700_core_putc
+	.globl console_a3700_core_init
+	.globl console_a3700_core_getc
+	.globl console_a3700_core_flush
+
+	.globl console_a3700_putc
+	.globl console_a3700_getc
+	.globl console_a3700_flush
 
 	/* -----------------------------------------------
-	 * int console_core_init(unsigned long base_addr,
+	 * int console_a3700_core_init(unsigned long base_addr,
 	 * unsigned int uart_clk, unsigned int baud_rate)
 	 * Function to initialize the console without a
 	 * C Runtime to print debug information. This
@@ -27,7 +38,7 @@
 	 * Clobber list : x1, x2, x3
 	 * -----------------------------------------------
 	 */
-func console_core_init
+func console_a3700_core_init
 	/* Check the input base address */
 	cbz	x0, init_fail
 	/* Check baud rate and uart clock for sanity */
@@ -95,10 +106,43 @@
 init_fail:
 	mov	w0, #0
 	ret
-endfunc console_core_init
+endfunc console_a3700_core_init
+
+	.globl console_a3700_register
+
+	/* -----------------------------------------------
+	 * int console_a3700_register(console_16550_t *console,
+		uintptr_t base, uint32_t clk, uint32_t baud)
+	 * Function to initialize and register a new a3700
+	 * console. Storage passed in for the console struct
+	 * *must* be persistent (i.e. not from the stack).
+	 * In: x0 - UART register base address
+	 *     w1 - UART clock in Hz
+	 *     w2 - Baud rate
+	 *     x3 - pointer to empty console_a3700_t struct
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : x0, x1, x2, x6, x7, x14
+	 * -----------------------------------------------
+	 */
+func console_a3700_register
+	mov	x7, x30
+	mov	x6, x3
+	cbz	x6, register_fail
+	str	x0, [x6, #CONSOLE_T_A3700_BASE]
+
+	bl	console_a3700_core_init
+	cbz	x0, register_fail
+
+	mov	x0, x6
+	mov	x30, x7
+	finish_console_register a3700, putc=1, getc=1, flush=1
+
+register_fail:
+	ret	x7
+endfunc console_a3700_register
 
 	/* --------------------------------------------------------
-	 * int console_core_putc(int c, unsigned int base_addr)
+	 * int console_a3700_core_putc(int c, unsigned int base_addr)
 	 * Function to output a character over the console. It
 	 * returns the character printed on success or -1 on error.
 	 * In : w0 - character to be printed
@@ -107,7 +151,7 @@
 	 * Clobber list : x2
 	 * --------------------------------------------------------
 	 */
-func console_core_putc
+func console_a3700_core_putc
 	/* Check the input parameter */
 	cbz	x1, putc_error
 
@@ -132,10 +176,25 @@
 putc_error:
 	mov	w0, #-1
 	ret
-endfunc console_core_putc
+endfunc console_a3700_core_putc
+
+	/* --------------------------------------------------------
+	 * int console_a3700_putc(int c, console_a3700_t *console)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - pointer to console_t structure
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_a3700_putc
+	ldr	x1, [x1, #CONSOLE_T_A3700_BASE]
+	b	console_a3700_core_putc
+endfunc console_a3700_putc
 
 	/* ---------------------------------------------
-	 * int console_core_getc(void)
+	 * int console_a3700_core_getc(void)
 	 * Function to get a character from the console.
 	 * It returns the character grabbed on success
 	 * or -1 on error.
@@ -144,16 +203,28 @@
 	 * Clobber list : x0, x1
 	 * ---------------------------------------------
 	 */
-func console_core_getc
-	/* Check if the receive FIFO is empty */
-	ret
-getc_error:
+func console_a3700_core_getc
 	mov	w0, #-1
 	ret
-endfunc console_core_getc
+endfunc console_a3700_core_getc
+
+	/* ---------------------------------------------
+	 * int console_a3700_getc(console_a3700_t *console)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on if no character is available.
+	 * In :  x0 - pointer to console_t structure
+	 * Out : w0 - character if available, else -1
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_a3700_getc
+	ldr	x0, [x0, #CONSOLE_T_A3700_BASE]
+	b	console_a3700_core_getc
+endfunc console_a3700_getc
 
 	/* ---------------------------------------------
-	 * int console_core_flush(uintptr_t base_addr)
+	 * int console_a3700_core_flush(uintptr_t base_addr)
 	 * Function to force a write of all buffered
 	 * data that hasn't been output.
 	 * In : x0 - console base address
@@ -161,8 +232,22 @@
 	 * Clobber list : x0, x1
 	 * ---------------------------------------------
 	 */
-func console_core_flush
-	/* Placeholder */
+func console_a3700_core_flush
 	mov	w0, #0
 	ret
-endfunc console_core_flush
+endfunc console_a3700_core_flush
+
+	/* ---------------------------------------------
+	 * int console_a3700_flush(console_a3700_t *console)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - pointer to console_t structure
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_a3700_flush
+	ldr	x0, [x0, #CONSOLE_T_A3700_BASE]
+	b	console_a3700_core_flush
+endfunc console_a3700_flush
+
diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c
index 9cc917d..0c51e62 100644
--- a/drivers/partition/gpt.c
+++ b/drivers/partition/gpt.c
@@ -13,10 +13,14 @@
 
 static int unicode_to_ascii(unsigned short *str_in, unsigned char *str_out)
 {
-	uint8_t *name = (uint8_t *)str_in;
+	uint8_t *name;
 	int i;
 
-	assert((str_in != NULL) && (str_out != NULL) && (name[0] != '\0'));
+	assert((str_in != NULL) && (str_out != NULL));
+
+	name = (uint8_t *)str_in;
+
+	assert(name[0] != '\0');
 
 	/* check whether the unicode string is valid */
 	for (i = 1; i < (EFI_NAMELEN << 1); i += 2) {
@@ -36,7 +40,7 @@
 {
 	int result;
 
-	assert((gpt_entry != 0) && (entry != 0));
+	assert((gpt_entry != NULL) && (entry != NULL));
 
 	if ((gpt_entry->first_lba == 0) && (gpt_entry->last_lba == 0)) {
 		return -EINVAL;
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index f0bf363..b8457cb 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -1323,7 +1323,7 @@
 	int ret, len;
 	enum stm32mp1_pll_id i;
 	bool lse_css = false;
-	const uint32_t *pkcs_cell;
+	const fdt32_t *pkcs_cell;
 
 	/* Check status field to disable security */
 	if (!fdt_get_rcc_secure_status()) {
@@ -1529,7 +1529,7 @@
 		priv->pkcs_usb_value = 0;
 
 		for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) {
-			uint32_t pkcs = (uint32_t)fdt32_to_cpu(pkcs_cell[j]);
+			uint32_t pkcs = fdt32_to_cpu(pkcs_cell[j]);
 
 			if (pkcs == (uint32_t)CLK_CKPER_DISABLED) {
 				ckper_disabled = true;
diff --git a/drivers/st/clk/stm32mp1_clkfunc.c b/drivers/st/clk/stm32mp1_clkfunc.c
index d4c69cb..078d803 100644
--- a/drivers/st/clk/stm32mp1_clkfunc.c
+++ b/drivers/st/clk/stm32mp1_clkfunc.c
@@ -265,11 +265,11 @@
  * This function gets the pointer to a rcc-clk property from its name.
  * It reads the values indicated inside the device tree.
  * Length of the property is stored in the second parameter.
- * Returns pointer if success, and NULL value else.
+ * Returns pointer on success, and NULL value on failure.
  ******************************************************************************/
-const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
+const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
 {
-	const uint32_t *cuint;
+	const fdt32_t *cuint;
 	int node, len;
 	void *fdt;
 
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index 792703a..303d6ba 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -4,30 +4,27 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <asm_macros.S>
+#include <assert_macros.S>
+#define USE_FINISH_CONSOLE_REG_2
+#include <console_macros.S>
+#include <stm32_console.h>
+#include <stm32_uart_regs.h>
 
 #define USART_TIMEOUT		0x1000
 
-#define USART_CR1		0x00
-#define USART_CR1_UE		0x00000001
-#define USART_CR1_TE		0x00000008
-#define USART_CR1_FIFOEN	0x20000000
-
-#define USART_CR2		0x04
-#define USART_CR2_STOP		0x00003000
-
-#define USART_BRR		0x0C
+	/*
+	 * "core" functions are low-level implementations that don't require
+	 * writeable memory and are thus safe to call in BL1 crash context.
+	 */
+	.globl	console_stm32_core_init
+	.globl	console_stm32_core_putc
+	.globl	console_stm32_core_getc
+	.globl	console_stm32_core_flush
 
-#define USART_ISR		0x1C
-#define USART_ISR_TC		0x00000040
-#define USART_ISR_TXE		0x00000080
-#define USART_ISR_TEACK		0x00200000
+	.globl	console_stm32_putc
+	.globl	console_stm32_flush
 
-#define USART_TDR		0x28
 
-	.globl	console_core_init
-	.globl	console_core_putc
-	.globl	console_core_getc
-	.globl	console_core_flush
 
 	/* -----------------------------------------------------------------
 	 * int console_core_init(uintptr_t base_addr,
@@ -45,7 +42,7 @@
 	 * Clobber list : r1, r2, r3
 	 * -----------------------------------------------------------------
 	 */
-func console_core_init
+func console_stm32_core_init
 	/* Check the input base address */
 	cmp	r0, #0
 	beq	core_init_fail
@@ -88,7 +85,43 @@
 core_init_fail:
 	mov	r0, #0
 	bx	lr
-endfunc console_core_init
+endfunc console_stm32_core_init
+
+	.globl console_stm32_register
+
+	/* -------------------------------------------------------
+	 * int console_stm32_register(uintptr_t baseaddr,
+	 *     uint32_t clock, uint32_t baud,
+	 *     struct console_stm32 *console);
+	 * Function to initialize and register a new STM32
+	 * console. Storage passed in for the console struct
+	 * *must* be persistent (i.e. not from the stack).
+	 * In: r0 - UART register base address
+	 *     r1 - UART clock in Hz
+	 *     r2 - Baud rate
+	 *     r3 - pointer to empty console_stm32 struct
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : r0, r1, r2
+	 * -------------------------------------------------------
+	 */
+func console_stm32_register
+	push	{r4, lr}
+	mov	r4, r3
+	cmp	r4, #0
+	beq	register_fail
+	str	r0, [r4, #CONSOLE_T_STM32_BASE]
+
+	bl console_stm32_core_init
+	cmp	r0, #0
+	beq	register_fail
+
+	mov	r0, r4
+	pop	{r4, lr}
+	finish_console_register stm32 putc=1, getc=0, flush=1
+
+register_fail:
+	pop	{r4, pc}
+endfunc console_stm32_register
 
 	/* ---------------------------------------------------------------
 	 * int console_core_putc(int c, uintptr_t base_addr)
@@ -102,7 +135,7 @@
 	 * Clobber list : r2
 	 * ---------------------------------------------------------------
 	 */
-func console_core_putc
+func console_stm32_core_putc
 	/* Check the input parameter */
 	cmp	r1, #0
 	beq	putc_error
@@ -138,7 +171,26 @@
 putc_error:
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_putc
+endfunc console_stm32_core_putc
+
+	/* ------------------------------------------------------------
+	 * int console_stm32_putc(int c, struct console_stm32 *console)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In: r0 - character to be printed
+	 *     r1 - pointer to console_t structure
+	 * Out : return -1 on error else return character.
+	 * Clobber list: r2
+	 * ------------------------------------------------------------
+	 */
+func console_stm32_putc
+#if ENABLE_ASSERTIONS
+	cmp	r1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r1, [r1, #CONSOLE_T_STM32_BASE]
+	b	console_stm32_core_putc
+endfunc console_stm32_putc
 
 	/* -----------------------------------------------------------
 	 * int console_core_getc(uintptr_t base_addr)
@@ -151,11 +203,11 @@
 	 * Clobber list : r0, r1
 	 * -----------------------------------------------------------
 	 */
-func console_core_getc
+func console_stm32_core_getc
 	/* Not supported */
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_getc
+endfunc console_stm32_core_getc
 
 	/* ---------------------------------------------------------------
 	 * int console_core_flush(uintptr_t base_addr)
@@ -168,7 +220,7 @@
 	 * Clobber list : r0, r1
 	 * ---------------------------------------------------------------
 	 */
-func console_core_flush
+func console_stm32_core_flush
 	cmp	r0, #0
 	beq	flush_error
 	/* Check Transmit Data Register Empty */
@@ -181,4 +233,22 @@
 flush_error:
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_flush
+endfunc console_stm32_core_flush
+
+	/* ------------------------------------------------------
+	 * int console_stm32_flush(struct console_stm32 *console)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : r0 - pointer to console_t structure
+	 * Out : return -1 on error else return 0.
+	 * Clobber list: r0, r1
+	 * ------------------------------------------------------
+	 */
+func console_stm32_flush
+#if ENABLE_ASSERTIONS
+	cmp	r0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r0, [r0, #CONSOLE_T_STM32_BASE]
+	b	console_stm32_core_flush
+endfunc console_stm32_flush
diff --git a/include/drivers/arm/tzc_dmc620.h b/include/drivers/arm/tzc_dmc620.h
new file mode 100644
index 0000000..074bbc1
--- /dev/null
+++ b/include/drivers/arm/tzc_dmc620.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TZC_DMC620_H
+#define TZC_DMC620_H
+
+#include <utils_def.h>
+
+/* DMC-620 memc register offsets */
+#define DMC620_MEMC_STATUS	U(0x0000)
+#define DMC620_MEMC_CMD		U(0x0008)
+
+/* Mask value to check the status of memc_cmd register */
+#define DMC620_MEMC_CMD_MASK	U(0x00000007)
+
+/* memc_cmd register's action values */
+#define DMC620_MEMC_CMD_GO	U(0x00000003)
+#define DMC620_MEMC_CMD_EXECUTE	U(0x00000004)
+
+/* Address offsets of access address next region 0 registers */
+#define DMC620_ACC_ADDR_MIN_31_00_NEXT_BASE	U(0x0080)
+#define DMC620_ACC_ADDR_MIN_47_32_NEXT_BASE	U(0x0084)
+#define DMC620_ACC_ADDR_MAX_31_00_NEXT_BASE	U(0x0088)
+#define DMC620_ACC_ADDR_MAX_47_32_NEXT_BASE	U(0x008c)
+
+/* Length of one block of access address next register region */
+#define DMC620_ACC_ADDR_NEXT_SIZE		U(0x0010)
+
+/* Address offsets of access address next registers */
+#define DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no)	\
+		(DMC620_ACC_ADDR_MIN_31_00_NEXT_BASE +	\
+			(region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+#define DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no)	\
+		(DMC620_ACC_ADDR_MIN_47_32_NEXT_BASE +	\
+			(region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+#define DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no)	\
+		(DMC620_ACC_ADDR_MAX_31_00_NEXT_BASE +	\
+			(region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+#define DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no)	\
+		(DMC620_ACC_ADDR_MAX_47_32_NEXT_BASE +	\
+			(region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+
+/* Number of TZC address regions in DMC-620 */
+#define DMC620_ACC_ADDR_COUNT	U(8)
+/* Width of access address registers */
+#define DMC620_ACC_ADDR_WIDTH	U(32)
+
+/* Peripheral ID registers offsets */
+#define DMC620_PERIPHERAL_ID_0		U(0x1fe0)
+
+/* Default values in id registers */
+#define DMC620_PERIPHERAL_ID_0_VALUE	U(0x00000054)
+
+/* Secure access region attributes. */
+#define TZC_DMC620_REGION_NS_RD		U(0x00000001)
+#define TZC_DMC620_REGION_NS_WR		U(0x00000002)
+#define TZC_DMC620_REGION_NS_RDWR	\
+	(TZC_DMC620_REGION_NS_RD | TZC_DMC620_REGION_NS_WR)
+#define TZC_DMC620_REGION_S_RD		U(0x00000004)
+#define TZC_DMC620_REGION_S_WR		U(0x00000008)
+#define TZC_DMC620_REGION_S_RDWR	\
+	(TZC_DMC620_REGION_S_RD | TZC_DMC620_REGION_S_WR)
+#define TZC_DMC620_REGION_S_NS_RDWR	\
+	(TZC_DMC620_REGION_NS_RDWR | TZC_DMC620_REGION_S_RDWR)
+
+/*
+ * Contains pointer to the base addresses of all the DMC-620 instances.
+ * 'dmc_count' specifies the number of DMC base addresses contained in the
+ * array pointed to by dmc_base.
+ */
+typedef struct tzc_dmc620_driver_data {
+	const uintptr_t *dmc_base;
+	const unsigned int dmc_count;
+} tzc_dmc620_driver_data_t;
+
+/*
+ * Contains region base, region top addresses and corresponding attributes
+ * for configuring TZC access region registers.
+ */
+typedef struct tzc_dmc620_acc_addr_data {
+	const unsigned long long region_base;
+	const unsigned long long region_top;
+	const unsigned int sec_attr;
+} tzc_dmc620_acc_addr_data_t;
+
+/*
+ * Contains platform specific data for configuring TZC region base and
+ * region top address. 'acc_addr_count' specifies the number of
+ * valid entries in 'plat_acc_addr_data' array.
+ */
+typedef struct tzc_dmc620_config_data {
+	const tzc_dmc620_driver_data_t *plat_drv_data;
+	const tzc_dmc620_acc_addr_data_t *plat_acc_addr_data;
+	const uint8_t acc_addr_count;
+} tzc_dmc620_config_data_t;
+
+/* Function prototypes */
+void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data);
+
+#endif /* TZC_DMC620_H */
+
diff --git a/include/drivers/cadence/cdns_uart.h b/include/drivers/cadence/cdns_uart.h
index f92d9fb..490be10 100644
--- a/include/drivers/cadence/cdns_uart.h
+++ b/include/drivers/cadence/cdns_uart.h
@@ -42,7 +42,7 @@
  * for the lifetime of the console, such as a global or static local variable.
  * Its contents will be reinitialized from scratch.
  */
-int console_cdns_register(uint64_t baseaddr, uint32_t clock, uint32_t baud,
+int console_cdns_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
 			  console_cdns_t *console);
 
 #endif /*__ASSEMBLY__*/
diff --git a/drivers/marvell/uart/a3700_console.h b/include/drivers/marvell/uart/a3700_console.h
similarity index 73%
rename from drivers/marvell/uart/a3700_console.h
rename to include/drivers/marvell/uart/a3700_console.h
index de7c4fc..01335a2 100644
--- a/drivers/marvell/uart/a3700_console.h
+++ b/include/drivers/marvell/uart/a3700_console.h
@@ -8,6 +8,8 @@
 #ifndef A3700_CONSOLE_H
 #define A3700_CONSOLE_H
 
+#include <console.h>
+
 /* MVEBU UART Registers */
 #define UART_RX_REG		0x00
 #define UART_TX_REG		0x04
@@ -52,4 +54,26 @@
 #define UART_CTRL_TXFIFO_RESET	(1 << 15)
 #define UARTLSR_TXFIFOEMPTY	(1 << 6)
 
+#define CONSOLE_T_A3700_BASE	CONSOLE_T_DRVDATA
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+typedef struct {
+	console_t console;
+	uintptr_t base;
+} console_a3700_t;
+
+/*
+ * Initialize a new a3700 console instance and register it with the console
+ * framework. The |console| pointer must point to storage that will be valid
+ * for the lifetime of the console, such as a global or static local variable.
+ * Its contents will be reinitialized from scratch.
+ */
+int console_a3700_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+			   console_a3700_t *console);
+
+#endif /*__ASSEMBLY__*/
+
-#endif /* A3700_CONSOLE_H */
+#endif	/* A3700_CONSOLE_H */
diff --git a/include/drivers/st/stm32_console.h b/include/drivers/st/stm32_console.h
new file mode 100644
index 0000000..57e6d74
--- /dev/null
+++ b/include/drivers/st/stm32_console.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_CONSOLE_H
+#define STM32_CONSOLE_H
+
+#include <console.h>
+
+#define CONSOLE_T_STM32_BASE	CONSOLE_T_DRVDATA
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+struct console_stm32 {
+	console_t console;
+	uintptr_t base;
+};
+
+/*
+ * Initialize a new STM32 console instance and register it with the console
+ * framework. The |console| pointer must point to storage that will be valid
+ * for the lifetime of the console, such as a global or static local variable.
+ * Its contents will be reinitialized from scratch.
+ */
+int console_stm32_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+			   struct console_stm32 *console);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* STM32_CONSOLE_H */
diff --git a/include/drivers/st/stm32_uart_regs.h b/include/drivers/st/stm32_uart_regs.h
new file mode 100644
index 0000000..e78d3d4
--- /dev/null
+++ b/include/drivers/st/stm32_uart_regs.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_UART_REGS_H
+#define STM32_UART_REGS_H
+
+#include <utils_def.h>
+
+#define USART_CR1		U(0x00)
+#define USART_CR2		U(0x04)
+#define USART_CR3		U(0x08)
+#define USART_BRR		U(0x0C)
+#define USART_GTPR		U(0x10)
+#define USART_RTOR		U(0x14)
+#define USART_RQR		U(0x18)
+#define USART_ISR		U(0x1C)
+#define USART_ICR		U(0x20)
+#define USART_RDR		U(0x24)
+#define USART_TDR		U(0x28)
+#define USART_PRESC		U(0x2C)
+
+/* USART_CR1 register fields */
+#define USART_CR1_UE		BIT(0)
+#define USART_CR1_UESM		BIT(1)
+#define USART_CR1_RE		BIT(2)
+#define USART_CR1_TE		BIT(3)
+#define USART_CR1_IDLEIE	BIT(4)
+#define USART_CR1_RXNEIE	BIT(5)
+#define USART_CR1_TCIE		BIT(6)
+#define USART_CR1_TXEIE		BIT(7)
+#define USART_CR1_PEIE		BIT(8)
+#define USART_CR1_PS		BIT(9)
+#define USART_CR1_PCE		BIT(10)
+#define USART_CR1_WAKE		BIT(11)
+#define USART_CR1_M		(BIT(28) | BIT(12))
+#define USART_CR1_M0		BIT(12)
+#define USART_CR1_MME		BIT(13)
+#define USART_CR1_CMIE		BIT(14)
+#define USART_CR1_OVER8		BIT(15)
+#define USART_CR1_DEDT		GENMASK(20, 16)
+#define USART_CR1_DEDT_0	BIT(16)
+#define USART_CR1_DEDT_1	BIT(17)
+#define USART_CR1_DEDT_2	BIT(18)
+#define USART_CR1_DEDT_3	BIT(19)
+#define USART_CR1_DEDT_4	BIT(20)
+#define USART_CR1_DEAT		GENMASK(25, 21)
+#define USART_CR1_DEAT_0	BIT(21)
+#define USART_CR1_DEAT_1	BIT(22)
+#define USART_CR1_DEAT_2	BIT(23)
+#define USART_CR1_DEAT_3	BIT(24)
+#define USART_CR1_DEAT_4	BIT(25)
+#define USART_CR1_RTOIE		BIT(26)
+#define USART_CR1_EOBIE		BIT(27)
+#define USART_CR1_M1		BIT(28)
+#define USART_CR1_FIFOEN	BIT(29)
+#define USART_CR1_TXFEIE	BIT(30)
+#define USART_CR1_RXFFIE	BIT(31)
+
+/* USART_CR2 register fields */
+#define USART_CR2_SLVEN		BIT(0)
+#define USART_CR2_DIS_NSS	BIT(3)
+#define USART_CR2_ADDM7		BIT(4)
+#define USART_CR2_LBDL		BIT(5)
+#define USART_CR2_LBDIE		BIT(6)
+#define USART_CR2_LBCL		BIT(8)
+#define USART_CR2_CPHA		BIT(9)
+#define USART_CR2_CPOL		BIT(10)
+#define USART_CR2_CLKEN		BIT(11)
+#define USART_CR2_STOP		GENMASK(13, 12)
+#define USART_CR2_STOP_0	BIT(12)
+#define USART_CR2_STOP_1	BIT(13)
+#define USART_CR2_LINEN		BIT(14)
+#define USART_CR2_SWAP		BIT(15)
+#define USART_CR2_RXINV		BIT(16)
+#define USART_CR2_TXINV		BIT(17)
+#define USART_CR2_DATAINV	BIT(18)
+#define USART_CR2_MSBFIRST	BIT(19)
+#define USART_CR2_ABREN		BIT(20)
+#define USART_CR2_ABRMODE	GENMASK(22, 21)
+#define USART_CR2_ABRMODE_0	BIT(21)
+#define USART_CR2_ABRMODE_1	BIT(22)
+#define USART_CR2_RTOEN		BIT(23)
+#define USART_CR2_ADD		GENMASK(31, 24)
+
+/* USART_CR3 register fields */
+#define USART_CR3_EIE		BIT(0)
+#define USART_CR3_IREN		BIT(1)
+#define USART_CR3_IRLP		BIT(2)
+#define USART_CR3_HDSEL		BIT(3)
+#define USART_CR3_NACK		BIT(4)
+#define USART_CR3_SCEN		BIT(5)
+#define USART_CR3_DMAR		BIT(6)
+#define USART_CR3_DMAT		BIT(7)
+#define USART_CR3_RTSE		BIT(8)
+#define USART_CR3_CTSE		BIT(9)
+#define USART_CR3_CTSIE		BIT(10)
+#define USART_CR3_ONEBIT	BIT(11)
+#define USART_CR3_OVRDIS	BIT(12)
+#define USART_CR3_DDRE		BIT(13)
+#define USART_CR3_DEM		BIT(14)
+#define USART_CR3_DEP		BIT(15)
+#define USART_CR3_SCARCNT	GENMASK(19, 17)
+#define USART_CR3_SCARCNT_0	BIT(17)
+#define USART_CR3_SCARCNT_1	BIT(18)
+#define USART_CR3_SCARCNT_2	BIT(19)
+#define USART_CR3_WUS		GENMASK(21, 20)
+#define USART_CR3_WUS_0		BIT(20)
+#define USART_CR3_WUS_1		BIT(21)
+#define USART_CR3_WUFIE		BIT(22)
+#define USART_CR3_TXFTIE	BIT(23)
+#define USART_CR3_TCBGTIE	BIT(24)
+#define USART_CR3_RXFTCFG	GENMASK(27, 25)
+#define USART_CR3_RXFTCFG_0	BIT(25)
+#define USART_CR3_RXFTCFG_1	BIT(26)
+#define USART_CR3_RXFTCFG_2	BIT(27)
+#define USART_CR3_RXFTIE	BIT(28)
+#define USART_CR3_TXFTCFG	GENMASK(31, 29)
+#define USART_CR3_TXFTCFG_0	BIT(29)
+#define USART_CR3_TXFTCFG_1	BIT(30)
+#define USART_CR3_TXFTCFG_2	BIT(31)
+
+/* USART_BRR register fields */
+#define USART_BRR_DIV_FRACTION	GENMASK(3, 0)
+#define USART_BRR_DIV_MANTISSA	GENMASK(15, 4)
+
+/* USART_GTPR register fields */
+#define USART_GTPR_PSC		GENMASK(7, 0)
+#define USART_GTPR_GT		GENMASK(15, 8)
+
+/* USART_RTOR register fields */
+#define USART_RTOR_RTO		GENMASK(23, 0)
+#define USART_RTOR_BLEN		GENMASK(31, 24)
+
+/* USART_RQR register fields */
+#define USART_RQR_ABRRQ		BIT(0)
+#define USART_RQR_SBKRQ		BIT(1)
+#define USART_RQR_MMRQ		BIT(2)
+#define USART_RQR_RXFRQ		BIT(3)
+#define USART_RQR_TXFRQ		BIT(4)
+
+/* USART_ISR register fields */
+#define USART_ISR_PE		BIT(0)
+#define USART_ISR_FE		BIT(1)
+#define USART_ISR_NE		BIT(2)
+#define USART_ISR_ORE		BIT(3)
+#define USART_ISR_IDLE		BIT(4)
+#define USART_ISR_RXNE		BIT(5)
+#define USART_ISR_TC		BIT(6)
+#define USART_ISR_TXE		BIT(7)
+#define USART_ISR_LBDF		BIT(8)
+#define USART_ISR_CTSIF		BIT(9)
+#define USART_ISR_CTS		BIT(10)
+#define USART_ISR_RTOF		BIT(11)
+#define USART_ISR_EOBF		BIT(12)
+#define USART_ISR_UDR		BIT(13)
+#define USART_ISR_ABRE		BIT(14)
+#define USART_ISR_ABRF		BIT(15)
+#define USART_ISR_BUSY		BIT(16)
+#define USART_ISR_CMF		BIT(17)
+#define USART_ISR_SBKF		BIT(18)
+#define USART_ISR_RWU		BIT(19)
+#define USART_ISR_WUF		BIT(20)
+#define USART_ISR_TEACK		BIT(21)
+#define USART_ISR_REACK		BIT(22)
+#define USART_ISR_TXFE		BIT(23)
+#define USART_ISR_RXFF		BIT(24)
+#define USART_ISR_TCBGT		BIT(25)
+#define USART_ISR_RXFT		BIT(26)
+#define USART_ISR_TXFT		BIT(27)
+
+/* USART_ICR register fields */
+#define USART_ICR_PECF		BIT(0)
+#define USART_ICR_FECF		BIT(1)
+#define USART_ICR_NCF		BIT(2)
+#define USART_ICR_ORECF		BIT(3)
+#define USART_ICR_IDLECF	BIT(4)
+#define USART_ICR_TCCF		BIT(6)
+#define USART_ICR_TCBGT		BIT(7)
+#define USART_ICR_LBDCF		BIT(8)
+#define USART_ICR_CTSCF		BIT(9)
+#define USART_ICR_RTOCF		BIT(11)
+#define USART_ICR_EOBCF		BIT(12)
+#define USART_ICR_UDRCF		BIT(13)
+#define USART_ICR_CMCF		BIT(17)
+#define USART_ICR_WUCF		BIT(20)
+
+/* USART_RDR register fields */
+#define USART_RDR_RDR		GENMASK(8, 0)
+
+/* USART_TDR register fields */
+#define USART_TDR_TDR		GENMASK(8, 0)
+
+/* USART_PRESC register fields */
+#define USART_PRESC_PRESCALER	GENMASK(3, 0)
+
+#endif /* STM32_UART_REGS_H */
diff --git a/include/drivers/st/stm32mp1_clkfunc.h b/include/drivers/st/stm32mp1_clkfunc.h
index b11ccf8..2467af9 100644
--- a/include/drivers/st/stm32mp1_clkfunc.h
+++ b/include/drivers/st/stm32mp1_clkfunc.h
@@ -7,6 +7,7 @@
 #ifndef STM32MP1_CLKFUNC_H
 #define STM32MP1_CLKFUNC_H
 
+#include <libfdt.h>
 #include <stdbool.h>
 
 enum stm32mp_osc_id {
@@ -33,7 +34,7 @@
 int fdt_rcc_read_uint32_array(const char *prop_name,
 			      uint32_t *array, uint32_t count);
 int fdt_rcc_subnode_offset(const char *name);
-const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp);
+const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp);
 bool fdt_get_rcc_secure_status(void);
 
 uintptr_t fdt_get_stgen_base(void);
diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h
index 9598d9b..288e072 100644
--- a/include/drivers/st/stm32mp1_ddr_regs.h
+++ b/include/drivers/st/stm32mp1_ddr_regs.h
@@ -408,6 +408,4 @@
 #define DDRPHYC_DXNDLLCR_SDPHASE_MASK		GENMASK(17, 14)
 #define DDRPHYC_DXNDLLCR_SDPHASE_SHIFT		14
 
-void ddr_enable_clock(void);
-
 #endif /* STM32MP1_DDR_REGS_H */
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index 38e01bd..3e5e3fb 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -33,10 +33,12 @@
 #define MPIDR_AFF0_SHIFT	U(0)
 #define MPIDR_AFF1_SHIFT	U(8)
 #define MPIDR_AFF2_SHIFT	U(16)
+#define MPIDR_AFF_SHIFT(_n)	MPIDR_AFF##_n##_SHIFT
 #define MPIDR_AFFINITY_MASK	U(0x00ffffff)
 #define MPIDR_AFFLVL0		U(0)
 #define MPIDR_AFFLVL1		U(1)
 #define MPIDR_AFFLVL2		U(2)
+#define MPIDR_AFFLVL(_n)	MPIDR_AFFLVL##_n
 
 #define MPIDR_AFFLVL0_VAL(mpidr) \
 		(((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
@@ -46,6 +48,20 @@
 		(((mpidr) >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK)
 #define MPIDR_AFFLVL3_VAL(mpidr)	U(0)
 
+#define MPIDR_AFF_ID(mpid, n)					\
+	(((mpid) >> MPIDR_AFF_SHIFT(n)) & MPIDR_AFFLVL_MASK)
+
+#define MPID_MASK		(MPIDR_MT_MASK				|\
+				 (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)|\
+				 (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT)|\
+				 (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT))
+
+/*
+ * An invalid MPID. This value can be used by functions that return an MPID to
+ * indicate an error.
+ */
+#define INVALID_MPID		U(0xFFFFFFFF)
+
 /*
  * The MPIDR_MAX_AFFLVL count starts from 0. Take care to
  * add one while using this macro to define array sizes.
@@ -127,7 +143,7 @@
 #define SDCR_RESET_VAL		U(0x0)
 
 /* HSCTLR definitions */
-#define HSCTLR_RES1 	((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \
+#define HSCTLR_RES1	((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \
 			 (U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \
 			 (U(1) << 11) | (U(1) << 4) | (U(1) << 3))
 
@@ -167,6 +183,7 @@
 #define GET_NS_BIT(scr)		((scr) & SCR_NS_BIT)
 
 /* HCR definitions */
+#define HCR_TGE_BIT		(U(1) << 27)
 #define HCR_AMO_BIT		(U(1) << 5)
 #define HCR_IMO_BIT		(U(1) << 4)
 #define HCR_FMO_BIT		(U(1) << 3)
@@ -212,10 +229,9 @@
 /* CNTHP_CTL definitions */
 #define CNTHP_CTL_RESET_VAL	U(0x0)
 
-/* NASCR definitions */
+/* NSACR definitions */
 #define NSASEDIS_BIT		(U(1) << 15)
 #define NSTRCDIS_BIT		(U(1) << 20)
-/* NOTE: correct typo in the definitions */
 #define NSACR_CP11_BIT		(U(1) << 11)
 #define NSACR_CP10_BIT		(U(1) << 10)
 #define NSACR_IMP_DEF_MASK	(U(0x7) << 16)
@@ -262,7 +278,6 @@
 /*
  * TTBCR definitions
  */
-/* The ARM Trusted Firmware uses the long descriptor format */
 #define TTBCR_EAE_BIT		(U(1) << 31)
 
 #define TTBCR_SH1_NON_SHAREABLE		(U(0x0) << 28)
@@ -407,14 +422,30 @@
 #define CNTACR_RWPT_SHIFT	U(0x5)
 
 /*******************************************************************************
- * Definitions of register offsets in the CNTBaseN Frame of the
+ * Definitions of register offsets and fields in the CNTBaseN Frame of the
  * system level implementation of the Generic Timer.
  ******************************************************************************/
-#define CNTBASE_CNTFRQ		U(0x10)
+/* Physical Count register. */
+#define CNTPCT_LO		U(0x0)
+/* Counter Frequency register. */
+#define CNTBASEN_CNTFRQ		U(0x10)
+/* Physical Timer CompareValue register. */
+#define CNTP_CVAL_LO		U(0x20)
+/* Physical Timer Control register. */
+#define CNTP_CTL		U(0x2c)
+
+/* Physical timer control register bit fields shifts and masks */
+#define CNTP_CTL_ENABLE_SHIFT   0
+#define CNTP_CTL_IMASK_SHIFT    1
+#define CNTP_CTL_ISTATUS_SHIFT  2
+
+#define CNTP_CTL_ENABLE_MASK    U(1)
+#define CNTP_CTL_IMASK_MASK     U(1)
+#define CNTP_CTL_ISTATUS_MASK   U(1)
 
 /* MAIR macros */
-#define MAIR0_ATTR_SET(attr, index)	((attr) << ((index) << 3))
-#define MAIR1_ATTR_SET(attr, index)	((attr) << (((index) - U(3)) << 3))
+#define MAIR0_ATTR_SET(attr, index)	((attr) << ((index) << U(3)))
+#define MAIR1_ATTR_SET(attr, index)	((attr) << (((index) - U(3)) << U(3)))
 
 /* System register defines The format is: coproc, opt1, CRn, CRm, opt2 */
 #define SCR		p15, 0, c1, c1, 0
@@ -423,6 +454,7 @@
 #define SDCR		p15, 0, c1, c3, 1
 #define MPIDR		p15, 0, c0, c0, 5
 #define MIDR		p15, 0, c0, c0, 0
+#define HVBAR		p15, 4, c12, c0, 0
 #define VBAR		p15, 0, c12, c0, 0
 #define MVBAR		p15, 0, c12, c0, 1
 #define NSACR		p15, 0, c1, c1, 2
@@ -443,6 +475,7 @@
 #define TTBR0		p15, 0, c2, c0, 0
 #define TTBR1		p15, 0, c2, c0, 1
 #define TLBIALL		p15, 0, c8, c7, 0
+#define TLBIALLH	p15, 4, c8, c7, 0
 #define TLBIALLIS	p15, 0, c8, c3, 0
 #define TLBIMVA		p15, 0, c8, c7, 1
 #define TLBIMVAA	p15, 0, c8, c7, 3
@@ -472,6 +505,7 @@
 /* Debug register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
 #define HDCR		p15, 4, c1, c1, 1
 #define PMCR		p15, 0, c9, c12, 0
+#define CNTHP_TVAL	p15, 4, c14, c2, 0
 #define CNTHP_CTL	p15, 4, c14, c2, 1
 
 /* AArch32 coproc registers for 32bit MMU descriptor support */
@@ -507,6 +541,7 @@
 #define VTTBR_64	p15, 6, c2
 #define CNTPCT_64	p15, 0, c14
 #define HTTBR_64	p15, 4, c2
+#define CNTHP_CVAL_64	p15, 6, c14
 #define PAR_64		p15, 0, c7
 
 /* 64 bit GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRm */
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
index 03f0e86..7d1944c 100644
--- a/include/lib/aarch32/arch_helpers.h
+++ b/include/lib/aarch32/arch_helpers.h
@@ -7,7 +7,7 @@
 #ifndef ARCH_HELPERS_H
 #define ARCH_HELPERS_H
 
-#include <arch.h>	/* for additional register definitions */
+#include <arch.h>
 #include <cdefs.h>
 #include <stdint.h>
 #include <string.h>
@@ -33,13 +33,8 @@
 
 /*
  *  The undocumented %Q and %R extended asm are used to implemented the below
- *  64 bit `mrrc` and `mcrr` instructions. It works only on Little Endian
- *  systems for GCC versions < 4.6. Above GCC 4.6, both Little Endian and
- *  Big Endian systems generate the right instruction encoding.
+ *  64 bit `mrrc` and `mcrr` instructions.
  */
-#if !(__clang__ || __GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6))
-#error "clang or GCC 4.6 or above is required to build AArch32 Trusted Firmware"
-#endif
 
 #define _DEFINE_COPROCR_WRITE_FUNC_64(_name, coproc, opc1, CRm)		\
 static inline void write64_## _name(uint64_t v)				\
@@ -78,6 +73,10 @@
 #define DEFINE_COPROCR_READ_FUNC(_name, ...) 				\
 	_DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__)
 
+/* Define write function for coproc register */
+#define DEFINE_COPROCR_WRITE_FUNC(_name, ...) 				\
+	_DEFINE_COPROCR_WRITE_FUNC(_name, __VA_ARGS__)
+
 /* Define read & write function for coproc register */
 #define DEFINE_COPROCR_RW_FUNCS(_name, ...) 				\
 	_DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__)			\
@@ -87,6 +86,10 @@
 #define DEFINE_COPROCR_READ_FUNC_64(_name, ...) 			\
 	_DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__)
 
+/* Define 64 bit write function for coproc register */
+#define DEFINE_COPROCR_WRITE_FUNC_64(_name, ...) 			\
+	_DEFINE_COPROCR_WRITE_FUNC_64(_name, __VA_ARGS__)
+
 /* Define 64 bit read & write function for coproc register */
 #define DEFINE_COPROCR_RW_FUNCS_64(_name, ...) 				\
 	_DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__)		\
@@ -101,30 +104,15 @@
  * Macros to create inline functions for tlbi operations
  *********************************************************************/
 
-#if ERRATA_A57_813419
-/*
- * Define function for TLBI instruction with type specifier that
- * implements the workaround for errata 813419 of Cortex-A57
- */
 #define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)		\
 static inline void tlbi##_op(void)					\
 {									\
 	u_register_t v = 0;						\
 	__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
-	__asm__ volatile ("dsb ish");\
-	__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
 }
 
-#define _DEFINE_TLBIOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2)	\
-static inline void tlbi##_op(u_register_t v)				\
-{									\
-	__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
-	__asm__ volatile ("dsb ish");\
-	__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
-}
-#else
-#define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)		\
-static inline void tlbi##_op(void)					\
+#define _DEFINE_BPIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)		\
+static inline void bpi##_op(void)					\
 {									\
 	u_register_t v = 0;						\
 	__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
@@ -135,14 +123,6 @@
 {									\
 	__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
 }
-#endif /* ERRATA_A57_813419 */
-
-#define _DEFINE_BPIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)		\
-static inline void bpi##_op(void)					\
-{									\
-	u_register_t v = 0;						\
-	__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
-}
 
 /* Define function for simple TLBI operation */
 #define DEFINE_TLBIOP_FUNC(_op, ...)					\
@@ -250,10 +230,13 @@
 DEFINE_COPROCR_RW_FUNCS(cnthctl, CNTHCTL)
 DEFINE_COPROCR_RW_FUNCS(mair0, MAIR0)
 DEFINE_COPROCR_RW_FUNCS(mair1, MAIR1)
+DEFINE_COPROCR_RW_FUNCS(hmair0, HMAIR0)
 DEFINE_COPROCR_RW_FUNCS(ttbcr, TTBCR)
+DEFINE_COPROCR_RW_FUNCS(htcr, HTCR)
 DEFINE_COPROCR_RW_FUNCS(ttbr0, TTBR0)
 DEFINE_COPROCR_RW_FUNCS_64(ttbr0, TTBR0_64)
 DEFINE_COPROCR_RW_FUNCS(ttbr1, TTBR1)
+DEFINE_COPROCR_RW_FUNCS_64(httbr, HTTBR_64)
 DEFINE_COPROCR_RW_FUNCS(vpidr, VPIDR)
 DEFINE_COPROCR_RW_FUNCS(vmpidr, VMPIDR)
 DEFINE_COPROCR_RW_FUNCS_64(vttbr, VTTBR_64)
@@ -261,6 +244,9 @@
 DEFINE_COPROCR_RW_FUNCS_64(cntvoff, CNTVOFF_64)
 DEFINE_COPROCR_RW_FUNCS(csselr, CSSELR)
 DEFINE_COPROCR_RW_FUNCS(hstr, HSTR)
+DEFINE_COPROCR_RW_FUNCS(cnthp_ctl_el2, CNTHP_CTL)
+DEFINE_COPROCR_RW_FUNCS(cnthp_tval_el2, CNTHP_TVAL)
+DEFINE_COPROCR_RW_FUNCS_64(cnthp_cval_el2, CNTHP_CVAL_64)
 
 DEFINE_COPROCR_RW_FUNCS(icc_sre_el1, ICC_SRE)
 DEFINE_COPROCR_RW_FUNCS(icc_sre_el2, ICC_HSRE)
@@ -268,6 +254,7 @@
 DEFINE_COPROCR_RW_FUNCS(icc_pmr_el1, ICC_PMR)
 DEFINE_COPROCR_RW_FUNCS(icc_rpr_el1, ICC_RPR)
 DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el3, ICC_MGRPEN1)
+DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el1, ICC_IGRPEN1)
 DEFINE_COPROCR_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0)
 DEFINE_COPROCR_RW_FUNCS(icc_hppir0_el1, ICC_HPPIR0)
 DEFINE_COPROCR_RW_FUNCS(icc_hppir1_el1, ICC_HPPIR1)
@@ -276,13 +263,17 @@
 DEFINE_COPROCR_RW_FUNCS(icc_eoir0_el1, ICC_EOIR0)
 DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1)
 DEFINE_COPROCR_RW_FUNCS_64(icc_sgi0r_el1, ICC_SGI0R_EL1_64)
+DEFINE_COPROCR_WRITE_FUNC_64(icc_sgi1r, ICC_SGI1R_EL1_64)
 
 DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
 DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
 DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
 
-DEFINE_COPROCR_RW_FUNCS(ats1cpr, ATS1CPR)
-DEFINE_COPROCR_RW_FUNCS(ats1hr, ATS1HR)
+/*
+ * Address translation
+ */
+DEFINE_COPROCR_WRITE_FUNC(ats1cpr, ATS1CPR)
+DEFINE_COPROCR_WRITE_FUNC(ats1hr, ATS1HR)
 DEFINE_COPROCR_RW_FUNCS_64(par, PAR_64)
 
 DEFINE_COPROCR_RW_FUNCS(nsacr, NSACR)
@@ -340,9 +331,7 @@
 #define IS_IN_SVC()	(GET_M32(read_cpsr()) == MODE32_svc)
 #define IS_IN_MON()	(GET_M32(read_cpsr()) == MODE32_mon)
 #define IS_IN_EL2()	IS_IN_HYP()
- /*
-  * If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3
-  */
+/* If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3 */
 #define IS_IN_EL3() \
 	((GET_M32(read_cpsr()) == MODE32_mon) ||	\
 		(IS_IN_SECURE() && (GET_M32(read_cpsr()) != MODE32_usr)))
@@ -378,7 +367,15 @@
 
 #define read_ctr_el0()		read_ctr()
 
-#define write_icc_sgi0r_el1(_v) \
-		write64_icc_sgi0r_el1(_v)
+#define write_icc_sgi0r_el1(_v)	write64_icc_sgi0r_el1(_v)
+
+#define read_daif()		read_cpsr()
+#define write_daif(flags)	write_cpsr(flags)
+
+#define read_cnthp_cval_el2()	read64_cnthp_cval_el2()
+#define write_cnthp_cval_el2(v)	write64_cnthp_cval_el2(v)
+
+#define read_amcntenset0_el0()	read_amcntenset0()
+#define read_amcntenset1_el0()	read_amcntenset1()
 
 #endif /* ARCH_HELPERS_H */
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index e6842e1..d7867bc 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -35,12 +35,14 @@
 #define MPIDR_AFF1_SHIFT	U(8)
 #define MPIDR_AFF2_SHIFT	U(16)
 #define MPIDR_AFF3_SHIFT	U(32)
+#define MPIDR_AFF_SHIFT(_n)	MPIDR_AFF##_n##_SHIFT
 #define MPIDR_AFFINITY_MASK	ULL(0xff00ffffff)
 #define MPIDR_AFFLVL_SHIFT	U(3)
-#define MPIDR_AFFLVL0		U(0x0)
-#define MPIDR_AFFLVL1		U(0x1)
-#define MPIDR_AFFLVL2		U(0x2)
-#define MPIDR_AFFLVL3		U(0x3)
+#define MPIDR_AFFLVL0		ULL(0x0)
+#define MPIDR_AFFLVL1		ULL(0x1)
+#define MPIDR_AFFLVL2		ULL(0x2)
+#define MPIDR_AFFLVL3		ULL(0x3)
+#define MPIDR_AFFLVL(_n)	MPIDR_AFFLVL##_n
 #define MPIDR_AFFLVL0_VAL(mpidr) \
 		(((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
 #define MPIDR_AFFLVL1_VAL(mpidr) \
@@ -56,28 +58,42 @@
  */
 #define MPIDR_MAX_AFFLVL	U(2)
 
-/* Constant to highlight the assumption that MPIDR allocation starts from 0 */
-#define FIRST_MPIDR		ULL(0)
+#define MPID_MASK		(MPIDR_MT_MASK				 | \
+				 (MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT) | \
+				 (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT) | \
+				 (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) | \
+				 (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT))
+
+#define MPIDR_AFF_ID(mpid, n)					\
+	(((mpid) >> MPIDR_AFF_SHIFT(n)) & MPIDR_AFFLVL_MASK)
+
+/*
+ * An invalid MPID. This value can be used by functions that return an MPID to
+ * indicate an error.
+ */
+#define INVALID_MPID		U(0xFFFFFFFF)
 
 /*******************************************************************************
  * Definitions for CPU system register interface to GICv3
  ******************************************************************************/
-#define ICC_SRE_EL1     S3_0_C12_C12_5
-#define ICC_SRE_EL2     S3_4_C12_C9_5
-#define ICC_SRE_EL3     S3_6_C12_C12_5
-#define ICC_CTLR_EL1    S3_0_C12_C12_4
-#define ICC_CTLR_EL3    S3_6_C12_C12_4
-#define ICC_PMR_EL1     S3_0_C4_C6_0
-#define ICC_RPR_EL1     S3_0_C12_C11_3
-#define ICC_IGRPEN1_EL3 S3_6_c12_c12_7
-#define ICC_IGRPEN0_EL1 S3_0_c12_c12_6
-#define ICC_HPPIR0_EL1  S3_0_c12_c8_2
-#define ICC_HPPIR1_EL1  S3_0_c12_c12_2
-#define ICC_IAR0_EL1    S3_0_c12_c8_0
-#define ICC_IAR1_EL1    S3_0_c12_c12_0
-#define ICC_EOIR0_EL1   S3_0_c12_c8_1
-#define ICC_EOIR1_EL1   S3_0_c12_c12_1
-#define ICC_SGI0R_EL1	S3_0_c12_c11_7
+#define ICC_IGRPEN1_EL1		S3_0_C12_C12_7
+#define ICC_SGI1R		S3_0_C12_C11_5
+#define ICC_SRE_EL1		S3_0_C12_C12_5
+#define ICC_SRE_EL2		S3_4_C12_C9_5
+#define ICC_SRE_EL3		S3_6_C12_C12_5
+#define ICC_CTLR_EL1		S3_0_C12_C12_4
+#define ICC_CTLR_EL3		S3_6_C12_C12_4
+#define ICC_PMR_EL1		S3_0_C4_C6_0
+#define ICC_RPR_EL1		S3_0_C12_C11_3
+#define ICC_IGRPEN1_EL3		S3_6_c12_c12_7
+#define ICC_IGRPEN0_EL1		S3_0_c12_c12_6
+#define ICC_HPPIR0_EL1		S3_0_c12_c8_2
+#define ICC_HPPIR1_EL1		S3_0_c12_c12_2
+#define ICC_IAR0_EL1		S3_0_c12_c8_0
+#define ICC_IAR1_EL1		S3_0_c12_c12_0
+#define ICC_EOIR0_EL1		S3_0_c12_c8_1
+#define ICC_EOIR1_EL1		S3_0_c12_c12_1
+#define ICC_SGI0R_EL1		S3_0_c12_c11_7
 
 /*******************************************************************************
  * Generic timer memory mapped registers & offsets
@@ -140,6 +156,25 @@
 #define ID_AA64MMFR0_EL1_PARANGE_SHIFT	U(0)
 #define ID_AA64MMFR0_EL1_PARANGE_MASK	ULL(0xf)
 
+/* ID_AA64ISAR1_EL1 definitions */
+#define ID_AA64ISAR1_GPI_SHIFT	U(28)
+#define ID_AA64ISAR1_GPI_WIDTH	U(4)
+#define ID_AA64ISAR1_GPA_SHIFT	U(24)
+#define ID_AA64ISAR1_GPA_WIDTH	U(4)
+#define ID_AA64ISAR1_API_SHIFT	U(8)
+#define ID_AA64ISAR1_API_WIDTH	U(4)
+#define ID_AA64ISAR1_APA_SHIFT	U(4)
+#define ID_AA64ISAR1_APA_WIDTH	U(4)
+
+#define ID_AA64ISAR1_GPI_MASK \
+	(((ULL(1) << ID_AA64ISAR1_GPI_WIDTH) - ULL(1)) << ID_AA64ISAR1_GPI_SHIFT)
+#define ID_AA64ISAR1_GPA_MASK \
+	(((ULL(1) << ID_AA64ISAR1_GPA_WIDTH) - ULL(1)) << ID_AA64ISAR1_GPA_SHIFT)
+#define ID_AA64ISAR1_API_MASK \
+	(((ULL(1) << ID_AA64ISAR1_API_WIDTH) - ULL(1)) << ID_AA64ISAR1_API_SHIFT)
+#define ID_AA64ISAR1_APA_MASK \
+	(((ULL(1) << ID_AA64ISAR1_APA_WIDTH) - ULL(1)) << ID_AA64ISAR1_APA_SHIFT)
+
 #define PARANGE_0000	U(32)
 #define PARANGE_0001	U(36)
 #define PARANGE_0010	U(40)
@@ -278,6 +313,7 @@
 /* HCR definitions */
 #define HCR_API_BIT		(ULL(1) << 41)
 #define HCR_APK_BIT		(ULL(1) << 40)
+#define HCR_TGE_BIT		(ULL(1) << 27)
 #define HCR_RW_SHIFT		U(31)
 #define HCR_RW_BIT		(ULL(1) << HCR_RW_SHIFT)
 #define HCR_AMO_BIT		(ULL(1) << 5)
@@ -351,6 +387,8 @@
 #define DISABLE_ALL_EXCEPTIONS \
 		(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
 
+#define DISABLE_INTERRUPTS	(DAIF_FIQ_BIT | DAIF_IRQ_BIT)
+
 /*
  * RMR_EL3 definitions
  */
@@ -360,12 +398,12 @@
 /*
  * HI-VECTOR address for AArch32 state
  */
-#define HI_VECTOR_BASE	U(0xFFFF0000)
+#define HI_VECTOR_BASE		U(0xFFFF0000)
 
 /*
  * TCR defintions
  */
-#define TCR_EL3_RES1		((U(1) << 31) | (U(1) << 23))
+#define TCR_EL3_RES1		((ULL(1) << 31) | (ULL(1) << 23))
 #define TCR_EL2_RES1		((ULL(1) << 31) | (ULL(1) << 23))
 #define TCR_EL1_IPS_SHIFT	U(32)
 #define TCR_EL2_PS_SHIFT	U(16)
@@ -571,10 +609,17 @@
 #define CNTACR_RWPT_SHIFT	U(0x5)
 
 /*******************************************************************************
- * Definitions of register offsets in the CNTBaseN Frame of the
+ * Definitions of register offsets and fields in the CNTBaseN Frame of the
  * system level implementation of the Generic Timer.
  ******************************************************************************/
-#define CNTBASE_CNTFRQ		U(0x10)
+/* Physical Count register. */
+#define CNTPCT_LO		U(0x0)
+/* Counter Frequency register. */
+#define CNTBASEN_CNTFRQ		U(0x10)
+/* Physical Timer CompareValue register. */
+#define CNTP_CVAL_LO		U(0x20)
+/* Physical Timer Control register. */
+#define CNTP_CTL		U(0x2c)
 
 /* PMCR_EL0 definitions */
 #define PMCR_EL0_RESET_VAL	U(0x0)
@@ -753,7 +798,22 @@
 #define ERXCTLR_EL1		S3_0_C5_C4_1
 #define ERXSTATUS_EL1		S3_0_C5_C4_2
 #define ERXADDR_EL1		S3_0_C5_C4_3
+#define ERXPFGF_EL1		S3_0_C5_C4_4
+#define ERXPFGCTL_EL1		S3_0_C5_C4_5
+#define ERXPFGCDN_EL1		S3_0_C5_C4_6
 #define ERXMISC0_EL1		S3_0_C5_C5_0
 #define ERXMISC1_EL1		S3_0_C5_C5_1
 
+#define ERXCTLR_ED_BIT		(U(1) << 0)
+#define ERXCTLR_UE_BIT		(U(1) << 4)
+
+#define ERXPFGCTL_UC_BIT	(U(1) << 1)
+#define ERXPFGCTL_UEU_BIT	(U(1) << 2)
+#define ERXPFGCTL_CDEN_BIT	(U(1) << 31)
+
+/*******************************************************************************
+ * Armv8.3 Pointer Authentication Registers
+ *******************************************************************************/
+#define APGAKeyLo_EL1		S3_0_C2_C3_0
+
 #endif /* ARCH_H */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 61f9830..8b3d53a 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -7,8 +7,8 @@
 #ifndef ARCH_HELPERS_H
 #define ARCH_HELPERS_H
 
-#include <arch.h>	/* for additional register definitions */
-#include <cdefs.h>	/* For __dead2 */
+#include <arch.h>
+#include <cdefs.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
@@ -179,11 +179,13 @@
 #define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
 #define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
 
-DEFINE_SYSREG_READ_FUNC(par_el1)
+DEFINE_SYSREG_RW_FUNCS(par_el1)
 DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
 DEFINE_SYSREG_READ_FUNC(CurrentEl)
+DEFINE_SYSREG_READ_FUNC(ctr_el0)
 DEFINE_SYSREG_RW_FUNCS(daif)
 DEFINE_SYSREG_RW_FUNCS(spsr_el1)
 DEFINE_SYSREG_RW_FUNCS(spsr_el2)
@@ -202,14 +204,20 @@
 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, oshld)
+DEFINE_SYSOP_TYPE_FUNC(dmb, oshst)
+DEFINE_SYSOP_TYPE_FUNC(dmb, osh)
+DEFINE_SYSOP_TYPE_FUNC(dmb, nshld)
+DEFINE_SYSOP_TYPE_FUNC(dmb, nshst)
+DEFINE_SYSOP_TYPE_FUNC(dmb, nsh)
+DEFINE_SYSOP_TYPE_FUNC(dmb, ishld)
 DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
+DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
 DEFINE_SYSOP_FUNC(isb)
 
 uint32_t get_afflvl_shift(uint32_t);
 uint32_t mpidr_mask_lower_afflvls(uint64_t, uint32_t);
 
-
 void __dead2 eret(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3,
 		  uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7);
 void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3,
@@ -286,9 +294,15 @@
 
 DEFINE_SYSREG_RW_FUNCS(cpacr_el1)
 DEFINE_SYSREG_RW_FUNCS(cntfrq_el0)
+DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2)
+DEFINE_SYSREG_RW_FUNCS(cnthp_tval_el2)
+DEFINE_SYSREG_RW_FUNCS(cnthp_cval_el2)
 DEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1)
 DEFINE_SYSREG_RW_FUNCS(cntps_tval_el1)
 DEFINE_SYSREG_RW_FUNCS(cntps_cval_el1)
+DEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0)
+DEFINE_SYSREG_RW_FUNCS(cntp_tval_el0)
+DEFINE_SYSREG_RW_FUNCS(cntp_cval_el0)
 DEFINE_SYSREG_READ_FUNC(cntpct_el0)
 DEFINE_SYSREG_RW_FUNCS(cnthctl_el2)
 
@@ -298,24 +312,23 @@
 
 DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
 DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
-DEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0)
 
 DEFINE_SYSREG_READ_FUNC(isr_el1)
 
-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)
 
+/* GICv3 System Registers */
+
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(icc_rpr_el1, ICC_RPR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el3, ICC_IGRPEN1_EL3)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el1, ICC_IGRPEN1_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir0_el1, ICC_HPPIR0_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir1_el1, ICC_HPPIR1_EL1)
@@ -324,6 +337,7 @@
 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir0_el1, ICC_EOIR0_EL1)
 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(icc_sgi1r, ICC_SGI1R)
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcgcr_el0, AMCGCR_EL0)
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0)
@@ -351,11 +365,14 @@
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
 
+/* Armv8.3 Pointer Authentication Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(apgakeylo_el1, APGAKeyLo_EL1)
+
 #define IS_IN_EL(x) \
 	(GET_EL(read_CurrentEl()) == MODE_EL##x)
 
 #define IS_IN_EL1() IS_IN_EL(1)
-#define IS_IN_EL3() IS_IN_EL(3)
+#define IS_IN_EL2() IS_IN_EL(2)
 #define IS_IN_EL3() IS_IN_EL(3)
 
 static inline unsigned int get_current_el(void)
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index b27e481..b7febc3 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -302,10 +302,10 @@
 	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
 	void (*pwr_domain_suspend_finish)(
 				const psci_power_state_t *target_state);
-	void (*pwr_domain_pwr_down_wfi)(
-				const psci_power_state_t *target_state) __dead2;
-	void (*system_off)(void) __dead2;
-	void (*system_reset)(void) __dead2;
+	void __dead2 (*pwr_domain_pwr_down_wfi)(
+				const psci_power_state_t *target_state);
+	void __dead2 (*system_off)(void);
+	void __dead2 (*system_reset)(void);
 	int (*validate_power_state)(unsigned int power_state,
 				    psci_power_state_t *req_state);
 	int (*validate_ns_entrypoint)(uintptr_t ns_entrypoint);
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 1dd57cb..02963ac 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -30,11 +30,19 @@
  * position @h. For example
  * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#if defined(__LINKER__) || defined(__ASSEMBLY__)
+#define GENMASK_32(h, l) \
+	(((0xFFFFFFFF) << (l)) & (0xFFFFFFFF >> (32 - 1 - (h))))
+
+#define GENMASK_64(h, l) \
+	((~0 << (l)) & (~0 >> (64 - 1 - (h))))
+#else
 #define GENMASK_32(h, l) \
 	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
 
 #define GENMASK_64(h, l) \
 	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
+#endif
 
 #ifdef AARCH32
 #define GENMASK				GENMASK_32
@@ -152,5 +160,6 @@
  */
 #define ASSERT_SYM_PTR_ALIGN(sym) assert(((size_t)(sym) % __alignof__(*(sym))) == 0)
 
+#define COMPILER_BARRIER() __asm__ volatile ("" ::: "memory")
 
 #endif /* UTILS_DEF_H */
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 4bd0bb2..8c0a567 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -34,6 +34,12 @@
 	MAP_REGION(_adr, _adr, _sz, _attr)
 
 /*
+ * Helper macro to define entries for mmap_region_t. It allows to define 'pa'
+ * and sets 'va' to 0 for each region. To be used with mmap_add_alloc_va().
+ */
+#define MAP_REGION_ALLOC_VA(pa, sz, attr)	MAP_REGION(pa, 0, sz, attr)
+
+/*
  * Helper macro to define an mmap_region_t to map with the desired granularity
  * of translation tables.
  *
@@ -219,6 +225,21 @@
 void mmap_add(const mmap_region_t *mm);
 void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);
 
+/*
+ * Add a region with defined base PA. Returns base VA calculated using the
+ * highest existing region in the mmap array even if it fails to allocate the
+ * region.
+ */
+void mmap_add_region_alloc_va(unsigned long long base_pa, uintptr_t *base_va,
+			      size_t size, unsigned int attr);
+void mmap_add_region_alloc_va_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
+
+/*
+ * Add an array of static regions with defined base PA, and fill the base VA
+ * field on the array of structs. This function can only be used before
+ * initializing the translation tables. The regions cannot be removed afterwards.
+ */
+void mmap_add_alloc_va(mmap_region_t *mm);
 
 #if PLAT_XLAT_TABLES_DYNAMIC
 /*
@@ -237,6 +258,21 @@
 int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
 
 /*
+ * Add a dynamic region with defined base PA. Returns base VA calculated using
+ * the highest existing region in the mmap array even if it fails to allocate
+ * the region.
+ *
+ * mmap_add_dynamic_region_alloc_va() returns the allocated VA in 'base_va'.
+ * mmap_add_dynamic_region_alloc_va_ctx() returns it in 'mm->base_va'.
+ *
+ * It returns the same error values as mmap_add_dynamic_region().
+ */
+int mmap_add_dynamic_region_alloc_va(unsigned long long base_pa,
+				     uintptr_t *base_va,
+				     size_t size, unsigned int attr);
+int mmap_add_dynamic_region_alloc_va_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
+
+/*
  * Remove a region with the specified base VA and size. Only dynamic regions can
  * be removed, and they can be removed even if the translation tables are
  * initialized.
diff --git a/include/plat/marvell/a3700/common/plat_marvell.h b/include/plat/marvell/a3700/common/plat_marvell.h
index 8c289e9..01e42c5 100644
--- a/include/plat/marvell/a3700/common/plat_marvell.h
+++ b/include/plat/marvell/a3700/common/plat_marvell.h
@@ -39,6 +39,12 @@
 #endif
 );
 
+/* Console utility functions */
+void marvell_console_boot_init(void);
+void marvell_console_boot_end(void);
+void marvell_console_runtime_init(void);
+void marvell_console_runtime_end(void);
+
 /* IO storage utility functions */
 void marvell_io_setup(void);
 
diff --git a/include/plat/marvell/a8k/common/plat_marvell.h b/include/plat/marvell/a8k/common/plat_marvell.h
index f062491..037548d 100644
--- a/include/plat/marvell/a8k/common/plat_marvell.h
+++ b/include/plat/marvell/a8k/common/plat_marvell.h
@@ -48,6 +48,12 @@
 #endif
 );
 
+/* Console utility functions */
+void marvell_console_boot_init(void);
+void marvell_console_boot_end(void);
+void marvell_console_runtime_init(void);
+void marvell_console_runtime_end(void);
+
 /* IO storage utility functions */
 void marvell_io_setup(void);
 
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index 46b9206..00dde31 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -15,6 +15,7 @@
 INC         = $(INCLUDES:-I%=-I../../%)
 PPFLAGS     = $(INC) $(DEFINES) -P -D__ASSEMBLY__ -D__LINKER__ -MD -MP -MT $(BUILD_DIR)/romlib.ld
 OBJS        = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o
+MAPFILE     = ../../$(BUILD_PLAT)/romlib/romlib.map
 
 V ?= 0
 ifeq ($(V),0)
@@ -25,7 +26,7 @@
 
 ifeq ($(DEBUG),1)
    CFLAGS  := -g
-   LDFLAGS := -g
+   LDFLAGS := -g --gc-sections -O1 -Map=$(MAPFILE)
 endif
 
 
diff --git a/lib/romlib/gen_combined_bl1_romlib.sh b/lib/romlib/gen_combined_bl1_romlib.sh
new file mode 100755
index 0000000..1e3f73a
--- /dev/null
+++ b/lib/romlib/gen_combined_bl1_romlib.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+set -e
+
+output="bl1_romlib.bin"
+
+# Set trap for removing temporary file
+trap 'r=$?;rm -f $bin_path/$$.tmp;exit $r' EXIT HUP QUIT INT TERM
+
+# Read input parameters
+for i
+do
+	case $i in
+	-o)
+		output=$2
+		shift 2
+		;;
+	--)
+		shift
+		break
+		;;
+	-*)
+		echo usage: gen_combined_bl1_romlib.sh [-o output] path_to_build_directory >&2
+		;;
+	esac
+done
+
+
+bin_path=$1
+romlib_path=$1/romlib
+bl1_file="$1/bl1/bl1.elf"
+romlib_file="$1/romlib/romlib.elf"
+bl1_end=""
+romlib_begin=""
+
+# Get address of __BL1_ROM_END__
+bl1_end=`nm -a "$bl1_file" |
+awk '$3 == "__BL1_ROM_END__" {print "0x"$1}'`
+
+# Get start address of romlib "text" section
+romlib_begin=`nm -a "$romlib_file" |
+awk '$3 == ".text" {print "0x"$1}'`
+
+# Character "U" will be read as "55" in hex when it is
+# concatenated with bl1.bin. Generate combined BL1 and ROMLIB
+# binary with filler bytes for juno
+(cat $bin_path/bl1.bin
+ yes U | sed $(($romlib_begin - $bl1_end))q | tr -d '\n'
+ cat $bin_path/romlib/romlib.bin) > $bin_path/$$.tmp &&
+mv $bin_path/$$.tmp $bin_path/$output
diff --git a/lib/romlib/genwrappers.sh b/lib/romlib/genwrappers.sh
index bcf670b..48ee5a4 100755
--- a/lib/romlib/genwrappers.sh
+++ b/lib/romlib/genwrappers.sh
@@ -31,7 +31,7 @@
 done
 
 awk  '{sub(/[:blank:]*#.*/,"")}
-!/^$/ {print $1*4, $2, $3}' "$@" |
+!/^$/ && !/\\tpatch$/ {print $1*4, $2, $3}' "$@" |
 while read idx lib sym
 do
 	file=$build/${lib}_$sym
diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i
index 338cd8a..5eca5aa 100644
--- a/lib/romlib/jmptbl.i
+++ b/lib/romlib/jmptbl.i
@@ -3,6 +3,10 @@
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
+# Format:
+# index	lib	function	[patch]
+# Add "patch" at the end of the line to patch a function. For example:
+# 14	mbedtls	mbedtls_memory_buffer_alloc_init	patch
 
 0	rom	rom_lib_init
 1	fdt	fdt_getprop_namelen
@@ -27,9 +31,10 @@
 20	mbedtls	mbedtls_pk_init
 21	mbedtls	mbedtls_pk_parse_subpubkey
 22	mbedtls	mbedtls_pk_verify_ext
-23	mbedtls	mbedtls_platform_set_snprintf
-24	mbedtls	mbedtls_x509_get_rsassa_pss_params
-25	mbedtls	mbedtls_x509_get_sig_alg
-26	mbedtls	mbedtls_md_info_from_type
-27	c	exit
-28	c	atexit
+23	mbedtls	mbedtls_platform_set_calloc_free
+24	mbedtls	mbedtls_platform_set_snprintf
+25	mbedtls	mbedtls_x509_get_rsassa_pss_params
+26	mbedtls	mbedtls_x509_get_sig_alg
+27	mbedtls	mbedtls_md_info_from_type
+28	c	exit
+29	c	atexit
\ No newline at end of file
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index f180774..b887427 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -38,6 +38,25 @@
 	mmap_add_ctx(&tf_xlat_ctx, mm);
 }
 
+void mmap_add_region_alloc_va(unsigned long long base_pa, uintptr_t *base_va,
+			      size_t size, unsigned int attr)
+{
+	mmap_region_t mm = MAP_REGION_ALLOC_VA(base_pa, size, attr);
+
+	mmap_add_region_alloc_va_ctx(&tf_xlat_ctx, &mm);
+
+	*base_va = mm.base_va;
+}
+
+void mmap_add_alloc_va(mmap_region_t *mm)
+{
+	while (mm->granularity != 0U) {
+		assert(mm->base_va == 0U);
+		mmap_add_region_alloc_va_ctx(&tf_xlat_ctx, mm);
+		mm++;
+	}
+}
+
 #if PLAT_XLAT_TABLES_DYNAMIC
 
 int mmap_add_dynamic_region(unsigned long long base_pa, uintptr_t base_va,
@@ -48,6 +67,20 @@
 	return mmap_add_dynamic_region_ctx(&tf_xlat_ctx, &mm);
 }
 
+int mmap_add_dynamic_region_alloc_va(unsigned long long base_pa,
+				     uintptr_t *base_va, size_t size,
+				     unsigned int attr)
+{
+	mmap_region_t mm = MAP_REGION_ALLOC_VA(base_pa, size, attr);
+
+	int rc = mmap_add_dynamic_region_alloc_va_ctx(&tf_xlat_ctx, &mm);
+
+	*base_va = mm.base_va;
+
+	return rc;
+}
+
+
 int mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
 {
 	return mmap_remove_dynamic_region_ctx(&tf_xlat_ctx,
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index 8ced76e..185473a 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -811,6 +811,80 @@
 		ctx->max_va = end_va;
 }
 
+/*
+ * Determine the table level closest to the initial lookup level that
+ * can describe this translation. Then, align base VA to the next block
+ * at the determined level.
+ */
+static void mmap_alloc_va_align_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
+{
+	/*
+	 * By or'ing the size and base PA the alignment will be the one
+	 * corresponding to the smallest boundary of the two of them.
+	 *
+	 * There are three different cases. For example (for 4 KiB page size):
+	 *
+	 * +--------------+------------------++--------------+
+	 * | PA alignment | Size multiple of || VA alignment |
+	 * +--------------+------------------++--------------+
+	 * |     2 MiB    |       2 MiB      ||     2 MiB    | (1)
+	 * |     2 MiB    |       4 KiB      ||     4 KiB    | (2)
+	 * |     4 KiB    |       2 MiB      ||     4 KiB    | (3)
+	 * +--------------+------------------++--------------+
+	 *
+	 * - In (1), it is possible to take advantage of the alignment of the PA
+	 *   and the size of the region to use a level 2 translation table
+	 *   instead of a level 3 one.
+	 *
+	 * - In (2), the size is smaller than a block entry of level 2, so it is
+	 *   needed to use a level 3 table to describe the region or the library
+	 *   will map more memory than the desired one.
+	 *
+	 * - In (3), even though the region has the size of one level 2 block
+	 *   entry, it isn't possible to describe the translation with a level 2
+	 *   block entry because of the alignment of the base PA.
+	 *
+	 *   Only bits 47:21 of a level 2 block descriptor are used by the MMU,
+	 *   bits 20:0 of the resulting address are 0 in this case. Because of
+	 *   this, the PA generated as result of this translation is aligned to
+	 *   2 MiB. The PA that was requested to be mapped is aligned to 4 KiB,
+	 *   though, which means that the resulting translation is incorrect.
+	 *   The only way to prevent this is by using a finer granularity.
+	 */
+	unsigned long long align_check;
+
+	align_check = mm->base_pa | (unsigned long long)mm->size;
+
+	/*
+	 * Assume it is always aligned to level 3. There's no need to check that
+	 * level because its block size is PAGE_SIZE. The checks to verify that
+	 * the addresses and size are aligned to PAGE_SIZE are inside
+	 * mmap_add_region.
+	 */
+	for (unsigned int level = ctx->base_level; level <= 2U; ++level) {
+
+		if ((align_check & XLAT_BLOCK_MASK(level)) != 0U)
+			continue;
+
+		mm->base_va = round_up(mm->base_va, XLAT_BLOCK_SIZE(level));
+		return;
+	}
+}
+
+void mmap_add_region_alloc_va_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
+{
+	mm->base_va = ctx->max_va + 1UL;
+
+	assert(mm->size > 0U);
+
+	mmap_alloc_va_align_ctx(ctx, mm);
+
+	/* Detect overflows. More checks are done in mmap_add_region_check(). */
+	assert(mm->base_va > ctx->max_va);
+
+	mmap_add_region_ctx(ctx, mm);
+}
+
 void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
 {
 	const mmap_region_t *mm_cursor = mm;
@@ -931,6 +1005,23 @@
 	return 0;
 }
 
+int mmap_add_dynamic_region_alloc_va_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
+{
+	mm->base_va = ctx->max_va + 1UL;
+
+	if (mm->size == 0U)
+		return 0;
+
+	mmap_alloc_va_align_ctx(ctx, mm);
+
+	/* Detect overflows. More checks are done in mmap_add_region_check(). */
+	if (mm->base_va < ctx->max_va) {
+		return -ENOMEM;
+	}
+
+	return mmap_add_dynamic_region_ctx(ctx, mm);
+}
+
 /*
  * Removes the region with given base Virtual Address and size from the given
  * context.
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index e186fc1..d60a5bf 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -338,7 +338,7 @@
 LDLIBS += -l$(1)
 
 ifeq ($(USE_ROMLIB),1)
-LDLIBS := -lwrappers -lc
+LIBWRAPPER = -lwrappers
 endif
 
 all: ${LIB_DIR}/lib$(1).a
@@ -402,7 +402,7 @@
 endif
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \
 		--script $(LINKERFILE) $(BUILD_DIR)/build_message.o \
-		$(OBJS) $(LDPATHS) $(LDLIBS) $(BL_LIBS)
+		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 
 $(DUMP): $(ELF)
 	$${ECHO} "  OD      $$@"
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 8f597c3..2c66329 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -11,6 +11,7 @@
 #include <generic_delay_timer.h>
 #include <gicv2.h>
 #include <libfdt.h>
+#include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
 #include <sunxi_def.h>
@@ -148,6 +149,25 @@
 
 	sunxi_security_setup();
 
+	/*
+	 * On the A64 U-Boot's SPL sets the bus clocks to some conservative
+	 * values, to work around FEL mode instabilities with SRAM C accesses.
+	 * FEL mode is gone when we reach ATF, so bring the AHB1 bus
+	 * (the "main" bus) clock frequency back to the recommended 200MHz,
+	 * for improved performance.
+	 */
+	if (soc_id == SUNXI_SOC_A64)
+		mmio_write_32(SUNXI_CCU_BASE + 0x54, 0x00003180);
+
+	/*
+	 * U-Boot or the kernel don't setup AHB2, which leaves it at the
+	 * AHB1 frequency (200 MHz, see above). However Allwinner recommends
+	 * 300 MHz, for improved Ethernet and USB performance. Switch the
+	 * clock to use "PLL_PERIPH0 / 2".
+	 */
+	if (soc_id == SUNXI_SOC_A64 || soc_id == SUNXI_SOC_H5)
+		mmio_write_32(SUNXI_CCU_BASE + 0x5c, 0x1);
+
 	sunxi_pmic_setup(soc_id, fdt);
 
 	INFO("BL31: Platform setup done\n");
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index af30477..59feed7 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -118,7 +118,7 @@
 	return rsb_write(AXP803_RT_ADDR, reg, val);
 }
 
-static int axp_setbits(uint8_t reg, uint8_t set_mask)
+static int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
 {
 	uint8_t regval;
 	int ret;
@@ -127,11 +127,14 @@
 	if (ret < 0)
 		return ret;
 
-	regval = ret | set_mask;
+	regval = (ret & ~clr_mask) | set_mask;
 
 	return rsb_write(AXP803_RT_ADDR, reg, regval);
 }
 
+#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
+#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
+
 static bool should_enable_regulator(const void *fdt, int node)
 {
 	if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
@@ -178,8 +181,9 @@
 	unsigned char switch_reg;
 	unsigned char switch_bit;
 } regulators[] = {
-	{"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0xff, 9},
-	{"dcdc5",  800, 1840,  10,       32, 0x24, 0xff, 9},
+	{"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0x10, 0},
+	{"dcdc5",  800, 1840,  10,       32, 0x24, 0x10, 4},
+	{"dcdc6",  600, 1520,  10,       50, 0x25, 0x10, 5},
 	{"dldo1",  700, 3300, 100, NO_SPLIT, 0x15, 0x12, 3},
 	{"dldo2",  700, 4200, 100,       27, 0x16, 0x12, 4},
 	{"dldo3",  700, 3300, 100, NO_SPLIT, 0x17, 0x12, 5},
@@ -226,8 +230,11 @@
 		return;
 	}
 
-	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL))
-		axp_setbits(0x8f, BIT(4));
+	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
+		axp_clrbits(0x8f, BIT(4));
+		axp_setbits(0x30, BIT(2));
+		INFO("PMIC: AXP803: Enabling DRIVEVBUS\n");
+	}
 
 	/* descend into the "regulators" subnode */
 	node = fdt_first_subnode(fdt, node);
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 4fd4aef..58b68ab 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -268,4 +268,6 @@
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(ARM_SP_IMAGE_NS_BUF_BASE +	\
 					 ARM_SP_IMAGE_NS_BUF_SIZE)
 
+#define PLAT_SP_PRI			PLAT_RAS_PRI
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 735e4a3..0bbe3e1 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -55,7 +55,8 @@
 #define PLAT_ARM_TRUSTED_SRAM_SIZE	UL(0x00040000)	/* 256 KB */
 
 /* Use the bypass address */
-#define PLAT_ARM_TRUSTED_ROM_BASE	V2M_FLASH0_BASE + BL1_ROM_BYPASS_OFFSET
+#define PLAT_ARM_TRUSTED_ROM_BASE	(V2M_FLASH0_BASE + \
+					BL1_ROM_BYPASS_OFFSET)
 
 #define NSRAM_BASE			UL(0x2e000000)
 #define NSRAM_SIZE			UL(0x00008000)	/* 32KB */
@@ -64,11 +65,22 @@
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
 
 /*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0x1000)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0xe000)
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0)
+#endif
+
+/*
  * Actual ROM size on Juno is 64 KB, but TBB currently requires at least 80 KB
  * in debug mode. We can test TBB on Juno bypassing the ROM and using 128 KB of
  * flash
  */
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0
 
 #if TRUSTED_BOARD_BOOT
 #define PLAT_ARM_TRUSTED_ROM_SIZE	UL(0x00020000)
@@ -121,15 +133,6 @@
 #endif
 
 /*
- * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
- */
-#if USE_ROMLIB
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0x1000)
-#else
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
-#endif
-
-/*
  * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
  * little space for growth.
  */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index f28139d..ba1acd4 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -96,6 +96,14 @@
   Please set RESET_TO_BL31 to 0.")
 endif
 
+ifeq ($(USE_ROMLIB),1)
+all : bl1_romlib.bin
+endif
+
+bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/romlib/romlib.bin
+	@echo "Building combined BL1 and ROMLIB binary for Juno $@"
+	./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT)
+
 # Errata workarounds for Cortex-A53:
 ERRATA_A53_826319		:=	1
 ERRATA_A53_835769		:=	1
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index 1870fc7..c06a0a1 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -8,11 +8,16 @@
 #define PLATFORM_DEF_H
 
 #include <sgi_base_platform_def.h>
+#include <utils_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		2
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	4
 #define CSS_SGI_MAX_PE_PER_CPU		1
 
-#define PLAT_CSS_MHU_BASE		0x45000000
+#define PLAT_CSS_MHU_BASE		UL(0x45000000)
+
+/* Base address of DMC-620 instances */
+#define SGI575_DMC620_BASE0		UL(0x4e000000)
+#define SGI575_DMC620_BASE1		UL(0x4e100000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index 8df8b12..dd82d29 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -14,7 +14,9 @@
 
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}
 
-BL2_SOURCES		+=	lib/utils/mem_region.c			\
+BL2_SOURCES		+=	${SGI575_BASE}/sgi575_security.c	\
+				drivers/arm/tzc/tzc_dmc620.c		\
+				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
 BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
diff --git a/plat/arm/board/sgi575/sgi575_security.c b/plat/arm/board/sgi575/sgi575_security.c
new file mode 100644
index 0000000..7ccc59a
--- /dev/null
+++ b/plat/arm/board/sgi575/sgi575_security.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <platform_def.h>
+#include <tzc_dmc620.h>
+
+uintptr_t sgi575_dmc_base[] = {
+	SGI575_DMC620_BASE0,
+	SGI575_DMC620_BASE1
+};
+
+static const tzc_dmc620_driver_data_t sgi575_plat_driver_data = {
+	.dmc_base = sgi575_dmc_base,
+	.dmc_count = ARRAY_SIZE(sgi575_dmc_base)
+};
+
+static const tzc_dmc620_acc_addr_data_t sgi575_acc_addr_data[] = {
+	{
+		.region_base = ARM_AP_TZC_DRAM1_BASE,
+		.region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1,
+		.sec_attr = TZC_DMC620_REGION_S_RDWR
+	}
+};
+
+static const tzc_dmc620_config_data_t sgi575_plat_config_data = {
+	.plat_drv_data = &sgi575_plat_driver_data,
+	.plat_acc_addr_data = sgi575_acc_addr_data,
+	.acc_addr_count = ARRAY_SIZE(sgi575_acc_addr_data)
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+	arm_tzc_dmc620_setup(&sgi575_plat_config_data);
+}
diff --git a/plat/arm/board/sgiclarka/include/platform_def.h b/plat/arm/board/sgiclarka/include/platform_def.h
index abc48d8..ba6d043 100644
--- a/plat/arm/board/sgiclarka/include/platform_def.h
+++ b/plat/arm/board/sgiclarka/include/platform_def.h
@@ -8,11 +8,16 @@
 #define PLATFORM_DEF_H
 
 #include <sgi_base_platform_def.h>
+#include <utils_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		2
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	4
 #define CSS_SGI_MAX_PE_PER_CPU		1
 
-#define PLAT_CSS_MHU_BASE		0x45400000
+#define PLAT_CSS_MHU_BASE		UL(0x45400000)
+
+/* Base address of DMC-620 instances */
+#define SGICLARKA_DMC620_BASE0		UL(0x4e000000)
+#define SGICLARKA_DMC620_BASE1		UL(0x4e100000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgiclarka/platform.mk b/plat/arm/board/sgiclarka/platform.mk
index fc2f766..cf02219 100644
--- a/plat/arm/board/sgiclarka/platform.mk
+++ b/plat/arm/board/sgiclarka/platform.mk
@@ -14,7 +14,9 @@
 
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}
 
-BL2_SOURCES		+=	lib/utils/mem_region.c			\
+BL2_SOURCES		+=	${SGICLARKA_BASE}/sgiclarka_security.c	\
+				drivers/arm/tzc/tzc_dmc620.c		\
+				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
 BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
diff --git a/plat/arm/board/sgiclarka/sgiclarka_security.c b/plat/arm/board/sgiclarka/sgiclarka_security.c
new file mode 100644
index 0000000..29cd754
--- /dev/null
+++ b/plat/arm/board/sgiclarka/sgiclarka_security.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <platform_def.h>
+#include <tzc_dmc620.h>
+
+uintptr_t sgiclarka_dmc_base[] = {
+	SGICLARKA_DMC620_BASE0,
+	SGICLARKA_DMC620_BASE1
+};
+
+static const tzc_dmc620_driver_data_t sgiclarka_plat_driver_data = {
+	.dmc_base = sgiclarka_dmc_base,
+	.dmc_count = ARRAY_SIZE(sgiclarka_dmc_base)
+};
+
+static const tzc_dmc620_acc_addr_data_t sgiclarka_acc_addr_data[] = {
+	{
+		.region_base = ARM_AP_TZC_DRAM1_BASE,
+		.region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1,
+		.sec_attr = TZC_DMC620_REGION_S_RDWR
+	}
+};
+
+static const tzc_dmc620_config_data_t sgiclarka_plat_config_data = {
+	.plat_drv_data = &sgiclarka_plat_driver_data,
+	.plat_acc_addr_data = sgiclarka_acc_addr_data,
+	.acc_addr_count = ARRAY_SIZE(sgiclarka_acc_addr_data)
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+	arm_tzc_dmc620_setup(&sgiclarka_plat_config_data);
+}
diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c
index 665871b..f313851 100644
--- a/plat/arm/common/aarch64/arm_ehf.c
+++ b/plat/arm/common/aarch64/arm_ehf.c
@@ -23,6 +23,9 @@
 	/* Normal priority SDEI */
 	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
 #endif
+#if ENABLE_SPM
+	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI),
+#endif
 };
 
 /* Plug in ARM exceptions to Exception Handling Framework. */
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index b72dd20..56ad8ae 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -128,10 +128,10 @@
 	/*
 	 * Initialize CNTFRQ register in Non-secure CNTBase frame.
 	 * This is only required for Juno, because it doesn't follow ARM ARM
-	 * in that the value updated in CNTFRQ is not reflected in CNTBASE_CNTFRQ.
-	 * Hence update the value manually.
+	 * in that the value updated in CNTFRQ is not reflected in
+	 * CNTBASEN_CNTFRQ. Hence update the value manually.
 	 */
-	mmio_write_32(ARM_SYS_CNT_BASE_NS + CNTBASE_CNTFRQ, freq_val);
+	mmio_write_32(ARM_SYS_CNT_BASE_NS + CNTBASEN_CNTFRQ, freq_val);
 #endif
 }
 #endif /* ARM_SYS_TIMCTL_BASE */
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 90eb336..1395373 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -142,6 +142,8 @@
 					SOC_CSS_DEVICE_SIZE,	\
 					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
+#define PLAT_SP_PRI				PLAT_RAS_PRI
+
 #if RAS_EXTENSION
 /* Allocate 128KB for CPER buffers */
 #define PLAT_SP_BUF_BASE			ULL(0x20000)
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index d6e5448..46fa7c4 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -35,8 +35,7 @@
 
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}
 
-BL2_SOURCES		+=	${CSS_ENT_BASE}/sgi_security.c		\
-				${CSS_ENT_BASE}/sgi_image_load.c
+BL2_SOURCES		+=	${CSS_ENT_BASE}/sgi_image_load.c
 
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}			\
 				${ENT_GIC_SOURCES}			\
diff --git a/plat/arm/css/sgi/sgi_security.c b/plat/arm/css/sgi/sgi_security.c
deleted file mode 100644
index 23e1a64..0000000
--- a/plat/arm/css/sgi/sgi_security.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arm_config.h>
-#include <plat_arm.h>
-
-/*
- * We assume that all security programming is done by the primary core.
- */
-void plat_arm_security_setup(void)
-{
-}
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index 791076c..d42afe0 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -336,7 +336,7 @@
 	params.flags = MMC_FLAG_CMD23;
 	info.mmc_dev_type = MMC_IS_EMMC;
 	dw_mmc_init(&params, &info);
-	mdelay(5);
+	mdelay(20);
 
 	hikey_io_setup();
 }
diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk
index ff96394..3983c70 100644
--- a/plat/marvell/a3700/common/a3700_common.mk
+++ b/plat/marvell/a3700/common/a3700_common.mk
@@ -71,7 +71,6 @@
 				$(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0
 DOIMAGE_FLAGS		:= -r $(DOIMAGE_CFG) -v -D
 
-
 # GICV3
 $(eval $(call add_define,CONFIG_GICV3))
 
@@ -91,8 +90,8 @@
 PLAT_INCLUDES		:=	-I$(PLAT_FAMILY_BASE)/$(PLAT)		\
 				-I$(PLAT_COMMON_BASE)/include		\
 				-I$(PLAT_INCLUDE_BASE)/common		\
-				-I$(MARVELL_DRV_BASE)/uart		\
 				-I$(MARVELL_DRV_BASE)			\
+				-Iinclude/drivers/marvell/uart		\
 				-I$/drivers/arm/gic/common/		\
 				$(ATF_INCLUDES)
 
@@ -159,12 +158,12 @@
 	@truncate -s %16 $(WTMI_MULTI_IMG)
 	@openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \
 	-out $(WTMI_ENC_IMG) \
-	-K `cat $(IMAGESPATH)/aes-256.txt` -k 0 -nosalt \
+	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
 	@truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
 	@openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
 	-out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \
-	-K `cat $(IMAGESPATH)/aes-256.txt` -k 0 -nosalt \
+	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
 endif
 	$(DOIMAGETOOL) $(DOIMAGE_FLAGS)
diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk
index a589004..6136a1f 100644
--- a/plat/marvell/a8k/common/a8k_common.mk
+++ b/plat/marvell/a8k/common/a8k_common.mk
@@ -25,7 +25,6 @@
 $(eval $(call add_define,PCI_EP_SUPPORT))
 $(eval $(call assert_boolean,PCI_EP_SUPPORT))
 
-
 AP_NUM			:= 1
 $(eval $(call add_define,AP_NUM))
 
diff --git a/plat/marvell/a8k/common/ble/ble.mk b/plat/marvell/a8k/common/ble/ble.mk
index a76083e..5f24ced 100644
--- a/plat/marvell/a8k/common/ble/ble.mk
+++ b/plat/marvell/a8k/common/ble/ble.mk
@@ -12,8 +12,9 @@
 
 BLE_SOURCES		+= 	$(BLE_PATH)/ble_main.c				\
 				$(BLE_PATH)/ble_mem.S				\
-				drivers/delay_timer/delay_timer.c	\
-				$(PLAT_MARVELL)/common/plat_delay_timer.c
+				drivers/delay_timer/delay_timer.c		\
+				$(PLAT_MARVELL)/common/plat_delay_timer.c	\
+				$(PLAT_MARVELL)/common/marvell_console.c
 
 PLAT_INCLUDES		+= 	-I$(MV_DDR_PATH) \
 				-I$(CURDIR)/include/ \
diff --git a/plat/marvell/a8k/common/ble/ble_main.c b/plat/marvell/a8k/common/ble/ble_main.c
index e52c738..b04e8b7 100644
--- a/plat/marvell/a8k/common/ble/ble_main.c
+++ b/plat/marvell/a8k/common/ble/ble_main.c
@@ -35,13 +35,11 @@
 	 * initialize the console and prints will be ignored
 	 */
 	if ((bootrom_flags & BR_FLAG_SILENT) == 0)
-		console_init(PLAT_MARVELL_BOOT_UART_BASE,
-			     PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-			     MARVELL_CONSOLE_BAUDRATE);
+		marvell_console_boot_init();
 
 	NOTICE("Starting binary extension\n");
 
-	/* initiliaze time (for delay functionality) */
+	/* initialize time (for delay functionality) */
 	plat_delay_timer_init();
 
 	ble_plat_setup(&skip);
diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c
index 0c74b2f..1b68d07 100644
--- a/plat/marvell/a8k/common/plat_pm.c
+++ b/plat/marvell/a8k/common/plat_pm.c
@@ -19,7 +19,6 @@
 #include <plat_marvell.h>
 #include <platform.h>
 #include <plat_pm_trace.h>
-#include <platform.h>
 
 #define MVEBU_PRIVATE_UID_REG		0x30
 #define MVEBU_RFU_GLOBL_SW_RST		0x84
@@ -614,6 +613,8 @@
 
 		INFO("Suspending to RAM\n");
 
+		marvell_console_runtime_end();
+
 		/* Prevent interrupts from spuriously waking up this cpu */
 		gicv2_cpuif_disable();
 
@@ -687,9 +688,7 @@
 			/* Initialize the console to provide
 			 * early debug support
 			 */
-			console_init(PLAT_MARVELL_BOOT_UART_BASE,
-			PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-			MARVELL_CONSOLE_BAUDRATE);
+			marvell_console_runtime_init();
 
 			bl31_plat_arch_setup();
 			marvell_bl31_platform_setup();
diff --git a/plat/marvell/common/aarch64/marvell_helpers.S b/plat/marvell/common/aarch64/marvell_helpers.S
index 128c3ab..fbd19cb 100644
--- a/plat/marvell/common/aarch64/marvell_helpers.S
+++ b/plat/marvell/common/aarch64/marvell_helpers.S
@@ -65,7 +65,11 @@
 	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
 	mov_imm	x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ
 	mov_imm	x2, MARVELL_CONSOLE_BAUDRATE
-	b	console_core_init
+#ifdef PLAT_a3700
+	b	console_a3700_core_init
+#else
+	b	console_16550_core_init
+#endif
 endfunc plat_crash_console_init
 
 	/* ---------------------------------------------
@@ -77,7 +81,12 @@
 	 */
 func plat_crash_console_putc
 	mov_imm	x1, PLAT_MARVELL_CRASH_UART_BASE
-	b	console_core_putc
+#ifdef PLAT_a3700
+
+	b	console_a3700_core_putc
+#else
+	b	console_16550_core_putc
+#endif
 endfunc plat_crash_console_putc
 
 	/* ---------------------------------------------
@@ -85,12 +94,16 @@
 	 * Function to force a write of all buffered
 	 * data that hasn't been output.
 	 * Out : return -1 on error else return 0.
-	 * Clobber list : x0, x1
+	 * Clobber list : r0
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_flush
 	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
-	b	console_core_flush
+#ifdef PLAT_a3700
+	b	console_a3700_core_flush
+#else
+	b	console_16550_core_flush
+#endif
 endfunc plat_crash_console_flush
 
 	/* ---------------------------------------------------------------------
diff --git a/plat/marvell/common/marvell_bl1_setup.c b/plat/marvell/common/marvell_bl1_setup.c
index 4e1b256..c96f006 100644
--- a/plat/marvell/common/marvell_bl1_setup.c
+++ b/plat/marvell/common/marvell_bl1_setup.c
@@ -35,9 +35,7 @@
 void marvell_bl1_early_platform_setup(void)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_MARVELL_BOOT_UART_BASE,
-		     PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-		     MARVELL_CONSOLE_BAUDRATE);
+	marvell_console_boot_init();
 
 	/* Allow BL1 to see the whole Trusted RAM */
 	bl1_ram_layout.total_base = MARVELL_BL_RAM_BASE;
diff --git a/plat/marvell/common/marvell_bl2_setup.c b/plat/marvell/common/marvell_bl2_setup.c
index d33aba4..883336f 100644
--- a/plat/marvell/common/marvell_bl2_setup.c
+++ b/plat/marvell/common/marvell_bl2_setup.c
@@ -40,9 +40,7 @@
 void marvell_bl2_early_platform_setup(meminfo_t *mem_layout)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_MARVELL_BOOT_UART_BASE,
-		     PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-		     MARVELL_CONSOLE_BAUDRATE);
+	marvell_console_boot_init();
 
 	/* Setup the BL2 memory layout */
 	bl2_tzram_layout = *mem_layout;
diff --git a/plat/marvell/common/marvell_bl31_setup.c b/plat/marvell/common/marvell_bl31_setup.c
index da91b56..3b1a6f1 100644
--- a/plat/marvell/common/marvell_bl31_setup.c
+++ b/plat/marvell/common/marvell_bl31_setup.c
@@ -74,9 +74,7 @@
 				       void *plat_params_from_bl2)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_MARVELL_BOOT_UART_BASE,
-		     PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-		     MARVELL_CONSOLE_BAUDRATE);
+	marvell_console_boot_init();
 
 #if RESET_TO_BL31
 	/* There are no parameters from BL2 if BL31 is a reset vector */
@@ -190,10 +188,10 @@
  */
 void marvell_bl31_plat_runtime_setup(void)
 {
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+
 	/* Initialize the runtime console */
-	console_init(PLAT_MARVELL_BL31_RUN_UART_BASE,
-		     PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ,
-		     MARVELL_CONSOLE_BAUDRATE);
+	marvell_console_runtime_init();
 }
 
 void bl31_platform_setup(void)
diff --git a/plat/marvell/common/marvell_common.mk b/plat/marvell/common/marvell_common.mk
index 3a6bb03..fb6fbb5 100644
--- a/plat/marvell/common/marvell_common.mk
+++ b/plat/marvell/common/marvell_common.mk
@@ -11,6 +11,8 @@
 
 VERSION_STRING			+=(Marvell-${SUBVERSION})
 
+MULTI_CONSOLE_API		:= 1
+
 SEPARATE_CODE_AND_RODATA	:= 1
 
 # flag to switch from PLL to ARO
@@ -28,7 +30,8 @@
 PLAT_BL_COMMON_SOURCES  +=      lib/xlat_tables/xlat_tables_common.c			\
 				lib/xlat_tables/aarch64/xlat_tables.c			\
 				$(MARVELL_PLAT_BASE)/common/aarch64/marvell_common.c	\
-				$(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S
+				$(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S	\
+				$(MARVELL_COMMON_BASE)/marvell_console.c
 
 BL1_SOURCES		+=	drivers/delay_timer/delay_timer.c			\
 				drivers/io/io_fip.c					\
diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c
new file mode 100644
index 0000000..eba106d
--- /dev/null
+++ b/plat/marvell/common/marvell_console.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <plat_marvell.h>
+#include <platform_def.h>
+
+#ifdef PLAT_a3700
+#include <a3700_console.h>
+
+static console_a3700_t marvell_boot_console;
+static console_a3700_t marvell_runtime_console;
+#else
+#include <uart_16550.h>
+
+static console_16550_t marvell_boot_console;
+static console_16550_t marvell_runtime_console;
+#endif
+
+/*******************************************************************************
+ * Functions that set up the console
+ ******************************************************************************/
+
+/* Initialize the console to provide early debug support */
+void marvell_console_boot_init(void)
+{
+	int rc =
+#ifdef PLAT_a3700
+	console_a3700_register(
+#else
+	console_16550_register(
+#endif
+				PLAT_MARVELL_BOOT_UART_BASE,
+				PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+				MARVELL_CONSOLE_BAUDRATE,
+				&marvell_boot_console);
+	if (rc == 0) {
+		/*
+		 * The crash console doesn't use the multi console API, it uses
+		 * the core console functions directly. It is safe to call panic
+		 * and let it print debug information.
+		 */
+		panic();
+	}
+
+	console_set_scope(&marvell_boot_console.console,
+			  CONSOLE_FLAG_BOOT);
+}
+
+void marvell_console_boot_end(void)
+{
+	(void)console_flush();
+
+	(void)console_unregister(&marvell_boot_console.console);
+}
+
+/* Initialize the runtime console */
+void marvell_console_runtime_init(void)
+{
+	int rc =
+#ifdef PLAT_a3700
+	console_a3700_register(
+#else
+	console_16550_register(
+#endif
+				PLAT_MARVELL_BOOT_UART_BASE,
+				PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+				MARVELL_CONSOLE_BAUDRATE,
+				&marvell_runtime_console);
+	if (rc == 0)
+		panic();
+
+	console_set_scope(&marvell_runtime_console.console,
+			  CONSOLE_FLAG_RUNTIME);
+}
+
+void marvell_console_runtime_end(void)
+{
+	(void)console_flush();
+
+	(void)console_unregister(&marvell_runtime_console.console);
+}
diff --git a/plat/renesas/rcar/bl2_secure_setting.c b/plat/renesas/rcar/bl2_secure_setting.c
index 35c658c..c0d49de 100644
--- a/plat/renesas/rcar/bl2_secure_setting.c
+++ b/plat/renesas/rcar/bl2_secure_setting.c
@@ -66,7 +66,9 @@
 	    /*      {SEC_SEL12,             0xFFFFFFFFU},                   */
 	    /* Bit22: RPC slave ports.                                      */
 	    /*        0: registers accessed from secure resource only.      */
-	    /* {SEC_SEL13,          0xFFBFFFFFU},*/
+#if (RCAR_RPC_HYPERFLASH_LOCKED == 1)
+	    {SEC_SEL13,          0xFFBFFFFFU},
+#endif
 	    /* Bit27: System Timer (SCMT) slave ports                       */
 	    /*        0: registers accessed from secure resource only       */
 	    /* Bit26: System Watchdog Timer (SWDT) slave ports              */
@@ -183,8 +185,10 @@
 	/** Security group 1 attribute setting for slave ports 13	*/
 	    /* Bit22: RPC slave ports.                                      */
 	    /*        SecurityGroup3                                        */
-	    /* {SEC_GRP0COND13,     0x00400000U}, */
-	    /* {SEC_GRP1COND13,     0x00400000U}, */
+#if (RCAR_RPC_HYPERFLASH_LOCKED == 1)
+	    {SEC_GRP0COND13,     0x00400000U},
+	    {SEC_GRP1COND13,     0x00400000U},
+#endif
 	/** Security group 0 attribute setting for slave ports 14	*/
 	/** Security group 1 attribute setting for slave ports 14	*/
 	    /* Bit26: System Timer (SCMT) slave ports                       */
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 95b7902..f7d6216 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -137,6 +137,13 @@
   $(eval $(call add_define,RCAR_LSI))
 endif
 
+# lock RPC HYPERFLASH access by default
+# unlock to repogram the ATF firmware from u-boot
+ifndef RCAR_RPC_HYPERFLASH_LOCKED
+RCAR_RPC_HYPERFLASH_LOCKED := 1
+endif
+$(eval $(call add_define,RCAR_RPC_HYPERFLASH_LOCKED))
+
 # Process RCAR_SECURE_BOOT flag
 ifndef RCAR_SECURE_BOOT
 RCAR_SECURE_BOOT := 1
diff --git a/plat/rpi3/include/platform_def.h b/plat/rpi3/include/platform_def.h
index 7122401..3b12c30 100644
--- a/plat/rpi3/include/platform_def.h
+++ b/plat/rpi3/include/platform_def.h
@@ -63,6 +63,25 @@
  * secure DRAM. Note that this is all actually DRAM with different names,
  * there is no Secure RAM in the Raspberry Pi 3.
  */
+#if RPI3_USE_UEFI_MAP
+#define SEC_ROM_BASE			ULL(0x00000000)
+#define SEC_ROM_SIZE			ULL(0x00010000)
+
+/* FIP placed after ROM to append it to BL1 with very little padding. */
+#define PLAT_RPI3_FIP_BASE		ULL(0x00020000)
+#define PLAT_RPI3_FIP_MAX_SIZE		ULL(0x00010000)
+
+/* Reserve 2M of secure SRAM and DRAM, starting at 2M */
+#define SEC_SRAM_BASE			ULL(0x00200000)
+#define SEC_SRAM_SIZE			ULL(0x00100000)
+
+#define SEC_DRAM0_BASE			ULL(0x00300000)
+#define SEC_DRAM0_SIZE			ULL(0x00100000)
+
+/* Windows on ARM requires some RAM at 4M */
+#define NS_DRAM0_BASE			ULL(0x00400000)
+#define NS_DRAM0_SIZE			ULL(0x00C00000)
+#else
 #define SEC_ROM_BASE			ULL(0x00000000)
 #define SEC_ROM_SIZE			ULL(0x00020000)
 
@@ -80,6 +99,7 @@
 
 #define NS_DRAM0_BASE			ULL(0x11000000)
 #define NS_DRAM0_SIZE			ULL(0x01000000)
+#endif /* RPI3_USE_UEFI_MAP */
 
 /*
  * BL33 entrypoint.
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index 36c1ee2..db96de8 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -109,6 +109,13 @@
 # Assume that BL33 isn't the Linux kernel by default
 RPI3_DIRECT_LINUX_BOOT		:= 0
 
+# UART to use at runtime. -1 means the runtime UART is disabled.
+# Any other value means the default UART will be used.
+RPI3_RUNTIME_UART		:= -1
+
+# Use normal memory mapping for ROM, FIP, SRAM and DRAM
+RPI3_USE_UEFI_MAP		:= 0
+
 # BL32 location
 RPI3_BL32_RAM_LOCATION	:= tdram
 ifeq (${RPI3_BL32_RAM_LOCATION}, tsram)
@@ -126,6 +133,8 @@
 $(eval $(call add_define,RPI3_BL33_IN_AARCH32))
 $(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT))
 $(eval $(call add_define,RPI3_PRELOADED_DTB_BASE))
+$(eval $(call add_define,RPI3_RUNTIME_UART))
+$(eval $(call add_define,RPI3_USE_UEFI_MAP))
 
 # Verify build config
 # -------------------
diff --git a/plat/rpi3/rpi3_common.c b/plat/rpi3/rpi3_common.c
index 18ff1c8..c7e8b3a 100644
--- a/plat/rpi3/rpi3_common.c
+++ b/plat/rpi3/rpi3_common.c
@@ -96,6 +96,10 @@
 
 void rpi3_console_init(void)
 {
+	int console_scope = CONSOLE_FLAG_BOOT;
+#if RPI3_RUNTIME_UART != -1
+	console_scope |= CONSOLE_FLAG_RUNTIME;
+#endif
 	int rc = console_16550_register(PLAT_RPI3_UART_BASE,
 					PLAT_RPI3_UART_CLK_IN_HZ,
 					PLAT_RPI3_UART_BAUDRATE,
@@ -109,8 +113,7 @@
 		panic();
 	}
 
-	console_set_scope(&rpi3_console.console,
-			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+	console_set_scope(&rpi3_console.console, console_scope);
 }
 
 /*******************************************************************************
diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c
index 9a02312..fdbd4bf 100644
--- a/plat/st/stm32mp1/bl2_io_storage.c
+++ b/plat/st/stm32mp1/bl2_io_storage.c
@@ -37,7 +37,7 @@
 	.length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */
 };
 
-uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
+static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
 
 static const io_block_dev_spec_t mmc_block_dev_spec = {
 	/* It's used as temp buffer in block driver */
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 9f2d8bd..d85ae96 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -8,7 +8,6 @@
 #include <assert.h>
 #include <bl_common.h>
 #include <boot_api.h>
-#include <console.h>
 #include <debug.h>
 #include <delay_timer.h>
 #include <desc_image_load.h>
@@ -16,11 +15,12 @@
 #include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
+#include <stm32_console.h>
 #include <stm32mp1_clk.h>
+#include <stm32mp1_context.h>
 #include <stm32mp1_dt.h>
 #include <stm32mp1_pmic.h>
 #include <stm32mp1_private.h>
-#include <stm32mp1_context.h>
 #include <stm32mp1_pwr.h>
 #include <stm32mp1_ram.h>
 #include <stm32mp1_rcc.h>
@@ -28,6 +28,8 @@
 #include <string.h>
 #include <xlat_tables_v2.h>
 
+static struct console_stm32 console;
+
 void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
 				  u_register_t arg2, u_register_t arg3)
 {
@@ -137,8 +139,8 @@
 
 	clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_dev_info.clock);
 
-	if (console_init(dt_dev_info.base, clk_rate,
-			 STM32MP1_UART_BAUDRATE) == 0) {
+	if (console_stm32_register(dt_dev_info.base, clk_rate,
+				   STM32MP1_UART_BAUDRATE, &console) == 0) {
 		panic();
 	}
 
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index 3c6d677..d5b328e 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -5,6 +5,7 @@
  */
 
 #include <desc_image_load.h>
+#include <platform.h>
 
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 678a852..f4a0ca4 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -8,6 +8,7 @@
 ARM_WITH_NEON		:=	yes
 BL2_AT_EL3		:=	1
 USE_COHERENT_MEM	:=	0
+MULTI_CONSOLE_API	:=	1
 
 STM32_TF_VERSION	?=	0
 
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 56598c8..bd4f2ec 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -7,7 +7,6 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <bl_common.h>
-#include <console.h>
 #include <context.h>
 #include <context_mgmt.h>
 #include <debug.h>
@@ -17,6 +16,7 @@
 #include <platform.h>
 #include <platform_def.h>
 #include <platform_sp_min.h>
+#include <stm32_console.h>
 #include <stm32mp1_clk.h>
 #include <stm32mp1_dt.h>
 #include <stm32mp1_private.h>
@@ -30,6 +30,8 @@
  ******************************************************************************/
 static entry_point_info_t bl33_image_ep_info;
 
+static struct console_stm32 console;
+
 /*******************************************************************************
  * Interrupt handler for FIQ (secure IRQ)
  ******************************************************************************/
@@ -112,8 +114,9 @@
 	result = dt_get_stdout_uart_info(&dt_dev_info);
 
 	if ((result > 0) && dt_dev_info.status) {
-		if (console_init(dt_dev_info.base, 0, STM32MP1_UART_BAUDRATE)
-		    == 0) {
+		if (console_stm32_register(dt_dev_info.base, 0,
+					   STM32MP1_UART_BAUDRATE, &console) ==
+		    0) {
 			panic();
 		}
 	}
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index b0ea0d8..673706e 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -149,7 +149,7 @@
 	ldr	r0, =STM32MP1_DEBUG_USART_BASE
 	ldr	r1, =STM32MP1_HSI_CLK
 	ldr	r2, =STM32MP1_UART_BAUDRATE
-	b	console_core_init
+	b	console_stm32_core_init
 endfunc plat_crash_console_init
 
 	/* ---------------------------------------------
@@ -160,7 +160,7 @@
 	 */
 func plat_crash_console_flush
 	ldr	r1, =STM32MP1_DEBUG_USART_BASE
-	b	console_core_flush
+	b	console_stm32_core_flush
 endfunc plat_crash_console_flush
 
 	/* ---------------------------------------------
@@ -176,5 +176,5 @@
 	 */
 func plat_crash_console_putc
 	ldr	r1, =STM32MP1_DEBUG_USART_BASE
-	b	console_core_putc
+	b	console_stm32_core_putc
 endfunc plat_crash_console_putc
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index e834a2b..fa778c0 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -485,15 +485,14 @@
 	/*
 	 * We reach here when client completes the event.
 	 *
-	 * If the cause of dispatch originally interrupted the Secure world, and
-	 * if Non-secure world wasn't allowed to preempt Secure execution,
+	 * If the cause of dispatch originally interrupted the Secure world,
 	 * resume Secure.
 	 *
 	 * No need to save the Non-secure context ahead of a world switch: the
 	 * Non-secure context was fully saved before dispatch, and has been
 	 * returned to its pre-dispatch state.
 	 */
-	if ((sec_state == SECURE) && (ehf_is_ns_preemption_allowed() == 0U))
+	if (sec_state == SECURE)
 		restore_and_resume_secure_context();
 
 	/*
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index 585707d..880e86e 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -9,6 +9,7 @@
 #include <bl31.h>
 #include <context_mgmt.h>
 #include <debug.h>
+#include <ehf.h>
 #include <errno.h>
 #include <mm_svc.h>
 #include <platform.h>
@@ -233,6 +234,19 @@
 		VERBOSE("MM_COMMUNICATE: comm_size_address is not 0 as recommended.\n");
 	}
 
+	/*
+	 * The current secure partition design mandates
+	 * - at any point, only a single core can be
+	 *   executing in the secure partiton.
+	 * - a core cannot be preempted by an interrupt
+	 *   while executing in secure partition.
+	 * Raise the running priority of the core to the
+	 * interrupt level configured for secure partition
+	 * so as to block any interrupt from preempting this
+	 * core.
+	 */
+	ehf_activate_priority(PLAT_SP_PRI);
+
 	/* Save the Normal world context */
 	cm_el1_sysregs_context_save(NON_SECURE);
 
@@ -243,6 +257,12 @@
 	cm_el1_sysregs_context_restore(NON_SECURE);
 	cm_set_next_eret_context(NON_SECURE);
 
+	/*
+	 * Exited from secure partition. This core can take
+	 * interrupts now.
+	 */
+	ehf_deactivate_priority(PLAT_SP_PRI);
+
 	SMC_RET1(handle, rc);
 }