peredOS/kernel/pic.c
msh356 d64856e1b1 MULTIPLE: 3 изменения
PIC: добавил ремаппер
IRQ: добавил таймер
KERNEL: работа со строками и памятью
2026-07-01 19:55:26 +03:00

76 lines
2.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "pic.h"
#include "io.h"
#include "logger.h"
#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21
#define PIC2_COMMAND 0xA0
#define PIC2_DATA 0xA1
#define ICW1_INIT 0x10 // Инициализация
#define ICW1_IC4 0x01 // Будет ICW4
#define ICW4_8086 0x01 // Режим 8086/8186
void pic_remap(uint8_t master_offset, uint8_t slave_offset) {
log_info(LOG_DETAIL, "Remapping PIC...");
// Сохраняем текущие маски прерываний (какое железо сейчас отключено)
uint8_t a1 = inb(PIC1_DATA);
uint8_t a2 = inb(PIC2_DATA);
// Свисток к началу инициализации (ICW1)
outb(PIC1_COMMAND, ICW1_INIT | ICW1_IC4);
io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_IC4);
io_wait();
// Задаем новые смещения векторов (ICW2)
outb(PIC1_DATA, master_offset); // Master IRQ 0-7 -> вешаем на master_offset (32)
io_wait();
outb(PIC2_DATA, slave_offset); // Slave IRQ 8-15 -> вешаем на slave_offset (40)
io_wait();
// Связываем Master и Slave между собой (ICW3)
outb(PIC1_DATA, 4); // Сообщаем Master, что Slave сидит на IRQ2 (00000100б = 4)
io_wait();
outb(PIC2_DATA, 2); // Сообщаем Slave его каскадный ID (2)
io_wait();
// Включаем режим 8086 (ICW4)
outb(PIC1_DATA, ICW4_8086);
io_wait();
outb(PIC2_DATA, ICW4_8086);
io_wait();
// Восстанавливаем сохраненные маски
outb(PIC1_DATA, a1);
outb(PIC2_DATA, a2);
log_info(LOG_DETAIL, "PIC remapped");
}
// Запретить прерывание от конкретного IRQ
void pic_set_mask(uint8_t irq_line) {
uint16_t port;
if (irq_line < 8) {
port = PIC1_DATA;
} else {
port = PIC2_DATA;
irq_line -= 8;
}
uint8_t value = inb(port) | (1 << irq_line);
outb(port, value);
}
// Разрешить прерывание от конкретного IRQ
void pic_clear_mask(uint8_t irq_line) {
uint16_t port;
if (irq_line < 8) {
port = PIC1_DATA;
} else {
port = PIC2_DATA;
irq_line -= 8;
}
uint8_t value = inb(port) & ~(1 << irq_line);
outb(port, value);
}