f06428116c1fa803e057518c07b448228705df61
1 /* $Id: kmap.c,v 1.10 2001/05/05 19:13:10 chorns Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/kmap.c
6 * PURPOSE: Implements the kernel memory pool
7 * PROGRAMMER: David Welch (welch@cwcom.net)
10 /* INCLUDES ****************************************************************/
12 #include <ddk/ntddk.h>
13 #include <internal/mm.h>
14 #include <internal/bitops.h>
15 #include <internal/ntoskrnl.h>
16 #include <internal/pool.h>
19 #include <internal/debug.h>
21 /* GLOBALS *****************************************************************/
23 #define ALLOC_MAP_SIZE (NONPAGED_POOL_SIZE / PAGESIZE)
26 * One bit for each page in the kmalloc region
27 * If set then the page is used by a kmalloc block
29 static unsigned int AllocMap
[ALLOC_MAP_SIZE
/32]={0,};
30 static KSPIN_LOCK AllocMapLock
;
32 static PVOID NonPagedPoolBase
;
34 /* FUNCTIONS ***************************************************************/
37 ExUnmapPage(PVOID Addr
)
40 ULONG i
= (Addr
- NonPagedPoolBase
) / PAGESIZE
;
42 DPRINT("ExUnmapPage(Addr %x)\n",Addr
);
45 KeAcquireSpinLock(&AllocMapLock
, &oldIrql
);
46 MmDeleteVirtualMapping(NULL
, (PVOID
)Addr
, FALSE
, NULL
, NULL
);
47 clear_bit(i
%32, &AllocMap
[i
/32]);
48 KeReleaseSpinLock(&AllocMapLock
, oldIrql
);
56 PhysPage
= (ULONG
)MmAllocPage(0);
62 return(ExAllocatePageWithPhysPage(PhysPage
));
66 MiZeroPage(ULONG PhysPage
)
70 TempAddress
= ExAllocatePageWithPhysPage(PhysPage
);
71 if (TempAddress
== NULL
)
73 return(STATUS_NO_MEMORY
);
75 memset(TempAddress
, 0, PAGESIZE
);
76 ExUnmapPage(TempAddress
);
77 return(STATUS_SUCCESS
);
81 MiCopyFromUserPage(ULONG DestPhysPage
, PVOID SourceAddress
)
85 TempAddress
= ExAllocatePageWithPhysPage(DestPhysPage
);
86 if (TempAddress
== NULL
)
88 return(STATUS_NO_MEMORY
);
90 memcpy(TempAddress
, SourceAddress
, PAGESIZE
);
91 ExUnmapPage(TempAddress
);
92 return(STATUS_SUCCESS
);
96 ExAllocatePageWithPhysPage(ULONG PhysPage
)
103 KeAcquireSpinLock(&AllocMapLock
, &oldlvl
);
104 for (i
=1; i
<ALLOC_MAP_SIZE
;i
++)
106 if (!test_bit(i
%32,&AllocMap
[i
/32]))
109 set_bit(i
%32,&AllocMap
[i
/32]);
110 addr
= (ULONG
)(NonPagedPoolBase
+ (i
*PAGESIZE
));
111 Status
= MmCreateVirtualMapping(NULL
,
113 PAGE_READWRITE
| PAGE_SYSTEM
,
115 if (!NT_SUCCESS(Status
))
117 DbgPrint("Unable to create virtual mapping\n");
120 KeReleaseSpinLock(&AllocMapLock
, oldlvl
);
124 KeReleaseSpinLock(&AllocMapLock
, oldlvl
);
129 MmInitKernelMap(PVOID BaseAddress
)
131 NonPagedPoolBase
= BaseAddress
;
132 KeInitializeSpinLock(&AllocMapLock
);
136 MiAllocNonPagedPoolRegion(ULONG nr_pages
)
138 * FUNCTION: Allocates a region of pages within the nonpaged pool area
141 unsigned int start
= 0;
142 unsigned int length
= 0;
145 for (i
=1; i
<ALLOC_MAP_SIZE
;i
++)
147 if (!test_bit(i
%32,&AllocMap
[i
/32]))
158 if (length
==nr_pages
)
160 for (j
=start
;j
<(start
+length
);j
++)
162 set_bit(j
%32,&AllocMap
[j
/32]);
164 DPRINT("returning %x\n",((start
*PAGESIZE
)+NonPagedPoolBase
));
165 return(((start
*PAGESIZE
)+NonPagedPoolBase
));
174 DbgPrint("CRITICAL: Out of non-paged pool space\n");