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:
parent
fa26805fd7
commit
ad411e1a90
|
@ -19,12 +19,12 @@ SRC_S += spec/x86_64/crt0.s
|
||||||
# add C++ sources
|
# add C++ sources
|
||||||
SRC_CC += spec/x86_64_muen/platform_support.cc
|
SRC_CC += spec/x86_64_muen/platform_support.cc
|
||||||
SRC_CC += spec/x86_64_muen/sinfo.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/kernel/thread_base.cc
|
||||||
SRC_CC += spec/x86_64/idt.cc
|
SRC_CC += spec/x86_64/idt.cc
|
||||||
SRC_CC += spec/x86_64/tss.cc
|
SRC_CC += spec/x86_64/tss.cc
|
||||||
SRC_CC += spec/x86/platform_support.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/kernel/pd.cc
|
||||||
SRC_CC += spec/x86/cpu.cc
|
SRC_CC += spec/x86/cpu.cc
|
||||||
SRC_CC += x86/io_port_session_component.cc
|
SRC_CC += x86/io_port_session_component.cc
|
||||||
|
|
|
@ -36,12 +36,27 @@ class Genode::Pic
|
||||||
NR_OF_IRQ = 256,
|
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
|
* Dummies
|
||||||
*/
|
*/
|
||||||
Pic() { }
|
Pic() { }
|
||||||
bool take_request(unsigned &irq) { return false; }
|
|
||||||
void finish_request() { }
|
void finish_request() { }
|
||||||
void unmask(unsigned const i, unsigned) { }
|
void unmask(unsigned const i, unsigned) { }
|
||||||
void mask(unsigned const i) { }
|
void mask(unsigned const i) { }
|
||||||
|
@ -49,6 +64,10 @@ class Genode::Pic
|
||||||
void init_cpu_local() { }
|
void init_cpu_local() { }
|
||||||
bool is_ip_interrupt(unsigned, unsigned) { return false; }
|
bool is_ip_interrupt(unsigned, unsigned) { return false; }
|
||||||
void trigger_ip_interrupt(unsigned) { }
|
void trigger_ip_interrupt(unsigned) { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool isr[NR_OF_IRQ] = {false};
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Kernel { class Pic : public Genode::Pic { }; }
|
namespace Kernel { class Pic : public Genode::Pic { }; }
|
||||||
|
|
43
repos/base-hw/src/core/spec/x86_64_muen/kernel/cpu.cc
Normal file
43
repos/base-hw/src/core/spec/x86_64_muen/kernel/cpu.cc
Normal 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);
|
||||||
|
}
|
57
repos/base-hw/src/core/spec/x86_64_muen/kernel/thread.cc
Normal file
57
repos/base-hw/src/core/spec/x86_64_muen/kernel/thread.cc
Normal 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() { }
|
Loading…
Reference in New Issue
Block a user