qemu_riscv32: use hifive1 configuration
Use hifive1 configuration for this qemu and set SYS_CLOCK_HW_CYCLES_PER_SEC to 10000000 Fixes #10043 Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
b38fba35a3
commit
c2c6a6a245
|
@ -1,4 +1,4 @@
|
|||
config BOARD_QEMU_RISCV32
|
||||
bool "QEMU RISCV32 target"
|
||||
depends on SOC_RISCV32_QEMU
|
||||
depends on SOC_RISCV32_SIFIVE_FREEDOM
|
||||
select QEMU_TARGET
|
||||
|
|
|
@ -3,9 +3,8 @@ set(EMU_PLATFORM qemu)
|
|||
set(QEMU_CPU_TYPE_${ARCH} riscv32)
|
||||
|
||||
set(QEMU_FLAGS_${ARCH}
|
||||
-m ${CONFIG_RISCV_RAM_SIZE_MB}
|
||||
-nographic
|
||||
-machine sifive
|
||||
-machine sifive_e
|
||||
)
|
||||
|
||||
set(BOARD_DEBUG_RUNNER qemu)
|
||||
|
|
|
@ -1,23 +1,32 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <riscv32-qemu.dtsi>
|
||||
#include <riscv32-fe310.dtsi>
|
||||
|
||||
/ {
|
||||
model = "qemu_riscv32";
|
||||
compatible = "qemu,riscv32";
|
||||
|
||||
aliases {
|
||||
uart-0 = &uart0;
|
||||
};
|
||||
model = "SiFive HiFive 1";
|
||||
compatible = "sifive,hifive1";
|
||||
|
||||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &uart0;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "ok";
|
||||
current-speed = <115200>;
|
||||
clock-frequency = <16000000>;
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
clock-frequency = <16000000>;
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ name: QEMU Emulation for RISC V
|
|||
type: qemu
|
||||
simulation: qemu
|
||||
arch: riscv32
|
||||
ram: 16
|
||||
toolchain:
|
||||
- zephyr
|
||||
- xtools
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
CONFIG_RISCV32=y
|
||||
CONFIG_SOC_SERIES_RISCV32_QEMU=y
|
||||
CONFIG_SOC_RISCV32_QEMU=y
|
||||
CONFIG_SOC_SERIES_RISCV32_SIFIVE_FREEDOM=y
|
||||
CONFIG_SOC_RISCV32_SIFIVE_FREEDOM=y
|
||||
CONFIG_BOARD_QEMU_RISCV32=y
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_UART_RISCV_QEMU=y
|
||||
CONFIG_UART_SIFIVE=y
|
||||
CONFIG_UART_SIFIVE_PORT_0=y
|
||||
CONFIG_UART_CONSOLE=y
|
||||
CONFIG_UART_CONSOLE_ON_DEV_NAME="uart0"
|
||||
CONFIG_PLIC=y
|
||||
CONFIG_PINMUX=y
|
||||
CONFIG_PINMUX_SIFIVE=y
|
||||
CONFIG_RISCV_MACHINE_TIMER=y
|
||||
CONFIG_BOOT_BANNER=y
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_GPIO_SIFIVE=y
|
||||
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=10000000
|
||||
|
|
|
@ -115,7 +115,7 @@ config ARCV2_INTERRUPT_UNIT
|
|||
config PLIC
|
||||
bool "Platform Level Interrupt Controller (PLIC)"
|
||||
default y
|
||||
depends on SOC_FAMILY_RISCV_PRIVILEGE && !QEMU_TARGET
|
||||
depends on SOC_FAMILY_RISCV_PRIVILEGE
|
||||
select RISCV_HAS_PLIC
|
||||
help
|
||||
Platform Level Interrupt Controller provides support
|
||||
|
|
|
@ -17,7 +17,6 @@ zephyr_library_sources_ifdef(CONFIG_NRF_UARTE_PERIPHERAL uart_nrfx_uarte.c)
|
|||
zephyr_library_sources_if_kconfig(uart_ns16550.c)
|
||||
zephyr_library_sources_if_kconfig(uart_nsim.c)
|
||||
zephyr_library_sources_if_kconfig(uart_qmsi.c)
|
||||
zephyr_library_sources_if_kconfig(uart_riscv_qemu.c)
|
||||
zephyr_library_sources_if_kconfig(uart_sam.c)
|
||||
zephyr_library_sources_if_kconfig(usart_sam.c)
|
||||
zephyr_library_sources_if_kconfig(uart_stellaris.c)
|
||||
|
|
|
@ -91,8 +91,6 @@ source "drivers/serial/Kconfig.cc32xx"
|
|||
|
||||
source "drivers/serial/Kconfig.cmsdk_apb"
|
||||
|
||||
source "drivers/serial/Kconfig.riscv_qemu"
|
||||
|
||||
source "drivers/serial/Kconfig.sifive"
|
||||
|
||||
source "drivers/serial/Kconfig.esp32"
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
# Kconfig.riscv_qemu - riscv-qemu UART configuration option
|
||||
#
|
||||
# Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
menuconfig UART_RISCV_QEMU
|
||||
bool "riscv-qemu UART driver"
|
||||
depends on SOC_RISCV32_QEMU
|
||||
select SERIAL_HAS_DRIVER
|
||||
help
|
||||
Enable the riscv-qemu UART driver.
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <uart.h>
|
||||
#include <sys_io.h>
|
||||
|
||||
#define DEV_CFG(dev) \
|
||||
((const struct uart_device_config * const) \
|
||||
(dev)->config->config_info)
|
||||
|
||||
static unsigned char uart_riscv_qemu_poll_out(struct device *dev,
|
||||
unsigned char c)
|
||||
{
|
||||
sys_write8(c, DEV_CFG(dev)->regs);
|
||||
return c;
|
||||
}
|
||||
|
||||
static int uart_riscv_qemu_poll_in(struct device *dev, unsigned char *c)
|
||||
{
|
||||
*c = sys_read8(DEV_CFG(dev)->regs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uart_riscv_qemu_init(struct device *dev)
|
||||
{
|
||||
/* Nothing to do */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct uart_driver_api uart_riscv_qemu_driver_api = {
|
||||
.poll_in = uart_riscv_qemu_poll_in,
|
||||
.poll_out = uart_riscv_qemu_poll_out,
|
||||
.err_check = NULL,
|
||||
};
|
||||
|
||||
static const struct uart_device_config uart_riscv_qemu_dev_cfg_0 = {
|
||||
.regs = RISCV_QEMU_UART_BASE,
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(uart_riscv_qemu_0, "uart0",
|
||||
uart_riscv_qemu_init, NULL,
|
||||
&uart_riscv_qemu_dev_cfg_0,
|
||||
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||
(void *)&uart_riscv_qemu_driver_api);
|
|
@ -1,26 +0,0 @@
|
|||
---
|
||||
title: RISCV QEMU UART
|
||||
version: 0.1
|
||||
|
||||
description: >
|
||||
This binding gives a base representation of the RISCV QEMU UART
|
||||
|
||||
inherits:
|
||||
!include uart.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
constraint: "riscv,qemu-uart"
|
||||
|
||||
reg:
|
||||
type: array
|
||||
description: mmio register space
|
||||
generation: define
|
||||
category: required
|
||||
|
||||
interrupts:
|
||||
type: array
|
||||
category: required
|
||||
description: required interrupts
|
||||
generation: define
|
||||
...
|
|
@ -1,42 +0,0 @@
|
|||
#include "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "qemu,riscv32";
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
flash0: flash@1000 {
|
||||
compatible = "soc-nv-flash";
|
||||
reg = <0x1000 0x100000>;
|
||||
};
|
||||
|
||||
sram0: memory@80000000 {
|
||||
device_type = "memory";
|
||||
compatible = "mmio-sram";
|
||||
reg = <0x80000000 0x2000000>;
|
||||
};
|
||||
|
||||
soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
uart0: uart@40002000 {
|
||||
compatible = "riscv,qemu-uart";
|
||||
reg = <0x40002000 0x400>;
|
||||
label = "uart0";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
|
@ -122,8 +122,6 @@ extern u32_t _timer_cycle_get_32(void);
|
|||
|
||||
#if defined(CONFIG_SOC_RISCV32_PULPINO)
|
||||
#include <arch/riscv32/pulpino/asm_inline.h>
|
||||
#elif defined(CONFIG_SOC_RISCV32_QEMU)
|
||||
#include <arch/riscv32/riscv32-qemu/asm_inline.h>
|
||||
#elif defined(CONFIG_SOC_FAMILY_RISCV_PRIVILEGE)
|
||||
#include <arch/riscv32/riscv-privilege/asm_inline.h>
|
||||
#endif
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_RISCV32_RISCV32_QEMU_ASM_INLINE_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_RISCV32_RISCV32_QEMU_ASM_INLINE_H_
|
||||
|
||||
/*
|
||||
* The file must not be included directly
|
||||
* Include arch/cpu.h instead
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <arch/riscv32/riscv32-qemu/asm_inline_gcc.h>
|
||||
#else
|
||||
#error "Supports only GNU C compiler"
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_RISCV32_RISCV32_QEMU_ASM_INLINE_H_ */
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_RISCV32_RISCV32_QEMU_ASM_INLINE_GCC_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_RISCV32_RISCV32_QEMU_ASM_INLINE_GCC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The file must not be included directly
|
||||
* Include arch/cpu.h instead
|
||||
* riscv32-qemu does not have bit manipulation asm opcodes.
|
||||
* Handle find_lsb_set and find_msb_set in C.
|
||||
*/
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <toolchain.h>
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief find least significant bit set in a 32-bit word
|
||||
*
|
||||
* This routine finds the first bit set starting from the least significant bit
|
||||
* in the argument passed in and returns the index of that bit. Bits are
|
||||
* numbered starting at 1 from the least significant bit. A return value of
|
||||
* zero indicates that the value passed is zero.
|
||||
*
|
||||
* @return least significant bit set, 0 if @a op is 0
|
||||
*/
|
||||
static ALWAYS_INLINE unsigned int find_lsb_set(u32_t op)
|
||||
{
|
||||
return __builtin_ffs(op);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief find most significant bit set in a 32-bit word
|
||||
*
|
||||
* This routine finds the first bit set starting from the most significant bit
|
||||
* in the argument passed in and returns the index of that bit. Bits are
|
||||
* numbered starting at 1 from the least significant bit. A return value of
|
||||
* zero indicates that the value passed is zero.
|
||||
*
|
||||
* @return most significant bit set, 0 if @a op is 0
|
||||
*/
|
||||
static ALWAYS_INLINE unsigned int find_msb_set(u32_t op)
|
||||
{
|
||||
if (!op)
|
||||
return 0;
|
||||
|
||||
return 32 - __builtin_clz(op);
|
||||
}
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_RISCV32_RISCV32_QEMU_ASM_INLINE_GCC_H_ */
|
|
@ -4,8 +4,5 @@ zephyr_sources(
|
|||
idle.c
|
||||
soc_irq.S
|
||||
soc_common_irq.c
|
||||
vector.S
|
||||
)
|
||||
|
||||
if(NOT(CONFIG_SOC_SERIES_RISCV32_QEMU))
|
||||
zephyr_sources(vector.S)
|
||||
endif()
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
zephyr_sources(
|
||||
qemu_irq.S
|
||||
vector.S
|
||||
)
|
|
@ -1,27 +0,0 @@
|
|||
if SOC_SERIES_RISCV32_QEMU
|
||||
|
||||
config SOC_SERIES
|
||||
string
|
||||
default "riscv32-qemu"
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
int
|
||||
default 10000000
|
||||
|
||||
config RISCV_SOC_INTERRUPT_INIT
|
||||
bool
|
||||
default y
|
||||
|
||||
config INCLUDE_RESET_VECTOR
|
||||
bool
|
||||
default y
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
default 32
|
||||
|
||||
config RISCV_RAM_SIZE_MB
|
||||
int
|
||||
default 32
|
||||
|
||||
endif # SOC_SERIES_RISCV32_QEMU
|
|
@ -1,13 +0,0 @@
|
|||
# Kconfig - riscv32 QEMU SOC implementation
|
||||
#
|
||||
# Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
config SOC_SERIES_RISCV32_QEMU
|
||||
bool "riscv32 QEMU SOC implementation"
|
||||
depends on RISCV32
|
||||
select SOC_FAMILY_RISCV_PRIVILEGE
|
||||
help
|
||||
Enable support for riscv32 QEMU SOC implementation
|
|
@ -1,16 +0,0 @@
|
|||
# Kconfig - RISCV32_QEMU SOC configuration options
|
||||
#
|
||||
# Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
choice
|
||||
prompt "riscv32_qemu SOC implementation"
|
||||
depends on SOC_SERIES_RISCV32_QEMU
|
||||
|
||||
config SOC_RISCV32_QEMU
|
||||
bool "riscv32_qemu SOC implementation"
|
||||
select ATOMIC_OPERATIONS_C
|
||||
|
||||
endchoice
|
|
@ -1,5 +0,0 @@
|
|||
#define CONFIG_RISCV_RAM_BASE_ADDR CONFIG_SRAM_BASE_ADDRESS
|
||||
|
||||
#define CONFIG_RISCV_ROM_BASE_ADDR CONFIG_FLASH_BASE_ADDRESS
|
||||
|
||||
#define CONFIG_RISCV_ROM_SIZE (CONFIG_FLASH_SIZE *1024)
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Linker script for riscv32-qemu
|
||||
*/
|
||||
#include <generated_dts_board.h>
|
||||
#include <arch/riscv32/common/linker.ld>
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <kernel_structs.h>
|
||||
#include <offsets.h>
|
||||
#include <toolchain.h>
|
||||
#include <linker/sections.h>
|
||||
#include <soc.h>
|
||||
|
||||
/* exports */
|
||||
GTEXT(__soc_is_irq)
|
||||
|
||||
/*
|
||||
* riscv32-qemu does not truely follow riscv privilege specification
|
||||
* when determining if exception is the result of an interrupt or an
|
||||
* exception. Hence, reimplement __soc_is_irq here.
|
||||
*
|
||||
* return 1 (interrupt) or 0 (exception)
|
||||
*/
|
||||
SECTION_FUNC(exception.other, __soc_is_irq)
|
||||
/* Get exception number from the mcause CSR register. */
|
||||
csrr t0, mcause
|
||||
li t1, SOC_MCAUSE_EXP_MASK
|
||||
and t0, t0, t1
|
||||
|
||||
/*
|
||||
* If corresponding exception bit is set in the
|
||||
* Machine Interrupt Pending register (mip),
|
||||
* the exception is an interrupt, otherwise it
|
||||
* is an unexpected exception.
|
||||
*/
|
||||
csrr t2, mip
|
||||
li t3, 1
|
||||
sll t4, t3, t0
|
||||
|
||||
addi a0, x0, 0
|
||||
bne t2, t4, not_interrupt
|
||||
addi a0, a0, 1
|
||||
|
||||
not_interrupt:
|
||||
/* return */
|
||||
jalr x0, ra
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file SoC configuration macros for the riscv-qemu
|
||||
*/
|
||||
|
||||
#ifndef __RISCV32_QEMU_SOC_H_
|
||||
#define __RISCV32_QEMU_SOC_H_
|
||||
|
||||
#include <soc_common.h>
|
||||
|
||||
#include <misc/util.h>
|
||||
|
||||
/* UART configuration */
|
||||
#define RISCV_QEMU_UART_BASE 0x40002000
|
||||
|
||||
/* Timer configuration */
|
||||
#define RISCV_MTIME_BASE 0x40000000
|
||||
#define RISCV_MTIMECMP_BASE 0x40000008
|
||||
|
||||
/* lib-c hooks required RAM defined variables */
|
||||
#define RISCV_RAM_BASE CONFIG_RISCV_RAM_BASE_ADDR
|
||||
#define RISCV_RAM_SIZE MB(CONFIG_RISCV_RAM_SIZE_MB)
|
||||
|
||||
#endif /* __RISCV32_QEMU_SOC_H_ */
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
* Contributors: 2018 Antmicro <www.antmicro.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <toolchain.h>
|
||||
|
||||
/* exports */
|
||||
GTEXT(__start)
|
||||
|
||||
/* imports */
|
||||
GTEXT(__reset)
|
||||
GTEXT(__irq_wrapper)
|
||||
|
||||
/*
|
||||
* following riscv32-qemu specs
|
||||
* IVT is placed at 0x000001000 and is mapped as follows:
|
||||
* 0x00001000: reset
|
||||
* 0x00001004: non-maskable interrupt (nmi) vector
|
||||
* 0x00001010: machine trap (mt) vector
|
||||
*
|
||||
* Call __irq_wrapper to handle all interrupts/exceptions/faults
|
||||
*/
|
||||
SECTION_FUNC(vectors, __start)
|
||||
.option norvc;
|
||||
|
||||
/*
|
||||
* jal instruction cannot be used to jump to address whose offset
|
||||
* is > 12-bits wide. In this case, we have to use a call or tail
|
||||
* instruction to jump to a far-away sub-routine.
|
||||
*
|
||||
* Given that IVT is found at a different address-space than the
|
||||
* RAM in riscv32-qemu, we have to use call or tail instructions
|
||||
* to jump to __reset or __isr_wrapper subroutines.
|
||||
* However, call or tail instructions are pseudo instructions,
|
||||
* which generate two base-instructions upon compilation. In this case,
|
||||
* using them at a particular entry in the IVT will overwrite the next
|
||||
* entry in the IVT. For example, using tail instruction in the
|
||||
* reset vector, will overwrite the nmi-vector entry. To prevent this,
|
||||
* perform a two-phase jump instructions to __reset or __irq_wrapper
|
||||
* subroutines. The first jump performs a jal instruction, which will
|
||||
* jump to an offset in the same vector address-space, but outside the
|
||||
* IVT. The second jump performs a tail instruction to the __reset
|
||||
* or __irq_wrapper subroutines.
|
||||
*/
|
||||
|
||||
/* Call __reset for reset vector */
|
||||
jal x0, do_reset
|
||||
|
||||
/* Call __irq_wrapper for nmi vector */
|
||||
jal x0, do_irq_wrapper
|
||||
|
||||
.org 0x10
|
||||
/* Call __irq_wrapper for mt vector */
|
||||
jal x0, do_irq_wrapper
|
||||
|
||||
.org 0x400 /* we are outside IVT */
|
||||
do_reset:
|
||||
/*
|
||||
* Set mtvec (Machine Trap-Vector Base-Address Register)
|
||||
* to __irq_wrapper, so that we jump directly to __irq_wrapper,
|
||||
* instead to the default machine trap vector address in IVT.
|
||||
* This will preserve us from performing two jump instructions upon
|
||||
* an interrupt.
|
||||
*/
|
||||
la t0, __irq_wrapper
|
||||
csrw mtvec, t0
|
||||
|
||||
/* Jump to __reset */
|
||||
tail __reset
|
||||
|
||||
do_irq_wrapper:
|
||||
tail __irq_wrapper
|
Loading…
Reference in a new issue