hook the vectors the b9/b11 jumps to on interrupt
This commit is contained in:
parent
352e211fb0
commit
20038f84ab
8 changed files with 113 additions and 0 deletions
|
@ -7,5 +7,6 @@ if config["ENABLE_I2C"]:
|
|||
add_driver(False, "mcu")
|
||||
add_driver(True, "framebuffer")
|
||||
add_driver(False, "picafb")
|
||||
add_driver(False, "vectorinit")
|
||||
print("Enable complete Unicode font: NO (because of the size)")
|
||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
||||
|
|
26
kernel/hw/3ds11/vectorinit/vectorinit.cpp
Normal file
26
kernel/hw/3ds11/vectorinit/vectorinit.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "vectorinit.hpp"
|
||||
extern "C" {
|
||||
extern uintptr_t branch_macro;
|
||||
void data_abort();
|
||||
void fast_irq();
|
||||
void normal_irq();
|
||||
void prefetch_abort();
|
||||
void svc_call();
|
||||
void undefined_op();
|
||||
}
|
||||
void initVectors() {
|
||||
uintptr_t *vectors = (uintptr_t *)0x1FFFFFA0;
|
||||
// branch_macro is a ldr pc, [pc,#-4], meaning it reads the following word as PC
|
||||
vectors[0] = branch_macro;
|
||||
vectors[1] = (uintptr_t)&normal_irq;
|
||||
vectors[2] = branch_macro;
|
||||
vectors[3] = (uintptr_t)&fast_irq;
|
||||
vectors[4] = branch_macro;
|
||||
vectors[5] = (uintptr_t)&svc_call;
|
||||
vectors[6] = branch_macro;
|
||||
vectors[7] = (uintptr_t)&undefined_op;
|
||||
vectors[8] = branch_macro;
|
||||
vectors[9] = (uintptr_t)&prefetch_abort;
|
||||
vectors[10] = branch_macro;
|
||||
vectors[11] = (uintptr_t)&data_abort;
|
||||
}
|
2
kernel/hw/3ds11/vectorinit/vectorinit.hpp
Normal file
2
kernel/hw/3ds11/vectorinit/vectorinit.hpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include <stdint.h>
|
||||
void initVectors();
|
|
@ -1,5 +1,6 @@
|
|||
config["ENABLE_EXTRA_MEMORY"] = get_yes_no("Enable 512KB of memory on n3DS", True)
|
||||
add_driver(True, "framebuffer")
|
||||
add_driver(False, "picafb")
|
||||
add_driver(False, "vectorinit")
|
||||
print("Enable complete Unicode font: NO (because of the size)")
|
||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
||||
|
|
26
kernel/hw/3ds9/vectorinit/vectorinit.cpp
Normal file
26
kernel/hw/3ds9/vectorinit/vectorinit.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "vectorinit.hpp"
|
||||
extern "C" {
|
||||
extern uintptr_t branch_macro;
|
||||
void data_abort();
|
||||
void fast_irq();
|
||||
void normal_irq();
|
||||
void prefetch_abort();
|
||||
void svc_call();
|
||||
void undefined_op();
|
||||
}
|
||||
void initVectors() {
|
||||
uintptr_t *vectors = (uintptr_t *)0x08000000;
|
||||
// branch_macro is a ldr pc, [pc,#-4], meaning it reads the following word as PC
|
||||
vectors[0] = branch_macro;
|
||||
vectors[1] = (uintptr_t)&normal_irq;
|
||||
vectors[2] = branch_macro;
|
||||
vectors[3] = (uintptr_t)&fast_irq;
|
||||
vectors[4] = branch_macro;
|
||||
vectors[5] = (uintptr_t)&svc_call;
|
||||
vectors[6] = branch_macro;
|
||||
vectors[7] = (uintptr_t)&undefined_op;
|
||||
vectors[8] = branch_macro;
|
||||
vectors[9] = (uintptr_t)&prefetch_abort;
|
||||
vectors[10] = branch_macro;
|
||||
vectors[11] = (uintptr_t)&data_abort;
|
||||
}
|
2
kernel/hw/3ds9/vectorinit/vectorinit.hpp
Normal file
2
kernel/hw/3ds9/vectorinit/vectorinit.hpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include <stdint.h>
|
||||
void initVectors();
|
35
kernel/hw/pc/idt/idt.cpp
Normal file
35
kernel/hw/pc/idt/idt.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include "idt.hpp"
|
||||
extern "C" void intr_stub_0();
|
||||
IDT_entry entries[256];
|
||||
void setIDTEntry(int i, void *entry) {
|
||||
uintptr_t p = (uintptr_t)entry;
|
||||
entries[i].offset0 = (uint16_t)p;
|
||||
p >>= 16;
|
||||
#ifndef __x86_64__
|
||||
entries[i].selector = 0x8;
|
||||
#else
|
||||
entries[i].selector = 0x28;
|
||||
#endif
|
||||
entries[i].zero = 0;
|
||||
entries[i].type = 0b1110;
|
||||
entries[i].storageSeg = false;
|
||||
entries[i].dpl = 3;
|
||||
entries[i].used = true;
|
||||
entries[i].offset1 = (uint16_t)p;
|
||||
p >>= 16;
|
||||
#ifdef __x86_64__
|
||||
entries[i].offset2 = (uint32_t)p;
|
||||
entries[i].zero2 = 0;
|
||||
#endif
|
||||
}
|
||||
void initIDT() {
|
||||
void *start_vectors = (void *)&intr_stub_0;
|
||||
for (int i = 0; i < 256; i++) setIDTEntry(i, start_vectors + 16 * i);
|
||||
struct {
|
||||
uint16_t size;
|
||||
uint32_t off;
|
||||
} __attribute__((packed)) idtr;
|
||||
idtr.size = sizeof(entries);
|
||||
idtr.off = (uint32_t)((uintptr_t)entries);
|
||||
asm volatile("lidt %0" : : "m"(idtr));
|
||||
}
|
20
kernel/hw/pc/idt/idt.hpp
Normal file
20
kernel/hw/pc/idt/idt.hpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
/**
|
||||
* Element of the interrupt descriptor table.
|
||||
*/
|
||||
struct IDT_entry {
|
||||
uint16_t offset0; ///< bits 0…15 of interrupt entry address
|
||||
uint16_t selector; ///< segment of the interrupt handler
|
||||
uint8_t zero; ///< has to be zero
|
||||
uint8_t type : 4; ///< Type of the interrupt
|
||||
bool storageSeg : 1; ///< 0 for interrupt gates (???)
|
||||
uint8_t dpl : 2; ///< Priviledge level required for calling this interrupt
|
||||
bool used : 1; ///< true if the entry is usable
|
||||
uint16_t offset1; ///< Bits 16…31 of the entrypoint
|
||||
#ifdef __x86_64__
|
||||
uint32_t offset2; ///< Bits 32…63 of the entrypoint. Only present on AMD64
|
||||
uint32_t zero2; ///< Must be zero. Only present on AMD64
|
||||
#endif
|
||||
} __attribute__((packed));
|
||||
void initIDT();
|
Loading…
Reference in a new issue