started adding IRQ and clock sources. non-pc target are broken
This commit is contained in:
parent
bc5bf258a0
commit
cf16b1c37c
15 changed files with 171 additions and 15 deletions
|
@ -14,5 +14,7 @@ void drivers_init() {
|
||||||
setMainTTY(&term);
|
setMainTTY(&term);
|
||||||
--term;
|
--term;
|
||||||
initVectors();
|
initVectors();
|
||||||
asm volatile("svc #0");
|
*((volatile uint32_t*)0x17E00600)=67108;
|
||||||
|
*((volatile uint32_t*)0x17E00608=3;
|
||||||
|
asm volatile("CPSIE aif");
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,10 @@ void drivers_init() {
|
||||||
setMainTTY(&term);
|
setMainTTY(&term);
|
||||||
--term;
|
--term;
|
||||||
initVectors();
|
initVectors();
|
||||||
asm volatile("svc #0");
|
//Init 1000Hz timer
|
||||||
|
*((volatile uint16_t*)0x10003002)=0;
|
||||||
|
*((volatile uint16_t*)0x10003000)=65;
|
||||||
|
*((volatile uint16_t*)0x10003002)=0b11000011;
|
||||||
|
*((volatile uint32_t*)0x10001000)|=1<<8;
|
||||||
|
asm volatile("CPSIE aif");
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,5 +14,5 @@ void drivers_init() {
|
||||||
setMainTTY(&term);
|
setMainTTY(&term);
|
||||||
--term;
|
--term;
|
||||||
initVectors();
|
initVectors();
|
||||||
asm volatile("svc #0");
|
asm volatile("CPSIE aif");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "../../hw/pc/8259/pic.hpp"
|
#include "../../hw/pc/8259/pic.hpp"
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <regs.h>
|
#include <regs.h>
|
||||||
|
#include <irq.hpp>
|
||||||
void print_regdump(cpu_state *state) {
|
void print_regdump(cpu_state *state) {
|
||||||
(*out << "eax: ").puti(state->eax);
|
(*out << "eax: ").puti(state->eax);
|
||||||
(*out << " ebx: ").puti(state->ebx);
|
(*out << " ebx: ").puti(state->ebx);
|
||||||
|
@ -18,14 +19,17 @@ extern "C" cpu_state *handleINT(cpu_state *state) {
|
||||||
*out << "Interrupt ";
|
*out << "Interrupt ";
|
||||||
out->puti(state->intr);
|
out->puti(state->intr);
|
||||||
*out << " occurred!\n";
|
*out << " occurred!\n";
|
||||||
|
cpu_state *new_cpu=state;
|
||||||
if (state->intr < 32) {
|
if (state->intr < 32) {
|
||||||
out->setColor(Color::RED);
|
out->setColor(Color::RED);
|
||||||
print_regdump(state);
|
print_regdump(state);
|
||||||
*out << "KERNEL PANIC: Unhandled CPU exception\n";
|
*out << "KERNEL PANIC: Unhandled CPU exception\n";
|
||||||
for (;;)
|
for (;;)
|
||||||
;
|
;
|
||||||
|
} else if(state->intr < 48) {
|
||||||
|
new_cpu=(cpu_state*)irqs->handleIRQ(new_cpu);
|
||||||
}
|
}
|
||||||
return state;
|
return new_cpu;
|
||||||
}
|
}
|
||||||
extern "C" void panic2(cpu_state *state) {
|
extern "C" void panic2(cpu_state *state) {
|
||||||
state->esp = (uintptr_t)state;
|
state->esp = (uintptr_t)state;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../../../hw/pc/8259/pic.hpp"
|
#include "../../../hw/pc/8259/pic.hpp"
|
||||||
#include "../../../hw/pc/idt/idt.hpp"
|
#include "../../../hw/pc/idt/idt.hpp"
|
||||||
#include "../../../hw/pc/pmm/pmm.hpp"
|
#include "../../../hw/pc/pmm/pmm.hpp"
|
||||||
|
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
static multiboot_info_t *mb_info;
|
static multiboot_info_t *mb_info;
|
||||||
#ifndef ENABLE_FRAMEBUFFER
|
#ifndef ENABLE_FRAMEBUFFER
|
||||||
|
@ -28,5 +29,4 @@ void drivers_init() {
|
||||||
initIDT();
|
initIDT();
|
||||||
PIC::initPIC(0x20, 0x28);
|
PIC::initPIC(0x20, 0x28);
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
asm volatile("int $0x20");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,5 +29,4 @@ void drivers_init() {
|
||||||
initIDT();
|
initIDT();
|
||||||
PIC::initPIC(0x20, 0x28);
|
PIC::initPIC(0x20, 0x28);
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
asm volatile("int $32");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,3 +24,33 @@ void initVectors() {
|
||||||
vectors[10] = branch_macro;
|
vectors[10] = branch_macro;
|
||||||
vectors[11] = (uintptr_t)&data_abort;
|
vectors[11] = (uintptr_t)&data_abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IRQ_IO::IRQ_IO() {
|
||||||
|
*((volatile uint32_t*)0x17E00100)=1;
|
||||||
|
*((volatile uint32_t*)0x17E00104)=0xF0;
|
||||||
|
for(int i=0;i<32;i+=4) {
|
||||||
|
*((volatile uint32_t*)(0x7E01100+i))=~0;
|
||||||
|
}
|
||||||
|
uint32_t intid;
|
||||||
|
while((intid=*((volatile uint32_t*)0x7E00118))!=1023) {
|
||||||
|
*((volatile uint32_t*)0x7E00110)=intid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IRQ_IO::~IRQ_IO() {}
|
||||||
|
|
||||||
|
void IRQ_IO::handleIRQ(void *data) {
|
||||||
|
uint32_t interrupt=*((volatile uint32_t*)0x7E0010C);
|
||||||
|
int intid = interrupt & 255;
|
||||||
|
data = handlers[intid](data);
|
||||||
|
*((volatile uint32_t*)0x7E00110) = interrupt;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRQ_IO::mask(int number) {}
|
||||||
|
void IRQ_IO::unmask(int number) {}
|
||||||
|
|
||||||
|
static IRQ_IO irq;
|
||||||
|
__attribute__((constructor))
|
||||||
|
static void init_irq() {
|
||||||
|
irqs = (IRQ*)&irq;
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +1,12 @@
|
||||||
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <irq.hpp>
|
||||||
void initVectors();
|
void initVectors();
|
||||||
|
|
||||||
|
struct IRQ_IO {
|
||||||
|
IRQ_IO();
|
||||||
|
virtual ~IRQ_IO();
|
||||||
|
virtual void* handleIRQ(void *data);
|
||||||
|
virtual void mask(int number);
|
||||||
|
virtual void unmask(int number);
|
||||||
|
};
|
||||||
|
|
|
@ -9,8 +9,6 @@ void svc_call();
|
||||||
void undefined_op();
|
void undefined_op();
|
||||||
void flushAll();
|
void flushAll();
|
||||||
}
|
}
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC optimize("O0")
|
|
||||||
void initVectors() {
|
void initVectors() {
|
||||||
uintptr_t *vectors = (uintptr_t *)0x08000000;
|
uintptr_t *vectors = (uintptr_t *)0x08000000;
|
||||||
// branch_macro is a ldr pc, [pc,#-4], meaning it reads the following word as PC
|
// branch_macro is a ldr pc, [pc,#-4], meaning it reads the following word as PC
|
||||||
|
@ -28,4 +26,31 @@ void initVectors() {
|
||||||
vectors[11] = (uintptr_t)&data_abort;
|
vectors[11] = (uintptr_t)&data_abort;
|
||||||
flushAll();
|
flushAll();
|
||||||
}
|
}
|
||||||
#pragma GCC pop_options
|
|
||||||
|
IRQ_IO::IRQ_IO() {
|
||||||
|
*((volatile uint32_t*)0x10001000)=~0;
|
||||||
|
*((volatile uint32_t*)0x10001004)=0;
|
||||||
|
}
|
||||||
|
IRQ_IO::~IRQ_IO() {}
|
||||||
|
|
||||||
|
void* IRQ_IO::handleIRQ(void *data) {
|
||||||
|
//Call IRQ handlers until all IRQs are done.
|
||||||
|
int bit;
|
||||||
|
while(bit=__builtin_ffs(*((volatile int*)0x10001004))) {
|
||||||
|
data = handlers[bit-1](data);
|
||||||
|
*((volatile int*)0x10001004)&=~(1<<(bit-1));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRQ_IO::mask(int number) {
|
||||||
|
*((volatile int*)0x10001004)&=~(1<<number);
|
||||||
|
}
|
||||||
|
void IRQ_IO::unmask(int number) {
|
||||||
|
*((volatile int*)0x10001004)|=1<<number;
|
||||||
|
}
|
||||||
|
static IRQ_IO irq;
|
||||||
|
__attribute__((constructor))
|
||||||
|
static void init_irq() {
|
||||||
|
irqs = (IRQ*)&irq;
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +1,12 @@
|
||||||
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <irq.hpp>
|
||||||
void initVectors();
|
void initVectors();
|
||||||
|
|
||||||
|
struct IRQ_IO {
|
||||||
|
IRQ_IO();
|
||||||
|
virtual ~IRQ_IO();
|
||||||
|
virtual void* handleIRQ(void *data);
|
||||||
|
virtual void mask(int number);
|
||||||
|
virtual void unmask(int number);
|
||||||
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "pic.hpp"
|
#include "pic.hpp"
|
||||||
#include "../io.hpp"
|
#include "../io.hpp"
|
||||||
|
#include <regs.h>
|
||||||
#define PIC1 0x20
|
#define PIC1 0x20
|
||||||
#define PIC2 0xA0
|
#define PIC2 0xA0
|
||||||
#define PIC1_COMMAND PIC1
|
#define PIC1_COMMAND PIC1
|
||||||
|
@ -19,6 +20,33 @@
|
||||||
#define ICW4_BUF_SLAVE 0x04
|
#define ICW4_BUF_SLAVE 0x04
|
||||||
#define ICW4_BUF_MASTER 0x0C
|
#define ICW4_BUF_MASTER 0x0C
|
||||||
#define ICW4_SFNM 0x10
|
#define ICW4_SFNM 0x10
|
||||||
|
IRQ_PIC::IRQ_PIC() {
|
||||||
|
PIC::initPIC(0x20, 0x28);
|
||||||
|
}
|
||||||
|
IRQ_PIC::~IRQ_PIC() {
|
||||||
|
PIC::disable();
|
||||||
|
}
|
||||||
|
void* IRQ_PIC::handleIRQ(void *data) {
|
||||||
|
cpu_state* cpu = (cpu_state*)data;
|
||||||
|
auto val = handlers[cpu->intr-0x20](data);
|
||||||
|
PIC::sendEOI(cpu->intr > 0x27);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
void IRQ_PIC::mask(int number) {
|
||||||
|
PIC::mask(number);
|
||||||
|
}
|
||||||
|
void IRQ_PIC::unmask(int number) {
|
||||||
|
PIC::unmask(number);
|
||||||
|
}
|
||||||
|
static IRQ_PIC irqpic;
|
||||||
|
__attribute__((constructor))
|
||||||
|
static void initIRQ() {
|
||||||
|
irqs = &irqpic;
|
||||||
|
//Init pic
|
||||||
|
out<uint8_t>(0x43, 0x34);
|
||||||
|
out<uint8_t>(0x40, 156);
|
||||||
|
out<uint8_t>(0x40, 46);
|
||||||
|
}
|
||||||
namespace PIC {
|
namespace PIC {
|
||||||
auto sendEOI(bool slave) -> void {
|
auto sendEOI(bool slave) -> void {
|
||||||
if (slave) { out<unsigned char>(PIC2_COMMAND, PIC_EOI); }
|
if (slave) { out<unsigned char>(PIC2_COMMAND, PIC_EOI); }
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <irq.hpp>
|
||||||
|
struct IRQ_PIC: IRQ {
|
||||||
|
IRQ_PIC();
|
||||||
|
virtual ~IRQ_PIC();
|
||||||
|
virtual void* handleIRQ(void *data);
|
||||||
|
virtual void mask(int number);
|
||||||
|
virtual void unmask(int number);
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Namespace contains function to control the Programmable Interrupt Controller
|
* Namespace contains function to control the Programmable Interrupt Controller
|
||||||
*/
|
*/
|
||||||
|
@ -7,8 +15,8 @@ namespace PIC {
|
||||||
auto sendEOI(bool slave) -> void; ///< Signals the PIC that the interrupt has ended
|
auto sendEOI(bool slave) -> void; ///< Signals the PIC that the interrupt has ended
|
||||||
auto initPIC(int off1, int off2) -> void; ///< Initializes the pic/remaps it
|
auto initPIC(int off1, int off2) -> void; ///< Initializes the pic/remaps it
|
||||||
auto disable() -> void; ///< disables PIC completely
|
auto disable() -> void; ///< disables PIC completely
|
||||||
auto maskIRQ(int no) -> void; ///< disables a single IRQ
|
auto mask(int no) -> void; ///< disables a single IRQ
|
||||||
auto unmaskIRQ(int no) -> void; ///< reenables a single IRQ
|
auto unmask(int no) -> void; ///< reenables a single IRQ
|
||||||
auto disableSlave() -> void; ///< disables IRQ2 and 8-15
|
auto disableSlave() -> void; ///< disables IRQ2 and 8-15
|
||||||
auto enableSlave() -> void; ///< reenables at least IRQ2
|
auto enableSlave() -> void; ///< reenables at least IRQ2
|
||||||
auto isSpurious(bool slave) -> bool; ///< Return if this isn't an actual IRQ.
|
auto isSpurious(bool slave) -> bool; ///< Return if this isn't an actual IRQ.
|
||||||
|
|
26
kernel/src/include/irq.hpp
Normal file
26
kernel/src/include/irq.hpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
#include "../../../config.h"
|
||||||
|
constexpr int same_string(char const* lhs, char const* rhs) {
|
||||||
|
return !__builtin_strcmp(lhs, rhs);
|
||||||
|
}
|
||||||
|
constexpr int get_max_irq() {
|
||||||
|
if constexpr(same_string(ARCH, "x86") || same_string(ARCH, "x86_64")) {
|
||||||
|
return 32;
|
||||||
|
} else if constexpr(same_string(SYSTEM, "3ds9")) {
|
||||||
|
return 30;
|
||||||
|
} else if constexpr(same_string(SYSTEM, "3ds11")) {
|
||||||
|
return 256;
|
||||||
|
} else {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define MAX_IRQ get_max_irq()
|
||||||
|
struct IRQ {
|
||||||
|
void*(*handlers[MAX_IRQ])(void*);
|
||||||
|
IRQ();
|
||||||
|
virtual ~IRQ();
|
||||||
|
virtual void* handleIRQ(void *data);
|
||||||
|
virtual void mask(int number);
|
||||||
|
virtual void unmask(int number);
|
||||||
|
};
|
||||||
|
extern IRQ *irqs;
|
12
kernel/src/irq.cpp
Normal file
12
kernel/src/irq.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include <irq.hpp>
|
||||||
|
IRQ *irqs;
|
||||||
|
static void* do_nothing(void *a) {return a;}
|
||||||
|
IRQ::IRQ() {
|
||||||
|
for(int i=0;i<MAX_IRQ;i++)
|
||||||
|
handlers[i]=&do_nothing;
|
||||||
|
}
|
||||||
|
IRQ::~IRQ() {}
|
||||||
|
void* IRQ::handleIRQ(void *data) {return data;}
|
||||||
|
|
||||||
|
void IRQ::mask(int number) {};
|
||||||
|
void IRQ::unmask(int number) {};
|
|
@ -12,9 +12,6 @@ void main() {
|
||||||
drivers_init();
|
drivers_init();
|
||||||
*out << "Hello!\n";
|
*out << "Hello!\n";
|
||||||
*out << "テスト\n";
|
*out << "テスト\n";
|
||||||
while(true) {
|
for(;;);
|
||||||
out->puti((*pmm, 1));
|
|
||||||
*out << "\n";
|
|
||||||
}
|
|
||||||
for (auto dtor = &start_dtors; dtor != &end_dtors; dtor++) (**dtor)();
|
for (auto dtor = &start_dtors; dtor != &end_dtors; dtor++) (**dtor)();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue