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
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
# asm/dynamic.S

View file

@ -2,6 +2,7 @@
#include <inttypes.h>
#include <stddef.h>
#include <initializer_list>
#if defined(CIRCUIT_OS)
#include "kstdlib.h"
@ -56,6 +57,15 @@ namespace ker
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)
{
this->resize(other.mLength);

View file

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

View file

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

View file

@ -7,6 +7,8 @@
#include <vmtype.hpp>
#include <types/vmprimitivetype.hpp>
#include <interrupts.h>
extern "C" {
extern const char mainscript_start;
extern const char mainscript_end;
@ -56,15 +58,6 @@ struct dtortest {
~dtortest() { free(mem); }
};
extern "C" void vm_start()
{
/*
}
void code()
{
//*/
struct {
const char *ptr;
@ -74,41 +67,81 @@ void code()
(uint32_t)&mainscript_size
};
VirtualMachine vm;
vm.import("print") = printArguments;
struct IrqList {
static const size_t length = 64;
volatile uint32_t read;
volatile uint32_t write;
CpuState items[IrqList::length];
} irqFiFo {
0, 0, {}
};
Assembly *assembly = vm.load(mainAssembly.ptr, mainAssembly.size);
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.");
}
}
extern "C" void vm_start()
{
intr_set_handler(0x20, vm_handle_interrupt);
intr_set_handler(0x21, vm_handle_interrupt);
VirtualMachine machine;
machine.import("print") = printArguments;
Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size);
if(assembly == nullptr) {
kprintf("failed to load assembly :(\n");
return;
}
/*
kprintf("Assembly:\n");
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) {
Process *irqService = machine.createProcess(assembly, true);
if(irqService == nullptr) {
kprintf("Failed to create process.\n");
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
}
process->release();
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);
}
irqService->release();
irqService = nullptr;
assembly->release();
kprintf("\n");

View file

@ -54,10 +54,12 @@ DISTFILES += \
README.md \
scripts/main.spark
INCLUDEPATH += include
DEPENDPATH += include
INCLUDEPATH += $$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