From a674d2eb1b880936dc64092d3d35885ba40696ab Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 8 Jan 2024 23:17:01 +0100 Subject: [PATCH] Import 'beep' module --- xtldr/modules/CMakeLists.txt | 1 + xtldr/modules/beep/CMakeLists.txt | 27 ++++ xtldr/modules/beep/beep.c | 209 ++++++++++++++++++++++++++ xtldr/modules/beep/globals.c | 13 ++ xtldr/modules/beep/includes/beep.h | 38 +++++ xtldr/modules/beep/includes/globals.h | 18 +++ 6 files changed, 306 insertions(+) create mode 100644 xtldr/modules/beep/CMakeLists.txt create mode 100644 xtldr/modules/beep/beep.c create mode 100644 xtldr/modules/beep/globals.c create mode 100644 xtldr/modules/beep/includes/beep.h create mode 100644 xtldr/modules/beep/includes/globals.h diff --git a/xtldr/modules/CMakeLists.txt b/xtldr/modules/CMakeLists.txt index 136fbbb..375c1d7 100644 --- a/xtldr/modules/CMakeLists.txt +++ b/xtldr/modules/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(beep) add_subdirectory(dummy) add_subdirectory(fb_o) add_subdirectory(pecoff_o) diff --git a/xtldr/modules/beep/CMakeLists.txt b/xtldr/modules/beep/CMakeLists.txt new file mode 100644 index 0000000..fb81272 --- /dev/null +++ b/xtldr/modules/beep/CMakeLists.txt @@ -0,0 +1,27 @@ +# XT Boot Loader Beep Module +PROJECT(XTLDR_BEEP) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_BEEP_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_BEEP_SOURCE + ${XTLDR_BEEP_SOURCE_DIR}/beep.c + ${XTLDR_BEEP_SOURCE_DIR}/globals.c) + +# Link bootloader executable +add_executable(beep ${XTLDR_BEEP_SOURCE}) + +# Add linker libraries +target_link_libraries(beep libxtldr libxtos) + +# Set proper binary name and install target +set_target_properties(beep PROPERTIES SUFFIX .efi) +set_install_target(beep efi/boot/xtldr/modules) + +# Set module entrypoint and subsystem +set_entrypoint(beep "XtLdrModuleMain") +set_linker_map(beep TRUE) +set_subsystem(beep efi_boot_service_driver) diff --git a/xtldr/modules/beep/beep.c b/xtldr/modules/beep/beep.c new file mode 100644 index 0000000..1eab7b0 --- /dev/null +++ b/xtldr/modules/beep/beep.c @@ -0,0 +1,209 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/beep/beep.c + * DESCRIPTION: XTLDR Beep Module + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* Dummy module information */ +XTBL_MODINFO = L"Plays a GRUB compatible tune via PC speaker"; + +/** + * Disables the PC speaker. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BpDisableToneBeep() +{ + UCHAR Status; + + /* Stop the PC speaker */ + Status = HlIoPortInByte(0x61); + HlIoPortOutByte(0x61, Status & 0xFC); +} + +/** + * Enables the PC speaker and plays a sound. + * + * @param Pitch + * Specifies a pitch (in Hz) of the sound. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BpEnableToneBeep(IN UINT Pitch) +{ + UINT Counter; + UCHAR Status; + + /* Pitch only in range of 20..20000 */ + if(Pitch < 20) + { + Pitch = 20; + } + else if(Pitch > 20000) + { + Pitch = 20000; + } + + /* Set the desired frequency of the PIT clock */ + Counter = 0x1234DD / Pitch; + HlIoPortOutByte(0x43, 0xB6); + HlIoPortOutByte(0x43, 0xB6); + HlIoPortOutByte(0x42, (UCHAR) Counter & 0xFF); + HlIoPortOutByte(0x42, (UCHAR) (Counter >> 8) & 0xFF); + + /* Start the PC speaker */ + Status = HlIoPortInByte(0x61); + HlIoPortOutByte(0x61, Status | 0x03); +} + +/** + * This routine plays a tune. + * + * @param Arguments + * Optional list of parameters provided with the command. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BpPlayTune(IN PWCHAR Arguments) +{ + LONG Pitch, Duration, Tempo; + PWCHAR Argument, LastArgument; + + /* Reset pitch and duration */ + Duration = -1; + Pitch = -1; + Tempo = -1; + + /* Tokenize provided list of arguments */ + Argument = RtlTokenizeWideString(Arguments, L" ", &LastArgument); + + /* Iterate over all arguments */ + while(Argument != NULL) + { + /* Check if tempo, pitch and duration are set */ + if(Tempo < 0) + { + /* Set the tempo */ + Tempo = BpWideStringToNumber(Argument); + } + else if(Pitch < 0) + { + /* Set the pitch */ + Pitch = BpWideStringToNumber(Argument); + } + else + { + /* Set the duration */ + Duration = BpWideStringToNumber(Argument); + + /* Check pitch value */ + if(Pitch > 0) + { + /* Emit the beep tone */ + BpEnableToneBeep(Pitch); + } + else + { + /* Stop emitting beep tone */ + BpDisableToneBeep(); + } + + /* Wait for duration time */ + XtLdrProto->Util.SleepExecution(60000 * Duration / Tempo); + + /* Reset pitch and duration */ + Pitch = -1; + Duration = -1; + } + + /* Get next argument */ + Argument = RtlTokenizeWideString(NULL, L" ", &LastArgument); + } + + /* Stop emitting beep tone */ + BpDisableToneBeep(); +} + +/** + * Converts a wide string into a number. + * + * @param String + * Supplies an input wide string. + * + * @return This routine returns the number that was converted from the wide string. + * + * @since XT 1.0 + */ +XTCDECL +UINT +BpWideStringToNumber(IN PWCHAR String) +{ + ULONG Number = 0; + + /* Iterate over all characters until '\0' found */ + do + { + /* Check if this is a digit */ + if(*String - '0' < 10) + { + /* Add another digit to the number */ + Number *= 10; + Number += *String - '0'; + } + } + while(*++String != L'\0'); + + /* Return number */ + return Number; +} + +/** + * This routine is the entry point of the XT EFI boot loader module. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param SystemTable + * Provides the EFI system table. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + EFI_STATUS Status; + + /* Open the XTLDR protocol */ + Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProto); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open the protocol, return error */ + return STATUS_EFI_PROTOCOL_ERROR; + } + + /* Play the tune set in the configuration */ + BpPlayTune(XtLdrProto->Config.GetValue(L"TUNE")); + + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr/modules/beep/globals.c b/xtldr/modules/beep/globals.c new file mode 100644 index 0000000..eb8e3cc --- /dev/null +++ b/xtldr/modules/beep/globals.c @@ -0,0 +1,13 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/beep/globals.c + * DESCRIPTION: Dummy XTLDR module global variables + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* XTLDR protocol handler */ +PXTBL_LOADER_PROTOCOL XtLdrProto; diff --git a/xtldr/modules/beep/includes/beep.h b/xtldr/modules/beep/includes/beep.h new file mode 100644 index 0000000..db0af8f --- /dev/null +++ b/xtldr/modules/beep/includes/beep.h @@ -0,0 +1,38 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/beep/includes/beep.h + * DESCRIPTION: XTLDR Beep Module header file + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_BEEP_BEEP_H +#define __XTLDR_BEEP_BEEP_H + +#include +#include + + +/* Beep module routines forward references */ +XTCDECL +VOID +BpDisableToneBeep(); + +XTCDECL +VOID +BpEnableToneBeep(IN UINT Pitch); + +XTCDECL +VOID +BpPlayTune(IN PWCHAR Arguments); + +XTCDECL +UINT +BpWideStringToNumber(IN PWCHAR String); + +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +#endif/* __XTLDR_BEEP_BEEP_H */ diff --git a/xtldr/modules/beep/includes/globals.h b/xtldr/modules/beep/includes/globals.h new file mode 100644 index 0000000..ee5bff0 --- /dev/null +++ b/xtldr/modules/beep/includes/globals.h @@ -0,0 +1,18 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/beep/includes/globals.h + * DESCRIPTION: XTLDR Beep Module global variables + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_BEEP_GLOBALS_H +#define __XTLDR_BEEP_GLOBALS_H + +#include + + +/* XTLDR protocol handler */ +EXTERN PXTBL_LOADER_PROTOCOL XtLdrProto; + +#endif/* __XTLDR_BEEP_GLOBALS_H */