update for HEAD-2003091401
[reactos.git] / ntoskrnl / mm / ncache.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 non-cached 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 #include <internal/ps.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21 /* FUNCTIONS *****************************************************************/
22
23
24 /**********************************************************************
25  * NAME                                                 EXPORTED
26  *      MmAllocateNonCachedMemory@4
27  *
28  * DESCRIPTION
29  *      Allocates a virtual address range of noncached and cache
30  *      aligned memory.
31  *      
32  * ARGUMENTS
33  *      NumberOfBytes
34  *              Size of region to allocate.
35  *              
36  * RETURN VALUE
37  *      The base address of the range on success;
38  *      NULL on failure.
39  *
40  * NOTE
41  *      Description taken from include/ddk/mmfuncs.h.
42  *      Code taken from ntoskrnl/mm/special.c.
43  *
44  * REVISIONS
45  *
46  * @implemented
47  */
48 PVOID STDCALL 
49 MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
50 {
51    PVOID Result;
52    MEMORY_AREA* marea;
53    NTSTATUS Status;
54    ULONG i;
55    ULONG Attributes;
56
57    MmLockAddressSpace(MmGetKernelAddressSpace());
58    Result = NULL;
59    Status = MmCreateMemoryArea (NULL,
60                                 MmGetKernelAddressSpace(),
61                                 MEMORY_AREA_NO_CACHE,
62                                 &Result,
63                                 NumberOfBytes,
64                                 0,
65                                 &marea,
66                                 FALSE,
67                                 FALSE);
68    MmUnlockAddressSpace(MmGetKernelAddressSpace());
69
70    if (!NT_SUCCESS(Status))
71      {
72         return (NULL);
73      }
74    Attributes = PAGE_READWRITE | PAGE_SYSTEM | PAGE_NOCACHE | 
75      PAGE_WRITETHROUGH;
76    for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE); i++)
77      {
78        PHYSICAL_ADDRESS NPage;
79
80        Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage);
81        MmCreateVirtualMapping (NULL,
82                                Result + (i * PAGE_SIZE),
83                                Attributes,
84                                NPage,
85                                TRUE);
86      }
87    return ((PVOID)Result);
88 }
89
90 VOID STATIC
91 MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, 
92                     PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, 
93                     BOOLEAN Dirty)
94 {
95   assert(SwapEntry == 0);
96   if (PhysAddr.QuadPart != 0)
97     {
98       MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr);
99     }
100 }
101
102 /**********************************************************************
103  * NAME                                                 EXPORTED
104  *      MmFreeNonCachedMemory@8
105  *
106  * DESCRIPTION
107  *      Releases a range of noncached memory allocated with 
108  *      MmAllocateNonCachedMemory.
109  *      
110  * ARGUMENTS
111  *      BaseAddress
112  *              Virtual address to be freed;
113  *              
114  *      NumberOfBytes
115  *              Size of the region to be freed.
116  *              
117  * RETURN VALUE
118  *      None.
119  *
120  * NOTE
121  *      Description taken from include/ddk/mmfuncs.h.
122  *      Code taken from ntoskrnl/mm/special.c.
123  *
124  * REVISIONS
125  *
126  * @implemented
127  */
128 VOID STDCALL MmFreeNonCachedMemory (IN PVOID BaseAddress,
129                                     IN ULONG NumberOfBytes)
130 {
131   MmLockAddressSpace(MmGetKernelAddressSpace());
132   MmFreeMemoryArea (MmGetKernelAddressSpace(),
133                     BaseAddress,
134                     NumberOfBytes,
135                     MmFreeNonCachedPage,
136                     NULL);
137   MmUnlockAddressSpace(MmGetKernelAddressSpace());
138 }
139
140 /* EOF */