Adds initializer_list support to vector. Improves interrupt handler a bit. Adds support for IRQ-calls to vm integration.

This commit is contained in:
Felix Queißner 2015-10-07 21:27:38 +02:00
parent 2a5e3220d7
commit cc72d4f366
6 changed files with 100 additions and 45 deletions

View file

@ -96,7 +96,8 @@ obj/cpp-test.o: src/cpp-test.cpp include/console.h include/ker/string.hpp \
# src/vm.cpp # src/vm.cpp
obj/vm.o: src/vm.cpp include/kstdlib.h include/varargs.h include/config.h \ obj/vm.o: src/vm.cpp include/kstdlib.h include/varargs.h include/config.h \
include/malloc.h include/timer.h include/dynamic.h include/console.h include/malloc.h include/timer.h include/dynamic.h include/console.h \
include/interrupts.h include/cpustate.h
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp $(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp
# asm/dynamic.S # asm/dynamic.S

View file

@ -2,6 +2,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <stddef.h> #include <stddef.h>
#include <initializer_list>
#if defined(CIRCUIT_OS) #if defined(CIRCUIT_OS)
#include "kstdlib.h" #include "kstdlib.h"
@ -56,6 +57,15 @@ namespace ker
other.mReserved = 0; other.mReserved = 0;
} }
Vector(const std::initializer_list<T> &init) :
Vector()
{
this->reserve(init.size());
for(auto & value : init) {
this->append(value);
}
}
Vector & operator = (const Vector &other) Vector & operator = (const Vector &other)
{ {
this->resize(other.mLength); this->resize(other.mLength);

View file

@ -26,4 +26,16 @@ _loop:
jmp _loop jmp _loop
_end: _end:
; Our OS should not end.
jmp _end
ret
irq:
pusht "Hello IRQ: "
load -1
pusht ", "
load -2
pusht "\n"
calln print 5
ret ret

View file

@ -80,11 +80,12 @@ void intr_routine(CpuState *state)
if(state->intr < interruptNameCount) if(state->intr < interruptNameCount)
name = interruptNames[state->intr]; name = interruptNames[state->intr];
InterruptHandler handler = handlers[state->intr]; InterruptHandler handler = handlers[state->intr];
if(handler != nullptr) {
handler(state);
}
if(state->intr < 0x20) if(state->intr < 0x20)
{ {
if(handler != nullptr) { if(handler == nullptr) {
handler(state);
} else {
kprintf("\n\x12\x04 Exception [%d] %s!\x12\0x07 \n", state->intr, name); kprintf("\n\x12\x04 Exception [%d] %s!\x12\0x07 \n", state->intr, name);
kprintf( kprintf(
"EIP: %x" "EIP: %x"
@ -98,9 +99,7 @@ void intr_routine(CpuState *state)
} }
if (state->intr >= 0x20 && state->intr <= 0x2f) if (state->intr >= 0x20 && state->intr <= 0x2f)
{ {
if(handler != nullptr) { if(handler == nullptr) {
handler(state);
} else {
kprintf("[Unhandled IRQ: %d]", state->intr); kprintf("[Unhandled IRQ: %d]", state->intr);
} }
@ -114,9 +113,7 @@ void intr_routine(CpuState *state)
} }
else else
{ {
if(handler != nullptr) { if(handler == nullptr) {
handler(state);
} else {
kprintf("\n\x12\x04Interrupt [%d] %s occurred!\x12\0x7\n", state->intr, name); kprintf("\n\x12\x04Interrupt [%d] %s occurred!\x12\0x7\n", state->intr, name);
while(1) while(1)
{ {

View file

@ -7,6 +7,8 @@
#include <vmtype.hpp> #include <vmtype.hpp>
#include <types/vmprimitivetype.hpp> #include <types/vmprimitivetype.hpp>
#include <interrupts.h>
extern "C" { extern "C" {
extern const char mainscript_start; extern const char mainscript_start;
extern const char mainscript_end; extern const char mainscript_end;
@ -56,59 +58,90 @@ struct dtortest {
~dtortest() { free(mem); } ~dtortest() { free(mem); }
}; };
extern "C" void vm_start()
{
/* struct {
const char *ptr;
uint32_t size;
} mainAssembly {
&mainscript_start,
(uint32_t)&mainscript_size
};
struct IrqList {
static const size_t length = 64;
volatile uint32_t read;
volatile uint32_t write;
CpuState items[IrqList::length];
} irqFiFo {
0, 0, {}
};
extern "C" void vm_handle_interrupt(CpuState *state)
{
irqFiFo.items[irqFiFo.write] = *state;
irqFiFo.write += 1;
if(irqFiFo.write >= irqFiFo.length) {
// TODO: Don't die
die("irqList overflow.");
}
} }
void code() extern "C" void vm_start()
{ {
//*/ intr_set_handler(0x20, vm_handle_interrupt);
intr_set_handler(0x21, vm_handle_interrupt);
struct { VirtualMachine machine;
const char *ptr; machine.import("print") = printArguments;
uint32_t size;
} mainAssembly {
&mainscript_start,
(uint32_t)&mainscript_size
};
VirtualMachine vm; Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size);
vm.import("print") = printArguments;
Assembly *assembly = vm.load(mainAssembly.ptr, mainAssembly.size);
if(assembly == nullptr) { if(assembly == nullptr) {
kprintf("failed to load assembly :(\n"); kprintf("failed to load assembly :(\n");
return; return;
} }
/* Process *irqService = machine.createProcess(assembly, true);
kprintf("Assembly:\n"); if(irqService == nullptr) {
kprintf(" Name: %s\n", assembly->name().str());
kprintf(" Author: %s\n", assembly->author().str());
kprintf(" Description: %s\n", assembly->description().str());
//*/
/*
kprintf("Type list:\n");
for(const auto &type : vm.types()) {
kprintf("%s: %x\n", type.first.str(), vm.type(type.first));
}
//*/
Process *process = vm.createProcess(assembly);
if(process == nullptr) {
kprintf("Failed to create process.\n"); kprintf("Failed to create process.\n");
return; return;
} }
uint32_t irqRoutine = irqService->assembly()->exports()["irq"];
while(vm.step()) while(machine.step())
{ {
// kprintf("."); // check for IRQ requests
do
{
// atomic checking for existing IRQ item
irq_disable();
bool hasItem = (irqFiFo.read < irqFiFo.write);
irq_enable();
if(hasItem == false) {
break; // we don't have anything to read
}
CpuState *cpu = &irqFiFo.items[irqFiFo.read];
auto *thread = irqService->createThread(irqRoutine);
thread->start({ VMValue::Int32(cpu->intr), VMValue::Int32(cpu->eip) });
irqFiFo.read += 1;
irq_disable();
// When fifo is emptied, reset list pointers
if(irqFiFo.read == irqFiFo.write) {
irqFiFo.read = 0;
irqFiFo.write = 0;
}
irq_enable();
} while(true);
} }
process->release(); irqService->release();
irqService = nullptr;
assembly->release(); assembly->release();
kprintf("\n"); kprintf("\n");

View file

@ -54,10 +54,12 @@ DISTFILES += \
README.md \ README.md \
scripts/main.spark scripts/main.spark
INCLUDEPATH += include
DEPENDPATH += include
INCLUDEPATH += $$quote("/home/felix/projects/Electronics/Electronics/Conductance") INCLUDEPATH += $$quote("/home/felix/projects/Electronics/Electronics/Conductance")
DEPENDPATH += $$quote("/home/felix/projects/Electronics/Electronics/Conductance") DEPENDPATH += $$quote("/home/felix/projects/Electronics/Electronics/Conductance")
QMAKE_INCDIR =
QMAKE_CFLAGS = -m32 -Dnullptr=0 -std=c11 -Wall -fno-stack-protector -ffreestanding QMAKE_CFLAGS = -m32 -Dnullptr=0 -std=c11 -Wall -fno-stack-protector -ffreestanding