update for HEAD-2003091401
[reactos.git] / ntoskrnl / mm / cont.c
1 /* $Id$
2  * 
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            ntoskrnl/mm/cont.c
6  * PURPOSE:         Manages continuous memory
7  * PROGRAMMER:      David Welch (welch@cwcom.net)
8  * UPDATE HISTORY:
9  *                  Created 22/05/98
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/mm.h>
16
17 #define NDEBUG
18 #include <internal/debug.h>
19
20 /* FUNCTIONS *****************************************************************/
21
22 VOID STATIC
23 MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, 
24                      PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, 
25                      BOOLEAN Dirty)
26 {
27   assert(SwapEntry == 0);
28   if (PhysAddr.QuadPart != 0)
29     {
30       MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr);
31     }
32 }
33
34 PVOID STDCALL
35 MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
36                                   IN PHYSICAL_ADDRESS HighestAcceptableAddress,
37                                   IN ULONG Alignment)
38 {
39    PMEMORY_AREA MArea;
40    NTSTATUS Status;
41    PVOID BaseAddress = 0;
42    PHYSICAL_ADDRESS PBase;
43    ULONG i;
44    
45    MmLockAddressSpace(MmGetKernelAddressSpace());
46    Status = MmCreateMemoryArea(NULL,
47                                MmGetKernelAddressSpace(),
48                                MEMORY_AREA_CONTINUOUS_MEMORY,
49                                &BaseAddress,
50                                NumberOfBytes,
51                                0,
52                                &MArea,
53                                FALSE,
54                                FALSE);
55    MmUnlockAddressSpace(MmGetKernelAddressSpace());
56
57    if (!NT_SUCCESS(Status))
58      {
59         return(NULL);
60      }
61    DPRINT( "Base = %x\n", BaseAddress );
62    PBase = MmGetContinuousPages(NumberOfBytes,
63                                 HighestAcceptableAddress,
64                                 Alignment);
65    if (PBase.QuadPart == 0LL)
66      {
67        MmLockAddressSpace(MmGetKernelAddressSpace());
68        MmFreeMemoryArea(MmGetKernelAddressSpace(),
69                         BaseAddress,
70                         0,
71                         NULL,
72                         NULL);
73        MmUnlockAddressSpace(MmGetKernelAddressSpace());
74        return(NULL);
75      }
76    for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++)
77      {
78         MmCreateVirtualMapping(NULL,
79                                BaseAddress + (i * 4096),
80                                PAGE_EXECUTE_READWRITE | PAGE_SYSTEM,
81                                (LARGE_INTEGER)(PBase.QuadPart + (i * 4096)),
82                                TRUE);
83      }
84    return(BaseAddress);
85 }
86
87 /**********************************************************************
88  * NAME                                                 EXPORTED
89  *      MmAllocateContiguousMemory@12
90  *
91  * DESCRIPTION
92  *      Allocates a range of physically contiguous cache aligned
93  *      memory from the non-paged pool.
94  *      
95  * ARGUMENTS
96  *      NumberOfBytes
97  *              Size of the memory block to allocate;
98  *              
99  *      HighestAcceptableAddress
100  *              Highest address valid for the caller.
101  *              
102  * RETURN VALUE
103  *      The virtual address of the memory block on success;
104  *      NULL on error.
105  *
106  * NOTE
107  *      Description taken from include/ddk/mmfuncs.h.
108  *      Code taken from ntoskrnl/mm/special.c.
109  *
110  * REVISIONS
111  *
112  * @implemented
113  */
114 PVOID STDCALL 
115 MmAllocateContiguousMemory (IN ULONG NumberOfBytes,
116                             IN PHYSICAL_ADDRESS HighestAcceptableAddress)
117 {
118   return(MmAllocateContiguousAlignedMemory(NumberOfBytes,
119                                            HighestAcceptableAddress,
120                                            PAGE_SIZE));
121 }
122
123
124 /**********************************************************************
125  * NAME                                                 EXPORTED
126  *      MmFreeContiguousMemory@4
127  *
128  * DESCRIPTION
129  *      Releases a range of physically contiguous memory allocated
130  *      with MmAllocateContiguousMemory.
131  *      
132  * ARGUMENTS
133  *      BaseAddress
134  *              Virtual address of the memory to be freed.
135  *
136  * RETURN VALUE
137  *      None.
138  *
139  * NOTE
140  *      Description taken from include/ddk/mmfuncs.h.
141  *      Code taken from ntoskrnl/mm/special.c.
142  *
143  * REVISIONS
144  *
145  * @implemented
146  */
147 VOID STDCALL 
148 MmFreeContiguousMemory(IN PVOID BaseAddress)
149 {
150    MmLockAddressSpace(MmGetKernelAddressSpace());
151    MmFreeMemoryArea(MmGetKernelAddressSpace(),
152                     BaseAddress,
153                     0,
154                     MmFreeContinuousPage,
155                     NULL);
156    MmUnlockAddressSpace(MmGetKernelAddressSpace());
157 }
158
159 /* EOF */