From e245754d95af163d8d965f08d351d7634de47140 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 25 Nov 2023 23:14:15 +0100 Subject: [PATCH] Add running level management support --- xtoskrnl/CMakeLists.txt | 2 + xtoskrnl/hl/amd64/runlevel.c | 75 ++++++++++++++++++++ xtoskrnl/hl/i686/runlevel.c | 133 +++++++++++++++++++++++++++++++++++ xtoskrnl/includes/hl.h | 17 +++++ xtoskrnl/includes/ke.h | 12 ++++ xtoskrnl/ke/runlevel.c | 81 +++++++++++++++++++++ 6 files changed, 320 insertions(+) create mode 100644 xtoskrnl/hl/amd64/runlevel.c create mode 100644 xtoskrnl/hl/i686/runlevel.c create mode 100644 xtoskrnl/ke/runlevel.c diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index f378862..f24a455 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/hl/globals.c ${XTOSKRNL_SOURCE_DIR}/hl/pic.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c + ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.c ${XTOSKRNL_SOURCE_DIR}/ke/apc.c ${XTOSKRNL_SOURCE_DIR}/ke/dpc.c ${XTOSKRNL_SOURCE_DIR}/ke/event.c @@ -26,6 +27,7 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c ${XTOSKRNL_SOURCE_DIR}/ke/kthread.c ${XTOSKRNL_SOURCE_DIR}/ke/panic.c + ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.c ${XTOSKRNL_SOURCE_DIR}/ke/semphore.c ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.c ${XTOSKRNL_SOURCE_DIR}/ke/timer.c diff --git a/xtoskrnl/hl/amd64/runlevel.c b/xtoskrnl/hl/amd64/runlevel.c new file mode 100644 index 0000000..d67b5d5 --- /dev/null +++ b/xtoskrnl/hl/amd64/runlevel.c @@ -0,0 +1,75 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/hl/amd64/runlevel.c + * DESCRIPTION: Run Level management support for AMD64 architecture + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Gets the current run level from APIC for the current processor. + * + * @return This routine returns the current run level. + * + * @since XT 1.0 + */ +XTFASTCALL +KRUNLEVEL +HlGetRunLevel() +{ + return (KRUNLEVEL)ArReadControlRegister(8); +} + +/** + * Sets new run level for the current processor. + * + * @param RunLevel + * Supplies the new run level to store into APIC. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +HlSetRunLevel(IN KRUNLEVEL RunLevel) +{ + ArWriteControlRegister(8, RunLevel); +} + +/** + * Maps APIC interrupt vector to XT run level. + * + * @param Tpr + * Supplies the interrupt vector rad from APIC Task Priority Register. + * + * @return This routine returns the XT run level corresponding to the specified APIC interrupt vector. + * + * @since XT 1.0 + */ +XTFASTCALL +KRUNLEVEL +HlpTransformApicTprToRunLevel(IN UCHAR Tpr) +{ + return (KRUNLEVEL)(Tpr >> 4); +} + +/** + * Maps XT run level to interrupt vector suitable for the APIC Task Priority Register. + * + * @param RunLevel + * Supplies the XT run level. + * + * @return This routine returns the APIC interrupt vector corresponding to the specified XT run level. + * + * @since XT 1.0 + */ +XTFASTCALL +UCHAR +HlpTransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel) +{ + return (RunLevel << 4); +} diff --git a/xtoskrnl/hl/i686/runlevel.c b/xtoskrnl/hl/i686/runlevel.c new file mode 100644 index 0000000..8a22b35 --- /dev/null +++ b/xtoskrnl/hl/i686/runlevel.c @@ -0,0 +1,133 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/hl/i686/runlevel.c + * DESCRIPTION: Run Level management support for i686 architecture + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Gets the current run level from APIC for the current processor. + * + * @return This routine returns the current run level. + * + * @since XT 1.0 + */ +XTFASTCALL +KRUNLEVEL +HlGetRunLevel() +{ + return HlpTransformApicTprToRunLevel(HlReadApicRegister(APIC_TPR)); +} + +/** + * Sets new run level for the current processor. + * + * @param RunLevel + * Supplies the new run level to store into APIC. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +HlSetRunLevel(IN KRUNLEVEL RunLevel) +{ + HlWriteApicRegister(APIC_TPR, HlpTransformRunLevelToApicTpr(RunLevel)); +} + +/** + * Maps APIC interrupt vector to XT run level. + * + * @param Tpr + * Supplies the interrupt vector rad from APIC Task Priority Register. + * + * @return This routine returns the XT run level corresponding to the specified APIC interrupt vector. + * + * @since XT 1.0 + */ +XTFASTCALL +KRUNLEVEL +HlpTransformApicTprToRunLevel(IN UCHAR Tpr) +{ + KRUNLEVEL TransformationTable[16] = + { + PASSIVE_LEVEL, + PASSIVE_LEVEL, + PASSIVE_LEVEL, + APC_LEVEL, + DISPATCH_LEVEL, + DEVICE1_LEVEL, + DEVICE2_LEVEL, + DEVICE3_LEVEL, + DEVICE4_LEVEL, + DEVICE5_LEVEL, + DEVICE6_LEVEL, + DEVICE7_LEVEL, + PROFILE_LEVEL, + CLOCK_LEVEL, + IPI_LEVEL, + HIGH_LEVEL + }; + + /* Return the run level corresponding to the TPR from the transformation table. */ + return TransformationTable[Tpr / 16]; +} + +/** + * Maps XT run level to interrupt vector suitable for the APIC Task Priority Register. + * + * @param RunLevel + * Supplies the XT run level. + * + * @return This routine returns the APIC interrupt vector corresponding to the specified XT run level. + * + * @since XT 1.0 + */ +XTFASTCALL +UCHAR +HlpTransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel) +{ + UCHAR TransformationTable[32] = + { + APIC_VECTOR_ZERO, + APIC_VECTOR_APC, + APIC_VECTOR_DPC, + APIC_VECTOR_DPC, + APIC_VECTOR_DEVICE1, + APIC_VECTOR_DEVICE2, + APIC_VECTOR_DEVICE3, + APIC_VECTOR_DEVICE4, + APIC_VECTOR_DEVICE5, + APIC_VECTOR_DEVICE6, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_DEVICE7, + APIC_VECTOR_GENERIC, + APIC_VECTOR_CLOCK, + APIC_VECTOR_IPI, + APIC_VECTOR_POWERFAIL, + APIC_VECTOR_NMI + }; + + /* Return the TPR corresponding to the run level from the transformation table. */ + return TransformationTable[RunLevel]; +} diff --git a/xtoskrnl/includes/hl.h b/xtoskrnl/includes/hl.h index 2eda761..fb72c9b 100644 --- a/xtoskrnl/includes/hl.h +++ b/xtoskrnl/includes/hl.h @@ -40,6 +40,11 @@ HlDrawPixel(IN ULONG PosX, IN ULONG PosY, IN ULONG Color); +XTFASTCALL +KRUNLEVEL +HlGetRunLevel(); + + XTCDECL XTSTATUS HlInitializeComPort(IN OUT PCPPORT Port, @@ -55,9 +60,21 @@ XTFASTCALL ULONG HlReadApicRegister(IN APIC_REGISTER Register); +XTFASTCALL +VOID +HlSetRunLevel(IN KRUNLEVEL RunLevel); + XTFASTCALL VOID HlWriteApicRegister(IN APIC_REGISTER Register, IN ULONG Value); +XTFASTCALL +KRUNLEVEL +HlpTransformApicTprToRunLevel(IN UCHAR Tpr); + +XTFASTCALL +UCHAR +HlpTransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel); + #endif /* __XTOSKRNL_HL_H */ diff --git a/xtoskrnl/includes/ke.h b/xtoskrnl/includes/ke.h index 1bbdbeb..0dd8e0b 100644 --- a/xtoskrnl/includes/ke.h +++ b/xtoskrnl/includes/ke.h @@ -17,6 +17,10 @@ XTAPI VOID KeClearEvent(IN PKEVENT Event); +XTFASTCALL +KRUNLEVEL +KeGetCurrentRunLevel(); + XTAPI VOID KeHaltSystem(); @@ -47,6 +51,10 @@ KeInitializeThread(IN PKPROCESS Process, IN PVOID Stack, IN BOOLEAN StartThread); +XTFASTCALL +VOID +KeLowerRunLevel(IN KRUNLEVEL RunLevel); + XTAPI VOID KePanic(IN ULONG Code); @@ -59,6 +67,10 @@ KePanicEx(IN ULONG Code, IN ULONG_PTR Parameter3, IN ULONG_PTR Parameter4); +XTFASTCALL +KRUNLEVEL +KeRaiseRunLevel(IN KRUNLEVEL RunLevel); + XTAPI LONG KeSetEvent(IN PKEVENT Event, diff --git a/xtoskrnl/ke/runlevel.c b/xtoskrnl/ke/runlevel.c new file mode 100644 index 0000000..dee28b0 --- /dev/null +++ b/xtoskrnl/ke/runlevel.c @@ -0,0 +1,81 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/runlevel.c + * DESCRIPTION: Running Level management support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Gets the current running level of the current processor. + * + * @return This routine returns the current running level. + * + * @since XT 1.0 + */ +XTFASTCALL +KRUNLEVEL +KeGetCurrentRunLevel() +{ + return HlGetRunLevel(); +} + +/** + * Lowers the running level of the current processor. + * + * @param RunLevel + * Supplies the new running level to lower to. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +KeLowerRunLevel(IN KRUNLEVEL RunLevel) +{ + KRUNLEVEL OldRunLevel; + + /* Read current run level */ + OldRunLevel = HlGetRunLevel(); + + /* Validate run level lowerage */ + if(OldRunLevel > RunLevel) + { + /* Set new, lower run level */ + HlSetRunLevel(RunLevel); + } +} + +/** + * Raises the running level of the current processor. + * + * @param RunLevel + * Supplies the new running level to raise to. + * + * @return This routine returns the old running level. + * + * @since XT 1.0 + */ +XTFASTCALL +KRUNLEVEL +KeRaiseRunLevel(IN KRUNLEVEL RunLevel) +{ + KRUNLEVEL OldRunLevel; + + /* Read current run level */ + OldRunLevel = HlGetRunLevel(); + + /* Validate run level raise */ + if(OldRunLevel < RunLevel) + { + /* Set new, higher run level */ + HlSetRunLevel(RunLevel); + } + + /* Return old run level */ + return OldRunLevel; +}