forked from xuos/xiuos
42 changed files with 6303 additions and 1 deletions
@ -0,0 +1,3 @@ |
|||
SRC_FILES := boot.S interrupt.c tick.c |
|||
|
|||
include $(KERNEL_ROOT)/compiler.mk |
@ -0,0 +1,287 @@ |
|||
/****************************************************************************
|
|||
* arch/risc-v/include/gap8/irq.h |
|||
* GAP8 event system |
|||
* |
|||
* Copyright (C) 2018 Gregory Nutt. All rights reserved. |
|||
* Author: hhuysqt <1020988872@qq.com> |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions |
|||
* are met: |
|||
* |
|||
* 1. Redistributions of source code must retain the above copyright |
|||
* notice, this list of conditions and the following disclaimer. |
|||
* 2. Redistributions in binary form must reproduce the above copyright |
|||
* notice, this list of conditions and the following disclaimer in |
|||
* the documentation and/or other materials provided with the |
|||
* distribution. |
|||
* 3. Neither the name NuttX nor the names of its contributors may be |
|||
* used to endorse or promote products derived from this software |
|||
* without specific prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* GAP8 features a FC controller and a 8-core cluster. IRQ from peripherals |
|||
* have unique ID, which are dispatched to the FC or cluster by the SOC |
|||
* event unit, and then by the FC event unit or cluster event unit, and |
|||
* finally to FC or cluster. Peripherals share the same IRQ entry. |
|||
****************************************************************************/ |
|||
|
|||
#ifndef ARCH_INTERRUPT_H__ |
|||
#define ARCH_INTERRUPT_H__ |
|||
|
|||
/****************************************************************************
|
|||
* Included Files |
|||
****************************************************************************/ |
|||
|
|||
#include <stdint.h> |
|||
|
|||
/****************************************************************************
|
|||
* Pre-Processor Definitions |
|||
****************************************************************************/ |
|||
|
|||
/* Unique ID in SOC domain */ |
|||
|
|||
/* uDMA data events.
|
|||
* Each peripheral has a uDMA_ID. |
|||
* Each peripheral also has RX and TX event ID, which happen to be 2*uDMA_ID |
|||
* and 2*uDMA_ID+1. |
|||
*/ |
|||
|
|||
#define GAP8_EVENT_UDMA_LVDS_RX 0 |
|||
#define GAP8_EVENT_UDMA_LVDS_TX 1 |
|||
#define GAP8_EVENT_UDMA_SPIM0_RX 2 |
|||
#define GAP8_EVENT_UDMA_SPIM0_TX 3 |
|||
#define GAP8_EVENT_UDMA_SPIM1_RX 4 |
|||
#define GAP8_EVENT_UDMA_SPIM1_TX 5 |
|||
#define GAP8_EVENT_UDMA_HYPERBUS_RX 6 |
|||
#define GAP8_EVENT_UDMA_HYPERBUS_TX 7 |
|||
#define GAP8_EVENT_UDMA_UART_RX 8 |
|||
#define GAP8_EVENT_UDMA_UART_TX 9 |
|||
#define GAP8_EVENT_UDMA_I2C0_RX 10 |
|||
#define GAP8_EVENT_UDMA_I2C0_TX 11 |
|||
#define GAP8_EVENT_UDMA_I2C1_RX 12 |
|||
#define GAP8_EVENT_UDMA_I2C1_TX 13 |
|||
#define GAP8_EVENT_UDMA_TCDM_RX 14 |
|||
#define GAP8_EVENT_UDMA_TCDM_TX 15 |
|||
#define GAP8_EVENT_UDMA_SAI_CH0 16 |
|||
#define GAP8_EVENT_UDMA_SAI_CH1 17 |
|||
#define GAP8_EVENT_UDMA_CPI_RX 18 |
|||
|
|||
#define GAP8_UDMA_MAX_EVENT 18 |
|||
|
|||
/* Other events of uDMA peripherals */ |
|||
|
|||
#define GAP8_EVENT_LVDS_GEN0 20 |
|||
#define GAP8_EVENT_LVDS_GEN1 21 |
|||
#define GAP8_EVENT_SPIM0_EOT 22 |
|||
#define GAP8_EVENT_SPIM1_EOT 23 |
|||
#define GAP8_EVENT_HYPERBUS_RESERVED 24 |
|||
#define GAP8_EVENT_UART_RESERVED 25 |
|||
#define GAP8_EVENT_I2C0_ERROR 26 |
|||
#define GAP8_EVENT_I2C1_ERROR 27 |
|||
#define GAP8_EVENT_I2S_RESERVED 28 |
|||
#define GAP8_EVENT_CAM_RESERVED 29 |
|||
|
|||
/* PMU events */ |
|||
|
|||
#define GAP8_EVENT_PMU_CLUSTER_POWER_ON 31 |
|||
#define GAP8_EVENT_PMU_CLUSTER_RESERVED0 32 |
|||
#define GAP8_EVENT_PMU_CLUSTER_RESERVED1 33 |
|||
#define GAP8_EVENT_PMU_CLUSTER_RESERVED2 34 |
|||
#define GAP8_EVENT_PMU_CLUSTER_CLOCK_GATING 35 |
|||
#define GAP8_EVENT_PMU_DLC_BRIDGE_PICL_OK 36 |
|||
#define GAP8_EVENT_PMU_DLC_BRIDGE_SCU_OK 37 |
|||
|
|||
/* Other SOC domain peripheral events */ |
|||
|
|||
#define GAP8_EVENT_PWM0 38 |
|||
#define GAP8_EVENT_PWM1 39 |
|||
#define GAP8_EVENT_PWM2 40 |
|||
#define GAP8_EVENT_PWM3 41 |
|||
#define GAP8_EVENT_GPIO 42 /* GPIO group interrupt */ |
|||
#define GAP8_EVENT_RTC_APB 43 |
|||
#define GAP8_EVENT_RTC 44 |
|||
#define GAP8_EVENT_RESERVED0 45 |
|||
#define GAP8_EVENT_RESERVED1 46 |
|||
#define GAP8_EVENT_RESERVED2 47 |
|||
#define GAP8_EVENT_SOC_SW_0 48 /* GAP8 SOC SW Event0 */ |
|||
#define GAP8_EVENT_SOC_SW_1 49 /* GAP8 SOC SW Event1 */ |
|||
#define GAP8_EVENT_SOC_SW_2 50 /* GAP8 SOC SW Event2 */ |
|||
#define GAP8_EVENT_SOC_SW_3 51 /* GAP8 SOC SW Event3 */ |
|||
#define GAP8_EVENT_SOC_SW_4 52 /* GAP8 SOC SW Event4 */ |
|||
#define GAP8_EVENT_SOC_SW_5 53 /* GAP8 SOC SW Event5 */ |
|||
#define GAP8_EVENT_SOC_SW_6 54 /* GAP8 SOC SW Event6 */ |
|||
#define GAP8_EVENT_SOC_SW_7 55 /* GAP8 SOC SW Event7 */ |
|||
#define GAP8_EVENT_REF32K_CLK_RISE 56 /* Reference 32K Clock event */ |
|||
|
|||
/* FC domain IRQ ID */ |
|||
|
|||
#define GAP8_IRQ_FC_SW_0 0 |
|||
#define GAP8_IRQ_FC_SW_1 1 |
|||
#define GAP8_IRQ_FC_SW_2 2 |
|||
#define GAP8_IRQ_FC_SW_3 3 |
|||
#define GAP8_IRQ_FC_SW_4 4 |
|||
#define GAP8_IRQ_FC_SW_5 5 |
|||
#define GAP8_IRQ_FC_SW_6 6 |
|||
#define GAP8_IRQ_FC_SW_7 7 |
|||
#define GAP8_IRQ_FC_TIMER_LO 10 |
|||
#define GAP8_IRQ_FC_TIMER_HI 11 |
|||
#define GAP8_IRQ_FC_UDMA 27 |
|||
#define GAP8_IRQ_FC_MPU 28 |
|||
#define GAP8_IRQ_FC_UDMA_ERR 29 |
|||
#define GAP8_IRQ_FC_HP_0 30 |
|||
#define GAP8_IRQ_FC_HP_1 31 |
|||
|
|||
#define GAP8_IRQ_RESERVED 60 |
|||
|
|||
/* Cluster domain IRQ ID */ |
|||
|
|||
/* TODO */ |
|||
|
|||
/* RISCY core exception vectors */ |
|||
|
|||
#define GAP8_IRQ_RST 32 |
|||
#define GAP8_IRQ_ILLEGAL 33 |
|||
#define GAP8_IRQ_SYSCALL 34 |
|||
|
|||
/* Total number of IRQs.
|
|||
* 32 ISRs + reset-handler + illegal-instruction-handler + |
|||
* system-call-handler |
|||
*/ |
|||
|
|||
#define NR_IRQS 35 |
|||
|
|||
/****************************************************************************
|
|||
* Public Types |
|||
****************************************************************************/ |
|||
|
|||
/* SOC_EU - SOC domain event unit */ |
|||
|
|||
typedef struct |
|||
{ |
|||
volatile uint32_t EVENT; /* event register */ |
|||
volatile uint32_t FC_MASK_MSB; /* fc mask MSB register */ |
|||
volatile uint32_t FC_MASK_LSB; /* fc mask LSB register */ |
|||
volatile uint32_t CL_MASK_MSB; /* cluster mask MSB register */ |
|||
volatile uint32_t CL_MASK_LSB; /* cluster mask LSB register */ |
|||
volatile uint32_t PR_MASK_MSB; /* propagate mask MSB register */ |
|||
volatile uint32_t PR_MASK_LSB; /* propagate mask LSB register */ |
|||
volatile uint32_t ERR_MASK_MSB; /* error mask MSB register */ |
|||
volatile uint32_t ERR_MASK_LSB; /* error mask LSB register */ |
|||
volatile uint32_t TIMER_SEL_HI; /* timer high register */ |
|||
volatile uint32_t TIMER_SEL_LO; /* timer low register */ |
|||
} soc_eu_reg_t; |
|||
|
|||
#define SOC_EU ((soc_eu_reg_t *)0x1A106000U) |
|||
|
|||
/* FCEU - FC domain event unit */ |
|||
|
|||
typedef struct |
|||
{ |
|||
volatile uint32_t MASK; /* mask register */ |
|||
volatile uint32_t MASK_AND; /* mask-and(clr) register */ |
|||
volatile uint32_t MASK_OR; /* mask-or(set) register */ |
|||
volatile uint32_t MASK_IRQ; /* irq mask register */ |
|||
volatile uint32_t MASK_IRQ_AND; /* irq mask-and(clr) register */ |
|||
volatile uint32_t MASK_IRQ_OR; /* irq mask-or(set) register */ |
|||
volatile uint32_t STATUS; /* clock Status register */ |
|||
volatile uint32_t BUFFER; /* irq pending register */ |
|||
volatile uint32_t BUFFER_MASKED; /* buffer masked register */ |
|||
volatile uint32_t BUFFER_IRQ_MASKED; /* buffer irq masked register */ |
|||
volatile uint32_t BUFFER_CLEAR; /* clear irq pending */ |
|||
volatile uint32_t SW_EVENTS_MASK; /* software event mask register */ |
|||
volatile uint32_t SW_EVENTS_MASK_AND; /* software event mask and register */ |
|||
volatile uint32_t SW_EVENTS_MASK_OR; /* software event mask or register */ |
|||
volatile uint32_t EVENT_WAIT; /* event wait register */ |
|||
volatile uint32_t EVENT_WAIT_CLEAR; /* event wait clear register */ |
|||
volatile uint32_t MASK_SEC_IRQ; /* mask sec irq register */ |
|||
} fceu_reg_t; |
|||
|
|||
#define FCEU ((fceu_reg_t*)0x00204000U) |
|||
|
|||
/* Current interrupt event ID */ |
|||
|
|||
typedef struct |
|||
{ |
|||
volatile uint32_t CURRENT_EVENT; /* current event register */ |
|||
} soc_event_reg_t; |
|||
|
|||
#define SOC_EVENTS ((soc_event_reg_t*)0x00200F00UL) |
|||
|
|||
/* event trigger and mask */ |
|||
|
|||
typedef struct |
|||
{ |
|||
volatile uint32_t TRIGGER_SET[8]; /* trigger set register */ |
|||
volatile uint32_t _reserved0[8]; /* Offset: 0x20 (R/W) Empty Registers */ |
|||
volatile uint32_t TRIGGER_WAIT[8]; /* trigger wait register */ |
|||
volatile uint32_t _reserved1[8]; /* Offset: 0x60 (R/W) Empty Registers */ |
|||
volatile uint32_t TRIGGER_CLR[8]; /* trigger clear register */ |
|||
} eu_sw_events_trigger_reg_t; |
|||
|
|||
#define EU_SW_EVNT_TRIG ((eu_sw_events_trigger_reg_t*)0x00204100UL) |
|||
|
|||
#define ARCH_MAX_IRQ_NUM NR_IRQS |
|||
|
|||
int ArchEnableHwIrq(uint32_t irq_num); |
|||
int ArchDisableHwIrq(uint32_t irq_num); |
|||
|
|||
|
|||
/****************************************************************************
|
|||
* Name: up_disable_event |
|||
* |
|||
* Description: |
|||
* Disable the specific event. Note that setting 1 means to disable an |
|||
* event... |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
static inline void up_disable_event(int event) |
|||
{ |
|||
if (event >= 32) |
|||
{ |
|||
SOC_EU->FC_MASK_MSB |= (1 << (event - 32)); |
|||
} |
|||
else |
|||
{ |
|||
SOC_EU->FC_MASK_LSB |= (1 << event); |
|||
} |
|||
} |
|||
|
|||
/****************************************************************************
|
|||
* Name: up_enable_event |
|||
* |
|||
* Description: |
|||
* Enable the specific event. Note that setting 0 means to enable an |
|||
* event... |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
static inline void up_enable_event(int event) |
|||
{ |
|||
if (event >= 32) |
|||
{ |
|||
SOC_EU->FC_MASK_MSB &= ~(1 << (event - 32)); |
|||
} |
|||
else |
|||
{ |
|||
SOC_EU->FC_MASK_LSB &= ~(1 << event); |
|||
} |
|||
} |
|||
|
|||
#endif |
@ -0,0 +1,382 @@ |
|||
/**************************************************************************** |
|||
* arch/risc-v/src/gapuino/gap8_head.S |
|||
* Startup file for FC of GAP8 |
|||
* Interrupt vector and reset handler |
|||
* |
|||
* Copyright (C) 2018 Gregory Nutt. All rights reserved. |
|||
* Author: hhuysqt <1020988872@qq.com> |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions |
|||
* are met: |
|||
* |
|||
* 1. Redistributions of source code must retain the above copyright |
|||
* notice, this list of conditions and the following disclaimer. |
|||
* 2. Redistributions in binary form must reproduce the above copyright |
|||
* notice, this list of conditions and the following disclaimer in |
|||
* the documentation and/or other materials provided with the |
|||
* distribution. |
|||
* 3. Neither the name NuttX nor the names of its contributors may be |
|||
* used to endorse or promote products derived from this software |
|||
* without specific prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
/**************************************************************************** |
|||
* Pre-processor Definitions |
|||
****************************************************************************/ |
|||
|
|||
/* Exception context size: EPC + 31 common regs + 6 loop regs */ |
|||
|
|||
#define EXCEPTION_STACK_SIZE 4*38 |
|||
|
|||
/**************************************************************************** |
|||
* Assembler Macro Definitions |
|||
****************************************************************************/ |
|||
|
|||
/* save all the registers on interrupt entry */ |
|||
|
|||
.macro SAVE_REGS |
|||
addi sp, sp, -EXCEPTION_STACK_SIZE |
|||
sw x1, 1*4(sp) /* ra */ |
|||
sw x3, 3*4(sp) /* gp */ |
|||
sw x4, 4*4(sp) /* tp */ |
|||
sw x5, 5*4(sp) /* t0 */ |
|||
sw x6, 6*4(sp) /* t1 */ |
|||
sw x7, 7*4(sp) /* t2 */ |
|||
sw x8, 8*4(sp) /* s0 */ |
|||
sw x9, 9*4(sp) /* s1 */ |
|||
sw x10, 10*4(sp) /* a0 */ |
|||
sw x11, 11*4(sp) /* a1 */ |
|||
sw x12, 12*4(sp) /* a2 */ |
|||
sw x13, 13*4(sp) /* a3 */ |
|||
sw x14, 14*4(sp) /* a4 */ |
|||
sw x15, 15*4(sp) /* a5 */ |
|||
sw x16, 16*4(sp) /* a6 */ |
|||
sw x17, 17*4(sp) /* a7 */ |
|||
sw x18, 18*4(sp) /* s2 */ |
|||
sw x19, 19*4(sp) /* s3 */ |
|||
sw x20, 20*4(sp) /* s4 */ |
|||
sw x21, 21*4(sp) /* s5 */ |
|||
sw x22, 22*4(sp) /* s6 */ |
|||
sw x23, 23*4(sp) /* s7 */ |
|||
sw x24, 24*4(sp) /* s8 */ |
|||
sw x25, 25*4(sp) /* s9 */ |
|||
sw x26, 26*4(sp) /* s10 */ |
|||
sw x27, 27*4(sp) /* s11 */ |
|||
sw x28, 28*4(sp) /* t3 */ |
|||
sw x29, 29*4(sp) /* t4 */ |
|||
sw x30, 30*4(sp) /* t5 */ |
|||
sw x31, 31*4(sp) /* t6 */ |
|||
csrr x28, 0x7B0 |
|||
csrr x29, 0x7B1 |
|||
csrr x30, 0x7B2 |
|||
sw x28, 32*4(sp) /* lpstart[0] */ |
|||
sw x29, 33*4(sp) /* lpend[0] */ |
|||
sw x30, 34*4(sp) /* lpcount[0] */ |
|||
csrr x28, 0x7B4 |
|||
csrr x29, 0x7B5 |
|||
csrr x30, 0x7B6 |
|||
sw x28, 35*4(sp) /* lpstart[1] */ |
|||
sw x29, 36*4(sp) /* lpend[1] */ |
|||
sw x30, 37*4(sp) /* lpcount[1] */ |
|||
addi s0, sp, EXCEPTION_STACK_SIZE |
|||
sw s0, 2*4(sp) /* original SP */ |
|||
.endm |
|||
|
|||
/* restore regs and `mret` */ |
|||
|
|||
.macro RESTORE_REGS |
|||
lw x28, 35*4(sp) /* lpstart[1] */ |
|||
lw x29, 36*4(sp) /* lpend[1] */ |
|||
lw x30, 37*4(sp) /* lpcount[1] */ |
|||
csrrw x0, 0x7B4, x28 |
|||
csrrw x0, 0x7B5, x29 |
|||
csrrw x0, 0x7B6, x30 |
|||
lw x28, 32*4(sp) /* lpstart[0] */ |
|||
lw x29, 33*4(sp) /* lpend[0] */ |
|||
lw x30, 34*4(sp) /* lpcount[0] */ |
|||
csrrw x0, 0x7B0, x28 |
|||
csrrw x0, 0x7B1, x29 |
|||
csrrw x0, 0x7B2, x30 |
|||
li s0, 0x1890 /* machine mode, UPIE & MPIE enabled */ |
|||
csrrw x0, mstatus, s0 |
|||
lw x3, 3*4(sp) /* gp */ |
|||
lw x4, 4*4(sp) /* tp */ |
|||
lw x5, 5*4(sp) /* t0 */ |
|||
lw x6, 6*4(sp) /* t1 */ |
|||
lw x7, 7*4(sp) /* t2 */ |
|||
lw x8, 8*4(sp) /* s0 */ |
|||
lw x9, 9*4(sp) /* s1 */ |
|||
lw x10, 10*4(sp) /* a0 */ |
|||
lw x11, 11*4(sp) /* a1 */ |
|||
lw x12, 12*4(sp) /* a2 */ |
|||
lw x13, 13*4(sp) /* a3 */ |
|||
lw x14, 14*4(sp) /* a4 */ |
|||
lw x15, 15*4(sp) /* a5 */ |
|||
lw x16, 16*4(sp) /* a6 */ |
|||
lw x17, 17*4(sp) /* a7 */ |
|||
lw x18, 18*4(sp) /* s2 */ |
|||
lw x19, 19*4(sp) /* s3 */ |
|||
lw x20, 20*4(sp) /* s4 */ |
|||
lw x21, 21*4(sp) /* s5 */ |
|||
lw x22, 22*4(sp) /* s6 */ |
|||
lw x23, 23*4(sp) /* s7 */ |
|||
lw x24, 24*4(sp) /* s8 */ |
|||
lw x25, 25*4(sp) /* s9 */ |
|||
lw x26, 26*4(sp) /* s10 */ |
|||
lw x27, 27*4(sp) /* s11 */ |
|||
lw x28, 28*4(sp) /* t3 */ |
|||
lw x29, 29*4(sp) /* t4 */ |
|||
lw x30, 30*4(sp) /* t5 */ |
|||
lw x31, 31*4(sp) /* t6 */ |
|||
|
|||
lw x1, 1*4(sp) /* ra */ |
|||
|
|||
lw sp, 2*4(sp) /* restore original sp */ |
|||
.endm |
|||
|
|||
/* wrapper for IRQ vector */ |
|||
|
|||
.macro WRAP_IRQ Routine, IRQn |
|||
wrap_irq_\Routine : |
|||
SAVE_REGS |
|||
|
|||
csrr s0, mepc |
|||
sw s0, 0(sp) /* exception PC */ |
|||
|
|||
li a0, \IRQn /* irq = IRQn */ |
|||
mv a1, sp /* context = sp */ |
|||
jal x1, gap8_dispatch_irq |
|||
|
|||
/* If context switch is needed, return |
|||
* a new sp |
|||
*/ |
|||
|
|||
mv sp, a0 |
|||
|
|||
lw s0, 0(sp) /* restore ePC */ |
|||
csrw mepc, s0 |
|||
|
|||
RESTORE_REGS |
|||
|
|||
mret |
|||
.endm |
|||
|
|||
|
|||
/******************************************************************************* |
|||
* External Variables and Functions |
|||
*******************************************************************************/ |
|||
|
|||
# .extern _sbss |
|||
# .extern _ebss |
|||
.extern __bss_start |
|||
.extern __bss_end |
|||
.extern _idle_stack_end |
|||
.extern __data_start__ |
|||
|
|||
.extern gap8_dispatch_irq |
|||
.extern entry |
|||
.extern gapuino_sysinit |
|||
.extern GapuinoStart |
|||
|
|||
.globl reset_handler |
|||
/******************************************************************************* |
|||
* Reset handler |
|||
*******************************************************************************/ |
|||
reset_handler: |
|||
#if 0 |
|||
csrr a0, 0xf14 /* Cluster ID */ |
|||
andi a1, a0, 0x1f /* Core ID */ |
|||
srli a0, a0, 5 |
|||
#endif |
|||
# la gp, __data_start__ |
|||
li a0, 0x1800 /* Set MSTATUS : Machine Mode */ |
|||
csrw mstatus, a0 |
|||
|
|||
li a0, 0x1C000000 /* Set MTVEC */ |
|||
csrw mtvec, a0 |
|||
|
|||
/* Stack initialization */ |
|||
|
|||
la x2, _idle_stack_end |
|||
|
|||
/* Clear BSS */ |
|||
|
|||
la x26, __bss_start |
|||
la x27, __bss_end |
|||
|
|||
bge x26, x27, zero_loop_end |
|||
|
|||
zero_loop: |
|||
sw x0, 0(x26) |
|||
addi x26, x26, 4 |
|||
ble x26, x27, zero_loop |
|||
|
|||
zero_loop_end: |
|||
|
|||
/* TODO: initialize data section */ |
|||
|
|||
/* Initialize cache and clock */ |
|||
|
|||
|
|||
# jal x1, gapuino_sysinit |
|||
|
|||
/* Directly call NuttX nx_start() */ |
|||
csrr a0, 0xf14 /* Cluster ID */ |
|||
andi a1, a0, 0x1f /* Core ID */ |
|||
|
|||
j GapuinoStart |
|||
|
|||
/* If it ever returns, spin here forever... */ |
|||
|
|||
dead_loop: |
|||
jal x0, dead_loop |
|||
|
|||
|
|||
/* IRQ wrappers |
|||
* IRQn are identical to gap8_interrupt.h |
|||
*/ |
|||
|
|||
WRAP_IRQ sw_evt0, 0 |
|||
WRAP_IRQ sw_evt1, 1 |
|||
WRAP_IRQ sw_evt2, 2 |
|||
WRAP_IRQ sw_evt3, 3 |
|||
WRAP_IRQ sw_evt4, 4 |
|||
WRAP_IRQ sw_evt5, 5 |
|||
WRAP_IRQ sw_evt6, 6 |
|||
WRAP_IRQ sw_evt7, 7 |
|||
|
|||
WRAP_IRQ timer_lo, 10 |
|||
WRAP_IRQ timer_hi, 11 |
|||
|
|||
WRAP_IRQ udma, 27 |
|||
WRAP_IRQ mpu, 28 |
|||
WRAP_IRQ udma_err, 29 |
|||
WRAP_IRQ fc_hp0, 30 |
|||
WRAP_IRQ fc_hp1, 31 |
|||
|
|||
WRAP_IRQ reserved, 60 |
|||
|
|||
/* RISCV exceptions */ |
|||
|
|||
illegal_insn_handler: |
|||
csrr s0, mepc |
|||
sw s0, 0*4(sp) /* exception PC */ |
|||
|
|||
/* Spin here so that debugger would read `s0` */ |
|||
|
|||
1: |
|||
j 1b |
|||
|
|||
/* Systemcall handler */ |
|||
|
|||
ecall_insn_handler: |
|||
SAVE_REGS |
|||
|
|||
/* Point to the next instruction of `ecall` */ |
|||
|
|||
csrr s0, mepc |
|||
addi s0, s0, 4 |
|||
sw s0, 0(sp) /* exception PC */ |
|||
|
|||
li a0, 34 /* irq = 34 */ |
|||
mv a1, sp /* context = sp */ |
|||
jal x1, gap8_dispatch_irq |
|||
|
|||
/* If context switch is needed, return |
|||
* a new sp |
|||
*/ |
|||
|
|||
mv sp, a0 |
|||
|
|||
lw s0, 0(sp) /* restore ePC */ |
|||
csrw mepc, s0 |
|||
|
|||
RESTORE_REGS |
|||
|
|||
mret |
|||
|
|||
/******************************************************************************* |
|||
* INTERRUPT VECTOR TABLE |
|||
*******************************************************************************/ |
|||
/* This section has to be down here, since we have to disable rvc for it */ |
|||
|
|||
.section .vectors_M, "ax" |
|||
.option norvc; |
|||
|
|||
j wrap_irq_sw_evt0 /* 0 */ |
|||
j wrap_irq_sw_evt1 /* 1 */ |
|||
j wrap_irq_sw_evt2 /* 2 */ |
|||
j wrap_irq_sw_evt3 /* 3 */ |
|||
j wrap_irq_sw_evt4 /* 4 */ |
|||
j wrap_irq_sw_evt5 /* 5 */ |
|||
j wrap_irq_sw_evt6 /* 6 */ |
|||
j wrap_irq_sw_evt7 /* 7 */ |
|||
j wrap_irq_reserved /* 8 */ |
|||
j wrap_irq_reserved /* 9 */ |
|||
j wrap_irq_timer_lo /* 10 */ |
|||
j wrap_irq_timer_hi /* 11 */ |
|||
j wrap_irq_reserved /* 12 */ |
|||
j wrap_irq_reserved /* 13 */ |
|||
j wrap_irq_reserved /* 14 */ |
|||
j wrap_irq_reserved /* 15 */ |
|||
j wrap_irq_reserved /* 16 */ |
|||
j wrap_irq_reserved /* 17 */ |
|||
j wrap_irq_reserved /* 18 */ |
|||
j wrap_irq_reserved /* 19 */ |
|||
j wrap_irq_reserved /* 20 */ |
|||
j wrap_irq_reserved /* 21 */ |
|||
j wrap_irq_reserved /* 22 */ |
|||
j wrap_irq_reserved /* 23 */ |
|||
j wrap_irq_reserved /* 24 */ |
|||
j wrap_irq_reserved /* 25 */ |
|||
j wrap_irq_reserved /* 26 */ |
|||
j wrap_irq_udma /* 27 */ |
|||
j wrap_irq_mpu /* 28 */ |
|||
j wrap_irq_udma_err /* 29 */ |
|||
j wrap_irq_fc_hp0 /* 30 */ |
|||
j wrap_irq_fc_hp1 /* 31 */ |
|||
|
|||
j reset_handler /* 32 */ |
|||
j illegal_insn_handler/* 33 */ |
|||
j ecall_insn_handler /* 34 */ |
|||
|
|||
|
|||
|
|||
/**************************************************************************** |
|||
* This variable is pointed to the structure containing all information |
|||
* exchanged with the platform loader. It is using a fixed address so that |
|||
* the loader can also find it and then knows the address of the debug |
|||
* structure. |
|||
****************************************************************************/ |
|||
|
|||
.section .dbg_struct, "ax" |
|||
.option norvc; |
|||
.org 0x90 |
|||
.global __rt_debug_struct_ptr |
|||
__rt_debug_struct_ptr: |
|||
.word Debug_Struct |
|||
|
|||
/**************************************************************************** |
|||
* This global variable is unsigned int g_idle_topstack and is exported here |
|||
* only because of its coupling to idle thread stack. |
|||
****************************************************************************/ |
|||
|
|||
.section .data |
|||
.global g_idle_topstack |
|||
g_idle_topstack: |
|||
.word _idle_stack_end |
@ -0,0 +1,57 @@ |
|||
/****************************************************************************
|
|||
* arch/risc-v/include/gap8/chip.h |
|||
* Gapuino chip features |
|||
* |
|||
* Copyright (C) 2018 Gregory Nutt. All rights reserved. |
|||
* Author: hhuysqt <1020988872@qq.com> |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions |
|||
* are met: |
|||
* |
|||
* 1. Redistributions of source code must retain the above copyright |
|||
* notice, this list of conditions and the following disclaimer. |
|||
* 2. Redistributions in binary form must reproduce the above copyright |
|||
* notice, this list of conditions and the following disclaimer in |
|||
* the documentation and/or other materials provided with the |
|||
* distribution. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
/* This file should never be included directly but, rather, only indirectly
|
|||
* through nuttx/irq.h |
|||
*/ |
|||
|
|||
#ifndef __ARCH_RISCV_INCLUDE_GAP8_CHIP_H |
|||
#define __ARCH_RISCV_INCLUDE_GAP8_CHIP_H |
|||
|
|||
/****************************************************************************
|
|||
* Included Files |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Pre-processor Definitions |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Public Types |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Public Function Prototypes |
|||
****************************************************************************/ |
|||
|
|||
#endif /* __ARCH_RISCV_INCLUDE_GAP8_CHIP_H */ |
File diff suppressed because it is too large
@ -0,0 +1,98 @@ |
|||
/****************************************************************************
|
|||
* arch/risc-v/src/gap8/gap8_allocateheap.c |
|||
* |
|||
* Copyright (C) 2018 Gregory Nutt. All rights reserved. |
|||
* Author: Gregory Nutt <gnutt@nuttx.org> |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions |
|||
* are met: |
|||
* |
|||
* 1. Redistributions of source code must retain the above copyright |
|||
* notice, this list of conditions and the following disclaimer. |
|||
* 2. Redistributions in binary form must reproduce the above copyright |
|||
* notice, this list of conditions and the following disclaimer in |
|||
* the documentation and/or other materials provided with the |
|||
* distribution. |
|||
* 3. Neither the name NuttX nor the names of its contributors may be |
|||
* used to endorse or promote products derived from this software |
|||
* without specific prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Included Files |
|||
****************************************************************************/ |
|||
|
|||
#include <nuttx/config.h> |
|||
|
|||
#include <sys/types.h> |
|||
#include <debug.h> |
|||
|
|||
#include <nuttx/arch.h> |
|||
#include <nuttx/board.h> |
|||
#include <arch/board/board.h> |
|||
|
|||
#include "riscv_arch.h" |
|||
#include "riscv_internal.h" |
|||
|
|||
/****************************************************************************
|
|||
* Public Functions |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Name: up_allocate_heap |
|||
* |
|||
* Description: |
|||
* This function will be called to dynamically set aside the heap region. |
|||
* |
|||
* For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and |
|||
* user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the |
|||
* size of the unprotected, user-space heap. |
|||
* |
|||
* If a protected kernel-space heap is provided, the kernel heap must be |
|||
* allocated (and protected) by an analogous up_allocate_kheap(). |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
void up_allocate_heap(FAR void **heap_start, size_t *heap_size) |
|||
{ |
|||
/* These values come from GAP8.ld */ |
|||
|
|||
extern uint8_t *_heap_start; |
|||
extern uint8_t *_heap_end; |
|||
uint32_t hstart = (uint32_t)&_heap_start; |
|||
uint32_t hend = (uint32_t)&_heap_end; |
|||
|
|||
*heap_start = &_heap_start; |
|||
*heap_size = hend - hstart; |
|||
} |
|||
|
|||
/****************************************************************************
|
|||
* Name: riscv_addregion |
|||
* |
|||
* Description: |
|||
* RAM may be added in non-contiguous chunks. This routine adds all chunks |
|||
* that may be used for heap. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
#if CONFIG_MM_REGIONS > 1 |
|||
void riscv_addregion(void) |
|||
{ |
|||
/* TODO: add L1 memorie */ |
|||
} |
|||
#endif |
@ -0,0 +1,84 @@ |
|||
/****************************************************************************
|
|||
* arch/risc-v/src/gap8/gap8_idle.c |
|||
* |
|||
* Copyright (C) 2018 Gregory Nutt. All rights reserved. |
|||
* Author: Gregory Nutt <gnutt@nuttx.org> |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions |
|||
* are met: |
|||
* |
|||
* 1. Redistributions of source code must retain the above copyright |
|||
* notice, this list of conditions and the following disclaimer. |
|||
* 2. Redistributions in binary form must reproduce the above copyright |
|||
* notice, this list of conditions and the following disclaimer in |
|||
* the documentation and/or other materials provided with the |
|||
* distribution. |
|||
* 3. Neither the name NuttX nor the names of its contributors may be |
|||
* used to endorse or promote products derived from this software |
|||
* without specific prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Included Files |
|||
****************************************************************************/ |
|||
|
|||
#include <nuttx/config.h> |
|||
#include <nuttx/irq.h> |
|||
#include <nuttx/arch.h> |
|||
|
|||
#include "riscv_internal.h" |
|||
|
|||
/****************************************************************************
|
|||
* Public Functions |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Name: up_idle |
|||
* |
|||
* Description: |
|||
* up_idle() is the logic that will be executed when there is no other |
|||
* ready-to-run task. This is processor idle time and will continue until |
|||
* some interrupt occurs to cause a context switch from the idle task. |
|||
* |
|||
* Processing in this state may be processor-specific. e.g., this is where |
|||
* power management operations might be performed. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
void up_idle(void) |
|||
{ |
|||
#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) |
|||
/* If the system is idle and there are no timer interrupts, then process
|
|||
* "fake" timer interrupts. Hopefully, something will wake up. |
|||
*/ |
|||
|
|||
nxsched_process_timer(); |
|||
#else |
|||
|
|||
/* GAP8 would sleep on software event #3, which would be triggered at
|
|||
* gap8_dispatch_irq(). |
|||
*/ |
|||
|
|||
gap8_sleep_wait_sw_evnt(1 << 3); |
|||
|
|||
#ifdef CONFIG_SCHED_WORKQUEUE |
|||
irqstate_t flags = enter_critical_section(); |
|||
leave_critical_section(flags); |
|||
#endif |
|||
#endif |
|||
} |
@ -0,0 +1,199 @@ |
|||
/****************************************************************************
|
|||
* arch/risc-v/src/gap8/gap8_schedulesigaction.c |
|||
* |
|||
* Copyright (C) 2018 Gregory Nutt. All rights reserved. |
|||
* Author: Gregory Nutt <gnutt@nuttx.org> |
|||
* |
|||
* Modified for RISC-V: |
|||
* |
|||
* Author: hhuysqt <1020988872@qq.com> |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions |
|||
* are met: |
|||
* |
|||
* 1. Redistributions of source code must retain the above copyright |
|||
* notice, this list of conditions and the following disclaimer. |
|||
* 2. Redistributions in binary form must reproduce the above copyright |
|||
* notice, this list of conditions and the following disclaimer in |
|||
* the documentation and/or other materials provided with the |
|||
* distribution. |
|||
* 3. Neither the name NuttX nor the names of its contributors may be |
|||
* used to endorse or promote products derived from this software |
|||
* without specific prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Included Files |
|||
****************************************************************************/ |
|||
|
|||
#include <nuttx/config.h> |
|||
|
|||
#include <stdint.h> |
|||
#include <sched.h> |
|||
#include <debug.h> |
|||
|
|||
#include <nuttx/irq.h> |
|||
#include <nuttx/arch.h> |
|||
#include <arch/gap8/irq.h> |
|||
|
|||
#include "sched/sched.h" |
|||
#include "riscv_internal.h" |
|||
#include "riscv_arch.h" |
|||
|
|||
/****************************************************************************
|
|||
* Public Functions |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Name: up_schedule_sigaction |
|||
* |
|||
* Description: |
|||
* This function is called by the OS when one or more |
|||
* signal handling actions have been queued for execution. |
|||
* The architecture specific code must configure things so |
|||
* that the 'sigdeliver' callback is executed on the thread |
|||
* specified by 'tcb' as soon as possible. |
|||
* |
|||
* This function may be called from interrupt handling logic. |
|||
* |
|||
* This operation should not cause the task to be unblocked |
|||
* nor should it cause any immediate execution of sigdeliver. |
|||
* Typically, a few cases need to be considered: |
|||
* |
|||
* (1) This function may be called from an interrupt handler |
|||
* During interrupt processing, all xcptcontext structures |
|||
* should be valid for all tasks. That structure should |
|||
* be modified to invoke sigdeliver() either on return |
|||
* from (this) interrupt or on some subsequent context |
|||
* switch to the recipient task. |
|||
* (2) If not in an interrupt handler and the tcb is NOT |
|||
* the currently executing task, then again just modify |
|||
* the saved xcptcontext structure for the recipient |
|||
* task so it will invoke sigdeliver when that task is |
|||
* later resumed. |
|||
* (3) If not in an interrupt handler and the tcb IS the |
|||
* currently executing task -- just call the signal |
|||
* handler now. |
|||
* |
|||
* Assumptions: |
|||
* Called from critical section |
|||
* |
|||
****************************************************************************/ |
|||
irqstate_t flags; |
|||
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) |
|||
{ |
|||
// uint32_t int_ctx;
|
|||
|
|||
sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); |
|||
|
|||
/* Make sure that interrupts are disabled */ |
|||
|
|||
flags = enter_critical_section(); |
|||
|
|||
/* Refuse to handle nested signal actions */ |
|||
|
|||
if (!tcb->xcp.sigdeliver) |
|||
{ |
|||
/* First, handle some special cases when the signal is
|
|||
* being delivered to the currently executing task. |
|||
*/ |
|||
|
|||
sinfo("rtcb=0x%p g_current_regs=0x%p\n", |
|||
this_task(), g_current_regs); |
|||
|
|||
if (tcb == this_task()) |
|||
{ |
|||
/* CASE 1: We are not in an interrupt handler and
|
|||
* a task is signaling itself for some reason. |
|||
*/ |
|||
|
|||
if (!g_current_regs) |
|||
{ |
|||
/* In this case just deliver the signal now. */ |
|||
|
|||
sigdeliver(tcb); |
|||
} |
|||
|
|||
/* CASE 2: We are in an interrupt handler AND the
|
|||
* interrupted task is the same as the one that |
|||
* must receive the signal, then we will have to modify |
|||
* the return state as well as the state in the TCB. |
|||
* |
|||
* Hmmm... there looks like a latent bug here: The following |
|||
* logic would fail in the strange case where we are in an |
|||
* interrupt handler, the thread is signaling itself, but |
|||
* a context switch to another task has occurred so that |
|||
* g_current_regs does not refer to the thread of this_task()! |
|||
*/ |
|||
|
|||
else |
|||
{ |
|||
/* Save the return EPC and STATUS registers. These will be
|
|||
* restored by the signal trampoline after the signals have |
|||
* been delivered. |
|||
*/ |
|||
|
|||
tcb->xcp.sigdeliver = sigdeliver; |
|||
tcb->xcp.saved_epc = g_current_regs[REG_EPC]; |
|||
|
|||
/* Then set up to vector to the trampoline with interrupts
|
|||
* disabled |
|||
*/ |
|||
|
|||
g_current_regs[REG_EPC] = (uint32_t)up_sigdeliver; |
|||
|
|||
/* And make sure that the saved context in the TCB
|
|||
* is the same as the interrupt return context. |
|||
*/ |
|||
|
|||
up_savestate(tcb->xcp.regs); |
|||
|
|||
// sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n",
|
|||
// tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx,
|
|||
// g_current_regs[REG_EPC], g_current_regs[REG_STATUS]);
|
|||
} |
|||
} |
|||
|
|||
/* Otherwise, we are (1) signaling a task is not running
|
|||
* from an interrupt handler or (2) we are not in an |
|||
* interrupt handler and the running task is signaling |
|||
* some non-running task. |
|||
*/ |
|||
|
|||
else |
|||
{ |
|||
/* Save the return EPC and STATUS registers. These will be
|
|||
* restored by the signal trampoline after the signals have |
|||
* been delivered. |
|||
*/ |
|||
|
|||
tcb->xcp.sigdeliver = sigdeliver; |
|||
tcb->xcp.saved_epc = tcb->xcp.regs[REG_EPC]; |
|||
|
|||
/* Then set up to vector to the trampoline with interrupts
|
|||
* disabled |
|||
*/ |
|||
|
|||
tcb->xcp.regs[REG_EPC] = (uint32_t)up_sigdeliver; |
|||
|
|||
// sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n",
|
|||
// tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx,
|
|||
// tcb->xcp.regs[REG_EPC], tcb->xcp.regs[REG_STATUS]);
|
|||
} |
|||
} |
|||
} |
@ -0,0 +1,361 @@ |
|||
/****************************************************************************
|
|||
* arch/risc-v/src/gap8/gap8_interrupt.c |
|||
* GAP8 event system |
|||
* |
|||
* Copyright (C) 2018 Gregory Nutt. All rights reserved. |
|||
* Author: hhuysqt <1020988872@qq.com> |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions |
|||
* are met: |
|||
* |
|||
* 1. Redistributions of source code must retain the above copyright |
|||
* notice, this list of conditions and the following disclaimer. |
|||
* 2. Redistributions in binary form must reproduce the above copyright |
|||
* notice, this list of conditions and the following disclaimer in |
|||
* the documentation and/or other materials provided with the |
|||
* distribution. |
|||
* 3. Neither the name NuttX nor the names of its contributors may be |
|||
* used to endorse or promote products derived from this software |
|||
* without specific prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* GAP8 features a FC controller and a 8-core cluster. IRQ from peripherals |
|||
* have unique ID, which are dispatched to the FC or cluster by the SOC |
|||
* event unit, and then by the FC event unit or cluster event unit, and |
|||
* finally to FC or cluster. Peripherals share the same IRQ entry. |
|||
****************************************************************************/ |
|||
|
|||
/****************************************************************************
|
|||
* Included Files |
|||
****************************************************************************/ |
|||
|
|||
#include <arch_interrupt.h> |
|||
#include <xs_base.h> |
|||
#include <xs_isr.h> |
|||
|
|||
/****************************************************************************
|
|||
* Public Data |
|||
****************************************************************************/ |
|||
|
|||
volatile uint32_t *g_current_regs; |
|||
|
|||
/****************************************************************************
|
|||
* Public Functions |
|||
****************************************************************************/ |
|||
|
|||
/* Function exported to the NuttX kernel */ |
|||
|
|||
void up_mdelay(unsigned int time) |
|||
{ |
|||
while (time--) |
|||
{ |
|||
volatile int dummy = 200000; |
|||
while (dummy--) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
|
|||
/****************************************************************************
|
|||
* Name: up_disable_irq |
|||
* |
|||
* Description: |
|||
* Disable the IRQ specified by 'irq'. Mind the Machine privilege. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
int ArchDisableHwIrq(uint32_t irq_num) |
|||
{ |
|||
FCEU->MASK_IRQ_AND = (1UL << irq_num); |
|||
} |
|||
/****************************************************************************
|
|||
* Name: up_enable_irq |
|||
* |
|||
* Description: |
|||
* Enable the IRQ specified by 'irq'. Mind the Machine privilege. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
int ArchEnableHwIrq(uint32_t irq_num) |
|||
{ |
|||
FCEU->MASK_IRQ_OR = (1 << irq_num); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/****************************************************************************
|
|||
* Name: up_ack_irq |
|||
* |
|||
* Description: |
|||
* Acknowledge the IRQ |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
static inline void up_ack_irq(int irq) |
|||
{ |
|||
} |
|||
|
|||
/****************************************************************************
|
|||
* Name: _current_privilege |
|||
* |
|||
* Description: |
|||
* Get the current privilege mode. 0x0 for user mode, and 0x3 for machine |
|||
* mode. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
static inline uint32_t _current_privilege(void) |
|||
{ |
|||
uint32_t result; |
|||
|
|||
asm volatile ("csrr %0, 0xC10" : "=r" (result)); |
|||
|
|||
return result; |
|||
} |
|||
/****************************************************************************
|
|||
* Name: up_irq_restore |
|||
* |
|||
* Description: |
|||
* Restore previous IRQ mask state |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
static inline void up_irq_restore(unsigned int pri) |
|||
{ |
|||
if (_current_privilege()) |
|||
{ |
|||
/* Machine mode - mstatus */ |
|||
|
|||
asm volatile("csrw 0x300, %0" : /* no output */ : "r" (pri)); |
|||
} |
|||
else |
|||
{ |
|||
/* User mode - ustatus */ |
|||
|
|||
asm volatile("csrw 0x000, %0" : /* no output */ : "r" (pri)); |
|||
} |
|||
} |
|||
/****************************************************************************
|
|||
* Name: up_irq_save |
|||
* |
|||
* Description: |
|||
* Disable interrupt and return the current interrupt state. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
x_base up_irq_save(void) |
|||
{ |
|||
x_base oldstat; |
|||
x_base newstat; |
|||
|
|||
if (_current_privilege()) |
|||
{ |
|||
/* Machine mode: Unset MIE and UIE */ |
|||
|
|||
asm volatile ("csrr %0, 0x300": "=r" (oldstat)); |
|||
newstat = oldstat & ~(0x9); |
|||
asm volatile("csrw 0x300, %0" : /* no output */ : "r" (newstat)); |
|||
} |
|||
else |
|||
{ |
|||
/* User mode: Unset UIE */ |
|||
|
|||
asm volatile ("csrr %0, 0x000": "=r" (oldstat)); |
|||
newstat = oldstat & ~(1L << 0); |
|||
asm volatile("csrw 0x000, %0" : /* no output */ : "r" (newstat)); |
|||
} |
|||
|
|||
return oldstat; |
|||
} |
|||
/****************************************************************************
|
|||
* Name: up_irq_save |
|||
* |
|||
* Description: |
|||
* Disable interrupt and return the current interrupt state. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
x_base DisableLocalInterrupt(void) |
|||
{ |
|||
// x_base oldstat;
|
|||
// x_base newstat;
|
|||
|
|||
// if (_current_privilege())
|
|||
// {
|
|||
// /* Machine mode: Unset MIE and UIE */
|
|||
// asm volatile("nop");
|
|||
// asm volatile ("csrr %0, 0x300": "=r" (oldstat));
|
|||
// newstat = oldstat & ~(0x9);
|
|||
// asm volatile("csrw 0x300, %0" : /* no output */ : "r" (newstat));
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// /* User mode: Unset UIE */
|
|||
|
|||
// asm volatile ("csrr %0, 0x000": "=r" (oldstat));
|
|||
// newstat = oldstat & ~(1L << 0);
|
|||
// asm volatile("csrw 0x000, %0" : /* no output */ : "r" (newstat));
|
|||
// }
|
|||
|
|||
// return oldstat;
|
|||
|
|||
x_base level; |
|||
asm volatile("nop"); |
|||
asm volatile ("csrrci %0, mstatus, 8" : "=r"(level)); |
|||
|
|||
return level; |
|||
} |
|||
|
|||
|
|||
|
|||
/****************************************************************************
|
|||
* Name: up_irq_enable |
|||
* |
|||
* Description: |
|||
* Return the current interrupt state and enable interrupts |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
void EnableLocalInterrupt(x_base oldstat) |
|||
{ |
|||
x_base newstat; |
|||
|
|||
// if (_current_privilege())
|
|||
// {
|
|||
// /* Machine mode: Set MIE and UIE */
|
|||
// asm volatile("nop");
|
|||
// asm volatile ("csrr %0, 0x300": "=r" (oldstat));
|
|||
// newstat = oldstat | (0x8);
|
|||
// // asm volatile("csrw 0x300, %0" : /* no output */ : "r" (newstat));
|
|||
// asm volatile("csrw mstatus, %0" : /* no output */ : "r" (newstat));
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// /* User mode: Set UIE */
|
|||
|
|||
// asm volatile ("csrr %0, 0x000": "=r" (oldstat));
|
|||
// newstat = oldstat | (1L << 0);
|
|||
// asm volatile("csrw 0x000, %0" : /* no output */ : "r" (newstat));
|
|||
// }
|
|||
asm volatile ("csrw mstatus, %0" :: "r"(oldstat)); |
|||
} |
|||
|
|||
/****************************************************************************
|
|||
* Name: gap8_sleep_wait_sw_evnt |
|||
* |
|||
* Description: |
|||
* Sleep on specific event. |
|||
* |
|||
****************************************************************************/ |
|||
|
|||
// static inline void gap8_sleep_wait_sw_evnt(uint32_t event_mask)
|
|||
// {
|
|||
// FCEU->MASK_OR = event_mask;
|
|||