- Implemented InterlockedBitTestAndReset, InterlockedBitTestAndSet, InterlockedExchan...
[reactos.git] / reactos / ntoskrnl / mm / iospace.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/iospace.c
6 * PURPOSE: Mapping I/O space
7 *
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* FUNCTIONS *****************************************************************/
18
19 /**********************************************************************
20 * NAME EXPORTED
21 * MmMapIoSpace@16
22 *
23 * DESCRIPTION
24 * Maps a physical memory range into system space.
25 *
26 * ARGUMENTS
27 * PhysicalAddress
28 * First physical address to map;
29 *
30 * NumberOfBytes
31 * Number of bytes to map;
32 *
33 * CacheEnable
34 * Type of memory caching.
35 *
36 * RETURN VALUE
37 * The base virtual address which maps the region.
38 *
39 * NOTE
40 * Description moved here from include/ddk/mmfuncs.h.
41 * Code taken from ntoskrnl/mm/special.c.
42 *
43 * REVISIONS
44 *
45 * @implemented
46 */
47 PVOID STDCALL
48 MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress,
49 IN ULONG NumberOfBytes,
50 IN MEMORY_CACHING_TYPE CacheEnable)
51 {
52 PVOID Result;
53 ULONG Offset;
54 MEMORY_AREA* marea;
55 NTSTATUS Status;
56 ULONG i;
57 ULONG Protect;
58 PHYSICAL_ADDRESS BoundaryAddressMultiple;
59 PFN_TYPE Pfn;
60
61 DPRINT("MmMapIoSpace(%lx, %d, %d)\n", PhysicalAddress, NumberOfBytes, CacheEnable);
62
63 if (CacheEnable != MmNonCached &&
64 CacheEnable != MmCached &&
65 CacheEnable != MmWriteCombined)
66 {
67 return NULL;
68 }
69
70 BoundaryAddressMultiple.QuadPart = 0;
71 Result = NULL;
72 Offset = PhysicalAddress.u.LowPart % PAGE_SIZE;
73 NumberOfBytes += Offset;
74 PhysicalAddress.QuadPart -= Offset;
75 Protect = PAGE_EXECUTE_READWRITE | PAGE_SYSTEM;
76 if (CacheEnable != MmCached)
77 {
78 Protect |= (PAGE_NOCACHE | PAGE_WRITETHROUGH);
79 }
80
81 MmLockAddressSpace(MmGetKernelAddressSpace());
82 Status = MmCreateMemoryArea (MmGetKernelAddressSpace(),
83 MEMORY_AREA_IO_MAPPING,
84 &Result,
85 NumberOfBytes,
86 Protect,
87 &marea,
88 0,
89 FALSE,
90 BoundaryAddressMultiple);
91 MmUnlockAddressSpace(MmGetKernelAddressSpace());
92
93 if (!NT_SUCCESS(Status))
94 {
95 DPRINT("MmMapIoSpace failed (%lx)\n", Status);
96 return (NULL);
97 }
98 Pfn = PhysicalAddress.QuadPart >> PAGE_SHIFT;
99 for (i = 0; i < PAGE_ROUND_UP(NumberOfBytes); i += PAGE_SIZE, Pfn++)
100 {
101 Status = MmCreateVirtualMappingForKernel((char*)Result + i,
102 Protect,
103 &Pfn,
104 1);
105 if (!NT_SUCCESS(Status))
106 {
107 DbgPrint("Unable to create virtual mapping\n");
108 KEBUGCHECK(0);
109 }
110 }
111 return (PVOID)((ULONG_PTR)Result + Offset);
112 }
113
114
115 /**********************************************************************
116 * NAME EXPORTED
117 * MmUnmapIoSpace@8
118 *
119 * DESCRIPTION
120 * Unmaps a physical memory range from system space.
121 *
122 * ARGUMENTS
123 * BaseAddress
124 * The base virtual address which maps the region;
125 *
126 * NumberOfBytes
127 * Number of bytes to unmap.
128 *
129 * RETURN VALUE
130 * None.
131 *
132 * NOTE
133 * Code taken from ntoskrnl/mm/special.c.
134 *
135 * REVISIONS
136 *
137 * @implemented
138 */
139 VOID STDCALL
140 MmUnmapIoSpace (IN PVOID BaseAddress,
141 IN ULONG NumberOfBytes)
142 {
143 ULONG Offset;
144 PVOID Address = BaseAddress;
145
146 Offset = (ULONG_PTR)Address % PAGE_SIZE;
147 Address = RVA(Address, - Offset);
148 NumberOfBytes += Offset;
149
150 MmLockAddressSpace(MmGetKernelAddressSpace());
151 MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
152 Address,
153 NULL,
154 NULL);
155 MmUnlockAddressSpace(MmGetKernelAddressSpace());
156 }
157
158
159 /**********************************************************************
160 * NAME EXPORTED
161 * MmMapVideoDisplay@16
162 *
163 * @implemented
164 */
165 PVOID STDCALL
166 MmMapVideoDisplay (IN PHYSICAL_ADDRESS PhysicalAddress,
167 IN ULONG NumberOfBytes,
168 IN MEMORY_CACHING_TYPE CacheType)
169 {
170 return MmMapIoSpace (PhysicalAddress, NumberOfBytes, (BOOLEAN)CacheType);
171 }
172
173
174 /*
175 * @implemented
176 */
177 VOID STDCALL
178 MmUnmapVideoDisplay (IN PVOID BaseAddress,
179 IN ULONG NumberOfBytes)
180 {
181 MmUnmapIoSpace (BaseAddress, NumberOfBytes);
182 }
183
184
185 /* EOF */