FreeNOS
ARM64Process.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2025 Ivan Tan
3 * Copyright (C) 2015 Niek Linnenbank
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <FreeNOS/System.h>
20#include <Log.h>
21#include <SplitAllocator.h>
22#include "ARM64Process.h"
23
24#define MEMALIGN16 16
25
26static bool firstProcess = true;
27extern u8 svcStack[PAGESIZE * 16];
28
30 : Process(id, entry, privileged, map)
31{
32}
33
35{
36 Memory::Range range;
37 Allocator::Range alloc_args;
38
39 // Create MMU context
40 m_memoryContext = new ARM64Paging(&m_map, Kernel::instance()->getAllocator());
41 if (!m_memoryContext)
42 {
43 ERROR("failed to create memory context");
44 return OutOfMemory;
45 }
46
47 // Initialize MMU context
49 if (memResult != MemoryContext::Success)
50 {
51 ERROR("failed to initialize MemoryContext: result = " << (int) memResult);
52 return OutOfMemory;
53 }
54
55 // Allocate User stack
58 alloc_args.address = 0;
59 alloc_args.size = range.size;
60 alloc_args.alignment = PAGESIZE;
61
62 if (Kernel::instance()->getAllocator()->allocate(alloc_args) != Allocator::Success)
63 {
64 ERROR("failed to allocate user stack");
65 return OutOfMemory;
66 }
67 range.phys = alloc_args.address;
68
69 // Map User stack
71 {
72 ERROR("failed to map user stack");
73 return MemoryMapError;
74 }
75
76 // Fill usermode program registers
78
79 // Finalize with generic initialization
80 return Process::initialize();
81}
82
86
88{
89 return &m_cpuState;
90}
91
93{
95}
96
98{
99 const Result r = Process::join(result);
100 if (r == Success)
101 {
102 m_cpuState.x0 = API::Success | (result << 16);
103 }
104
105 return r;
106}
107
109{
111
113 m_cpuState.sp = range.virt + range.size - MEMALIGN16; // user stack pointer
114 m_cpuState.pc = entry; // user program counter
115 m_cpuState.cpsr = (m_privileged ? 0x5 : 0x0); // current program status (CPSR)
116}
117
119{
120 DEBUG("proc " << previous->getID() << " switch to proc " << getID() );
121 // Activates memory context of this process
123
124 // First process starts from loadCoreState0
125 if (firstProcess)
126 {
127 firstProcess = false;
128
129 // Kernel stacks are currently 16KiB (see ARMBoot.S)
130 CPUState *ptr = ((CPUState *) (svcStack + sizeof(svcStack))) - 1;
131 MemoryBlock::copy(ptr, &m_cpuState, sizeof(*ptr));
132 NOTICE("svcStack " << (void *)svcStack);
133
134 // Switch to the actual SVC stack and switch to usermode
135 asm volatile ("ldr x0, =(svcStack + (4096*16))\n"
136 "mov sp, x0\n"
137 "sub sp, sp, %0\n"
138 "ldr x0, =returnFromEL0Call8\n"
139 "br x0\n" : : "i" (sizeof(m_cpuState)) );
140 }
141}
#define MEMALIGN16
static bool firstProcess
u8 svcStack[PAGESIZE *16]
u8 svcStack[PAGESIZE *4]
static bool firstProcess
u32 entry[]
Definition IntelACPI.h:1
@ Success
Definition API.h:70
ARM64 virtual memory implementation.
Definition ARM64Paging.h:51
virtual void execute(Process *previous)
Allow the Process to run on the CPU.
virtual Result initialize()
Initialize the Process.
void setCpuState(const CPUState *cpuState)
Overwrite the saved CPU registers for this task.
virtual ~ARM64Process()
Destructor function.
virtual void reset(const Address entry)
Restart execution at the given entry point.
virtual Result join(const uint result)
Complete waiting for another Process.
ARM64Process(ProcessID id, Address entry, bool privileged, const MemoryMap &map)
Constructor function.
CPUState m_cpuState
Contains all the CPU registers for this task.
const CPUState * cpuState() const
Retrieve saved CPU state.
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
ProcessID getID() const
Retrieve our ID number.
Definition Process.cpp:60
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
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
#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
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 pc
Definition ARMCore.h:249
u32 cpsr
Definition ARMCore.h:246
u32 sp
Definition ARMCore.h:247
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