forked from xuos/xiuos
add gap8 board of riscv for xiuos
This commit is contained in:
Regular → Executable
+4
@@ -16,4 +16,8 @@ ifeq ($(CONFIG_BOARD_AIIT_RISCV_EVB),y)
|
||||
SRC_DIR +=k210
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_GAPUINO),y)
|
||||
SRC_DIR +=gap8
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := boot.S interrupt.c tick.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
+287
@@ -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
|
||||
Executable
+382
@@ -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
|
||||
Executable
+57
@@ -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 */
|
||||
Executable
+2045
File diff suppressed because it is too large
Load Diff
+98
@@ -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
|
||||
+84
@@ -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
|
||||
}
|
||||
+199
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+361
@@ -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;
|
||||
// __builtin_pulp_event_unit_read((void *)&FCEU->EVENT_WAIT_CLEAR, 0);
|
||||
// FCEU->MASK_AND = event_mask;
|
||||
// }
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
*
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_get_newintctx
|
||||
*
|
||||
* Description:
|
||||
* Return a value for EPIC. But GAP8 doesn't use EPIC for event control.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t up_get_newintctx(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_irqinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the IRQ on FC.
|
||||
*
|
||||
****************************************************************************/
|
||||
extern void gap8_udma_doirq(int irq, void *arg);
|
||||
void irqinitialize(void)
|
||||
{
|
||||
x_base level;
|
||||
/* Deactivate all the soc events */
|
||||
|
||||
SOC_EU->FC_MASK_MSB = 0xffffffff;
|
||||
SOC_EU->FC_MASK_LSB = 0xffffffff;
|
||||
|
||||
/* enable soc peripheral interrupt */
|
||||
|
||||
isrManager.done->registerIrq(GAP8_IRQ_FC_UDMA, gap8_udma_doirq, NONE);
|
||||
isrManager.done->enableIrq(GAP8_IRQ_FC_UDMA);
|
||||
|
||||
/* Attach system call handler */
|
||||
|
||||
// extern int up_swint(int irq, FAR void *context, FAR void *arg);
|
||||
// RegisterHwIrq(GAP8_IRQ_SYSCALL, up_swint, NULL);
|
||||
|
||||
// EnableLocalInterrupt(0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gap8_dispatch_irq
|
||||
*
|
||||
* Description:
|
||||
* Called from IRQ vectors. Input vector id. Return SP pointer, modified
|
||||
* or not.
|
||||
*
|
||||
****************************************************************************/
|
||||
extern void KTaskOsAssignAfterIrq(void *context);
|
||||
|
||||
void *gap8_dispatch_irq(uint32_t vector, void *current_regs)
|
||||
{
|
||||
/* Clear pending bit and trigger a software event.
|
||||
* GAP8 would sleep on sw event 3 on up_idle().
|
||||
*/
|
||||
|
||||
FCEU->BUFFER_CLEAR = (1 << vector);
|
||||
EU_SW_EVNT_TRIG->TRIGGER_SET[3] = 0;
|
||||
|
||||
/* Call nuttx kernel, which may change curr_regs, to perform
|
||||
* a context switch
|
||||
*/
|
||||
|
||||
g_current_regs = current_regs;
|
||||
// irq_dispatch(vector, current_regs);
|
||||
|
||||
isrManager.done->incCounter();
|
||||
isrManager.done->handleIrq(vector);
|
||||
|
||||
isrManager.done->decCounter();
|
||||
|
||||
KTaskOsAssignAfterIrq(current_regs);
|
||||
|
||||
current_regs = (void *)g_current_regs;
|
||||
g_current_regs = NONE;
|
||||
|
||||
return current_regs;
|
||||
}
|
||||
|
||||
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
#include <xs_ktick.h>
|
||||
static volatile unsigned long tick_cycles = 0;
|
||||
int TickIsr(void)
|
||||
{
|
||||
TickAndTaskTimesliceUpdate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user