FreeNOS
IntelProcess.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 <MemoryBlock.h>
20#include <Memory.h>
21#include <SplitAllocator.h>
22#include <intel/IntelPaging.h>
23#include "IntelProcess.h"
24
26 : Process(id, entry, privileged, map)
27{
28}
29
31{
32 Memory::Range range;
33 Allocator::Range allocPhys, allocVirt;
34
35 // Create MMU context
36 m_memoryContext = new IntelPaging(&m_map, Kernel::instance()->getAllocator());
37 if (!m_memoryContext)
38 {
39 ERROR("failed to create memory context");
40 return OutOfMemory;
41 }
42
43 // Initialize MMU context
45 if (memResult != MemoryContext::Success)
46 {
47 ERROR("failed to initialize MemoryContext: result = " << (int) memResult);
48 return OutOfMemory;
49 }
50
51 // Allocate User stack
54 allocPhys.address = 0;
55 allocPhys.size = range.size;
56 allocPhys.alignment = PAGESIZE;
57
58 if (Kernel::instance()->getAllocator()->allocate(allocPhys) != Allocator::Success)
59 {
60 ERROR("failed to allocate user stack");
61 return OutOfMemory;
62 }
63 range.phys = allocPhys.address;
64
65 // Map User stack
67 {
68 ERROR("failed to map user stack");
69 return MemoryMapError;
70 }
71
72 // Allocate Kernel stack
73 allocPhys.address = 0;
74 allocPhys.size = KernelStackSize;
75 allocPhys.alignment = PAGESIZE;
76
77 if (Kernel::instance()->getAllocator()->allocate(allocPhys, allocVirt) != Allocator::Success)
78 {
79 ERROR("failed to allocate kernel stack");
80 return OutOfMemory;
81 }
82 m_kernelStackBase = allocVirt.address;
84
85 // Initialize registers
87
88 // Finalize with generic initialization
89 return Process::initialize();
90}
91
93{
94 // Release the kernel stack memory page
97}
98
100{
102 const Address userStack = range.virt + range.size - MEMALIGN;
103 const u16 dataSel = m_privileged ? KERNEL_DS_SEL : USER_DS_SEL;
104 const u16 codeSel = m_privileged ? KERNEL_CS_SEL : USER_CS_SEL;
105
106 // Reset saved kernel stack pointer
108 - sizeof(IRQRegs0)
109 - sizeof(CPURegs);
110
111 // Fill kernel stack with initial (user)registers to restore
112 // loadCoreState: struct CPUState
113 CPUState *regs = (CPUState *) m_kernelStackBase - 1;
114 MemoryBlock::set(regs, 0, sizeof(CPUState));
115 regs->seg.ss0 = KERNEL_DS_SEL;
116 regs->seg.fs = dataSel;
117 regs->seg.gs = dataSel;
118 regs->seg.es = dataSel;
119 regs->seg.ds = dataSel;
120 regs->regs.ebp = userStack;
121 regs->regs.esp0 = m_kernelStack;
122 regs->irq.eip = m_entry;
123 regs->irq.cs = codeSel;
125 INTEL_EFLAGS_IRQ | (0x3 << 12);
126 regs->irq.esp3 = userStack;
127 regs->irq.ss3 = dataSel;
128
129 // restoreState: iret
130 IRQRegs0 *irq = (IRQRegs0 *) regs - 1;
131 irq->eip = (Address) loadCoreState;
132 irq->cs = KERNEL_CS_SEL;
134
135 // restoreState: popa
136 CPURegs *pusha = (CPURegs *) irq - 1;
137 MemoryBlock::set(pusha, 0, sizeof(CPURegs));
138 pusha->ebp = m_kernelStackBase - sizeof(CPURegs);
139 pusha->esp0 = pusha->ebp;
140}
141
143{
144 IntelProcess *p = (IntelProcess *) previous;
145
146 // Reload Task State Register (with kernel stack for interrupts)
148
149 // Activate the memory context of this process
151
152 // Switch kernel stack (includes saved userspace registers)
155}
u32 entry[]
Definition IntelACPI.h:1
Intel virtual memory implementation.
Definition IntelPaging.h:44
Process which may execute on an Intel CPU.
Address m_kernelStackBase
Base kernel stack (fixed)
Address m_kernelStack
Current kernel stack address (changes during execution).
virtual void execute(Process *previous)
Execute the process.
IntelProcess(ProcessID id, Address entry, bool privileged, const MemoryMap &map)
Constructor function.
virtual void reset(const Address entry)
Restart execution at the given entry point.
static const Size KernelStackSize
Size of the kernel stack.
virtual Result initialize()
Initialize the Process.
virtual ~IntelProcess()
Destructor function.
SplitAllocator * getAllocator()
Get physical memory allocator.
Definition Kernel.cpp:138
static void * set(void *dest, int ch, unsigned count)
Fill memory with a constant byte.
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
Result
Result codes.
Definition Process.h:55
@ 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
Allocator which separates kernel mapped memory at virtual and physical addresses.
Address toPhysical(const Address virt) const
Convert Address to physical pointer.
virtual Result release(const Address addr)
Release memory page.
static Kernel * instance()
Retrieve the instance.
Definition Singleton.h:86
#define PAGESIZE
ARM uses 4K pages.
Definition ARMConstant.h:97
#define MEMALIGN
Memory address alignment.
#define KERNEL_DS_SEL
#define USER_CS_SEL
C void loadCoreState()
Load Core State.
#define INTEL_EFLAGS_IRQ
Definition IntelCore.h:138
#define USER_DS_SEL
#define INTEL_EFLAGS_DEFAULT
Definition IntelCore.h:137
TSS kernelTss
Task State Segment.
#define KERNEL_CS_SEL
C void switchCoreState(Address *currentStack, Address stack)
Switch Core Stack.
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 short u16
Unsigned 16-bit number.
Definition Types.h:56
#define ZERO
Zero value.
Definition Macros.h:43
@ 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
Structure represents the pusha/popa format.
Definition IntelCore.h:201
u32 ebp
Definition IntelCore.h:202
u32 esp0
Definition IntelCore.h:202
Contains all the CPU registers.
Definition ARMCore.h:244
IRQRegs3 irq
Definition IntelCore.h:250
SegRegs seg
Definition IntelCore.h:241
CPURegs regs
Definition IntelCore.h:244
Privileged Interrupt Registers (ring 0)
Definition IntelCore.h:213
u32 eflags
Definition IntelCore.h:214
u32 eflags
Definition IntelCore.h:231
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
u32 ss0
Definition IntelCore.h:193
u32 esp0
Definition IntelCore.h:155