hw_x86_64_muen: Implement PIC take_request()

The Muen-specific PIC implementation provides the irq_occurred()
function which is used to register an IRQ with the PIC upon thread
exception.

The occurred IRQs are stored in a boolean array internally and handed
out to a CPU via take_request().
This commit is contained in:
Reto Buerki 2015-04-24 16:03:51 +02:00 committed by Stefan Kalkowski
parent fa26805fd7
commit ad411e1a90
4 changed files with 122 additions and 3 deletions

View File

@ -19,12 +19,12 @@ SRC_S += spec/x86_64/crt0.s
# add C++ sources
SRC_CC += spec/x86_64_muen/platform_support.cc
SRC_CC += spec/x86_64_muen/sinfo.cc
SRC_CC += spec/x86_64_muen/kernel/thread.cc
SRC_CC += spec/x86_64_muen/kernel/cpu.cc
SRC_CC += spec/x86_64/kernel/thread_base.cc
SRC_CC += spec/x86_64/idt.cc
SRC_CC += spec/x86_64/tss.cc
SRC_CC += spec/x86/platform_support.cc
SRC_CC += spec/x86/kernel/thread.cc
SRC_CC += spec/x86/kernel/cpu.cc
SRC_CC += spec/x86/kernel/pd.cc
SRC_CC += spec/x86/cpu.cc
SRC_CC += x86/io_port_session_component.cc

View File

@ -36,12 +36,27 @@ class Genode::Pic
NR_OF_IRQ = 256,
};
void irq_occurred(unsigned irq)
{
isr[irq] = true;
}
bool take_request(unsigned &irq)
{
for (int i = 0; i < 256; i++) {
if (isr[i] == true) {
irq = i;
isr[i] = false;
return true;
}
}
return false;
}
/*
* Dummies
*/
Pic() { }
bool take_request(unsigned &irq) { return false; }
void finish_request() { }
void unmask(unsigned const i, unsigned) { }
void mask(unsigned const i) { }
@ -49,6 +64,10 @@ class Genode::Pic
void init_cpu_local() { }
bool is_ip_interrupt(unsigned, unsigned) { return false; }
void trigger_ip_interrupt(unsigned) { }
private:
bool isr[NR_OF_IRQ] = {false};
};
namespace Kernel { class Pic : public Genode::Pic { }; }

View File

@ -0,0 +1,43 @@
/*
* \brief Class for kernel data that is needed to manage a specific CPU
* \author Reto Buerki
* \date 2015-04-28
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <kernel/cpu.h>
#include <kernel/kernel.h>
#include <kernel/pd.h>
using namespace Kernel;
Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::MIN, 0)
{
Cpu_job::cpu(cpu);
ip = (addr_t)&_main;
sp = (addr_t)&_stack[stack_size];
init((addr_t)core_pd()->translation_table(), true);
}
void Cpu_idle::exception(unsigned const cpu)
{
if (trapno == RESET) {
return;
} else if (trapno >= INTERRUPTS_START && trapno <= INTERRUPTS_END) {
pic()->irq_occurred(trapno);
_interrupt(cpu);
return;
}
PWRN("Unknown exception %lu with error code %lu at ip=%p", trapno,
errcode, (void *)ip);
assert(0);
}

View File

@ -0,0 +1,57 @@
/*
* \brief Kernel backend for execution contexts in userland
* \author Adrian-Ken Rueegsegger
* \author Reto Buerki
* \date 2015-04-28
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <kernel/thread.h>
#include <pic.h>
using namespace Kernel;
Thread::Thread(unsigned const priority, unsigned const quota,
char const * const label)
: Thread_base(this), Cpu_job(priority, quota), _state(AWAITS_START),
_signal_receiver(0), _label(label) { }
void Thread::exception(unsigned const cpu)
{
switch (trapno) {
case PAGE_FAULT:
_mmu_exception();
return;
case NO_MATH_COPROC:
if (_cpu->retry_fpu_instr(&_lazy_state)) { return; }
PWRN("%s -> %s: FPU error", pd_label(), label());
_stop();
return;
case UNDEFINED_INSTRUCTION:
PWRN("%s -> %s: undefined instruction at ip=%p",
pd_label(), label(), (void*)ip);
_stop();
case SUPERVISOR_CALL:
_call();
return;
}
if (trapno >= INTERRUPTS_START && trapno <= INTERRUPTS_END) {
pic()->irq_occurred(trapno);
_interrupt(cpu);
return;
}
PWRN("%s -> %s: triggered unknown exception %lu with error code %lu"
" at ip=%p", pd_label(), label(), trapno, errcode, (void*)ip);
_stop();
}
void Thread::_call_update_pd() { }