Impl APC to run syscalls
parent
4665773a4e
commit
56c394343d
|
@ -14,7 +14,7 @@ add_compile_flags(LD
|
|||
# C Flags Settings
|
||||
add_compile_flags(BOTH
|
||||
-mcmodel=medany
|
||||
-march=rv64imafdc
|
||||
-march=rv64imafc
|
||||
-fno-common
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
|
|
|
@ -160,6 +160,27 @@
|
|||
|
||||
#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
|
||||
|
||||
#define SYS_switch_ctx 2012
|
||||
#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
|
||||
|
|
318
lib/bsp/crt.S
318
lib/bsp/crt.S
|
@ -18,7 +18,9 @@
|
|||
# define IRQ_STACK_SIZE 20480
|
||||
|
||||
.global g_wake_address
|
||||
.global g_irq_count
|
||||
.global xPortStartScheduler
|
||||
.global sys_queue_apc
|
||||
|
||||
.section .text.start, "ax", @progbits
|
||||
.globl _start
|
||||
|
@ -73,38 +75,38 @@ _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
|
||||
|
@ -131,27 +133,13 @@ _start:
|
|||
.macro get_irq_count
|
||||
csrr t0, mhartid
|
||||
slli t1, t0, 3
|
||||
la t2, _irq_count
|
||||
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:
|
||||
csrw mscratch, t0
|
||||
ld t0, _irq_enabled
|
||||
bnez t0, 1f
|
||||
# Disable interrupt
|
||||
li t0, MSTATUS_MPIE
|
||||
csrc mstatus, t0
|
||||
csrr t0, mscratch
|
||||
mret
|
||||
1:
|
||||
csrr t0, mscratch
|
||||
# Store context
|
||||
addi sp, sp, -64 * REGBYTES
|
||||
.macro save_context
|
||||
addi sp, sp, -NUM_XCEPT_REGS * REGBYTES
|
||||
|
||||
sd x1, 1 * REGBYTES(sp)
|
||||
sd x2, 2 * REGBYTES(sp)
|
||||
|
@ -184,38 +172,124 @@ 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)
|
||||
.endm
|
||||
|
||||
.macro restore_context
|
||||
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
|
||||
.endm
|
||||
|
||||
.globl trap_entry
|
||||
.type trap_entry, @function
|
||||
.align 2
|
||||
trap_entry:
|
||||
csrw mscratch, t0
|
||||
ld t0, _irq_enabled
|
||||
bnez t0, 1f
|
||||
# Disable interrupt
|
||||
li t0, MSTATUS_MPIE
|
||||
csrc mstatus, t0
|
||||
csrr t0, mscratch
|
||||
mret
|
||||
1:
|
||||
csrr t0, mscratch
|
||||
# Save context
|
||||
save_context
|
||||
|
||||
# Store mepc
|
||||
csrr t0, mepc
|
||||
|
@ -276,78 +350,26 @@ trap_entry:
|
|||
# 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)
|
||||
|
||||
fld f0, ( 0 + 32) * REGBYTES(a0)
|
||||
fld f1, ( 1 + 32) * REGBYTES(a0)
|
||||
fld f2, ( 2 + 32) * REGBYTES(a0)
|
||||
fld f3, ( 3 + 32) * REGBYTES(a0)
|
||||
fld f4, ( 4 + 32) * REGBYTES(a0)
|
||||
fld f5, ( 5 + 32) * REGBYTES(a0)
|
||||
fld f6, ( 6 + 32) * REGBYTES(a0)
|
||||
fld f7, ( 7 + 32) * REGBYTES(a0)
|
||||
fld f8, ( 8 + 32) * REGBYTES(a0)
|
||||
fld f9, ( 9 + 32) * REGBYTES(a0)
|
||||
fld f10, (10 + 32) * REGBYTES(a0)
|
||||
fld f11, (11 + 32) * REGBYTES(a0)
|
||||
fld f12, (12 + 32) * REGBYTES(a0)
|
||||
fld f13, (13 + 32) * REGBYTES(a0)
|
||||
fld f14, (14 + 32) * REGBYTES(a0)
|
||||
fld f15, (15 + 32) * REGBYTES(a0)
|
||||
fld f16, (16 + 32) * REGBYTES(a0)
|
||||
fld f17, (17 + 32) * REGBYTES(a0)
|
||||
fld f18, (18 + 32) * REGBYTES(a0)
|
||||
fld f19, (19 + 32) * REGBYTES(a0)
|
||||
fld f20, (20 + 32) * REGBYTES(a0)
|
||||
fld f21, (21 + 32) * REGBYTES(a0)
|
||||
fld f22, (22 + 32) * REGBYTES(a0)
|
||||
fld f23, (23 + 32) * REGBYTES(a0)
|
||||
fld f24, (24 + 32) * REGBYTES(a0)
|
||||
fld f25, (25 + 32) * REGBYTES(a0)
|
||||
fld f26, (26 + 32) * REGBYTES(a0)
|
||||
fld f27, (27 + 32) * REGBYTES(a0)
|
||||
fld f28, (28 + 32) * REGBYTES(a0)
|
||||
fld f29, (29 + 32) * REGBYTES(a0)
|
||||
fld f30, (30 + 32) * REGBYTES(a0)
|
||||
fld f31, (31 + 32) * REGBYTES(a0)
|
||||
|
||||
# Restore a0
|
||||
restore_context
|
||||
csrr a0, mscratch
|
||||
addi sp, sp, 64 * REGBYTES
|
||||
mret
|
||||
|
||||
sys_queue_apc:
|
||||
addi sp, sp, -NUM_XCEPT_REGS * REGBYTES
|
||||
ld t0, REG_APC_PROC * REGBYTES(sp)
|
||||
jalr t0
|
||||
csrw mscratch, a0
|
||||
mv a0, sp
|
||||
restore_context
|
||||
csrr a0, mscratch
|
||||
li a7, SYS_apc_return
|
||||
ecall
|
||||
j .
|
||||
|
||||
.global _init
|
||||
.type _init, @function
|
||||
|
@ -367,7 +389,7 @@ xPortStartScheduler:
|
|||
j .restore
|
||||
|
||||
.align 3
|
||||
_irq_count:
|
||||
g_irq_count:
|
||||
.8byte 0
|
||||
.8byte 0
|
||||
_irq_enabled:
|
||||
|
|
|
@ -96,6 +96,7 @@ static const char *TAG = "SYSCALL";
|
|||
|
||||
extern char _heap_start[];
|
||||
extern char _heap_end[];
|
||||
extern void sys_queue_apc();
|
||||
char *_heap_cur = &_heap_start[0];
|
||||
|
||||
void __attribute__((noreturn)) sys_exit(int code)
|
||||
|
@ -289,7 +290,6 @@ static void handle_ecall(uintptr_t *regs)
|
|||
SYS_ID_CLOSE,
|
||||
SYS_ID_GETTIMEOFDAY,
|
||||
SYS_ID_LSEEK,
|
||||
SYS_ID_SWITCHCONTEXT,
|
||||
SYS_ID_MAX
|
||||
};
|
||||
|
||||
|
@ -304,8 +304,7 @@ static void handle_ecall(uintptr_t *regs)
|
|||
[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_SWITCHCONTEXT] = (void*)sys_switchcontext
|
||||
[SYS_ID_LSEEK] = (void *)sys_lseek
|
||||
};
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
@ -313,56 +312,57 @@ static void handle_ecall(uintptr_t *regs)
|
|||
#endif
|
||||
|
||||
uintptr_t n = regs[REG_A7];
|
||||
uintptr_t syscall_id = SYS_ID_NOSYS;
|
||||
switch (n)
|
||||
|
||||
if (n == SYS_switch_ctx)
|
||||
{
|
||||
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;
|
||||
case SYS_switch_ctx:
|
||||
syscall_id = SYS_ID_SWITCHCONTEXT;
|
||||
break;
|
||||
sys_switchcontext();
|
||||
regs[REG_EPC] += 4;
|
||||
}
|
||||
else if (n == SYS_apc_return)
|
||||
{
|
||||
regs[REG_EPC] = regs[REG_APC_RET];
|
||||
}
|
||||
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 ret = syscall_table[syscall_id](
|
||||
regs[REG_A0], /* a0 */
|
||||
regs[REG_A1], /* a1 */
|
||||
regs[REG_A2], /* a2 */
|
||||
regs[REG_A3], /* a3 */
|
||||
regs[REG_A4], /* a4 */
|
||||
regs[REG_A5], /* a5 */
|
||||
n /* n */
|
||||
);
|
||||
|
||||
regs[REG_A0] = ret;
|
||||
regs[REG_EPC] += 4;
|
||||
regs[REG_APC_PROC] = (uintptr_t)syscall_table[syscall_id];
|
||||
regs[REG_APC_RET] = regs[REG_EPC] + 4;
|
||||
regs[REG_EPC] = (uintptr_t)sys_queue_apc;
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((weak, alias("handle_ecall"))) handle_ecall_u(uintptr_t *regs);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -25,20 +25,6 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
#define REG_EPC 0
|
||||
#define REG_RA 1
|
||||
#define REG_SP 2
|
||||
#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 NUM_XCEPT_REGS (64)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CORE_SYNC_NONE,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
#include <sysctl.h>
|
||||
#include <syslog.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
|
||||
|
@ -93,6 +95,11 @@ UBaseType_t uxPortGetProcessorId()
|
|||
return (UBaseType_t)read_csr(mhartid);
|
||||
}
|
||||
|
||||
UBaseType_t uxPortIsInISR()
|
||||
{
|
||||
return g_irq_count[uxPortGetProcessorId()] > 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Sets the next timer interrupt
|
||||
|
@ -117,6 +124,8 @@ 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();
|
||||
|
@ -216,3 +225,8 @@ UBaseType_t uxPortGetCPUClock()
|
|||
{
|
||||
return uxCPUClockRate;
|
||||
}
|
||||
|
||||
void vPortDebugBreak(void)
|
||||
{
|
||||
asm volatile("sbreak");
|
||||
}
|
||||
|
|
|
@ -94,8 +94,6 @@ typedef unsigned long UBaseType_t;
|
|||
#define portCRITICAL_NESTING_IN_TCB 1
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define SYS_switch_ctx 2010
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYield(void);
|
||||
extern void vPortYieldFromISR(void);
|
||||
|
@ -137,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()
|
||||
|
||||
|
|
|
@ -3874,7 +3874,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId();
|
|||
}
|
||||
else
|
||||
{
|
||||
if( uxSchedulerSuspended[uxPsrId] == ( UBaseType_t ) pdFALSE )
|
||||
if( uxSchedulerSuspended[uxPortGetProcessorId()] == ( UBaseType_t ) pdFALSE )
|
||||
{
|
||||
xReturn = taskSCHEDULER_RUNNING;
|
||||
}
|
||||
|
|
|
@ -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