Dynamic IRQ handling
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user