started adding IRQ and clock sources. non-pc target are broken

This commit is contained in:
Morten Delenk 2017-07-24 11:23:05 +01:00
parent bc5bf258a0
commit cf16b1c37c
15 changed files with 171 additions and 15 deletions

View file

@ -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");
} }

View file

@ -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");
} }

View file

@ -14,5 +14,5 @@ void drivers_init() {
setMainTTY(&term); setMainTTY(&term);
--term; --term;
initVectors(); initVectors();
asm volatile("svc #0"); asm volatile("CPSIE aif");
} }

View file

@ -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;

View file

@ -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");
} }

View file

@ -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");
} }

View file

@ -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;
}

View file

@ -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);
};

View file

@ -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;
}

View file

@ -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);
};

View file

@ -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); }

View file

@ -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.

View 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
View 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) {};

View file

@ -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)();
} }