VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c@ 43363

Last change on this file since 43363 was 43363, checked in by vboxsync, 12 years ago

Haiku Additions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.7 KB
Line 
1/* $Id: memobj-r0drv-haiku.c 43363 2012-09-20 09:56:07Z vboxsync $ */
2/** @file
3 * IPRT - Ring-0 Memory Objects, Haiku.
4 */
5
6/*
7 * Copyright (C) 2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "the-haiku-kernel.h"
32
33#include <iprt/memobj.h>
34#include <iprt/mem.h>
35#include <iprt/err.h>
36#include <iprt/assert.h>
37#include <iprt/log.h>
38#include <iprt/param.h>
39#include <iprt/process.h>
40#include "internal/memobj.h"
41
42/*******************************************************************************
43* Structures and Typedefs *
44*******************************************************************************/
45/**
46 * The Haiku version of the memory object structure.
47 */
48typedef struct RTR0MEMOBJHAIKU
49{
50 /** The core structure. */
51 RTR0MEMOBJINTERNAL Core;
52 /** Area identifier */
53 area_id AreaId;
54} RTR0MEMOBJHAIKU, *PRTR0MEMOBJHAIKU;
55
56
57//MALLOC_DEFINE(M_IPRTMOBJ, "iprtmobj", "IPRT - R0MemObj");
58#if 0
59/**
60 * Gets the virtual memory map the specified object is mapped into.
61 *
62 * @returns VM map handle on success, NULL if no map.
63 * @param pMem The memory object.
64 */
65static vm_map_t rtR0MemObjHaikuGetMap(PRTR0MEMOBJINTERNAL pMem)
66{
67 switch (pMem->enmType)
68 {
69 case RTR0MEMOBJTYPE_PAGE:
70 case RTR0MEMOBJTYPE_LOW:
71 case RTR0MEMOBJTYPE_CONT:
72 return kernel_map;
73
74 case RTR0MEMOBJTYPE_PHYS:
75 case RTR0MEMOBJTYPE_PHYS_NC:
76 return NULL; /* pretend these have no mapping atm. */
77
78 case RTR0MEMOBJTYPE_LOCK:
79 return pMem->u.Lock.R0Process == NIL_RTR0PROCESS
80 ? kernel_map
81 : &((struct proc *)pMem->u.Lock.R0Process)->p_vmspace->vm_map;
82
83 case RTR0MEMOBJTYPE_RES_VIRT:
84 return pMem->u.ResVirt.R0Process == NIL_RTR0PROCESS
85 ? kernel_map
86 : &((struct proc *)pMem->u.ResVirt.R0Process)->p_vmspace->vm_map;
87
88 case RTR0MEMOBJTYPE_MAPPING:
89 return pMem->u.Mapping.R0Process == NIL_RTR0PROCESS
90 ? kernel_map
91 : &((struct proc *)pMem->u.Mapping.R0Process)->p_vmspace->vm_map;
92
93 default:
94 return NULL;
95 }
96}
97#endif
98
99int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
100{
101 PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)pMem;
102 int rc = B_OK;
103
104 switch (pMemHaiku->Core.enmType)
105 {
106 case RTR0MEMOBJTYPE_PAGE:
107 case RTR0MEMOBJTYPE_LOW:
108 case RTR0MEMOBJTYPE_CONT:
109 case RTR0MEMOBJTYPE_MAPPING:
110 case RTR0MEMOBJTYPE_PHYS:
111 case RTR0MEMOBJTYPE_PHYS_NC:
112 {
113 if (pMemHaiku->AreaId > -1)
114 rc = delete_area(pMemHaiku->AreaId);
115
116 AssertMsg(rc == B_OK, ("%#x", rc));
117 break;
118 }
119
120 case RTR0MEMOBJTYPE_LOCK:
121 {
122 team_id team = B_SYSTEM_TEAM;
123
124 if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
125 team = ((team_id)pMemHaiku->Core.u.Lock.R0Process);
126
127 rc = unlock_memory_etc(team, pMemHaiku->Core.pv, pMemHaiku->Core.cb, B_READ_DEVICE);
128 AssertMsg(rc == B_OK, ("%#x", rc));
129 break;
130 }
131
132 case RTR0MEMOBJTYPE_RES_VIRT:
133 {
134 team_id team = B_SYSTEM_TEAM;
135 if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
136 team = ((team_id)pMemHaiku->Core.u.Lock.R0Process);
137
138 rc = vm_unreserve_address_range(team, pMemHaiku->Core.pv, pMemHaiku->Core.cb);
139 AssertMsg(rc == B_OK, ("%#x", rc));
140 break;
141 }
142
143 default:
144 AssertMsgFailed(("enmType=%d\n", pMemHaiku->Core.enmType));
145 return VERR_INTERNAL_ERROR;
146 }
147
148 return VINF_SUCCESS;
149}
150
151static int rtR0MemObjNativeAllocArea(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
152 bool fExecutable, RTR0MEMOBJTYPE type, RTHCPHYS PhysHighest, size_t uAlignment)
153{
154 NOREF(fExecutable);
155
156 int rc;
157 void *pvMap = NULL;
158 const char *pszName = NULL;
159 uint32 addressSpec = B_ANY_KERNEL_ADDRESS;
160 uint32 fLock = ~0U;
161 LogFlowFunc(("ppMem=%p cb=%u, fExecutable=%s, type=%08x, PhysHighest=%RX64 uAlignment=%u\n", ppMem, (unsigned)cb,
162 fExecutable ? "true" : "false", type, PhysHighest, (unsigned)uAlignment));
163
164 switch (type)
165 {
166 case RTR0MEMOBJTYPE_PAGE:
167 pszName = "IPRT R0MemObj Alloc";
168 fLock = B_FULL_LOCK;
169 break;
170 case RTR0MEMOBJTYPE_LOW:
171 pszName = "IPRT R0MemObj AllocLow";
172 fLock = B_32_BIT_FULL_LOCK;
173 break;
174 case RTR0MEMOBJTYPE_CONT:
175 pszName = "IPRT R0MemObj AllocCont";
176 fLock = B_32_BIT_CONTIGUOUS;
177 break;
178#if 0
179 case RTR0MEMOBJTYPE_MAPPING:
180 pszName = "IPRT R0MemObj Mapping";
181 fLock = B_FULL_LOCK;
182 break;
183#endif
184 case RTR0MEMOBJTYPE_PHYS:
185 /** @todo alignment */
186 if (uAlignment != PAGE_SIZE)
187 return VERR_NOT_SUPPORTED;
188 /** @todo r=ramshankar: no 'break' here?? */
189 case RTR0MEMOBJTYPE_PHYS_NC:
190 pszName = "IPRT R0MemObj AllocPhys";
191 fLock = (PhysHighest < _4G ? B_LOMEM : B_32_BIT_CONTIGUOUS);
192 break;
193#if 0
194 case RTR0MEMOBJTYPE_LOCK:
195 break;
196#endif
197 default:
198 return VERR_INTERNAL_ERROR;
199 }
200
201 /* Create the object. */
202 PRTR0MEMOBJHAIKU pMemHaiku;
203 pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), type, NULL, cb);
204 if (RT_UNLIKELY(!pMemHaiku))
205 return VERR_NO_MEMORY;
206
207 rc = pMemHaiku->AreaId = create_area(pszName, &pvMap, addressSpec, cb, fLock, B_READ_AREA | B_WRITE_AREA);
208 if (pMemHaiku->AreaId >= 0)
209 {
210 physical_entry physMap[2];
211 pMemHaiku->Core.pv = pvMap; /* store start address */
212 switch (type)
213 {
214 case RTR0MEMOBJTYPE_CONT:
215 rc = get_memory_map(pvMap, cb, physMap, 2);
216 if (rc == B_OK)
217 pMemHaiku->Core.u.Cont.Phys = physMap[0].address;
218 break;
219
220 case RTR0MEMOBJTYPE_PHYS:
221 case RTR0MEMOBJTYPE_PHYS_NC:
222 rc = get_memory_map(pvMap, cb, physMap, 2);
223 if (rc == B_OK)
224 {
225 pMemHaiku->Core.u.Phys.PhysBase = physMap[0].address;
226 pMemHaiku->Core.u.Phys.fAllocated = true;
227 }
228 break;
229
230 default:
231 break;
232 }
233 if (rc >= B_OK)
234 {
235 *ppMem = &pMemHaiku->Core;
236 return VINF_SUCCESS;
237 }
238
239 delete_area(pMemHaiku->AreaId);
240 }
241
242 rtR0MemObjDelete(&pMemHaiku->Core);
243 return RTErrConvertFromHaikuKernReturn(rc);
244}
245
246
247int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
248{
249 return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_PAGE, 0 /* PhysHighest */, 0 /* uAlignment */);
250}
251
252
253int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
254{
255 return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_LOW, 0 /* PhysHighest */, 0 /* uAlignment */);
256}
257
258
259int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
260{
261 return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_CONT, 0 /* PhysHighest */, 0 /* uAlignment */);
262}
263
264int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
265{
266 return rtR0MemObjNativeAllocArea(ppMem, cb, false, RTR0MEMOBJTYPE_PHYS, PhysHighest, uAlignment);
267}
268
269
270int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
271{
272 return rtR0MemObjNativeAllocPhys(ppMem, cb, PhysHighest, PAGE_SIZE);
273}
274
275
276int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
277{
278 AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
279 LogFlowFunc(("ppMem=%p Phys=%08x cb=%u uCachePolicy=%x\n", ppMem, Phys, (unsigned)cb, uCachePolicy));
280
281 /* Create the object. */
282 PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_PHYS, NULL, cb);
283 if (!pMemHaiku)
284 return VERR_NO_MEMORY;
285
286 /* There is no allocation here, it needs to be mapped somewhere first. */
287 pMemHaiku->AreaId = -1;
288 pMemHaiku->Core.u.Phys.fAllocated = false;
289 pMemHaiku->Core.u.Phys.PhysBase = Phys;
290 pMemHaiku->Core.u.Phys.uCachePolicy = uCachePolicy;
291 *ppMem = &pMemHaiku->Core;
292 return VINF_SUCCESS;
293}
294
295
296/**
297 * Worker locking the memory in either kernel or user maps.
298 *
299 * @returns IPRT status code.
300 * @param ppMem Where to store the allocated memory object.
301 * @param pvStart The starting address.
302 * @param cb The size of the block.
303 * @param fAccess The mapping protection to apply.
304 * @param R0Process The process to map the memory to (use NIL_RTR0PROCESS
305 * for the kernel)
306 * @param fFlags Memory flags (B_READ_DEVICE indicates the memory is
307 * intended to be written from a "device").
308 */
309static int rtR0MemObjNativeLockInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvStart, size_t cb, uint32_t fAccess,
310 RTR0PROCESS R0Process, int fFlags)
311{
312 NOREF(fAccess);
313 int rc;
314 team_id TeamId = B_SYSTEM_TEAM;
315
316 LogFlowFunc(("ppMem=%p pvStart=%p cb=%u fAccess=%x R0Process=%d fFlags=%x\n", ppMem, pvStart, cb, fAccess, R0Process,
317 fFlags));
318
319 /* Create the object. */
320 PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_LOCK, pvStart, cb);
321 if (RT_UNLIKELY(!pMemHaiku))
322 return VERR_NO_MEMORY;
323
324 if (R0Process != NIL_RTR0PROCESS)
325 TeamId = (team_id)R0Process;
326 rc = lock_memory_etc(TeamId, pvStart, cb, fFlags);
327 if (rc == B_OK)
328 {
329 pMemHaiku->AreaId = -1;
330 pMemHaiku->Core.u.Lock.R0Process = R0Process;
331 *ppMem = &pMemHaiku->Core;
332 return VINF_SUCCESS;
333 }
334 rtR0MemObjDelete(&pMemHaiku->Core);
335 return RTErrConvertFromHaikuKernReturn(rc);
336}
337
338
339int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
340{
341 return rtR0MemObjNativeLockInMap(ppMem, (void *)R3Ptr, cb, fAccess, R0Process, B_READ_DEVICE);
342}
343
344
345int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
346{
347 return rtR0MemObjNativeLockInMap(ppMem, pv, cb, fAccess, NIL_RTR0PROCESS, B_READ_DEVICE);
348}
349
350
351#if 0
352/** @todo Reserve address space */
353/**
354 * Worker for the two virtual address space reservers.
355 *
356 * We're leaning on the examples provided by mmap and vm_mmap in vm_mmap.c here.
357 */
358static int rtR0MemObjNativeReserveInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment,
359 RTR0PROCESS R0Process)
360{
361 int rc;
362 team_id TeamId = B_SYSTEM_TEAM;
363
364 LogFlowFunc(("ppMem=%p pvFixed=%p cb=%u uAlignment=%u R0Process=%d\n", ppMem, pvFixed, (unsigned)cb, uAlignment, R0Process));
365
366 if (R0Process != NIL_RTR0PROCESS)
367 team = (team_id)R0Process;
368
369 /* Check that the specified alignment is supported. */
370 if (uAlignment > PAGE_SIZE)
371 return VERR_NOT_SUPPORTED;
372
373 /* Create the object. */
374 PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_RES_VIRT, NULL, cb);
375 if (!pMemHaiku)
376 return VERR_NO_MEMORY;
377
378 /* Ask the kernel to reserve the address range. */
379 //XXX: vm_reserve_address_range ?
380 return VERR_NOT_SUPPORTED;
381}
382#endif
383
384
385int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
386{
387 return VERR_NOT_SUPPORTED;
388}
389
390
391int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
392{
393 return VERR_NOT_SUPPORTED;
394}
395
396
397int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
398 unsigned fProt, size_t offSub, size_t cbSub)
399{
400 PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
401 PRTR0MEMOBJHAIKU pMemHaiku;
402 area_id area = -1;
403 void *pvMap = pvFixed;
404 uint32 uAddrSpec = B_EXACT_ADDRESS;
405 uint32 fProtect = 0;
406 int rc = VERR_MAP_FAILED;
407 AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
408 AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
409#if 0
410 /** @todo r=ramshankar: Wrong format specifiers, fix later! */
411 dprintf("%s(%p, %p, %p, %d, %x, %u, %u)\n", __FUNCTION__, ppMem, pMemToMap, pvFixed, uAlignment,
412 fProt, offSub, cbSub);
413#endif
414 /* Check that the specified alignment is supported. */
415 if (uAlignment > PAGE_SIZE)
416 return VERR_NOT_SUPPORTED;
417
418 /* We can't map anything to the first page, sorry. */
419 if (pvFixed == 0)
420 return VERR_NOT_SUPPORTED;
421
422 if (fProt & RTMEM_PROT_READ)
423 fProtect |= B_KERNEL_READ_AREA;
424 if (fProt & RTMEM_PROT_WRITE)
425 fProtect |= B_KERNEL_WRITE_AREA;
426
427 /*
428 * Either the object we map has an area associated with, which we can clone,
429 * or it's a physical address range which we must map.
430 */
431 if (pMemToMapHaiku->AreaId > -1)
432 {
433 if (pvFixed == (void *)-1)
434 uAddrSpec = B_ANY_KERNEL_ADDRESS;
435
436 rc = area = clone_area("IPRT R0MemObj MapKernel", &pvMap, uAddrSpec, fProtect, pMemToMapHaiku->AreaId);
437 LogFlow(("rtR0MemObjNativeMapKernel: clone_area uAddrSpec=%d fProtect=%x AreaId=%d rc=%d\n", uAddrSpec, fProtect,
438 pMemToMapHaiku->AreaId, rc));
439 }
440 else if (pMemToMapHaiku->Core.enmType == RTR0MEMOBJTYPE_PHYS)
441 {
442 /* map_physical_memory() won't let you choose where. */
443 if (pvFixed != (void *)-1)
444 return VERR_NOT_SUPPORTED;
445 uAddrSpec = B_ANY_KERNEL_ADDRESS;
446
447 rc = area = map_physical_memory("IPRT R0MemObj MapKernelPhys", (phys_addr_t)pMemToMapHaiku->Core.u.Phys.PhysBase,
448 pMemToMapHaiku->Core.cb, uAddrSpec, fProtect, &pvMap);
449 }
450 else
451 return VERR_NOT_SUPPORTED;
452
453 if (rc >= B_OK)
454 {
455 /* Create the object. */
456 pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), RTR0MEMOBJTYPE_MAPPING, pvMap,
457 pMemToMapHaiku->Core.cb);
458 if (RT_UNLIKELY(!pMemHaiku))
459 return VERR_NO_MEMORY;
460
461 pMemHaiku->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
462 pMemHaiku->Core.pv = pvMap;
463 pMemHaiku->AreaId = area;
464 *ppMem = &pMemHaiku->Core;
465 return VINF_SUCCESS;
466 }
467 rc = VERR_MAP_FAILED;
468
469 /** @todo finish the implementation. */
470
471 rtR0MemObjDelete(&pMemHaiku->Core);
472 return rc;
473}
474
475
476int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
477{
478#if 0
479 /*
480 * Check for unsupported stuff.
481 */
482 AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
483 AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
484 if (uAlignment > PAGE_SIZE)
485 return VERR_NOT_SUPPORTED;
486
487 int rc;
488 PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
489 struct proc *pProc = (struct proc *)R0Process;
490 struct vm_map *pProcMap = &pProc->p_vmspace->vm_map;
491
492 /* calc protection */
493 vm_prot_t ProtectionFlags = 0;
494 if ((fProt & RTMEM_PROT_NONE) == RTMEM_PROT_NONE)
495 ProtectionFlags = VM_PROT_NONE;
496 if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ)
497 ProtectionFlags |= VM_PROT_READ;
498 if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE)
499 ProtectionFlags |= VM_PROT_WRITE;
500 if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC)
501 ProtectionFlags |= VM_PROT_EXECUTE;
502
503 /* calc mapping address */
504 PROC_LOCK(pProc);
505 vm_offset_t AddrR3 = round_page((vm_offset_t)pProc->p_vmspace->vm_daddr + lim_max(pProc, RLIMIT_DATA));
506 PROC_UNLOCK(pProc);
507
508 /* Insert the object in the map. */
509 rc = vm_map_find(pProcMap, /* Map to insert the object in */
510 NULL, /* Object to map */
511 0, /* Start offset in the object */
512 &AddrR3, /* Start address IN/OUT */
513 pMemToMap->cb, /* Size of the mapping */
514 TRUE, /* Whether a suitable address should be searched for first */
515 ProtectionFlags, /* protection flags */
516 VM_PROT_ALL, /* Maximum protection flags */
517 0); /* Copy on write */
518
519 /* Map the memory page by page into the destination map. */
520 if (rc == KERN_SUCCESS)
521 {
522 size_t cPages = pMemToMap->cb >> PAGE_SHIFT;;
523 pmap_t pPhysicalMap = pProcMap->pmap;
524 vm_offset_t AddrR3Dst = AddrR3;
525
526 if ( pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS
527 || pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS_NC
528 || pMemToMap->enmType == RTR0MEMOBJTYPE_PAGE)
529 {
530 /* Mapping physical allocations */
531 Assert(cPages == pMemToMapHaiku->u.Phys.cPages);
532
533 /* Insert the memory page by page into the mapping. */
534 for (uint32_t iPage = 0; iPage < cPages; iPage++)
535 {
536 vm_page_t pPage = pMemToMapHaiku->u.Phys.apPages[iPage];
537
538 MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE);
539 AddrR3Dst += PAGE_SIZE;
540 }
541 }
542 else
543 {
544 /* Mapping cont or low memory types */
545 vm_offset_t AddrToMap = (vm_offset_t)pMemToMap->pv;
546
547 for (uint32_t iPage = 0; iPage < cPages; iPage++)
548 {
549 vm_page_t pPage = PHYS_TO_VM_PAGE(vtophys(AddrToMap));
550
551 MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE);
552 AddrR3Dst += PAGE_SIZE;
553 AddrToMap += PAGE_SIZE;
554 }
555 }
556 }
557
558 if (RT_SUCCESS(rc))
559 {
560 /*
561 * Create a mapping object for it.
562 */
563 PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU),
564 RTR0MEMOBJTYPE_MAPPING,
565 (void *)AddrR3,
566 pMemToMap->cb);
567 if (pMemHaiku)
568 {
569 Assert((vm_offset_t)pMemHaiku->Core.pv == AddrR3);
570 pMemHaiku->Core.u.Mapping.R0Process = R0Process;
571 *ppMem = &pMemHaiku->Core;
572 return VINF_SUCCESS;
573 }
574
575 rc = vm_map_remove(pProcMap, ((vm_offset_t)AddrR3), ((vm_offset_t)AddrR3) + pMemToMap->cb);
576 AssertMsg(rc == KERN_SUCCESS, ("Deleting mapping failed\n"));
577 }
578#endif
579 return VERR_NOT_SUPPORTED;
580}
581
582
583int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
584{
585 return VERR_NOT_SUPPORTED;
586}
587
588
589RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
590{
591 PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)pMem;
592 status_t rc;
593
594 /** @todo r=ramshankar: Validate objects */
595
596 LogFlow(("rtR0MemObjNativeGetPagePhysAddr: pMem=%p enmType=%x iPage=%u\n", pMem, pMemHaiku->Core.enmType, (unsigned)iPage));
597
598 switch (pMemHaiku->Core.enmType)
599 {
600 case RTR0MEMOBJTYPE_LOCK:
601 {
602 team_id TeamId = B_SYSTEM_TEAM;
603 physical_entry aPhysMap[2];
604 int32 cPhysMap = 2; /** @todo r=ramshankar: why not use RT_ELEMENTS? */
605
606 if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
607 TeamId = (team_id)pMemHaiku->Core.u.Lock.R0Process;
608 void *pb = pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
609
610 rc = get_memory_map_etc(TeamId, pb, B_PAGE_SIZE, aPhysMap, &cPhysMap);
611 if (rc < B_OK || cPhysMap < 1)
612 return NIL_RTHCPHYS;
613
614 return aPhysMap[0].address;
615 }
616
617#if 0
618 case RTR0MEMOBJTYPE_MAPPING:
619 {
620 vm_offset_t pb = (vm_offset_t)pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
621
622 if (pMemHaiku->Core.u.Mapping.R0Process != NIL_RTR0PROCESS)
623 {
624 struct proc *pProc = (struct proc *)pMemHaiku->Core.u.Mapping.R0Process;
625 struct vm_map *pProcMap = &pProc->p_vmspace->vm_map;
626 pmap_t pPhysicalMap = pProcMap->pmap;
627
628 return pmap_extract(pPhysicalMap, pb);
629 }
630 return vtophys(pb);
631 }
632#endif
633 case RTR0MEMOBJTYPE_CONT:
634 return pMemHaiku->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
635
636 case RTR0MEMOBJTYPE_PHYS:
637 return pMemHaiku->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
638
639 case RTR0MEMOBJTYPE_LOW:
640 case RTR0MEMOBJTYPE_PAGE:
641 case RTR0MEMOBJTYPE_PHYS_NC:
642 {
643 team_id TeamId = B_SYSTEM_TEAM;
644 physical_entry aPhysMap[2];
645 int32 cPhysMap = 2; /** @todo r=ramshankar: why not use RT_ELEMENTS? */
646
647 void *pb = pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
648 rc = get_memory_map_etc(TeamId, pb, B_PAGE_SIZE, aPhysMap, &cPhysMap);
649 if (rc < B_OK || cPhysMap < 1)
650 return NIL_RTHCPHYS;
651
652 return aPhysMap[0].address;
653 }
654
655 case RTR0MEMOBJTYPE_RES_VIRT:
656 default:
657 return NIL_RTHCPHYS;
658 }
659}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette