From: Alan Cox Date: Sun, 31 May 2015 15:27:21 +0000 (+0100) Subject: dragon-nx-32: initial patches to move to the new IRQ stack arrangement X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=d7e6cab0b024eb601c18ffb4c7f855134d2aad0e;p=FUZIX.git dragon-nx-32: initial patches to move to the new IRQ stack arrangement We still copy 256 more bytes than we should.. --- diff --git a/Kernel/lowlevel-6809.s b/Kernel/lowlevel-6809.s index a4d8ace5..ac7ce0e1 100644 --- a/Kernel/lowlevel-6809.s +++ b/Kernel/lowlevel-6809.s @@ -32,7 +32,7 @@ .globl map_save .globl map_restore .globl outchar - .globl _kernel_flag + .globl _need_resched .globl _inint .globl _platform_interrupt @@ -71,9 +71,6 @@ ; unix_syscall_entry: SAM_KERNEL ; stack now invalid - ; make sure the interrupt logic knows we are in kernel mode - lda #1 - sta _kernel_flag leax 14,s ; 12 stacked by the swi + return address of caller ldy #U_DATA__U_ARGN @@ -102,6 +99,10 @@ unix_syscall_entry: ; switch to kernel stack (makes our stack valid again) lds #kstack_top + ; we are in syscall state + lda #1 + sta U_DATA__U_INSYS + ; map in kernel keeping common jsr map_kernel @@ -114,7 +115,7 @@ unix_syscall_entry: orcc #0x10 ; let the interrupt logic know we are not in kernel mode any more ; kernel_flag is not in common so write it before we map it away - clr _kernel_flag + clr U_DATA__U_INSYS ; map process memory back in based on common (common may have ; changed on a task switch) @@ -198,7 +199,6 @@ _doexec: orcc #0x10 ; this is a funny extra path out of syscall so we must also cover ; the exit from kernel here - clr _kernel_flag ; map task into address space (kernel_flag is no longer mapped, don't ; re-order this) @@ -235,16 +235,13 @@ interrupt_handler: ; FIXME: add profil support here (need to keep profil ptrs ; unbanked if so ?) - ; don't allow us to run re-entrant, we've only got one interrupt stack - lda U_DATA__U_ININTERRUPT - bne interrupt_return - inca + lda #1 sta U_DATA__U_ININTERRUPT ; switch stacks sts istack_switched_sp - ; Unlike Z80 even the istack is banked, it's only valid on SAM - ; based boxes when SAM_KERNEL is true + ; Unlike Z80 even the istack is banked, it's only valid on some + ; SAM based boxes when SAM_KERNEL is true lds #istack_top-2 ; FIXME: check store/dec order might not need to be -2 here!!!! @@ -260,8 +257,7 @@ interrupt_handler: ; kernel_flag is in the kernel map so we need to map early, we ; need to map anyway for trap_signal ; - ldb _kernel_flag - pshs b,cc + ldb U_DATA__U_INSYS ; In a system call ? bne in_kernel ; we're not in kernel mode, check for signals and fault @@ -280,35 +276,56 @@ in_kernel: lda #1 sta _inint - ; this may task switch if not within a system call - ; if we switch then istack_switched_sp is out of date. - ; When this occurs we will exit via the resume path + ; + ; If the kernel decides to task switch it will set + ; _need_resched, and will only do so if the caller was in + ; user space so has a free kernel stack + ; ; Y is caller saves so we'll get the right Y back ; for our SAM_RESTORE jsr _platform_interrupt clr _inint - - puls b,cc ; Z = in kernel - bne in_kernel_2 - - ; On a return to user space always do a new map, we may have - ; changed process - jsr map_process_always - bra int_switch - ; On a return from an interrupt in kernel mode restore the old - ; mapping as it will vary during kernel activity and the kernel - ; wants it put back as it was before -in_kernel_2: - jsr map_restore -int_switch: lds istack_switched_sp ; stack back + sts U_DATA__U_SYSCALL_SP ; save again somewhere safe for + ; preemption clr U_DATA__U_ININTERRUPT lda U_DATA__U_INSYS bne interrupt_return - + lda _need_resched + clr _need_resched + beq no_switch + + ; Pre emption occurs on the task stack. Conceptually its a + ; not quite a syscall + lds #kstack_top + ldx U_DATA__U_PTAB + ; Move to ready state + lda #P_READY + sta P_TAB__P_STATUS_OFFSET,x + ; Sleep on the kernel stack, IRQs will get re-enabled if need + ; be + jsr _switchout + ; + ; We will resume here after the pre-emption. Get back onto + ; the user stack and map ourself in + lds U_DATA__U_SYSCALL_SP + ; do the map on the user stack (for SAM switching) SAM_USER + jsr map_process_always + bra intdone + + ; Not task switching - the easy and usual path +no_switch: + ; On a return from an interrupt restore the old mapping as it + ; will vary during kernel activity and we need to put it put + ; it back as it was before the interrupt + ; pre-emption is handled differently... + SAM_USER + jsr map_restore + +intdone: ; we're not in kernel mode, check for signals ; runs off the user stack so need user ram mapped on a SAM ; based platform @@ -376,7 +393,7 @@ nmi_handler: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; outstring: Print the string at X until 0 byte is found -; destroys: AF HL +; destroys: A, X outstring: lda ,x+ beq outstrdone @@ -385,7 +402,7 @@ outstring: outstrdone: rts -; print the string at (HL) in hex (continues until 0 byte seen) +; print the string at (X) in hex (continues until 0 byte seen) outstringhex: lda ,x+ beq outstrdone diff --git a/Kernel/platform-dragon-nx32/dragon.s b/Kernel/platform-dragon-nx32/dragon.s index 96c96523..2fd041bf 100644 --- a/Kernel/platform-dragon-nx32/dragon.s +++ b/Kernel/platform-dragon-nx32/dragon.s @@ -61,7 +61,7 @@ init_hardware: .globl init_early .globl init_hardware .globl _program_vectors - .globl _kernel_flag + .globl _need_resched ; imported symbols @@ -72,12 +72,6 @@ init_hardware: .area .common -trapmsg: .ascii "Trapdoor: SP=" - .db 0 -trapmsg2: .ascii ", PC=" - .db 0 -tm_user_sp: .dw 0 - _trap_reboot: _trap_monitor: cwai #0 @@ -121,7 +115,7 @@ badswi_handler: rti ; outchar: Simple writing to video memory - +; FIXME: we are now in grapics mode ! outchar: pshs x ldx traceptr @@ -135,6 +129,6 @@ lc anda #0x3F .area .common -_kernel_flag: .db 1 +_need_resched: .db 1 traceptr: .dw 0x0400 diff --git a/Kernel/platform-dragon-nx32/tricks.s b/Kernel/platform-dragon-nx32/tricks.s index d678285b..6f41e9d0 100644 --- a/Kernel/platform-dragon-nx32/tricks.s +++ b/Kernel/platform-dragon-nx32/tricks.s @@ -49,10 +49,6 @@ _switchout: pshs d,y,u sts U_DATA__U_SP ; this is where the SP is restored in _switchin - ; set inint to false - lda #0 - sta _inint - ; Stash the uarea into process memory bank jsr map_process_always @@ -137,8 +133,8 @@ nostash: puls x,y,u ; return code and saved U and Y ; enable interrupts, if the ISR isn't already running - lda _inint - beq swtchdone ; in ISR, leave interrupts off + lda U_DATA__U_ININTERRUPT + bne swtchdone ; in ISR, leave interrupts off andcc #0xef swtchdone: rts