arch: add fault handlers, rename exceptions
This commit is contained in:
parent
7fa55c8dab
commit
05662bc39e
9 changed files with 368 additions and 141 deletions
|
|
@ -16,9 +16,11 @@ target_sources(ardix_arch PRIVATE
|
|||
atom.c
|
||||
atomic.c
|
||||
entry.c
|
||||
handle_fault.c
|
||||
handle_fault.S
|
||||
handle_pend_sv.S
|
||||
handle_svc.S
|
||||
interrupt.c
|
||||
irq_pend_sv.S
|
||||
irq_svc.S
|
||||
mutex.S
|
||||
sched.c
|
||||
serial.c
|
||||
|
|
|
|||
53
arch/at91sam3x8e/handle_fault.S
Normal file
53
arch/at91sam3x8e/handle_fault.S
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* See the end of this file for copyright, license, and warranty information. */
|
||||
|
||||
/*
|
||||
* See arch_handle_fault()
|
||||
*/
|
||||
|
||||
.include "asm.S"
|
||||
|
||||
.text
|
||||
|
||||
/* __naked __noreturn void arch_handle_fault(struct reg_snapshot *regs, int irqnum); */
|
||||
.extern arch_handle_fault
|
||||
|
||||
func_begin handle_hard_fault
|
||||
push {r4-r11,lr}
|
||||
mov r0, sp
|
||||
mov r1, #0xfffffff3 /* -13 */
|
||||
b arch_handle_fault
|
||||
func_end handle_hard_fault
|
||||
|
||||
func_begin handle_mm_fault
|
||||
push {r4-r11,lr}
|
||||
mov r0, sp
|
||||
mov r1, #0xfffffff4 /* -12 */
|
||||
b arch_handle_fault
|
||||
func_end handle_mm_fault
|
||||
|
||||
func_begin handle_bus_fault
|
||||
push {r4-r11,lr}
|
||||
mov r0, sp
|
||||
mov r1, #0xfffffff5 /* -11 */
|
||||
b arch_handle_fault
|
||||
func_end handle_bus_fault
|
||||
|
||||
func_begin handle_usage_fault
|
||||
push {r4-r11,lr}
|
||||
mov r0, sp
|
||||
mov r1, #0xfffffff6 /* -10 */
|
||||
b arch_handle_fault
|
||||
func_end handle_usage_fault
|
||||
|
||||
/*
|
||||
* This file is part of Ardix.
|
||||
* Copyright (c) 2020, 2021 Felix Kopp <owo@fef.moe>.
|
||||
*
|
||||
* Ardix is non-violent software: you may only use, redistribute,
|
||||
* and/or modify it under the terms of the CNPLv6+ as found in
|
||||
* the LICENSE file in the source code root directory or at
|
||||
* <https://git.pixie.town/thufie/CNPL>.
|
||||
*
|
||||
* Ardix comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||
* permitted by applicable law. See the CNPLv6+ for details.
|
||||
*/
|
||||
168
arch/at91sam3x8e/handle_fault.c
Normal file
168
arch/at91sam3x8e/handle_fault.c
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/* See the end of this file for copyright, license, and warranty information. */
|
||||
|
||||
#include <arch-generic/hardware.h>
|
||||
|
||||
#include <arch/hardware.h>
|
||||
#include <arch/interrupt.h>
|
||||
|
||||
#include <toolchain.h>
|
||||
|
||||
/** Setup UART to manual byte-by-byte control */
|
||||
static inline void uart_emergency_setup(void)
|
||||
{
|
||||
REG_UART_PDC_PTCR = REG_UART_PDC_PTCR_RXTDIS_MASK | REG_UART_PDC_PTCR_TXTDIS_MASK;
|
||||
|
||||
REG_UART_CR = REG_UART_CR_RXDIS_MASK | REG_UART_CR_RSTRX_MASK
|
||||
| REG_UART_CR_TXDIS_MASK | REG_UART_CR_RSTTX_MASK;
|
||||
|
||||
REG_UART_IDR = 0xffffffff;
|
||||
|
||||
REG_UART_CR = REG_UART_CR_RXEN_MASK | REG_UART_CR_TXEN_MASK;
|
||||
}
|
||||
|
||||
static void uart_write_sync(const char *s)
|
||||
{
|
||||
char c;
|
||||
while ((c = *s++) != '\0') {
|
||||
mom_are_we_there_yet(REG_UART_SR & REG_UART_SR_TXRDY_MASK);
|
||||
REG_UART_THR = c;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
static inline void print_err_msg(enum irqno irqno)
|
||||
{
|
||||
switch (irqno) {
|
||||
case IRQNO_HARD_FAULT:
|
||||
uart_write_sync("Hard");
|
||||
break;
|
||||
case IRQNO_MM_FAULT:
|
||||
uart_write_sync("Memory Management");
|
||||
break;
|
||||
case IRQNO_BUS_FAULT:
|
||||
uart_write_sync("Bus");
|
||||
break;
|
||||
case IRQNO_USAGE_FAULT:
|
||||
uart_write_sync("Usage");
|
||||
break;
|
||||
}
|
||||
|
||||
uart_write_sync(" Fault encountered, system halted.\n\n");
|
||||
}
|
||||
#pragma GCC diagnostic pop /* -Wswitch */
|
||||
|
||||
static void reg_to_str(char *dest, uint32_t val)
|
||||
{
|
||||
for (int i = 28; i >= 0; i -= 4) {
|
||||
uint8_t digit = (val >> i) & 0x0f;
|
||||
|
||||
if (digit < 0x0a)
|
||||
digit += '0';
|
||||
else
|
||||
digit += 'a';
|
||||
|
||||
*dest++ = digit;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_regs(struct reg_snapshot *regs)
|
||||
{
|
||||
static char reg_line[] = "r0 = 0x????????\n";
|
||||
char *reg_val = ®_line[8]; /* first question mark */
|
||||
|
||||
reg_to_str(reg_val, regs->hw.r0);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '1';
|
||||
reg_to_str(reg_val, regs->hw.r1);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '2';
|
||||
reg_to_str(reg_val, regs->hw.r2);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '3';
|
||||
reg_to_str(reg_val, regs->hw.r3);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '4';
|
||||
reg_to_str(reg_val, regs->sw.r4);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '5';
|
||||
reg_to_str(reg_val, regs->sw.r5);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '6';
|
||||
reg_to_str(reg_val, regs->sw.r6);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '7';
|
||||
reg_to_str(reg_val, regs->sw.r7);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '8';
|
||||
reg_to_str(reg_val, regs->sw.r8);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '9';
|
||||
reg_to_str(reg_val, regs->sw.r9);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[1] = '1';
|
||||
reg_line[2] = '0';
|
||||
reg_to_str(reg_val, regs->sw.r10);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[2] = '1';
|
||||
reg_to_str(reg_val, regs->sw.r11);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[2] = '2';
|
||||
reg_to_str(reg_val, regs->hw.r12);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[0] = 's';
|
||||
reg_line[1] = 'p';
|
||||
reg_line[2] = ' ';
|
||||
reg_to_str(reg_val, (uint32_t)(regs + 1)); /* where SP was before reg save */
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[0] = 'l';
|
||||
reg_line[1] = 'r';
|
||||
reg_to_str(reg_val, (uint32_t)regs->hw.lr);
|
||||
uart_write_sync(reg_line);
|
||||
|
||||
reg_line[0] = 'p';
|
||||
reg_line[1] = 'c';
|
||||
reg_to_str(reg_val, (uint32_t)regs->hw.pc);
|
||||
uart_write_sync(reg_line);
|
||||
}
|
||||
|
||||
#include <arch/debug.h>
|
||||
|
||||
__naked __noreturn void arch_handle_fault(struct reg_snapshot *regs, enum irqno irqno)
|
||||
{
|
||||
uart_emergency_setup();
|
||||
print_err_msg(irqno);
|
||||
print_regs(regs);
|
||||
|
||||
/* give developers a chance to inspect the system */
|
||||
__breakpoint;
|
||||
/* but never leave this function */
|
||||
while (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This file is part of Ardix.
|
||||
* Copyright (c) 2020, 2021 Felix Kopp <owo@fef.moe>.
|
||||
*
|
||||
* Ardix is non-violent software: you may only use, redistribute,
|
||||
* and/or modify it under the terms of the CNPLv6+ as found in
|
||||
* the LICENSE file in the source code root directory or at
|
||||
* <https://git.pixie.town/thufie/CNPL>.
|
||||
*
|
||||
* Ardix comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||
* permitted by applicable law. See the CNPLv6+ for details.
|
||||
*/
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
.extern sched_process_switch
|
||||
|
||||
/* void irq_pend_sv(void); */
|
||||
func_begin irq_pend_sv
|
||||
/* void handle_pend_sv(void); */
|
||||
func_begin handle_pend_sv
|
||||
/*
|
||||
* Some registers have already been saved by hardware at this point,
|
||||
* we only need to take care of r4-r11 and lr (the latter of which is
|
||||
|
|
@ -40,7 +40,7 @@ func_begin irq_pend_sv
|
|||
|
||||
bx lr
|
||||
|
||||
func_end irq_pend_sv
|
||||
func_end handle_pend_sv
|
||||
|
||||
/*
|
||||
* This file is part of Ardix.
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
.extern arch_enter
|
||||
|
||||
/* void irq_svc(void); */
|
||||
func_begin irq_svc
|
||||
/* void handle_svc(void); */
|
||||
func_begin handle_svc
|
||||
/*
|
||||
* Syscalls on Cortex-M use the following parameter calling convention:
|
||||
*
|
||||
|
|
@ -34,7 +34,7 @@ func_begin irq_svc
|
|||
|
||||
bx lr
|
||||
|
||||
func_end irq_svc
|
||||
func_end handle_svc
|
||||
|
||||
/*
|
||||
* This file is part of Ardix.
|
||||
|
|
@ -2,26 +2,26 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/** Reset interrupt handler */
|
||||
void irq_reset(void);
|
||||
/** Reset exception handler */
|
||||
void handle_reset(void);
|
||||
/** Non-maskable interrupt handler */
|
||||
void irq_nmi(void);
|
||||
/** Hard fault inerrupt handler */
|
||||
void irq_hard_fault(void);
|
||||
/** Memory management fault interrupt handler */
|
||||
void irq_mem_fault(void);
|
||||
/** Bus fault interrupt handler */
|
||||
void irq_bus_fault(void);
|
||||
/** Usage fault (illegal instruction) interrupt handler */
|
||||
void irq_usage_fault(void);
|
||||
/** SVC interrupt handler */
|
||||
void irq_svc(void);
|
||||
void handle_nmi(void);
|
||||
/** Hard fault exception handler */
|
||||
void handle_hard_fault(void);
|
||||
/** Memory management fault exception handler */
|
||||
void handle_mem_fault(void);
|
||||
/** Bus fault exception handler */
|
||||
void handle_bus_fault(void);
|
||||
/** Usage fault exception handler */
|
||||
void handle_usage_fault(void);
|
||||
/** SVC exception handler */
|
||||
void handle_svc(void);
|
||||
/** Debug handler (reserved) */
|
||||
void irq_debug_mon(void);
|
||||
/** Pending SV interrupt handler */
|
||||
void irq_pend_sv(void);
|
||||
/** SysTick interrupt handler */
|
||||
void irq_sys_tick(void);
|
||||
void handle_debug_mon(void);
|
||||
/** PendSV interrupt handler */
|
||||
void handle_pend_sv(void);
|
||||
/** SysTick exception handler */
|
||||
void handle_sys_tick(void);
|
||||
|
||||
/** Supply Controller (0) interrupt handler */
|
||||
void irq_supc(void);
|
||||
|
|
@ -107,11 +107,14 @@ void irq_can0(void);
|
|||
void irq_can1(void);
|
||||
|
||||
/**
|
||||
* Interrupt numbers for sam3x8e
|
||||
* @brief IRQ numbers for sam3x8e.
|
||||
*
|
||||
* Like CMSIS, we treat other exceptions basically the same as IRQs.
|
||||
*/
|
||||
enum irqno {
|
||||
IRQNO_NMI = -14,
|
||||
IRQNO_MEM_FAULT = -12,
|
||||
IRQNO_HARD_FAULT = -13,
|
||||
IRQNO_MM_FAULT = -12,
|
||||
IRQNO_BUS_FAULT = -11,
|
||||
IRQNO_USAGE_FAULT = -10,
|
||||
IRQNO_SVC_CALL = -5,
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
void irq_sys_tick(void)
|
||||
void handle_sys_tick(void)
|
||||
{
|
||||
/*
|
||||
* fire a PendSV interrupt and do the actual context switching there
|
||||
* fire a PendSV exception and do the actual context switching there
|
||||
* because it is faster that way (according to the docs, at least)
|
||||
*/
|
||||
if (!is_atomic_context())
|
||||
|
|
@ -68,7 +68,7 @@ void arch_sched_task_init(struct task *task, void (*entry)(void))
|
|||
|
||||
void yield(enum task_state state)
|
||||
{
|
||||
REG_SYSTICK_VAL = 0U; /* Reset timer */
|
||||
REG_SYSTICK_VAL = 0U; /* Reset timer (TODO: don't do this lmao) */
|
||||
current->state = state;
|
||||
arch_irq_invoke(IRQNO_PEND_SV);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ extern uint32_t _eheap; /* heap end */
|
|||
/* implementation in init/main.c */
|
||||
extern int main(void);
|
||||
|
||||
__naked void irq_reset(void)
|
||||
__naked __noreturn void handle_reset(void)
|
||||
{
|
||||
sys_init();
|
||||
|
||||
|
|
@ -45,133 +45,129 @@ __naked void irq_reset(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* Default IRQ for unimplemented interrupts.
|
||||
* Default handler for unimplemented interrupts.
|
||||
* This will halt the system.
|
||||
*/
|
||||
void irq_stub(void)
|
||||
void _stub_handler(void)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
__weak __alias(irq_stub) void irq_nmi(void);
|
||||
__weak __alias(irq_stub) void irq_hard_fault(void);
|
||||
__weak __alias(irq_stub) void irq_mem_fault(void);
|
||||
__weak __alias(irq_stub) void irq_bus_fault(void);
|
||||
__weak __alias(irq_stub) void irq_usage_fault(void);
|
||||
__weak __alias(irq_stub) void irq_svc(void);
|
||||
__weak __alias(irq_stub) void irq_debug_mon(void);
|
||||
__weak __alias(irq_stub) void irq_pend_sv(void);
|
||||
__weak __alias(irq_stub) void irq_sys_tick(void);
|
||||
void handle_nmi(void) __weak __alias(_stub_handler);
|
||||
void handle_hard_fault(void) __weak __alias(_stub_handler);
|
||||
void handle_mm_fault(void) __weak __alias(_stub_handler);
|
||||
void handle_bus_fault(void) __weak __alias(_stub_handler);
|
||||
void handle_usage_fault(void) __weak __alias(_stub_handler);
|
||||
void handle_svc(void) __weak __alias(_stub_handler);
|
||||
void handle_debug_mon(void) __weak __alias(_stub_handler);
|
||||
void handle_pend_sv(void) __weak __alias(_stub_handler);
|
||||
void handle_sys_tick(void) __weak __alias(_stub_handler);
|
||||
|
||||
__weak __alias(irq_stub) void irq_supc(void);
|
||||
__weak __alias(irq_stub) void irq_rstc(void);
|
||||
__weak __alias(irq_stub) void irq_rtc(void);
|
||||
__weak __alias(irq_stub) void irq_rtt(void);
|
||||
__weak __alias(irq_stub) void irq_wdt(void);
|
||||
__weak __alias(irq_stub) void irq_pmc(void);
|
||||
__weak __alias(irq_stub) void irq_efc0(void);
|
||||
__weak __alias(irq_stub) void irq_efc1(void);
|
||||
__weak __alias(irq_stub) void irq_uart(void);
|
||||
__weak __alias(irq_stub) void irq_smc(void);
|
||||
__weak __alias(irq_stub) void irq_pioa(void);
|
||||
__weak __alias(irq_stub) void irq_piob(void);
|
||||
__weak __alias(irq_stub) void irq_pioc(void);
|
||||
__weak __alias(irq_stub) void irq_piod(void);
|
||||
__weak __alias(irq_stub) void irq_usart0(void);
|
||||
__weak __alias(irq_stub) void irq_usart1(void);
|
||||
__weak __alias(irq_stub) void irq_usart2(void);
|
||||
__weak __alias(irq_stub) void irq_usart3(void);
|
||||
__weak __alias(irq_stub) void irq_hsmci(void);
|
||||
__weak __alias(irq_stub) void irq_twi0(void);
|
||||
__weak __alias(irq_stub) void irq_twi1(void);
|
||||
__weak __alias(irq_stub) void irq_spi0(void);
|
||||
__weak __alias(irq_stub) void irq_ssc(void);
|
||||
__weak __alias(irq_stub) void irq_tc0(void);
|
||||
__weak __alias(irq_stub) void irq_tc1(void);
|
||||
__weak __alias(irq_stub) void irq_tc2(void);
|
||||
__weak __alias(irq_stub) void irq_tc3(void);
|
||||
__weak __alias(irq_stub) void irq_tc4(void);
|
||||
__weak __alias(irq_stub) void irq_tc5(void);
|
||||
__weak __alias(irq_stub) void irq_tc6(void);
|
||||
__weak __alias(irq_stub) void irq_tc7(void);
|
||||
__weak __alias(irq_stub) void irq_tc8(void);
|
||||
__weak __alias(irq_stub) void irq_pwm(void);
|
||||
__weak __alias(irq_stub) void irq_adc(void);
|
||||
__weak __alias(irq_stub) void irq_dacc(void);
|
||||
__weak __alias(irq_stub) void irq_dmac(void);
|
||||
__weak __alias(irq_stub) void irq_uotghs(void);
|
||||
__weak __alias(irq_stub) void irq_trng(void);
|
||||
__weak __alias(irq_stub) void irq_emac(void);
|
||||
__weak __alias(irq_stub) void irq_can0(void);
|
||||
__weak __alias(irq_stub) void irq_can1(void);
|
||||
void irq_supc(void) __weak __alias(_stub_handler);
|
||||
void irq_rstc(void) __weak __alias(_stub_handler);
|
||||
void irq_rtc(void) __weak __alias(_stub_handler);
|
||||
void irq_rtt(void) __weak __alias(_stub_handler);
|
||||
void irq_wdt(void) __weak __alias(_stub_handler);
|
||||
void irq_pmc(void) __weak __alias(_stub_handler);
|
||||
void irq_efc0(void) __weak __alias(_stub_handler);
|
||||
void irq_efc1(void) __weak __alias(_stub_handler);
|
||||
void irq_uart(void) __weak __alias(_stub_handler);
|
||||
void irq_smc(void) __weak __alias(_stub_handler);
|
||||
void irq_pioa(void) __weak __alias(_stub_handler);
|
||||
void irq_piob(void) __weak __alias(_stub_handler);
|
||||
void irq_pioc(void) __weak __alias(_stub_handler);
|
||||
void irq_piod(void) __weak __alias(_stub_handler);
|
||||
void irq_usart0(void) __weak __alias(_stub_handler);
|
||||
void irq_usart1(void) __weak __alias(_stub_handler);
|
||||
void irq_usart2(void) __weak __alias(_stub_handler);
|
||||
void irq_usart3(void) __weak __alias(_stub_handler);
|
||||
void irq_hsmci(void) __weak __alias(_stub_handler);
|
||||
void irq_twi0(void) __weak __alias(_stub_handler);
|
||||
void irq_twi1(void) __weak __alias(_stub_handler);
|
||||
void irq_spi0(void) __weak __alias(_stub_handler);
|
||||
void irq_ssc(void) __weak __alias(_stub_handler);
|
||||
void irq_tc0(void) __weak __alias(_stub_handler);
|
||||
void irq_tc1(void) __weak __alias(_stub_handler);
|
||||
void irq_tc2(void) __weak __alias(_stub_handler);
|
||||
void irq_tc3(void) __weak __alias(_stub_handler);
|
||||
void irq_tc4(void) __weak __alias(_stub_handler);
|
||||
void irq_tc5(void) __weak __alias(_stub_handler);
|
||||
void irq_tc6(void) __weak __alias(_stub_handler);
|
||||
void irq_tc7(void) __weak __alias(_stub_handler);
|
||||
void irq_tc8(void) __weak __alias(_stub_handler);
|
||||
void irq_pwm(void) __weak __alias(_stub_handler);
|
||||
void irq_adc(void) __weak __alias(_stub_handler);
|
||||
void irq_dacc(void) __weak __alias(_stub_handler);
|
||||
void irq_dmac(void) __weak __alias(_stub_handler);
|
||||
void irq_uotghs(void) __weak __alias(_stub_handler);
|
||||
void irq_trng(void) __weak __alias(_stub_handler);
|
||||
void irq_emac(void) __weak __alias(_stub_handler);
|
||||
void irq_can0(void) __weak __alias(_stub_handler);
|
||||
void irq_can1(void) __weak __alias(_stub_handler);
|
||||
|
||||
__section(.vectors) const void *exception_table[] = {
|
||||
&_estack, /* initial SP value (stack grows down) */
|
||||
&irq_reset, /* reset vector */
|
||||
handle_reset, /* reset vector */
|
||||
NULL, /* reserved */
|
||||
&irq_hard_fault, /* hard fault */
|
||||
&irq_mem_fault, /* memory management fault */
|
||||
&irq_bus_fault, /* bus fault */
|
||||
&irq_usage_fault, /* usage fault */
|
||||
handle_hard_fault, /* hard fault */
|
||||
handle_mm_fault, /* memory management fault */
|
||||
handle_bus_fault, /* bus fault */
|
||||
handle_usage_fault, /* usage fault */
|
||||
NULL, /* reserved */
|
||||
NULL, /* reserved */
|
||||
NULL, /* reserved */
|
||||
NULL, /* reserved */
|
||||
&irq_svc, /* SVC call (used for syscalls) */
|
||||
&irq_debug_mon, /* reserved for debug */
|
||||
handle_svc, /* SVC call (used for syscalls) */
|
||||
handle_debug_mon, /* reserved for debug */
|
||||
NULL, /* reserved */
|
||||
&irq_pend_sv, /* PendSV (used by the scheduler) */
|
||||
&irq_sys_tick, /* SysTick */
|
||||
handle_pend_sv, /* PendSV (used by the scheduler) */
|
||||
handle_sys_tick, /* SysTick */
|
||||
|
||||
/*
|
||||
* Ok I am REALLY tired of writing out mnemonics.
|
||||
* Just have a look at include/arch/at91sam3x8e.h for details.
|
||||
*/
|
||||
&irq_supc,
|
||||
&irq_rstc,
|
||||
&irq_rtc,
|
||||
&irq_rtt,
|
||||
&irq_wdt,
|
||||
&irq_pmc,
|
||||
&irq_efc0,
|
||||
&irq_efc1,
|
||||
&irq_uart,
|
||||
&irq_smc,
|
||||
irq_supc,
|
||||
irq_rstc,
|
||||
irq_rtc,
|
||||
irq_rtt,
|
||||
irq_wdt,
|
||||
irq_pmc,
|
||||
irq_efc0,
|
||||
irq_efc1,
|
||||
irq_uart,
|
||||
irq_smc,
|
||||
NULL, /* reserved */
|
||||
&irq_pioa,
|
||||
&irq_piob,
|
||||
&irq_pioc,
|
||||
&irq_piod,
|
||||
irq_pioa,
|
||||
irq_piob,
|
||||
irq_pioc,
|
||||
irq_piod,
|
||||
NULL, /* reserved */
|
||||
NULL, /* reserved */
|
||||
&irq_usart0,
|
||||
&irq_usart1,
|
||||
&irq_usart2,
|
||||
&irq_usart3,
|
||||
&irq_hsmci,
|
||||
&irq_twi0,
|
||||
&irq_twi1,
|
||||
&irq_spi0,
|
||||
irq_usart0,
|
||||
irq_usart1,
|
||||
irq_usart2,
|
||||
irq_usart3,
|
||||
irq_hsmci,
|
||||
irq_twi0,
|
||||
irq_twi1,
|
||||
irq_spi0,
|
||||
NULL, /* reserved */
|
||||
&irq_ssc,
|
||||
&irq_tc0,
|
||||
&irq_tc1,
|
||||
&irq_tc2,
|
||||
&irq_tc3,
|
||||
&irq_tc4,
|
||||
&irq_tc5,
|
||||
&irq_tc6,
|
||||
&irq_tc7,
|
||||
&irq_tc8,
|
||||
&irq_pwm,
|
||||
&irq_adc,
|
||||
&irq_dacc,
|
||||
&irq_dmac,
|
||||
&irq_uotghs,
|
||||
&irq_trng,
|
||||
&irq_emac,
|
||||
&irq_can0,
|
||||
&irq_can1,
|
||||
irq_ssc,
|
||||
irq_tc0,
|
||||
irq_tc1,
|
||||
irq_tc2,
|
||||
irq_tc3,
|
||||
irq_tc4,
|
||||
irq_tc5,
|
||||
irq_tc6,
|
||||
irq_tc7,
|
||||
irq_tc8,
|
||||
irq_pwm,
|
||||
irq_adc,
|
||||
irq_dacc,
|
||||
irq_dmac,
|
||||
irq_uotghs,
|
||||
irq_trng,
|
||||
irq_emac,
|
||||
irq_can0,
|
||||
irq_can1,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -11,20 +11,25 @@
|
|||
* Force a method to always be inlined by the compiler.
|
||||
* Do not use this for functions exceeding one or two lines.
|
||||
*/
|
||||
#define __always_inline inline __attribute__((always_inline))
|
||||
#define __always_inline inline __attribute__(( always_inline ))
|
||||
#endif /* __always_inline */
|
||||
|
||||
#ifndef __naked
|
||||
/** Function attribute for disabling register saving. */
|
||||
#define __naked __attribute__((naked))
|
||||
#define __naked __attribute__(( naked ))
|
||||
#endif
|
||||
|
||||
#ifndef __noreturn
|
||||
/** Function attribute denoting the call will never return. */
|
||||
#define __noreturn __attribute__(( noreturn ))
|
||||
#endif /* __noreturn */
|
||||
|
||||
#ifndef __weak
|
||||
/**
|
||||
* Add the `weak` attribute to a symbol.
|
||||
* This allows that identifier to be re-declared without any warnings.
|
||||
*/
|
||||
#define __weak __attribute__((__weak__))
|
||||
#define __weak __attribute__(( weak ))
|
||||
#endif /* __weak */
|
||||
|
||||
#ifndef __alias
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue