sysres.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*++
  2. Copyright (c) 2012 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. sysres.c
  9. Abstract:
  10. This module implements management of builtin system resources.
  11. Author:
  12. Evan Green 17-Oct-2012
  13. Environment:
  14. Kernel
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/kernel/kernel.h>
  20. #include "keinit.h"
  21. #include "kep.h"
  22. //
  23. // ---------------------------------------------------------------- Definitions
  24. //
  25. #define SYSTEM_RESOURCE_ALLOCATION_TAG 0x52737953 // 'RsyS'
  26. //
  27. // ------------------------------------------------------ Data Type Definitions
  28. //
  29. //
  30. // ----------------------------------------------- Internal Function Prototypes
  31. //
  32. //
  33. // -------------------------------------------------------------------- Globals
  34. //
  35. //
  36. // Define a lock that protects access to the system resources and the system
  37. // resource list head.
  38. //
  39. KSPIN_LOCK KeSystemResourceSpinLock;
  40. LIST_ENTRY KeSystemResourceListHead;
  41. //
  42. // ------------------------------------------------------------------ Functions
  43. //
  44. KERNEL_API
  45. PSYSTEM_RESOURCE_HEADER
  46. KeAcquireSystemResource (
  47. SYSTEM_RESOURCE_TYPE ResourceType
  48. )
  49. /*++
  50. Routine Description:
  51. This routine attempts to find an unacquired system resource of the given
  52. type.
  53. Arguments:
  54. ResourceType - Supplies the type of builtin resource to acquire.
  55. Return Value:
  56. Returns a pointer to a resource of the given type on success.
  57. NULL on failure.
  58. --*/
  59. {
  60. return KepGetSystemResource(ResourceType, TRUE);
  61. }
  62. KERNEL_API
  63. VOID
  64. KeReleaseSystemResource (
  65. PSYSTEM_RESOURCE_HEADER ResourceHeader
  66. )
  67. /*++
  68. Routine Description:
  69. This routine releases a system resource.
  70. Arguments:
  71. ResourceHeader - Supplies a pointer to the resource header to release back
  72. to the system.
  73. Return Value:
  74. None.
  75. --*/
  76. {
  77. BOOL Enabled;
  78. Enabled = ArDisableInterrupts();
  79. KeAcquireSpinLock(&KeSystemResourceSpinLock);
  80. ResourceHeader->Acquired = FALSE;
  81. KeReleaseSpinLock(&KeSystemResourceSpinLock);
  82. if (Enabled != FALSE) {
  83. ArEnableInterrupts();
  84. }
  85. return;
  86. }
  87. KSTATUS
  88. KepInitializeSystemResources (
  89. PKERNEL_INITIALIZATION_BLOCK Parameters,
  90. ULONG Phase
  91. )
  92. /*++
  93. Routine Description:
  94. This routine initializes the system resource manager.
  95. Arguments:
  96. Parameters - Supplies a pointer to the kernel initialization block.
  97. Phase - Supplies the phase. Valid values are 0 and 1.
  98. Return Value:
  99. Status code.
  100. --*/
  101. {
  102. PLIST_ENTRY CurrentEntry;
  103. PSYSTEM_RESOURCE_HEADER GenericHeader;
  104. ULONG NewEntrySize;
  105. PSYSTEM_RESOURCE_HEADER NewHeader;
  106. KSTATUS Status;
  107. LIST_ENTRY TemporaryListHead;
  108. Status = STATUS_SUCCESS;
  109. //
  110. // In phase 0, initialize the spin lock and move all resources off of the
  111. // loader block. Pools are not yet available.
  112. //
  113. if (Phase == 0) {
  114. KeInitializeSpinLock(&KeSystemResourceSpinLock);
  115. INITIALIZE_LIST_HEAD(&KeSystemResourceListHead);
  116. if (LIST_EMPTY(&(Parameters->SystemResourceListHead)) == FALSE) {
  117. MOVE_LIST(&(Parameters->SystemResourceListHead),
  118. &KeSystemResourceListHead);
  119. INITIALIZE_LIST_HEAD(&(Parameters->SystemResourceListHead));
  120. }
  121. } else {
  122. ASSERT(Phase == 1);
  123. //
  124. // In preparation for all boot mappings being released, reallocate
  125. // each entry in non-paged pool. Start by putting all current entries
  126. // on a temporary list.
  127. //
  128. INITIALIZE_LIST_HEAD(&TemporaryListHead);
  129. if (LIST_EMPTY(&KeSystemResourceListHead) == FALSE) {
  130. MOVE_LIST(&KeSystemResourceListHead, &TemporaryListHead);
  131. INITIALIZE_LIST_HEAD(&KeSystemResourceListHead);
  132. }
  133. //
  134. // Grab each item off the temporary list.
  135. //
  136. while (!LIST_EMPTY(&TemporaryListHead)) {
  137. CurrentEntry = TemporaryListHead.Next;
  138. LIST_REMOVE(CurrentEntry);
  139. GenericHeader = LIST_VALUE(CurrentEntry,
  140. SYSTEM_RESOURCE_HEADER,
  141. ListEntry);
  142. //
  143. // Determine the size of the entry.
  144. //
  145. switch (GenericHeader->Type) {
  146. case SystemResourceFrameBuffer:
  147. NewEntrySize = sizeof(SYSTEM_RESOURCE_FRAME_BUFFER);
  148. break;
  149. case SystemResourceHardwareModule:
  150. NewEntrySize = sizeof(SYSTEM_RESOURCE_HARDWARE_MODULE);
  151. break;
  152. case SystemResourceRamDisk:
  153. NewEntrySize = sizeof(SYSTEM_RESOURCE_RAM_DISK);
  154. break;
  155. case SystemResourceDebugDevice:
  156. NewEntrySize = sizeof(SYSTEM_RESOURCE_DEBUG_DEVICE);
  157. break;
  158. //
  159. // Unknown resource type. Something bad has probably happened.
  160. //
  161. default:
  162. ASSERT(FALSE);
  163. Status = STATUS_UNSUCCESSFUL;
  164. goto InitializeSystemResourcesEnd;
  165. }
  166. //
  167. // Allocate and initialize the new entry.
  168. //
  169. NewHeader = MmAllocateNonPagedPool(NewEntrySize,
  170. SYSTEM_RESOURCE_ALLOCATION_TAG);
  171. if (NewHeader == NULL) {
  172. Status = STATUS_NO_MEMORY;
  173. goto InitializeSystemResourcesEnd;
  174. }
  175. RtlCopyMemory(NewHeader, GenericHeader, NewEntrySize);
  176. //
  177. // Insert the new entry onto the main list. Simply drop the old
  178. // boot entry as it will get cleaned up later during MM
  179. // initialization.
  180. //
  181. INSERT_BEFORE(&(NewHeader->ListEntry), &KeSystemResourceListHead);
  182. }
  183. }
  184. InitializeSystemResourcesEnd:
  185. return Status;
  186. }
  187. PSYSTEM_RESOURCE_HEADER
  188. KepGetSystemResource (
  189. SYSTEM_RESOURCE_TYPE ResourceType,
  190. BOOL Acquire
  191. )
  192. /*++
  193. Routine Description:
  194. This routine attempts to find an unacquired system resource of the given
  195. type.
  196. Arguments:
  197. ResourceType - Supplies the type of builtin resource to acquire.
  198. Acquire - Supplies a boolean indicating if the resource should be acquired
  199. or not.
  200. Return Value:
  201. Returns a pointer to a resource of the given type on success.
  202. NULL on failure.
  203. --*/
  204. {
  205. PLIST_ENTRY CurrentEntry;
  206. BOOL Enabled;
  207. PSYSTEM_RESOURCE_HEADER Header;
  208. //
  209. // Acquire the high level lock.
  210. //
  211. Enabled = ArDisableInterrupts();
  212. KeAcquireSpinLock(&KeSystemResourceSpinLock);
  213. CurrentEntry = KeSystemResourceListHead.Next;
  214. while (CurrentEntry != &KeSystemResourceListHead) {
  215. Header = LIST_VALUE(CurrentEntry, SYSTEM_RESOURCE_HEADER, ListEntry);
  216. if ((Header->Type == ResourceType) && (Header->Acquired == FALSE)) {
  217. if (Acquire != FALSE) {
  218. Header->Acquired = TRUE;
  219. }
  220. break;
  221. }
  222. CurrentEntry = CurrentEntry->Next;
  223. }
  224. if (CurrentEntry == &KeSystemResourceListHead) {
  225. Header = NULL;
  226. }
  227. //
  228. // Release the high level lock.
  229. //
  230. KeReleaseSpinLock(&KeSystemResourceSpinLock);
  231. if (Enabled != FALSE) {
  232. ArEnableInterrupts();
  233. }
  234. return Header;
  235. }
  236. //
  237. // --------------------------------------------------------- Internal Functions
  238. //