Changeset 5179 for trunk/src


Ignore:
Timestamp:
Feb 19, 2001, 6:49:05 AM (25 years ago)
Author:
bird
Message:

Implemented the API. And extending the it to take alignment flags too.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/win32k/k32/k32AllocMemEx.cpp

    r4787 r5179  
    1 /* $Id: k32AllocMemEx.cpp,v 1.4 2000-12-11 06:53:52 bird Exp $
     1/* $Id: k32AllocMemEx.cpp,v 1.5 2001-02-19 05:49:05 bird Exp $
    22 *
    33 * k32AllocMemEx - Equivalent to DosAllocMem, but this one
     
    1717#define INCL_DOSERRORS
    1818#define INCL_OS2KRNL_VM
     19#define INCL_OS2KRNL_TK
    1920
    2021#define NO_WIN32K_LIB_FUNCTIONS
    2122
    22 #ifndef OBJ_SELMAPALL
    23 #define OBJ_SELMAPALL   0x00000800UL
    24 #endif
    2523
    2624
     
    4038
    4139/* nasty! These should be imported from the kernel later! */
    42 
     40/*
     41 * These are unchanged from Warp3 to Warp 4.51.
     42 */
    4343ULONG vmApiF0[] =
    4444{
    45     0,
    46     VMA_READ,
    47     VMA_WRITE | VMA_READ,
    48     VMA_WRITE | VMA_READ,
    49     VMA_EXECUTE,
    50     VMA_EXECUTE | VMA_READ,
    51     VMA_WRITE | VMA_EXECUTE | VMA_READ,
    52     VMA_WRITE | VMA_EXECUTE | VMA_READ,
    53     VMA_GUARD,
    54     VMA_READ | VMA_GUARD,
    55     VMA_WRITE | VMA_READ | VMA_GUARD,
    56     VMA_WRITE | VMA_READ | VMA_GUARD,
    57     VMA_EXECUTE | VMA_GUARD,
    58     VMA_EXECUTE | VMA_READ | VMA_GUARD,
    59     VMA_WRITE | VMA_EXECUTE | VMA_READ | VMA_GUARD,
    60     VMA_WRITE | VMA_EXECUTE | VMA_READ | VMA_GUARD
     45    0,                                              /* 0 */
     46    VMA_READ,                                       /* PAG_READ  */
     47    VMA_WRITE | VMA_READ,                           /* PAG_WRITE */
     48    VMA_WRITE | VMA_READ,                           /* PAG_READ | PAG_WRITE */
     49    VMA_EXECUTE,                                    /* PAG_EXECUTE */
     50    VMA_EXECUTE | VMA_READ,                         /* PAG_READ | PAG_EXECUTE */
     51    VMA_WRITE | VMA_EXECUTE | VMA_READ,             /* PAG_WRITE | PAG_EXECUTE */
     52    VMA_WRITE | VMA_EXECUTE | VMA_READ,             /* PAG_READ | PAG_WRITE | PAG_EXECUTE */
     53    VMA_GUARD,                                      /* PAG_GUARD  */
     54    VMA_READ | VMA_GUARD,                           /* PAG_READ | PAG_GUARD */
     55    VMA_WRITE | VMA_READ | VMA_GUARD,               /* PAG_WRITE | PAG_GUARD */
     56    VMA_WRITE | VMA_READ | VMA_GUARD,               /* PAG_READ | PAG_WRITE | PAG_GUARD */
     57    VMA_EXECUTE | VMA_GUARD,                        /* PAG_EXECUTE | PAG_GUARD */
     58    VMA_EXECUTE | VMA_READ | VMA_GUARD,             /* PAG_READ | PAG_EXECUTE | PAG_GUARD */
     59    VMA_WRITE | VMA_EXECUTE | VMA_READ | VMA_GUARD, /* PAG_WRITE | PAG_EXECUTE | PAG_GUARD */
     60    VMA_WRITE | VMA_EXECUTE | VMA_READ | VMA_GUARD  /* PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD */
    6161};
    62 
    6362
    6463ULONG vmApiF1[] =
    6564{
    66     0,
    67     0,
    68     VMA_DECOMMIT,
    69     VMA_DECOMMIT,
    70     VMA_TILE,
    71     VMA_TILE,
    72     VMA_DECOMMIT | VMA_TILE,
    73     VMA_DECOMMIT | VMA_TILE,
    74     VMA_PROTECTED,
    75     VMA_PROTECTED,
    76     VMA_PROTECTED | VMA_DECOMMIT,
    77     VMA_PROTECTED | VMA_DECOMMIT,
    78     VMA_PROTECTED | VMA_TILE,
    79     VMA_PROTECTED | VMA_TILE,
    80     VMA_PROTECTED | VMA_DECOMMIT | VMA_TILE,
    81     VMA_PROTECTED | VMA_DECOMMIT | VMA_TILE
     65    0,                                              /* 0 */
     66    0,                                              /* PAG_COMMIT */
     67    VMA_DECOMMIT,                                   /* PAG_DECOMMIT */
     68    VMA_DECOMMIT,                                   /* PAG_COMMIT | PAG_DECOMMIT */
     69    VMA_SELALLOC,                                   /* OBJ_TILE */
     70    VMA_SELALLOC,                                   /* PAG_COMMIT | OBJ_TILE */
     71    VMA_DECOMMIT | VMA_SELALLOC,                    /* PAG_DECOMMIT | OBJ_TILE */
     72    VMA_DECOMMIT | VMA_SELALLOC,                    /* PAG_COMMIT | PAG_DECOMMIT | OBJ_TILE */
     73    VMA_PROTECTED,                                  /* OBJ_PROTECTED */
     74    VMA_PROTECTED,                                  /* PAG_COMMIT | OBJ_PROTECTED */
     75    VMA_PROTECTED | VMA_DECOMMIT,                   /* PAG_DECOMMIT | OBJ_PROTECTED */
     76    VMA_PROTECTED | VMA_DECOMMIT,                   /* PAG_COMMIT | PAG_DECOMMIT | OBJ_PROTECTED */
     77    VMA_PROTECTED | VMA_SELALLOC,                   /* OBJ_TILE | OBJ_PROTECTED */
     78    VMA_PROTECTED | VMA_SELALLOC,                   /* PAG_COMMIT | OBJ_TILE | OBJ_PROTECTED */
     79    VMA_PROTECTED | VMA_DECOMMIT | VMA_SELALLOC,    /* PAG_DECOMMIT | OBJ_TILE | OBJ_PROTECTED */
     80    VMA_PROTECTED | VMA_DECOMMIT | VMA_SELALLOC     /* PAG_COMMIT | PAG_DECOMMIT | OBJ_TILE | OBJ_PROTECTED */
    8281};
    8382
    8483
    8584/**
    86  * Extended edition of DosAllocMem. Allows you to suggest an address where you
    87  * want the memory allocated.
    88  * @returns   OS2 returncode.
    89  * @param     ppv    Pointer to a pointer. This points to a pointer which points to the
    90  *                   suggested address of the memory block.
    91  * @param     cb     Size of the memory block.
    92  * @param     flag   Flags just as for DosAllocMem.
    93  * @param     ulCS   CS where the memoryobject were requested.
    94  * @param     ulEIP  EIP where the memoryobject were requested.
     85 * Extended edition of DosAllocMem:
     86 *      Allows you to suggest an address where you want the memory allocated.
     87 *      Specify 64KB alignment.
     88 * @returns OS2 returncode.
     89 *          ERROR_INVALID_PARAMETER   Some input parameter is bad.
     90 *          ERROR_INVALID_ADDRESS     *pvv is wrong.
     91 * @param   ppv     Pointer to a pointer.
     92 *                  If OBJ_LOCATION is specified this *ppv holds a suggested address of the memory block.
     93 * @param   cb      Size of the memory block.
     94 * @param   flFlags Flags just as for DosAllocMem and two more:
     95 *                      OBJ_ALIGN64K    Align on 64 boundrary. Default in compatibility region.
     96 *                      OBJ_ALIGNPAGE   Page align the memory. (only high region) Default in 32-bit region.
     97 *                      OBJ_LOCATION    *ppv specifies a suggested address of the memory block.
     98 * @param   ulCS    CS where the memoryobject was requested.
     99 * @param   ulEIP   EIP where the memoryobject was requested.
    95100 * @sketch
    96  * @status    stub
    97  * @author    knut st. osmundsen (knut.stange.osmundsen@mynd.no)
    98  * @remark
     101 * @status  partially implemented.
     102 * @author  knut st. osmundsen (knut.stange.osmundsen@mynd.no)
     103 * @remark  Seems like I have to solve that "Grow private arena" problem which
     104 *          applies when we allocate at a specific address.
     105 *          I'll look into it ASAP and add a fix for this in the loader too.
    99106 */
    100 APIRET k32AllocMemEx(PPVOID ppv, ULONG cb, ULONG flag, ULONG ulCS, ULONG ulEIP)
     107APIRET k32AllocMemEx(PPVOID ppv, ULONG cb, ULONG flFlags, ULONG ulCS, ULONG ulEIP)
    101108{
    102     #if 0
    103109    APIRET  rc;
    104     ULONG   flFlags2;
     110    ULONG   flVMFlags;
     111    ULONG   flSelFlags;
    105112    VMAC    vmac = {0};
    106113    ULONG   cbCommit;
    107114    HMTE    hMTE;
    108115
    109     if ((flag & ~(PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD | PAG_COMMIT
    110                  | OBJ_TILE | OBJ_SELMAPALL))
    111         || (flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) == 0UL
     116
     117    kprintf(("k32AllocMemEx(ppv=0x%08x, cb=0x%x, flFlags=0x%08x, ulCS=0x%04x, ulEIP=0x%08x)\n",
     118             ppv, cb, flFlags, ulCS, ulEIP));
     119
     120    /** @sketch
     121     * General parameter validations:
     122     *      Only allowable flFlagss - DosAllocMem + our own.
     123     *      At least one access flag must be set.
     124     *      OBJ_TILE don't work OBJ_ANY or OBJ_ALIGNPAGE.
     125     *      Must be larger than 0 bytes.
     126     *      Caller CS and EIP must not be 0.
     127     * Align size and check if it's resonable.
     128     * If address is specified Then
     129     *      Check that the memory block is within possible private address space.
     130     */
     131    if (   (flFlags & ~(PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD | PAG_COMMIT
     132                        | OBJ_ANY | OBJ_TILE | OBJ_SELMAPALL | OBJ_ALIGNMASK | OBJ_LOCATION))
     133        || (flFlags & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) == 0
     134        || ((flFlags & OBJ_TILE) && ((flFlags & OBJ_ANY) || (flFlags & OBJ_ALIGNMASK) == OBJ_ALIGNPAGE))
    112135        || cb == 0
    113         || ulCS == 0
    114         || ulEIP == 0
     136        || ulCS == 0 || ulEIP == 0
    115137        )
     138    {
     139        kprintf(("k32AllocMemEx: Bad param (1)\n"));
    116140        return ERROR_INVALID_PARAMETER;
    117     if (cb > 0xC0000000UL)
     141    }
     142
     143    cb = PAGEALIGNUP(cb);
     144    if (cb >= VirtualAddressLimit)
     145    {
     146        kprintf(("k32AllocMemEx: Bad size cb=%d\n", cb));
    118147        return ERROR_NOT_ENOUGH_MEMORY;
    119 
    120     vmac.ac_va = (ULONG)*ppv;
    121     cb = (cb + 0xFFFUL) & ~0xFFFUL;
    122     if (flag & PAG_COMMIT)
    123         cbCommit = cb;
    124     flag = vmApiF0[flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD)]
    125            | vmApiF1[(flag & (PAG_COMMIT | PAG_DECOMMIT | OBJ_TILE | OBJ_PROTECTED)) >> 2]
    126            | VMA_USER | VMA_RESIDENT | VMA_LOWMEM2 | VMA_TILE | 0x12000000;
    127     flFlags2 = (flag & VMA_WRITE ? VMAF2_WRITE : 0) | 0x460;
    128 
     148    }
     149
     150    if (flFlags & OBJ_LOCATION)
     151    {
     152        rc = TKFuULongNF(SSToDS(&vmac.ac_va), ppv);
     153        if (rc)
     154        {
     155            kprintf(("k32AllocMemEx: Failed to fetch *ppv. rc=%d\n", rc));
     156            return rc;
     157        }
     158        kprintf(("k32AllocMemEx: Location *ppv =0x%08x\n", vmac.ac_va));
     159        if (    vmac.ac_va < 0x10000
     160            ||  vmac.ac_va + cb < vmac.ac_va
     161            ||  vmac.ac_va + cb > ((vmac.ac_va >= 0x20000000 && pahvmhShr) ? pahvmhShr : pahvmShr)->ah_laddrMax
     162                )
     163        {
     164            kprintf(("k32AllocMemEx: *ppv has an invalid address. *ppv=0x%08x\n", vmac.ac_va));
     165            return ERROR_INVALID_ADDRESS;
     166        }
     167    }
     168
     169
     170    /** @sketch
     171     * Get the hMTE of the executable object we're called from - may fail.
     172     * Determin size of precommitted memory.
     173     * Determin VM Flags:
     174     *      Default
     175     *      Handle OBJ_ANY (only applies if there are high arenas).
     176     *      Access flags are determined using vmApiF0.
     177     *      Commit, decommit, tile and unused protected flags using vmApiF1.
     178     * Set Alignment flags if specified.
     179     * If location specified Then Set location specific and arena flags correctly.
     180     * Else set the location any flag.
     181     * Determin SEL Flags.
     182     */
    129183    hMTE = VMGetOwner(ulCS, ulEIP);
     184
     185    cbCommit = flFlags & PAG_COMMIT ? cb : 0;
     186
     187    flVMFlags =  VMA_USER | VMA_ZEROFILL | VMA_LOWMEM2 | VMA_ARENAPRIVATE /* 0x02010084*/
     188        | ((flFlags & OBJ_ANY) && pahvmhShr ? VMA_ARENAHIGHA : VMA_SELALLOC | VMA_ALIGNSEL)
     189        | vmApiF0[flFlags  & (PAG_READ | PAG_WRITE | PAG_EXECUTE | PAG_GUARD)]
     190        | vmApiF1[(flFlags & (PAG_COMMIT | PAG_DECOMMIT | OBJ_TILE | OBJ_PROTECTED)) >> 4];
     191
     192    if (    (flVMFlags & VMA_SELALLOC)
     193        ||  (flFlags & OBJ_ALIGNMASK) == OBJ_ALIGN64K)
     194        flVMFlags |= VMA_ALIGNSEL;
     195    else if ((flFlags & OBJ_ALIGNMASK) == OBJ_ALIGNPAGE)
     196        flVMFlags |= VMA_ALIGNPAGE;
     197
     198    if (flFlags & OBJ_LOCATION)
     199    {
     200        flVMFlags |= VMA_LOCSPECIFIC;
     201        if (vmac.ac_va < 0x20000000)
     202            flVMFlags &= ~VMA_ARENAHIGHA;
     203    }
     204    else
     205        flVMFlags |= VMA_LOCANY;
     206
     207    flSelFlags = 0;
     208    if (flVMFlags & VMA_SELALLOC)
     209        flSelFlags = SELAF_SELMAP | SELAF_DPL3 | /* 0x0460 */
     210                     (flVMFlags & VMA_WRITE ? SELAF_WRITE : 0);
     211
     212
     213    /** @sketch
     214     * Call VMAllocMem.
     215     * If success Then
     216     *      Try set return variable.
     217     *      Free Memory on failure and return rc from previous operation.
     218     * Endif
     219     * Return return code.
     220     */
     221    kprintf(("k32AllocMemEx: cb=0x%08x flVMFlags=0x%08x flSelFlags=0x%08x, hMTE=%04d vmac.ac_va=0x%08x\n",
     222             cb, flVMFlags, flSelFlags, hMTE, vmac.ac_va));
    130223    rc = VMAllocMem(cb,
    131224                    cbCommit,
    132                     flag,
     225                    flVMFlags,
    133226                    0,
    134227                    0,
    135228                    hMTE,
    136                     flFlags2,
     229                    flSelFlags,
    137230                    0,
    138231                    (PVMAC)SSToDS(&vmac));
    139232
     233    if (rc == NO_ERROR)
     234    {
     235        rc = TKSuULongNF(ppv, SSToDS(&vmac.ac_va));
     236        if (rc)
     237        {
     238            kprintf(("k32AllocMemEx: Failed to set *ppv. rc=%d\n", rc));
     239            VMFreeMem(vmac.ac_va, 0, 0);
     240        }
     241    }
     242    else
     243        kprintf(("k32AllocMemEx: VMAllocMem failed with rc=%d\n", rc));
     244
     245    kprintf(("k32AllocMemEx: returns rc=%d (*ppv=0x%08x)\n", rc, vmac.ac_va));
    140246    return rc;
    141     #else
    142     NOREF(ppv);
    143     NOREF(cb);
    144     NOREF(flag);
    145     NOREF(ulCS);
    146     NOREF(ulEIP);
    147     return ERROR_NOT_SUPPORTED;
    148     #endif
    149247}
    150248
Note: See TracChangeset for help on using the changeset viewer.