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)
55  return API::AccessViolation;
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 }
MemoryBlock::copy
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Definition: MemoryBlock.cpp:36
VMCopyHandler
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
SplitAllocator.h
ProcessManager
Represents a process which may run on the host.
Definition: ProcessManager.h:44
MemoryContext
Virtual memory abstract interface.
Definition: MemoryContext.h:42
API::Result
Result
Enumeration of generic kernel API result codes.
Definition: API.h:68
API::Operation
Operation
Various actions which may be performed inside an APIHandler.
Definition: API.h:91
Process
Represents a process which may run on the host.
Definition: Process.h:44
Memory::Writable
@ Writable
Definition: Memory.h:42
PAGEMASK
#define PAGEMASK
Mask to find the page.
Definition: ARMConstant.h:121
PAGESIZE
#define PAGESIZE
ARM uses 4K pages.
Definition: ARMConstant.h:97
API::Write
@ Write
Definition: API.h:99
MemoryContext::map
virtual Result map(Address virt, Address phys, Memory::Access access)=0
Map a physical page to a virtual address.
API::AccessViolation
@ AccessViolation
Definition: API.h:71
ProcessID
u32 ProcessID
Process Identification Number.
Definition: Types.h:140
Address
unsigned long Address
A memory address.
Definition: Types.h:131
MemoryBlock.h
MemoryContext::unmap
virtual Result unmap(Address virt)=0
Unmap a virtual address.
Memory::Readable
@ Readable
Definition: Memory.h:41
Kernel::getProcessManager
ProcessManager * getProcessManager()
Get process manager.
Definition: Kernel.cpp:143
API::RangeError
@ RangeError
Definition: API.h:72
API::Read
@ Read
Definition: API.h:98
API::IOError
@ IOError
Definition: API.h:76
MemoryContext::lookup
virtual Result lookup(Address virt, Address *phys) const =0
Translate virtual address to physical address.
SELF
#define SELF
Definition: ProcessID.h:35
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
Process::getMemoryContext
MemoryContext * getMemoryContext()
Get MMU memory context.
Definition: Process.cpp:95
MemoryContext::Result
Result
Result codes.
Definition: MemoryContext.h:49
MemoryContext::Success
@ Success
Definition: MemoryContext.h:51
MemoryContext::findFree
virtual Result findFree(Size size, MemoryMap::Region region, Address *virt) const
Find unused memory.
Definition: MemoryContext.cpp:117
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
WeakSingleton< Kernel >::instance
static Kernel * instance()
Retrieve the instance.
Definition: Singleton.h:86
MemoryMap::KernelPrivate
@ KernelPrivate
< Kernel dynamic memory mappings
Definition: MemoryMap.h:55
ProcessManager::get
Process * get(const ProcessID id)
Retrieve a Process by it's ID.
Definition: ProcessManager.cpp:95
API::NotFound
@ NotFound
Definition: API.h:73
assert
#define assert(exp)
Insert program diagnostics.
Definition: assert.h:60
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
API::Success
@ Success
Definition: API.h:70
ProcessManager::current
Process * current()
Current process running.
Definition: ProcessManager.cpp:203
API::ReadPhys
@ ReadPhys
Definition: API.h:100
VMCopy.h