Merge pull request #37 from kendryte/feature/new_sched
Refactor scheduler and interrupt handlerfix/double
commit
8f14b9dae3
|
@ -14,12 +14,11 @@ add_compile_flags(LD
|
|||
# C Flags Settings
|
||||
add_compile_flags(BOTH
|
||||
-mcmodel=medany
|
||||
-march=rv64imafdc
|
||||
-march=rv64imafc
|
||||
-fno-common
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-fstrict-volatile-bitfields
|
||||
-fno-zero-initialized-in-bss
|
||||
-O2
|
||||
-ggdb
|
||||
)
|
||||
|
|
|
@ -53,12 +53,14 @@ SECTIONS
|
|||
KEEP( *(.text.start) )
|
||||
KEEP( *(.text.systick) )
|
||||
} > ram : DATA
|
||||
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} > ram : DATA
|
||||
|
||||
|
||||
. = ALIGN(8);
|
||||
. = .;
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
|
@ -163,6 +165,7 @@ SECTIONS
|
|||
} > ram : DATA
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
|
||||
. = ALIGN(8);
|
||||
. = .;
|
||||
__bss_start = .;
|
||||
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } > ram : DYN_DATA
|
||||
|
|
|
@ -37,15 +37,15 @@ extern "C"
|
|||
: "memory"); \
|
||||
}
|
||||
|
||||
#define atomic_set(ptr, val) (*(volatile typeof(*(ptr))*)(ptr) = val)
|
||||
#define atomic_read(ptr) (*(volatile typeof(*(ptr))*)(ptr))
|
||||
#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val)
|
||||
#define atomic_read(ptr) (*(volatile typeof(*(ptr)) *)(ptr))
|
||||
|
||||
#define atomic_add(ptr, inc) __sync_fetch_and_add(ptr, inc)
|
||||
#define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc)
|
||||
#define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp)
|
||||
#define atomic_cas(ptr, cmp, swp) __sync_val_compare_and_swap(ptr, cmp, swp)
|
||||
|
||||
static inline int spinlock_trylock(spinlock_t* lock)
|
||||
static inline int spinlock_trylock(spinlock_t *lock)
|
||||
{
|
||||
int res = atomic_swap(&lock->lock, -1);
|
||||
/*Use memory barrier to keep coherency */
|
||||
|
@ -53,7 +53,7 @@ extern "C"
|
|||
return res;
|
||||
}
|
||||
|
||||
static inline void spinlock_lock(spinlock_t* lock)
|
||||
static inline void spinlock_lock(spinlock_t *lock)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ extern "C"
|
|||
} while (spinlock_trylock(lock));
|
||||
}
|
||||
|
||||
static inline void spinlock_unlock(spinlock_t* lock)
|
||||
static inline void spinlock_unlock(spinlock_t *lock)
|
||||
{
|
||||
/*Use memory barrier to keep coherency */
|
||||
mb();
|
||||
|
@ -83,7 +83,7 @@ extern "C"
|
|||
.core = -1 \
|
||||
}
|
||||
|
||||
static inline int corelock_trylock(corelock_t* lock)
|
||||
static inline int corelock_trylock(corelock_t *lock)
|
||||
{
|
||||
int res = 0;
|
||||
unsigned long core;
|
||||
|
@ -115,7 +115,7 @@ extern "C"
|
|||
return res;
|
||||
}
|
||||
|
||||
static inline void corelock_lock(corelock_t* lock)
|
||||
static inline void corelock_lock(corelock_t *lock)
|
||||
{
|
||||
unsigned long core;
|
||||
|
||||
|
@ -148,7 +148,7 @@ extern "C"
|
|||
spinlock_unlock(&lock->lock);
|
||||
}
|
||||
|
||||
static inline void corelock_unlock(corelock_t* lock)
|
||||
static inline void corelock_unlock(corelock_t *lock)
|
||||
{
|
||||
unsigned long core;
|
||||
|
||||
|
@ -168,17 +168,7 @@ extern "C"
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Different core release lock */
|
||||
spinlock_unlock(&lock->lock);
|
||||
|
||||
register unsigned long a7 asm("a7") = 93;
|
||||
register unsigned long a0 asm("a0") = 0;
|
||||
register unsigned long a1 asm("a1") = 0;
|
||||
register unsigned long a2 asm("a2") = 0;
|
||||
|
||||
asm volatile("scall"
|
||||
: "+r"(a0)
|
||||
: "r"(a1), "r"(a2), "r"(a7));
|
||||
asm volatile("sbreak");
|
||||
}
|
||||
spinlock_unlock(&lock->lock);
|
||||
}
|
||||
|
|
|
@ -160,6 +160,26 @@
|
|||
|
||||
#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
|
||||
|
||||
#define SYS_apc_return 2013
|
||||
|
||||
#define REG_EPC 0
|
||||
#define REG_RA 1
|
||||
#define REG_SP 2
|
||||
#define REG_T0 5
|
||||
#define REG_T1 6
|
||||
#define REG_A0 10
|
||||
#define REG_A1 11
|
||||
#define REG_A2 12
|
||||
#define REG_A3 13
|
||||
#define REG_A4 14
|
||||
#define REG_A5 15
|
||||
#define REG_A6 16
|
||||
#define REG_A7 17
|
||||
#define REG_APC_PROC 64
|
||||
#define REG_APC_RET 65
|
||||
|
||||
#define NUM_XCEPT_REGS (66)
|
||||
|
||||
#ifdef __riscv
|
||||
|
||||
#ifdef __riscv64
|
||||
|
|
644
lib/bsp/crt.S
644
lib/bsp/crt.S
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2018 Canaan Inc.
|
||||
# Copyright 2018 Canaan Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -15,12 +15,18 @@
|
|||
|
||||
# define REGBYTES 8
|
||||
# define STKSHIFT 16
|
||||
# define IRQ_STACK_SIZE 20480
|
||||
|
||||
.global g_wake_address
|
||||
.global g_irq_count
|
||||
.global xPortStartScheduler
|
||||
.global sys_apc_thunk
|
||||
|
||||
.section .text.start, "ax", @progbits
|
||||
.globl _start
|
||||
_start:
|
||||
j 1f
|
||||
.half 0x0000
|
||||
nop
|
||||
.word 0xdeadbeef
|
||||
1:
|
||||
csrw mideleg, 0
|
||||
|
@ -29,6 +35,9 @@ _start:
|
|||
csrw mip, 0
|
||||
la t0, trap_entry
|
||||
csrw mtvec, t0
|
||||
|
||||
li t0, 1
|
||||
sd t0, _irq_enabled, t1
|
||||
|
||||
li x1, 0
|
||||
li x2, 0
|
||||
|
@ -66,266 +75,97 @@ _start:
|
|||
csrs mstatus, t0
|
||||
|
||||
fssr x0
|
||||
fmv.d.x f0, x0
|
||||
fmv.d.x f1, x0
|
||||
fmv.d.x f2, x0
|
||||
fmv.d.x f3, x0
|
||||
fmv.d.x f4, x0
|
||||
fmv.d.x f5, x0
|
||||
fmv.d.x f6, x0
|
||||
fmv.d.x f7, x0
|
||||
fmv.d.x f8, x0
|
||||
fmv.d.x f9, x0
|
||||
fmv.d.x f10,x0
|
||||
fmv.d.x f11,x0
|
||||
fmv.d.x f12,x0
|
||||
fmv.d.x f13,x0
|
||||
fmv.d.x f14,x0
|
||||
fmv.d.x f15,x0
|
||||
fmv.d.x f16,x0
|
||||
fmv.d.x f17,x0
|
||||
fmv.d.x f18,x0
|
||||
fmv.d.x f19,x0
|
||||
fmv.d.x f20,x0
|
||||
fmv.d.x f21,x0
|
||||
fmv.d.x f22,x0
|
||||
fmv.d.x f23,x0
|
||||
fmv.d.x f24,x0
|
||||
fmv.d.x f25,x0
|
||||
fmv.d.x f26,x0
|
||||
fmv.d.x f27,x0
|
||||
fmv.d.x f28,x0
|
||||
fmv.d.x f29,x0
|
||||
fmv.d.x f30,x0
|
||||
fmv.d.x f31,x0
|
||||
fmv.w.x f0, x0
|
||||
fmv.w.x f1, x0
|
||||
fmv.w.x f2, x0
|
||||
fmv.w.x f3, x0
|
||||
fmv.w.x f4, x0
|
||||
fmv.w.x f5, x0
|
||||
fmv.w.x f6, x0
|
||||
fmv.w.x f7, x0
|
||||
fmv.w.x f8, x0
|
||||
fmv.w.x f9, x0
|
||||
fmv.w.x f10,x0
|
||||
fmv.w.x f11,x0
|
||||
fmv.w.x f12,x0
|
||||
fmv.w.x f13,x0
|
||||
fmv.w.x f14,x0
|
||||
fmv.w.x f15,x0
|
||||
fmv.w.x f16,x0
|
||||
fmv.w.x f17,x0
|
||||
fmv.w.x f18,x0
|
||||
fmv.w.x f19,x0
|
||||
fmv.w.x f20,x0
|
||||
fmv.w.x f21,x0
|
||||
fmv.w.x f22,x0
|
||||
fmv.w.x f23,x0
|
||||
fmv.w.x f24,x0
|
||||
fmv.w.x f25,x0
|
||||
fmv.w.x f26,x0
|
||||
fmv.w.x f27,x0
|
||||
fmv.w.x f28,x0
|
||||
fmv.w.x f29,x0
|
||||
fmv.w.x f30,x0
|
||||
fmv.w.x f31,x0
|
||||
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
la tp, _end + 63
|
||||
and tp, tp, -64
|
||||
csrr a0, mhartid
|
||||
|
||||
sll a2, a0, STKSHIFT
|
||||
add tp, tp, a2
|
||||
add sp, a0, 1
|
||||
sll sp, sp, STKSHIFT
|
||||
add sp, sp, tp
|
||||
csrr t0, mhartid
|
||||
beqz t0, 2f
|
||||
la sp, _idle_stack1_top
|
||||
la t0, g_wake_address
|
||||
1:
|
||||
lr.d t1, 0(t0)
|
||||
beqz t1, 1b
|
||||
jr t1
|
||||
2:
|
||||
la sp, _idle_stack0_top
|
||||
|
||||
# clear the bss segment
|
||||
la t0, __bss_start
|
||||
la t1, __bss_end
|
||||
1:
|
||||
sd zero, 0(t0)
|
||||
addi t0, t0, 8
|
||||
bltu t0, t1, 1b
|
||||
|
||||
j _init_bsp
|
||||
la t0, _init_bsp
|
||||
jr t0
|
||||
|
||||
# t0 = mhartid
|
||||
# t1 = mhartid * 8
|
||||
# t2 = _irq_count + t1
|
||||
# t3 = _irq_count[t1]
|
||||
.macro get_irq_count
|
||||
csrr t0, mhartid
|
||||
slli t1, t0, 3
|
||||
la t2, g_irq_count
|
||||
add t2, t2, t1
|
||||
ld t3, 0(t2)
|
||||
.endm
|
||||
|
||||
.globl trap_entry
|
||||
.type trap_entry, @function
|
||||
.align 2
|
||||
trap_entry:
|
||||
addi sp, sp, -REGBYTES
|
||||
sd t0, 0x0(sp)
|
||||
csrr t0, mcause
|
||||
bgez t0, .handle_other
|
||||
# Test soft interrupt
|
||||
slli t0, t0, 1
|
||||
addi t0, t0, -(IRQ_M_SOFT << 1)
|
||||
bnez t0, .handle_irq
|
||||
# Interupt is soft interrupt
|
||||
# Get event
|
||||
addi sp, sp, -REGBYTES
|
||||
sd t1, 0x0(sp)
|
||||
la t0, g_core_pending_switch
|
||||
csrr t1, mhartid
|
||||
slli t1, t1, 3
|
||||
add t0, t0, t1
|
||||
ld t1, 0x0(sp)
|
||||
addi sp, sp, REGBYTES
|
||||
# Test ContextSwitch event
|
||||
ld t0, 0x0(t0)
|
||||
beqz t0, .handle_irq
|
||||
|
||||
ld t0, 0x0(sp)
|
||||
addi sp, sp, REGBYTES
|
||||
# Do not use jal here
|
||||
j xPortSysTickInt
|
||||
csrw mscratch, t0
|
||||
ld t0, _irq_enabled
|
||||
bnez t0, 1f
|
||||
# Disable interrupt
|
||||
li t0, MSTATUS_MPIE
|
||||
csrc mstatus, t0
|
||||
csrr t0, mscratch
|
||||
mret
|
||||
.handle_irq:
|
||||
ld t0, 0x0(sp)
|
||||
addi sp, sp, REGBYTES
|
||||
addi sp, sp, -36 * REGBYTES
|
||||
|
||||
sd ra, 0 * REGBYTES(sp)
|
||||
sd t0, 1 * REGBYTES(sp)
|
||||
sd t1, 2 * REGBYTES(sp)
|
||||
sd t2, 3 * REGBYTES(sp)
|
||||
sd a0, 4 * REGBYTES(sp)
|
||||
sd a1, 5 * REGBYTES(sp)
|
||||
sd a2, 6 * REGBYTES(sp)
|
||||
sd a3, 7 * REGBYTES(sp)
|
||||
sd a4, 8 * REGBYTES(sp)
|
||||
sd a5, 9 * REGBYTES(sp)
|
||||
sd a6, 10 * REGBYTES(sp)
|
||||
sd a7, 11 * REGBYTES(sp)
|
||||
sd t3, 12 * REGBYTES(sp)
|
||||
sd t4, 13 * REGBYTES(sp)
|
||||
sd t5, 14 * REGBYTES(sp)
|
||||
sd t6, 15 * REGBYTES(sp)
|
||||
|
||||
fsd ft0, ( 0 + 16) * REGBYTES(sp)
|
||||
fsd ft1, ( 1 + 16) * REGBYTES(sp)
|
||||
fsd ft2, ( 2 + 16) * REGBYTES(sp)
|
||||
fsd ft3, ( 3 + 16) * REGBYTES(sp)
|
||||
fsd ft4, ( 4 + 16) * REGBYTES(sp)
|
||||
fsd ft5, ( 5 + 16) * REGBYTES(sp)
|
||||
fsd ft6, ( 6 + 16) * REGBYTES(sp)
|
||||
fsd ft7, ( 7 + 16) * REGBYTES(sp)
|
||||
fsd fa0, ( 8 + 16) * REGBYTES(sp)
|
||||
fsd fa1, ( 9 + 16) * REGBYTES(sp)
|
||||
fsd fa2, (10 + 16) * REGBYTES(sp)
|
||||
fsd fa3, (11 + 16) * REGBYTES(sp)
|
||||
fsd fa4, (12 + 16) * REGBYTES(sp)
|
||||
fsd fa5, (13 + 16) * REGBYTES(sp)
|
||||
fsd fa6, (14 + 16) * REGBYTES(sp)
|
||||
fsd fa7, (15 + 16) * REGBYTES(sp)
|
||||
fsd ft8, (16 + 16) * REGBYTES(sp)
|
||||
fsd ft9, (17 + 16) * REGBYTES(sp)
|
||||
fsd ft10, (18 + 16) * REGBYTES(sp)
|
||||
fsd ft11, (19 + 16) * REGBYTES(sp)
|
||||
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
jal handle_irq
|
||||
|
||||
li t0, MSTATUS_MPP | MSTATUS_MPIE
|
||||
csrs mstatus, t0
|
||||
|
||||
ld ra, 0 * REGBYTES(sp)
|
||||
ld t0, 1 * REGBYTES(sp)
|
||||
ld t1, 2 * REGBYTES(sp)
|
||||
ld t2, 3 * REGBYTES(sp)
|
||||
ld a0, 4 * REGBYTES(sp)
|
||||
ld a1, 5 * REGBYTES(sp)
|
||||
ld a2, 6 * REGBYTES(sp)
|
||||
ld a3, 7 * REGBYTES(sp)
|
||||
ld a4, 8 * REGBYTES(sp)
|
||||
ld a5, 9 * REGBYTES(sp)
|
||||
ld a6, 10 * REGBYTES(sp)
|
||||
ld a7, 11 * REGBYTES(sp)
|
||||
ld t3, 12 * REGBYTES(sp)
|
||||
ld t4, 13 * REGBYTES(sp)
|
||||
ld t5, 14 * REGBYTES(sp)
|
||||
ld t6, 15 * REGBYTES(sp)
|
||||
|
||||
fld ft0, ( 0 + 16) * REGBYTES(sp)
|
||||
fld ft1, ( 1 + 16) * REGBYTES(sp)
|
||||
fld ft2, ( 2 + 16) * REGBYTES(sp)
|
||||
fld ft3, ( 3 + 16) * REGBYTES(sp)
|
||||
fld ft4, ( 4 + 16) * REGBYTES(sp)
|
||||
fld ft5, ( 5 + 16) * REGBYTES(sp)
|
||||
fld ft6, ( 6 + 16) * REGBYTES(sp)
|
||||
fld ft7, ( 7 + 16) * REGBYTES(sp)
|
||||
fld fa0, ( 8 + 16) * REGBYTES(sp)
|
||||
fld fa1, ( 9 + 16) * REGBYTES(sp)
|
||||
fld fa2, (10 + 16) * REGBYTES(sp)
|
||||
fld fa3, (11 + 16) * REGBYTES(sp)
|
||||
fld fa4, (12 + 16) * REGBYTES(sp)
|
||||
fld fa5, (13 + 16) * REGBYTES(sp)
|
||||
fld fa6, (14 + 16) * REGBYTES(sp)
|
||||
fld fa7, (15 + 16) * REGBYTES(sp)
|
||||
fld ft8, (16 + 16) * REGBYTES(sp)
|
||||
fld ft9, (17 + 16) * REGBYTES(sp)
|
||||
fld ft10, (18 + 16) * REGBYTES(sp)
|
||||
fld ft11, (19 + 16) * REGBYTES(sp)
|
||||
|
||||
addi sp, sp, 36 * REGBYTES
|
||||
mret
|
||||
.handle_other:
|
||||
csrr t0, mcause
|
||||
addi t0, t0, -CAUSE_USER_ECALL
|
||||
bltz t0, .handle_except
|
||||
.handle_syscall:
|
||||
ld t0, 0x0(sp)
|
||||
addi sp, sp, REGBYTES
|
||||
addi sp, sp, -29 * REGBYTES
|
||||
|
||||
sd ra, 0 * REGBYTES(sp)
|
||||
sd t0, 1 * REGBYTES(sp)
|
||||
sd t1, 2 * REGBYTES(sp)
|
||||
sd t2, 3 * REGBYTES(sp)
|
||||
sd a6, 4 * REGBYTES(sp)
|
||||
sd t3, 5 * REGBYTES(sp)
|
||||
sd t4, 6 * REGBYTES(sp)
|
||||
sd t5, 7 * REGBYTES(sp)
|
||||
sd t6, 8 * REGBYTES(sp)
|
||||
|
||||
fsd ft0, ( 0 + 9) * REGBYTES(sp)
|
||||
fsd ft1, ( 1 + 9) * REGBYTES(sp)
|
||||
fsd ft2, ( 2 + 9) * REGBYTES(sp)
|
||||
fsd ft3, ( 3 + 9) * REGBYTES(sp)
|
||||
fsd ft4, ( 4 + 9) * REGBYTES(sp)
|
||||
fsd ft5, ( 5 + 9) * REGBYTES(sp)
|
||||
fsd ft6, ( 6 + 9) * REGBYTES(sp)
|
||||
fsd ft7, ( 7 + 9) * REGBYTES(sp)
|
||||
fsd fa0, ( 8 + 9) * REGBYTES(sp)
|
||||
fsd fa1, ( 9 + 9) * REGBYTES(sp)
|
||||
fsd fa2, (10 + 9) * REGBYTES(sp)
|
||||
fsd fa3, (11 + 9) * REGBYTES(sp)
|
||||
fsd fa4, (12 + 9) * REGBYTES(sp)
|
||||
fsd fa5, (13 + 9) * REGBYTES(sp)
|
||||
fsd fa6, (14 + 9) * REGBYTES(sp)
|
||||
fsd fa7, (15 + 9) * REGBYTES(sp)
|
||||
fsd ft8, (16 + 9) * REGBYTES(sp)
|
||||
fsd ft9, (17 + 9) * REGBYTES(sp)
|
||||
fsd ft10, (18 + 9) * REGBYTES(sp)
|
||||
fsd ft11, (19 + 9) * REGBYTES(sp)
|
||||
|
||||
csrr a6, mepc
|
||||
jal handle_syscall
|
||||
csrw mepc, a1
|
||||
|
||||
# /* Run in machine mode */
|
||||
li t0, MSTATUS_MPP | MSTATUS_MPIE
|
||||
csrs mstatus, t0
|
||||
|
||||
ld ra, 0 * REGBYTES(sp)
|
||||
ld t0, 1 * REGBYTES(sp)
|
||||
ld t1, 2 * REGBYTES(sp)
|
||||
ld t2, 3 * REGBYTES(sp)
|
||||
ld a6, 4 * REGBYTES(sp)
|
||||
ld t3, 5 * REGBYTES(sp)
|
||||
ld t4, 6 * REGBYTES(sp)
|
||||
ld t5, 7 * REGBYTES(sp)
|
||||
ld t6, 8 * REGBYTES(sp)
|
||||
|
||||
fld ft0, ( 0 + 9) * REGBYTES(sp)
|
||||
fld ft1, ( 1 + 9) * REGBYTES(sp)
|
||||
fld ft2, ( 2 + 9) * REGBYTES(sp)
|
||||
fld ft3, ( 3 + 9) * REGBYTES(sp)
|
||||
fld ft4, ( 4 + 9) * REGBYTES(sp)
|
||||
fld ft5, ( 5 + 9) * REGBYTES(sp)
|
||||
fld ft6, ( 6 + 9) * REGBYTES(sp)
|
||||
fld ft7, ( 7 + 9) * REGBYTES(sp)
|
||||
fld fa0, ( 8 + 9) * REGBYTES(sp)
|
||||
fld fa1, ( 9 + 9) * REGBYTES(sp)
|
||||
fld fa2, (10 + 9) * REGBYTES(sp)
|
||||
fld fa3, (11 + 9) * REGBYTES(sp)
|
||||
fld fa4, (12 + 9) * REGBYTES(sp)
|
||||
fld fa5, (13 + 9) * REGBYTES(sp)
|
||||
fld fa6, (14 + 9) * REGBYTES(sp)
|
||||
fld fa7, (15 + 9) * REGBYTES(sp)
|
||||
fld ft8, (16 + 9) * REGBYTES(sp)
|
||||
fld ft9, (17 + 9) * REGBYTES(sp)
|
||||
fld ft10, (18 + 9) * REGBYTES(sp)
|
||||
fld ft11, (19 + 9) * REGBYTES(sp)
|
||||
|
||||
addi sp, sp, 29 * REGBYTES
|
||||
mret
|
||||
.handle_except:
|
||||
ld t0, 0x0(sp)
|
||||
addi sp, sp, REGBYTES
|
||||
addi sp, sp, -64 * REGBYTES
|
||||
1:
|
||||
csrr t0, mscratch
|
||||
# Save context
|
||||
addi sp, sp, -NUM_XCEPT_REGS * REGBYTES
|
||||
|
||||
sd x0, 0 * REGBYTES(sp)
|
||||
sd x1, 1 * REGBYTES(sp)
|
||||
sd x2, 2 * REGBYTES(sp)
|
||||
sd x3, 3 * REGBYTES(sp)
|
||||
sd x4, 4 * REGBYTES(sp)
|
||||
sd x5, 5 * REGBYTES(sp)
|
||||
sd x6, 6 * REGBYTES(sp)
|
||||
|
@ -355,56 +195,184 @@ trap_entry:
|
|||
sd x30, 30 * REGBYTES(sp)
|
||||
sd x31, 31 * REGBYTES(sp)
|
||||
|
||||
fsd f0, ( 0 + 32) * REGBYTES(sp)
|
||||
fsd f1, ( 1 + 32) * REGBYTES(sp)
|
||||
fsd f2, ( 2 + 32) * REGBYTES(sp)
|
||||
fsd f3, ( 3 + 32) * REGBYTES(sp)
|
||||
fsd f4, ( 4 + 32) * REGBYTES(sp)
|
||||
fsd f5, ( 5 + 32) * REGBYTES(sp)
|
||||
fsd f6, ( 6 + 32) * REGBYTES(sp)
|
||||
fsd f7, ( 7 + 32) * REGBYTES(sp)
|
||||
fsd f8, ( 8 + 32) * REGBYTES(sp)
|
||||
fsd f9, ( 9 + 32) * REGBYTES(sp)
|
||||
fsd f10, (10 + 32) * REGBYTES(sp)
|
||||
fsd f11, (11 + 32) * REGBYTES(sp)
|
||||
fsd f12, (12 + 32) * REGBYTES(sp)
|
||||
fsd f13, (13 + 32) * REGBYTES(sp)
|
||||
fsd f14, (14 + 32) * REGBYTES(sp)
|
||||
fsd f15, (15 + 32) * REGBYTES(sp)
|
||||
fsd f16, (16 + 32) * REGBYTES(sp)
|
||||
fsd f17, (17 + 32) * REGBYTES(sp)
|
||||
fsd f18, (18 + 32) * REGBYTES(sp)
|
||||
fsd f19, (19 + 32) * REGBYTES(sp)
|
||||
fsd f20, (20 + 32) * REGBYTES(sp)
|
||||
fsd f21, (21 + 32) * REGBYTES(sp)
|
||||
fsd f22, (22 + 32) * REGBYTES(sp)
|
||||
fsd f23, (23 + 32) * REGBYTES(sp)
|
||||
fsd f24, (24 + 32) * REGBYTES(sp)
|
||||
fsd f25, (25 + 32) * REGBYTES(sp)
|
||||
fsd f26, (26 + 32) * REGBYTES(sp)
|
||||
fsd f27, (27 + 32) * REGBYTES(sp)
|
||||
fsd f28, (28 + 32) * REGBYTES(sp)
|
||||
fsd f29, (29 + 32) * REGBYTES(sp)
|
||||
fsd f30, (30 + 32) * REGBYTES(sp)
|
||||
fsd f31, (31 + 32) * REGBYTES(sp)
|
||||
fsw f0, ( 0 + 32) * REGBYTES(sp)
|
||||
fsw f1, ( 1 + 32) * REGBYTES(sp)
|
||||
fsw f2, ( 2 + 32) * REGBYTES(sp)
|
||||
fsw f3, ( 3 + 32) * REGBYTES(sp)
|
||||
fsw f4, ( 4 + 32) * REGBYTES(sp)
|
||||
fsw f5, ( 5 + 32) * REGBYTES(sp)
|
||||
fsw f6, ( 6 + 32) * REGBYTES(sp)
|
||||
fsw f7, ( 7 + 32) * REGBYTES(sp)
|
||||
fsw f8, ( 8 + 32) * REGBYTES(sp)
|
||||
fsw f9, ( 9 + 32) * REGBYTES(sp)
|
||||
fsw f10, (10 + 32) * REGBYTES(sp)
|
||||
fsw f11, (11 + 32) * REGBYTES(sp)
|
||||
fsw f12, (12 + 32) * REGBYTES(sp)
|
||||
fsw f13, (13 + 32) * REGBYTES(sp)
|
||||
fsw f14, (14 + 32) * REGBYTES(sp)
|
||||
fsw f15, (15 + 32) * REGBYTES(sp)
|
||||
fsw f16, (16 + 32) * REGBYTES(sp)
|
||||
fsw f17, (17 + 32) * REGBYTES(sp)
|
||||
fsw f18, (18 + 32) * REGBYTES(sp)
|
||||
fsw f19, (19 + 32) * REGBYTES(sp)
|
||||
fsw f20, (20 + 32) * REGBYTES(sp)
|
||||
fsw f21, (21 + 32) * REGBYTES(sp)
|
||||
fsw f22, (22 + 32) * REGBYTES(sp)
|
||||
fsw f23, (23 + 32) * REGBYTES(sp)
|
||||
fsw f24, (24 + 32) * REGBYTES(sp)
|
||||
fsw f25, (25 + 32) * REGBYTES(sp)
|
||||
fsw f26, (26 + 32) * REGBYTES(sp)
|
||||
fsw f27, (27 + 32) * REGBYTES(sp)
|
||||
fsw f28, (28 + 32) * REGBYTES(sp)
|
||||
fsw f29, (29 + 32) * REGBYTES(sp)
|
||||
fsw f30, (30 + 32) * REGBYTES(sp)
|
||||
fsw f31, (31 + 32) * REGBYTES(sp)
|
||||
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
mv a2, sp
|
||||
add a3, sp, 32 * REGBYTES
|
||||
jal handle_except
|
||||
csrw mepc, a0
|
||||
# Store mepc
|
||||
csrr t0, mepc
|
||||
sd t0, 0 * REGBYTES(sp)
|
||||
|
||||
# a0 = regs
|
||||
mv a0, sp
|
||||
# a1 = mcause
|
||||
csrr a1, mcause
|
||||
|
||||
get_irq_count
|
||||
# _irq_count++
|
||||
addi t4, t3, 1
|
||||
sd t4, 0(t2)
|
||||
# Test if already in trap handler
|
||||
bnez t3, 3f
|
||||
# If not in trap handler, store sp
|
||||
la t2, pxCurrentTCB
|
||||
add t2, t2, t1
|
||||
ld t2, 0(t2)
|
||||
beqz t2, 1f
|
||||
sd sp, 0(t2)
|
||||
1:
|
||||
# Then set sp to irq stack top
|
||||
beqz t0, 2f
|
||||
la sp, _irq_stack1_top
|
||||
j 3f
|
||||
2:
|
||||
la sp, _irq_stack0_top
|
||||
3:
|
||||
la t0, handle_irq
|
||||
jalr t0
|
||||
|
||||
# Disable interrupt
|
||||
li t0, MSTATUS_MIE
|
||||
csrc mstatus, t0
|
||||
|
||||
get_irq_count
|
||||
# _irq_count--
|
||||
addi t4, t3, -1
|
||||
sd t4, 0(t2)
|
||||
|
||||
# If restore to task, use pxCurrentTCB instead of a0
|
||||
bnez t4, 1f
|
||||
.restore:
|
||||
la t2, pxCurrentTCB
|
||||
add t2, t2, t1
|
||||
ld t2, 0(t2)
|
||||
beqz t2, 1f
|
||||
ld a0, 0(t2)
|
||||
|
||||
# Restore context
|
||||
li t0, MSTATUS_MPP | MSTATUS_MPIE
|
||||
csrs mstatus, t0
|
||||
1:
|
||||
# a0 = regs
|
||||
|
||||
# Restore mepc
|
||||
ld t0, 0 * REGBYTES(a0)
|
||||
csrw mepc, t0
|
||||
|
||||
# Store a0 to mscratch
|
||||
ld t0, 10 * REGBYTES(a0)
|
||||
csrw mscratch, t0
|
||||
|
||||
ld x1, 1 * REGBYTES(a0)
|
||||
ld x2, 2 * REGBYTES(a0)
|
||||
ld x4, 4 * REGBYTES(a0)
|
||||
ld x5, 5 * REGBYTES(a0)
|
||||
ld x6, 6 * REGBYTES(a0)
|
||||
ld x7, 7 * REGBYTES(a0)
|
||||
ld x8, 8 * REGBYTES(a0)
|
||||
ld x9, 9 * REGBYTES(a0)
|
||||
ld x11, 11 * REGBYTES(a0)
|
||||
ld x12, 12 * REGBYTES(a0)
|
||||
ld x13, 13 * REGBYTES(a0)
|
||||
ld x14, 14 * REGBYTES(a0)
|
||||
ld x15, 15 * REGBYTES(a0)
|
||||
ld x16, 16 * REGBYTES(a0)
|
||||
ld x17, 17 * REGBYTES(a0)
|
||||
ld x18, 18 * REGBYTES(a0)
|
||||
ld x19, 19 * REGBYTES(a0)
|
||||
ld x20, 20 * REGBYTES(a0)
|
||||
ld x21, 21 * REGBYTES(a0)
|
||||
ld x22, 22 * REGBYTES(a0)
|
||||
ld x23, 23 * REGBYTES(a0)
|
||||
ld x24, 24 * REGBYTES(a0)
|
||||
ld x25, 25 * REGBYTES(a0)
|
||||
ld x26, 26 * REGBYTES(a0)
|
||||
ld x27, 27 * REGBYTES(a0)
|
||||
ld x28, 28 * REGBYTES(a0)
|
||||
ld x29, 29 * REGBYTES(a0)
|
||||
ld x30, 30 * REGBYTES(a0)
|
||||
ld x31, 31 * REGBYTES(a0)
|
||||
|
||||
flw f0, ( 0 + 32) * REGBYTES(a0)
|
||||
flw f1, ( 1 + 32) * REGBYTES(a0)
|
||||
flw f2, ( 2 + 32) * REGBYTES(a0)
|
||||
flw f3, ( 3 + 32) * REGBYTES(a0)
|
||||
flw f4, ( 4 + 32) * REGBYTES(a0)
|
||||
flw f5, ( 5 + 32) * REGBYTES(a0)
|
||||
flw f6, ( 6 + 32) * REGBYTES(a0)
|
||||
flw f7, ( 7 + 32) * REGBYTES(a0)
|
||||
flw f8, ( 8 + 32) * REGBYTES(a0)
|
||||
flw f9, ( 9 + 32) * REGBYTES(a0)
|
||||
flw f10, (10 + 32) * REGBYTES(a0)
|
||||
flw f11, (11 + 32) * REGBYTES(a0)
|
||||
flw f12, (12 + 32) * REGBYTES(a0)
|
||||
flw f13, (13 + 32) * REGBYTES(a0)
|
||||
flw f14, (14 + 32) * REGBYTES(a0)
|
||||
flw f15, (15 + 32) * REGBYTES(a0)
|
||||
flw f16, (16 + 32) * REGBYTES(a0)
|
||||
flw f17, (17 + 32) * REGBYTES(a0)
|
||||
flw f18, (18 + 32) * REGBYTES(a0)
|
||||
flw f19, (19 + 32) * REGBYTES(a0)
|
||||
flw f20, (20 + 32) * REGBYTES(a0)
|
||||
flw f21, (21 + 32) * REGBYTES(a0)
|
||||
flw f22, (22 + 32) * REGBYTES(a0)
|
||||
flw f23, (23 + 32) * REGBYTES(a0)
|
||||
flw f24, (24 + 32) * REGBYTES(a0)
|
||||
flw f25, (25 + 32) * REGBYTES(a0)
|
||||
flw f26, (26 + 32) * REGBYTES(a0)
|
||||
flw f27, (27 + 32) * REGBYTES(a0)
|
||||
flw f28, (28 + 32) * REGBYTES(a0)
|
||||
flw f29, (29 + 32) * REGBYTES(a0)
|
||||
flw f30, (30 + 32) * REGBYTES(a0)
|
||||
flw f31, (31 + 32) * REGBYTES(a0)
|
||||
|
||||
# Restore a0
|
||||
addi sp, sp, NUM_XCEPT_REGS * REGBYTES
|
||||
csrr a0, mscratch
|
||||
mret
|
||||
|
||||
sys_apc_thunk:
|
||||
addi sp, sp, -NUM_XCEPT_REGS * REGBYTES
|
||||
ld t0, REG_APC_PROC * REGBYTES(sp)
|
||||
sd a7, REG_APC_PROC * REGBYTES(sp)
|
||||
jalr t0
|
||||
|
||||
ld x1, 1 * REGBYTES(sp)
|
||||
ld x2, 2 * REGBYTES(sp)
|
||||
ld x3, 3 * REGBYTES(sp)
|
||||
ld x4, 4 * REGBYTES(sp)
|
||||
ld x5, 5 * REGBYTES(sp)
|
||||
ld x6, 6 * REGBYTES(sp)
|
||||
ld x7, 7 * REGBYTES(sp)
|
||||
ld x8, 8 * REGBYTES(sp)
|
||||
ld x9, 9 * REGBYTES(sp)
|
||||
ld x10, 10 * REGBYTES(sp)
|
||||
ld x11, 11 * REGBYTES(sp)
|
||||
ld x12, 12 * REGBYTES(sp)
|
||||
ld x13, 13 * REGBYTES(sp)
|
||||
|
@ -427,41 +395,43 @@ trap_entry:
|
|||
ld x30, 30 * REGBYTES(sp)
|
||||
ld x31, 31 * REGBYTES(sp)
|
||||
|
||||
fld f0, ( 0 + 32) * REGBYTES(sp)
|
||||
fld f1, ( 1 + 32) * REGBYTES(sp)
|
||||
fld f2, ( 2 + 32) * REGBYTES(sp)
|
||||
fld f3, ( 3 + 32) * REGBYTES(sp)
|
||||
fld f4, ( 4 + 32) * REGBYTES(sp)
|
||||
fld f5, ( 5 + 32) * REGBYTES(sp)
|
||||
fld f6, ( 6 + 32) * REGBYTES(sp)
|
||||
fld f7, ( 7 + 32) * REGBYTES(sp)
|
||||
fld f8, ( 8 + 32) * REGBYTES(sp)
|
||||
fld f9, ( 9 + 32) * REGBYTES(sp)
|
||||
fld f10, (10 + 32) * REGBYTES(sp)
|
||||
fld f11, (11 + 32) * REGBYTES(sp)
|
||||
fld f12, (12 + 32) * REGBYTES(sp)
|
||||
fld f13, (13 + 32) * REGBYTES(sp)
|
||||
fld f14, (14 + 32) * REGBYTES(sp)
|
||||
fld f15, (15 + 32) * REGBYTES(sp)
|
||||
fld f16, (16 + 32) * REGBYTES(sp)
|
||||
fld f17, (17 + 32) * REGBYTES(sp)
|
||||
fld f18, (18 + 32) * REGBYTES(sp)
|
||||
fld f19, (19 + 32) * REGBYTES(sp)
|
||||
fld f20, (20 + 32) * REGBYTES(sp)
|
||||
fld f21, (21 + 32) * REGBYTES(sp)
|
||||
fld f22, (22 + 32) * REGBYTES(sp)
|
||||
fld f23, (23 + 32) * REGBYTES(sp)
|
||||
fld f24, (24 + 32) * REGBYTES(sp)
|
||||
fld f25, (25 + 32) * REGBYTES(sp)
|
||||
fld f26, (26 + 32) * REGBYTES(sp)
|
||||
fld f27, (27 + 32) * REGBYTES(sp)
|
||||
fld f28, (28 + 32) * REGBYTES(sp)
|
||||
fld f29, (29 + 32) * REGBYTES(sp)
|
||||
fld f30, (30 + 32) * REGBYTES(sp)
|
||||
fld f31, (31 + 32) * REGBYTES(sp)
|
||||
|
||||
addi sp, sp, 64 * REGBYTES
|
||||
mret
|
||||
flw f0, ( 0 + 32) * REGBYTES(sp)
|
||||
flw f1, ( 1 + 32) * REGBYTES(sp)
|
||||
flw f2, ( 2 + 32) * REGBYTES(sp)
|
||||
flw f3, ( 3 + 32) * REGBYTES(sp)
|
||||
flw f4, ( 4 + 32) * REGBYTES(sp)
|
||||
flw f5, ( 5 + 32) * REGBYTES(sp)
|
||||
flw f6, ( 6 + 32) * REGBYTES(sp)
|
||||
flw f7, ( 7 + 32) * REGBYTES(sp)
|
||||
flw f8, ( 8 + 32) * REGBYTES(sp)
|
||||
flw f9, ( 9 + 32) * REGBYTES(sp)
|
||||
flw f10, (10 + 32) * REGBYTES(sp)
|
||||
flw f11, (11 + 32) * REGBYTES(sp)
|
||||
flw f12, (12 + 32) * REGBYTES(sp)
|
||||
flw f13, (13 + 32) * REGBYTES(sp)
|
||||
flw f14, (14 + 32) * REGBYTES(sp)
|
||||
flw f15, (15 + 32) * REGBYTES(sp)
|
||||
flw f16, (16 + 32) * REGBYTES(sp)
|
||||
flw f17, (17 + 32) * REGBYTES(sp)
|
||||
flw f18, (18 + 32) * REGBYTES(sp)
|
||||
flw f19, (19 + 32) * REGBYTES(sp)
|
||||
flw f20, (20 + 32) * REGBYTES(sp)
|
||||
flw f21, (21 + 32) * REGBYTES(sp)
|
||||
flw f22, (22 + 32) * REGBYTES(sp)
|
||||
flw f23, (23 + 32) * REGBYTES(sp)
|
||||
flw f24, (24 + 32) * REGBYTES(sp)
|
||||
flw f25, (25 + 32) * REGBYTES(sp)
|
||||
flw f26, (26 + 32) * REGBYTES(sp)
|
||||
flw f27, (27 + 32) * REGBYTES(sp)
|
||||
flw f28, (28 + 32) * REGBYTES(sp)
|
||||
flw f29, (29 + 32) * REGBYTES(sp)
|
||||
flw f30, (30 + 32) * REGBYTES(sp)
|
||||
flw f31, (31 + 32) * REGBYTES(sp)
|
||||
|
||||
addi sp, sp, NUM_XCEPT_REGS * REGBYTES
|
||||
li a7, SYS_apc_return
|
||||
ecall
|
||||
j .
|
||||
|
||||
.global _init
|
||||
.type _init, @function
|
||||
|
@ -471,4 +441,32 @@ _init:
|
|||
_fini:
|
||||
ret
|
||||
.size _init, .-_init
|
||||
.size _fini, .-_fini
|
||||
.size _fini, .-_fini
|
||||
|
||||
xPortStartScheduler:
|
||||
la t0, vPortSetupTimer
|
||||
jalr t0
|
||||
csrr t0, mhartid
|
||||
slli t1, t0, 3
|
||||
j .restore
|
||||
|
||||
.align 3
|
||||
g_irq_count:
|
||||
.8byte 0
|
||||
.8byte 0
|
||||
_irq_enabled:
|
||||
.8byte 0
|
||||
g_wake_address:
|
||||
.8byte 0
|
||||
|
||||
.section .bss
|
||||
.align 3
|
||||
_irq_stack_base:
|
||||
.space IRQ_STACK_SIZE
|
||||
_irq_stack0_top:
|
||||
.space IRQ_STACK_SIZE
|
||||
_irq_stack1_top:
|
||||
.space IRQ_STACK_SIZE
|
||||
_idle_stack0_top:
|
||||
.space IRQ_STACK_SIZE
|
||||
_idle_stack1_top:
|
|
@ -589,7 +589,7 @@ private:
|
|||
}
|
||||
|
||||
if (xHigherPriorityTaskWoken)
|
||||
portYIELD();
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
|
||||
static int is_memory(uintptr_t address)
|
||||
|
|
|
@ -520,7 +520,7 @@ private:
|
|||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(driver.session_.stage_completion_event, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken)
|
||||
portYIELD();
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -83,7 +83,7 @@ static void plic_complete_irq(uint32_t source)
|
|||
}
|
||||
|
||||
/* Entry Point for PLIC Interrupt Handler */
|
||||
extern "C" void handle_irq_m_ext(uintptr_t cause, uintptr_t epc)
|
||||
extern "C" void handle_irq_m_ext(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
/**
|
||||
* After the highest-priority pending interrupt is claimed by a target
|
||||
|
@ -95,22 +95,22 @@ extern "C" void handle_irq_m_ext(uintptr_t cause, uintptr_t epc)
|
|||
* without first restoring the interrupted context and taking another
|
||||
* interrupt trap.
|
||||
*/
|
||||
if (read_csr(mip) & MIP_MEIP)
|
||||
//if (read_csr(mip) & MIP_MEIP)
|
||||
{
|
||||
/* Get current core id */
|
||||
uint64_t core_id = read_csr(mhartid);
|
||||
uint64_t ie_flag = read_csr(mie);
|
||||
// uint64_t ie_flag = read_csr(mie);
|
||||
uint32_t int_num = plic.targets.target[core_id].claim_complete;
|
||||
uint32_t int_threshold = plic.targets.target[core_id].priority_threshold;
|
||||
|
||||
plic.targets.target[core_id].priority_threshold = plic.source_priorities.priority[int_num];
|
||||
clear_csr(mie, MIP_MTIP | MIP_MSIP);
|
||||
set_csr(mstatus, MSTATUS_MIE);
|
||||
//clear_csr(mie, MIP_MTIP | MIP_MSIP);
|
||||
//set_csr(mstatus, MSTATUS_MIE);
|
||||
kernel_iface_pic_on_irq(int_num);
|
||||
plic_complete_irq(int_num);
|
||||
clear_csr(mstatus, MSTATUS_MIE);
|
||||
set_csr(mstatus, MSTATUS_MPIE | MSTATUS_MPP);
|
||||
write_csr(mie, ie_flag);
|
||||
//clear_csr(mstatus, MSTATUS_MIE);
|
||||
//set_csr(mstatus, MSTATUS_MPIE | MSTATUS_MPP);
|
||||
//write_csr(mie, ie_flag);
|
||||
plic.targets.target[core_id].priority_threshold = int_threshold;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,16 @@
|
|||
#include <syslog.h>
|
||||
#include <uarths.h>
|
||||
#include "dump.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
#define DUMP_PRINTF printk
|
||||
|
||||
static corelock_t s_dump_lock = CORELOCK_INIT;
|
||||
|
||||
void dump_core(const char* reason, uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void dump_core(const char *reason, uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
static const char* const reg_usage[][2] = {
|
||||
{"zero ", "Hard-wired zero"},
|
||||
{"mpec ", "Machine exception program counter"},
|
||||
{"ra ", "Return address"},
|
||||
{"sp ", "Stack pointer"},
|
||||
{"gp ", "Global pointer"},
|
||||
|
@ -104,8 +105,10 @@ void dump_core(const char* reason, uintptr_t cause, uintptr_t epc, uintptr_t reg
|
|||
if (!reason)
|
||||
reason = unknown_reason;
|
||||
|
||||
uintptr_t *fregs = regs + 32;
|
||||
|
||||
DUMP_PRINTF("core %d, core dump: %s\n", (int)read_csr(mhartid), reason);
|
||||
DUMP_PRINTF("Cause 0x%016lx, EPC 0x%016lx\n", cause, epc);
|
||||
DUMP_PRINTF("Cause 0x%016lx\n", cause);
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
|
|
@ -12,28 +12,25 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "interrupt.h"
|
||||
#include "pin_cfg_priv.h"
|
||||
#include <FreeRTOSConfig.h>
|
||||
#include <clint.h>
|
||||
#include <fpioa.h>
|
||||
#include <hal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysctl.h>
|
||||
#include <uarths.h>
|
||||
#include "pin_cfg_priv.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define PLL1_OUTPUT_FREQ 160000000UL
|
||||
#define PLL2_OUTPUT_FREQ 45158400UL
|
||||
|
||||
extern uint8_t __bss_start[];
|
||||
extern uint8_t __bss_end[];
|
||||
extern uint8_t _tls_data[];
|
||||
|
||||
extern int main(int argc, char* argv[]);
|
||||
extern void __libc_init_array(void);
|
||||
extern void __libc_fini_array(void);
|
||||
extern int os_entry(int core_id, int number_of_cores, int (*user_main)(int, char**));
|
||||
extern int main(int argc, char *argv[]);
|
||||
extern int os_entry(int (*user_main)(int, char **));
|
||||
|
||||
static void setup_clocks()
|
||||
{
|
||||
|
@ -41,29 +38,15 @@ static void setup_clocks()
|
|||
sysctl_pll_set_freq(SYSCTL_PLL2, PLL2_OUTPUT_FREQ);
|
||||
}
|
||||
|
||||
static void init_bss(void)
|
||||
void _init_bsp()
|
||||
{
|
||||
memset(__bss_start, 0, __bss_end - __bss_start);
|
||||
}
|
||||
/* Init FPIOA */
|
||||
fpioa_init();
|
||||
bsp_pin_setup();
|
||||
/* Setup clocks */
|
||||
setup_clocks();
|
||||
/* Init UART */
|
||||
uarths_init();
|
||||
|
||||
void _init_bsp(int core_id, int number_of_cores)
|
||||
{
|
||||
if (core_id == 0)
|
||||
{
|
||||
/* Initialize bss data to 0 */
|
||||
init_bss();
|
||||
/* Register finalization function */
|
||||
atexit(__libc_fini_array);
|
||||
/* Init libc array for C++ */
|
||||
__libc_init_array();
|
||||
/* Init FPIOA */
|
||||
fpioa_init();
|
||||
bsp_pin_setup();
|
||||
/* Setup clocks */
|
||||
setup_clocks();
|
||||
/* Init UART */
|
||||
uarths_init();
|
||||
}
|
||||
|
||||
exit(os_entry(core_id, number_of_cores, main));
|
||||
exit(os_entry(main));
|
||||
}
|
||||
|
|
|
@ -12,81 +12,62 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "dump.h"
|
||||
#include "interrupt.h"
|
||||
#include <encoding.h>
|
||||
#include <stdlib.h>
|
||||
#include "dump.h"
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) (void)(x)
|
||||
#endif
|
||||
|
||||
uintptr_t __attribute__((weak))
|
||||
handle_misaligned_fetch(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void __attribute__((weak)) handle_misaligned_fetch(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
dump_core("misaligned fetch", cause, epc, regs, fregs);
|
||||
exit(1337);
|
||||
return epc;
|
||||
dump_core("misaligned fetch", regs, cause);
|
||||
sys_exit(1337);
|
||||
}
|
||||
|
||||
uintptr_t __attribute__((weak))
|
||||
handle_fault_fetch(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void __attribute__((weak)) handle_fault_fetch(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
dump_core("fault fetch", cause, epc, regs, fregs);
|
||||
exit(1337);
|
||||
return epc;
|
||||
dump_core("fault fetch", regs, cause);
|
||||
sys_exit(1337);
|
||||
}
|
||||
|
||||
uintptr_t __attribute__((weak))
|
||||
handle_illegal_instruction(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void __attribute__((weak)) handle_illegal_instruction(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
dump_core("illegal instruction", cause, epc, regs, fregs);
|
||||
exit(1337);
|
||||
return epc;
|
||||
dump_core("illegal instruction", regs, cause);
|
||||
sys_exit(1337);
|
||||
}
|
||||
|
||||
uintptr_t __attribute__((weak))
|
||||
handle_breakpoint(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void __attribute__((weak)) handle_breakpoint(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
dump_core("breakpoint", cause, epc, regs, fregs);
|
||||
exit(1337);
|
||||
return epc;
|
||||
dump_core("breakpoint", regs, cause);
|
||||
sys_exit(1337);
|
||||
}
|
||||
|
||||
uintptr_t __attribute__((weak))
|
||||
handle_misaligned_load(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void __attribute__((weak)) handle_misaligned_load(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
dump_core("misaligned load", cause, epc, regs, fregs);
|
||||
exit(1337);
|
||||
return epc;
|
||||
dump_core("misaligned load", regs, cause);
|
||||
sys_exit(1337);
|
||||
}
|
||||
|
||||
uintptr_t __attribute__((weak))
|
||||
handle_fault_load(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void __attribute__((weak)) handle_fault_load(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
dump_core("fault load", cause, epc, regs, fregs);
|
||||
exit(1337);
|
||||
return epc;
|
||||
dump_core("fault load", regs, cause);
|
||||
sys_exit(1337);
|
||||
}
|
||||
|
||||
uintptr_t __attribute__((weak))
|
||||
handle_misaligned_store(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void __attribute__((weak)) handle_misaligned_store(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
dump_core("misaligned store", cause, epc, regs, fregs);
|
||||
exit(1337);
|
||||
return epc;
|
||||
dump_core("misaligned store", regs, cause);
|
||||
sys_exit(1337);
|
||||
}
|
||||
|
||||
uintptr_t __attribute__((weak))
|
||||
handle_fault_store(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void __attribute__((weak)) handle_fault_store(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
dump_core("fault store", cause, epc, regs, fregs);
|
||||
exit(1337);
|
||||
return epc;
|
||||
dump_core("fault store", regs, cause);
|
||||
sys_exit(1337);
|
||||
}
|
||||
|
||||
uintptr_t handle_except(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
|
||||
void handle_except(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
static uintptr_t(*const cause_table[])(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32]) = {
|
||||
static void (*const cause_table[])(uintptr_t * regs, uintptr_t cause) = {
|
||||
[CAUSE_MISALIGNED_FETCH] = handle_misaligned_fetch,
|
||||
[CAUSE_FAULT_FETCH] = handle_fault_fetch,
|
||||
[CAUSE_ILLEGAL_INSTRUCTION] = handle_illegal_instruction,
|
||||
|
@ -97,5 +78,5 @@ uintptr_t handle_except(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uint
|
|||
[CAUSE_FAULT_STORE] = handle_fault_store
|
||||
};
|
||||
|
||||
return cause_table[cause](cause, epc, regs, fregs);
|
||||
cause_table[cause & CAUSE_HYPERVISOR_IRQ_REASON_MASK](regs, cause);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
void dump_core(const char* reason, uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32]);
|
||||
void dump_core(const char *reason, uintptr_t *regs, uintptr_t cause);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
#ifndef _BSP_INTERRUPT_H
|
||||
#define _BSP_INTERRUPT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <core_sync.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -36,7 +40,13 @@ extern "C" {
|
|||
|
||||
/* Supervisor interrupt reason mask for 64 bit system, 0x7FFF FFFF FFFF FFFF */
|
||||
#define CAUSE_SUPERVISOR_IRQ_REASON_MASK (CAUSE_SUPERVISOR_IRQ_MASK - 1)
|
||||
/* clang-format on */
|
||||
|
||||
void handle_except(uintptr_t *regs, uintptr_t cause);
|
||||
void handle_irq_m_soft(uintptr_t *regs, uintptr_t cause);
|
||||
void handle_irq_m_timer(uintptr_t *regs, uintptr_t cause);
|
||||
void handle_irq_m_ext(uintptr_t *regs, uintptr_t cause);
|
||||
void handle_syscall(uintptr_t *regs, uintptr_t cause);
|
||||
void __attribute__((noreturn)) sys_exit(int code);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -12,51 +12,51 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "interrupt.h"
|
||||
#include "dump.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include "interrupt.h"
|
||||
#include "dump.h"
|
||||
#include <task.h>
|
||||
|
||||
static const char* TAG = "INTERRUPT";
|
||||
static const char *TAG = "INTERRUPT";
|
||||
|
||||
void __attribute__((weak))
|
||||
handle_irq_dummy(uintptr_t cause, uintptr_t epc)
|
||||
void __attribute__((weak)) handle_irq_dummy(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
LOGE(TAG, "unhandled interrupt: Cause 0x%016lx, EPC 0x%016lx\n", cause, epc);
|
||||
LOGE(TAG, "unhandled interrupt: Cause 0x%016lx, EPC 0x%016lx\n", cause, regs[REG_EPC]);
|
||||
exit(1337);
|
||||
}
|
||||
|
||||
void __attribute__((weak, alias("handle_irq_dummy")))
|
||||
handle_irq_m_soft(uintptr_t cause, uintptr_t epc);
|
||||
|
||||
void __attribute__((weak, alias("handle_irq_dummy")))
|
||||
handle_irq_m_timer(uintptr_t cause, uintptr_t epc);
|
||||
|
||||
void __attribute__((weak, alias("handle_irq_dummy")))
|
||||
handle_irq_m_ext(uintptr_t cause, uintptr_t epc);
|
||||
|
||||
void __attribute__((weak))
|
||||
handle_irq(uintptr_t cause, uintptr_t epc)
|
||||
uintptr_t *handle_irq(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
|
||||
// NMI
|
||||
if (cause & CAUSE_MACHINE_IRQ_MASK)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Woverride-init"
|
||||
#endif
|
||||
/* clang-format off */
|
||||
static void(* const irq_table[])(
|
||||
uintptr_t cause,
|
||||
uintptr_t epc) = {
|
||||
[0 ... 14] = handle_irq_dummy,
|
||||
[IRQ_M_SOFT] = handle_irq_m_soft,
|
||||
[IRQ_M_TIMER] = handle_irq_m_timer,
|
||||
[IRQ_M_EXT] = handle_irq_m_ext,
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
/* clang-format off */
|
||||
static void(* const irq_table[])(
|
||||
uintptr_t *regs, uintptr_t cause) = {
|
||||
[0 ... 14] = handle_irq_dummy,
|
||||
[IRQ_M_SOFT] = handle_irq_m_soft,
|
||||
[IRQ_M_TIMER] = handle_irq_m_timer,
|
||||
[IRQ_M_EXT] = handle_irq_m_ext,
|
||||
};
|
||||
/* clang-format on */
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic warning "-Woverride-init"
|
||||
#endif
|
||||
|
||||
irq_table[cause & CAUSE_MACHINE_IRQ_REASON_MASK](cause, epc);
|
||||
irq_table[cause & CAUSE_HYPERVISOR_IRQ_REASON_MASK](regs, cause);
|
||||
}
|
||||
else if (cause > CAUSE_USER_ECALL)
|
||||
{
|
||||
handle_syscall(regs, cause);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_except(regs, cause);
|
||||
}
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
|
|
@ -92,23 +92,11 @@
|
|||
#define UNUSED(x) (void)(x)
|
||||
#endif
|
||||
|
||||
#define SYS_RET(epc_val, err_val) \
|
||||
syscall_ret_t ret = { \
|
||||
.err = err_val, \
|
||||
.epc = epc_val \
|
||||
}; \
|
||||
return ret;
|
||||
|
||||
typedef struct _syscall_ret
|
||||
{
|
||||
uintptr_t err;
|
||||
uintptr_t epc;
|
||||
} syscall_ret_t;
|
||||
|
||||
static const char *TAG = "SYSCALL";
|
||||
|
||||
extern char _heap_start[];
|
||||
extern char _heap_end[];
|
||||
extern void sys_apc_thunk();
|
||||
char *_heap_cur = &_heap_start[0];
|
||||
|
||||
void __attribute__((noreturn)) sys_exit(int code)
|
||||
|
@ -125,6 +113,9 @@ static int sys_nosys(long a0, long a1, long a2, long a3, long a4, long a5, unsig
|
|||
UNUSED(a4);
|
||||
UNUSED(a5);
|
||||
|
||||
LOGW(TAG, "Unimplemented syscall 0x%lx\n", (uint64_t)n);
|
||||
exit(ENOSYS);
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
|
@ -284,7 +275,7 @@ static int sys_gettimeofday(struct timeval *tp, void *tzp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static syscall_ret_t handle_ecall(uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t epc, uintptr_t n)
|
||||
static void handle_ecall(uintptr_t *regs)
|
||||
{
|
||||
enum syscall_id_e
|
||||
{
|
||||
|
@ -313,94 +304,76 @@ static syscall_ret_t handle_ecall(uintptr_t a0, uintptr_t a1, uintptr_t a2, uint
|
|||
[SYS_ID_FSTAT] = (void *)sys_fstat,
|
||||
[SYS_ID_CLOSE] = (void *)sys_close,
|
||||
[SYS_ID_GETTIMEOFDAY] = (void *)sys_gettimeofday,
|
||||
[SYS_ID_LSEEK] = (void *)sys_lseek,
|
||||
[SYS_ID_LSEEK] = (void *)sys_lseek
|
||||
};
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Woverride-init"
|
||||
#endif
|
||||
static const uint8_t syscall_id_table[0x100] = {
|
||||
[0x00 ... 0xFF] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_exit] = SYS_ID_EXIT,
|
||||
[0xFF & SYS_exit_group] = SYS_ID_EXIT,
|
||||
[0xFF & SYS_getpid] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_kill] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_read] = SYS_ID_READ,
|
||||
[0xFF & SYS_write] = SYS_ID_WRITE,
|
||||
[0xFF & SYS_open] = SYS_ID_OPEN,
|
||||
[0xFF & SYS_openat] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_close] = SYS_ID_CLOSE,
|
||||
[0xFF & SYS_lseek] = SYS_ID_LSEEK,
|
||||
[0xFF & SYS_brk] = SYS_ID_BRK,
|
||||
[0xFF & SYS_link] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_unlink] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_mkdir] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_chdir] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_getcwd] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_stat] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_fstat] = SYS_ID_FSTAT,
|
||||
[0xFF & SYS_lstat] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_fstatat] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_access] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_faccessat] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_pread] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_pwrite] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_uname] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_getuid] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_geteuid] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_getgid] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_getegid] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_mmap] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_munmap] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_mremap] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_time] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_getmainvars] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_rt_sigaction] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_writev] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_gettimeofday] = SYS_ID_GETTIMEOFDAY,
|
||||
[0xFF & SYS_times] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_fcntl] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_getdents] = SYS_ID_NOSYS,
|
||||
[0xFF & SYS_dup] = SYS_ID_NOSYS,
|
||||
};
|
||||
|
||||
uintptr_t n = regs[REG_A7];
|
||||
|
||||
if (n == SYS_apc_return)
|
||||
{
|
||||
regs[REG_EPC] = regs[REG_APC_RET];
|
||||
regs[REG_A7] = regs[REG_APC_PROC];
|
||||
}
|
||||
else
|
||||
{
|
||||
uintptr_t syscall_id = SYS_ID_NOSYS;
|
||||
switch (n)
|
||||
{
|
||||
case SYS_exit:
|
||||
case SYS_exit_group:
|
||||
syscall_id = SYS_ID_EXIT;
|
||||
break;
|
||||
case SYS_read:
|
||||
syscall_id = SYS_ID_READ;
|
||||
break;
|
||||
case SYS_write:
|
||||
syscall_id = SYS_ID_WRITE;
|
||||
break;
|
||||
case SYS_open:
|
||||
syscall_id = SYS_ID_OPEN;
|
||||
break;
|
||||
case SYS_close:
|
||||
syscall_id = SYS_ID_CLOSE;
|
||||
break;
|
||||
case SYS_lseek:
|
||||
syscall_id = SYS_ID_LSEEK;
|
||||
break;
|
||||
case SYS_brk:
|
||||
syscall_id = SYS_ID_BRK;
|
||||
break;
|
||||
case SYS_fstat:
|
||||
syscall_id = SYS_ID_FSTAT;
|
||||
break;
|
||||
case SYS_gettimeofday:
|
||||
syscall_id = SYS_ID_GETTIMEOFDAY;
|
||||
break;
|
||||
}
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic warning "-Woverride-init"
|
||||
#endif
|
||||
|
||||
uintptr_t err = syscall_table[syscall_id_table[0xFF & n]](
|
||||
a0, /* a0 */
|
||||
a1, /* a1 */
|
||||
a2, /* a2 */
|
||||
a3, /* a3 */
|
||||
a4, /* a4 */
|
||||
a5, /* a5 */
|
||||
n /* n */
|
||||
);
|
||||
|
||||
epc += 4;
|
||||
SYS_RET(epc, err);
|
||||
regs[REG_APC_PROC] = (uintptr_t)syscall_table[syscall_id];
|
||||
regs[REG_APC_RET] = regs[REG_EPC] + 4;
|
||||
regs[REG_EPC] = (uintptr_t)sys_apc_thunk;
|
||||
}
|
||||
}
|
||||
|
||||
syscall_ret_t __attribute__((weak, alias("handle_ecall")))
|
||||
handle_ecall_u(uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t epc, uintptr_t n);
|
||||
void __attribute__((weak, alias("handle_ecall"))) handle_ecall_u(uintptr_t *regs);
|
||||
void __attribute__((weak, alias("handle_ecall"))) handle_ecall_h(uintptr_t *regs);
|
||||
void __attribute__((weak, alias("handle_ecall"))) handle_ecall_s(uintptr_t *regs);
|
||||
void __attribute__((weak, alias("handle_ecall"))) handle_ecall_m(uintptr_t *regs);
|
||||
|
||||
syscall_ret_t __attribute__((weak, alias("handle_ecall")))
|
||||
handle_ecall_h(uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t epc, uintptr_t n);
|
||||
|
||||
syscall_ret_t __attribute__((weak, alias("handle_ecall")))
|
||||
handle_ecall_s(uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t epc, uintptr_t n);
|
||||
|
||||
syscall_ret_t __attribute__((weak, alias("handle_ecall")))
|
||||
handle_ecall_m(uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t epc, uintptr_t n);
|
||||
|
||||
syscall_ret_t handle_syscall(uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t epc, uintptr_t n)
|
||||
void handle_syscall(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
static syscall_ret_t (*const cause_table[])(uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t epc, uintptr_t n) = {
|
||||
static void (*const cause_table[])(uintptr_t * regs) = {
|
||||
[CAUSE_USER_ECALL] = handle_ecall_u,
|
||||
[CAUSE_SUPERVISOR_ECALL] = handle_ecall_h,
|
||||
[CAUSE_HYPERVISOR_ECALL] = handle_ecall_s,
|
||||
[CAUSE_MACHINE_ECALL] = handle_ecall_m,
|
||||
};
|
||||
|
||||
return cause_table[read_csr(mcause)](a0, a1, a2, a3, a4, a5, epc, n);
|
||||
cause_table[cause & CAUSE_MACHINE_IRQ_REASON_MASK](regs);
|
||||
}
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "syscalls.h"
|
||||
#include <FreeRTOS.h>
|
||||
#include <devices.h>
|
||||
#include <filesystem.h>
|
||||
#include <kernel/driver_impl.hpp>
|
||||
#include <string.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <task.h>
|
||||
|
||||
using namespace sys;
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ enum
|
|||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
|
||||
/* memory */
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 1024 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 20480 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 1024 * 1024 ) )
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
|
@ -114,7 +114,7 @@ enum
|
|||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
|
||||
|
||||
/* Main task */
|
||||
#define configMAIN_TASK_PRIORITY 1
|
||||
#define configMAIN_TASK_PRIORITY 0
|
||||
#define configMAIN_TASK_STACK_SIZE (4096 * 8)
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */
|
||||
|
@ -127,6 +127,7 @@ enum
|
|||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
|
||||
|
|
|
@ -12,25 +12,24 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <atomic.h>
|
||||
#include <clint.h>
|
||||
#include <core_sync.h>
|
||||
#include <encoding.h>
|
||||
#include <plic.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
volatile UBaseType_t g_core_pending_switch[portNUM_PROCESSORS] = { 0 };
|
||||
static volatile UBaseType_t s_core_sync_events[portNUM_PROCESSORS] = { 0 };
|
||||
static volatile TaskHandle_t s_pending_to_add_tasks[portNUM_PROCESSORS] = { 0 };
|
||||
static volatile UBaseType_t s_core_awake[portNUM_PROCESSORS] = { 1, 0 };
|
||||
static volatile UBaseType_t s_core_sync_in_progress[portNUM_PROCESSORS] = { 0 };
|
||||
extern UBaseType_t *volatile pxCurrentTCB[portNUM_PROCESSORS];
|
||||
extern volatile uintptr_t g_wake_address;
|
||||
|
||||
void handle_irq_m_soft(uintptr_t cause, uintptr_t epc)
|
||||
static volatile core_sync_event_t s_core_sync_events[portNUM_PROCESSORS];
|
||||
static corelock_t s_core_sync_locks[portNUM_PROCESSORS] = { CORELOCK_INIT, CORELOCK_INIT };
|
||||
static volatile TaskHandle_t s_pending_to_add_tasks[portNUM_PROCESSORS];
|
||||
|
||||
void handle_irq_m_soft(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
uint64_t core_id = uxPortGetProcessorId();
|
||||
atomic_set(&s_core_sync_in_progress[core_id], 1);
|
||||
clint_ipi_clear(core_id);
|
||||
switch (s_core_sync_events[core_id])
|
||||
{
|
||||
case CORE_SYNC_ADD_TCB:
|
||||
|
@ -43,8 +42,8 @@ void handle_irq_m_soft(uintptr_t cause, uintptr_t epc)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case CORE_SYNC_WAKE_UP:
|
||||
atomic_set(&s_core_awake[core_id], 1);
|
||||
case CORE_SYNC_SWITCH_CONTEXT:
|
||||
vTaskSwitchContext();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -53,68 +52,33 @@ void handle_irq_m_soft(uintptr_t cause, uintptr_t epc)
|
|||
core_sync_complete(core_id);
|
||||
}
|
||||
|
||||
void handle_irq_m_timer(uintptr_t cause, uintptr_t epc)
|
||||
void core_sync_request(uint64_t core_id, int event)
|
||||
{
|
||||
if (pxCurrentTCB[uxPortGetProcessorId()])
|
||||
{
|
||||
prvSetNextTimerInterrupt();
|
||||
/* Increment the RTOS tick. */
|
||||
if (xTaskIncrementTick() != pdFALSE)
|
||||
{
|
||||
core_sync_request_context_switch(uxPortGetProcessorId());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clear_csr(mie, MIP_MTIP);
|
||||
}
|
||||
}
|
||||
|
||||
void core_sync_request_context_switch(uint64_t core_id)
|
||||
{
|
||||
atomic_set(&g_core_pending_switch[core_id], 1);
|
||||
corelock_lock(&s_core_sync_locks[core_id]);
|
||||
while (s_core_sync_events[core_id] != CORE_SYNC_NONE)
|
||||
;
|
||||
s_core_sync_events[core_id] = event;
|
||||
clint_ipi_send(core_id);
|
||||
corelock_unlock(&s_core_sync_locks[core_id]);
|
||||
}
|
||||
|
||||
void core_sync_complete(uint64_t core_id)
|
||||
{
|
||||
if (atomic_read(&g_core_pending_switch[core_id]) == 0)
|
||||
clint_ipi_clear(core_id);
|
||||
atomic_set(&s_core_sync_events[core_id], CORE_SYNC_NONE);
|
||||
atomic_set(&s_core_sync_in_progress[core_id], 0);
|
||||
}
|
||||
|
||||
void core_sync_complete_context_switch(uint64_t core_id)
|
||||
void core_sync_awaken(uintptr_t address)
|
||||
{
|
||||
if (atomic_read(&s_core_sync_events[core_id]) == CORE_SYNC_NONE)
|
||||
clint_ipi_clear(core_id);
|
||||
atomic_set(&g_core_pending_switch[core_id], 0);
|
||||
g_wake_address = address;
|
||||
}
|
||||
|
||||
int core_sync_is_awake(uint64_t core_id)
|
||||
void vPortAddNewTaskToReadyListAsync(UBaseType_t core_id, void *pxNewTaskHandle)
|
||||
{
|
||||
return !!atomic_read(&s_core_awake[core_id]);
|
||||
}
|
||||
|
||||
void core_sync_awaken(uint64_t core_id)
|
||||
{
|
||||
while (atomic_cas(&s_core_sync_events[core_id], CORE_SYNC_NONE, CORE_SYNC_WAKE_UP) != CORE_SYNC_NONE)
|
||||
corelock_lock(&s_core_sync_locks[core_id]);
|
||||
while (s_core_sync_events[core_id] != CORE_SYNC_NONE)
|
||||
;
|
||||
s_pending_to_add_tasks[core_id] = pxNewTaskHandle;
|
||||
s_core_sync_events[core_id] = CORE_SYNC_ADD_TCB;
|
||||
clint_ipi_send(core_id);
|
||||
}
|
||||
|
||||
int core_sync_is_in_progress(uint64_t core_id)
|
||||
{
|
||||
return !!atomic_read(&s_core_sync_in_progress[core_id]);
|
||||
}
|
||||
|
||||
void vPortAddNewTaskToReadyListAsync(UBaseType_t uxPsrId, void* pxNewTaskHandle)
|
||||
{
|
||||
// Wait for last adding tcb complete
|
||||
while (atomic_read(&s_pending_to_add_tasks[uxPsrId]));
|
||||
atomic_set(&s_pending_to_add_tasks[uxPsrId], pxNewTaskHandle);
|
||||
|
||||
while (atomic_cas(&s_core_sync_events[uxPsrId], CORE_SYNC_NONE, CORE_SYNC_ADD_TCB) != CORE_SYNC_NONE)
|
||||
;
|
||||
clint_ipi_send(uxPsrId);
|
||||
corelock_unlock(&s_core_sync_locks[core_id]);
|
||||
}
|
||||
|
|
|
@ -29,15 +29,12 @@ typedef enum
|
|||
{
|
||||
CORE_SYNC_NONE,
|
||||
CORE_SYNC_ADD_TCB,
|
||||
CORE_SYNC_WAKE_UP
|
||||
CORE_SYNC_SWITCH_CONTEXT
|
||||
} core_sync_event_t;
|
||||
|
||||
void core_sync_request_context_switch(uint64_t core_id);
|
||||
void core_sync_complete_context_switch(uint64_t core_id);
|
||||
void core_sync_request(uint64_t core_id, int event);
|
||||
void core_sync_complete(uint64_t core_id);
|
||||
int core_sync_is_awake(uint64_t core_id);
|
||||
void core_sync_awaken(uint64_t core_id);
|
||||
int core_sync_is_in_progress(uint64_t core_id);
|
||||
void core_sync_awaken(uintptr_t address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
#include <sys/lock.h>
|
||||
#include <stdlib.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "portmacro.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
#include <stdlib.h>
|
||||
#include <sys/lock.h>
|
||||
|
||||
typedef long _lock_t;
|
||||
static void lock_init_generic(_lock_t *lock, uint8_t mutex_type)
|
||||
{
|
||||
portENTER_CRITICAL();
|
||||
if (*lock)
|
||||
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
|
||||
{
|
||||
/* nothing to do until the scheduler is running */
|
||||
portEXIT_CRITICAL();
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if (!*lock)
|
||||
{
|
||||
xSemaphoreHandle new_sem = xQueueCreateMutex(mutex_type);
|
||||
if (!new_sem)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
*lock = (_lock_t)new_sem;
|
||||
}
|
||||
|
||||
portEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
|
@ -42,12 +45,11 @@ void _lock_close(_lock_t *lock)
|
|||
if (*lock)
|
||||
{
|
||||
xSemaphoreHandle h = (xSemaphoreHandle)(*lock);
|
||||
#if (INCLUDE_xSemaphoreGetMutexHolder == 1)
|
||||
configASSERT(xSemaphoreGetMutexHolder(h) == NULL);
|
||||
#endif
|
||||
vSemaphoreDelete(h);
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
portEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
|
@ -58,20 +60,43 @@ static int lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t mutex_typ
|
|||
xSemaphoreHandle h = (xSemaphoreHandle)(*lock);
|
||||
if (!h)
|
||||
{
|
||||
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
|
||||
return 0; /* locking is a no-op before scheduler is up, so this "succeeds" */
|
||||
|
||||
lock_init_generic(lock, mutex_type);
|
||||
h = (xSemaphoreHandle)(*lock);
|
||||
configASSERT(h != NULL);
|
||||
}
|
||||
|
||||
BaseType_t success;
|
||||
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
|
||||
if (uxPortIsInISR())
|
||||
{
|
||||
success = xSemaphoreTakeRecursive(h, delay);
|
||||
/* In ISR Context */
|
||||
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
|
||||
{
|
||||
vPortDebugBreak();
|
||||
abort(); /* recursive mutexes make no sense in ISR context */
|
||||
}
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
success = xSemaphoreTakeFromISR(h, &xHigherPriorityTaskWoken);
|
||||
if (!success && delay > 0)
|
||||
{
|
||||
vPortDebugBreak();
|
||||
abort(); /* Tried to block on mutex from ISR, couldn't... rewrite your program to avoid libc interactions in ISRs! */
|
||||
}
|
||||
|
||||
if (xHigherPriorityTaskWoken)
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
else
|
||||
{
|
||||
success = xSemaphoreTake(h, delay);
|
||||
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
|
||||
success = xSemaphoreTakeRecursive(h, delay);
|
||||
else
|
||||
success = xSemaphoreTake(h, delay);
|
||||
}
|
||||
|
||||
return (success == pdTRUE) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
@ -103,15 +128,30 @@ static void lock_release_generic(_lock_t *lock, uint8_t mutex_type)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
|
||||
if (uxPortIsInISR())
|
||||
{
|
||||
xSemaphoreGiveRecursive(h);
|
||||
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
|
||||
{
|
||||
vPortDebugBreak();
|
||||
abort(); /* recursive mutexes make no sense in ISR context */
|
||||
}
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(h, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken)
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
else
|
||||
{
|
||||
xSemaphoreGive(h);
|
||||
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
|
||||
{
|
||||
xSemaphoreGiveRecursive(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
xSemaphoreGive(h);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _lock_release(_lock_t *lock)
|
||||
|
|
|
@ -28,67 +28,61 @@ typedef struct
|
|||
int ret;
|
||||
} main_thunk_param_t;
|
||||
|
||||
extern void __libc_init_array(void);
|
||||
extern void __libc_fini_array(void);
|
||||
|
||||
static StaticTask_t s_idle_task;
|
||||
static StackType_t s_idle_task_stack[configMINIMAL_STACK_SIZE];
|
||||
|
||||
void start_scheduler(int core_id);
|
||||
|
||||
static void main_thunk(void *p)
|
||||
{
|
||||
main_thunk_param_t *param = (main_thunk_param_t *)p;
|
||||
param->ret = param->user_main(0, 0);
|
||||
}
|
||||
|
||||
void enable_core(int core_id)
|
||||
{
|
||||
core_sync_awaken(core_id);
|
||||
}
|
||||
|
||||
int __attribute__((weak)) configure_fpioa()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int os_entry(int core_id, int number_of_cores, int (*user_main)(int, char **))
|
||||
static void main_thunk(void *p)
|
||||
{
|
||||
/* Register finalization function */
|
||||
atexit(__libc_fini_array);
|
||||
/* Init libc array for C++ */
|
||||
__libc_init_array();
|
||||
|
||||
install_hal();
|
||||
install_drivers();
|
||||
configure_fpioa();
|
||||
|
||||
main_thunk_param_t *param = (main_thunk_param_t *)p;
|
||||
param->ret = param->user_main(0, 0);
|
||||
}
|
||||
|
||||
static void os_entry_core1()
|
||||
{
|
||||
clear_csr(mie, MIP_MTIP);
|
||||
clint_ipi_enable();
|
||||
set_csr(mstatus, MSTATUS_MIE);
|
||||
|
||||
if (core_id == 0)
|
||||
{
|
||||
install_hal();
|
||||
install_drivers();
|
||||
configure_fpioa();
|
||||
|
||||
TaskHandle_t mainTask;
|
||||
main_thunk_param_t param = {};
|
||||
param.user_main = user_main;
|
||||
|
||||
if (xTaskCreate(main_thunk, "Core 0 Main", configMAIN_TASK_STACK_SIZE, ¶m, configMAIN_TASK_PRIORITY, &mainTask) != pdPASS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
enable_core(1);
|
||||
start_scheduler(core_id);
|
||||
return param.ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!core_sync_is_awake(core_id))
|
||||
{
|
||||
asm volatile("wfi");
|
||||
}
|
||||
|
||||
start_scheduler(core_id);
|
||||
return 0;
|
||||
}
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
void start_scheduler(int core_id)
|
||||
int os_entry(int (*user_main)(int, char **))
|
||||
{
|
||||
clear_csr(mie, MIP_MTIP);
|
||||
clint_ipi_enable();
|
||||
set_csr(mstatus, MSTATUS_MIE);
|
||||
|
||||
TaskHandle_t mainTask;
|
||||
main_thunk_param_t param = {};
|
||||
param.user_main = user_main;
|
||||
|
||||
if (xTaskCreate(main_thunk, "Core 0 Main", configMAIN_TASK_STACK_SIZE, ¶m, configMAIN_TASK_PRIORITY, &mainTask) != pdPASS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//core_sync_awaken((uintptr_t)os_entry_core1);
|
||||
vTaskStartScheduler();
|
||||
return param.ret;
|
||||
}
|
||||
|
||||
void vApplicationIdleHook(void)
|
||||
|
|
|
@ -44,6 +44,10 @@
|
|||
*----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "core_sync.h"
|
||||
#include "portmacro.h"
|
||||
#include "task.h"
|
||||
#include <atomic.h>
|
||||
#include <clint.h>
|
||||
#include <encoding.h>
|
||||
|
@ -52,17 +56,15 @@
|
|||
#include <string.h>
|
||||
#include <sysctl.h>
|
||||
#include <syslog.h>
|
||||
#include "core_sync.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "portmacro.h"
|
||||
#include "task.h"
|
||||
|
||||
extern volatile uintptr_t g_irq_count[portNUM_PROCESSORS];
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
variable has to be stored as part of the task context and must be initialised to
|
||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
the scheduler starts. As it is stored as part of the task context it will
|
||||
automatically be set to 0 when the first task is started. */
|
||||
static UBaseType_t uxCriticalNesting[portNUM_PROCESSORS] = {[0 ... portNUM_PROCESSORS - 1] = 0xaaaaaaaa};
|
||||
static UBaseType_t uxCriticalNesting[portNUM_PROCESSORS] = { [0 ... portNUM_PROCESSORS - 1] = 0xaaaaaaaa };
|
||||
PRIVILEGED_DATA static corelock_t xCoreLock = CORELOCK_INIT;
|
||||
|
||||
UBaseType_t uxCPUClockRate = 390000000;
|
||||
|
@ -70,7 +72,7 @@ UBaseType_t uxCPUClockRate = 390000000;
|
|||
/* Contains context when starting scheduler, save all 31 registers */
|
||||
#ifdef __gracefulExit
|
||||
#error Not ported
|
||||
BaseType_t xStartContext[31] = {0};
|
||||
BaseType_t xStartContext[31] = { 0 };
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -93,15 +95,9 @@ UBaseType_t uxPortGetProcessorId()
|
|||
return (UBaseType_t)read_csr(mhartid);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Sets and enable the timer interrupt */
|
||||
void vPortSetupTimer(void)
|
||||
UBaseType_t uxPortIsInISR()
|
||||
{
|
||||
UBaseType_t uxPsrId = uxPortGetProcessorId();
|
||||
clint->mtimecmp[uxPsrId] = clint->mtime + (configTICK_CLOCK_HZ / configTICK_RATE_HZ);
|
||||
/* Enable timer interupt */
|
||||
__asm volatile("csrs mie,%0" ::"r"(0x80));
|
||||
return g_irq_count[uxPortGetProcessorId()] > 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -111,10 +107,30 @@ void vPortSetupTimer(void)
|
|||
void prvSetNextTimerInterrupt(void)
|
||||
{
|
||||
UBaseType_t uxPsrId = uxPortGetProcessorId();
|
||||
clint->mtimecmp[uxPsrId] += (configTICK_CLOCK_HZ / configTICK_RATE_HZ);
|
||||
clint->mtimecmp[uxPsrId] = clint->mtime + (configTICK_CLOCK_HZ / configTICK_RATE_HZ);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Sets and enable the timer interrupt */
|
||||
void vPortSetupTimer(void)
|
||||
{
|
||||
prvSetNextTimerInterrupt();
|
||||
/* Enable timer interupt */
|
||||
__asm volatile("csrs mie,%0" ::"r"(0x80));
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void handle_irq_m_timer(uintptr_t *regs, uintptr_t cause)
|
||||
{
|
||||
prvSetNextTimerInterrupt();
|
||||
|
||||
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
|
||||
return;
|
||||
/* Increment the RTOS tick. */
|
||||
if (xTaskIncrementTick() != pdFALSE)
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
|
||||
void prvTaskExitError(void)
|
||||
{
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
|
@ -144,7 +160,7 @@ int vPortSetInterruptMask(void)
|
|||
int ret;
|
||||
__asm volatile("csrr %0,mie"
|
||||
: "=r"(ret));
|
||||
__asm volatile("csrc mie,%0" ::"i"(7));
|
||||
__asm volatile("csrc mie,%0" ::"r"(0x888));
|
||||
return ret;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -152,49 +168,44 @@ int vPortSetInterruptMask(void)
|
|||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t* pxPortInitialiseStack(StackType_t* pxTopOfStack, TaskFunction_t pxCode, void* pvParameters)
|
||||
StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters)
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
pxTopOfStack -= 64;
|
||||
memset(pxTopOfStack, 0, sizeof(StackType_t) * 64);
|
||||
pxTopOfStack -= NUM_XCEPT_REGS;
|
||||
memset(pxTopOfStack, 0, sizeof(StackType_t) * NUM_XCEPT_REGS);
|
||||
|
||||
pxTopOfStack[0] = (portSTACK_TYPE)prvTaskExitError; /* Register ra */
|
||||
pxTopOfStack[1] = (portSTACK_TYPE)pxTopOfStack;
|
||||
pxTopOfStack[8] = (portSTACK_TYPE)pvParameters; /* Register a0 */
|
||||
pxTopOfStack[30] = 0; /* Register fsr */
|
||||
pxTopOfStack[31] = (portSTACK_TYPE)pxCode; /* Register mepc */
|
||||
pxTopOfStack[REG_RA] = (portSTACK_TYPE)prvTaskExitError; /* Register ra */
|
||||
pxTopOfStack[REG_SP] = (portSTACK_TYPE)pxTopOfStack;
|
||||
pxTopOfStack[REG_A0] = (portSTACK_TYPE)pvParameters; /* Register a0 */
|
||||
pxTopOfStack[REG_EPC] = (portSTACK_TYPE)pxCode; /* Register mepc */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
void vPortSysTickHandler(void)
|
||||
{
|
||||
core_sync_complete_context_switch(uxPortGetProcessorId());
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical(void)
|
||||
{
|
||||
if (!core_sync_is_in_progress(uxPortGetProcessorId()))
|
||||
vTaskEnterCritical();
|
||||
vTaskEnterCritical();
|
||||
corelock_lock(&xCoreLock);
|
||||
}
|
||||
|
||||
void vPortExitCritical(void)
|
||||
{
|
||||
corelock_unlock(&xCoreLock);
|
||||
if (!core_sync_is_in_progress(uxPortGetProcessorId()))
|
||||
vTaskExitCritical();
|
||||
vTaskExitCritical();
|
||||
}
|
||||
|
||||
void vPortYield()
|
||||
{
|
||||
core_sync_request_context_switch(uxPortGetProcessorId());
|
||||
core_sync_request(uxPortGetProcessorId(), CORE_SYNC_SWITCH_CONTEXT);
|
||||
}
|
||||
|
||||
void vPortFatal(const char* file, int line, const char* message)
|
||||
void vPortYieldFromISR(void)
|
||||
{
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
|
||||
void vPortFatal(const char *file, int line, const char *message)
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
corelock_lock(&xCoreLock);
|
||||
|
@ -210,3 +221,8 @@ UBaseType_t uxPortGetCPUClock()
|
|||
{
|
||||
return uxCPUClockRate;
|
||||
}
|
||||
|
||||
void vPortDebugBreak(void)
|
||||
{
|
||||
asm volatile("sbreak");
|
||||
}
|
||||
|
|
|
@ -1,287 +0,0 @@
|
|||
# Copyright 2018 Canaan Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
# All rights reserved
|
||||
|
||||
# VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
# This file is part of the FreeRTOS distribution and was contributed
|
||||
# to the project by Technolution B.V. (www.technolution.nl,
|
||||
# freertos-riscv@technolution.eu) under the terms of the FreeRTOS
|
||||
# contributors license.
|
||||
|
||||
# FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License (version 2) as published by the
|
||||
# Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
# ***************************************************************************
|
||||
# >>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
# >>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
# >>! obliged to provide the source code for proprietary components !<<
|
||||
# >>! outside of the FreeRTOS kernel. !<<
|
||||
# ***************************************************************************
|
||||
|
||||
# FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
# link: http://www.freertos.org/a00114.html
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * FreeRTOS provides completely free yet professionally developed, *
|
||||
# * robust, strictly quality controlled, supported, and cross *
|
||||
# * platform software that is more than just the market leader, it *
|
||||
# * is the industry's de facto standard. *
|
||||
# * *
|
||||
# * Help yourself get started quickly while simultaneously helping *
|
||||
# * to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
# * tutorial book, reference manual, or both: *
|
||||
# * http://www.FreeRTOS.org/Documentation *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
# http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
# the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
# defined configASSERT()?
|
||||
|
||||
# http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
# embedded software for free we request you assist our global community by
|
||||
# participating in the support forum.
|
||||
|
||||
# http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
# be as productive as possible as early as possible. Now you can receive
|
||||
# FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
# Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
# http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
# including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
# compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
# http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
# Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
# http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
# Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
# licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
# http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
# engineered and independently SIL3 certified version for use in safety and
|
||||
# mission critical applications that require provable dependability.
|
||||
|
||||
# 1 tab == 4 spaces!
|
||||
#
|
||||
|
||||
# include "encoding.h"
|
||||
|
||||
# define REGBYTES 8
|
||||
|
||||
.global xPortSysTickInt
|
||||
.global xPortStartScheduler
|
||||
.global vPortYield
|
||||
.global vTaskIncrementTick
|
||||
.global vPortEndScheduler
|
||||
.global xExitStack
|
||||
.global uxPortGetProcessorId
|
||||
|
||||
# /* Macro for saving task context */
|
||||
.macro portSAVE_CONTEXT
|
||||
.global pxCurrentTCB
|
||||
# /* make room in stack */
|
||||
addi sp, sp, -REGBYTES * 64
|
||||
|
||||
# /* Save Context */
|
||||
sd ra, 0 * REGBYTES(sp)
|
||||
sd sp, 1 * REGBYTES(sp)
|
||||
sd tp, 2 * REGBYTES(sp)
|
||||
sd t0, 3 * REGBYTES(sp)
|
||||
sd t1, 4 * REGBYTES(sp)
|
||||
sd t2, 5 * REGBYTES(sp)
|
||||
sd s0, 6 * REGBYTES(sp)
|
||||
sd s1, 7 * REGBYTES(sp)
|
||||
sd a0, 8 * REGBYTES(sp)
|
||||
sd a1, 9 * REGBYTES(sp)
|
||||
sd a2, 10 * REGBYTES(sp)
|
||||
sd a3, 11 * REGBYTES(sp)
|
||||
sd a4, 12 * REGBYTES(sp)
|
||||
sd a5, 13 * REGBYTES(sp)
|
||||
sd a6, 14 * REGBYTES(sp)
|
||||
sd a7, 15 * REGBYTES(sp)
|
||||
sd s2, 16 * REGBYTES(sp)
|
||||
sd s3, 17 * REGBYTES(sp)
|
||||
sd s4, 18 * REGBYTES(sp)
|
||||
sd s5, 19 * REGBYTES(sp)
|
||||
sd s6, 20 * REGBYTES(sp)
|
||||
sd s7, 21 * REGBYTES(sp)
|
||||
sd s8, 22 * REGBYTES(sp)
|
||||
sd s9, 23 * REGBYTES(sp)
|
||||
sd s10, 24 * REGBYTES(sp)
|
||||
sd s11, 25 * REGBYTES(sp)
|
||||
sd t3, 26 * REGBYTES(sp)
|
||||
sd t4, 27 * REGBYTES(sp)
|
||||
sd t5, 28 * REGBYTES(sp)
|
||||
sd t6, 29 * REGBYTES(sp)
|
||||
|
||||
frsr t0
|
||||
sd t0, 30 * REGBYTES(sp)
|
||||
|
||||
csrr t0, mepc
|
||||
sd t0, 31 * REGBYTES(sp)
|
||||
|
||||
fsd f0, ( 0 + 32) * REGBYTES(sp)
|
||||
fsd f1, ( 1 + 32) * REGBYTES(sp)
|
||||
fsd f2, ( 2 + 32) * REGBYTES(sp)
|
||||
fsd f3, ( 3 + 32) * REGBYTES(sp)
|
||||
fsd f4, ( 4 + 32) * REGBYTES(sp)
|
||||
fsd f5, ( 5 + 32) * REGBYTES(sp)
|
||||
fsd f6, ( 6 + 32) * REGBYTES(sp)
|
||||
fsd f7, ( 7 + 32) * REGBYTES(sp)
|
||||
fsd f8, ( 8 + 32) * REGBYTES(sp)
|
||||
fsd f9, ( 9 + 32) * REGBYTES(sp)
|
||||
fsd f10, (10 + 32) * REGBYTES(sp)
|
||||
fsd f11, (11 + 32) * REGBYTES(sp)
|
||||
fsd f12, (12 + 32) * REGBYTES(sp)
|
||||
fsd f13, (13 + 32) * REGBYTES(sp)
|
||||
fsd f14, (14 + 32) * REGBYTES(sp)
|
||||
fsd f15, (15 + 32) * REGBYTES(sp)
|
||||
fsd f16, (16 + 32) * REGBYTES(sp)
|
||||
fsd f17, (17 + 32) * REGBYTES(sp)
|
||||
fsd f18, (18 + 32) * REGBYTES(sp)
|
||||
fsd f19, (19 + 32) * REGBYTES(sp)
|
||||
fsd f20, (20 + 32) * REGBYTES(sp)
|
||||
fsd f21, (21 + 32) * REGBYTES(sp)
|
||||
fsd f22, (22 + 32) * REGBYTES(sp)
|
||||
fsd f23, (23 + 32) * REGBYTES(sp)
|
||||
fsd f24, (24 + 32) * REGBYTES(sp)
|
||||
fsd f25, (25 + 32) * REGBYTES(sp)
|
||||
fsd f26, (26 + 32) * REGBYTES(sp)
|
||||
fsd f27, (27 + 32) * REGBYTES(sp)
|
||||
fsd f28, (28 + 32) * REGBYTES(sp)
|
||||
fsd f29, (29 + 32) * REGBYTES(sp)
|
||||
fsd f30, (30 + 32) * REGBYTES(sp)
|
||||
fsd f31, (31 + 32) * REGBYTES(sp)
|
||||
|
||||
# /* Store current stackpointer in task control block (TCB) */
|
||||
la t0, pxCurrentTCB
|
||||
csrr t1, mhartid
|
||||
slli t1, t1, 3
|
||||
add t0, t0, t1
|
||||
|
||||
ld t0, 0x0(t0)
|
||||
sd sp, 0x0(t0)
|
||||
.endm
|
||||
|
||||
# /* Macro for restoring task context */
|
||||
.macro portRESTORE_CONTEXT
|
||||
.global pxCurrentTCB
|
||||
# /* Load stack pointer from the current TCB */
|
||||
la t0, pxCurrentTCB
|
||||
csrr t1, mhartid
|
||||
slli t1, t1, 3
|
||||
add t0, t0, t1
|
||||
|
||||
ld sp, 0x0(t0)
|
||||
ld sp, 0x0(sp)
|
||||
|
||||
ld t0, 30 * REGBYTES(sp)
|
||||
fssr t0
|
||||
|
||||
ld t0, 31 * REGBYTES(sp)
|
||||
csrw mepc, t0
|
||||
|
||||
# /* Run in machine mode */
|
||||
li t0, MSTATUS_MPP | MSTATUS_MPIE
|
||||
csrs mstatus, t0
|
||||
|
||||
# /* Restore registers */
|
||||
ld ra, 0 * REGBYTES(sp)
|
||||
ld sp, 1 * REGBYTES(sp)
|
||||
ld tp, 2 * REGBYTES(sp)
|
||||
ld t0, 3 * REGBYTES(sp)
|
||||
ld t1, 4 * REGBYTES(sp)
|
||||
ld t2, 5 * REGBYTES(sp)
|
||||
ld s0, 6 * REGBYTES(sp)
|
||||
ld s1, 7 * REGBYTES(sp)
|
||||
ld a0, 8 * REGBYTES(sp)
|
||||
ld a1, 9 * REGBYTES(sp)
|
||||
ld a2, 10 * REGBYTES(sp)
|
||||
ld a3, 11 * REGBYTES(sp)
|
||||
ld a4, 12 * REGBYTES(sp)
|
||||
ld a5, 13 * REGBYTES(sp)
|
||||
ld a6, 14 * REGBYTES(sp)
|
||||
ld a7, 15 * REGBYTES(sp)
|
||||
ld s2, 16 * REGBYTES(sp)
|
||||
ld s3, 17 * REGBYTES(sp)
|
||||
ld s4, 18 * REGBYTES(sp)
|
||||
ld s5, 19 * REGBYTES(sp)
|
||||
ld s6, 20 * REGBYTES(sp)
|
||||
ld s7, 21 * REGBYTES(sp)
|
||||
ld s8, 22 * REGBYTES(sp)
|
||||
ld s9, 23 * REGBYTES(sp)
|
||||
ld s10, 24 * REGBYTES(sp)
|
||||
ld s11, 25 * REGBYTES(sp)
|
||||
ld t3, 26 * REGBYTES(sp)
|
||||
ld t4, 27 * REGBYTES(sp)
|
||||
ld t5, 28 * REGBYTES(sp)
|
||||
ld t6, 29 * REGBYTES(sp)
|
||||
|
||||
fld f0, ( 0 + 32) * REGBYTES(sp)
|
||||
fld f1, ( 1 + 32) * REGBYTES(sp)
|
||||
fld f2, ( 2 + 32) * REGBYTES(sp)
|
||||
fld f3, ( 3 + 32) * REGBYTES(sp)
|
||||
fld f4, ( 4 + 32) * REGBYTES(sp)
|
||||
fld f5, ( 5 + 32) * REGBYTES(sp)
|
||||
fld f6, ( 6 + 32) * REGBYTES(sp)
|
||||
fld f7, ( 7 + 32) * REGBYTES(sp)
|
||||
fld f8, ( 8 + 32) * REGBYTES(sp)
|
||||
fld f9, ( 9 + 32) * REGBYTES(sp)
|
||||
fld f10, (10 + 32) * REGBYTES(sp)
|
||||
fld f11, (11 + 32) * REGBYTES(sp)
|
||||
fld f12, (12 + 32) * REGBYTES(sp)
|
||||
fld f13, (13 + 32) * REGBYTES(sp)
|
||||
fld f14, (14 + 32) * REGBYTES(sp)
|
||||
fld f15, (15 + 32) * REGBYTES(sp)
|
||||
fld f16, (16 + 32) * REGBYTES(sp)
|
||||
fld f17, (17 + 32) * REGBYTES(sp)
|
||||
fld f18, (18 + 32) * REGBYTES(sp)
|
||||
fld f19, (19 + 32) * REGBYTES(sp)
|
||||
fld f20, (20 + 32) * REGBYTES(sp)
|
||||
fld f21, (21 + 32) * REGBYTES(sp)
|
||||
fld f22, (22 + 32) * REGBYTES(sp)
|
||||
fld f23, (23 + 32) * REGBYTES(sp)
|
||||
fld f24, (24 + 32) * REGBYTES(sp)
|
||||
fld f25, (25 + 32) * REGBYTES(sp)
|
||||
fld f26, (26 + 32) * REGBYTES(sp)
|
||||
fld f27, (27 + 32) * REGBYTES(sp)
|
||||
fld f28, (28 + 32) * REGBYTES(sp)
|
||||
fld f29, (29 + 32) * REGBYTES(sp)
|
||||
fld f30, (30 + 32) * REGBYTES(sp)
|
||||
fld f31, (31 + 32) * REGBYTES(sp)
|
||||
|
||||
addi sp, sp, REGBYTES * 64
|
||||
mret
|
||||
.endm
|
||||
|
||||
xPortStartScheduler:
|
||||
jal vPortSetupTimer
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
vPortEndScheduler:
|
||||
ret
|
||||
|
||||
.section .text.systick, "ax", @progbits
|
||||
xPortSysTickInt:
|
||||
portSAVE_CONTEXT
|
||||
call vPortSysTickHandler
|
||||
portRESTORE_CONTEXT
|
|
@ -94,12 +94,11 @@ typedef unsigned long UBaseType_t;
|
|||
#define portCRITICAL_NESTING_IN_TCB 1
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYield( void );
|
||||
#define portYIELD() vPortYield()
|
||||
|
||||
extern void vPortYield(void);
|
||||
extern void vPortYieldFromISR(void);
|
||||
#define portYIELD() vPortYield()
|
||||
#define portYIELD_FROM_ISR() vPortYieldFromISR()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
|
@ -136,7 +135,9 @@ void vPortAddNewTaskToReadyListAsync(UBaseType_t uxPsrId, void* pxNewTaskHandle)
|
|||
void vPortEnterCritical(void);
|
||||
void vPortExitCritical(void);
|
||||
|
||||
UBaseType_t uxPortGetCPUClock();
|
||||
UBaseType_t uxPortGetCPUClock(void);
|
||||
UBaseType_t uxPortIsInISR(void);
|
||||
void vPortDebugBreak(void);
|
||||
|
||||
#define portGET_PROCESSOR_ID() uxPortGetProcessorId()
|
||||
|
||||
|
|
|
@ -2096,7 +2096,7 @@ void vTaskSuspendAll( void )
|
|||
post in the FreeRTOS support forum before reporting this as a bug! -
|
||||
http://goo.gl/wu4acr */
|
||||
UBaseType_t uxPsrId = uxPortGetProcessorId();
|
||||
++uxSchedulerSuspended[uxPsrId];
|
||||
++uxSchedulerSuspended[uxPsrId];
|
||||
}
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
|
@ -2924,7 +2924,11 @@ UBaseType_t uxPsrId = uxPortGetProcessorId();
|
|||
void vTaskSwitchContext( void )
|
||||
{
|
||||
UBaseType_t uxPsrId = uxPortGetProcessorId();
|
||||
if( uxSchedulerSuspended[uxPsrId] != ( UBaseType_t ) pdFALSE )
|
||||
if (xSchedulerRunning[uxPsrId] != pdTRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if( uxSchedulerSuspended[uxPsrId] != ( UBaseType_t ) pdFALSE )
|
||||
{
|
||||
/* The scheduler is currently suspended - do not allow a context
|
||||
switch. */
|
||||
|
@ -3870,7 +3874,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId();
|
|||
}
|
||||
else
|
||||
{
|
||||
if( uxSchedulerSuspended[uxPsrId] == ( UBaseType_t ) pdFALSE )
|
||||
if( uxSchedulerSuspended[uxPortGetProcessorId()] == ( UBaseType_t ) pdFALSE )
|
||||
{
|
||||
xReturn = taskSCHEDULER_RUNNING;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ int pthread_join(pthread_t pthread, void **retval)
|
|||
(void)xSemaphoreTake(&k_thrd->join_barrier, portMAX_DELAY);
|
||||
|
||||
/* Create a critical section to clean up the joined thread. */
|
||||
vTaskSuspendAll();
|
||||
//vTaskSuspendAll();
|
||||
|
||||
/* Release xJoinBarrier and delete it. */
|
||||
(void)xSemaphoreGive(&k_thrd->join_barrier);
|
||||
|
@ -219,7 +219,7 @@ int pthread_join(pthread_t pthread, void **retval)
|
|||
delete k_thrd;
|
||||
|
||||
/* End the critical section. */
|
||||
xTaskResumeAll();
|
||||
//xTaskResumeAll();
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <semphr.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
|
@ -38,7 +41,6 @@ void ff_memfree (
|
|||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
@ -90,8 +92,24 @@ int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a gran
|
|||
FF_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
/* FreeRTOS */
|
||||
return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
if (uxPortIsInISR())
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
int success = (int)xSemaphoreTakeFromISR(sobj, &xHigherPriorityTaskWoken);
|
||||
if (!success && FF_FS_TIMEOUT > 0)
|
||||
{
|
||||
vPortDebugBreak();
|
||||
abort(); /* Tried to block on mutex from ISR, couldn't... rewrite your program to avoid libc interactions in ISRs! */
|
||||
}
|
||||
if (xHigherPriorityTaskWoken)
|
||||
portYIELD_FROM_ISR();
|
||||
return success;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FreeRTOS */
|
||||
return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,8 +123,18 @@ void ff_rel_grant (
|
|||
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
/* FreeRTOS */
|
||||
xSemaphoreGive(sobj);
|
||||
if (uxPortIsInISR())
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(sobj, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken)
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FreeRTOS */
|
||||
xSemaphoreGive(sobj);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,8 +18,8 @@ typedef unsigned short WORD;
|
|||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
typedef int LONG;
|
||||
typedef unsigned int DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
|
Loading…
Reference in New Issue