VirtualBox

Changeset 27003 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 3, 2010 6:56:23 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
58312
Message:

rtR0MemObjNativeAllocPhysNC implementation for Solaris.

Location:
trunk/src/VBox/Runtime/r0drv/solaris/vbi
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c

    r25183 r27003  
    314314
    315315static void *
    316 vbi_internal_alloc(uint64_t *phys, size_t size, int contig)
     316vbi_internal_alloc(uint64_t *phys, size_t size, uint64_t alignment, int contig)
    317317{
    318318        ddi_dma_attr_t attr;
     
    323323        if ((size & PAGEOFFSET) != 0)
    324324                return (NULL);
    325         npages = size >> PAGESHIFT;
     325        npages = (size + PAGESIZE - 1) >> PAGESHIFT;
    326326        if (npages == 0)
    327327                return (NULL);
     
    329329        attr = base_attr;
    330330        attr.dma_attr_addr_hi = *phys;
     331    attr.dma_attr_align   = alignment;
    331332        if (!contig)
    332333                attr.dma_attr_sgllen = npages;
     
    348349vbi_contig_alloc(uint64_t *phys, size_t size)
    349350{
    350         return (vbi_internal_alloc(phys, size, 1));
     351    /* Obsolete */
     352        return (vbi_internal_alloc(phys, size, PAGESIZE /* alignment */, 1 /* contiguous */));
    351353}
    352354
     
    354356vbi_contig_free(void *va, size_t size)
    355357{
     358    /* Obsolete */
    356359        p_contig_free(va, size);
    357360}
     
    746749         */
    747750        va = seg->s_base;
    748         pgcnt = seg->s_size >> PAGESHIFT;
     751        pgcnt = (seg->s_size + PAGESIZE - 1) >> PAGESHIFT;
    749752        for (p = 0; p < pgcnt; ++p, va += PAGESIZE) {
    750753                hat_devload(as->a_hat, va,
     
    865868segvbi_getoffset(struct seg *seg, caddr_t addr)
    866869{
     870    cmn_err(CE_NOTE, "segvbi_getoffset\n");
    867871        return ((uintptr_t)addr - (uintptr_t)seg->s_base);
    868872}
     
    968972        map_addr(va, len, 0, 0, MAP_SHARED);
    969973        if (*va != NULL)
     974        {
    970975                error = as_map(as, *va, len, segvbi_create, &args);
     976        }
    971977        else
    972978                error = ENOMEM;
     
    12031209 * increased. Also change vbi_modlmisc at the top of the file.
    12041210 */
    1205 uint_t vbi_revision_level = 6;
     1211uint_t vbi_revision_level = 7;
    12061212
    12071213void *
    12081214vbi_lowmem_alloc(uint64_t phys, size_t size)
    12091215{
    1210         return (vbi_internal_alloc(&phys, size, 0));
     1216        return (vbi_internal_alloc(&phys, size, PAGESIZE /* alignment */, 0 /* non-contiguous */));
    12111217}
    12121218
     
    12291235}
    12301236
     1237/*
     1238 * This is revision 7 of the interface.
     1239 */
     1240
     1241void *
     1242vbi_phys_alloc(uint64_t *phys, size_t size, uint64_t alignment, int contig)
     1243{
     1244        return (vbi_internal_alloc(phys, size, alignment, contig));
     1245}
     1246
     1247void
     1248vbi_phys_free(void *va, size_t size)
     1249{
     1250        p_contig_free(va, size);
     1251}
  • trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h

    r25183 r27003  
    336336/* end of interfaces defined for version 6 */
    337337
     338/* begin interfaces defined for version 7 */
     339/*
     340 * Allocate and free physically limited, aligned as specified continuous or non-continuous memory.
     341 *
     342 * return value is a) NULL if memory below "phys" not available or
     343 * b) virtual address of memory in kernel heap
     344 *
     345 * phys on input is set to the upper boundary of acceptable memory
     346 *
     347 * size is the amount to allocate and must be a multiple of PAGESIZE
     348 */
     349extern void *vbi_phys_alloc(uint64_t *phys, size_t size, uint64_t alignment, int contig);
     350extern void vbi_phys_free(void *va, size_t size);
     351/* end of interfaces defined for version 7 */
     352
    338353#ifdef  __cplusplus
    339354}
  • trunk/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c

    r26847 r27003  
    7777
    7878        case RTR0MEMOBJTYPE_CONT:
     79        case RTR0MEMOBJTYPE_PHYS:
    7980            vbi_contig_free(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
     81            break;
     82
     83        case RTR0MEMOBJTYPE_PHYS_NC:
     84            vbi_phys_free(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
    8085            break;
    8186
     
    101106        }
    102107
    103         /* unused */
    104         case RTR0MEMOBJTYPE_PHYS:
    105108        default:
    106109            AssertMsgFailed(("enmType=%d\n", pMemSolaris->Core.enmType));
     
    161164{
    162165    NOREF(fExecutable);
    163 
    164     /* Create the object */
    165     PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_CONT, NULL, cb);
    166     if (!pMemSolaris)
    167         return VERR_NO_MEMORY;
    168 
    169     /* Allocate physically contiguous page-aligned memory. */
     166    return rtR0MemObjNativeAllocPhys(ppMem, cb, (uint64_t)0xffffffff /* highest address */, PAGE_SIZE /* alignment */);
     167}
     168
     169
     170int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
     171{
     172#if HC_ARCH_BITS == 64
     173    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_PHYS_NC, NULL, cb);
     174    if (!pMemSolaris)
     175        return VERR_NO_MEMORY;
     176
     177    if (PhysHighest == NIL_RTHCPHYS)
     178        PhysHighest = (uint64_t)0xffffffff;
     179
     180    /* Allocate physically non-contiguous page-aligned memory. */
    170181    caddr_t virtAddr;
    171     uint64_t phys = (unsigned)0xffffffff;
    172     virtAddr = vbi_contig_alloc(&phys, cb);
     182    uint64_t phys = PhysHighest;
     183    virtAddr = vbi_phys_alloc(&phys, cb, PAGE_SIZE, 0 /* non-contiguous */);
    173184    if (virtAddr == NULL)
    174185    {
    175186        rtR0MemObjDelete(&pMemSolaris->Core);
    176         return VERR_NO_CONT_MEMORY;
     187        return VERR_NO_MEMORY;
    177188    }
    178189    Assert(phys < (uint64_t)1 << 32);
    179190    pMemSolaris->Core.pv = virtAddr;
    180     pMemSolaris->Core.u.Cont.Phys = phys;
     191    pMemSolaris->Core.u.Phys.PhysBase = phys;
     192    pMemSolaris->Core.u.Phys.fAllocated = true;
    181193    pMemSolaris->pvHandle = NULL;
    182194    *ppMem = &pMemSolaris->Core;
    183195    return VINF_SUCCESS;
    184 }
    185 
    186 
    187 int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
    188 {
     196#else
    189197    /** @todo rtR0MemObjNativeAllocPhysNC / solaris */
    190198    return VERR_NOT_SUPPORTED; /* see the RTR0MemObjAllocPhysNC specs */
     199#endif
    191200}
    192201
     
    196205    AssertMsgReturn(PhysHighest >= 16 *_1M, ("PhysHigest=%RHp\n", PhysHighest), VERR_NOT_IMPLEMENTED);
    197206
    198     /** @todo alignment */
     207    /** @todo alignment, vbi currently assumes PAGE_SIZE not even less than PAGE_SIZE */
    199208    if (uAlignment != PAGE_SIZE)
    200209        return VERR_NOT_SUPPORTED;
    201210
    202     return rtR0MemObjNativeAllocCont(ppMem, cb, false);
     211    if (PhysHighest == NIL_RTHCPHYS)
     212        PhysHighest = (uint64_t)0xffffffff;
     213
     214     PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_CONT, NULL, cb);
     215     if (!pMemSolaris)
     216         return VERR_NO_MEMORY;
     217
     218     /* Allocate physically contiguous memory aligned as specified. */
     219     caddr_t virtAddr;
     220     uint64_t phys = PhysHighest;
     221     virtAddr = vbi_phys_alloc(&phys, cb, uAlignment, 1 /* contiguous */);
     222     if (virtAddr == NULL)
     223     {
     224         rtR0MemObjDelete(&pMemSolaris->Core);
     225         return VERR_NO_CONT_MEMORY;
     226     }
     227     Assert(phys < (uint64_t)1 << 32);
     228     pMemSolaris->Core.pv = virtAddr;
     229     pMemSolaris->Core.u.Cont.Phys = phys;
     230     pMemSolaris->pvHandle = NULL;
     231     *ppMem = &pMemSolaris->Core;
     232     return VINF_SUCCESS;
    203233}
    204234
     
    240270    if (rc != 0)
    241271    {
    242         cmn_err(CE_NOTE,"rtR0MemObjNativeLockUser: vbi_lock_va failed rc=%d\n", rc);
     272        LogRel(("rtR0MemObjNativeLockUser: vbi_lock_va failed rc=%d\n", rc));
    243273        rtR0MemObjDelete(&pMemSolaris->Core);
    244274        return VERR_LOCK_FAILED;
     
    270300    if (rc != 0)
    271301    {
    272         cmn_err(CE_NOTE,"rtR0MemObjNativeLockKernel: vbi_lock_va failed rc=%d\n", rc);
     302        LogRel(("rtR0MemObjNativeLockKernel: vbi_lock_va failed rc=%d\n", rc));
    273303        rtR0MemObjDelete(&pMemSolaris->Core);
    274304        return VERR_LOCK_FAILED;
     
    325355    AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
    326356    AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
    327     if (uAlignment > PAGE_SIZE)
     357    if (uAlignment != PAGE_SIZE)
    328358        return VERR_NOT_SUPPORTED;
    329359
     
    348378        if (paddrs[iPage] == -(uint64_t)1)
    349379        {
    350             cmn_err(CE_NOTE, "rtR0MemObjNativeMapUser: no page to map.\n");
    351             rc = VERR_MAP_FAILED;
    352             goto l_done;
     380            LogRel(("rtR0MemObjNativeMapUser: no page to map.\n"));
     381            kmem_free(paddrs, sizeof(uint64_t) * cPages);
     382            rtR0MemObjDelete(&pMemSolaris->Core);
     383            return VERR_MAP_FAILED;
    353384        }
    354385        pv = (void *)((uintptr_t)pv + PAGE_SIZE);
     
    358389    if (rc != 0)
    359390    {
    360         cmn_err(CE_NOTE, "rtR0MemObjNativeMapUser: vbi failure.\n");
    361         rc = VERR_MAP_FAILED;
    362         rtR0MemObjDelete(&pMemSolaris->Core);
    363         goto l_done;
     391        LogRel(("rtR0MemObjNativeMapUser: vbi mapping failure.\n"));
     392        kmem_free(paddrs, sizeof(uint64_t) * cPages);
     393        rtR0MemObjDelete(&pMemSolaris->Core);
     394        return VERR_MAP_FAILED;
    364395    }
    365396    else
     
    369400    pMemSolaris->Core.pv = addr;
    370401    *ppMem = &pMemSolaris->Core;
    371 l_done:
    372402    kmem_free(paddrs, sizeof(uint64_t) * cPages);
    373403    return rc;
     
    393423        case RTR0MEMOBJTYPE_PAGE:
    394424        case RTR0MEMOBJTYPE_LOW:
    395         case RTR0MEMOBJTYPE_MAPPING:
    396425        case RTR0MEMOBJTYPE_LOCK:
    397426        {
     
    400429        }
    401430
     431        /*
     432         * Although mapping can be handled by vbi_va_to_pa(offset) like the above case,
     433         * request it from the parent so that we have a clear distinction between CONT/PHYS_NC.
     434         */
     435        case RTR0MEMOBJTYPE_MAPPING:
     436            return rtR0MemObjNativeGetPagePhysAddr(pMemSolaris->Core.uRel.Child.pParent, iPage);
     437
    402438        case RTR0MEMOBJTYPE_CONT:
     439        case RTR0MEMOBJTYPE_PHYS:
    403440            return pMemSolaris->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
    404441
    405         case RTR0MEMOBJTYPE_PHYS:
     442        case RTR0MEMOBJTYPE_PHYS_NC:
     443            if (pMemSolaris->Core.u.Phys.fAllocated == true)
     444            {
     445                uint8_t *pb = (uint8_t *)pMemSolaris->Core.pv + ((size_t)iPage << PAGE_SHIFT);
     446                return vbi_va_to_pa(pb);
     447            }
    406448            return pMemSolaris->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
    407449
    408         case RTR0MEMOBJTYPE_PHYS_NC:
    409             AssertFailed(/* not implemented */);
    410450        case RTR0MEMOBJTYPE_RES_VIRT:
    411451        default:
Note: See TracChangeset for help on using the changeset viewer.

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