addded simulation and fixed serial
This commit is contained in:
parent
1b0f312834
commit
24edc2599b
@ -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
|
||||
|
@ -9,6 +9,7 @@
|
||||
[Sources]
|
||||
UefiMain.c
|
||||
drawing.c
|
||||
rng.c
|
||||
|
||||
[Packages]
|
||||
edk2/MdePkg/MdePkg.dec
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "drawing.h"
|
||||
#include "global.h"
|
||||
#include "macros.h"
|
||||
#include "rng.h"
|
||||
#include "types.h"
|
||||
#include <Base.h>
|
||||
#include <Library/BaseLib.h>
|
||||
@ -15,7 +16,9 @@
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Protocol/GraphicsOutput.h>
|
||||
#include <Uefi.h>
|
||||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
@ -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]) {
|
||||
|
@ -3,5 +3,5 @@
|
||||
#include <Protocol/GraphicsOutput.h>
|
||||
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);
|
||||
void clear_screen();
|
||||
BOOLEAN step_firework(firework_instance *firework);
|
@ -5,4 +5,4 @@
|
||||
.Red = ((hex) >> 16) & 0xFF, \
|
||||
.Reserved = 0}
|
||||
|
||||
#define SERIAL_PRINT(str) SerialPortWrite((UINT8 *)str, AsciiStrLen(str))
|
||||
#define SERIAL_PRINT(str) SerialPortWrite((UINT8 *)str, AsciiStrLen(str))
|
||||
|
71
src/UEFI_fireworks/rng.c
Normal file
71
src/UEFI_fireworks/rng.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include "rng.h"
|
||||
#include "Library/UefiBootServicesTableLib.h"
|
||||
#include "Library/UefiLib.h"
|
||||
#include "ProcessorBind.h"
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/RngLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Uefi.h>
|
||||
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;
|
||||
}
|
||||
}
|
3
src/UEFI_fireworks/rng.h
Normal file
3
src/UEFI_fireworks/rng.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
extern void (*fill_random_bytes)(void *dst, UINTN n);
|
||||
void init_rng();
|
@ -2,18 +2,12 @@
|
||||
#include "ProcessorBind.h"
|
||||
#include "Protocol/GraphicsOutput.h"
|
||||
#include <Library/BaseLib.h>
|
||||
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')
|
||||
} firework_instance;
|
||||
|
4
test.sh
4
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user