memobj-r0drv-haiku.c revision 2b3dc93fedb4e72ac5b3cbaa89a9fc2f559be550
/* $Id$ */
/** @file
* IPRT - Ring-0 Memory Objects, Haiku.
*/
/*
* Copyright (C) 2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "the-haiku-kernel.h"
#include <iprt/memobj.h>
#include <iprt/mem.h>
#include <iprt/err.h>
#include <iprt/assert.h>
#include <iprt/log.h>
#include <iprt/param.h>
#include <iprt/process.h>
#include "internal/memobj.h"
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* The Haiku version of the memory object structure.
*/
typedef struct RTR0MEMOBJHAIKU
{
/** The core structure. */
RTR0MEMOBJINTERNAL Core;
/** Area identifier */
area_id AreaId;
} RTR0MEMOBJHAIKU, *PRTR0MEMOBJHAIKU;
//MALLOC_DEFINE(M_IPRTMOBJ, "iprtmobj", "IPRT - R0MemObj");
#if 0
/**
* Gets the virtual memory map the specified object is mapped into.
*
* @returns VM map handle on success, NULL if no map.
* @param pMem The memory object.
*/
static vm_map_t rtR0MemObjHaikuGetMap(PRTR0MEMOBJINTERNAL pMem)
{
switch (pMem->enmType)
{
case RTR0MEMOBJTYPE_PAGE:
case RTR0MEMOBJTYPE_LOW:
case RTR0MEMOBJTYPE_CONT:
return kernel_map;
case RTR0MEMOBJTYPE_PHYS:
case RTR0MEMOBJTYPE_PHYS_NC:
return NULL; /* pretend these have no mapping atm. */
case RTR0MEMOBJTYPE_LOCK:
return pMem->u.Lock.R0Process == NIL_RTR0PROCESS
? kernel_map
: &((struct proc *)pMem->u.Lock.R0Process)->p_vmspace->vm_map;
case RTR0MEMOBJTYPE_RES_VIRT:
return pMem->u.ResVirt.R0Process == NIL_RTR0PROCESS
? kernel_map
: &((struct proc *)pMem->u.ResVirt.R0Process)->p_vmspace->vm_map;
case RTR0MEMOBJTYPE_MAPPING:
return pMem->u.Mapping.R0Process == NIL_RTR0PROCESS
? kernel_map
: &((struct proc *)pMem->u.Mapping.R0Process)->p_vmspace->vm_map;
default:
return NULL;
}
}
#endif
int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
{
PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)pMem;
int rc = B_OK;
switch (pMemHaiku->Core.enmType)
{
case RTR0MEMOBJTYPE_PAGE:
case RTR0MEMOBJTYPE_LOW:
case RTR0MEMOBJTYPE_CONT:
case RTR0MEMOBJTYPE_MAPPING:
case RTR0MEMOBJTYPE_PHYS:
case RTR0MEMOBJTYPE_PHYS_NC:
{
if (pMemHaiku->AreaId > -1)
rc = delete_area(pMemHaiku->AreaId);
AssertMsg(rc == B_OK, ("%#x", rc));
break;
}
case RTR0MEMOBJTYPE_LOCK:
{
team_id team = B_SYSTEM_TEAM;
if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
team = ((team_id)pMemHaiku->Core.u.Lock.R0Process);
rc = unlock_memory_etc(team, pMemHaiku->Core.pv, pMemHaiku->Core.cb, B_READ_DEVICE);
AssertMsg(rc == B_OK, ("%#x", rc));
break;
}
case RTR0MEMOBJTYPE_RES_VIRT:
{
team_id team = B_SYSTEM_TEAM;
if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
team = ((team_id)pMemHaiku->Core.u.Lock.R0Process);
rc = vm_unreserve_address_range(team, pMemHaiku->Core.pv, pMemHaiku->Core.cb);
AssertMsg(rc == B_OK, ("%#x", rc));
break;
}
default:
AssertMsgFailed(("enmType=%d\n", pMemHaiku->Core.enmType));
return VERR_INTERNAL_ERROR;
}
return VINF_SUCCESS;
}
static int rtR0MemObjNativeAllocArea(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
bool fExecutable, RTR0MEMOBJTYPE type, RTHCPHYS PhysHighest, size_t uAlignment)
{
NOREF(fExecutable);
int rc;
void *pvMap = NULL;
const char *pszName = NULL;
uint32 addressSpec = B_ANY_KERNEL_ADDRESS;
uint32 fLock = ~0U;
LogFlowFunc(("ppMem=%p cb=%u, fExecutable=%s, type=%08x, PhysHighest=%RX64 uAlignment=%u\n", ppMem,(unsigned)cb,
fExecutable ? "true" : "false", type, PhysHighest,(unsigned)uAlignment));
switch (type)
{
case RTR0MEMOBJTYPE_PAGE:
pszName = "IPRT R0MemObj Alloc";
fLock = B_FULL_LOCK;
break;
case RTR0MEMOBJTYPE_LOW:
pszName = "IPRT R0MemObj AllocLow";
fLock = B_32_BIT_FULL_LOCK;
break;
case RTR0MEMOBJTYPE_CONT:
pszName = "IPRT R0MemObj AllocCont";
fLock = B_32_BIT_CONTIGUOUS;
break;
#if 0
case RTR0MEMOBJTYPE_MAPPING:
pszName = "IPRT R0MemObj Mapping";
fLock = B_FULL_LOCK;
break;
#endif
case RTR0MEMOBJTYPE_PHYS:
/** @todo alignment */
if (uAlignment != PAGE_SIZE)
return VERR_NOT_SUPPORTED;
/** @todo r=ramshankar: no 'break' here?? */
case RTR0MEMOBJTYPE_PHYS_NC:
pszName = "IPRT R0MemObj AllocPhys";
fLock = (PhysHighest < _4G ? B_LOMEM : B_32_BIT_CONTIGUOUS);
break;
#if 0
case RTR0MEMOBJTYPE_LOCK:
break;
#endif
default:
return VERR_INTERNAL_ERROR;
}
/* Create the object. */
PRTR0MEMOBJHAIKU pMemHaiku;
pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), type, NULL, cb);
if (RT_UNLIKELY(!pMemHaiku))
return VERR_NO_MEMORY;
rc = pMemHaiku->AreaId = create_area(pszName, &pvMap, addressSpec, cb, fLock, B_READ_AREA | B_WRITE_AREA);
if (pMemHaiku->AreaId >= 0)
{
physical_entry physMap[2];
pMemHaiku->Core.pv = pvMap; /* store start address */
switch (type)
{
case RTR0MEMOBJTYPE_CONT:
rc = get_memory_map(pvMap, cb, physMap, 2);
if (rc == B_OK)
pMemHaiku->Core.u.Cont.Phys = physMap[0].address;
break;
case RTR0MEMOBJTYPE_PHYS:
case RTR0MEMOBJTYPE_PHYS_NC:
rc = get_memory_map(pvMap, cb, physMap, 2);
if (rc == B_OK)
{
pMemHaiku->Core.u.Phys.PhysBase = physMap[0].address;
pMemHaiku->Core.u.Phys.fAllocated = true;
}
break;
default:
break;
}
if (rc >= B_OK)
{
*ppMem = &pMemHaiku->Core;
return VINF_SUCCESS;
}
delete_area(pMemHaiku->AreaId);
}
rtR0MemObjDelete(&pMemHaiku->Core);
return RTErrConvertFromHaikuKernReturn(rc);
}
int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_PAGE, 0 /* PhysHighest */, 0 /* uAlignment */);
}
int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_LOW, 0 /* PhysHighest */, 0 /* uAlignment */);
}
int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
{
return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_CONT, 0 /* PhysHighest */, 0 /* uAlignment */);
}
int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
{
return rtR0MemObjNativeAllocArea(ppMem, cb, false, RTR0MEMOBJTYPE_PHYS, PhysHighest, uAlignment);
}
int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
{
return rtR0MemObjNativeAllocPhys(ppMem, cb, PhysHighest, PAGE_SIZE);
}
int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
{
AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
LogFlowFunc(("ppMem=%p Phys=%08x cb=%u uCachePolicy=%x\n", ppMem, Phys,(unsigned)cb, uCachePolicy));
/* Create the object. */
PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_PHYS, NULL, cb);
if (!pMemHaiku)
return VERR_NO_MEMORY;
/* There is no allocation here, it needs to be mapped somewhere first. */
pMemHaiku->AreaId = -1;
pMemHaiku->Core.u.Phys.fAllocated = false;
pMemHaiku->Core.u.Phys.PhysBase = Phys;
pMemHaiku->Core.u.Phys.uCachePolicy = uCachePolicy;
*ppMem = &pMemHaiku->Core;
return VINF_SUCCESS;
}
/**
* Worker locking the memory in either kernel or user maps.
*
* @returns IPRT status code.
* @param ppMem Where to store the allocated memory object.
* @param pvStart The starting address.
* @param cb The size of the block.
* @param fAccess The mapping protection to apply.
* @param R0Process The process to map the memory to (use NIL_RTR0PROCESS
* for the kernel)
* @param fFlags Memory flags (B_READ_DEVICE indicates the memory is
* intended to be written from a "device").
*/
static int rtR0MemObjNativeLockInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvStart, size_t cb, uint32_t fAccess,
RTR0PROCESS R0Process, int fFlags)
{
NOREF(fAccess);
int rc;
team_id TeamId = B_SYSTEM_TEAM;
LogFlowFunc(("ppMem=%p pvStart=%p cb=%u fAccess=%x R0Process=%d fFlags=%x\n", ppMem, pvStart, cb, fAccess, R0Process,
fFlags));
/* Create the object. */
PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_LOCK, pvStart, cb);
if (RT_UNLIKELY(!pMemHaiku))
return VERR_NO_MEMORY;
if (R0Process != NIL_RTR0PROCESS)
TeamId = (team_id)R0Process;
rc = lock_memory_etc(TeamId, pvStart, cb, fFlags);
if (rc == B_OK)
{
pMemHaiku->AreaId = -1;
pMemHaiku->Core.u.Lock.R0Process = R0Process;
*ppMem = &pMemHaiku->Core;
return VINF_SUCCESS;
}
rtR0MemObjDelete(&pMemHaiku->Core);
return RTErrConvertFromHaikuKernReturn(rc);
}
int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
{
return rtR0MemObjNativeLockInMap(ppMem, (void *)R3Ptr, cb, fAccess, R0Process, B_READ_DEVICE);
}
int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
{
return rtR0MemObjNativeLockInMap(ppMem, pv, cb, fAccess, NIL_RTR0PROCESS, B_READ_DEVICE);
}
#if 0
/** @todo Reserve address space */
/**
* Worker for the two virtual address space reservers.
*
* We're leaning on the examples provided by mmap and vm_mmap in vm_mmap.c here.
*/
static int rtR0MemObjNativeReserveInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment,
RTR0PROCESS R0Process)
{
int rc;
team_id TeamId = B_SYSTEM_TEAM;
LogFlowFunc(("ppMem=%p pvFixed=%p cb=%u uAlignment=%u R0Process=%d\n", ppMem, pvFixed, (unsigned)cb, uAlignment, R0Process));
if (R0Process != NIL_RTR0PROCESS)
team = (team_id)R0Process;
/* Check that the specified alignment is supported. */
if (uAlignment > PAGE_SIZE)
return VERR_NOT_SUPPORTED;
/* Create the object. */
PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_RES_VIRT, NULL, cb);
if (!pMemHaiku)
return VERR_NO_MEMORY;
/* Ask the kernel to reserve the address range. */
//XXX: vm_reserve_address_range ?
return VERR_NOT_SUPPORTED;
}
#endif
int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
{
return VERR_NOT_SUPPORTED;
}
int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
{
return VERR_NOT_SUPPORTED;
}
int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
unsigned fProt, size_t offSub, size_t cbSub)
{
PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
PRTR0MEMOBJHAIKU pMemHaiku;
area_id area = -1;
void *pvMap = pvFixed;
uint32 uAddrSpec = B_EXACT_ADDRESS;
uint32 fProtect = 0;
int rc = VERR_MAP_FAILED;
AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
#if 0
/** @todo r=ramshankar: Wrong format specifiers, fix later! */
dprintf("%s(%p, %p, %p, %d, %x, %u, %u)\n", __FUNCTION__, ppMem, pMemToMap, pvFixed, uAlignment,
fProt, offSub, cbSub);
#endif
/* Check that the specified alignment is supported. */
if (uAlignment > PAGE_SIZE)
return VERR_NOT_SUPPORTED;
/* We can't map anything to the first page, sorry. */
if (pvFixed == 0)
return VERR_NOT_SUPPORTED;
if (fProt & RTMEM_PROT_READ)
fProtect |= B_KERNEL_READ_AREA;
if (fProt & RTMEM_PROT_WRITE)
fProtect |= B_KERNEL_WRITE_AREA;
/*
* Either the object we map has an area associated with, which we can clone,
* or it's a physical address range which we must map.
*/
if (pMemToMapHaiku->AreaId > -1)
{
if (pvFixed == (void *)-1)
uAddrSpec = B_ANY_KERNEL_ADDRESS;
rc = area = clone_area("IPRT R0MemObj MapKernel", &pvMap, uAddrSpec, fProtect, pMemToMapHaiku->AreaId);
LogFlow(("rtR0MemObjNativeMapKernel: clone_area uAddrSpec=%d fProtect=%x AreaId=%d rc=%d\n", uAddrSpec, fProtect,
pMemToMapHaiku->AreaId, rc));
}
else if (pMemToMapHaiku->Core.enmType == RTR0MEMOBJTYPE_PHYS)
{
/* map_physical_memory() won't let you choose where. */
if (pvFixed != (void *)-1)
return VERR_NOT_SUPPORTED;
uAddrSpec = B_ANY_KERNEL_ADDRESS;
rc = area = map_physical_memory("IPRT R0MemObj MapKernelPhys", (phys_addr_t)pMemToMapHaiku->Core.u.Phys.PhysBase,
pMemToMapHaiku->Core.cb, uAddrSpec, fProtect, &pvMap);
}
else
return VERR_NOT_SUPPORTED;
if (rc >= B_OK)
{
/* Create the object. */
pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), RTR0MEMOBJTYPE_MAPPING, pvMap,
pMemToMapHaiku->Core.cb);
if (RT_UNLIKELY(!pMemHaiku))
return VERR_NO_MEMORY;
pMemHaiku->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
pMemHaiku->Core.pv = pvMap;
pMemHaiku->AreaId = area;
*ppMem = &pMemHaiku->Core;
return VINF_SUCCESS;
}
rc = VERR_MAP_FAILED;
/** @todo finish the implementation. */
rtR0MemObjDelete(&pMemHaiku->Core);
return rc;
}
int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
{
#if 0
/*
* Check for unsupported stuff.
*/
AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
if (uAlignment > PAGE_SIZE)
return VERR_NOT_SUPPORTED;
int rc;
PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
struct proc *pProc = (struct proc *)R0Process;
struct vm_map *pProcMap = &pProc->p_vmspace->vm_map;
/* calc protection */
vm_prot_t ProtectionFlags = 0;
if ((fProt & RTMEM_PROT_NONE) == RTMEM_PROT_NONE)
ProtectionFlags = VM_PROT_NONE;
if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ)
ProtectionFlags |= VM_PROT_READ;
if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE)
ProtectionFlags |= VM_PROT_WRITE;
if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC)
ProtectionFlags |= VM_PROT_EXECUTE;
/* calc mapping address */
PROC_LOCK(pProc);
vm_offset_t AddrR3 = round_page((vm_offset_t)pProc->p_vmspace->vm_daddr + lim_max(pProc, RLIMIT_DATA));
PROC_UNLOCK(pProc);
/* Insert the object in the map. */
rc = vm_map_find(pProcMap, /* Map to insert the object in */
NULL, /* Object to map */
0, /* Start offset in the object */
&AddrR3, /* Start address IN/OUT */
pMemToMap->cb, /* Size of the mapping */
TRUE, /* Whether a suitable address should be searched for first */
ProtectionFlags, /* protection flags */
VM_PROT_ALL, /* Maximum protection flags */
0); /* Copy on write */
/* Map the memory page by page into the destination map. */
if (rc == KERN_SUCCESS)
{
size_t cPages = pMemToMap->cb >> PAGE_SHIFT;;
pmap_t pPhysicalMap = pProcMap->pmap;
vm_offset_t AddrR3Dst = AddrR3;
if ( pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS
|| pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS_NC
|| pMemToMap->enmType == RTR0MEMOBJTYPE_PAGE)
{
/* Mapping physical allocations */
Assert(cPages == pMemToMapHaiku->u.Phys.cPages);
/* Insert the memory page by page into the mapping. */
for (uint32_t iPage = 0; iPage < cPages; iPage++)
{
vm_page_t pPage = pMemToMapHaiku->u.Phys.apPages[iPage];
MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE);
AddrR3Dst += PAGE_SIZE;
}
}
else
{
/* Mapping cont or low memory types */
vm_offset_t AddrToMap = (vm_offset_t)pMemToMap->pv;
for (uint32_t iPage = 0; iPage < cPages; iPage++)
{
vm_page_t pPage = PHYS_TO_VM_PAGE(vtophys(AddrToMap));
MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE);
AddrR3Dst += PAGE_SIZE;
AddrToMap += PAGE_SIZE;
}
}
}
if (RT_SUCCESS(rc))
{
/*
* Create a mapping object for it.
*/
PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU),
RTR0MEMOBJTYPE_MAPPING,
(void *)AddrR3,
pMemToMap->cb);
if (pMemHaiku)
{
Assert((vm_offset_t)pMemHaiku->Core.pv == AddrR3);
pMemHaiku->Core.u.Mapping.R0Process = R0Process;
*ppMem = &pMemHaiku->Core;
return VINF_SUCCESS;
}
rc = vm_map_remove(pProcMap, ((vm_offset_t)AddrR3), ((vm_offset_t)AddrR3) + pMemToMap->cb);
AssertMsg(rc == KERN_SUCCESS, ("Deleting mapping failed\n"));
}
#endif
return VERR_NOT_SUPPORTED;
}
int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
{
return VERR_NOT_SUPPORTED;
}
RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
{
PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)pMem;
status_t rc;
/** @todo r=ramshankar: Validate objects */
LogFlow(("rtR0MemObjNativeGetPagePhysAddr: pMem=%p enmType=%x iPage=%u\n", pMem, pMemHaiku->Core.enmType,(unsigned)iPage));
switch (pMemHaiku->Core.enmType)
{
case RTR0MEMOBJTYPE_LOCK:
{
team_id TeamId = B_SYSTEM_TEAM;
physical_entry aPhysMap[2];
int32 cPhysMap = 2; /** @todo r=ramshankar: why not use RT_ELEMENTS? */
if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
TeamId = (team_id)pMemHaiku->Core.u.Lock.R0Process;
void *pb = pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
rc = get_memory_map_etc(TeamId, pb, B_PAGE_SIZE, aPhysMap, &cPhysMap);
if (rc < B_OK || cPhysMap < 1)
return NIL_RTHCPHYS;
return aPhysMap[0].address;
}
#if 0
case RTR0MEMOBJTYPE_MAPPING:
{
vm_offset_t pb = (vm_offset_t)pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
if (pMemHaiku->Core.u.Mapping.R0Process != NIL_RTR0PROCESS)
{
struct proc *pProc = (struct proc *)pMemHaiku->Core.u.Mapping.R0Process;
struct vm_map *pProcMap = &pProc->p_vmspace->vm_map;
pmap_t pPhysicalMap = pProcMap->pmap;
return pmap_extract(pPhysicalMap, pb);
}
return vtophys(pb);
}
#endif
case RTR0MEMOBJTYPE_CONT:
return pMemHaiku->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
case RTR0MEMOBJTYPE_PHYS:
return pMemHaiku->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
case RTR0MEMOBJTYPE_LOW:
case RTR0MEMOBJTYPE_PAGE:
case RTR0MEMOBJTYPE_PHYS_NC:
{
team_id TeamId = B_SYSTEM_TEAM;
physical_entry aPhysMap[2];
int32 cPhysMap = 2; /** @todo r=ramshankar: why not use RT_ELEMENTS? */
void *pb = pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
rc = get_memory_map_etc(TeamId, pb, B_PAGE_SIZE, aPhysMap, &cPhysMap);
if (rc < B_OK || cPhysMap < 1)
return NIL_RTHCPHYS;
return aPhysMap[0].address;
}
case RTR0MEMOBJTYPE_RES_VIRT:
default:
return NIL_RTHCPHYS;
}
}