void ide_ata_init();
ide_ata_init();
- request_irq(0x0E, ide_irq_handler, NULL, "hard", "IDE");
+ request_irq(0x0E, ide_irq_handler, "hard", "IDE");
// init_pci_controller(0x0106);
init_pci_controller(0x0101);
typedef struct irqaction {
// void (*handler)(pt_regs_t * regs, unsigned int irq);
void (*handler)(unsigned int irq, pt_regs_t *regs, void *dev_id);
- void (*bh_handler)();
const char *dev_name;
void *dev_id;
struct irqaction *next;
unsigned int depth;
} irq_desc_t;
+typedef struct irq_bh_action {
+ void (*handler)();
+ struct irq_bh_action *next;
+} irq_bh_action_t;
+
extern irq_chip_t i8259_chip;
extern irq_desc_t irq_desc[];
extern irq_desc_t no_irq_desc;
int request_irq(unsigned int irq,
// void (*handler)(pt_regs_t *, unsigned int),
- void (*handler)(unsigned int, pt_regs_t *, void *), void (*bh_handler)(), const char *devname,
- void *dev_id);
+ void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname, void *dev_id);
+
+void add_irq_bh_handler(void (*handler)());
int open_irq(unsigned int irq);
int close_irq(unsigned int irq);
void debug_print_all_tasks();
void dump_irq_nr_stack();
+void clk_bh_handler();
void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
// if (jiffies % 100 == 0) {
printl(MPL_CLOCK, "clock irq: %d", jiffies);
}
assert(current->ticks <= TASK_MAX_PRIORITY); // 防止ticks被减到0后再减溢出
+
+ add_irq_bh_handler(clk_bh_handler);
}
// 开中断执行这个函数
#include <task.h>
irq_desc_t irq_desc[NR_IRQS];
-
-int enable_no_irq_chip(unsigned int irq) { return 0; }
-int disable_no_irq_chip(unsigned int irq) { return 0; }
-
-irq_chip_t no_irq_chip = {.name = "none", .enable = enable_no_irq_chip, .disable = disable_no_irq_chip};
-
-irq_desc_t no_irq_desc = {.chip = &no_irq_chip, .action = NULL, .status = 0, .depth = 0};
+irq_bh_action_t *irq_bh_actions = NULL;
+irq_bh_action_t *irq_bh_actions_end = NULL;
#if 0
unsigned int irq_nr_stack[64] = {1, 2, 3, 4};
}
#endif
+void irq_bh_handler();
+
__attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
unsigned int irq = regs->irq;
if (irq >= NR_IRQS) {
{
enable_irq();
- action = p->action;
- while (action) {
- if (action->bh_handler != NULL) {
- action->bh_handler();
- }
- action = action->next;
- }
+ irq_bh_handler();
disable_irq();
}
schedule();
}
-int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), void (*bh_handler)(),
- const char *devname, void *dev_id) {
+extern uint32_t jiffies;
+void irq_bh_handler() {
+ uint32_t end = jiffies + 2;
+ while (true) {
+ irq_bh_action_t *action = NULL;
+
+ disable_irq();
+
+ action = irq_bh_actions;
+ irq_bh_actions = NULL;
+ irq_bh_actions_end = NULL;
+
+ enable_irq();
+
+ if (action == NULL) {
+ break;
+ }
+
+ while (action != NULL) {
+ action->handler();
+ irq_bh_action_t *p = action;
+ action = action->next;
+ kfree(p);
+ }
+
+ if (jiffies >= end) {
+ break;
+ }
+
+ // 这里可能存在有部分没处理完
+ }
+
+ // 这之后也可能存在再次被中断加入下半部处理请求
+ // 但这些都不会丢失
+ // 而是会延迟到这次中断返回后下一次的中断的下半部分处理逻辑
+}
+
+int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname,
+ void *dev_id) {
irq_action_t *p;
if (irq >= NR_IRQS) {
p->dev_name = devname;
p->dev_id = dev_id;
p->handler = handler;
- p->bh_handler = bh_handler;
p->next = NULL;
if (irq_desc[irq].action != NULL) {
p->next = irq_desc[irq].action;
return 0;
}
+void add_irq_bh_handler(void (*handler)()) {
+ // 只能在中断处理函数中调用
+ assert(irq_disabled());
+
+ irq_bh_action_t *p;
+ p = (irq_bh_action_t *)kmalloc(sizeof(irq_bh_action_t), 0);
+ assert(p != NULL);
+
+ p->handler = handler;
+
+ if (irq_bh_actions_end == NULL) {
+ assert(irq_bh_actions == NULL);
+ irq_bh_actions = p;
+ irq_bh_actions_end = p;
+
+ } else {
+ assert(irq_bh_actions != NULL);
+ irq_bh_actions_end->next = p;
+ irq_bh_actions_end = p;
+ }
+ p->next = NULL;
+
+ irq_bh_actions = p;
+}
+
int open_irq(unsigned int irq) { return irq_desc[irq].chip->enable(irq); }
int close_irq(unsigned int irq) { return irq_desc[irq].chip->disable(irq); }
return false;
}
-bool irq_disabled() { return !irq_enabled(); }
\ No newline at end of file
+bool irq_disabled() { return !irq_enabled(); }
+
+int enable_no_irq_chip(unsigned int irq) { return 0; }
+int disable_no_irq_chip(unsigned int irq) { return 0; }
+
+irq_chip_t no_irq_chip = {.name = "none", .enable = enable_no_irq_chip, .disable = disable_no_irq_chip};
+irq_desc_t no_irq_desc = {.chip = &no_irq_chip, .action = NULL, .status = 0, .depth = 0};
setup_gate();
set_tss();
- setup_i8253(20);
+ setup_i8253(100);
setup_sysc();
void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id);
void clk_bh_handler();
- request_irq(0x00, clk_handler, clk_bh_handler, "Intel 8254", "Clock Chip");
- request_irq(0x01, kbd_handler, NULL, "Intel 8042", "PS/2 Keyboard");
+ request_irq(0x00, clk_handler, "Intel 8254", "Clock Chip");
+ request_irq(0x01, kbd_handler, "Intel 8042", "PS/2 Keyboard");
// request_irq(0x0E, default_ide_irq_handler, "hard", "IDE");
for (int i = 0; i < 16; i++) {
if (i != 0 && i != 1 && i != 10 && i != 14) {
- request_irq(i, default_irq_handler, NULL, "default", "default");
+ request_irq(i, default_irq_handler, "default", "default");
}
}
boot/multiboot.S.o(.text)
*(.multiboot2_header)
*(.text)
- *(.ring3.text);
+ *(.ring3.text);
*(.sysexit) /* last */
}
etext = .;