Platform: Make UART1 non-secure by default

Make UART1 non-secure peripheral by default, which can
be switched to secure using a compile time switch for
demonstration purposes.

Change-Id: I834b7d9a2b42ce55e14ee9f06e244420c9e6ac5b
Signed-off-by: Miklos Balint <miklos.balint@arm.com>
diff --git a/CommonConfig.cmake b/CommonConfig.cmake
index 8fa700d..74f7d79 100755
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -85,6 +85,9 @@
 	add_definitions(-DTARGET_MUSCA_A)
 endif()
 
+# Option to demonstrate usage of secure-only peripheral
+set (SECURE_UART1 OFF)
+
 if (REGRESSION)
 	set(SERVICES_TEST_ENABLED ON)
 else()
diff --git a/platform/ext/Mps2AN519.cmake b/platform/ext/Mps2AN519.cmake
index dfa6c21..4d7cfd6 100755
--- a/platform/ext/Mps2AN519.cmake
+++ b/platform/ext/Mps2AN519.cmake
@@ -51,6 +51,11 @@
 if (NOT DEFINED BUILD_UART_STDOUT)
   message(FATAL_ERROR "Configuration variable BUILD_UART_STDOUT (true|false) is undefined!")
 elseif(BUILD_UART_STDOUT)
+  if (NOT DEFINED SECURE_UART1)
+    message(FATAL_ERROR "Configuration variable SECURE_UART1 (true|false) is undefined!")
+  elseif(SECURE_UART1)
+    add_definitions(-DSECURE_UART1)
+  endif()
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/uart_stdout.c")
   embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
   set(BUILD_NATIVE_DRIVERS true)
diff --git a/platform/ext/Mps2AN521.cmake b/platform/ext/Mps2AN521.cmake
index a740066..9c56ad4 100755
--- a/platform/ext/Mps2AN521.cmake
+++ b/platform/ext/Mps2AN521.cmake
@@ -64,6 +64,11 @@
 if (NOT DEFINED BUILD_UART_STDOUT)
   message(FATAL_ERROR "Configuration variable BUILD_UART_STDOUT (true|false) is undefined!")
 elseif(BUILD_UART_STDOUT)
+  if (NOT DEFINED SECURE_UART1)
+    message(FATAL_ERROR "Configuration variable SECURE_UART1 (true|false) is undefined!")
+  elseif(SECURE_UART1)
+    add_definitions(-DSECURE_UART1)
+  endif()
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/uart_stdout.c")
   embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
   set(BUILD_NATIVE_DRIVERS true)
diff --git a/platform/ext/common/uart_stdout.c b/platform/ext/common/uart_stdout.c
index fbf2d17..8075873 100755
--- a/platform/ext/common/uart_stdout.c
+++ b/platform/ext/common/uart_stdout.c
@@ -71,19 +71,33 @@
     /* Add a configuration step for the UART channel to use, 0 or 1 */

     switch(uchan) {

     case UART0_CHANNEL:

-        /* UART0 is configured as a non-secure peripheral, so we wouldn't be

-         * able to access it using its secure alias. Ideally, we would want

-         * to use UART1 only from S side as it's a secure peripheral, but for

-         * simplicity, leave the option to use UART0 and use a workaround

+        /* UART0 is configured as a non-secure peripheral, so it cannot be

+         * accessed using its secure alias. Ideally the driver would

+         * be configured with the right properties, but for simplicity,

+         * use a workaround for now

          */

 #ifdef TARGET_MUSCA_A

         memcpy(&UART0_DEV_S, &UART0_DEV_NS, sizeof(struct uart_pl011_dev_t));

 #else

-        memcpy(&ARM_UART0_DEV_S, &ARM_UART0_DEV_NS, sizeof(struct arm_uart_dev_t));

+        memcpy(&ARM_UART0_DEV_S, &ARM_UART0_DEV_NS,

+                                                sizeof(struct arm_uart_dev_t));

 #endif

         Driver_USART = &Driver_USART0;

         break;

     case UART1_CHANNEL:

+#ifndef SECURE_UART1

+        /* If UART1 is configured as a non-secure peripheral, it cannot be

+         * accessed using its secure alias. Ideally the driver would

+         * be configured with the right properties, but for simplicity,

+         * use a workaround for now

+         */

+#ifdef TARGET_MUSCA_A

+        memcpy(&UART1_DEV_S, &UART1_DEV_NS, sizeof(struct uart_pl011_dev_t));

+#else

+        memcpy(&ARM_UART1_DEV_S, &ARM_UART1_DEV_NS,

+                                                sizeof(struct arm_uart_dev_t));

+#endif

+#endif

         Driver_USART = &Driver_USART1;

         break;

     default:

diff --git a/platform/ext/musca_a.cmake b/platform/ext/musca_a.cmake
index d90aa26..89edff7 100755
--- a/platform/ext/musca_a.cmake
+++ b/platform/ext/musca_a.cmake
@@ -51,6 +51,11 @@
 if (NOT DEFINED BUILD_UART_STDOUT)
   message(FATAL_ERROR "Configuration variable BUILD_UART_STDOUT (true|false) is undefined!")
 elseif(BUILD_UART_STDOUT)
+  if (NOT DEFINED SECURE_UART1)
+    message(FATAL_ERROR "Configuration variable SECURE_UART1 (true|false) is undefined!")
+  elseif(SECURE_UART1)
+    message(FATAL_ERROR "Configuration SECURE_UART1 TRUE is invalid for this target!")
+  endif()
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/uart_stdout.c")
   embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
   set(BUILD_NATIVE_DRIVERS true)
diff --git a/platform/ext/target/mps2/an519/target_cfg.c b/platform/ext/target/mps2/an519/target_cfg.c
index 64aaba3..3d32b2a 100644
--- a/platform/ext/target/mps2/an519/target_cfg.c
+++ b/platform/ext/target/mps2/an519/target_cfg.c
@@ -76,7 +76,7 @@
      */
 }
 
