FreeNOS
VMCopy.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2009 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 <MemoryBlock.h>
21#include <SplitAllocator.h>
22#include "VMCopy.h"
23
25 const API::Operation how,
26 const Address ours,
27 const Address theirs,
28 const Size sz)
29{
32 Size bytes = 0, pageOff, total = 0;
33 Address paddr, vaddr;
34 Address ourAddr = ours, theirAddr = theirs;
35 Process *proc;
36
37 DEBUG("");
38
39 // Find the corresponding Process
40 if (procID == SELF)
41 proc = procs->current();
42 else if (!(proc = procs->get(procID)))
43 return API::NotFound;
44
45 MemoryContext *local = procs->current()->getMemoryContext();
46 MemoryContext *remote = proc->getMemoryContext();
47
48 // Keep on going until all memory is processed
49 while (total < sz)
50 {
51 // Update variables
52 if (how == API::ReadPhys)
53 paddr = theirAddr & PAGEMASK;
54 else if (remote->lookup(theirAddr, &paddr) != MemoryContext::Success)
56
57 assert(!(paddr & ~PAGEMASK));
58 pageOff = theirAddr & ~PAGEMASK;
59 bytes = (PAGESIZE - pageOff) < (sz - total) ?
60 (PAGESIZE - pageOff) : (sz - total);
61
62 // Valid address?
63 if (!paddr) break;
64
65 // Map their address into our local address space
67 return API::RangeError;
68
69 if ((memResult = local->map(vaddr, paddr,
71 {
72 ERROR("failed to map physical address " << (void *)paddr << ": " << (int)memResult);
73 return API::IOError;
74 }
75
76 // Process the action appropriately
77 switch (how)
78 {
79 case API::Read:
80 case API::ReadPhys:
81 MemoryBlock::copy((void *)ourAddr, (void *)(vaddr + pageOff), bytes);
82 break;
83
84 case API::Write:
85 MemoryBlock::copy((void *)(vaddr + pageOff), (void *)ourAddr, bytes);
86 break;
87
88 default:
89 ;
90 }
91
92 // Unmap, which must always succeed
93 memResult = local->unmap(vaddr);
94 assert(memResult == MemoryContext::Success);
95
96 // Update counters
97 ourAddr += bytes;
98 theirAddr += bytes;
99 total += bytes;
100 }
101
102 return API::Success;
103}
Result
Enumeration of generic kernel API result codes.
Definition API.h:69
@ NotFound
Definition API.h:73
@ IOError
Definition API.h:76
@ RangeError
Definition API.h:72
@ Success
Definition API.h:70
@ AccessViolation
Definition API.h:71
Operation
Various actions which may be performed inside an APIHandler.
Definition API.h:92
@ ReadPhys
Definition API.h:100
@ Read
Definition API.h:98
@ Write
Definition API.h:99
ProcessManager * getProcessManager()
Get process manager.
Definition Kernel.cpp:143
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Virtual memory abstract interface.
Result
Result codes.
virtual Result unmap(Address virt)=0
Unmap a virtual address.
virtual Result findFree(Size size, MemoryMap::Region region, Address *virt) const
Find unused memory.
virtual Result map(Address virt, Address phys, Memory::Access access)=0
Map a physical page to a virtual address.
virtual Result lookup(Address virt, Address *phys) const =0
Translate virtual address to physical address.
@ KernelPrivate
< Kernel dynamic memory mappings
Definition MemoryMap.h:55
Represents a process which may run on the host.
Process * get(const ProcessID id)
Retrieve a Process by it's ID.
Process * current()
Current process running.
Represents a process which may run on the host.
Definition Process.h:45
MemoryContext * getMemoryContext()
Get MMU memory context.
Definition Process.cpp:95
static Kernel * instance()
Retrieve the instance.
Definition Singleton.h:86
API::Result VMCopyHandler(const ProcessID procID, const API::Operation how, const Address ours, const Address theirs, const Size sz)
Kernel handler prototype.
Definition VMCopy.cpp:24
#define SELF
Definition ProcessID.h:35
#define PAGESIZE
ARM uses 4K pages.
Definition ARMConstant.h:97
#define PAGEMASK
Mask to find the page.
#define assert(exp)
Insert program diagnostics.
Definition assert.h:60
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 Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
@ Readable
Definition Memory.h:41
@ Writable
Definition Memory.h:42