kern

annotate src/intr-asm.S @ 54:4eaecb14fe31

bringing the task switching thing into shape with proper per-process kernel stacks and shit
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 14 Aug 2011 16:57:23 +0300
parents 1d8877d12de0
children 88a6c4e192f9
rev   line source
nuclear@54 1 #define ASM
nuclear@54 2 #include "segm.h"
nuclear@54 3
nuclear@11 4 .data
nuclear@11 5 .align 4
nuclear@11 6 .short 0
nuclear@11 7 /* memory reserved for set_idt */
nuclear@11 8 lim:.short 0
nuclear@11 9 addr:.long 0
nuclear@11 10
nuclear@11 11 .text
nuclear@11 12 /* set_idt(uint32_t addr, uint16_t limit)
nuclear@11 13 * loads the IDTR with the new address and limit for the IDT */
nuclear@11 14 .globl set_idt
nuclear@11 15 set_idt:
nuclear@11 16 movl 4(%esp), %eax
nuclear@11 17 movl %eax, (addr)
nuclear@11 18 movw 8(%esp), %ax
nuclear@11 19 movw %ax, (lim)
nuclear@11 20 lidt (lim)
nuclear@11 21 ret
nuclear@11 22
nuclear@25 23 /* get_intr_state()
nuclear@25 24 * returns 1 if interrutps are enabled, 0 if disabled */
nuclear@25 25 .globl get_intr_state
nuclear@25 26 get_intr_state:
nuclear@25 27 pushf
nuclear@25 28 popl %eax
nuclear@25 29 shr $9, %eax /* bit 9 of eflags is IF */
nuclear@25 30 andl $1, %eax
nuclear@25 31 ret
nuclear@25 32
nuclear@25 33 /* set_intr_state(int state)
nuclear@25 34 * enables interrupts if the argument is non-zero, disables them otherwise */
nuclear@25 35 .globl set_intr_state
nuclear@25 36 set_intr_state:
nuclear@25 37 cmpl $0, 4(%esp)
nuclear@25 38 jz 0f
nuclear@25 39 sti
nuclear@25 40 ret
nuclear@25 41 0: cli
nuclear@25 42 ret
nuclear@25 43
nuclear@25 44
nuclear@11 45 /* interrupt entry with error code macro
nuclear@11 46 * this macro generates an interrupt entry point for the
nuclear@11 47 * exceptions which include error codes in the stack frame
nuclear@11 48 */
nuclear@11 49 .macro ientry_err n name
nuclear@11 50 .globl intr_entry_\name
nuclear@11 51 intr_entry_\name:
nuclear@11 52 pushl $\n
nuclear@11 53 jmp intr_entry_common
nuclear@11 54 .endm
nuclear@11 55
nuclear@11 56 /* interrupt entry without error code macro
nuclear@11 57 * this macro generates an interrupt entry point for the interrupts
nuclear@11 58 * and exceptions which do not include error codes in the stack frame
nuclear@11 59 * it pushes a dummy error code (0), to make the stack frame identical
nuclear@11 60 */
nuclear@11 61 .macro ientry_noerr n name
nuclear@11 62 .globl intr_entry_\name
nuclear@11 63 intr_entry_\name:
nuclear@11 64 pushl $0
nuclear@11 65 pushl $\n
nuclear@11 66 jmp intr_entry_common
nuclear@11 67 .endm
nuclear@11 68
nuclear@11 69 /* common code used by all entry points. calls dispatch_intr()
nuclear@11 70 * defined in intr.c
nuclear@11 71 */
nuclear@11 72 .extern dispatch_intr
nuclear@11 73 intr_entry_common:
nuclear@54 74 /* save the current data segment selectors */
nuclear@54 75 pushl %gs
nuclear@54 76 pushl %fs
nuclear@54 77 pushl %es
nuclear@54 78 pushl %ds
nuclear@54 79 /* save general purpose registers */
nuclear@11 80 pusha
nuclear@54 81 /* if we entered from userspace ss and cs is set correctly, but
nuclear@54 82 * we must make sure all the other selectors are set to the
nuclear@54 83 * kernel data segment */
nuclear@54 84 mov $SEGM_KDATA, %ds
nuclear@54 85 mov $SEGM_KDATA, %es
nuclear@54 86 mov $SEGM_KDATA, %fs
nuclear@54 87 mov $SEGM_KDATA, %gs
nuclear@11 88 call dispatch_intr
nuclear@50 89 intr_ret_local:
nuclear@54 90 /* restore general purpose registers */
nuclear@11 91 popa
nuclear@54 92 /* restore data segment selectors */
nuclear@54 93 popl %ds
nuclear@54 94 popl %es
nuclear@54 95 popl %fs
nuclear@54 96 popl %gs
nuclear@11 97 /* remove error code and intr num from stack */
nuclear@11 98 add $8, %esp
nuclear@11 99 iret
nuclear@11 100
nuclear@50 101 /* intr_ret is called by context_switch to return from the kernel
nuclear@50 102 * to userspace. The argument is a properly formed intr_frame
nuclear@50 103 * structure with the saved context of the new task.
nuclear@50 104 *
nuclear@50 105 * First thing to do is remove the return address pointing back
nuclear@50 106 * to context_switch, which then leaves us with a proper interrupt
nuclear@50 107 * stack frame, so we can jump right in the middle of the regular
nuclear@50 108 * interrupt return code above.
nuclear@50 109 */
nuclear@50 110 .globl intr_ret
nuclear@50 111 intr_ret:
nuclear@50 112 add $4, %esp
nuclear@50 113 jmp intr_ret_local
nuclear@50 114
nuclear@11 115 /* by including interrupts.h with ASM defined, the macros above
nuclear@11 116 * are expanded to generate all required interrupt entry points
nuclear@11 117 */
nuclear@11 118 #include <interrupts.h>