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
25static bool firstProcess = true;
26extern u8 svcStack[PAGESIZE * 4];
27
28ARMProcess::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
77
78 // Finalize with generic initialization
79 return Process::initialize();
80}
81
85
87{
88 return &m_cpuState;
89}
90
91void 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
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}
#define MEMALIGN8
u8 svcStack[PAGESIZE *4]
static bool firstProcess
u32 entry[]
Definition IntelACPI.h:1
@ Success
Definition API.h:70
ARM virtual memory implementation.
Definition ARMPaging.h:44
void setCpuState(const CPUState *cpuState)
Overwrite the saved CPU registers for this task.
virtual ~ARMProcess()
Destructor function.
const CPUState * cpuState() const
Retrieve saved CPU state.
CPUState m_cpuState
Contains all the CPU registers for this task.
Definition ARMProcess.h:99
virtual Result join(const uint result)
Complete waiting for another Process.
virtual void reset(const Address entry)
Restart execution at the given entry point.
virtual void execute(Process *previous)
Allow the Process to run on the CPU.
virtual Result initialize()
Initialize the Process.
ARMProcess(ProcessID id, Address entry, bool privileged, const MemoryMap &map)
Constructor function.
static void * set(void *dest, int ch, unsigned count)
Fill memory with a constant byte.
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Result
Result codes.
virtual Result initialize()=0
Initialize the MemoryContext.
virtual Result activate(bool initializeMMU=false)=0
Activate the MemoryContext.
virtual Result mapRangeContiguous(Memory::Range *range)
Map a range of contiguous physical pages to virtual addresses.
Describes virtual memory map layout.
Definition MemoryMap.h:39
@ UserStack
< User stack
Definition MemoryMap.h:58
Memory::Range range(Region region) const
Get memory range for the given region.
Definition MemoryMap.cpp:36
Represents a process which may run on the host.
Definition Process.h:45
MemoryContext * m_memoryContext
MMU memory context.
Definition Process.h:271
virtual Result join(const uint result)
Complete waiting for another Process.
Definition Process.cpp:124
Result
Result codes.
Definition Process.h:55
@ Success
Definition Process.h:56
@ OutOfMemory
Definition Process.h:59
@ MemoryMapError
Definition Process.h:58
virtual Result initialize()
Initialize the Process.
Definition Process.cpp:172
MemoryMap m_map
Virtual memory layout.
Definition Process.h:268
bool m_privileged
Privilege level.
Definition Process.h:262
Address m_entry
Entry point of the program.
Definition Process.h:265
static Kernel * instance()
Retrieve the instance.
Definition Singleton.h:86
#define PAGESIZE
ARM uses 4K pages.
Definition ARMConstant.h:97
#define USR_MODE
ARM Program Status Register (CPSR)
Definition ARMConstant.h:46
#define SYS_MODE
Definition ARMConstant.h:52
u32 ProcessID
Process Identification Number.
Definition Types.h:140
unsigned long Address
A memory address.
Definition Types.h:131
#define ERROR(msg)
Output an error message.
Definition Log.h:61
unsigned int uint
Unsigned integer number.
Definition Types.h:44
unsigned char u8
Unsigned 8-bit number.
Definition Types.h:59
@ User
Definition Memory.h:44
@ Readable
Definition Memory.h:41
@ Writable
Definition Memory.h:42
Describes a range of memory.
Definition Allocator.h:66
Size alignment
Alignment in bytes or ZERO for default alignment.
Definition Allocator.h:69
Address address
Starting address of the memory range.
Definition Allocator.h:67
Size size
Amount of memory in bytes.
Definition Allocator.h:68
Contains all the CPU registers.
Definition ARMCore.h:244
u32 r0
Definition ARMCore.h:248
u32 pc
Definition ARMCore.h:249
u32 cpsr
Definition ARMCore.h:246
u32 sp
Definition ARMCore.h:247
u32 padding[4]
Definition ARMCore.h:245
Memory range.
Definition Memory.h:56
Size size
Size in number of bytes.
Definition Memory.h:59
Address phys
Physical address.
Definition Memory.h:58
Address virt
Virtual address.
Definition Memory.h:57
Access access
Page access flags.
Definition Memory.h:60