FreeNOS
RaspberryKernel.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2019 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <FreeNOS/System.h>
19#include <FreeNOS/ProcessManager.h>
20#include <Log.h>
21#include <SplitAllocator.h>
22#include <CoreInfo.h>
23#include <arm/ARMException.h>
24#include <arm/ARMConstant.h>
26#include "RaspberryKernel.h"
27
29 : ARMKernel(info)
30#ifdef BCM2836
31 , m_bcm(info->coreId)
32#endif /* BMC2836 */
33{
34 ARMControl ctrl;
35
36 NOTICE("");
37
38 // Setup interrupt callbacks
42
43 // Configure clocks and irqs. For BCM2836, only use the generic ARM timer
44 // when running under Qemu. Unfortunately, Qemu dropped support for the
45 // broadcom timer in recent versions. On hardware, use the broadcom timer.
46#ifdef BCM2836
47 u32 system_frequency = ctrl.read(ARMControl::SystemFrequency);
48 NOTICE("sysfreq = " << system_frequency);
49 if (system_frequency == 62500000)
50 {
51 // Use ARM generic timer
53 m_timerIrq = ARMTIMER_IRQ;
55
56 // Setup IRQ routing
58 }
59#endif /* BCM2836 */
60
61 /* Default to broadcom timer and interrupt handling */
62 if (m_timer == NULL)
63 {
66 m_bcmTimer.setFrequency( 250 ); /* trigger timer interrupts at 250Hz (clock runs at 1Mhz) */
68 }
69}
70
72{
75 bool tick;
76
77 DEBUG("procId = " << proc->getID());
78
79#ifdef BCM2836
80 if (kernel->m_timer == &kernel->m_armTimer)
81 {
83 }
84 else
85#endif /* BCM2836 */
86 {
88 }
89
90 if (tick)
91 {
92 kernel->m_timer->tick();
93 kernel->getProcessManager()->schedule();
94 }
95
96 for (uint i = kernel->m_timerIrq + 1; i < 64; i++)
97 {
98 if (kernel->m_intControl->isTriggered(i))
99 {
100 kernel->executeIntVector(i, (CPUState *)&state);
101 }
102 }
103
104 next = (ARMProcess *) kernel->getProcessManager()->current();
105 if (next != proc)
106 {
107 proc->setCpuState((const CPUState *)&state);
108 MemoryBlock::copy((void *)&state, next->cpuState(), sizeof(state));
109 }
110}
u8 coreId
Definition IntelACPI.h:1
virtual Result setFrequency(const Size hertz)
Set timer frequency.
ARM System Control Coprocessor (CP15).
Definition ARMControl.h:48
u32 read(Register reg) const
Read a register from the CP15.
@ SystemFrequency
Definition ARMControl.h:76
Result install(ExceptionType vector, Handler handler)
Install an exception handler.
Represents the ARM kernel implementation.
Definition ARMKernel.h:41
ARMException m_exception
ARM exception handling subsystem.
Definition ARMKernel.h:98
ARM specific process implementation.
Definition ARMProcess.h:35
void setCpuState(const CPUState *cpuState)
Overwrite the saved CPU registers for this task.
Result setCoreTimerIrq(Timer timer, bool enable)
Set Core Timer interrupt.
bool getCoreTimerIrqStatus(Timer timer) const
Get core timer interrupt status.
virtual Result setFrequency(Size hertz)
Set timer frequency.
virtual bool isTriggered(uint irq)
Check if an IRQ vector is set.
virtual Result enable(uint irq)=0
Enable hardware interrupt (IRQ).
virtual void executeIntVector(u32 vec, CPUState *state)
Execute an interrupt handler.
Definition Kernel.cpp:210
IntController * m_intControl
Interrupt Controller.
Definition Kernel.h:242
Timer * m_timer
Timer device.
Definition Kernel.h:245
ProcessManager * getProcessManager()
Get process manager.
Definition Kernel.cpp:143
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Result schedule()
Schedule next process to run.
Process * current()
Current process running.
ProcessID getID() const
Retrieve our ID number.
Definition Process.cpp:60
Represents the Raspberry Pi kernel implementation.
BroadcomTimer m_bcmTimer
Broadcom specific timer module.
Broadcom2836 m_bcm
Broadcom specific registers.
u8 m_timerIrq
Interrupt number for the timer.
BroadcomInterrupt m_bcmIntr
Broadcom specific interrupt controller.
ARM64Timer m_armTimer
ARM generic timer.
static void interrupt(CPUState state)
Interrupt handler routine.
RaspberryKernel(CoreInfo *info)
Constructor function.
virtual Result tick()
Process timer tick.
Definition Timer.cpp:74
static Kernel * instance()
Retrieve the instance.
Definition Singleton.h:86
#define BCM_IRQ_SYSTIMERM1
Triggered when the system timer matches the C1 register.
#define NULL
NULL means zero.
Definition Macros.h:39
unsigned int u32
Unsigned 32-bit number.
Definition Types.h:53
#define NOTICE(msg)
Output a notice message.
Definition Log.h:75
unsigned int uint
Unsigned integer number.
Definition Types.h:44
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
Contains all the CPU registers.
Definition ARMCore.h:244
Per-Core information structure.
Definition CoreInfo.h:61