Files
SUB-OS/arch/armv8i/cpu/gic.c
T
subhobhai943 7b646c8cc4 feat(arch): Add armv8i (32-bit ARM/AArch32) architecture & complete TUI configurator
- Support ARMv8i / ARM32 (AArch32) baremetal target with arm-linux-gnueabihf toolchain
- Implement ARMv8i boot entry point, banked exception mode stacks (IRQ, ABT, UND, SVC)
- Implement 8 exception vectors, GICv2 distributor/CPU interface, CP15 Generic Timer (100 Hz), flat Section MMU
- Support PL011 UART for early console & interactive LazyBox TTY input
- Update Makefile with make armv8i_defconfig and automated cross-compilation
- Update scripts/kconfig/menuconfig.py with dedicated armv8i options
2026-08-18 11:13:23 +05:30

63 lines
1.9 KiB
C

#include <arch/armv8i/gic.h>
#include <arch/armv8i/io.h>
#include <kernel/printk.h>
void gic_init(void) {
// 1. Disable Distributor and CPU interface during configuration
mmio_write32(GICD_CTLR, 0);
mmio_write32(GICC_CTLR, 0);
// 2. Query lines count (TYPER ITLinesNumber)
uint32_t typer = mmio_read32(GICD_TYPER);
uint32_t lines = 32 * ((typer & 0x1F) + 1);
// 3. Disable all interrupts & clear pending
for (uint32_t i = 0; i < lines / 32; i++) {
mmio_write32(GICD_ICENABLER(i), 0xFFFFFFFF);
mmio_write32(GICD_ICPENDR(i), 0xFFFFFFFF);
}
// 4. Default priority 0xA0 and target CPU 0 (0x01)
for (uint32_t i = 0; i < lines / 4; i++) {
mmio_write32(GICD_IPRIORITYR(i), 0xA0A0A0A0);
}
for (uint32_t i = 8; i < lines / 4; i++) {
mmio_write32(GICD_ITARGETSR(i), 0x01010101);
}
// 5. Enable Distributor (Group 0 & 1)
mmio_write32(GICD_CTLR, 3);
// 6. Set CPU Interface Priority Mask to allow all interrupts (0xF0)
mmio_write32(GICC_PMR, 0xF0);
// 7. Enable CPU Interface (Group 0 & 1)
mmio_write32(GICC_CTLR, 3);
// 8. Unmask Virtual Timer PPI 27
gic_enable_irq(27);
printk(KERN_INFO "GIC: ARM Generic Interrupt Controller v2 initialized (%u IRQ lines)\n", lines);
}
void gic_enable_irq(uint32_t irq) {
uint32_t reg_idx = irq / 32;
uint32_t bit_idx = irq % 32;
mmio_write32(GICD_ISENABLER(reg_idx), (1 << bit_idx));
}
void gic_disable_irq(uint32_t irq) {
uint32_t reg_idx = irq / 32;
uint32_t bit_idx = irq % 32;
mmio_write32(GICD_ICENABLER(reg_idx), (1 << bit_idx));
}
void gic_set_priority(uint32_t irq, uint8_t prio) {
uint32_t reg_idx = irq / 4;
uint32_t shift = (irq % 4) * 8;
uint32_t val = mmio_read32(GICD_IPRIORITYR(reg_idx));
val &= ~(0xFF << shift);
val |= ((uint32_t)prio << shift);
mmio_write32(GICD_IPRIORITYR(reg_idx), val);
}