FreeNOS
ARMKernel.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 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 "ARMKernel.h"
27 
29  : Kernel(info)
30  , m_exception(RAM_ADDR)
31 {
32  ARMControl ctrl;
33 
34  NOTICE("");
35 
36  // Setup interrupt callbacks
44 
45  // Set ARMCore modes
47 
48 #ifdef ARMV6
51 #endif
52 
53  // First page is used for exception handlers
54  m_alloc->allocate(info->memory.phys);
55 
56  // Allocate physical memory for the temporary stack.
57  //
58  // This is an area of 1MiB which must not be used. It is re-mapped on the
59  // secondary cores to an identity-mapped area on the boot core and is currently
60  // required in order to enable the early MMU and perform full kernel startup
61  // until the first program starts.
62  //
63  // If this area is re-used after the kernel started, the SplitAllocator::toVirtual()
64  // function will not translate properly, resulting in memory corruption.
65  if (m_coreInfo->coreId == 0) {
66  for (Size i = 0; i < (PAGESIZE*4); i += PAGESIZE)
67  m_alloc->allocate(TMPSTACKADDR + i);
68  } else {
69  for (Size i = 0; i < MegaByte(1); i += PAGESIZE)
70  m_alloc->allocate(info->memory.phys + TMPSTACKOFF + i);
71  }
72 }
73 
75 {
76  ARMCore core;
77  core.logException(&state);
78 
79  FATAL("core" << coreInfo.coreId << ": unhandled IRQ in procId = " <<
81 }
82 
84 {
85  ARMCore core;
86  core.logException(&state);
87 
88  FATAL("core" << coreInfo.coreId << ": procId = " <<
90 }
91 
93 {
94  ARMCore core;
95  core.logException(&state);
96 
97  FATAL("core" << coreInfo.coreId << ": procId = " <<
99 }
100 
102 {
103  ARMCore core;
104  core.logException(&state);
105 
106  FATAL("core" << coreInfo.coreId << ": procId = " <<
108 }
109 
110 
112 {
113  ARMCore core;
114  core.logException(&state);
115 
116  FATAL("core" << coreInfo.coreId << ": procId = " <<
118 }
119 
120 void ARMKernel::trap(volatile CPUState state)
121 {
123  ARMProcess *proc = (ARMProcess *) mgr->current(), *proc2;
124  ProcessID procId = proc->getID();
125 
126  DEBUG("coreId = " << coreInfo.coreId << " procId = " << procId << " api = " << state.r0);
127 
128  // Execute the kernel call
129  u32 r = Kernel::instance()->getAPI()->invoke(
130  (API::Number) state.r0,
131  state.r1,
132  state.r2,
133  state.r3,
134  state.r4,
135  state.r5
136  );
137 
138  // Did we change process?
139  proc2 = (ARMProcess *) mgr->current();
140  DEBUG("result = " << r << " scheduled = " << (bool)(proc != proc2));
141 
142  if (proc != proc2)
143  {
144  // Only if the previous process still exists (not killed in API)
145  if (mgr->get(procId) != NULL)
146  {
147  state.r0 = r;
148  proc->setCpuState((const CPUState *)&state);
149  }
150  MemoryBlock::copy((void*)&state, proc2->cpuState(), sizeof(state));
151  }
152  else
153  state.r0 = r;
154 }
ARMException.h
ARMCore::logException
void logException(CPUState *state) const
Log a CPU exception.
Definition: ARMCore.cpp:22
MemoryBlock::copy
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Definition: MemoryBlock.cpp:36
ARMControl::unset
void unset(SystemControlFlags flags)
Unset system control flags in CP15.
Definition: ARMControl.cpp:93
SplitAllocator::allocate
virtual Result allocate(Range &args)
Allocate physical memory.
Definition: SplitAllocator.cpp:35
ARMControl::AlignmentFaults
@ AlignmentFaults
Definition: ARMControl.h:91
SplitAllocator.h
ProcessManager
Represents a process which may run on the host.
Definition: ProcessManager.h:44
API::invoke
Result invoke(Number number, ulong arg1, ulong arg2, ulong arg3, ulong arg4, ulong arg5)
Execute a generic API function.
Definition: API.cpp:35
ARMConstant.h
NOTICE
#define NOTICE(msg)
Output a notice message.
Definition: Log.h:75
Kernel::m_coreInfo
CoreInfo * m_coreInfo
CoreInfo object for this core.
Definition: Kernel.h:236
ARMKernel::prefetchAbort
static void prefetchAbort(CPUState state)
Prefetch abort routine.
Definition: ARMKernel.cpp:92
Process::getID
ProcessID getID() const
Retrieve our ID number.
Definition: Process.cpp:60
PAGESIZE
#define PAGESIZE
ARM uses 4K pages.
Definition: ARMConstant.h:97
ARMException::PrefetchAbort
@ PrefetchAbort
Definition: ARMException.h:56
ARMKernel::interrupt
static void interrupt(CPUState state)
Interrupt handler routine.
Definition: ARMKernel.cpp:74
ProcessID
u32 ProcessID
Process Identification Number.
Definition: Types.h:140
CoreInfo::memory
Memory::Range memory
Defines the physical memory available to the core.
Definition: CoreInfo.h:69
ARMException::IRQ
@ IRQ
Definition: ARMException.h:59
API::Number
Number
Enumeration of supported generic kernel API functions.
Definition: API.h:49
CPUState::r0
u32 r0
Definition: ARMCore.h:248
ARMKernel.h
Kernel::getProcessManager
ProcessManager * getProcessManager()
Get process manager.
Definition: Kernel.cpp:143
Log.h
CoreInfo::coreId
uint coreId
Core identifier.
Definition: CoreInfo.h:66
MegaByte
#define MegaByte(v)
Convert megabytes to bytes.
Definition: Macros.h:57
FATAL
#define FATAL(msg)
Output a critical message and terminate program immediatly.
Definition: Log.h:50
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
CPUState::r5
u32 r5
Definition: ARMCore.h:248
ARMControl
ARM System Control Coprocessor (CP15).
Definition: ARMControl.h:47
Memory::Range::phys
Address phys
Physical address.
Definition: Memory.h:58
ARMException::install
Result install(ExceptionType vector, Handler handler)
Install an exception handler.
Definition: ARMException.cpp:39
ARMControl::BigEndian
@ BigEndian
Definition: ARMControl.h:95
Kernel::getAPI
API * getAPI()
Get API.
Definition: Kernel.cpp:148
NULL
#define NULL
NULL means zero.
Definition: Macros.h:39
u32
unsigned int u32
Unsigned 32-bit number.
Definition: Types.h:53
ARMException::SoftwareInterrupt
@ SoftwareInterrupt
Definition: ARMException.h:55
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
WeakSingleton< Kernel >::instance
static Kernel * instance()
Retrieve the instance.
Definition: Singleton.h:86
ARMProcess
ARM specific process implementation.
Definition: ARMProcess.h:34
ARMException::Reserved
@ Reserved
Definition: ARMException.h:58
Kernel
FreeNOS kernel implementation.
Definition: Kernel.h:92
ProcessManager::get
Process * get(const ProcessID id)
Retrieve a Process by it's ID.
Definition: ProcessManager.cpp:95
ARMException::UndefinedInstruction
@ UndefinedInstruction
Definition: ARMException.h:54
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
coreInfo
CoreInfo coreInfo
Local CoreInfo instance.
BroadcomInterrupt.h
ARMKernel::dataAbort
static void dataAbort(CPUState state)
Data abort routine.
Definition: ARMKernel.cpp:101
ARMException::FIQ
@ FIQ
Definition: ARMException.h:60
ARMControl::set
void set(SystemControlFlags flags)
Set system control flags in CP15.
Definition: ARMControl.cpp:88
ARMProcess::setCpuState
void setCpuState(const CPUState *cpuState)
Overwrite the saved CPU registers for this task.
Definition: ARMProcess.cpp:91
CPUState::r1
u32 r1
Definition: ARMCore.h:248
ARMException::DataAbort
@ DataAbort
Definition: ARMException.h:57
CoreInfo.h
ARMControl::AlignmentCorrect
@ AlignmentCorrect
Definition: ARMControl.h:90
Kernel::m_alloc
SplitAllocator * m_alloc
Physical memory allocator.
Definition: Kernel.h:227
ARMKernel::reserved
static void reserved(CPUState state)
Reserved routine.
Definition: ARMKernel.cpp:111
ARMKernel::ARMKernel
ARMKernel(CoreInfo *info)
Constructor function.
Definition: ARMKernel.cpp:28
ProcessManager::current
Process * current()
Current process running.
Definition: ProcessManager.cpp:203
ARMCore
Class representing an ARM processor core.
Definition: ARMCore.h:256
CPUState::r3
u32 r3
Definition: ARMCore.h:248
ARMKernel::undefinedInstruction
static void undefinedInstruction(CPUState state)
Undefined instruction routine.
Definition: ARMKernel.cpp:83
CPUState::r2
u32 r2
Definition: ARMCore.h:248
CPUState::r4
u32 r4
Definition: ARMCore.h:248
ARMKernel::trap
static void trap(CPUState state)
Software trap routine.
Definition: ARMKernel.cpp:120