From 24edc2599b36e9a4ade19f2a4ca20defd61a0820 Mon Sep 17 00:00:00 2001 From: PoliEcho Date: Fri, 15 Aug 2025 17:09:27 +0200 Subject: [PATCH] addded simulation and fixed serial --- UEFI_fireworks.dsc | 11 ++- src/UEFI_fireworks/UEFI_fireworks.inf | 1 + src/UEFI_fireworks/UefiMain.c | 114 +++++++++++++++++--------- src/UEFI_fireworks/drawing.c | 13 +-- src/UEFI_fireworks/drawing.h | 4 +- src/UEFI_fireworks/macros.h | 2 +- src/UEFI_fireworks/rng.c | 71 ++++++++++++++++ src/UEFI_fireworks/rng.h | 3 + src/UEFI_fireworks/types.h | 12 +-- test.sh | 4 +- 10 files changed, 172 insertions(+), 63 deletions(-) create mode 100644 src/UEFI_fireworks/rng.c create mode 100644 src/UEFI_fireworks/rng.h diff --git a/UEFI_fireworks.dsc b/UEFI_fireworks.dsc index c194651..b9a4000 100644 --- a/UEFI_fireworks.dsc +++ b/UEFI_fireworks.dsc @@ -17,16 +17,19 @@ MemoryAllocationLib|edk2/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAlloca DevicePathLib|edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiBootServicesTableLib|edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf UefiRuntimeServicesTableLib|edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf -DebugLib|edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +DebugLib|edk2/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf PrintLib|edk2/MdePkg/Library/BasePrintLib/BasePrintLib.inf PcdLib|edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf RegisterFilterLib|edk2/MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf StackCheckLib|edk2/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf -TimerLib|edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf IoLib|edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf RngLib|edk2/MdePkg/Library/BaseRngLib/BaseRngLib.inf -SerialPortLib|edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf - +SerialPortLib|edk2/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf +TimerLib|edk2/OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf +PciLib|edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf +HobLib|edk2/MdePkg/Library/DxeHobLib/DxeHobLib.inf +PciCf8Lib|edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf +DebugPrintErrorLevelLib|edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf [Components] src/UEFI_fireworks/UEFI_fireworks.inf diff --git a/src/UEFI_fireworks/UEFI_fireworks.inf b/src/UEFI_fireworks/UEFI_fireworks.inf index 1daca44..0ea9ed2 100644 --- a/src/UEFI_fireworks/UEFI_fireworks.inf +++ b/src/UEFI_fireworks/UEFI_fireworks.inf @@ -9,6 +9,7 @@ [Sources] UefiMain.c drawing.c + rng.c [Packages] edk2/MdePkg/MdePkg.dec diff --git a/src/UEFI_fireworks/UefiMain.c b/src/UEFI_fireworks/UefiMain.c index 5de99a3..959090f 100644 --- a/src/UEFI_fireworks/UefiMain.c +++ b/src/UEFI_fireworks/UefiMain.c @@ -3,6 +3,7 @@ #include "drawing.h" #include "global.h" #include "macros.h" +#include "rng.h" #include "types.h" #include #include @@ -15,7 +16,9 @@ #include #include #include +#include +firework_instance create_firework(); EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *framebuffer = NULL; @@ -40,60 +43,89 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle, framebuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)GraphicsOutput->Mode->FrameBufferBase; - clear_screen(GraphicsOutput); - - LIST_ENTRY firework_list; - InitializeListHead(&firework_list); + init_rng(); if (SerialPortInitialize() == RETURN_SUCCESS) { - SERIAL_PRINT("Serial initialized"); + SERIAL_PRINT("Serial initialized\n"); } else { - Print(L"Failed to initialize Serial"); - Exit(RETURN_DEVICE_ERROR); + Print(L"Failed to initialize Serial!\n"); } + SerialPortSetControl(EFI_SERIAL_CLEAR_TO_SEND | + EFI_SERIAL_DATA_TERMINAL_READY | + EFI_SERIAL_REQUEST_TO_SEND); + + firework_instance *firework_array[UINT8_MAX]; + gBS->SetMem(firework_array, sizeof(firework_array), + 0); // make all pointers null + + SERIAL_PRINT("DOES it work?"); + Print(L"If you see this message timer does not work\n"); + MicroSecondDelay(1000); + clear_screen(); + while (TRUE) { - UINT32 random; - GetRandomNumber32(&random); + UINT8 random; + fill_random_bytes(&random, sizeof(random)); if (random % 6 == 0) { // spawn new firework - firework_node *new_firework_node = - AllocateZeroPool(sizeof(firework_node)); - if (new_firework_node == NULL) { + firework_instance *new_firework_instence = + AllocateZeroPool(sizeof(firework_instance)); + if (new_firework_instence == NULL) { return EFI_OUT_OF_RESOURCES; } - new_firework_node->Signature = FIREWORK_NODE_SIGNATURE; - GetRandomNumber32(&random); - new_firework_node->Firework.max_r = - random % 501; // so max number can be 500 - for (UINT8 i = 0; i < ARRAY_SIZE(new_firework_node->Firework.color); - i++) { - GetRandomNumber32( - (UINT32 *)&new_firework_node->Firework.color[i]); // belive - new_firework_node->Firework.r[i] = 0; + + *new_firework_instence = create_firework(); + + for (UINT8 i = 0; i < ARRAY_SIZE(firework_array); i++) { + if (firework_array[i] == NULL || firework_array[i]->active != TRUE) { + if (firework_array[i] != NULL) { + FreePool(firework_array[i]); // free firework + firework_array[i] = NULL; + } + firework_array[i] = new_firework_instence; + goto assgned; + } // firework will not be created if if all slots are full } - new_firework_node->Firework.cleanup_r = 0; - GetRandomNumber32(&random); - new_firework_node->Firework.x = - random % GraphicsOutput->Mode->Info->HorizontalResolution + 1; - GetRandomNumber32(&random); - new_firework_node->Firework.y = - random % GraphicsOutput->Mode->Info->VerticalResolution + 1; - - InsertTailList(&firework_list, &new_firework_node->Link); + Print(L"NO free slots\n"); } - - firework_node *current_node = NULL; - for (LIST_ENTRY *node = GetFirstNode(&firework_list); - !IsNodeAtEnd(&firework_list, node); - node = GetNextNode(&firework_list, node)) { - // Print(L"Processing firework\r\n"); - - current_node = CR(node, firework_node, Link, FIREWORK_NODE_SIGNATURE); - if (!step_firework(¤t_node->Firework)) { - RemoveEntryList(node); // remove if firework ended + assgned: + for (UINT8 i = 0; i < ARRAY_SIZE(firework_array); i++) { + if (firework_array[i] != NULL) { + if (firework_array[i]->active == TRUE) { + if (!step_firework(firework_array[i])) { + firework_array[i]->active = FALSE; + } + } else { + FreePool(firework_array[i]); // free firework + firework_array[i] = NULL; + } } } - MicroSecondDelay(500000); + + MicroSecondDelay(100000); } + return EFI_SUCCESS; } + +firework_instance create_firework() { + firework_instance firework; + UINT32 random; + fill_random_bytes(&random, sizeof(random)); + firework.max_r = (random % 200) + 1; // 1 to 200, avoiding 0 + + for (UINT8 i = 0; i < ARRAY_SIZE(firework.color); i++) { + fill_random_bytes(&firework.color[i], + sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) - 1); + firework.r[i] = 0; + } + firework.cleanup_r = 0; + + fill_random_bytes(&random, sizeof(random)); + firework.x = random % GraphicsOutput->Mode->Info->HorizontalResolution; + fill_random_bytes(&random, sizeof(random)); + firework.y = random % GraphicsOutput->Mode->Info->VerticalResolution; + + firework.active = TRUE; + return firework; +} \ No newline at end of file diff --git a/src/UEFI_fireworks/drawing.c b/src/UEFI_fireworks/drawing.c index 35a7d69..a9558ef 100644 --- a/src/UEFI_fireworks/drawing.c +++ b/src/UEFI_fireworks/drawing.c @@ -9,12 +9,15 @@ void draw_pixel(const UINT32 x, const UINT32 y, const EFI_GRAPHICS_OUTPUT_BLT_PIXEL pixel) { + if (x > GraphicsOutput->Mode->Info->HorizontalResolution || + y > GraphicsOutput->Mode->Info + ->VerticalResolution) { // ignore when out of bounds + return; + } UINTN framebuffer_offset = (y * GraphicsOutput->Mode->Info->PixelsPerScanLine) + x; - if (framebuffer_offset < - GraphicsOutput->Mode->FrameBufferSize) { // ignre when out of bounds - framebuffer[framebuffer_offset] = pixel; - } + + framebuffer[framebuffer_offset] = pixel; } // uses Mid-Point Circle Drawing Algorithm @@ -82,7 +85,7 @@ void clear_screen() { } } -BOOLEAN step_firework(struct firework_instance *firework) { +BOOLEAN step_firework(firework_instance *firework) { for (UINT8 i = 0; i < ARRAY_SIZE(firework->r); i++) { if (firework->r[i] < firework->max_r) { if (i == 0 || (firework->max_r / 3.5) * i <= firework->r[i - 1]) { diff --git a/src/UEFI_fireworks/drawing.h b/src/UEFI_fireworks/drawing.h index 806eea2..e23ba04 100644 --- a/src/UEFI_fireworks/drawing.h +++ b/src/UEFI_fireworks/drawing.h @@ -3,5 +3,5 @@ #include void draw_circle(int xc, int yc, int r, const EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); -void clear_screen(EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput); -BOOLEAN step_firework(struct firework_instance *firework); \ No newline at end of file +void clear_screen(); +BOOLEAN step_firework(firework_instance *firework); \ No newline at end of file diff --git a/src/UEFI_fireworks/macros.h b/src/UEFI_fireworks/macros.h index 0b4bb70..a3e7ef7 100644 --- a/src/UEFI_fireworks/macros.h +++ b/src/UEFI_fireworks/macros.h @@ -5,4 +5,4 @@ .Red = ((hex) >> 16) & 0xFF, \ .Reserved = 0} -#define SERIAL_PRINT(str) SerialPortWrite((UINT8 *)str, AsciiStrLen(str)) \ No newline at end of file +#define SERIAL_PRINT(str) SerialPortWrite((UINT8 *)str, AsciiStrLen(str)) diff --git a/src/UEFI_fireworks/rng.c b/src/UEFI_fireworks/rng.c new file mode 100644 index 0000000..c40ec78 --- /dev/null +++ b/src/UEFI_fireworks/rng.c @@ -0,0 +1,71 @@ +#include "rng.h" +#include "Library/UefiBootServicesTableLib.h" +#include "Library/UefiLib.h" +#include "ProcessorBind.h" +#include +#include +#include +#include +#include +void (*fill_random_bytes)(void *dst, UINTN n); + +UINT16 shift_LFSR(UINT16 LFSR) { + UINT16 lsb = LFSR & 1; + LFSR >>= 1; + if (lsb) { + LFSR ^= 0xB400; + } + return LFSR; +} + +void fill_random_bytes_LFSR(void *dst, UINTN n) { + static UINT16 LFSR = 0xf5d7; + + if (n % 2 != 0) { + LFSR = shift_LFSR(LFSR); + *(UINT8 *)dst = (UINT8)LFSR; + dst++; + n--; + } + while (n != 0) { + LFSR = shift_LFSR(LFSR); + *(UINT16 *)dst = LFSR; + dst += 2; + n -= 2; + } +} +void fill_random_bytes_TRUE(void *dst, UINTN n) { + UINT16 rand; + if (n % 2 != 0) { + GetRandomNumber16(&rand); + *(UINT8 *)dst = (UINT8)rand; + dst++; + n--; + } + while (n != 0) { + GetRandomNumber16(&rand); + *(UINT16 *)dst = rand; + dst += 2; + n -= 2; + } +} + +void init_rng() { + UINT16 test_var; + if (GetRandomNumber16(&test_var)) { + fill_random_bytes = fill_random_bytes_TRUE; + } else { + gST->ConOut->SetAttribute(gST->ConOut, EFI_YELLOW); + Print(L"[WARNING]"); + gST->ConOut->SetAttribute(gST->ConOut, EFI_WHITE); + Print(L" RNG device not available falling back to LFSR\r\n"); + + Print(L"Continuing in "); + for (UINT8 i = 5; i > 0; i--) { + Print(L"\b%d", i); + MicroSecondDelay(1000000); + } + + fill_random_bytes = fill_random_bytes_LFSR; + } +} \ No newline at end of file diff --git a/src/UEFI_fireworks/rng.h b/src/UEFI_fireworks/rng.h new file mode 100644 index 0000000..a2c1589 --- /dev/null +++ b/src/UEFI_fireworks/rng.h @@ -0,0 +1,3 @@ +#pragma once +extern void (*fill_random_bytes)(void *dst, UINTN n); +void init_rng(); \ No newline at end of file diff --git a/src/UEFI_fireworks/types.h b/src/UEFI_fireworks/types.h index 7404067..33a266a 100644 --- a/src/UEFI_fireworks/types.h +++ b/src/UEFI_fireworks/types.h @@ -2,18 +2,12 @@ #include "ProcessorBind.h" #include "Protocol/GraphicsOutput.h" #include -struct firework_instance { +typedef struct { + BOOLEAN active; // IF FALSE can be overwriten UINT32 x; UINT32 y; UINT16 max_r; UINT16 r[3]; EFI_GRAPHICS_OUTPUT_BLT_PIXEL color[3]; UINT16 cleanup_r; -}; - -typedef struct { - UINTN Signature; - struct firework_instance Firework; - LIST_ENTRY Link; -} firework_node; -#define FIREWORK_NODE_SIGNATURE SIGNATURE_32('f', 'w', 'r', 'k') \ No newline at end of file +} firework_instance; diff --git a/test.sh b/test.sh index 8e7c18e..5176c23 100755 --- a/test.sh +++ b/test.sh @@ -6,9 +6,11 @@ qemu-system-x86_64 \ -machine type=q35,accel=kvm \ -drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \ -drive if=pflash,format=raw,file=./my_ovmf_vars.fd \ - -hda fat:rw:$(dirname build/UEFI_fireworks.efi) \ + -hda fat:rw:build \ + -boot order=c \ -smp 4 \ -s \ -serial mon:stdio + rm ./my_ovmf_vars.fd