+++ /dev/null
-; pcboot - bootable PC demo/game kernel
-; Copyright (C) 2018-2023 John Tsiombikas <nuclear@member.fsf.org>
-;
-; This program is free software: you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation, either version 3 of the License, or
-; (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY, without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
- section .data
- align 4
- dw 0
-idtr_desc:
-lim: dw 0
-addr: dd 0
-
- section .text
-; void set_idt(uint32_t addr, uint16_t limit)
- global set_idt
-set_idt:
- mov eax, [esp + 4]
- mov [addr], eax
- mov ax, [esp + 8]
- mov [lim], ax
- lidt [idtr_desc]
- ret
-
-; int get_intr_flag()
- global get_intr_flag
-get_intr_flag:
- pushf
- pop eax
- ; bit 9 of eflags is IF
- shr eax, 9
- and eax, 1
- ret
-
-; void set_intr_flag(int onoff)
- global set_intr_flag
-set_intr_flag:
- cmp dword [esp + 4], 0
- jz .off
- sti
- ret
-.off: cli
- ret
-
-; interrupt entry with error code macro
-; this macro generates an interrupt entry point for the
-; exceptions which include error codes in the stack frame
-%macro ientry_err 2
- global intr_entry_%2
-intr_entry_%2:
- push dword %1
- jmp intr_entry_common
-%endmacro
-
-; interrupt entry without error code macro
-; this macro generates an interrupt entry point for the interrupts
-; and exceptions which do not include error codes in the stack frame
-; it pushes a dummy error code (0), to make the stack frame identical
-%macro ientry_noerr 2
- global intr_entry_%2
-intr_entry_%2:
- push dword 0
- push dword %1
- jmp intr_entry_common
-%endmacro
-
-; common code used by all entry points. calls dispatch_intr()
-; defined in intr.c
- extern dispatch_intr
-intr_entry_common:
- ; save general purpose registers
- pusha
- call dispatch_intr
-intr_ret_local:
- ; restore general purpose registers
- popa
- ; remove error code and intr num from stack
- add esp, 8
- iret
-
-; special case for the timer interrupt, to avoid all the overhead of
-; going through the C interrupt dispatcher 250 times each second
-; extern nticks
-; global intr_entry_fast_timer
-;intr_entry_fast_timer:
-; inc dword [nticks]
-; ; signal end of interrupt
-; push eax
-; mov al, 20h
-; out 20h, al
-; pop eax
-; iret
-
-; special case for IRQ 7 and IRQ 15, to catch spurious interrupts
-PIC1_CMD equ 0x20
-PIC2_CMD equ 0xa0
-OCW2_EOI equ 0x20
-OCW3_ISR equ 0x0b
-
- global irq7_entry_check_spurious
-irq7_entry_check_spurious:
- push eax
- mov al, OCW3_ISR
- out PIC1_CMD, al
- in al, PIC1_CMD
- and al, 80h
- pop eax
- jnz intr_entry_irq7
- iret
-
- global irq15_entry_check_spurious
-irq15_entry_check_spurious:
- push eax
- mov al, OCW3_ISR
- out PIC2_CMD, al
- in al, PIC2_CMD
- and al, 80h
- jnz .legit
- ; it was spurious, send EOI to master PIC and iret
- mov al, OCW2_EOI
- out PIC1_CMD, al
- pop eax
- iret
-.legit: pop eax
- jmp intr_entry_irq15
-
-
-; XXX not necessary for now, just leaving it in in case it's useful
-; down the road.
-;
-; intr_ret is called by context_switch to return from the kernel
-; to userspace. The argument is a properly formed intr_frame
-; structure with the saved context of the new task.
-;
-; First thing to do is remove the return address pointing back
-; to context_switch, which then leaves us with a proper interrupt
-; stack frame, so we can jump right in the middle of the regular
-; interrupt return code above.
- global intr_ret
-intr_ret:
- add esp, $4
- jmp intr_ret_local
-
-; by including interrupts.h with ASM defined, the macros above
-; are expanded to generate all required interrupt entry points
-%define INTR_ENTRY_EC(n, name) ientry_err n, name
-%define INTR_ENTRY_NOEC(n, name) ientry_noerr n, name
-
-%include 'intrtab.h'
-
-; vi:set ts=8 sts=8 sw=8 ft=nasm: