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
52  m_timer = &m_armTimer;
53  m_timerIrq = ARMTIMER_IRQ;
54  m_armTimer.setFrequency(100);
55 
56  // Setup IRQ routing
57  m_bcm.setCoreTimerIrq(Broadcom2836::PhysicalTimer1, true);
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  {
82  tick = kernel->m_bcm.getCoreTimerIrqStatus(Broadcom2836::PhysicalTimer1);
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 }
RaspberryKernel::interrupt
static void interrupt(CPUState state)
Interrupt handler routine.
Definition: RaspberryKernel.cpp:71
ARMException.h
RaspberryKernel.h
MemoryBlock::copy
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Definition: MemoryBlock.cpp:36
SplitAllocator.h
RaspberryKernel::RaspberryKernel
RaspberryKernel(CoreInfo *info)
Constructor function.
Definition: RaspberryKernel.cpp:28
ARMConstant.h
NOTICE
#define NOTICE(msg)
Output a notice message.
Definition: Log.h:75
Kernel::m_timer
Timer * m_timer
Timer device.
Definition: Kernel.h:245
Process::getID
ProcessID getID() const
Retrieve our ID number.
Definition: Process.cpp:60
RaspberryKernel::m_timerIrq
u8 m_timerIrq
Interrupt number for the timer.
Definition: RaspberryKernel.h:77
ARMException::IRQ
@ IRQ
Definition: ARMException.h:59
Kernel::getProcessManager
ProcessManager * getProcessManager()
Get process manager.
Definition: Kernel.cpp:143
Log.h
uint
unsigned int uint
Unsigned integer number.
Definition: Types.h:44
BroadcomTimer::setFrequency
virtual Result setFrequency(Size hertz)
Set timer frequency.
Definition: BroadcomTimer.cpp:21
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
ARMControl
ARM System Control Coprocessor (CP15).
Definition: ARMControl.h:47
Kernel::m_intControl
IntController * m_intControl
Interrupt Controller.
Definition: Kernel.h:242
IntController::enable
virtual Result enable(uint irq)=0
Enable hardware interrupt (IRQ).
ARMException::install
Result install(ExceptionType vector, Handler handler)
Install an exception handler.
Definition: ARMException.cpp:39
ARMControl::SystemFrequency
@ SystemFrequency
Definition: ARMControl.h:76
NULL
#define NULL
NULL means zero.
Definition: Macros.h:39
u32
unsigned int u32
Unsigned 32-bit number.
Definition: Types.h:53
WeakSingleton< Kernel >::instance
static Kernel * instance()
Retrieve the instance.
Definition: Singleton.h:86
ProcessManager::schedule
Result schedule()
Schedule next process to run.
Definition: ProcessManager.cpp:155
ARMProcess
ARM specific process implementation.
Definition: ARMProcess.h:34
CPUState
Contains all the CPU registers.
Definition: ARMCore.h:243
CoreInfo
Per-Core information structure.
Definition: CoreInfo.h:60
ARMKernel::m_exception
ARMException m_exception
ARM exception handling subsystem.
Definition: ARMKernel.h:98
Broadcom2836::PhysicalTimer1
@ PhysicalTimer1
Definition: Broadcom2836.h:63
BCM_IRQ_SYSTIMERM1
#define BCM_IRQ_SYSTIMERM1
Triggered when the system timer matches the C1 register.
Definition: BroadcomInterrupt.h:40
BroadcomInterrupt.h
ARMException::FIQ
@ FIQ
Definition: ARMException.h:60
RaspberryKernel::m_bcmIntr
BroadcomInterrupt m_bcmIntr
Broadcom specific interrupt controller.
Definition: RaspberryKernel.h:63
IntController::isTriggered
virtual bool isTriggered(uint irq)
Check if an IRQ vector is set.
Definition: IntController.cpp:35
RaspberryKernel
Represents the Raspberry Pi kernel implementation.
Definition: RaspberryKernel.h:40
ARMProcess::setCpuState
void setCpuState(const CPUState *cpuState)
Overwrite the saved CPU registers for this task.
Definition: ARMProcess.cpp:91
ARMKernel
Represents the ARM kernel implementation.
Definition: ARMKernel.h:40
CoreInfo.h
ProcessManager::current
Process * current()
Current process running.
Definition: ProcessManager.cpp:203
coreId
u8 coreId
Definition: IntelACPI.h:64
Kernel::executeIntVector
virtual void executeIntVector(u32 vec, CPUState *state)
Execute an interrupt handler.
Definition: Kernel.cpp:210
RaspberryKernel::m_bcmTimer
BroadcomTimer m_bcmTimer
Broadcom specific timer module.
Definition: RaspberryKernel.h:74
Timer::tick
virtual Result tick()
Process timer tick.
Definition: Timer.cpp:74
ARMControl::read
u32 read(Register reg) const
Read a register from the CP15.
Definition: ARMControl.cpp:29