add basic secure monitor code for armv7+, for some reason sdram security does not...
authorchristinaa <kristinaa@tuta.io>
Fri, 6 Jan 2017 18:28:21 +0000 (18:28 +0000)
committerchristinaa <kristinaa@tuta.io>
Fri, 6 Jan 2017 18:28:21 +0000 (18:28 +0000)
arm_chainloader/chainloader.h
arm_chainloader/drivers/uart.c
arm_chainloader/main.c
arm_chainloader/start.s
arm_chainloader/trap.c [new file with mode: 0644]
arm_loader.cc
hardware.h
sdram.c

index d222593..6f416d2 100644 (file)
@@ -35,6 +35,23 @@ static inline void __attribute__((noreturn)) hang_cpu() {
     (((uintmax_t)(__n) >= NBBY * sizeof(uintmax_t)) ? 0 : \\r
     ((uintmax_t)1 << (uintmax_t)((__n) & (NBBY * sizeof(uintmax_t) - 1))))\r
 \r
     (((uintmax_t)(__n) >= NBBY * sizeof(uintmax_t)) ? 0 : \\r
     ((uintmax_t)1 << (uintmax_t)((__n) & (NBBY * sizeof(uintmax_t) - 1))))\r
 \r
+static inline uint32_t arm_get_cpsr() {\r
+       uint32_t r;\r
+       __asm__ volatile("mrs %0, cpsr\n" : "=r" (r) :: "memory");\r
+       return r;\r
+}\r
+\r
+#define ARM32_MODE_MASK 0x1f\r
+#define ARM32_USR 0x10\r
+#define ARM32_FIQ 0x11\r
+#define ARM32_IRQ 0x12\r
+#define ARM32_SVC 0x13\r
+#define ARM32_MON 0x16\r
+#define ARM32_ABT 0x17\r
+#define ARM32_HYP 0x1a\r
+#define ARM32_UND 0x1b\r
+#define ARM32_SYS 0x1f\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
index 0bce936..abf888c 100644 (file)
@@ -1,3 +1,4 @@
+#include <lib/runtime.h>\r
 #include <hardware.h>\r
 \r
 #define UART_DR     (UART_BASE+0x00)\r
 #include <hardware.h>\r
 \r
 #define UART_DR     (UART_BASE+0x00)\r
@@ -5,6 +6,6 @@
 \r
 void uart_putc(unsigned int ch)\r
 {\r
 \r
 void uart_putc(unsigned int ch)\r
 {\r
-        while(mmio_read32(UART_FR) & 0x20);\r
-        mmio_write32(UART_DR, ch);\r
+     while(mmio_read32(UART_FR) & 0x20);\r
+     mmio_write32(UART_DR, ch);\r
 }\r
 }\r
index 1b7ad8b..d3961f2 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdint.h>
 #include <chainloader.h>
 #include <hardware.h>
 #include <stdint.h>
 #include <chainloader.h>
 #include <hardware.h>
+#include <stdbool.h>
 
 extern uintptr_t* _end;
 
 
 extern uintptr_t* _end;
 
@@ -14,13 +15,42 @@ static void heap_init() {
 
        init_memory_pool(hs, start_of_heap);
 }
 
        init_memory_pool(hs, start_of_heap);
 }
