Skip to content

Commit

Permalink
You can register interrupt handlers now
Browse files Browse the repository at this point in the history
  • Loading branch information
Twometer committed Dec 18, 2020
1 parent 7bd238d commit 740baad
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Nekofile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
;

; Constants
CCFLAGS = -std=gnu++11 -ffreestanding -mno-red-zone -fno-exceptions -nostdlib -Wall -Wextra -fno-pie -O2 -mgeneral-regs-only
CCFLAGS = -std=gnu++11 -ffreestanding -mno-red-zone -fno-exceptions -nostdlib -Wall -Wextra -fno-pie -fno-rtti -O2 -mgeneral-regs-only

; Tools
[asm, multi]:
Expand Down
19 changes: 11 additions & 8 deletions kernel/arch/interrupts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

using namespace Kernel;

nk::Vector<InterruptHandlerEntry> Interrupts::entries;

static const char *exception_descriptors[] = {
"Division by Zero",
"Debug",
Expand Down Expand Up @@ -62,8 +64,6 @@ extern "C"

void irq1_handler(void)
{
unsigned char scan_code = IO::In8(0x60);
Device::Keyboard::HandleInterrupt(scan_code);
Interrupts::HandleInterrupt(1);
master_eoi();
}
Expand Down Expand Up @@ -204,9 +204,6 @@ extern "C"

void Interrupts::SetupIdt()
{
/* remapping the PIC */
Device::PIC::Remap();

/* build table */
SetIdtEntry(0, TYPE_TRAP_GATE, (unsigned long)exc0);
SetIdtEntry(1, TYPE_TRAP_GATE, (unsigned long)exc1);
Expand Down Expand Up @@ -272,7 +269,7 @@ void Interrupts::Disable()
void Interrupts::SetIdtEntry(unsigned int interrupt, unsigned char type, unsigned long address)
{
IDT[interrupt].offset_lowerbits = address & 0xffff;
IDT[interrupt].selector = 0x08; /* KERNEL_CODE_SEGMENT_OFFSET */
IDT[interrupt].selector = 0x08; /* kernel code segment */
IDT[interrupt].zero = 0;
IDT[interrupt].type_attr = type;
IDT[interrupt].offset_higherbits = (address & 0xffff0000) >> 16;
Expand All @@ -295,9 +292,15 @@ void Interrupts::HandleException(unsigned int vector, struct interrupt_frame *fr

void Interrupts::HandleInterrupt(unsigned int interrupt)
{
for (int i = 0; i < entries.Size(); i++) {
InterruptHandlerEntry &entry = entries.At(i);
if (entry.interrupt == interrupt)
entry.handler->HandleInterrupt(interrupt);
}
}

void Interrupts::AddHandler(unsigned int interrupt, InterruptHandler handler)
void Interrupts::AddHandler(unsigned int interrupt, InterruptHandler *handler)
{

InterruptHandlerEntry entry = {interrupt, handler};
entries.Add(entry);
}
14 changes: 14 additions & 0 deletions kernel/device/devicemanager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <device/devicemanager.h>

using namespace Device;

Keyboard* DeviceManager::keyboard;
PIC* DeviceManager::pic;

void DeviceManager::Initialize() {
keyboard = new Keyboard();
keyboard->Initialize();

pic = new PIC();
pic->Remap();
}
9 changes: 6 additions & 3 deletions kernel/device/keyboard.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include <kernel/tty.h>
#include <kernel/interrupts.h>
#include <kernel/io.h>
#include <device/keyboard.h>

using namespace Kernel;
using namespace Device;

char Keyboard::scancode_map[128];

void Keyboard::Initialize()
{
for (int i = 0; i < 128; i++)
Expand Down Expand Up @@ -63,10 +63,13 @@ void Keyboard::Initialize()
NewScancode(53, '-');
NewScancode(57, ' ');

Interrupts::AddHandler(1, this);
}

void Keyboard::HandleInterrupt(unsigned int scancode)
void Keyboard::HandleInterrupt(unsigned int interrupt)
{
unsigned int scancode = IO::In8(0x60);

if (scancode > 128)
return;

Expand Down
2 changes: 1 addition & 1 deletion kernel/heap.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include <device/cpu.h>
#include <device/devicemanager.h>
#include <string.h>
extern "C"
{
Expand Down
5 changes: 5 additions & 0 deletions kernel/include/device/cpu.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#ifndef _CPU_H
#define _CPU_H

namespace Device
{

Expand All @@ -8,3 +11,5 @@ namespace Device
};

} // namespace Device

#endif
23 changes: 23 additions & 0 deletions kernel/include/device/devicemanager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef _DEVICEMANAGER_H
#define _DEVICEMANAGER_H

#include "cpu.h"
#include "keyboard.h"
#include "pic.h"

namespace Device
{

class DeviceManager
{
public:
static Keyboard *keyboard;

static PIC *pic;

static void Initialize();
};

} // namespace Device

#endif
22 changes: 14 additions & 8 deletions kernel/include/device/keyboard.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
#ifndef _KEYBOARD_H
#define _KEYBOARD_H

#include <kernel/interrupts.h>

namespace Device
{
class Keyboard
class Keyboard : public Kernel::InterruptHandler
{
private:
static char scancode_map[128];
char scancode_map[128];

public:
static void Initialize();
void Initialize();

static void HandleInterrupt(unsigned int scancode);
void HandleInterrupt(unsigned int interrupt) override;

private:
static void NewScancode(unsigned int code, char c);

static char MapChar(unsigned int scancode);
void NewScancode(unsigned int code, char c);
char MapChar(unsigned int scancode);
};
} // namespace Device
} // namespace Device

#endif
7 changes: 6 additions & 1 deletion kernel/include/device/pic.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#ifndef _PIC_H
#define _PIC_H

namespace Device
{

class PIC
{
public:
static void Remap();
void Remap();
};

} // namespace Device

#endif
5 changes: 5 additions & 0 deletions kernel/include/kernel/heap.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#ifndef _HEAP_H
#define _HEAP_H

#include <stddef.h>
#include <stdint.h>

Expand All @@ -14,4 +17,6 @@ extern "C"

#ifdef __cplusplus
}
#endif

#endif
22 changes: 19 additions & 3 deletions kernel/include/kernel/interrupts.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#ifndef _INTERRUPTS_H
#define _INTERRUPTS_H

#include <nk/vector.h>

struct IDT_entry
{
Expand All @@ -21,11 +25,21 @@ namespace Kernel
{
class InterruptHandler
{
virtual void Handle(unsigned int interrupt);
public:
virtual void HandleInterrupt(unsigned int interrupt) = 0;
};

struct InterruptHandlerEntry
{
unsigned int interrupt;
InterruptHandler *handler;
};

class Interrupts
{
private:
static nk::Vector<InterruptHandlerEntry> entries;

public:
static void SetupIdt();

Expand All @@ -39,7 +53,9 @@ namespace Kernel

static void HandleInterrupt(unsigned int interrupt);

static void AddHandler(unsigned int interrupt, InterruptHandler handler);
static void AddHandler(unsigned int interrupt, InterruptHandler *handler);
};

}; // namespace Kernel
}; // namespace Kernel

#endif
14 changes: 8 additions & 6 deletions kernel/kernel.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include <kernel/tty.h>
#include <kernel/heap.h>
#include <kernel/interrupts.h>
#include <device/keyboard.h>
#include <device/cpu.h>
#include <device/devicemanager.h>
#include <stdio.h>

using namespace Kernel;
using namespace Device;

/* nekosys Kernel entry point */
extern "C" void nkmain() {
Expand All @@ -15,16 +15,18 @@ extern "C" void nkmain() {
printf("nekosys 0.01 <by Twometer>\n");
TTY::SetColor(0x0f);

printf("Initializing heap...\n");
heap_init();

printf("Initializing devices...\n");
DeviceManager::Initialize();

// Set up environment
printf("Setting up interrupts...\n");
Interrupts::Disable();
Interrupts::SetupIdt();
Interrupts::Enable();

printf("Registering devices...\n");
Device::Keyboard::Initialize();
heap_init();

// Dummy terminal
printf("Initialized.\n\n");
printf("$ ");
Expand Down
27 changes: 27 additions & 0 deletions libc/cpplib.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <stddef.h>
#include <stdlib.h>

extern "C" void __cxa_pure_virtual()
{
// Do nothing or print an error message.
}

void *operator new(size_t size)
{
return malloc(size);
}

void *operator new[](size_t size)
{
return malloc(size);
}

void operator delete(void *p)
{
free(p);
}

void operator delete[](void *p)
{
free(p);
}
Loading

0 comments on commit 740baad

Please sign in to comment.