Dynamic IRQ handling
This commit is contained in:
1
kernel/irq/.gitignore
vendored
Normal file
1
kernel/irq/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.o
|
||||
117
kernel/irq/irqhandler.c
Normal file
117
kernel/irq/irqhandler.c
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright 2025 Kamil Kowalczyk
|
||||
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
“AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <libk/types.h>
|
||||
#include <libk/list.h>
|
||||
#include <mm/liballoc.h>
|
||||
#include <irq/irqhandler.h>
|
||||
#include <sync/spinlock.h>
|
||||
#include <config.h>
|
||||
|
||||
#if defined(__i386__)
|
||||
#include <sys/pic.h>
|
||||
#endif
|
||||
|
||||
static struct irqhandlers irqhandlers = { .handlers = NULL };
|
||||
|
||||
void irqhandlers_init(void) {
|
||||
sl_init(&irqhandlers.sl, "irqhandlers");
|
||||
}
|
||||
|
||||
void irqhandler_register(int irq, irqhandler_func_t func) {
|
||||
struct irqhandler *irqhandler = malloc(sizeof(*irqhandler));
|
||||
if (irqhandler == NULL)
|
||||
goto done;
|
||||
|
||||
irqhandler->irq = irq;
|
||||
irqhandler->func = func;
|
||||
|
||||
sl_lock(&irqhandlers.sl);
|
||||
|
||||
linklist_append(struct irqhandler *, irqhandlers.handlers, irqhandler);
|
||||
|
||||
sl_unlock(&irqhandlers.sl);
|
||||
|
||||
done:
|
||||
return;
|
||||
}
|
||||
|
||||
void irqhandler_unregister(int irq) {
|
||||
struct irqhandler *irqhandler = NULL;
|
||||
|
||||
sl_lock(&irqhandlers.sl);
|
||||
|
||||
linklist_find(struct irqhandler *, irqhandlers.handlers, irqhandler, irq, irq);
|
||||
|
||||
if (irqhandler == NULL)
|
||||
goto done;
|
||||
|
||||
linklist_remove(struct irqhandler *, irqhandlers.handlers, irqhandler);
|
||||
|
||||
sl_unlock(&irqhandlers.sl);
|
||||
|
||||
free(irqhandler);
|
||||
return;
|
||||
|
||||
done:
|
||||
sl_unlock(&irqhandlers.sl);
|
||||
return;
|
||||
}
|
||||
|
||||
irqhandler_func_t irqhandler_find(int irq) {
|
||||
struct irqhandler *irqhandler = NULL;
|
||||
irqhandler_func_t func = NULL;
|
||||
|
||||
sl_lock(&irqhandlers.sl);
|
||||
|
||||
linklist_find(struct irqhandler *, irqhandlers.handlers, irqhandler, irq, irq);
|
||||
if (irqhandler == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
func = irqhandler->func;
|
||||
|
||||
done:
|
||||
sl_unlock(&irqhandlers.sl);
|
||||
return func;
|
||||
}
|
||||
|
||||
void irqhandler_enable(int irq) {
|
||||
#if defined(__i386__)
|
||||
pic_unmask_irq(irq);
|
||||
#endif
|
||||
}
|
||||
|
||||
void irqhandler_disable(int irq) {
|
||||
#if defined(__i386__)
|
||||
pic_mask_irq(irq);
|
||||
#endif
|
||||
}
|
||||
58
kernel/irq/irqhandler.h
Normal file
58
kernel/irq/irqhandler.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2025 Kamil Kowalczyk
|
||||
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
“AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _IRQ_IRQHANDLER_H
|
||||
#define _IRQ_IRQHANDLER_H
|
||||
|
||||
#include <libk/types.h>
|
||||
#include <sync/spinlock.h>
|
||||
|
||||
typedef void (*irqhandler_func_t)(void *cpustate);
|
||||
|
||||
struct irqhandler {
|
||||
struct irqhandler *next;
|
||||
irqhandler_func_t func;
|
||||
int irq;
|
||||
};
|
||||
|
||||
struct irqhandlers {
|
||||
struct irqhandler *handlers;
|
||||
struct spinlock sl;
|
||||
};
|
||||
|
||||
void irqhandlers_init(void);
|
||||
void irqhandler_register(int irq, irqhandler_func_t func);
|
||||
void irqhandler_unregister(int irq);
|
||||
irqhandler_func_t irqhandler_find(int irq);
|
||||
void irqhandler_enable(int irq);
|
||||
void irqhandler_disable(int irq);
|
||||
|
||||
#endif // _IRQ_IRQHANDLER_H
|
||||
5
kernel/irq/make.src
Normal file
5
kernel/irq/make.src
Normal file
@ -0,0 +1,5 @@
|
||||
dir_irq1 := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
|
||||
|
||||
c_files += $(dir_irq1)/irqhandler.c
|
||||
|
||||
o_files += $(dir_irq1)/irqhandler.o
|
||||
@ -1,12 +1,12 @@
|
||||
#ifndef _LIBK_LIST_H
|
||||
#define _LIBK_LIST_H
|
||||
|
||||
#define DL_APPEND(head, new) \
|
||||
#define dlinklist_append(type, head, new) \
|
||||
do { \
|
||||
if ((new) != NULL) { \
|
||||
(new)->next = NULL; \
|
||||
if ((head) != NULL) { \
|
||||
typeof((head)) __tmp = (head); \
|
||||
type __tmp = (head); \
|
||||
while (__tmp->next != NULL) { \
|
||||
__tmp = __tmp->next; \
|
||||
} \
|
||||
@ -19,7 +19,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DL_PREPEND(head, new) \
|
||||
#define dlinklist_prepend(head, new) \
|
||||
do { \
|
||||
if ((new) != NULL) { \
|
||||
(new)->prev = NULL; \
|
||||
@ -31,7 +31,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DL_REMOVE(head, ele) \
|
||||
#define dlinklist_remove(head, ele) \
|
||||
do { \
|
||||
if ((ele) != NULL) { \
|
||||
if ((ele)->prev != NULL) { \
|
||||
@ -47,10 +47,10 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DL_FINDPROP(head, out, propname, propvalue) \
|
||||
#define dlinklist_find(type, head, out, propname, propvalue) \
|
||||
do { \
|
||||
(out) = NULL; \
|
||||
typeof((head)) __tmp = (head); \
|
||||
type __tmp = (head); \
|
||||
while (__tmp) { \
|
||||
if (__tmp->propname == (propvalue)) { \
|
||||
(out) = __tmp; \
|
||||
@ -60,26 +60,26 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DL_FOREACH_SAFE(head, var, tmp) \
|
||||
#define dlinklist_foreach(head, var, tmp) \
|
||||
for (var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL; \
|
||||
var = tmp, tmp = (var ? var->next : NULL))
|
||||
|
||||
#define DL_FOREACH_SAFE_IDX(head, var, tmp, idx) \
|
||||
#define dlinklist_foreach_index(head, var, tmp, idx) \
|
||||
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL; \
|
||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
||||
|
||||
#define DL_FOREACH_SAFE_IDX_LIMIT(head, var, tmp, idx, max) \
|
||||
#define dlinklist_foreach_index_limit(head, var, tmp, idx, max) \
|
||||
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL && (idx) < (max); \
|
||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
||||
|
||||
#define DL_BACK(head, out) \
|
||||
#define dlinklist_back(type, head, out) \
|
||||
do { \
|
||||
(out) = NULL; \
|
||||
if ((head) != NULL) { \
|
||||
typeof((head)) __tmp = (head); \
|
||||
type __tmp = (head); \
|
||||
while (__tmp->next != NULL) { \
|
||||
__tmp = __tmp->next; \
|
||||
} \
|
||||
@ -87,11 +87,11 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DL_FRONT(head, out) \
|
||||
#define dlinklist_front(type, head, out) \
|
||||
do { \
|
||||
(out) = NULL; \
|
||||
if ((head) != NULL) { \
|
||||
typeof((head)) __tmp = (head); \
|
||||
type __tmp = (head); \
|
||||
while (__tmp->prev != NULL) { \
|
||||
__tmp = __tmp->prev; \
|
||||
} \
|
||||
@ -99,7 +99,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DL_INSERT_AFTER(head, pos, new) \
|
||||
#define dlinklist_insert_after(head, pos, new) \
|
||||
do { \
|
||||
if ((pos) != NULL && (new) != NULL) { \
|
||||
(new)->prev = (pos); \
|
||||
@ -115,7 +115,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DL_INSERT_BEFORE(head, pos, new) \
|
||||
#define dlinklist_insert_before(head, pos, new) \
|
||||
do { \
|
||||
if ((pos) != NULL && (new) != NULL) { \
|
||||
(new)->next = (pos); \
|
||||
@ -133,11 +133,11 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LL_APPEND(head, new) \
|
||||
#define linklist_append(type, head, new) \
|
||||
do { \
|
||||
if ((new) != NULL) { \
|
||||
if ((head) != NULL) { \
|
||||
typeof((head)) __tmp; \
|
||||
type __tmp; \
|
||||
(new)->next = NULL; \
|
||||
__tmp = (head); \
|
||||
while (__tmp->next != NULL) { \
|
||||
@ -151,11 +151,11 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define LL_REMOVE(head, ele) \
|
||||
#define linklist_remove(type, head, ele) \
|
||||
do { \
|
||||
if ((head) != NULL && (ele) != NULL) { \
|
||||
typeof((head)) __cur = (head); \
|
||||
typeof((head)) __prev = NULL; \
|
||||
type __cur = (head); \
|
||||
type __prev = NULL; \
|
||||
while (__cur != NULL && __cur != (ele)) { \
|
||||
__prev = __cur; \
|
||||
__cur = __cur->next; \
|
||||
@ -171,10 +171,10 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define LL_FINDPROP(head, out, propname, propvalue) \
|
||||
#define linklist_find(type, head, out, propname, propvalue) \
|
||||
do { \
|
||||
(out) = NULL; \
|
||||
typeof((head)) __tmp = (head); \
|
||||
type __tmp = (head); \
|
||||
while (__tmp) { \
|
||||
if (__tmp->propname == (propvalue)) { \
|
||||
(out) = __tmp; \
|
||||
@ -184,27 +184,27 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define LL_FOREACH_SAFE(head, var, tmp) \
|
||||
#define linklist_foreach(head, var, tmp) \
|
||||
for (var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL; \
|
||||
var = tmp, tmp = (var ? var->next : NULL) \
|
||||
)
|
||||
|
||||
#define LL_FOREACH_SAFE_IDX(head, var, tmp, idx) \
|
||||
#define linklist_foreach_index(head, var, tmp, idx) \
|
||||
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL; \
|
||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
||||
|
||||
#define LL_FOREACH_SAFE_IDX_LIMIT(head, var, tmp, idx, max) \
|
||||
#define linklist_foreach_index_limit(head, var, tmp, idx, max) \
|
||||
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL && (idx) < (max); \
|
||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
||||
|
||||
#define LL_BACK(head, out) \
|
||||
#define linklist_back(type, head, out) \
|
||||
do { \
|
||||
(out) = NULL; \
|
||||
if ((head) != NULL) { \
|
||||
typeof((head)) __tmp = (head); \
|
||||
type __tmp = (head); \
|
||||
while (__tmp->next != NULL) { \
|
||||
__tmp = __tmp->next; \
|
||||
} \
|
||||
|
||||
@ -6,3 +6,4 @@ include platform/$(platform)/make.src
|
||||
include libk/make.src
|
||||
include sync/make.src
|
||||
include mm/make.src
|
||||
include irq/make.src
|
||||
|
||||
@ -9,12 +9,15 @@
|
||||
|
||||
#include <libk/stdatomic.h>
|
||||
#include <libk/types.h>
|
||||
#include <sys/mm.h>
|
||||
#include <mm/liballoc.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <sync/spinlock.h>
|
||||
#include <config.h>
|
||||
|
||||
#if defined(__i386__)
|
||||
#include <sys/mm.h>
|
||||
#endif
|
||||
|
||||
struct spinlock liballoc_sl = { .flag = ATOMIC_FLAG_INIT, .name = "liballoc" };
|
||||
uptr_t liballoc_memory_start = KERNEL_HEAP_START;
|
||||
|
||||
@ -43,8 +46,6 @@ void *liballoc_alloc(int pages) {
|
||||
sl_unlock(&pd->sl);
|
||||
|
||||
return (void *)vaddr;
|
||||
#else
|
||||
#error "platform unimplemented"
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -52,7 +53,7 @@ int liballoc_free(void *ptr1, int pages) {
|
||||
#if defined(__i386__)
|
||||
struct page_dir *pd = mm_get_kernel_pd();
|
||||
|
||||
uptr_t ptr = ALIGN_DOWN((uptr_t)ptr1, 0x1000);
|
||||
uptr_t ptr = ALIGN_DOWN((uptr_t)ptr1, PAGE_SIZE);
|
||||
|
||||
sl_lock(&pd->sl);
|
||||
|
||||
@ -65,8 +66,6 @@ int liballoc_free(void *ptr1, int pages) {
|
||||
sl_unlock(&pd->sl);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
#error "platform unimplemented"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <sys/mm.h>
|
||||
#include <sys/pic.h>
|
||||
#include <sys/pit.h>
|
||||
#include <sys/isr.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/bba.h>
|
||||
#include <mm/liballoc.h>
|
||||
@ -135,14 +136,8 @@ void bootmain(void *mbootptr) {
|
||||
bba_init();
|
||||
mm_init();
|
||||
pit_init();
|
||||
pic_unmask();
|
||||
|
||||
__asm__ volatile("sti");
|
||||
|
||||
char *string = malloc(12);
|
||||
memset(string, 0, 12);
|
||||
strncpy(string, "Hello world", 12);
|
||||
dbgf("string = %s\n", string);
|
||||
free(string);
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
@ -135,13 +135,13 @@ struct trapframe {
|
||||
uint32_t edx;
|
||||
uint32_t ecx;
|
||||
uint32_t eax;
|
||||
uint32_t ec;
|
||||
uint32_t trapno;
|
||||
uint32_t ec;
|
||||
uint32_t eip;
|
||||
uint32_t cs;
|
||||
uint32_t eflags;
|
||||
uint32_t uesp;
|
||||
uint32_t uss;
|
||||
/* uint32_t uesp; */
|
||||
/* uint32_t uss; */
|
||||
} packed;
|
||||
|
||||
void cpu_init(void);
|
||||
|
||||
@ -34,5 +34,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.type halt, @function
|
||||
halt:
|
||||
cli
|
||||
hlt
|
||||
jmp halt
|
||||
|
||||
@ -38,8 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.type except ## exc, @function; \
|
||||
except ## exc:; \
|
||||
cli; \
|
||||
push $0; \
|
||||
push $exc; \
|
||||
pushl $0; \
|
||||
pushl $exc; \
|
||||
jmp temp_except_hndlr;
|
||||
|
||||
#define EXCEPT_ERR(exc) \
|
||||
@ -47,7 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.type except ## exc, @function; \
|
||||
except ## exc:; \
|
||||
cli; \
|
||||
push $exc; \
|
||||
pushl $exc; \
|
||||
jmp temp_except_hndlr;
|
||||
|
||||
EXCEPT_NOERR(0)
|
||||
@ -87,42 +87,42 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
temp_except_hndlr:
|
||||
pushal
|
||||
xorl %eax, %eax
|
||||
mov %ds, %ax
|
||||
push %eax
|
||||
movw %ds, %ax
|
||||
pushl %eax
|
||||
|
||||
/* load kernel DS */
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
movw $0x10, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
push %esp
|
||||
pushl %esp
|
||||
|
||||
call except_fini
|
||||
|
||||
add $0x04, %esp
|
||||
addl $4, %esp
|
||||
|
||||
/* restore DS */
|
||||
pop %ebx
|
||||
mov %bx, %ds
|
||||
mov %bx, %es
|
||||
mov %bx, %fs
|
||||
mov %bx, %gs
|
||||
popl %eax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
/* rebalance */
|
||||
popal
|
||||
add $0x8, %esp
|
||||
addl $8, %esp
|
||||
|
||||
iret
|
||||
iretl
|
||||
|
||||
#define IRQ(irq1) \
|
||||
.global irq ## irq1; \
|
||||
.type irq ## irq1, @function; \
|
||||
irq ## irq1:; \
|
||||
cli; \
|
||||
push $0; \
|
||||
push $irq1; \
|
||||
pushl $0; \
|
||||
pushl $irq1; \
|
||||
jmp temp_irq_hndlr;
|
||||
|
||||
IRQ(0)
|
||||
@ -145,31 +145,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
temp_irq_hndlr:
|
||||
pushal
|
||||
xorl %eax, %eax
|
||||
mov %ds, %ax
|
||||
push %eax
|
||||
movw %ds, %ax
|
||||
pushl %eax
|
||||
|
||||
/* load kernel DS */
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
movw $0x10, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
push %esp
|
||||
pushl %esp
|
||||
|
||||
call irq_fini
|
||||
|
||||
add $0x04, %esp
|
||||
addl $4, %esp
|
||||
|
||||
/* restore DS */
|
||||
pop %ebx
|
||||
mov %bx, %ds
|
||||
mov %bx, %es
|
||||
mov %bx, %fs
|
||||
mov %bx, %gs
|
||||
popl %eax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
/* rebalance */
|
||||
popal
|
||||
add $0x8, %esp
|
||||
addl $8, %esp
|
||||
|
||||
iret
|
||||
iretl
|
||||
|
||||
@ -83,20 +83,20 @@ void irq13(void);
|
||||
void irq14(void);
|
||||
void irq15(void);
|
||||
|
||||
#define ISR_PIT 32+0
|
||||
#define ISR_KBD 32+1
|
||||
#define ISR_COM2 32+3
|
||||
#define ISR_COM1 32+4
|
||||
#define ISR_LPT2 32+5
|
||||
#define ISR_FLOPPY 32+6
|
||||
#define ISR_LPT1 32+7
|
||||
#define ISR_CMOS_RTC 32+8
|
||||
#define ISR_FREE9 32+9
|
||||
#define ISR_FREE10 32+10
|
||||
#define ISR_FREE11 32+11
|
||||
#define ISR_PS2_MOUSE 32+12
|
||||
#define ISR_FPU 32+13
|
||||
#define ISR_PRIM_ATA 32+14
|
||||
#define ISR_SCND_ATA 32+15
|
||||
#define IRQ_PIT 32+0
|
||||
#define IRQ_KBD 32+1
|
||||
#define IRQ_COM2 32+3
|
||||
#define IRQ_COM1 32+4
|
||||
#define IRQ_LPT2 32+5
|
||||
#define IRQ_FLOPPY 32+6
|
||||
#define IRQ_LPT1 32+7
|
||||
#define IRQ_CMOS_RTC 32+8
|
||||
#define IRQ_FREE9 32+9
|
||||
#define IRQ_FREE10 32+10
|
||||
#define IRQ_FREE11 32+11
|
||||
#define IRQ_PS2_MOUSE 32+12
|
||||
#define IRQ_FPU 32+13
|
||||
#define IRQ_PRIM_ATA 32+14
|
||||
#define IRQ_SCND_ATA 32+15
|
||||
|
||||
#endif // _SYS_ISR_H
|
||||
|
||||
@ -30,36 +30,39 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <libk/types.h>
|
||||
#include <libk/list.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/serialdbg.h>
|
||||
#include <sys/halt.h>
|
||||
#include <sys/pit.h>
|
||||
#include <sys/isr.h>
|
||||
#include <sys/pic.h>
|
||||
#include <irq/irqhandler.h>
|
||||
#include <config.h>
|
||||
|
||||
void except_fini(struct trapframe *tf) {
|
||||
dbgf("EXCEPTION %u\n", tf->trapno);
|
||||
dbgf("trapframe:\n");
|
||||
|
||||
uptr_t cr2;
|
||||
__asm__ volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||
|
||||
dbgf("ds =%08x, edi=%08x, esi=%08x, ebp=%08x\n",
|
||||
tf->ds, tf->edi, tf->esi, tf->ebp);
|
||||
dbgf("esp=%08x, ebx=%08x, edx=%08x, ecx=%08x\n",
|
||||
tf->esp, tf->ebx, tf->edx, tf->ecx);
|
||||
dbgf("trp=%08x, erc=%08x, eip=%08x, cs =%08x\n",
|
||||
tf->trapno, tf->ec, tf->eip, tf->cs);
|
||||
dbgf("efl=%08x, usp=%08x, uss=%08x\n",
|
||||
tf->eflags, tf->uesp, tf->uss);
|
||||
dbgf("efl=%08x, cr2=%08x\n",
|
||||
tf->eflags, cr2);
|
||||
|
||||
halt();
|
||||
}
|
||||
|
||||
void irq_fini(struct trapframe *tf) {
|
||||
if (tf->trapno == ISR_PIT) {
|
||||
ticks_increment();
|
||||
goto done;
|
||||
}
|
||||
int irq = 0x20 + tf->trapno;
|
||||
|
||||
irqhandler_func_t func = irqhandler_find(irq);
|
||||
func((void *)tf);
|
||||
|
||||
done:
|
||||
pic_fini(tf->trapno);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -56,6 +56,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#define CASCADE_IRQ 2
|
||||
|
||||
static void pic_mask_all(void) {
|
||||
ioport_out8(PIC1_DATA, 0xFF);
|
||||
ioport_wait();
|
||||
ioport_out8(PIC2_DATA, 0xFF);
|
||||
ioport_wait();
|
||||
}
|
||||
|
||||
void pic_init(void) {
|
||||
// remap & disable
|
||||
|
||||
@ -82,21 +89,41 @@ void pic_init(void) {
|
||||
ioport_out8(PIC2_DATA, ICW4_8086);
|
||||
ioport_wait();
|
||||
|
||||
pic_mask();
|
||||
pic_mask_all();
|
||||
}
|
||||
|
||||
void pic_mask(void) {
|
||||
ioport_out8(PIC1_DATA, 0xFF);
|
||||
ioport_wait();
|
||||
ioport_out8(PIC2_DATA, 0xFF);
|
||||
ioport_wait();
|
||||
void pic_unmask_irq(uint8_t irq) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
irq -= 0x20;
|
||||
|
||||
if (irq < 8) {
|
||||
port = PIC1_DATA;
|
||||
} else {
|
||||
port = PIC2_DATA;
|
||||
irq -= 8;
|
||||
}
|
||||
|
||||
value = ioport_in8(port) & ~(1<<irq);
|
||||
ioport_out8(port, value);
|
||||
}
|
||||
|
||||
void pic_unmask(void) {
|
||||
ioport_out8(PIC1_DATA, 0);
|
||||
ioport_wait();
|
||||
ioport_out8(PIC2_DATA, 0);
|
||||
ioport_wait();
|
||||
void pic_mask_irq(uint8_t irq) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
irq -= 0x20;
|
||||
|
||||
if (irq < 8) {
|
||||
port = PIC1_DATA;
|
||||
} else {
|
||||
port = PIC2_DATA;
|
||||
irq -= 8;
|
||||
}
|
||||
|
||||
value = ioport_in8(port) | (1<<irq);
|
||||
ioport_out8(port, value);
|
||||
}
|
||||
|
||||
void pic_fini(uint8_t trap) {
|
||||
|
||||
@ -35,8 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <libk/types.h>
|
||||
|
||||
void pic_init(void);
|
||||
void pic_mask(void);
|
||||
void pic_unmask(void);
|
||||
void pic_fini(uint8_t trap);
|
||||
void pic_unmask_irq(uint8_t irq);
|
||||
void pic_mask_irq(uint8_t irq);
|
||||
|
||||
#endif // _SYS_PIC_H
|
||||
|
||||
@ -30,9 +30,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <libk/types.h>
|
||||
#include <libk/compiler.h>
|
||||
#include <sys/pit.h>
|
||||
#include <sys/ioport.h>
|
||||
#include <sys/isr.h>
|
||||
#include <sync/spinlock.h>
|
||||
#include <irq/irqhandler.h>
|
||||
#include <config.h>
|
||||
|
||||
#define PIT_COUNTER0 0x40
|
||||
#define PIT_CMD 0x43
|
||||
@ -65,14 +69,21 @@ uint32_t ticks_get(void) {
|
||||
return t;
|
||||
}
|
||||
|
||||
void ticks_increment(void) {
|
||||
static void ticks_increment(void) {
|
||||
sl_lock(&ticks_spinlock);
|
||||
ticks++;
|
||||
sl_unlock(&ticks_spinlock);
|
||||
}
|
||||
|
||||
static void pit_irqhandler(unused void *cpustate) {
|
||||
ticks_increment();
|
||||
}
|
||||
|
||||
void pit_init(void) {
|
||||
sl_init(&ticks_spinlock, "ticks");
|
||||
|
||||
irqhandler_register(IRQ_PIT, &pit_irqhandler);
|
||||
irqhandler_enable(IRQ_PIT);
|
||||
|
||||
uint32_t hz = 1000;
|
||||
uint32_t div = PIT_FREQ / hz;
|
||||
|
||||
@ -34,6 +34,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
void pit_init(void);
|
||||
uint32_t ticks_get(void);
|
||||
void ticks_increment(void);
|
||||
|
||||
#endif // _SYS_PIT_H
|
||||
|
||||
@ -32,7 +32,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <libk/stdatomic.h>
|
||||
#include <libk/string.h>
|
||||
#include <sync/spinlock.h>
|
||||
#include <sys/cpu.h>
|
||||
|
||||
#if defined(__i386__)
|
||||
#include <sys/cpu.h>
|
||||
#endif
|
||||
|
||||
void sl_init(struct spinlock *sl, const char *name) {
|
||||
if (strlen(name) > SPINLOCK_NAME_MAX) {
|
||||
@ -46,7 +49,9 @@ void sl_init(struct spinlock *sl, const char *name) {
|
||||
void sl_lock(struct spinlock *sl) {
|
||||
intr_save();
|
||||
while (atomic_flag_test_and_set_explicit(&sl->flag, memory_order_acquire)) {
|
||||
#if defined(__i386__)
|
||||
cpu_relax();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user