added copyright headers to new files
[bootcensus] / src / intr_asm.S
1 # pcboot - bootable PC demo/game kernel
2 # Copyright (C) 2018  John Tsiombikas <nuclear@member.fsf.org>
3
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY, without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17         .data
18         .align 4
19         .short 0
20 idtr_desc:
21 lim:    .short 0
22 addr:   .long 0
23
24         .text
25 /* void set_idt(uint32_t addr, uint16_t limit) */
26         .global set_idt
27 set_idt:
28         mov 4(%esp), %eax
29         mov %eax, addr
30         mov 8(%esp), %ax
31         mov %ax, lim
32         lidt (idtr_desc)
33         ret
34
35 /* int get_intr_flag() */
36         .global get_intr_flag
37 get_intr_flag:
38         pushf
39         popl %eax
40         # bit 9 of eflags is IF
41         shr $9, %eax
42         and $1, %eax
43         ret
44
45 /* void set_intr_flag(int onoff) */
46         .global set_intr_flag
47 set_intr_flag:
48         cmpl $0, 4(%esp)
49         jz 0f
50         sti
51         ret
52 0:      cli
53         ret
54
55 /* interrupt entry with error code macro
56  * this macro generates an interrupt entry point for the
57  * exceptions which include error codes in the stack frame
58  */
59         .macro ientry_err n name
60         .globl intr_entry_\name
61 intr_entry_\name:
62         pushl $\n
63         jmp intr_entry_common
64         .endm
65
66 /* interrupt entry without error code macro
67  * this macro generates an interrupt entry point for the interrupts
68  * and exceptions which do not include error codes in the stack frame
69  * it pushes a dummy error code (0), to make the stack frame identical
70  */
71         .macro ientry_noerr n name
72         .globl intr_entry_\name
73 intr_entry_\name:
74         pushl $0
75         pushl $\n
76         jmp intr_entry_common
77         .endm
78
79 /* common code used by all entry points. calls dispatch_intr()
80  * defined in intr.c
81  */
82         .extern dispatch_intr
83 intr_entry_common:
84         /* save general purpose registers */
85         pusha
86         call dispatch_intr
87 intr_ret_local:
88         /* restore general purpose registers */
89         popa
90         /* remove error code and intr num from stack */
91         add $8, %esp
92         iret
93
94 /* special case for the timer interrupt, to avoid all the overhead of
95  * going through the C interrupt dispatcher 250 times each second
96  */
97         .extern nticks
98         .global intr_entry_fast_timer
99 intr_entry_fast_timer:
100         incl nticks
101         # signal end of interrupt
102         push %eax
103         mov $0x20, %al
104         out %al, $0x20
105         pop %eax
106         iret
107         
108
109 /* XXX not necessary for now, just leaving it in in case it's useful
110  * down the road.
111  *
112  * intr_ret is called by context_switch to return from the kernel
113  * to userspace. The argument is a properly formed intr_frame
114  * structure with the saved context of the new task.
115  *
116  * First thing to do is remove the return address pointing back
117  * to context_switch, which then leaves us with a proper interrupt
118  * stack frame, so we can jump right in the middle of the regular
119  * interrupt return code above.
120  */
121         .global intr_ret
122 intr_ret:
123         add $4, %esp
124         jmp intr_ret_local
125
126 /* by including interrupts.h with ASM defined, the macros above
127  * are expanded to generate all required interrupt entry points
128  */
129 #define ASM
130 #include <intrtab.h>