3535 .extern OSPrioHighRdy
3636 .extern OSTCBCurPtr
3737 .extern OSTCBHighRdyPtr
38- .extern OSIntExit
3938 .extern OSTaskSwHook
4039
4140
4241 .global OSStartHighRdy # Functions declared in this file
4342 .global OSCtxSw
4443 .global OSIntCtxSw
4544 .global Software_IRQHandler
45+ .global ucos_intr_exception_handler
4646
4747
4848#********************************************************************************************************
4949# EQUATES
5050#********************************************************************************************************
5151
52- .equ RISCV_MSTATUS_MIE, 0x08
52+ .equ RISCV_MSTATUS_MIE, 0x08
5353
54- .equ RISCV_MIE_MSIE , 0x08 # M Soft Interrupt bit
54+ .equ ARCH_CPU_MCAUSE_INTR_MASK , 0x80000000
5555
56- .equ RISCV_PRCI_BASE_ADDR, 0x44000000
56+ .equ ARCH_CPU_MCAUSE_CAUSE_MASK, 0x000003FF
5757
5858
5959#********************************************************************************************************
7878
7979OSStartHighRdy:
8080# Disable interrupts
81+ # load immediately "RISCV_MSTATUS_MIE" into t0 register
8182 li t0, RISCV_MSTATUS_MIE
83+ # mstatus = mstatus & ~t0
8284 csrrc zero, mstatus, t0
8385
8486# Execute OS task switch hook.
87+ # jump to OSTaskSwHook function(address) and store the next instruction
88+ # into link register
89+ # this function will get called each time when the context switch happens
8590 jal OSTaskSwHook
8691
8792# OSRunning = TRUE;
8893 li t0, 0x01
94+ # load address of OSRunning into t1 register
8995 la t1, OSRunning
96+ # store byte value of t0 into memory address pointed by t1 with 0 offset
9097 sb t0, 0 (t1)
9198
9299# SWITCH TO HIGHEST PRIORITY TASK
93100 la t0, OSTCBHighRdyPtr
101+ # load word from address stored in [t0 + 0 (offset)] to t1
94102 lw t1, 0 (t0)
103+ # load word from address stored in [t1+ 0 (offset)] into sp
95104 lw sp , 0 (t1)
96105
97106# Retrieve the location where to jump
98107 lw t0, 31 * 4(sp)
108+ # value stored in t0 is stored into mepc
99109 csrw mepc, t0
100110
101111# Restore x1 to x31 registers
112+ # load word from memory addres [(0 * 4) + sp] into ra register
102113 lw ra, 0 * 4(sp)
103114 lw t0, 4 * 4(sp)
104115 lw t1, 5 * 4(sp)
@@ -129,6 +140,7 @@ OSStartHighRdy:
129140 lw t6, 30 * 4(sp)
130141
131142# Compensate for the stack pointer
143+ # sp = sp + 32 * 4
132144 addi sp , sp , 32 * 4
133145
134146# Use register t6 to jump to HIGHEST priority
@@ -147,66 +159,116 @@ OSStartHighRdy:
147159# PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
148160#
149161# Note(s) : 1 ) OSCtxSw() is called when OS wants to perform a task context switch. This function
150- # triggers a synchronous software interrupt by writing into the MSIP register
162+ # triggers a ecall.
151163#
152164# 2 ) OSIntCtxSw() is called by OSIntExit() when it determines a context switch is needed as
153- # the result of an interrupt. This function triggers a synchronous software interrupt by
154- # writing into the MSIP register
165+ # the result of an interrupt. This function just return back as the context switch after interrupt
166+ # is executed just before exiting the interrupt handler.
155167#********************************************************************************************************
168+ OSIntCtxSw:
169+ ret
156170
157171OSCtxSw:
158- OSIntCtxSw:
159- # MIE_MSIE -- enable software interrupt bit
160- li t0, RISCV_MIE_MSIE
161- csrrs zero, mie, t0
162-
163- # This will trigger a synchronous software interrupt; PRCI->MSIP[0] = 0x01;
164- li t0, RISCV_PRCI_BASE_ADDR
165- li t1, 0x1
166- sw t1, 0x0(t0)
172+ ecall
167173 ret
168174
175+ # Exception handler should be 256 bytes aligned
176+ .align 8
177+ ucos_intr_exception_handler:
178+ # save regs to current sp
179+ addi sp , sp , -4 *32
180+ # store contents of register ra into memory [(0 * 4) + sp]
181+ sw ra, 0 * 4(sp)
182+ sw t0, 4 * 4(sp)
183+ sw t1, 5 * 4(sp)
184+ sw t2, 6 * 4(sp)
185+ sw s0, 7 * 4(sp)
186+ sw s1, 8 * 4(sp)
187+ sw a0 , 9 * 4(sp)
188+ sw a1 , 10 * 4(sp)
189+ sw a2 , 11 * 4(sp)
190+ sw a3 , 12 * 4(sp)
191+ sw a4 , 13 * 4(sp)
192+ sw a5 , 14 * 4(sp)
193+ sw a6 , 15 * 4(sp)
194+ sw a7 , 16 * 4(sp)
195+ sw s2, 17 * 4(sp)
196+ sw s3, 18 * 4(sp)
197+ sw s4, 19 * 4(sp)
198+ sw s5, 20 * 4(sp)
199+ sw s6, 21 * 4(sp)
200+ sw s7, 22 * 4(sp)
201+ sw s8, 23 * 4(sp)
202+ sw s9, 24 * 4(sp)
203+ sw s10, 25 * 4(sp)
204+ sw s11, 26 * 4(sp)
205+ sw t3, 27 * 4(sp)
206+ sw t4, 28 * 4(sp)
207+ sw t5, 29 * 4(sp)
208+ sw t6, 30 * 4(sp)
209+
210+ # If it is a ecall, do not add 4 in mepc
211+ # otherwise add 4 in mepc
212+ li t1, ARCH_CPU_MCAUSE_CAUSE_MASK
213+ csrr t0, mcause
214+ # t3 = t1 & t0
215+ and t3, t1, t0
216+ li t1, 11
217+ csrr t0, mepc
218+ # If t1 != t3 jump to DONTADD:
219+ bne t1 , t3, DONTADD
220+ addi t0, t0, 4
221+
222+ DONTADD: # for interrupt do not add 4 in mepc
223+ sw t0, 31 *4 (sp )
224+ # load address of OSTCBCurPtr into t0 register
225+ la t0, OSTCBCurPtr
226+ # load word from register [t0 + 0 ] address into t1
227+ lw t1, 0 (t0)
228+ # store value stored in sp to [t1 + 0 ] address
229+ sw sp , 0 (t1)
230+
231+ li t1, ARCH_CPU_MCAUSE_INTR_MASK
232+ csrr t0, mcause
233+ and t2, t1, t0
234+ bne t1 , t2, run_exception_handler
235+ # it is a interrupt
236+ j run_interrupt_exception_handler
237+
238+ run_exception_handler:
239+ li t1, ARCH_CPU_MCAUSE_CAUSE_MASK
240+ csrr t0, mcause
241+ and t3, t1, t0
242+ li t1, 11
243+ bne t1 , t3, run_interrupt_exception_handler
244+ # it is a ecall
245+ j run_ecall_handler
246+
247+ run_interrupt_exception_handler:
248+ jal osa_intr_master_isr
249+
250+ run_ecall_handler:
251+ j Software_IRQHandler
252+
253+
254+
169255
170256#********************************************************************************************************
171257# void Software_IRQHandler (void)
172258#
173- # Note(s) : 1 ) This function is defined with weak linking in 'riscv_hal_stubs.c' so that it can be
174- # overridden by the kernel port with same prototype.
175- #
176- # 2 ) Pseudo-code is:
177- # a) Disable global interrupts.
178- # b) Clear soft interrupt for hart0 .
179- # c) Save the process SP in its TCB, OSTCBCurPtr->StkPtr = SP ;
180- # d) Call OSTaskSwHook();
181- # e) Get current high priority, OSPrioCur = OSPrioHighRdy;
182- # f) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
183- # g) Get new process SP from TCB, SP = OSTCBHighRdyPtr->StkPtr;
184- # h) Retrieve the address at which exception happened
185- # i) Restore x1-x31 from new process stack; x0 is always zero.
186- # j) Perform exception return which will restore remaining context.
259+ # 1 ) Pseudo-code is:
260+ # a) Call OSTaskSwHook();
261+ # b) Get current high priority, OSPrioCur = OSPrioHighRdy;
262+ # c) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
263+ # d) Get new process SP from TCB, SP = OSTCBHighRdyPtr->StkPtr;
264+ # e) Retrieve the address at which exception happened.
265+ # f) Restore x1-x31 from new process stack; x0 is always zero.
266+ # g) set MPIE = 1 to enable interrupt before returning.
267+ # h) Perform exception return which will restore remaining context.
187268#
188- # 3 ) On entry into Software_IRQHandler:
189- # a) The initial register context save is being done by 'entry.S'
190- # b) Stack pointer was passed by 'entry.s' in register a2 .
191- # c) OSTCBCurPtr points to the OS_TCB of the task to suspend
192- # OSTCBHighRdyPtr points to the OS_TCB of the task to resume
193269#********************************************************************************************************
194270
195271Software_IRQHandler:
196- # Disable interrupts globally and prevent interruption during context switch
197- li t0, RISCV_MSTATUS_MIE
198- csrrc zero, mstatus, t0
199-
200- # Clear soft interrupt for hart0 , PRCI->MSIP[0 ] = 0x00;
201- li t0, RISCV_PRCI_BASE_ADDR
202- sw zero, 0x0(t0)
203-
204- # Stack pointer was passed by 'entry.s' in register a2 .
205- # OSTCBCurPtr->StkPtr = SP ;
206- la t0, OSTCBCurPtr
207- lw t1, 0 (t0)
208- sw a2 , 0 (t1)
209-
210272# Execute OS task switch hook.
211273 jal OSTaskSwHook
212274
@@ -259,12 +321,16 @@ Software_IRQHandler:
259321 lw t5, 29 * 4(sp)
260322 lw t6, 30 * 4(sp)
261323
324+ # Compensate for the stack pointer
262325 addi sp , sp , 4 * 32
263326
264327# Exception return will restore remaining context
328+ # set MPIE = 1
329+ # interrupts will be enabled from here onwards
330+ li t0, 0x80
331+ csrrs zero, mstatus, t0
265332 mret
266333
267-
268334#********************************************************************************************************
269335# MODULE END
270336#*********************************************************************************************************
0 commit comments