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
|
#ifndef _LIBK_LIST_H
|
||||||
#define _LIBK_LIST_H
|
#define _LIBK_LIST_H
|
||||||
|
|
||||||
#define DL_APPEND(head, new) \
|
#define dlinklist_append(type, head, new) \
|
||||||
do { \
|
do { \
|
||||||
if ((new) != NULL) { \
|
if ((new) != NULL) { \
|
||||||
(new)->next = NULL; \
|
(new)->next = NULL; \
|
||||||
if ((head) != NULL) { \
|
if ((head) != NULL) { \
|
||||||
typeof((head)) __tmp = (head); \
|
type __tmp = (head); \
|
||||||
while (__tmp->next != NULL) { \
|
while (__tmp->next != NULL) { \
|
||||||
__tmp = __tmp->next; \
|
__tmp = __tmp->next; \
|
||||||
} \
|
} \
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DL_PREPEND(head, new) \
|
#define dlinklist_prepend(head, new) \
|
||||||
do { \
|
do { \
|
||||||
if ((new) != NULL) { \
|
if ((new) != NULL) { \
|
||||||
(new)->prev = NULL; \
|
(new)->prev = NULL; \
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DL_REMOVE(head, ele) \
|
#define dlinklist_remove(head, ele) \
|
||||||
do { \
|
do { \
|
||||||
if ((ele) != NULL) { \
|
if ((ele) != NULL) { \
|
||||||
if ((ele)->prev != NULL) { \
|
if ((ele)->prev != NULL) { \
|
||||||
@@ -47,10 +47,10 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DL_FINDPROP(head, out, propname, propvalue) \
|
#define dlinklist_find(type, head, out, propname, propvalue) \
|
||||||
do { \
|
do { \
|
||||||
(out) = NULL; \
|
(out) = NULL; \
|
||||||
typeof((head)) __tmp = (head); \
|
type __tmp = (head); \
|
||||||
while (__tmp) { \
|
while (__tmp) { \
|
||||||
if (__tmp->propname == (propvalue)) { \
|
if (__tmp->propname == (propvalue)) { \
|
||||||
(out) = __tmp; \
|
(out) = __tmp; \
|
||||||
@@ -60,26 +60,26 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DL_FOREACH_SAFE(head, var, tmp) \
|
#define dlinklist_foreach(head, var, tmp) \
|
||||||
for (var = (head), tmp = (var ? var->next : NULL); \
|
for (var = (head), tmp = (var ? var->next : NULL); \
|
||||||
var != NULL; \
|
var != NULL; \
|
||||||
var = tmp, tmp = (var ? var->next : 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); \
|
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||||
var != NULL; \
|
var != NULL; \
|
||||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
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); \
|
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||||
var != NULL && (idx) < (max); \
|
var != NULL && (idx) < (max); \
|
||||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
||||||
|
|
||||||
#define DL_BACK(head, out) \
|
#define dlinklist_back(type, head, out) \
|
||||||
do { \
|
do { \
|
||||||
(out) = NULL; \
|
(out) = NULL; \
|
||||||
if ((head) != NULL) { \
|
if ((head) != NULL) { \
|
||||||
typeof((head)) __tmp = (head); \
|
type __tmp = (head); \
|
||||||
while (__tmp->next != NULL) { \
|
while (__tmp->next != NULL) { \
|
||||||
__tmp = __tmp->next; \
|
__tmp = __tmp->next; \
|
||||||
} \
|
} \
|
||||||
@@ -87,11 +87,11 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DL_FRONT(head, out) \
|
#define dlinklist_front(type, head, out) \
|
||||||
do { \
|
do { \
|
||||||
(out) = NULL; \
|
(out) = NULL; \
|
||||||
if ((head) != NULL) { \
|
if ((head) != NULL) { \
|
||||||
typeof((head)) __tmp = (head); \
|
type __tmp = (head); \
|
||||||
while (__tmp->prev != NULL) { \
|
while (__tmp->prev != NULL) { \
|
||||||
__tmp = __tmp->prev; \
|
__tmp = __tmp->prev; \
|
||||||
} \
|
} \
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DL_INSERT_AFTER(head, pos, new) \
|
#define dlinklist_insert_after(head, pos, new) \
|
||||||
do { \
|
do { \
|
||||||
if ((pos) != NULL && (new) != NULL) { \
|
if ((pos) != NULL && (new) != NULL) { \
|
||||||
(new)->prev = (pos); \
|
(new)->prev = (pos); \
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DL_INSERT_BEFORE(head, pos, new) \
|
#define dlinklist_insert_before(head, pos, new) \
|
||||||
do { \
|
do { \
|
||||||
if ((pos) != NULL && (new) != NULL) { \
|
if ((pos) != NULL && (new) != NULL) { \
|
||||||
(new)->next = (pos); \
|
(new)->next = (pos); \
|
||||||
@@ -133,11 +133,11 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LL_APPEND(head, new) \
|
#define linklist_append(type, head, new) \
|
||||||
do { \
|
do { \
|
||||||
if ((new) != NULL) { \
|
if ((new) != NULL) { \
|
||||||
if ((head) != NULL) { \
|
if ((head) != NULL) { \
|
||||||
typeof((head)) __tmp; \
|
type __tmp; \
|
||||||
(new)->next = NULL; \
|
(new)->next = NULL; \
|
||||||
__tmp = (head); \
|
__tmp = (head); \
|
||||||
while (__tmp->next != NULL) { \
|
while (__tmp->next != NULL) { \
|
||||||
@@ -151,11 +151,11 @@
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define LL_REMOVE(head, ele) \
|
#define linklist_remove(type, head, ele) \
|
||||||
do { \
|
do { \
|
||||||
if ((head) != NULL && (ele) != NULL) { \
|
if ((head) != NULL && (ele) != NULL) { \
|
||||||
typeof((head)) __cur = (head); \
|
type __cur = (head); \
|
||||||
typeof((head)) __prev = NULL; \
|
type __prev = NULL; \
|
||||||
while (__cur != NULL && __cur != (ele)) { \
|
while (__cur != NULL && __cur != (ele)) { \
|
||||||
__prev = __cur; \
|
__prev = __cur; \
|
||||||
__cur = __cur->next; \
|
__cur = __cur->next; \
|
||||||
@@ -171,10 +171,10 @@
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define LL_FINDPROP(head, out, propname, propvalue) \
|
#define linklist_find(type, head, out, propname, propvalue) \
|
||||||
do { \
|
do { \
|
||||||
(out) = NULL; \
|
(out) = NULL; \
|
||||||
typeof((head)) __tmp = (head); \
|
type __tmp = (head); \
|
||||||
while (__tmp) { \
|
while (__tmp) { \
|
||||||
if (__tmp->propname == (propvalue)) { \
|
if (__tmp->propname == (propvalue)) { \
|
||||||
(out) = __tmp; \
|
(out) = __tmp; \
|
||||||
@@ -184,27 +184,27 @@
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define LL_FOREACH_SAFE(head, var, tmp) \
|
#define linklist_foreach(head, var, tmp) \
|
||||||
for (var = (head), tmp = (var ? var->next : NULL); \
|
for (var = (head), tmp = (var ? var->next : NULL); \
|
||||||
var != NULL; \
|
var != NULL; \
|
||||||
var = tmp, tmp = (var ? var->next : 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); \
|
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||||
var != NULL; \
|
var != NULL; \
|
||||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
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); \
|
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||||
var != NULL && (idx) < (max); \
|
var != NULL && (idx) < (max); \
|
||||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
||||||
|
|
||||||
#define LL_BACK(head, out) \
|
#define linklist_back(type, head, out) \
|
||||||
do { \
|
do { \
|
||||||
(out) = NULL; \
|
(out) = NULL; \
|
||||||
if ((head) != NULL) { \
|
if ((head) != NULL) { \
|
||||||
typeof((head)) __tmp = (head); \
|
type __tmp = (head); \
|
||||||
while (__tmp->next != NULL) { \
|
while (__tmp->next != NULL) { \
|
||||||
__tmp = __tmp->next; \
|
__tmp = __tmp->next; \
|
||||||
} \
|
} \
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ include platform/$(platform)/make.src
|
|||||||
include libk/make.src
|
include libk/make.src
|
||||||
include sync/make.src
|
include sync/make.src
|
||||||
include mm/make.src
|
include mm/make.src
|
||||||
|
include irq/make.src
|
||||||
|
|||||||
@@ -9,12 +9,15 @@
|
|||||||
|
|
||||||
#include <libk/stdatomic.h>
|
#include <libk/stdatomic.h>
|
||||||
#include <libk/types.h>
|
#include <libk/types.h>
|
||||||
#include <sys/mm.h>
|
|
||||||
#include <mm/liballoc.h>
|
#include <mm/liballoc.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <sync/spinlock.h>
|
#include <sync/spinlock.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined(__i386__)
|
||||||
|
#include <sys/mm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct spinlock liballoc_sl = { .flag = ATOMIC_FLAG_INIT, .name = "liballoc" };
|
struct spinlock liballoc_sl = { .flag = ATOMIC_FLAG_INIT, .name = "liballoc" };
|
||||||
uptr_t liballoc_memory_start = KERNEL_HEAP_START;
|
uptr_t liballoc_memory_start = KERNEL_HEAP_START;
|
||||||
|
|
||||||
@@ -43,8 +46,6 @@ void *liballoc_alloc(int pages) {
|
|||||||
sl_unlock(&pd->sl);
|
sl_unlock(&pd->sl);
|
||||||
|
|
||||||
return (void *)vaddr;
|
return (void *)vaddr;
|
||||||
#else
|
|
||||||
#error "platform unimplemented"
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ int liballoc_free(void *ptr1, int pages) {
|
|||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
struct page_dir *pd = mm_get_kernel_pd();
|
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);
|
sl_lock(&pd->sl);
|
||||||
|
|
||||||
@@ -65,8 +66,6 @@ int liballoc_free(void *ptr1, int pages) {
|
|||||||
sl_unlock(&pd->sl);
|
sl_unlock(&pd->sl);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
|
||||||
#error "platform unimplemented"
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <sys/mm.h>
|
#include <sys/mm.h>
|
||||||
#include <sys/pic.h>
|
#include <sys/pic.h>
|
||||||
#include <sys/pit.h>
|
#include <sys/pit.h>
|
||||||
|
#include <sys/isr.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <mm/bba.h>
|
#include <mm/bba.h>
|
||||||
#include <mm/liballoc.h>
|
#include <mm/liballoc.h>
|
||||||
@@ -135,14 +136,8 @@ void bootmain(void *mbootptr) {
|
|||||||
bba_init();
|
bba_init();
|
||||||
mm_init();
|
mm_init();
|
||||||
pit_init();
|
pit_init();
|
||||||
pic_unmask();
|
|
||||||
__asm__ volatile("sti");
|
|
||||||
|
|
||||||
char *string = malloc(12);
|
__asm__ volatile("sti");
|
||||||
memset(string, 0, 12);
|
|
||||||
strncpy(string, "Hello world", 12);
|
|
||||||
dbgf("string = %s\n", string);
|
|
||||||
free(string);
|
|
||||||
|
|
||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,13 +135,13 @@ struct trapframe {
|
|||||||
uint32_t edx;
|
uint32_t edx;
|
||||||
uint32_t ecx;
|
uint32_t ecx;
|
||||||
uint32_t eax;
|
uint32_t eax;
|
||||||
uint32_t ec;
|
|
||||||
uint32_t trapno;
|
uint32_t trapno;
|
||||||
|
uint32_t ec;
|
||||||
uint32_t eip;
|
uint32_t eip;
|
||||||
uint32_t cs;
|
uint32_t cs;
|
||||||
uint32_t eflags;
|
uint32_t eflags;
|
||||||
uint32_t uesp;
|
/* uint32_t uesp; */
|
||||||
uint32_t uss;
|
/* uint32_t uss; */
|
||||||
} packed;
|
} packed;
|
||||||
|
|
||||||
void cpu_init(void);
|
void cpu_init(void);
|
||||||
|
|||||||
@@ -34,5 +34,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
.type halt, @function
|
.type halt, @function
|
||||||
halt:
|
halt:
|
||||||
cli
|
cli
|
||||||
hlt
|
|
||||||
jmp halt
|
jmp halt
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
.type except ## exc, @function; \
|
.type except ## exc, @function; \
|
||||||
except ## exc:; \
|
except ## exc:; \
|
||||||
cli; \
|
cli; \
|
||||||
push $0; \
|
pushl $0; \
|
||||||
push $exc; \
|
pushl $exc; \
|
||||||
jmp temp_except_hndlr;
|
jmp temp_except_hndlr;
|
||||||
|
|
||||||
#define EXCEPT_ERR(exc) \
|
#define EXCEPT_ERR(exc) \
|
||||||
@@ -47,7 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
.type except ## exc, @function; \
|
.type except ## exc, @function; \
|
||||||
except ## exc:; \
|
except ## exc:; \
|
||||||
cli; \
|
cli; \
|
||||||
push $exc; \
|
pushl $exc; \
|
||||||
jmp temp_except_hndlr;
|
jmp temp_except_hndlr;
|
||||||
|
|
||||||
EXCEPT_NOERR(0)
|
EXCEPT_NOERR(0)
|
||||||
@@ -87,42 +87,42 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
temp_except_hndlr:
|
temp_except_hndlr:
|
||||||
pushal
|
pushal
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
mov %ds, %ax
|
movw %ds, %ax
|
||||||
push %eax
|
pushl %eax
|
||||||
|
|
||||||
/* load kernel DS */
|
/* load kernel DS */
|
||||||
mov $0x10, %ax
|
movw $0x10, %ax
|
||||||
mov %ax, %ds
|
movw %ax, %ds
|
||||||
mov %ax, %es
|
movw %ax, %es
|
||||||
mov %ax, %fs
|
movw %ax, %fs
|
||||||
mov %ax, %gs
|
movw %ax, %gs
|
||||||
|
|
||||||
push %esp
|
pushl %esp
|
||||||
|
|
||||||
call except_fini
|
call except_fini
|
||||||
|
|
||||||
add $0x04, %esp
|
addl $4, %esp
|
||||||
|
|
||||||
/* restore DS */
|
/* restore DS */
|
||||||
pop %ebx
|
popl %eax
|
||||||
mov %bx, %ds
|
movw %ax, %ds
|
||||||
mov %bx, %es
|
movw %ax, %es
|
||||||
mov %bx, %fs
|
movw %ax, %fs
|
||||||
mov %bx, %gs
|
movw %ax, %gs
|
||||||
|
|
||||||
/* rebalance */
|
/* rebalance */
|
||||||
popal
|
popal
|
||||||
add $0x8, %esp
|
addl $8, %esp
|
||||||
|
|
||||||
iret
|
iretl
|
||||||
|
|
||||||
#define IRQ(irq1) \
|
#define IRQ(irq1) \
|
||||||
.global irq ## irq1; \
|
.global irq ## irq1; \
|
||||||
.type irq ## irq1, @function; \
|
.type irq ## irq1, @function; \
|
||||||
irq ## irq1:; \
|
irq ## irq1:; \
|
||||||
cli; \
|
cli; \
|
||||||
push $0; \
|
pushl $0; \
|
||||||
push $irq1; \
|
pushl $irq1; \
|
||||||
jmp temp_irq_hndlr;
|
jmp temp_irq_hndlr;
|
||||||
|
|
||||||
IRQ(0)
|
IRQ(0)
|
||||||
@@ -145,31 +145,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
temp_irq_hndlr:
|
temp_irq_hndlr:
|
||||||
pushal
|
pushal
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
mov %ds, %ax
|
movw %ds, %ax
|
||||||
push %eax
|
pushl %eax
|
||||||
|
|
||||||
/* load kernel DS */
|
/* load kernel DS */
|
||||||
mov $0x10, %ax
|
movw $0x10, %ax
|
||||||
mov %ax, %ds
|
movw %ax, %ds
|
||||||
mov %ax, %es
|
movw %ax, %es
|
||||||
mov %ax, %fs
|
movw %ax, %fs
|
||||||
mov %ax, %gs
|
movw %ax, %gs
|
||||||
|
|
||||||
push %esp
|
pushl %esp
|
||||||
|
|
||||||
call irq_fini
|
call irq_fini
|
||||||
|
|
||||||
add $0x04, %esp
|
addl $4, %esp
|
||||||
|
|
||||||
/* restore DS */
|
/* restore DS */
|
||||||
pop %ebx
|
popl %eax
|
||||||
mov %bx, %ds
|
movw %ax, %ds
|
||||||
mov %bx, %es
|
movw %ax, %es
|
||||||
mov %bx, %fs
|
movw %ax, %fs
|
||||||
mov %bx, %gs
|
movw %ax, %gs
|
||||||
|
|
||||||
/* rebalance */
|
/* rebalance */
|
||||||
popal
|
popal
|
||||||
add $0x8, %esp
|
addl $8, %esp
|
||||||
|
|
||||||
iret
|
iretl
|
||||||
|
|||||||
@@ -83,20 +83,20 @@ void irq13(void);
|
|||||||
void irq14(void);
|
void irq14(void);
|
||||||
void irq15(void);
|
void irq15(void);
|
||||||
|
|
||||||
#define ISR_PIT 32+0
|
#define IRQ_PIT 32+0
|
||||||
#define ISR_KBD 32+1
|
#define IRQ_KBD 32+1
|
||||||
#define ISR_COM2 32+3
|
#define IRQ_COM2 32+3
|
||||||
#define ISR_COM1 32+4
|
#define IRQ_COM1 32+4
|
||||||
#define ISR_LPT2 32+5
|
#define IRQ_LPT2 32+5
|
||||||
#define ISR_FLOPPY 32+6
|
#define IRQ_FLOPPY 32+6
|
||||||
#define ISR_LPT1 32+7
|
#define IRQ_LPT1 32+7
|
||||||
#define ISR_CMOS_RTC 32+8
|
#define IRQ_CMOS_RTC 32+8
|
||||||
#define ISR_FREE9 32+9
|
#define IRQ_FREE9 32+9
|
||||||
#define ISR_FREE10 32+10
|
#define IRQ_FREE10 32+10
|
||||||
#define ISR_FREE11 32+11
|
#define IRQ_FREE11 32+11
|
||||||
#define ISR_PS2_MOUSE 32+12
|
#define IRQ_PS2_MOUSE 32+12
|
||||||
#define ISR_FPU 32+13
|
#define IRQ_FPU 32+13
|
||||||
#define ISR_PRIM_ATA 32+14
|
#define IRQ_PRIM_ATA 32+14
|
||||||
#define ISR_SCND_ATA 32+15
|
#define IRQ_SCND_ATA 32+15
|
||||||
|
|
||||||
#endif // _SYS_ISR_H
|
#endif // _SYS_ISR_H
|
||||||
|
|||||||
@@ -30,36 +30,39 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libk/types.h>
|
#include <libk/types.h>
|
||||||
|
#include <libk/list.h>
|
||||||
#include <sys/cpu.h>
|
#include <sys/cpu.h>
|
||||||
#include <sys/serialdbg.h>
|
#include <sys/serialdbg.h>
|
||||||
#include <sys/halt.h>
|
#include <sys/halt.h>
|
||||||
#include <sys/pit.h>
|
#include <sys/pit.h>
|
||||||
#include <sys/isr.h>
|
#include <sys/isr.h>
|
||||||
#include <sys/pic.h>
|
#include <sys/pic.h>
|
||||||
|
#include <irq/irqhandler.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
void except_fini(struct trapframe *tf) {
|
void except_fini(struct trapframe *tf) {
|
||||||
dbgf("EXCEPTION %u\n", tf->trapno);
|
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",
|
dbgf("ds =%08x, edi=%08x, esi=%08x, ebp=%08x\n",
|
||||||
tf->ds, tf->edi, tf->esi, tf->ebp);
|
tf->ds, tf->edi, tf->esi, tf->ebp);
|
||||||
dbgf("esp=%08x, ebx=%08x, edx=%08x, ecx=%08x\n",
|
dbgf("esp=%08x, ebx=%08x, edx=%08x, ecx=%08x\n",
|
||||||
tf->esp, tf->ebx, tf->edx, tf->ecx);
|
tf->esp, tf->ebx, tf->edx, tf->ecx);
|
||||||
dbgf("trp=%08x, erc=%08x, eip=%08x, cs =%08x\n",
|
dbgf("trp=%08x, erc=%08x, eip=%08x, cs =%08x\n",
|
||||||
tf->trapno, tf->ec, tf->eip, tf->cs);
|
tf->trapno, tf->ec, tf->eip, tf->cs);
|
||||||
dbgf("efl=%08x, usp=%08x, uss=%08x\n",
|
dbgf("efl=%08x, cr2=%08x\n",
|
||||||
tf->eflags, tf->uesp, tf->uss);
|
tf->eflags, cr2);
|
||||||
|
|
||||||
halt();
|
halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_fini(struct trapframe *tf) {
|
void irq_fini(struct trapframe *tf) {
|
||||||
if (tf->trapno == ISR_PIT) {
|
int irq = 0x20 + tf->trapno;
|
||||||
ticks_increment();
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
irqhandler_func_t func = irqhandler_find(irq);
|
||||||
|
func((void *)tf);
|
||||||
|
|
||||||
done:
|
|
||||||
pic_fini(tf->trapno);
|
pic_fini(tf->trapno);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#define CASCADE_IRQ 2
|
#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) {
|
void pic_init(void) {
|
||||||
// remap & disable
|
// remap & disable
|
||||||
|
|
||||||
@@ -82,21 +89,41 @@ void pic_init(void) {
|
|||||||
ioport_out8(PIC2_DATA, ICW4_8086);
|
ioport_out8(PIC2_DATA, ICW4_8086);
|
||||||
ioport_wait();
|
ioport_wait();
|
||||||
|
|
||||||
pic_mask();
|
pic_mask_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pic_mask(void) {
|
void pic_unmask_irq(uint8_t irq) {
|
||||||
ioport_out8(PIC1_DATA, 0xFF);
|
uint16_t port;
|
||||||
ioport_wait();
|
uint8_t value;
|
||||||
ioport_out8(PIC2_DATA, 0xFF);
|
|
||||||
ioport_wait();
|
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) {
|
void pic_mask_irq(uint8_t irq) {
|
||||||
ioport_out8(PIC1_DATA, 0);
|
uint16_t port;
|
||||||
ioport_wait();
|
uint8_t value;
|
||||||
ioport_out8(PIC2_DATA, 0);
|
|
||||||
ioport_wait();
|
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) {
|
void pic_fini(uint8_t trap) {
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <libk/types.h>
|
#include <libk/types.h>
|
||||||
|
|
||||||
void pic_init(void);
|
void pic_init(void);
|
||||||
void pic_mask(void);
|
|
||||||
void pic_unmask(void);
|
|
||||||
void pic_fini(uint8_t trap);
|
void pic_fini(uint8_t trap);
|
||||||
|
void pic_unmask_irq(uint8_t irq);
|
||||||
|
void pic_mask_irq(uint8_t irq);
|
||||||
|
|
||||||
#endif // _SYS_PIC_H
|
#endif // _SYS_PIC_H
|
||||||
|
|||||||
@@ -30,9 +30,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libk/types.h>
|
#include <libk/types.h>
|
||||||
|
#include <libk/compiler.h>
|
||||||
#include <sys/pit.h>
|
#include <sys/pit.h>
|
||||||
#include <sys/ioport.h>
|
#include <sys/ioport.h>
|
||||||
|
#include <sys/isr.h>
|
||||||
#include <sync/spinlock.h>
|
#include <sync/spinlock.h>
|
||||||
|
#include <irq/irqhandler.h>
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#define PIT_COUNTER0 0x40
|
#define PIT_COUNTER0 0x40
|
||||||
#define PIT_CMD 0x43
|
#define PIT_CMD 0x43
|
||||||
@@ -65,15 +69,22 @@ uint32_t ticks_get(void) {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ticks_increment(void) {
|
static void ticks_increment(void) {
|
||||||
sl_lock(&ticks_spinlock);
|
sl_lock(&ticks_spinlock);
|
||||||
ticks++;
|
ticks++;
|
||||||
sl_unlock(&ticks_spinlock);
|
sl_unlock(&ticks_spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pit_irqhandler(unused void *cpustate) {
|
||||||
|
ticks_increment();
|
||||||
|
}
|
||||||
|
|
||||||
void pit_init(void) {
|
void pit_init(void) {
|
||||||
sl_init(&ticks_spinlock, "ticks");
|
sl_init(&ticks_spinlock, "ticks");
|
||||||
|
|
||||||
|
irqhandler_register(IRQ_PIT, &pit_irqhandler);
|
||||||
|
irqhandler_enable(IRQ_PIT);
|
||||||
|
|
||||||
uint32_t hz = 1000;
|
uint32_t hz = 1000;
|
||||||
uint32_t div = PIT_FREQ / hz;
|
uint32_t div = PIT_FREQ / hz;
|
||||||
ioport_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0);
|
ioport_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0);
|
||||||
|
|||||||
@@ -34,6 +34,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
void pit_init(void);
|
void pit_init(void);
|
||||||
uint32_t ticks_get(void);
|
uint32_t ticks_get(void);
|
||||||
void ticks_increment(void);
|
|
||||||
|
|
||||||
#endif // _SYS_PIT_H
|
#endif // _SYS_PIT_H
|
||||||
|
|||||||
@@ -32,7 +32,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <libk/stdatomic.h>
|
#include <libk/stdatomic.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
#include <sync/spinlock.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) {
|
void sl_init(struct spinlock *sl, const char *name) {
|
||||||
if (strlen(name) > SPINLOCK_NAME_MAX) {
|
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) {
|
void sl_lock(struct spinlock *sl) {
|
||||||
intr_save();
|
intr_save();
|
||||||
while (atomic_flag_test_and_set_explicit(&sl->flag, memory_order_acquire)) {
|
while (atomic_flag_test_and_set_explicit(&sl->flag, memory_order_acquire)) {
|
||||||
|
#if defined(__i386__)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user