-/*------------------- NVIC interrupt target state to NS configuration ----------*/
+/*----------------- NVIC interrupt target state to NS configuration ----------*/
 void nvic_interrupt_target_state_cfg()
 {
     /* Target every interrupt to NS; unimplemented interrupts will be WI */
@@ -88,13 +88,15 @@
     NVIC_ClearTargetState(MPC_IRQn);
     NVIC_ClearTargetState(PPC_IRQn);
 
+#ifdef SECURE_UART1
     /* UART1 is a secure peripheral, so its IRQs have to target S state */
     NVIC_ClearTargetState(UARTRX1_IRQn);
     NVIC_ClearTargetState(UARTTX1_IRQn);
     NVIC_ClearTargetState(UART1_IRQn);
+#endif
 }
 
-/*------------------- NVIC interrupt enabling for S peripherals ----------------*/
+/*----------------- NVIC interrupt enabling for S peripherals ----------------*/
 void nvic_interrupt_enable()
 {
     struct spctrl_def* spctrl = CMSDK_SPCTRL;
@@ -123,7 +125,7 @@
     NVIC_EnableIRQ(PPC_IRQn);
 }
 
-/*------------------- SAU/IDAU configuration functions -------------------------*/
+/*------------------- SAU/IDAU configuration functions -----------------------*/
 
 void sau_and_idau_cfg(void)
 {
@@ -150,13 +152,18 @@
     /* Only UART1 is configured as a secure peripheral */
     SAU->RNR  = TFM_NS_REGION_PERIPH_1;
     SAU->RBAR = (PERIPHERALS_BASE_NS_START & SAU_RBAR_BADDR_Msk);
+
+#ifdef SECURE_UART1
+    /* To statically configure a peripheral range as secure, close NS peripheral
+     * region before range, and open a new NS region after the reserved space.
+     */
     SAU->RLAR = ((UART1_BASE_NS-1) & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk;
 
-    /* The UART1 range is considered as a (secure) gap */
-
     SAU->RNR  = TFM_NS_REGION_PERIPH_2;
     SAU->RBAR = (UART2_BASE_NS & SAU_RBAR_BADDR_Msk);
+#endif
+
     SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk;
 
@@ -211,7 +218,13 @@
     spctrl->apbnsppcexp1 |= (1U << CMSDK_SPI3_APB_PPC_POS);
     spctrl->apbnsppcexp1 |= (1U << CMSDK_SPI4_APB_PPC_POS);
     spctrl->apbnsppcexp1 |= (1U << CMSDK_UART0_APB_PPC_POS);
-    /* Do not do it for UART1 as it's a Secure peripheral */
+#ifdef SECURE_UART1
+    /* To statically configure a peripheral as secure, skip PPC NS peripheral
+     * configuration for the given device.
+     */
+#else
+    spctrl->apbnsppcexp1 |= (1U << CMSDK_UART1_APB_PPC_POS);
+#endif
     spctrl->apbnsppcexp1 |= (1U << CMSDK_UART2_APB_PPC_POS);
     spctrl->apbnsppcexp1 |= (1U << CMSDK_UART3_APB_PPC_POS);
     spctrl->apbnsppcexp1 |= (1U << CMSDK_UART4_APB_PPC_POS);
diff --git a/platform/ext/target/mps2/an521/target_cfg.c b/platform/ext/target/mps2/an521/target_cfg.c
index 6aaaa18..c81854c 100644
--- a/platform/ext/target/mps2/an521/target_cfg.c
+++ b/platform/ext/target/mps2/an521/target_cfg.c
@@ -78,7 +78,7 @@
                   | SCB_SHCSR_SECUREFAULTENA_Msk;
 }
 
-/*------------------- NVIC interrupt target state to NS configuration ----------*/
+/*----------------- NVIC interrupt target state to NS configuration ----------*/
 void nvic_interrupt_target_state_cfg()
 {
     /* Target every interrupt to NS; unimplemented interrupts will be WI */
@@ -90,13 +90,15 @@
     NVIC_ClearTargetState(MPC_IRQn);
     NVIC_ClearTargetState(PPC_IRQn);
 
+#ifdef SECURE_UART1
     /* UART1 is a secure peripheral, so its IRQs have to target S state */
     NVIC_ClearTargetState(UARTRX1_IRQn);
     NVIC_ClearTargetState(UARTTX1_IRQn);
     NVIC_ClearTargetState(UART1_IRQn);
+#endif
 }
 
-/*------------------- NVIC interrupt enabling for S peripherals ----------------*/
+/*----------------- NVIC interrupt enabling for S peripherals ----------------*/
 void nvic_interrupt_enable()
 {
     struct spctrl_def* spctrl = CMSDK_SPCTRL;
@@ -125,7 +127,7 @@
     NVIC_EnableIRQ(PPC_IRQn);
 }
 
-/*------------------- SAU/IDAU configuration functions -------------------------*/
+/*------------------- SAU/IDAU configuration functions -----------------------*/
 
 void sau_and_idau_cfg(void)
 {
@@ -152,13 +154,18 @@
     /* Only UART1 is configured as a secure peripheral */
     SAU->RNR  = TFM_NS_REGION_PERIPH_1;
     SAU->RBAR = (PERIPHERALS_BASE_NS_START & SAU_RBAR_BADDR_Msk);
+
+#ifdef SECURE_UART1
+    /* To statically configure a peripheral range as secure, close NS peripheral
+     * region before range, and open a new NS region after the reserved space.
+     */
     SAU->RLAR = ((UART1_BASE_NS-1) & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk;
 
-    /* The UART1 range is considered as a (secure) gap */
-
     SAU->RNR  = TFM_NS_REGION_PERIPH_2;
     SAU->RBAR = (UART2_BASE_NS & SAU_RBAR_BADDR_Msk);
+#endif
+
     SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk;
 
@@ -213,7 +220,13 @@
     spctrl->apbnsppcexp1 |= (1U << CMSDK_SPI3_APB_PPC_POS);
     spctrl->apbnsppcexp1 |= (1U << CMSDK_SPI4_APB_PPC_POS);
     spctrl->apbnsppcexp1 |= (1U << CMSDK_UART0_APB_PPC_POS);
-    /* Do not do it for UART1 as it's a Secure peripheral */
+#ifdef SECURE_UART1
+    /* To statically configure a peripheral as secure, skip PPC NS peripheral
+     * configuration for the given device.
+     */
+#else
+    spctrl->apbnsppcexp1 |= (1U << CMSDK_UART1_APB_PPC_POS);
+#endif
     spctrl->apbnsppcexp1 |= (1U << CMSDK_UART2_APB_PPC_POS);
     spctrl->apbnsppcexp1 |= (1U << CMSDK_UART3_APB_PPC_POS);
     spctrl->apbnsppcexp1 |= (1U << CMSDK_UART4_APB_PPC_POS);
diff --git a/platform/ext/target/musca_a/target_cfg.c b/platform/ext/target/musca_a/target_cfg.c
index 3bd0755..30e861c 100755
--- a/platform/ext/target/musca_a/target_cfg.c
+++ b/platform/ext/target/musca_a/target_cfg.c
@@ -91,11 +91,6 @@
     /* Make sure that MPC and PPC are targeted to S state */
     NVIC_ClearTargetState(MPC_IRQn);
     NVIC_ClearTargetState(PPC_IRQn);
-
-    /* UART1 is a secure peripheral, so its IRQs have to target S state */
-    NVIC_ClearTargetState(UARTRX1_IRQn);
-    NVIC_ClearTargetState(UARTTX1_IRQn);
-    NVIC_ClearTargetState(UART1_IRQn);
 }
 
 /*----------------- NVIC interrupt enabling for S peripherals ----------------*/
diff --git a/secure_fw/core/tfm_core.c b/secure_fw/core/tfm_core.c
index 9087120..f48e9fc 100644
--- a/secure_fw/core/tfm_core.c
+++ b/secure_fw/core/tfm_core.c
@@ -96,17 +96,11 @@
 
     __enable_irq();
 
+    uart_init(UART0_CHANNEL);
+    LOG_MSG("Secure image initializing!");
+
 #ifdef TFM_CORE_DEBUG
-    /* Initializes UART0 to print messages. The STDOUT is redirected to UART0 */
-    uart_init(UART0_CHANNEL);
-
-    LOG_MSG("Secure image initializing!");
     printf("TFM level is: %d\r\n", TFM_LVL);
-#else
-    /* FixMe: redirect secure log entries to secure log */
-    uart_init(UART0_CHANNEL);
-
-    LOG_MSG("Secure image initializing!");
 #endif
 
     /* Configures non-secure memory spaces in the target */