diff --git a/sdk/xtdk/kefuncs.h b/sdk/xtdk/kefuncs.h index fa8d831..3dbb8ea 100644 --- a/sdk/xtdk/kefuncs.h +++ b/sdk/xtdk/kefuncs.h @@ -24,6 +24,11 @@ XTFASTCALL VOID KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock); +XTAPI +XTSTATUS +KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + XTAPI BOOLEAN KeCancelTimer(IN PKTIMER Timer); @@ -32,6 +37,11 @@ XTFASTCALL KRUNLEVEL KeGetCurrentRunLevel(VOID); +XTAPI +XTSTATUS +KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + XTAPI BOOLEAN KeGetTimerState(IN PKTIMER Timer); @@ -101,6 +111,10 @@ XTFASTCALL VOID KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); +XTAPI +VOID +KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader); + XTAPI VOID KeSetTargetProcessorDpc(IN PKDPC Dpc, diff --git a/sdk/xtdk/ketypes.h b/sdk/xtdk/ketypes.h index 23cc289..7cb6ba4 100644 --- a/sdk/xtdk/ketypes.h +++ b/sdk/xtdk/ketypes.h @@ -183,6 +183,13 @@ typedef enum _MODE MaximumMode } MODE, *PMODE; +/* System resource types */ +typedef enum _SYSTEM_RESOURCE_TYPE +{ + SystemResourceInvalid, + SystemResourceFrameBuffer +} SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE; + /* Wait type */ typedef enum _WAIT_TYPE { @@ -500,4 +507,40 @@ typedef struct _KTHREAD BOOLEAN StackResident; } KTHREAD, *PKTHREAD; +/* System resource common header structure definition */ +typedef struct _SYSTEM_RESOURCE_HEADER +{ + LIST_ENTRY ListEntry; + SYSTEM_RESOURCE_TYPE ResourceType; + ULONG ResourceSize; + PVOID PhysicalAddress; + PVOID VirtualAddress; + BOOLEAN Acquired; +} SYSTEM_RESOURCE_HEADER, *PSYSTEM_RESOURCE_HEADER; + +/* FrameBuffer system resource structure definition */ +typedef struct _SYSTEM_RESOURCE_FRAMEBUFFER +{ + SYSTEM_RESOURCE_HEADER Header; + ULONG_PTR BufferSize; + UINT Width; + UINT Height; + UINT Depth; + UINT PixelsPerScanLine; + UINT BitsPerPixel; + UINT Pitch; + PVOID Font; + struct + { + USHORT BlueShift; + USHORT BlueSize; + USHORT GreenShift; + USHORT GreenSize; + USHORT RedShift; + USHORT RedSize; + USHORT ReservedShift; + USHORT ReservedSize; + } Pixels; +} SYSTEM_RESOURCE_FRAMEBUFFER, *PSYSTEM_RESOURCE_FRAMEBUFFER; + #endif /* __XTDK_KEFUNCS_H */ diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 1b53dc2..f61f9d5 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -32,6 +32,7 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.c ${XTOSKRNL_SOURCE_DIR}/ke/semphore.c ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.c + ${XTOSKRNL_SOURCE_DIR}/ke/sysres.c ${XTOSKRNL_SOURCE_DIR}/ke/timer.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irqs.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.c diff --git a/xtoskrnl/includes/globals.h b/xtoskrnl/includes/globals.h index bc43d6c..5ca422b 100644 --- a/xtoskrnl/includes/globals.h +++ b/xtoskrnl/includes/globals.h @@ -42,6 +42,12 @@ EXTERN KSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable[KSERVICE_TABLES_COUNT] /* Kernel process list */ EXTERN LIST_ENTRY KepProcessListHead; +/* Kernel system resources list */ +EXTERN LIST_ENTRY KepSystemResourcesListHead; + +/* Kernel system resources lock */ +EXTERN KSPIN_LOCK KepSystemResourcesLock; + /* Biggest free memory descriptor */ EXTERN PLOADER_MEMORY_MAPPING MmFreeDescriptor; diff --git a/xtoskrnl/includes/kei.h b/xtoskrnl/includes/kei.h index 59b8fd3..d1956d1 100644 --- a/xtoskrnl/includes/kei.h +++ b/xtoskrnl/includes/kei.h @@ -90,6 +90,16 @@ XTFASTCALL VOID KepExitDispatcher(IN KRUNLEVEL OldRunLevel); +XTAPI +VOID +KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + IN BOOLEAN Acquire, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + +XTAPI +XTSTATUS +KepInitializeSystemResources(VOID); + XTAPI VOID KepRemoveTimer(IN OUT PKTIMER Timer); diff --git a/xtoskrnl/ke/globals.c b/xtoskrnl/ke/globals.c index b0c3e68..28c6904 100644 --- a/xtoskrnl/ke/globals.c +++ b/xtoskrnl/ke/globals.c @@ -26,3 +26,9 @@ KSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable[KSERVICE_TABLES_COUNT]; /* Kernel process list */ LIST_ENTRY KepProcessListHead; + +/* Kernel system resources list */ +LIST_ENTRY KepSystemResourcesListHead; + +/* Kernel system resources lock */ +KSPIN_LOCK KepSystemResourcesLock; diff --git a/xtoskrnl/ke/sysres.c b/xtoskrnl/ke/sysres.c new file mode 100644 index 0000000..30cfd46 --- /dev/null +++ b/xtoskrnl/ke/sysres.c @@ -0,0 +1,214 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/sysres.c + * DESCRIPTION: Builtin system resources management + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Looks for an unacquired system resource of the specified type and acquires it. + * + * @param ResourceType + * Supplies system resource type. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + /* Acquire system resource */ + KepGetSystemResource(ResourceType, TRUE, ResourceHeader); + + /* Return status code */ + return (*ResourceHeader == NULL) ? STATUS_NOT_FOUND : STATUS_SUCCESS; +} + +/** + * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership. + * + * @param ResourceType + * Supplies system resource type. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + /* Get system resource */ + KepGetSystemResource(ResourceType, FALSE, ResourceHeader); + + /* Return status code */ + return (*ResourceHeader == NULL) ? STATUS_NOT_FOUND : STATUS_SUCCESS; +} + +/** + * Releases system resource. + * + * @param ResourceHeader + * Specifies a pointer to the system resource header. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) +{ + /* Disable interrupts and acquire a spinlock */ + ArClearInterruptFlag(); + KeAcquireSpinLock(&KepSystemResourcesLock); + + /* Release system resource */ + ResourceHeader->Acquired = FALSE; + + /* Release spinlock and enable interrupts */ + KeReleaseSpinLock(&KepSystemResourcesLock); + ArSetInterruptFlag(); +} + +/** + * Initializes system resource management. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KepInitializeSystemResources(VOID) +{ + PSYSTEM_RESOURCE_HEADER ResourceHeader; + PLIST_ENTRY ListEntry, NextListEntry; + ULONG ResourceSize; + + /* Initialize system resources spin lock and resource list */ + KeInitializeSpinLock(&KepSystemResourcesLock); + RtlInitializeListHead(&KepSystemResourcesListHead); + + /* Make sure there are some system resources available */ + if(!RtlListEmpty(&KeInitializationBlock->SystemResourcesListHead)) + { + /* Iterate through system resources list */ + ListEntry = KeInitializationBlock->SystemResourcesListHead.Flink; + while(ListEntry != &KeInitializationBlock->SystemResourcesListHead) + { + /* Get resource header and next list entry */ + ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); + NextListEntry = ListEntry->Flink; + + /* Basic resource type validation */ + switch(ResourceHeader->ResourceType) + { + case SystemResourceFrameBuffer: + /* FrameBuffer system resource */ + ResourceSize = sizeof(SYSTEM_RESOURCE_FRAMEBUFFER); + break; + default: + /* Unknown system resource type, return error */ + return STATUS_UNSUCCESSFUL; + } + + /* Validate resource size */ + if(ResourceHeader->ResourceSize == ResourceSize) + { + /* Move valid resource to the internal kernel list of system resources */ + RtlRemoveEntryList(&ResourceHeader->ListEntry); + RtlInsertTailList(&KepSystemResourcesListHead, &ResourceHeader->ListEntry); + } + + /* Go to the next list entry */ + ListEntry = NextListEntry; + } + } + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Looks for an unacquired system resource of the specified type. + * + * @param ResourceType + * Supplies system resource type. + * + * @param Acquire + * Specifies whether system resource should be acquired or not. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + IN BOOLEAN Acquire, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + PSYSTEM_RESOURCE_HEADER Resource; + PLIST_ENTRY ListEntry; + + /* Disable interrupts and acquire a spinlock */ + ArClearInterruptFlag(); + KeAcquireSpinLock(&KepSystemResourcesLock); + + /* Iterate through system resources list */ + ListEntry = KepSystemResourcesListHead.Flink; + while(ListEntry != &KepSystemResourcesListHead) + { + /* Get resource header */ + Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); + + /* Check if resource type matches and it's not already acquired */ + if(Resource->ResourceType == ResourceType && Resource->Acquired == FALSE) + { + /* Check if resource should be acquired */ + if(Acquire) + { + /* Mark resource as acquired */ + Resource->Acquired = TRUE; + } + + /* Stop browsing a list */ + break; + } + + /* Go to the next list entry */ + ListEntry = ListEntry->Flink; + } + + /* Check if resource was found */ + if(ListEntry == &KepSystemResourcesListHead) + { + /* Resource not found, return NULL */ + Resource = NULL; + } + + /* Release spinlock and enable interrupts */ + KeReleaseSpinLock(&KepSystemResourcesLock); + ArSetInterruptFlag(); + + /* Return resource header */ + *ResourceHeader = Resource; +} diff --git a/xtoskrnl/xtoskrnl.spec b/xtoskrnl/xtoskrnl.spec index 9944db7..d1c152b 100644 --- a/xtoskrnl/xtoskrnl.spec +++ b/xtoskrnl/xtoskrnl.spec @@ -13,9 +13,11 @@ @ cdecl HlIoPortOutShort(ptr long) @ fastcall KeAcquireQueuedSpinLock(long) @ fastcall KeAcquireSpinLock(ptr) +@ stdcall KeAcquireSystemResource(long ptr) @ stdcall KeCancelTimer(ptr) @ fastcall KeGetCurrentRunLevel() @ stdcall KeGetTimerState(ptr) +@ stdcall KeGetSystemResource(long ptr) @ stdcall KeInitializeApc(ptr ptr long ptr ptr ptr long ptr) @ stdcall KeInitializeDpc(ptr ptr ptr) @ stdcall KeInitializeSemaphore(ptr long long) @@ -28,6 +30,7 @@ @ stdcall KeReleaseSemaphore(ptr long long long) @ fastcall KeReleaseQueuedSpinLock(long) @ fastcall KeReleaseSpinLock(ptr) +@ stdcall KeReleaseSystemResource(ptr) @ stdcall KeSetTargetProcessorDpc(ptr long) @ stdcall KeSetTimer(ptr long long long ptr) @ stdcall KeSignalCallDpcDone(ptr)