From 2a8cfca4cf70dcf68dc297dd95d824d64a47c755 Mon Sep 17 00:00:00 2001 From: Jean-Paul Etienne Date: Wed, 11 Jan 2017 00:24:30 +0100 Subject: riscv32: added support for the pulpino soc pulpino soc has custom-extended riscv ISA that is accounted for if CONFIG_RISCV_GENERIC_TOOLCHAIN is not set. (ex: bit manipulation asm opcodes) Change-Id: I4dafc4ebc2fedcc4eb6a3dedd0412816afea6004 Signed-off-by: Jean-Paul Etienne --- arch/riscv32/soc/pulpino/Kbuild | 7 ++ arch/riscv32/soc/pulpino/Kconfig.defconfig | 87 ++++++++++++++++ arch/riscv32/soc/pulpino/Kconfig.soc | 2 + arch/riscv32/soc/pulpino/Makefile | 20 ++++ arch/riscv32/soc/pulpino/linker.ld | 21 ++++ arch/riscv32/soc/pulpino/pulpino_idle.c | 73 ++++++++++++++ arch/riscv32/soc/pulpino/pulpino_irq.c | 62 ++++++++++++ arch/riscv32/soc/pulpino/soc.h | 157 +++++++++++++++++++++++++++++ arch/riscv32/soc/pulpino/soc_irq.S | 124 +++++++++++++++++++++++ arch/riscv32/soc/pulpino/vector.S | 76 ++++++++++++++ 10 files changed, 629 insertions(+) create mode 100644 arch/riscv32/soc/pulpino/Kbuild create mode 100644 arch/riscv32/soc/pulpino/Kconfig.defconfig create mode 100644 arch/riscv32/soc/pulpino/Kconfig.soc create mode 100644 arch/riscv32/soc/pulpino/Makefile create mode 100644 arch/riscv32/soc/pulpino/linker.ld create mode 100644 arch/riscv32/soc/pulpino/pulpino_idle.c create mode 100644 arch/riscv32/soc/pulpino/pulpino_irq.c create mode 100644 arch/riscv32/soc/pulpino/soc.h create mode 100644 arch/riscv32/soc/pulpino/soc_irq.S create mode 100644 arch/riscv32/soc/pulpino/vector.S (limited to 'arch') diff --git a/arch/riscv32/soc/pulpino/Kbuild b/arch/riscv32/soc/pulpino/Kbuild new file mode 100644 index 000000000..6eff8cafb --- /dev/null +++ b/arch/riscv32/soc/pulpino/Kbuild @@ -0,0 +1,7 @@ +ccflags-y +=-I$(srctree)/include +ccflags-y +=-I$(srctree)/include/drivers +ccflags-y +=-I$(srctree)/drivers + +asflags-y := ${ccflags-y} + +obj-y = soc_irq.o vector.o pulpino_irq.o pulpino_idle.o diff --git a/arch/riscv32/soc/pulpino/Kconfig.defconfig b/arch/riscv32/soc/pulpino/Kconfig.defconfig new file mode 100644 index 000000000..172ddb34e --- /dev/null +++ b/arch/riscv32/soc/pulpino/Kconfig.defconfig @@ -0,0 +1,87 @@ +if SOC_RISCV32_PULPINO + +config SOC + string + default "pulpino" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + int + default 5000000 + +config RISCV_SOC_CONTEXT_SAVE + bool + default y + +config RISCV_SOC_INTERRUPT_INIT + bool + default y + +config RISCV_HAS_CPU_IDLE + bool + default y + +config INCLUDE_RESET_VECTOR + bool + default y + +config NUM_IRQS + int + default 32 + +config ATOMIC_OPERATIONS_C + bool + default y + +config ITCM_BASE_ADDRESS + hex + default 0x00000000 + +config ITCM_SIZE + hex + default 0x8000 + +config DTCM_BASE_ADDRESS + hex + default 0x00100000 + +config DTCM_SIZE + hex + default 0x8000 + +if UART_NS16550 + +config UART_NS16550_PCI + bool + default n + +config UART_NS16750 + bool + default y + +config UART_NS16550_PORT_0 + bool + default y + +if UART_NS16550_PORT_0 + +config UART_NS16550_PORT_0_NAME + string + default "UART_0" + +config UART_NS16550_PORT_0_IRQ_PRI + int + default 0 + +config UART_NS16550_PORT_0_BAUD_RATE + int + default 115200 + +config UART_NS16550_PORT_0_OPTIONS + int + default 0 + +endif # UART_NS16550_PORT_0 + +endif # UART_NS16550 + +endif # SOC_RISCV32_PULPINO diff --git a/arch/riscv32/soc/pulpino/Kconfig.soc b/arch/riscv32/soc/pulpino/Kconfig.soc new file mode 100644 index 000000000..5925c2390 --- /dev/null +++ b/arch/riscv32/soc/pulpino/Kconfig.soc @@ -0,0 +1,2 @@ +config SOC_RISCV32_PULPINO + bool "Pulpino SOC implementation" diff --git a/arch/riscv32/soc/pulpino/Makefile b/arch/riscv32/soc/pulpino/Makefile new file mode 100644 index 000000000..4dda17816 --- /dev/null +++ b/arch/riscv32/soc/pulpino/Makefile @@ -0,0 +1,20 @@ +soc-cflags := -I/$(srctree)/arch/$(ARCH)/soc/$(SOC_PATH)/ + +ifndef CONFIG_RISCV_GENERIC_TOOLCHAIN +soc-cflags += -march=IMXpulpv2 +endif + +KERNEL_S19_NAME = $(KERNEL_NAME).s19 + +quiet_cmd_gen_s19 = S19 $@ + cmd_gen_s19 = \ +( \ + $(OBJCOPY) --srec-len 1 --output-target=srec $< $@; \ +) + +$(KERNEL_S19_NAME): $(KERNEL_ELF_NAME) + $(call cmd,gen_s19) + +zephyr: $(KERNEL_S19_NAME) +all: $(KERNEL_S19_NAME) +export KERNEL_S19_NAME diff --git a/arch/riscv32/soc/pulpino/linker.ld b/arch/riscv32/soc/pulpino/linker.ld new file mode 100644 index 000000000..93992917c --- /dev/null +++ b/arch/riscv32/soc/pulpino/linker.ld @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Jean-Paul Etienne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @brief Linker script for pulpino + */ + +#include diff --git a/arch/riscv32/soc/pulpino/pulpino_idle.c b/arch/riscv32/soc/pulpino/pulpino_idle.c new file mode 100644 index 000000000..d95086e96 --- /dev/null +++ b/arch/riscv32/soc/pulpino/pulpino_idle.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 Jean-Paul Etienne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +static ALWAYS_INLINE void pulpino_idle(unsigned int key) +{ +#ifdef CONFIG_KERNEL_EVENT_LOGGER_SLEEP + _sys_k_event_logger_enter_sleep(); +#endif + /* unlock interrupts */ + irq_unlock(key); + + /* Put CPU core to sleep via SCR register */ + PULP_SCR = 0x01; + + /* Wait for interrupt */ + SOC_WFI; +} + +/** + * + * @brief Power save idle routine + * + * This function will be called by the kernel idle loop or possibly within + * an implementation of _sys_power_save_idle in the microkernel when the + * '_sys_power_save_flag' variable is non-zero. + * + * @return N/A + */ +void k_cpu_idle(void) +{ + pulpino_idle(SOC_MSTATUS_IEN); +} + +/** + * + * @brief Atomically re-enable interrupts and enter low power mode + * + * INTERNAL + * The requirements for k_cpu_atomic_idle() are as follows: + * 1) The enablement of interrupts and entering a low-power mode needs to be + * atomic, i.e. there should be no period of time where interrupts are + * enabled before the processor enters a low-power mode. See the comments + * in k_lifo_get(), for example, of the race condition that + * occurs if this requirement is not met. + * + * 2) After waking up from the low-power mode, the interrupt lockout state + * must be restored as indicated in the 'imask' input parameter. + * + * @return N/A + */ +void k_cpu_atomic_idle(unsigned int key) +{ + pulpino_idle(key); +} diff --git a/arch/riscv32/soc/pulpino/pulpino_irq.c b/arch/riscv32/soc/pulpino/pulpino_irq.c new file mode 100644 index 000000000..c49c88de6 --- /dev/null +++ b/arch/riscv32/soc/pulpino/pulpino_irq.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 Jean-Paul Etienne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * @brief pulpino interrupt management code + */ +#include +#include + +void _arch_irq_enable(unsigned int irq) +{ + int key; + + key = irq_lock(); + /* + * enable both IRQ and Event + * Event will allow system to wakeup upon an interrupt, + * if CPU was set to sleep + */ + PULP_IER |= (1 << irq); + PULP_EER |= (1 << irq); + irq_unlock(key); +}; + +void _arch_irq_disable(unsigned int irq) +{ + int key; + + key = irq_lock(); + PULP_IER &= ~(1 << irq); + PULP_EER &= ~(1 << irq); + irq_unlock(key); +}; + +int _arch_irq_is_enabled(unsigned int irq) +{ + return !!(PULP_IER & (1 << irq)); +} + +#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) +void soc_interrupt_init(void) +{ + /* ensure that all interrupts are disabled */ + (void)irq_lock(); + PULP_IER = 0; + PULP_EER = 0; +} +#endif diff --git a/arch/riscv32/soc/pulpino/soc.h b/arch/riscv32/soc/pulpino/soc.h new file mode 100644 index 000000000..26fd6b096 --- /dev/null +++ b/arch/riscv32/soc/pulpino/soc.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 Jean-Paul Etienne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file SoC configuration macros for the pulpino core + */ + +#ifndef __PULPINO_SOC_H_ +#define __PULPINO_SOC_H_ + +/* CSR Registers */ +#define PULP_MESTATUS 0x7C0 /* Machine Exception Status Register */ +#define PULP_LPSTART0 0x7B0 /* Hardware Loop 0 Start Register */ +#define PULP_LPEND0 0x7B1 /* Hardware Loop 0 End Register */ +#define PULP_LPCOUNT0 0x7B2 /* Hardware Loop 0 Count Register */ +#define PULP_LPSTART1 0x7B4 /* Hardware Loop 1 Start Register */ +#define PULP_LPEND1 0x7B5 /* Hardware Loop 1 End Register */ +#define PULP_LPCOUNT1 0x7B6 /* Hardware Loop 1 Count Register */ + +/* IRQ numbers */ +#define PULP_I2C_0_IRQ 23 /* I2C Controller */ +#define PULP_UART_0_IRQ 24 /* Uart Controller */ +#define PULP_GPIO_0_IRQ 25 /* GPIO Controller */ +#define PULP_SPI_0_IRQ 26 /* SPI Controller #0 */ +#define PULP_SPI_1_IRQ 27 /* SPI Controller #1 */ +#define PULP_TIMER_A_OVERFLOW_IRQ 28 /* Timer Overflow A */ +#define PULP_TIMER_A_CMP_IRQ 29 /* Timer Output Cmp A */ +#define PULP_TIMER_B_OVERFLOW_IRQ 30 /* Timer Overflow B */ +#define PULP_TIMER_B_CMP_IRQ 31 /* Timer Output Cmp B */ + +/* min value to consider as IRQ in MCAUSE register */ +#define PULP_MIN_IRQ PULP_I2C_0_IRQ + +/* Exception numbers */ +#define PULP_ECALL_EXP 11 /* ECALL Instruction */ + +/* + * SOC-specific MSTATUS related info + */ +/* MSTATUS register to save/restore upon interrupt/exception/context switch */ +#define SOC_MSTATUS_REG PULP_MESTATUS + +#define SOC_MSTATUS_IEN (1 << 0) /* Machine Interrupt Enable bit */ + +/* + * Default MSTATUS register value to restore from stack + * upon scheduling a thread for the first time + */ +#define SOC_MSTATUS_DEF_RESTORE SOC_MSTATUS_IEN + +/* SOC-specific MCAUSE bitfields */ +#define SOC_MCAUSE_IRQ_MASK 0x1F /* Exception code Mask */ +#define SOC_MCAUSE_ECALL_EXP PULP_ECALL_EXP /* ECALL exception number */ + +/* SOC-Specific EXIT ISR command */ +#define SOC_ERET eret + +/* UART configuration */ +#define UART_NS16550_PORT_0_BASE_ADDR 0x1A100000 +#define UART_NS16550_PORT_0_CLK_FREQ 2500000 +#define UART_NS16550_PORT_0_IRQ PULP_UART_0_IRQ + +/* GPIO configuration */ +#define PULP_GPIO_0_BASE 0x1A101000 + +/* PAD configuration */ +#define PULP_PAD_BASE 0x1A107000 + +/* IRQ configuration */ +#define PULP_IRQ_BASE 0x1A104000 + +#define PULP_IER_ADDR (PULP_IRQ_BASE + 0x00) /* IRQ Enable Register */ +#define PULP_IPR_ADDR (PULP_IRQ_BASE + 0x04) /* IRQ Pending Register */ +#define PULP_ISP_ADDR (PULP_IRQ_BASE + 0x08) /* IRQ Set Pending Register */ +#define PULP_ICP_ADDR (PULP_IRQ_BASE + 0x0C) /* IRQ Clear Pending Register */ +#define PULP_EER_ADDR (PULP_IRQ_BASE + 0x10) /* Event Enable Register */ +#define PULP_EPR_ADDR (PULP_IRQ_BASE + 0x14) /* Event Pending Register */ +#define PULP_ESP_ADDR (PULP_IRQ_BASE + 0x18) /* Event Set Pending Register */ +#define PULP_ECP_ADDR (PULP_IRQ_BASE + 0x1C) /* Event Clear Pending Register */ +#define PULP_SCR_ADDR (PULP_IRQ_BASE + 0x20) /* Sleep Control Register */ + +/* Timer configuration */ +#define PULP_TIMER_A_BASE 0x1A103000 +#define PULP_TIMER_B_BASE 0x1A103010 + +/* + * Zephyr-SDK makes use a the latest generic riscv32 toolchain, which + * encodes the wfi opcode as 0x10500073. Pulpino does not understand + * this opcode and will generate a fault upon execution. Pulpino core + * implementation is based on a previous RISC-V ISA specification and + * expects the wfi opcode to be encoded as 0x10200073. In new toolchain, + * 0x10200073 opcode is used to represent the sret opcode. Hence, + * when compiled with a generic riscv32 toolchain, define wfi by sret + * in assembly code. + */ +#if defined(CONFIG_RISCV_GENERIC_TOOLCHAIN) +#define wfi sret +#endif + +#ifndef _ASMLANGUAGE +#include + +/* Register Access MACRO */ +#define PULP_REG(x) (*((volatile unsigned int *)(x))) + +/* Interrupt Registers */ +#define PULP_IER PULP_REG(PULP_IER_ADDR) +#define PULP_IPR PULP_REG(PULP_IPR_ADDR) +#define PULP_ISP PULP_REG(PULP_ISP_ADDR) +#define PULP_ICP PULP_REG(PULP_ICP_ADDR) +#define PULP_EER PULP_REG(PULP_EER_ADDR) +#define PULP_EPR PULP_REG(PULP_EPR_ADDR) +#define PULP_ESP PULP_REG(PULP_ESP_ADDR) +#define PULP_ECP PULP_REG(PULP_ECP_ADDR) +#define PULP_SCR PULP_REG(PULP_SCR_ADDR) + +/* PAD MUX register */ +#define PULP_PADMUX PULP_REG(PULP_PAD_BASE) + +#define PULP_PAD_SPI 0 +#define PULP_PAD_GPIO 1 +#define PULP_PAD_MASK 1 + +#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) +void soc_interrupt_init(void); +#endif + +/* + * when a generic riscv32 toolchain is used replaced wfi by sret + * in inline assembly. Explanation given above. + */ +#if defined(CONFIG_RISCV_GENERIC_TOOLCHAIN) +#define SOC_WFI __asm__ volatile("sret") +#else +#define SOC_WFI __asm__ volatile("wfi") +#endif + +/* lib-c hooks required RAM defined variables */ +#define RISCV_RAM_BASE CONFIG_DTCM_BASE_ADDRESS +#define RISCV_RAM_SIZE CONFIG_DTCM_SIZE + +#endif /* !_ASMLANGUAGE */ + +#endif /* __PULPINO_SOC_H_ */ diff --git a/arch/riscv32/soc/pulpino/soc_irq.S b/arch/riscv32/soc/pulpino/soc_irq.S new file mode 100644 index 000000000..a5a7579fd --- /dev/null +++ b/arch/riscv32/soc/pulpino/soc_irq.S @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2016 Jean-Paul Etienne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _ASMLANGUAGE + +#include +#include +#include +#include +#include + +/* exports */ +GTEXT(__soc_save_context) +GTEXT(__soc_restore_context) +GTEXT(__soc_is_irq) +GTEXT(__soc_handle_irq) +GTEXT(__soc_irq_unlock) + +/* Use ABI name of registers for the sake of simplicity */ + +/* + * Pulpino core has hardware loops registers that need to be saved + * prior to handling an interrupt/exception. + * + * NOTE: Stack space allocation is not needed here, as already allocated at + * architecture level with __NANO_ESF_SIZEOF value (including space for the + * pulpino-specific registers) + */ +SECTION_FUNC(exception.other, __soc_save_context) + /* Save hardware loop registers to stack */ + csrr t0, PULP_LPSTART0 + csrr t1, PULP_LPEND0 + csrr t2, PULP_LPCOUNT0 + sw t0, __NANO_ESF_lpstart0_OFFSET(sp) + sw t1, __NANO_ESF_lpend0_OFFSET(sp) + sw t2, __NANO_ESF_lpcount0_OFFSET(sp) + csrr t0, PULP_LPSTART1 + csrr t1, PULP_LPEND1 + csrr t2, PULP_LPCOUNT1 + sw t0, __NANO_ESF_lpstart1_OFFSET(sp) + sw t1, __NANO_ESF_lpend1_OFFSET(sp) + sw t2, __NANO_ESF_lpcount1_OFFSET(sp) + + /* Return */ + jalr x0, ra + + +SECTION_FUNC(exception.other, __soc_restore_context) + /* Restore hardloop registers from stack */ + lw t0, __NANO_ESF_lpstart0_OFFSET(sp) + lw t1, __NANO_ESF_lpend0_OFFSET(sp) + lw t2, __NANO_ESF_lpcount0_OFFSET(sp) + csrw PULP_LPSTART0, t0 + csrw PULP_LPEND0, t1 + csrw PULP_LPCOUNT0, t2 + lw t0, __NANO_ESF_lpstart1_OFFSET(sp) + lw t1, __NANO_ESF_lpend1_OFFSET(sp) + lw t2, __NANO_ESF_lpcount1_OFFSET(sp) + csrw PULP_LPSTART1, t0 + csrw PULP_LPEND1, t1 + csrw PULP_LPCOUNT1, t2 + + /* Return */ + jalr x0, ra + + +/* + * SOC-specific function to handle pending IRQ number generating the interrupt. + * + * The pulpino core has: + * 1) an ICP register, which is used to clear the pending + * IRQ number upon an interrupt. + * 2) an ECP register, which is used to clear the pending IRQ number + * that has woken up the CPU from sleep state. + * + * Exception number is given as parameter via register a0. + */ +SECTION_FUNC(exception.other, __soc_handle_irq) + /* Clear exception number from the Interrupt pending register */ + li t1, PULP_ICP_ADDR + li t2, 1 + sll t3, t2, a0 + sw t3, 0x00(t1) + + /* Clear exception number from the Event pending register */ + li t1, PULP_ECP_ADDR + sw t3, 0x00(t1) + + /* Return */ + jalr x0, ra + + +/* + * SOC-specific function to determine if the exception is the result of a + * an interrupt or an exception + * return 1 (interrupt) or 0 (exception) + */ +SECTION_FUNC(exception.other, __soc_is_irq) + /* Get exception number from the mcause CSR register. */ + csrr t0, mcause + andi t0, t0, SOC_MCAUSE_IRQ_MASK + + /* if IRQ number < PULP_MIN_IRQ, not interrupt */ + li t1, PULP_MIN_IRQ + addi a0, x0, 0 + blt t0, t1, not_interrupt + addi a0, a0, 1 + +not_interrupt: + /* return */ + jalr x0, ra diff --git a/arch/riscv32/soc/pulpino/vector.S b/arch/riscv32/soc/pulpino/vector.S new file mode 100644 index 000000000..2de5ccb41 --- /dev/null +++ b/arch/riscv32/soc/pulpino/vector.S @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 Jean-Paul Etienne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _ASMLANGUAGE + +#include + +/* imports */ +GTEXT(__reset) +GTEXT(__irq_wrapper) + +/* + * following pulpino datasheet, addr 0x00000000 - 0x00000058 are not used + * in IVT. Hence, set them to nop. + * + * Call __irq_wrapper to handle all interrupts/exceptions/faults/ECALL + * + * ECALL is used to handle context switching of threads, as well as + * IRQ offloading (when enabled). + * + * Interrupt Line 23: I2C IRQ 0x0000005C + * Interrupt Line 24: UART IRQ 0x00000060 + * Interrupt Line 25: GPIO IRQ 0x00000064 + * Interrupt Line 26: SPI Master 0 0x00000068 + * Interrupt Line 27: SPI Master 1 0x0000006C + * Interrupt Line 28: Timer A Overflow 0x00000070 + * Interrupt Line 29: Timer A Output Cmp 0x00000074 + * Interrupt Line 30: Timer B Overflow 0x00000078 + * Interrupt Line 31: Timer B Output Cmp 0x0000007C + * + * RESET 0x00000080 - call __reset + + * Illegal Instruction Exception 0x00000084 + * ECALL Instruction 0x00000088 + * Invalid Memory Access 0x0000008C + */ +SECTION_FUNC(vectors, vinit) + .option norvc; + + /* nop addr 0x00000000 - 0x00000058 */ + .org 0x00 + .rept 23 + nop + .endr + + /* Call __irq_wrapper for all interrupts */ + .org 0x5C + .rept 9 + jal x0, __irq_wrapper + .endr + + /* Call __reset for reset vector */ + .org 0x80 + jal x0, __reset + + /* Illegal instruction */ + jal x0, __irq_wrapper + + /* ECALL (system call) */ + jal x0, __irq_wrapper + + /* Invalid memory access */ + jal x0, __irq_wrapper -- cgit v1.2.3