FreeNOS
ARMProcess.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 <Log.h>
20 #include <SplitAllocator.h>
21 #include "ARMProcess.h"
22 
23 #define MEMALIGN8 8
24 
25 static bool firstProcess = true;
26 extern u8 svcStack[PAGESIZE * 4];
27 
28 ARMProcess::ARMProcess(ProcessID id, Address entry, bool privileged, const MemoryMap &map)
29  : Process(id, entry, privileged, map)
30 {
31 }
32 
34 {
35  Memory::Range range;
36  Allocator::Range alloc_args;
37 
38  // Create MMU context
39  m_memoryContext = new ARMPaging(&m_map, Kernel::instance()->getAllocator());
40  if (!m_memoryContext)
41  {
42  ERROR("failed to create memory context");
43  return OutOfMemory;
44  }
45 
46  // Initialize MMU context
48  if (memResult != MemoryContext::Success)
49  {
50  ERROR("failed to initialize MemoryContext: result = " << (int) memResult);
51  return OutOfMemory;
52  }
53 
54  // Allocate User stack
57  alloc_args.address = 0;
58  alloc_args.size = range.size;
59  alloc_args.alignment = PAGESIZE;
60 
61  if (Kernel::instance()->getAllocator()->allocate(alloc_args) != Allocator::Success)
62  {
63  ERROR("failed to allocate user stack");
64  return OutOfMemory;
65  }
66  range.phys = alloc_args.address;
67 
68  // Map User stack
70  {
71  ERROR("failed to map user stack");
72  return MemoryMapError;
73  }
74 
75  // Fill usermode program registers
76  reset(m_entry);
77 
78  // Finalize with generic initialization
79  return Process::initialize();
80 }
81 
83 {
84 }
85 
87 {
88  return &m_cpuState;
89 }
90 
91 void ARMProcess::setCpuState(const CPUState *cpuState)
92 {
94 }
95 
97 {
98  const Result r = Process::join(result);
99  if (r == Success)
100  {
101  m_cpuState.r0 = API::Success | (result << 16);
102  }
103 
104  return r;
105 }
106 
108 {
110 
111  MemoryBlock::set(&m_cpuState, 0, sizeof(m_cpuState));
112  m_cpuState.sp = range.virt + range.size - MEMALIGN8; // user stack pointer
113  m_cpuState.pc = entry; // user program counter
114  m_cpuState.cpsr = (m_privileged ? SYS_MODE : USR_MODE); // current program status (CPSR)
115 }
116 
118 {
119  // Activates memory context of this process
121 
122  // First process starts from loadCoreState0
123  if (firstProcess)
124  {
125  firstProcess = false;
126 
127  // Kernel stacks are currently 16KiB (see ARMBoot.S)
128  CPUState *ptr = ((CPUState *) (svcStack + sizeof(svcStack))) - 1;
129  MemoryBlock::copy(ptr, &m_cpuState, sizeof(*ptr));
130 
131  // Switch to the actual SVC stack and switch to usermode
132  asm volatile ("ldr sp, =(svcStack + (4096*4))\n"
133  "sub sp, sp, %0\n"
134  "ldr r0, =loadCoreState0\n"
135  "bx r0\n" : : "i" (sizeof(m_cpuState) - sizeof(m_cpuState.padding)) );
136  }
137 }
MemoryContext::initialize
virtual Result initialize()=0
Initialize the MemoryContext.
MEMALIGN8
#define MEMALIGN8
Definition: ARMProcess.cpp:23
Process::m_memoryContext
MemoryContext * m_memoryContext
MMU memory context.
Definition: Process.h:271
MemoryBlock::copy
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Definition: MemoryBlock.cpp:36
SYS_MODE
#define SYS_MODE
Definition: ARMConstant.h:52
Memory::Range
Memory range.
Definition: Memory.h:55
SplitAllocator.h
Process::MemoryMapError
@ MemoryMapError
Definition: Process.h:58
Process
Represents a process which may run on the host.
Definition: Process.h:44
MemoryBlock::set
static void * set(void *dest, int ch, unsigned count)
Fill memory with a constant byte.
Definition: MemoryBlock.cpp:25
ARMProcess::~ARMProcess
virtual ~ARMProcess()
Destructor function.
Definition: ARMProcess.cpp:82
MemoryMap::UserStack
@ UserStack
< User stack
Definition: MemoryMap.h:58
Memory::Writable
@ Writable
Definition: Memory.h:42
ARMPaging
ARM virtual memory implementation.
Definition: ARMPaging.h:43
CPUState::sp
u32 sp
Definition: ARMCore.h:247
Memory::User
@ User
Definition: Memory.h:44
PAGESIZE
#define PAGESIZE
ARM uses 4K pages.
Definition: ARMConstant.h:97
Process::m_map
MemoryMap m_map
Virtual memory layout.
Definition: Process.h:268
ARMProcess::m_cpuState
CPUState m_cpuState
Contains all the CPU registers for this task.
Definition: ARMProcess.h:99
ProcessID
u32 ProcessID
Process Identification Number.
Definition: Types.h:140
firstProcess
static bool firstProcess
Definition: ARMProcess.cpp:25
Address
unsigned long Address
A memory address.
Definition: Types.h:131
Allocator::Range::address
Address address
Starting address of the memory range.
Definition: Allocator.h:67
Process::Success
@ Success
Definition: Process.h:56
Allocator::Range::alignment
Size alignment
Alignment in bytes or ZERO for default alignment.
Definition: Allocator.h:69
CPUState::cpsr
u32 cpsr
Definition: ARMCore.h:246
CPUState::r0
u32 r0
Definition: ARMCore.h:248
Memory::Readable
@ Readable
Definition: Memory.h:41
Log.h
uint
unsigned int uint
Unsigned integer number.
Definition: Types.h:44
Allocator::Range::size
Size size
Amount of memory in bytes.
Definition: Allocator.h:68
ARMProcess::execute
virtual void execute(Process *previous)
Allow the Process to run on the CPU.
Definition: ARMProcess.cpp:117
CPUState::padding
u32 padding[4]
Definition: ARMCore.h:245
ARMProcess.h
Process::Result
Result
Result codes.
Definition: Process.h:54
MemoryContext::activate
virtual Result activate(bool initializeMMU=false)=0
Activate the MemoryContext.
svcStack
u8 svcStack[PAGESIZE *4]
Process::OutOfMemory
@ OutOfMemory
Definition: Process.h:59
Allocator::Success
@ Success
Definition: Allocator.h:55
Memory::Range::phys
Address phys
Physical address.
Definition: Memory.h:58
MemoryContext::Result
Result
Result codes.
Definition: MemoryContext.h:49
MemoryMap::range
Memory::Range range(Region region) const
Get memory range for the given region.
Definition: MemoryMap.cpp:36
MemoryContext::Success
@ Success
Definition: MemoryContext.h:51
MemoryMap
Describes virtual memory map layout.
Definition: MemoryMap.h:38
WeakSingleton< Kernel >::instance
static Kernel * instance()
Retrieve the instance.
Definition: Singleton.h:86
USR_MODE
#define USR_MODE
ARM Program Status Register (CPSR)
Definition: ARMConstant.h:46
CPUState::pc
u32 pc
Definition: ARMCore.h:249
Process::m_entry
Address m_entry
Entry point of the program.
Definition: Process.h:265
ARMProcess::join
virtual Result join(const uint result)
Complete waiting for another Process.
Definition: ARMProcess.cpp:96
CPUState
Contains all the CPU registers.
Definition: ARMCore.h:243
ARMProcess::ARMProcess
ARMProcess(ProcessID id, Address entry, bool privileged, const MemoryMap &map)
Constructor function.
Definition: ARMProcess.cpp:28
ARMProcess::initialize
virtual Result initialize()
Initialize the Process.
Definition: ARMProcess.cpp:33
Allocator::Range
Describes a range of memory.
Definition: Allocator.h:65
Process::join
virtual Result join(const uint result)
Complete waiting for another Process.
Definition: Process.cpp:124
ARMProcess::reset
virtual void reset(const Address entry)
Restart execution at the given entry point.
Definition: ARMProcess.cpp:107
Process::initialize
virtual Result initialize()
Initialize the Process.
Definition: Process.cpp:172
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
entry
u32 entry[]
Definition: IntelACPI.h:64
u8
unsigned char u8
Unsigned 8-bit number.
Definition: Types.h:59
ARMProcess::setCpuState
void setCpuState(const CPUState *cpuState)
Overwrite the saved CPU registers for this task.
Definition: ARMProcess.cpp:91
API::Success
@ Success
Definition: API.h:70
Memory::Range::virt
Address virt
Virtual address.
Definition: Memory.h:57
ARMProcess::cpuState
const CPUState * cpuState() const
Retrieve saved CPU state.
Definition: ARMProcess.cpp:86
Memory::Range::size
Size size
Size in number of bytes.
Definition: Memory.h:59
Memory::Range::access
Access access
Page access flags.
Definition: Memory.h:60
MemoryContext::mapRangeContiguous
virtual Result mapRangeContiguous(Memory::Range *range)
Map a range of contiguous physical pages to virtual addresses.
Definition: MemoryContext.cpp:46
Process::m_privileged
bool m_privileged
Privilege level.
Definition: Process.h:262