Compare commits

..

No commits in common. '6951311c9c533ad5e86383278ca9b166ac9ed5b1' and '9ffd22e9412d8f8a3637fda6c42f59e4f31cea9c' have entirely different histories.

@ -69,8 +69,7 @@ enum Vector {
// Interrupts // Interrupts
KEYBOARD=32, KEYBOARD=32,
PANIC=33, PANIC=33,
TIMER=34, TIMER=34
ASSASSIN=35
}; };
constexpr size_t VECTORS = 256; constexpr size_t VECTORS = 256;

@ -129,23 +129,21 @@ void set(uint32_t counter, uint8_t divide, uint8_t vector, bool periodic,
LAPIC::write(TIMER_DIVIDE_CONFIGURATION, getClockDiv(divide)); LAPIC::write(TIMER_DIVIDE_CONFIGURATION, getClockDiv(divide));
LAPIC::write(TIMER_INITIAL_COUNTER, counter); LAPIC::write(TIMER_INITIAL_COUNTER, counter);
} }
uint64_t time_tick;
uint8_t dividender;
bool setup(uint32_t us) { bool setup(uint32_t us) {
time_tick = (static_cast<uint64_t>(ticks()) * us) / 1000ULL; uint64_t timer_ticks = (static_cast<uint64_t>(ticks()) * us) / 1000ULL;
dividender = 1; uint8_t divisor = 1;
while (time_tick > UINT32_MAX) { while (timer_ticks > UINT32_MAX) {
// While timer_ticks is to large to fit in 32bits. // While timer_ticks is to large to fit in 32bits.
time_tick >>= 1; timer_ticks >>= 1;
dividender <<= 1; divisor <<= 1;
} }
if (dividender > 128) if (divisor > 128)
return false; // Timer interval is to large. return false; // Timer interval is to large.
// Setup Masked interrupts to effectively disable the timer. // Setup Masked interrupts to effectively disable the timer.
set(static_cast<uint32_t>(timer_ticks), divisor, Core::Interrupt::TIMER, true, true);
return true; return true;
} }
@ -158,15 +156,15 @@ uint32_t interval() {
} }
void activate() { void activate() {
uint32_t timer_ticks = LAPIC::read(TIMER_INITIAL_COUNTER);
// Disable Counter to avoid spouriose interrupts. // Disable Counter to avoid spouriose interrupts.
LAPIC::write(TIMER_INITIAL_COUNTER, 0); LAPIC::write(TIMER_INITIAL_COUNTER, 0);
set(static_cast<uint32_t>(time_tick), dividender, Core::Interrupt::TIMER, true, true);
// Activate Timer interrupts. // Activate Timer interrupts.
setMasked(false); setMasked(false);
// enable counter with correct value. // enable counter with correct value.
LAPIC::write(TIMER_INITIAL_COUNTER, time_tick); LAPIC::write(TIMER_INITIAL_COUNTER, timer_ticks);
} }
void setMasked(bool masked) { void setMasked(bool masked) {

@ -3,7 +3,6 @@
#include "../arch/system.h" #include "../arch/system.h"
#include "../arch/core_interrupt.h" #include "../arch/core_interrupt.h"
#include "../arch/ioport.h" #include "../arch/ioport.h"
#include "../arch/ioapic.h"
#include "../compiler/fix.h" #include "../compiler/fix.h"
#include "../debug/output.h" #include "../debug/output.h"
#include "keydecoder.h" #include "keydecoder.h"
@ -107,10 +106,6 @@ void init() {
// Set to maximum speed & minimum delay // Set to maximum speed & minimum delay
setRepeatRate(SPEED_30_0CPS, DELAY_250MS); setRepeatRate(SPEED_30_0CPS, DELAY_250MS);
IOAPIC::config(1, Core::Interrupt::KEYBOARD);
IOAPIC::allow(1);
PS2Controller::drainBuffer();
} }
bool fetch(Key &pressed) { bool fetch(Key &pressed) {

@ -1,23 +1,17 @@
#include "epilogues.h" #include "epilogues.h"
#include "../debug/output.h" #include "../debug/output.h"
#include "../arch/core.h"
#include "../arch/lapic.h"
#include "guard.h" #include "guard.h"
#include "../thread/scheduler.h" #include "../thread/scheduler.h"
extern Key kout_key; extern Key kout_key;
#include "../user/app1/appl.h"
extern Application application1;
namespace Epilogues { namespace Epilogues {
void keyboard(Vault& v) { void keyboard(Vault& v) {
v.kout.setPos(0,0); v.kout.setPos(0,0);
v.kout << kout_key.ascii() << flush ; v.kout << kout_key.ascii() << flush ;
if(kout_key.scancode == Key::KEY_K)
v.sch.kill(v.sch.dispatcher.lifePointer[3]);
} }
void timer(Vault& v) { void timer(Vault& v) {
@ -25,17 +19,15 @@ void timer(Vault& v) {
int x, y; int x, y;
if(Core::getID() == 0) { if(Core::getID() == 0) {
v.kout.getPos(x, y); v.kout.getPos(x, y);
v.kout.setPos(65, 0); v.kout.setPos(65U, 0U);
v.kout << counter++ << flush; v.kout << counter++ << " " << flush;
v.kout.setPos(x, y); v.kout.setPos(x, y);
} }
DBG << "timer C:" << dec << Core::getID() << " L:" << LAPIC::getID() << "\n" << flush;
v.sch.resume(true); v.sch.resume(true);
} }
void assassin(Vault& v) { void assassin(Vault& v) {
DBG << "assassin epilog\n"<< endl;
if (v.sch.active()->kill_flag) { if (v.sch.active()->kill_flag) {
v.sch.exit(); v.sch.exit();
} }

@ -1,4 +1,5 @@
#include "guard.h" #include "guard.h"
#include "../arch/core.h" #include "../arch/core.h"
#include "../debug/output.h" #include "../debug/output.h"
#include "../object/bbuffer.h" #include "../object/bbuffer.h"
@ -23,11 +24,9 @@ Vault::Vault() {
Guarded::~Guarded() { Guard::leave(); } Guarded::~Guarded() { Guard::leave(); }
Guarded Guard::enter() { Guarded Guard::enter() {
bool status = Core::Interrupt::disable();
epi_flag FOR_CURRENT_CORE = true; epi_flag FOR_CURRENT_CORE = true;
Core::Interrupt::restore(status); //Core::Interrupt::enable();
global_lock.lock(); global_lock.lock();
Bellringer bellringer;
return Guarded(global_vault); return Guarded(global_vault);
} }
@ -58,7 +57,7 @@ void Guard::relay(Epilogue handler) {
Core::Interrupt::enable(); // goto level 0.5 Core::Interrupt::enable(); // goto level 0.5
if(epi_flag FOR_CURRENT_CORE){ if(epi_flag FOR_CURRENT_CORE){
epilogue_queue FOR_CURRENT_CORE.produce(handler); epilogue_queue->produce(handler);
} }
else{ else{
epi_flag FOR_CURRENT_CORE = true; epi_flag FOR_CURRENT_CORE = true;

@ -3,7 +3,6 @@
*/ */
//#pragma once //#pragma once
#include "sync/bellringer.h"
#include "../object/bbuffer.h" #include "../object/bbuffer.h"
#include "../object/key.h" #include "../object/key.h"
#include "../types.h" #include "../types.h"
@ -19,9 +18,6 @@ struct Vault {
// no copy // no copy
Vault(const Vault&) = delete; Vault(const Vault&) = delete;
Vault& operator=(const Vault&) = delete; Vault& operator=(const Vault&) = delete;
uint8_t counter;
Bellringer bellringer;
}; };
/*! \brief Lock guard that provides access to the epilogue \ref Vault /*! \brief Lock guard that provides access to the epilogue \ref Vault

@ -10,11 +10,9 @@
#include "../device/ps2controller.h" #include "../device/ps2controller.h"
#include "../sync/ticketlock.h" #include "../sync/ticketlock.h"
#include "../arch/core_interrupt.h"
#include "epilogues.h" #include "epilogues.h"
#include "guard.h" #include "guard.h"
Key kout_key = Key(); Key kout_key = Key();
void printContext(const InterruptContext *context) { void printContext(const InterruptContext *context) {
@ -79,7 +77,6 @@ void handle_keyboard() {
LAPIC::endOfInterrupt(); LAPIC::endOfInterrupt();
if (kout_key.ctrl() && kout_key.alt() && kout_key.scancode == Key::KEY_DEL) if (kout_key.ctrl() && kout_key.alt() && kout_key.scancode == Key::KEY_DEL)
System::reboot(); System::reboot();
Guard::relay(Epilogues::keyboard); Guard::relay(Epilogues::keyboard);
} }
else else
@ -101,7 +98,6 @@ void handle_keyboard() {
[[gnu::interrupt]] void handle_assassin(InterruptContext *context) { [[gnu::interrupt]] void handle_assassin(InterruptContext *context) {
(void)context; (void)context;
LAPIC::endOfInterrupt(); LAPIC::endOfInterrupt();
DBG << "assassin handler\n"<< endl;
Guard::relay(Epilogues::assassin); Guard::relay(Epilogues::assassin);
} }
[[gnu::interrupt]] void handle_wakeup(InterruptContext *context) { [[gnu::interrupt]] void handle_wakeup(InterruptContext *context) {
@ -130,8 +126,6 @@ void initInterruptHandlers() {
IDT::InterruptDescriptor::Returning(handle_keyboard_asm)); IDT::InterruptDescriptor::Returning(handle_keyboard_asm));
IDT::set(Core::Interrupt::Vector::TIMER, IDT::set(Core::Interrupt::Vector::TIMER,
IDT::InterruptDescriptor::Returning(handle_timer)); IDT::InterruptDescriptor::Returning(handle_timer));
IDT::set(Core::Interrupt::Vector::ASSASSIN,
IDT::InterruptDescriptor::Returning(handle_assassin));
// Load the idt pointer // Load the idt pointer
IDT::load(); IDT::load();
} }

@ -20,7 +20,7 @@
#include "arch/context.h" #include "arch/context.h"
#include "thread/thread.h" #include "thread/thread.h"
TextStream kout = TextStream(0, 80, 0, 10, true); ///TextStream kout = TextStream(0, 80, 0, 10, true);
Ticketlock koutlock; Ticketlock koutlock;
//Scheduler sch; //Scheduler sch;
@ -121,17 +121,27 @@ extern "C" int main() {
} }
LAPIC::Timer::setup(1000000); LAPIC::Timer::setup(1000000);
IOAPIC::init();
PS2Controller::init();
ApplicationProcessor::boot(); ApplicationProcessor::boot();
PS2Controller::init();
IOAPIC::init();
IOAPIC::config(1, Core::Interrupt::KEYBOARD);
IOAPIC::allow(1);
Core::Interrupt::enable(); Core::Interrupt::enable();
LAPIC::Timer::activate(); LAPIC::Timer::activate();
PS2Controller::drainBuffer();
DBG << "Main CPU " << static_cast<int>(LAPIC::getID()) << endl << flush; DBG << "Main CPU " << static_cast<int>(LAPIC::getID()) << endl << flush;
{ {
Guarded g = Guard::enter(); Guarded g = Guard::enter();
g.vault().sch.schedule(); g.vault().sch.schedule();
} }
@ -146,12 +156,11 @@ extern "C" int main() {
// Main function for application processors // Main function for application processors
extern "C" int main_ap() { extern "C" int main_ap() {
DBG << "CPU core " << static_cast<int>(Core::getID()) << " / LAPIC " DBG_VERBOSE << "CPU core " << static_cast<int>(Core::getID()) << " / LAPIC "
<< static_cast<int>(LAPIC::getID()) << " in main_ap()" << endl; << static_cast<int>(LAPIC::getID()) << " in main_ap()" << endl;
Core::Interrupt::enable(); Core::Interrupt::enable();
LAPIC::Timer::activate();
DBG << "App CPU " << static_cast<int>(Core::getID()) << endl << flush;
{ {
Guarded g = Guard::enter(); Guarded g = Guard::enter();

@ -1,38 +1,16 @@
#include "./bellringer.h" #include "./bellringer.h"
#include "../interrupt/guard.h" #include "../interrupt/guard.h"
// check: Checks whether bells are running out of time and rings them if // check: Checks whether bells are running out of time and rings them if
// necessary // necessary
void Bellringer::check(Vault &vault) { void Bellringer::check(Vault &vault) { (void)vault; }
auto first = vault.bellringer.bells.dequeue();
first->counter--;
if (vault.bellringer.bellPending()){
vault.bellringer.bells.insertFirst(*first);
}
if (vault.bellringer.bellPending()){
if (first->counter < 1) {
vault.sch.ready(vault.bellringer.bells.dequeue()->thread);
}
}
}
// job: Give a bell to the bellringer & ring it when the specified time ran out. // job: Give a bell to the bellringer & ring it when the specified time ran out.
void Bellringer::sleep(Vault &vault, unsigned int ms) { void Bellringer::sleep(Vault &vault, unsigned int ms) {
Bell bell; (void)vault;
bell.thread = vault.sch.dispatcher.active(); (void)ms;
auto tmp = vault.bellringer.bells.dequeue();
vault.bellringer.bells.insertFirst(*tmp);
do{
ms-=tmp->counter;
} while ((tmp=vault.bellringer.bells.next(*tmp)) != nullptr );
bell.counter = ms;
vault.sch.resume(false);
} }
// Are there bells in the queue? // Are there bells in the queue?
bool Bellringer::bellPending() const { bool Bellringer::bellPending() const { return false; }
if (bells.is_empty())
return false;
else
return true;
}

@ -1,30 +1,7 @@
#include "./semaphore.h" #include "./semaphore.h"
#include "../interrupt/guard.h"
#include "../thread/scheduler.h"
uint8_t counter;
Queue<Thread> waiting;
Semaphore::Semaphore(unsigned c) {
counter=c;
}
Semaphore::Semaphore(unsigned c) { (void)c; }
void Semaphore::p(Vault &vault) { void Semaphore::p(Vault &vault) { (void)vault; }
//resource is frei, läuft direkt weiter
if (vault.counter > 0)
vault.counter--;
else
//thread block, zu aktueller queue hinzufügen und
waiting.enqueue(*vault.sch.active()); //was is der calling thread
//
}
//release
void Semaphore::v(Vault &vault) {
Thread* first = waiting.dequeue();
if (first != nullptr)
vault.sch.ready(first); //wakeup "first" thread
else
vault.counter++;
}
void Semaphore::v(Vault &vault) { (void)vault; }

@ -27,7 +27,6 @@ void Dispatcher::go(Thread *first) {
} }
void Dispatcher::dispatch(Thread *next) { void Dispatcher::dispatch(Thread *next) {
Thread* tmp = lifePointer[Core::getID()]; //lifePointer[Core::getID()] = next;
lifePointer[Core::getID()] = next; lifePointer[Core::getID()]->resume(next);
tmp->resume(next);
} }

@ -1,10 +1,6 @@
// vim: set noet ts=4 sw=4: // vim: set noet ts=4 sw=4:
#include "scheduler.h" #include "scheduler.h"
#include "../arch/lapic.h"
#include "dispatcher.h"
#include "../interrupt/guard.h"
#include "../debug/output.h"
Queue<Thread> readyList = Queue<Thread>(); Queue<Thread> readyList = Queue<Thread>();
@ -43,17 +39,6 @@ void Scheduler::exit() {
void Scheduler::kill(Thread* that) { void Scheduler::kill(Thread* that) {
readyList.remove(that); readyList.remove(that);
that->kill_flag = true; that->kill_flag = true;
DBG << "kill..." << flush;
for(uint8_t i=0;i<Core::MAX; i++)
if(dispatcher.lifePointer[i] == that){
LAPIC::IPI::send(i, Core::Interrupt::Vector::ASSASSIN);
DBG << "found thread on Core" << dec << static_cast<int>(i) << "! killing...\n" << flush;
return;
}
DBG << "not found\n" << flush;
} }
bool Scheduler::isActive(const Thread* thread, unsigned int* cpu) { bool Scheduler::isActive(const Thread* thread, unsigned int* cpu) {
@ -62,9 +47,6 @@ bool Scheduler::isActive(const Thread* thread, unsigned int* cpu) {
return false; return false;
} }
bool Scheduler::isEmpty() const { return false; } bool Scheduler::isEmpty() const { return false; }
void Scheduler::setIdle(IdleThread* that) { (void)that; } void Scheduler::setIdle(IdleThread* that) { (void)that; }

@ -18,10 +18,11 @@ Thread::Thread(void* tos) {
#include "../thread/scheduler.h" #include "../thread/scheduler.h"
void Thread::resume(Thread* next) { void Thread::resume(Thread* next) {
Context *from = &this->context; Guarded g = Guard::enter();
Context *from = &g.vault().sch.active()->context;
Context *to = &next->context; Context *to = &next->context;
//g.vault().sch.dispatcher.lifePointer[Core::getID()] = next; g.vault().sch.dispatcher.lifePointer[Core::getID()] = next;
DBG << "from: " << hex << from << endl; DBG << "from: " << hex << from << endl;
DBG << "to : " << hex << to << endl << flush; DBG << "to : " << hex << to << endl << flush;
context_switch(to, from); context_switch(to, from);

@ -9,9 +9,9 @@
#include "../../interrupt/guard.h" #include "../../interrupt/guard.h"
#include "../../debug/output.h" #include "../../debug/output.h"
#include "../../arch/context.h" #include "../../arch/context.h"
#include "../../sync/semaphore.h"
static uint8_t appl_cnt = 0; static uint8_t appl_cnt = 0;
extern TextStream kout;
char text[] = "Ich mag\n\ char text[] = "Ich mag\n\
Saftige Pflaumen voller Aroma\n\ Saftige Pflaumen voller Aroma\n\
Ich knuddel jede Oma ins Koma\n\ Ich knuddel jede Oma ins Koma\n\
@ -25,6 +25,9 @@ Ich bin Großmuttersniffer\n\
Und wacht sie aus'm Koma auf, kriegt sie von mir 'n Sticker\n\ Und wacht sie aus'm Koma auf, kriegt sie von mir 'n Sticker\n\
\n"; \n";
extern Ticketlock koutlock;
extern Context* test2; extern Context* test1;
extern uint8_t test1_stack[], test2_stack[];
void activeWaitDelay(uint64_t cycles) { void activeWaitDelay(uint64_t cycles) {
uint64_t counter = 0; // Use volatile to prevent optimization uint64_t counter = 0; // Use volatile to prevent optimization
for (uint64_t i = 0; i < cycles; ++i) { for (uint64_t i = 0; i < cycles; ++i) {
@ -33,23 +36,18 @@ void activeWaitDelay(uint64_t cycles) {
//Core::pause(); //Core::pause();
} }
} }
Semaphore foo= Semaphore(1);
void Application::action() { // NOLINT void Application::action() { // NOLINT
uint16_t cnt = 0; uint16_t cnt = 0;
uint8_t row = appl_cnt++; uint8_t row = appl_cnt++;
while (1) { while (1) {
//koutlock.lock(); //koutlock.lock();
{ {
Guarded g= Guard::enter(); Guarded g = Guard::enter();
//g.vault(); //g.vault();
foo.p(g.vault()); g.vault().kout.setPos((unsigned)10*row,(unsigned)/*Core::getID()*2+*/1);
kout.setPos((unsigned)8*row,(unsigned)/*Core::getID()*2+*/1); g.vault().kout << cnt++ << flush;
kout << cnt++ << flush;
foo.v(g.vault());
g.vault().bellringer.sleep(g.vault(),6666);
//g.vault().kout << endl << flush; //g.vault().kout << endl << flush;
//Guard::leave(); //Guard::leave();
//koutlock.unlock(); //koutlock.unlock();

Loading…
Cancel
Save