Adds initializer_list support to vector. Improves interrupt handler a bit. Adds support for IRQ-calls to vm integration.
This commit is contained in:
parent
2a5e3220d7
commit
cc72d4f366
6 changed files with 100 additions and 45 deletions
3
Makefile
3
Makefile
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
101
src/vm.cpp
101
src/vm.cpp
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue