From 48af87ce32b77bba17990562435f1dc89427563d Mon Sep 17 00:00:00 2001 From: kristina Date: Mon, 30 May 2016 14:11:53 +0100 Subject: [PATCH] added hardware exception vectors --- start.s | 66 ++++++++++++++++++++++---------- trap.c | 85 +++++++++++++++++++++++++++++------------ vc4_include/common.h | 61 +++++++++++++++++++++++++++++ vc4_include/cpu.h | 16 ++++++++ vc4_include/exception.h | 54 ++++++++++++++++++++++++++ vc4_include/hardware.h | 3 ++ vc4_include/pcb.h | 55 ++++++++++++++++++++++++++ 7 files changed, 295 insertions(+), 45 deletions(-) create mode 100755 vc4_include/common.h create mode 100755 vc4_include/cpu.h create mode 100755 vc4_include/exception.h create mode 100755 vc4_include/hardware.h create mode 100755 vc4_include/pcb.h diff --git a/start.s b/start.s index 8beda47..716e918 100755 --- a/start.s +++ b/start.s @@ -41,20 +41,21 @@ _start: mov r0, cpuid mov r5, r0 - # get addr of the exception vector table - lea r1, __INTERRUPT_VECTORS - mov r3, r1 + /* vectors */ + mov r3, #0x1B000 + mov r1, r3 /* * populate the exception vector table using PC relative labels * so the code isnt position dependent */ .macro RegExceptionHandler label, exception_number - lea r2, Exc_\label + lea r2, fleh_\label st r2, (r1) add r1, #4 .endm + RegExceptionHandler zero, #0 RegExceptionHandler misaligned, #1 RegExceptionHandler dividebyzero, #2 @@ -71,6 +72,14 @@ _start: RegExceptionHandler breakpoint, #13 RegExceptionHandler unknown, #14 + add r1, r3, #252 + lea r2, fleh_irq + mov r4, #492 + +L_setup_hw_irq: + st r2, (r1)++ + ble r1, r4, L_setup_hw_irq + /* * load the interrupt and normal stack pointers. these * are chosen to be near the top of the available cache memory @@ -125,17 +134,30 @@ delayloop2: * Exception Handling ************************************************************/ -_sleh_generic_gate: - # get faulting PC - ld r1, 4(sp) - # call the C exception handler +.macro SaveRegsLower + push r0-r5, lr +.endm + +.macro SaveRegsUpper + push r6-r15 + push r16-r23 +.endm + +.macro SaveRegsAll + SaveRegsLower + SaveRegsUpper +.endm + +fatal_exception: + SaveRegsUpper + mov r0, sp b sleh_fatal - .macro ExceptionHandler label, exception_number -Exc_\label: - mov r0, \exception_number - b _sleh_generic_gate +fleh_\label: + SaveRegsLower + mov r1, \exception_number + b fatal_exception .endm ExceptionHandler zero, #0 @@ -154,12 +176,16 @@ Exc_\label: ExceptionHandler breakpoint, #13 ExceptionHandler unknown, #14 -/************************************************************ - * ISRs - ************************************************************/ +fleh_irq: + SaveRegsAll -.align 4 -__INTERRUPT_VECTORS: - # 31 slots, 4 byte each for processor exceptions. patched to have the correct - # exception handler routines at runtime to allow the code to be loaded anywhere - .space 124, 0 + /* top of savearea */ + mov r0, sp + bl sleh_irq + +return_from_exception: + pop r16-r23 + pop r6-r15 + pop r0-r15 + ld lr, (sp)++ + rti diff --git a/trap.c b/trap.c index 6e5a973..0f3d5ba 100755 --- a/trap.c +++ b/trap.c @@ -17,30 +17,13 @@ VideoCoreIV second level exception handlers. =============================================================================*/ -#include "lib/common.h" -#include "hardware.h" +#include +#include +#include +#include +#include -/* - * this file in the public release documents all exception names. - * brcm_usrlib\dag\vmcsx\vcfw\rtos\none\rtos_none.c - */ - -static const char* g_ExceptionNames[] = { - "zero", - "misaligned", - "divide by zero", - "undefined instruction", - "forbidden instruction", - "illegal memory", - "bus error", - "floating point", - "isp", - "dummy", - "icache", - "vec core", - "bad l2 alias", - "breakpoint" -}; +static const char* g_ExceptionNames[] = { VC4_EXC_NAMES }; static const char* exception_name(uint32_t n) { if (n >= (sizeof(g_ExceptionNames)/4)) @@ -48,6 +31,58 @@ static const char* exception_name(uint32_t n) { return g_ExceptionNames[n]; } -void sleh_fatal(uint32_t n, uint32_t pc) { - panic("fatal processor exception: %s (%d) at 0x%0x", exception_name(n), n, pc); +#define REGISTER_FORMAT_STRING(prefix) \ + prefix " r0: 0x%08x r1: 0x%08x r2: 0x%08x r3: 0x%08x\n" \ + prefix " r4: 0x%08x r5: 0x%08x r6: 0x%08x r7: 0x%08x\n" \ + prefix " r8: 0x%08x r9: 0x%08x r10: 0x%08x r11: 0x%08x\n" \ + prefix " r12: 0x%08x r13: 0x%08x r14: 0x%08x r15: 0x%08x\n" \ + prefix " pc: 0x%08x lr: 0x%08x sr: 0x%08x\n" + +void sleh_fatal(vc4_saved_state_t* pcb, uint32_t n) { + printf("Fatal VPU Exception: %s\n", exception_name(n)); + + printf("VPU registers:\n"); + + printf( + REGISTER_FORMAT_STRING(" "), + pcb->r0, + pcb->r1, + pcb->r2, + pcb->r3, + pcb->r4, + pcb->r5, + pcb->r6, + pcb->r7, + pcb->r8, + pcb->r9, + pcb->r10, + pcb->r11, + pcb->r12, + pcb->r13, + pcb->r14, + pcb->r15, + pcb->pc, + pcb->lr, + pcb->sr + ); + + printf("Exception info:\n"); + + printf( + " src0: 0x%08x src1: 0x%08x vaddr: 0x%08x\n" + " C: 0x%08x S: 0x%08x\n", + IC0_SRC0, + IC0_SRC1, + IC0_VADDR, + IC0_C, + IC0_S + ); + + printf("We are hanging here ...\n"); + + hang_cpu(); +} + +void sleh_irq(vc4_saved_state_t* pcb) { + panic("interrupt at 0x%X!", pcb->pc); } \ No newline at end of file diff --git a/vc4_include/common.h b/vc4_include/common.h new file mode 100755 index 0000000..706d153 --- /dev/null +++ b/vc4_include/common.h @@ -0,0 +1,61 @@ +#pragma once + +#include "../lib/stdarg.h" + +typedef unsigned long long u64; +typedef unsigned long long uint64_t; +typedef long long int64_t; + +typedef unsigned int u32; +typedef unsigned int uint32_t; +typedef int int32_t; + +typedef unsigned short u16; +typedef unsigned short uint16_t; +typedef short int16_t; + +typedef unsigned char u8; +typedef unsigned char uint8_t; + +typedef int bool; + +#define true 1 +#define false 0 + +#define NULL ((void*)0) + +typedef uint32_t size_t; + +# define ALWAYS_INLINE __attribute__((always_inline)) inline + +extern void panic(const char* fmt, ...) + __attribute__((noreturn)) + __attribute__ ((format (printf, 1, 2))); + +#define panic_plain(ex, ...) \ + (panic)(ex, ## __VA_ARGS__) +#define __STRINGIFY(x) #x +#define LINE_NUMBER(x) __STRINGIFY(x) +#define PANIC_LOCATION __FILE__ ":" LINE_NUMBER(__LINE__) +#define panic(ex, ...) \ + (panic)(# ex "@" PANIC_LOCATION, ## __VA_ARGS__) + +#define _OPEN_SOURCE + +extern void udelay(uint32_t time); +extern uint32_t __div64_32(uint64_t *n, uint32_t base); + +#define do_div __div64_32 + +/* + * this is done like that because clang likes using __builtin_memcpy + * which makes LLC choke in a fabulous way. + */ +extern void *__memcpy(void *_dst, const void *_src, unsigned len); +#define bcopy(s,d,l) __memcpy(d,s,l) +#define memcpy(d,s,l) __memcpy(d,s,l) + +extern int putchar(int c); +extern int vprintf(const char* fmt, va_list arp); +extern int printf(const char *fmt, ...); +extern int puts(const char* str); \ No newline at end of file diff --git a/vc4_include/cpu.h b/vc4_include/cpu.h new file mode 100755 index 0000000..5e08568 --- /dev/null +++ b/vc4_include/cpu.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +static inline void __attribute__((noreturn)) hang_cpu() { + /* disable interrupts and enter WFI state */ + __asm__ __volatile__ ( + "di\n" + "sleep\n" + ); + + /* in case the above fails */ + for (;;) { + __asm__ __volatile__ ("nop"); + } +} \ No newline at end of file diff --git a/vc4_include/exception.h b/vc4_include/exception.h new file mode 100755 index 0000000..210ebf0 --- /dev/null +++ b/vc4_include/exception.h @@ -0,0 +1,54 @@ +/*============================================================================= +Copyright (C) 2016 Kristina Brooks +All rights reserved. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +FILE DESCRIPTION +VideoCore4 exceptions. + +This file in the public release documents all exception names: + brcm_usrlib\dag\vmcsx\vcfw\rtos\none\rtos_none.c + +=============================================================================*/ + +#pragma once + +#define VC4_EXC_ZERO 0 +#define VC4_EXC_MISALIGNED 1 +#define VC4_EXC_DIVIDE_BY_ZERO 2 +#define VC4_EXC_UNDEF 3 +#define VC4_EXC_FORBIDDEN 4 +#define VC4_EXC_ILLEGAL_MEM 5 +#define VC4_EXC_BUS_ERROR 6 +#define VC4_EXC_FPE 7 +#define VC4_EXC_ISP 8 +#define VC4_EXC_DUMMY 9 +#define VC4_EXC_ICACHE 10 +#define VC4_EXC_VEC_CORE 11 +#define VC4_EXC_L2_ALIAS 12 +#define VC4_EXC_BKPT 13 + +#define VC4_EXC_NAMES \ + "Zero", \ + "Misaligned", \ + "Division by zero", \ + "Undefined instruction", \ + "Forbidden instruction", \ + "Illegal memory", \ + "Bus error", \ + "Floating point exception", \ + "ISP", \ + "Dummy", \ + "ICache", \ + "Vector core exception", \ + "Bad L2 alias", \ + "Breakpoint" diff --git a/vc4_include/hardware.h b/vc4_include/hardware.h new file mode 100755 index 0000000..98f19d4 --- /dev/null +++ b/vc4_include/hardware.h @@ -0,0 +1,3 @@ +/* glue */ +#pragma once +#include "../hardware.h" \ No newline at end of file diff --git a/vc4_include/pcb.h b/vc4_include/pcb.h new file mode 100755 index 0000000..06f08eb --- /dev/null +++ b/vc4_include/pcb.h @@ -0,0 +1,55 @@ +/*============================================================================= +Copyright (C) 2016 Kristina Brooks +All rights reserved. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +FILE DESCRIPTION +Process control block. + +=============================================================================*/ + +#pragma once + +#include + +typedef struct { + uint32_t r23; + uint32_t r22; + uint32_t r21; + uint32_t r20; + uint32_t r19; + uint32_t r18; + uint32_t r17; + uint32_t r16; + uint32_t r15; + uint32_t r14; + uint32_t r13; + uint32_t r12; + uint32_t r11; + uint32_t r10; + uint32_t r9; + uint32_t r8; + uint32_t r7; + uint32_t r6; + + uint32_t r5; + uint32_t r4; + uint32_t r3; + uint32_t r2; + uint32_t r1; + uint32_t r0; + + uint32_t lr; + + uint32_t sr; + uint32_t pc; +} vc4_saved_state_t; \ No newline at end of file