added hardware exception vectors
This commit is contained in:
parent
41ff22199e
commit
48af87ce32
66
start.s
66
start.s
|
@ -41,20 +41,21 @@ _start:
|
||||||
mov r0, cpuid
|
mov r0, cpuid
|
||||||
mov r5, r0
|
mov r5, r0
|
||||||
|
|
||||||
# get addr of the exception vector table
|
/* vectors */
|
||||||
lea r1, __INTERRUPT_VECTORS
|
mov r3, #0x1B000
|
||||||
mov r3, r1
|
mov r1, r3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* populate the exception vector table using PC relative labels
|
* populate the exception vector table using PC relative labels
|
||||||
* so the code isnt position dependent
|
* so the code isnt position dependent
|
||||||
*/
|
*/
|
||||||
.macro RegExceptionHandler label, exception_number
|
.macro RegExceptionHandler label, exception_number
|
||||||
lea r2, Exc_\label
|
lea r2, fleh_\label
|
||||||
st r2, (r1)
|
st r2, (r1)
|
||||||
add r1, #4
|
add r1, #4
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
RegExceptionHandler zero, #0
|
RegExceptionHandler zero, #0
|
||||||
RegExceptionHandler misaligned, #1
|
RegExceptionHandler misaligned, #1
|
||||||
RegExceptionHandler dividebyzero, #2
|
RegExceptionHandler dividebyzero, #2
|
||||||
|
@ -71,6 +72,14 @@ _start:
|
||||||
RegExceptionHandler breakpoint, #13
|
RegExceptionHandler breakpoint, #13
|
||||||
RegExceptionHandler unknown, #14
|
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
|
* load the interrupt and normal stack pointers. these
|
||||||
* are chosen to be near the top of the available cache memory
|
* are chosen to be near the top of the available cache memory
|
||||||
|
@ -125,17 +134,30 @@ delayloop2:
|
||||||
* Exception Handling
|
* Exception Handling
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
_sleh_generic_gate:
|
.macro SaveRegsLower
|
||||||
# get faulting PC
|
push r0-r5, lr
|
||||||
ld r1, 4(sp)
|
.endm
|
||||||
# call the C exception handler
|
|
||||||
|
.macro SaveRegsUpper
|
||||||
|
push r6-r15
|
||||||
|
push r16-r23
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro SaveRegsAll
|
||||||
|
SaveRegsLower
|
||||||
|
SaveRegsUpper
|
||||||
|
.endm
|
||||||
|
|
||||||
|
fatal_exception:
|
||||||
|
SaveRegsUpper
|
||||||
|
mov r0, sp
|
||||||
b sleh_fatal
|
b sleh_fatal
|
||||||
|
|
||||||
|
|
||||||
.macro ExceptionHandler label, exception_number
|
.macro ExceptionHandler label, exception_number
|
||||||
Exc_\label:
|
fleh_\label:
|
||||||
mov r0, \exception_number
|
SaveRegsLower
|
||||||
b _sleh_generic_gate
|
mov r1, \exception_number
|
||||||
|
b fatal_exception
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
ExceptionHandler zero, #0
|
ExceptionHandler zero, #0
|
||||||
|
@ -154,12 +176,16 @@ Exc_\label:
|
||||||
ExceptionHandler breakpoint, #13
|
ExceptionHandler breakpoint, #13
|
||||||
ExceptionHandler unknown, #14
|
ExceptionHandler unknown, #14
|
||||||
|
|
||||||
/************************************************************
|
fleh_irq:
|
||||||
* ISRs
|
SaveRegsAll
|
||||||
************************************************************/
|
|
||||||
|
|
||||||
.align 4
|
/* top of savearea */
|
||||||
__INTERRUPT_VECTORS:
|
mov r0, sp
|
||||||
# 31 slots, 4 byte each for processor exceptions. patched to have the correct
|
bl sleh_irq
|
||||||
# exception handler routines at runtime to allow the code to be loaded anywhere
|
|
||||||
.space 124, 0
|
return_from_exception:
|
||||||
|
pop r16-r23
|
||||||
|
pop r6-r15
|
||||||
|
pop r0-r15
|
||||||
|
ld lr, (sp)++
|
||||||
|
rti
|
||||||
|
|
85
trap.c
85
trap.c
|
@ -17,30 +17,13 @@ VideoCoreIV second level exception handlers.
|
||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include "lib/common.h"
|
#include <common.h>
|
||||||
#include "hardware.h"
|
#include <pcb.h>
|
||||||
|
#include <exception.h>
|
||||||
|
#include <hardware.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
/*
|
static const char* g_ExceptionNames[] = { VC4_EXC_NAMES };
|
||||||
* 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* exception_name(uint32_t n) {
|
static const char* exception_name(uint32_t n) {
|
||||||
if (n >= (sizeof(g_ExceptionNames)/4))
|
if (n >= (sizeof(g_ExceptionNames)/4))
|
||||||
|
@ -48,6 +31,58 @@ static const char* exception_name(uint32_t n) {
|
||||||
return g_ExceptionNames[n];
|
return g_ExceptionNames[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleh_fatal(uint32_t n, uint32_t pc) {
|
#define REGISTER_FORMAT_STRING(prefix) \
|
||||||
panic("fatal processor exception: %s (%d) at 0x%0x", exception_name(n), n, pc);
|
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);
|
||||||
}
|
}
|
61
vc4_include/common.h
Executable file
61
vc4_include/common.h
Executable file
|
@ -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);
|
16
vc4_include/cpu.h
Executable file
16
vc4_include/cpu.h
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <hardware.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
54
vc4_include/exception.h
Executable file
54
vc4_include/exception.h
Executable file
|
@ -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"
|
3
vc4_include/hardware.h
Executable file
3
vc4_include/hardware.h
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
/* glue */
|
||||||
|
#pragma once
|
||||||
|
#include "../hardware.h"
|
55
vc4_include/pcb.h
Executable file
55
vc4_include/pcb.h
Executable file
|
@ -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 <common.h>
|
||||||
|
|
||||||
|
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;
|
Loading…
Reference in New Issue
Block a user