+static const char* get_execution_mode_name() {
+       uint32_t cpsr = arm_get_cpsr() & ARM32_MODE_MASK;
+
+       switch (cpsr) {
+               case ARM32_USR: return "User";
+               case ARM32_FIQ: return "FIQ";
+               case ARM32_IRQ: return "IRQ";
+               case ARM32_SVC: return "Supervisor";
+               case ARM32_MON: return "Secure Monitor";
+               case ARM32_ABT: return "Abort";
+               case ARM32_UND: return "Undefined Instruction";
+               case ARM32_HYP: return "Hypervisor";
+               case ARM32_SYS: return "System";
+               default: return "Unknown Mode";
+       }
+}
 
 
-void main() {
+void main(bool security_supported)
+{
        /* wait for peripheral access */
        while(ARM_ID != ARM_IDVAL);
        /* wait for peripheral access */
        while(ARM_ID != ARM_IDVAL);
+       udelay(500);
 
        logf("Started on ARM, continuing boot from here ...\n");
 
 
        logf("Started on ARM, continuing boot from here ...\n");
 
+       logf("Firmware data: SDRAM_SIZE=%d, VPU_CPUID=0x%X\n",
+               g_FirmwareData.sdram_size,
+               g_FirmwareData.vpu_cpuid);
+
+       if (security_supported) {
+               logf("Security extensions are supported!\n");
+       }
+
+       logf("Execution mode: %s\n", get_execution_mode_name());
+
        heap_init();
 
        /* c++ runtime */
        heap_init();
 
        /* c++ runtime */
index 183f033..124f9c9 100644 (file)
@@ -24,37 +24,83 @@ the boot process.
 \r
 #include "memory_map.h"\r
 \r
 \r
 #include "memory_map.h"\r
 \r
+.arch_extension sec\r
+\r
 .text\r
 .globl _start\r
 _start:\r
        /* vectors */\r
 .text\r
 .globl _start\r
 _start:\r
        /* vectors */\r
-       b L_all_cores_start\r
-       nop\r
-       nop\r
-       nop\r
-       nop\r
-       nop\r
-       nop\r
-       nop\r
-\r
-L_all_cores_start:\r
-        /* check CPU id */\r
-       mrc p15, 0, r0, c0, c0, 5       @ read MPIDR\r
-       and r3, r0, #0xc0000000         @ multiprocessing extensions and\r
-       teq r3, #0x80000000             @ not part of a uniprocessor system?\r
-       bne L_core0                     @ no, assume UP\r
-       ands r0, r0, #0x03              @ CPU 0?\r
-       bne L_deadloop                  @ if not, spin.\r
-\r
-L_core0:\r
-       mov sp, #(MEM_STACK_END)\r
+       b _common_start /* reset */\r
+       nop /* undefined */\r
+       b _secure_monitor /* swi/smc */\r
+       nop /* prefetch abort */\r
+       nop /* data abort */\r
+       nop /* reserved */\r
+       nop /* irq */\r
+       nop /* fiq */\r
+\r
+.globl g_FirmwareData\r
+g_FirmwareData:\r
+       .long 0 /* SDRAM capacity */\r
+       .long 0 /* VPU CPUID */\r
+       .long 0 /* Reserved */\r
+       .long 0 /* Reserved */\r
+       .long 0 /* Reserved */\r
+\r
+_secure_monitor:\r
+       mrc p15, 0, r0, c1, c1, 0\r
+       bic     r0, r0, #0x4a /* clear IRQ, EA, nET */\r
+       orr r0, r0, #1 /* set NS */\r
+       mcr p15, 0, r0, c1, c1, 0\r
+\r
+       mov r0, #((1 << 7) | (1 << 8) | (1 << 6)) /* mask IRQ, AA and FIQ */\r
+       orr r0, r0, #0x1a /* switch to hypervisor mode */\r
+       msr spsr_cxfs, r0 \r
 \r
 \r
-        /* we are loaded in secure supervisor mode -- drop permissions */\r
-        mrc p15, 0, r0, c1, c1, 0\r
-        orr r0, r0, #1\r
-        mcr p15, 0, r0, c1, c1, 0\r
+       movs pc, lr\r
 \r
 \r
+_common_start:\r
+       /*\r
+        * read MIDR, see if this is an ARMv6 system, if it is, just\r
+        * assume single core (BCM2708) and not bother doing SMP stuff.\r
+        */\r
+       mrc p15, 0, r0, c0, c0, 0\r
+       lsr r0, #16\r
+       and r0, #0xF\r
+       cmp r0, #0x7\r
+       mov r12, #0\r
+       beq L_finish_init\r
+\r
+L_armv7_or_higher:\r
+       /*\r
+        * okay, we're an ARMv7 or an ARMv8.\r
+        */\r
+       mrc p15, 0, r0, c0, c0, 5       // read MPIDR\r
+       and r3, r0, #0xc0000000         // multiprocessing extensions and\r
+       teq r3, #0x80000000                     // not part of a uniprocessor system?\r
+       bne L_setup_monitor                     // no, assume UP\r
+       ands r0, r0, #0x03                      // CPU 0?\r
+       bne L_deadloop                          // if not, spin.\r
+\r
+L_setup_monitor:\r
+       adr     r1, _start\r
+       mcr     p15, 0, r1, c12, c0, 1 /* MVBAR */\r
+       mcr p15, 0, r1, c7, c5, 4 /* ISB (ARMv6 compatible way) */\r
+\r
+       mov r12, #1\r
+       smc 0\r
+       \r
+L_finish_init:\r
+       /* enable instruction cache */\r
+       mrc p15, 0, r0, c1, c0, 0\r
+       orr r0, r0, #(1<<12)\r
+       mcr p15, 0, r0, c1, c0, 0\r
+\r
+       mov sp, #(MEM_STACK_END)\r
+       mov r0, r12\r
        b main\r
 \r
 L_deadloop:\r
        b main\r
 \r
 L_deadloop:\r
+       cpsie if\r
+       wfi\r
        b L_deadloop\r
        b L_deadloop\r
diff --git a/arm_chainloader/trap.c b/arm_chainloader/trap.c
new file mode 100644 (file)
index 0000000..2946448
--- /dev/null
@@ -0,0 +1,6 @@
+/*
+ * trap.cc
+ * Copyright (c) 2017 Kristina Brooks
+ *
+ * ARM trap handling code.
+ */
\ No newline at end of file
index 9561e2e..ff007bd 100644 (file)
@@ -20,15 +20,27 @@ ARM initialization stuff.
 #include <lib/runtime.h>\r
 #include "hardware.h"\r
 \r
 #include <lib/runtime.h>\r
 #include "hardware.h"\r
 \r
-\r
 #define logf(fmt, ...) printf("[ARMLDR:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);\r
 \r
 #define logf(fmt, ...) printf("[ARMLDR:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);\r
 \r
+extern uint32_t g_CPUID;\r
+extern uint32_t g_RAMSize;\r
+\r
 extern uint8_t L_arm_code_start;\r
 extern uint8_t L_arm_code_end;\r
 \r
 #define ARM_MEMORY_BASE 0xC0000000\r
 #define ARM_BKPT_OPCODE 0xE1200070\r
 \r
 extern uint8_t L_arm_code_start;\r
 extern uint8_t L_arm_code_end;\r
 \r
 #define ARM_MEMORY_BASE 0xC0000000\r
 #define ARM_BKPT_OPCODE 0xE1200070\r
 \r
+/*\r
+ * RPi3: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488d/CIHBDCJD.html\r
+ */\r
+\r
+/*\r
+ * This controls AA64nAA32 signal, when set, ARM starts in AArch64 mode. Only applicable\r
+ * to systems using Cortex-A53.\r
+ */\r
+#define ARM_C0_AARCH64 0x00000200\r
+\r
 /* XXX: What is this? */\r
 #define PM_UNK_CFG_CLR 0xFFFCFFFF\r
 \r
 /* XXX: What is this? */\r
 #define PM_UNK_CFG_CLR 0xFFFCFFFF\r
 \r
@@ -137,6 +149,7 @@ void setup_bridge(bool bresp_cycle) {
                udelay(300);\r
        }\r
 \r
                udelay(300);\r
        }\r
 \r
+       logf("starting async bridge, ARM should be able to communicate through AXI ...\n");\r
        ARM_CONTROL1 &= ~ARM_C1_REQSTOP;\r
        udelay(300);\r
 \r
        ARM_CONTROL1 &= ~ARM_C1_REQSTOP;\r
        udelay(300);\r
 \r
@@ -231,10 +244,33 @@ static void arm_pmap_enter(uint32_t bus_address, uint32_t arm_address) {
 #define ARM_C0_PRIO_UC   0xF0000000\r
  */\r
 \r
 #define ARM_C0_PRIO_UC   0xF0000000\r
  */\r
 \r
+static void patch_arm_firmware_data() {\r
+       volatile firmware_arm_data_t* firmware_data = reinterpret_cast<firmware_arm_data_t*>(ARM_MEMORY_BASE + 32);\r
+\r
+       firmware_data->sdram_size = g_RAMSize;\r
+       firmware_data->vpu_cpuid = g_CPUID;\r
+}\r
+\r
+static void arm_enable_tzpc() {\r
+       /*\r
+        * enable SDRAM security.\r
+        * mask: 0xffffe000\r
+        */\r
+       logf("configuring secure SDRAM ...\n");\r
+       SD_SECSRT0 = 0xC0000000;\r
+       SD_SECEND0 = 0xC0011FFF;\r
+       logf("enabling secure SDRAM ...\n");\r
+       SD_SECSRT0 = 0xC0000001;\r
+       logf("secure SDRAM enabled ...\n");\r
+}\r
+\r
 extern "C" void arm_init() {\r
        logf("arm init started\n");\r
 \r
        arm_load_code();\r
 extern "C" void arm_init() {\r
        logf("arm init started\n");\r
 \r
        arm_load_code();\r
+       patch_arm_firmware_data();\r
+\r
+       //arm_enable_tzpc();\r
 \r
        logf("original memstart: 0x%X\n", *((volatile uint32_t*)ARM_MEMORY_BASE));\r
 \r
 \r
        logf("original memstart: 0x%X\n", *((volatile uint32_t*)ARM_MEMORY_BASE));\r
 \r
@@ -256,10 +292,10 @@ extern "C" void arm_init() {
         * enable peripheral access, map arm secure bits to axi secure bits 1:1 and\r
         * set the mem size for who knows what reason.\r
         */\r
         * enable peripheral access, map arm secure bits to axi secure bits 1:1 and\r
         * set the mem size for who knows what reason.\r
         */\r
-       ARM_CONTROL0 |= 0x008 | ARM_C0_APROTSYST | ARM_C0_SIZ1G | ARM_C0_FULLPERI;\r
-        ARM_CONTROL1 |= ARM_C1_PERSON;\r
+       ARM_CONTROL0 |= 0x008 | ARM_C0_APROTPASS | ARM_C0_SIZ1G | ARM_C0_FULLPERI;\r
+       ARM_CONTROL1 |= ARM_C1_PERSON;\r
 \r
 \r
-        ARM_IRQ_ENBL3 |= ARM_IE_MAIL;\r
+       ARM_IRQ_ENBL3 |= ARM_IE_MAIL;\r
 \r
        logf("using C0: 0x%X\n", ARM_CONTROL0);\r
 \r
 \r
        logf("using C0: 0x%X\n", ARM_CONTROL0);\r
 \r
index 8f599f6..5bbcdf5 100644 (file)
@@ -80,3 +80,13 @@ that are missing from the release. This is also used by ARM.
 #define CM_SRC_PLLH_AUX                7\r
 #define CM_SRC_PLLC_CORE1              8\r
 #define CM_SRC_PLLC_CORE2              9\r
 #define CM_SRC_PLLH_AUX                7\r
 #define CM_SRC_PLLC_CORE1              8\r
 #define CM_SRC_PLLC_CORE2              9\r
+\r
+typedef struct {\r
+       uint32_t sdram_size;\r
+       uint32_t vpu_cpuid;\r
+       uint32_t reserved[3];\r
+} firmware_arm_data_t;\r
+\r
+#ifdef __arm__\r
+extern firmware_arm_data_t g_FirmwareData;\r
+#endif
\ No newline at end of file
diff --git a/sdram.c b/sdram.c
index 1f7df89..e69428b 100644 (file)
--- a/sdram.c
+++ b/sdram.c
@@ -52,7 +52,7 @@ extern uint32_t g_CPUID;
 \r
 #define logf(fmt, ...) printf("[SDRAM:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);\r
 \r
 \r
 #define logf(fmt, ...) printf("[SDRAM:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);\r
 \r
-unsigned g_RAMSize = RAM_SIZE_UNKNOWN;\r
+uint32_t g_RAMSize = RAM_SIZE_UNKNOWN;\r
 \r
 static const char* lpddr2_manufacturer_name(uint32_t mr) {\r
        switch (mr) {\r
 \r
 static const char* lpddr2_manufacturer_name(uint32_t mr) {\r
        switch (mr) {\r
This page took 0.048271 seconds and 4 git commands to generate.