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