Add hardfault handler to corstone-300 target

Change-Id: I59561365b61d256d3211101739dfb5c3e15488fa
diff --git a/targets/corstone-300/target.cpp b/targets/corstone-300/target.cpp
index 3d18680..7c902d2 100644
--- a/targets/corstone-300/target.cpp
+++ b/targets/corstone-300/target.cpp
@@ -29,6 +29,8 @@
 #include "uart.h"
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
 
 using namespace EthosU;
 
@@ -79,6 +81,44 @@
 
 namespace {
 
+extern "C" {
+struct ExcContext {
+    uint32_t r0;
+    uint32_t r1;
+    uint32_t r2;
+    uint32_t r3;
+    uint32_t r12;
+    uint32_t lr;
+    uint32_t pc;
+    uint32_t xPsr;
+};
+
+void HardFault_Handler() {
+    int irq;
+    struct ExcContext *e;
+    uint32_t sp;
+
+    asm volatile("mrs %0, ipsr            \n" // Read IPSR (Exceptio number)
+                 "sub %0, #16             \n" // Get it into IRQn_Type range
+                 "tst lr, #4              \n" // Select the stack which was in use
+                 "ite eq                  \n"
+                 "mrseq %1, msp           \n"
+                 "mrsne %1, psp           \n"
+                 "mov %2, sp              \n"
+                 : "=r"(irq), "=r"(e), "=r"(sp));
+
+    printf("Hard fault. irq=%d, pc=0x%08" PRIx32 ", lr=0x%08" PRIx32 ", xpsr=0x%08" PRIx32 ", sp=0x%08" PRIx32 "\n",
+           irq,
+           e->pc,
+           e->lr,
+           e->xPsr,
+           sp);
+    printf(
+        "%11s cfsr=0x%08" PRIx32 " bfar=0x%08" PRIx32 " mmfar=0x%08" PRIx32 "\n", "", SCB->CFSR, SCB->BFAR, SCB->MMFAR);
+    exit(1);
+}
+}
+
 #ifdef ETHOSU
 void ethosuIrqHandler() {
     ethosu_irq_handler();