Add Pound log and assert macros in every system, and fixed all linux

compiler warnings

Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
Ronald Caesar 2025-09-21 12:18:46 -04:00
parent df86db1aa4
commit 61f1340dee
11 changed files with 79 additions and 85 deletions

View file

@ -1,16 +1,8 @@
add_library(common STATIC) add_library(common STATIC)
target_sources(common PRIVATE target_sources(common PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/Config.cpp
${CMAKE_CURRENT_SOURCE_DIR}/IoFile.cpp
${CMAKE_CURRENT_SOURCE_DIR}/PathUtil.cpp
${CMAKE_CURRENT_SOURCE_DIR}/StringUtil.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Thread.cpp
${CMAKE_CURRENT_SOURCE_DIR}/logging.cpp ${CMAKE_CURRENT_SOURCE_DIR}/logging.cpp
${CMAKE_CURRENT_SOURCE_DIR}/passert.cpp ${CMAKE_CURRENT_SOURCE_DIR}/passert.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Logging/Backend.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Logging/Filter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Logging/TextFormatter.cpp
) )
target_link_libraries(common PUBLIC fmt::fmt) target_link_libraries(common PUBLIC fmt::fmt)

View file

@ -4,12 +4,12 @@
__attribute__((noreturn)) void pound_internal_assert_fail(const char* file, int line, const char* func, __attribute__((noreturn)) void pound_internal_assert_fail(const char* file, int line, const char* func,
const char* expr_str, const char* user_msg, ...); const char* expr_str, const char* user_msg, ...);
#define PVM_ASSERT(expression, ...) \ #define PVM_ASSERT(expression) \
do \ do \
{ \ { \
if (!(expression)) \ if (!(expression)) \
{ \ { \
pound_internal_assert_fail(__FILE__, __LINE__, __func__, #expression, nullptr, ##__VA_ARGS__); \ pound_internal_assert_fail(__FILE__, __LINE__, __func__, #expression, nullptr, nullptr); \
} \ } \
} while (0) } while (0)
@ -18,7 +18,7 @@ __attribute__((noreturn)) void pound_internal_assert_fail(const char* file, int
{ \ { \
if (!(expression)) \ if (!(expression)) \
{ \ { \
pound_internal_assert_fail(__FILE__, __LINE__, __func__, #expression, format, ##__VA_ARGS__); \ pound_internal_assert_fail(__FILE__, __LINE__, __func__, #expression, format __VA_OPT__(,) __VA_ARGS__); \
} \ } \
} while (0) } while (0)

View file

@ -1,9 +1,11 @@
#include "gui.h" #include "gui.h"
#include "color.h" #include "color.h"
#include <assert.h> #include "common/passert.h"
#include "common/Logging/Log.h"
#include "imgui_impl_opengl3_loader.h" #include "imgui_impl_opengl3_loader.h"
#define LOG_MODULE "FRONTEND"
#include "common/logging.h"
#include <imgui.h> #include <imgui.h>
#include <imgui_impl_opengl3.h> #include <imgui_impl_opengl3.h>
#include <imgui_impl_sdl3.h> #include <imgui_impl_sdl3.h>
@ -16,8 +18,8 @@ static void apply_theme();
bool gui::window_init(window_t* window, const char* title, int64_t width, int64_t height) bool gui::window_init(window_t* window, const char* title, int64_t width, int64_t height)
{ {
assert(nullptr != window); PVM_ASSERT(nullptr != window);
assert(nullptr != title); PVM_ASSERT(nullptr != title);
bool ret = ::SDL_Init(SDL_INIT_VIDEO); bool ret = ::SDL_Init(SDL_INIT_VIDEO);
if (false == ret) if (false == ret)
@ -119,8 +121,8 @@ void gui::window_destroy(gui::window_t* window)
bool gui::init_imgui(gui::window_t* main_window) bool gui::init_imgui(gui::window_t* main_window)
{ {
assert(nullptr != main_window->data); PVM_ASSERT(nullptr != main_window->data);
assert(nullptr != main_window->gl_context); PVM_ASSERT(nullptr != main_window->gl_context);
// Initialize ImGui // Initialize ImGui
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
@ -137,9 +139,9 @@ bool gui::init_imgui(gui::window_t* main_window)
return false; return false;
} }
#ifdef __APPLE__ && (__aarch64__) #if defined(__APPLE__) && defined(__aarch64__)
ret = ::ImGui_ImplOpenGL3_Init("#version 120"); ret = ::ImGui_ImplOpenGL3_Init("#version 120");
#elif __APPLE__ && (__x86_64__) #elif defined(__APPLE__) && defined(__x86_64__)
ret = ::ImGui_ImplOpenGL3_Init("#version 150"); ret = ::ImGui_ImplOpenGL3_Init("#version 150");
#else #else
ret = ::ImGui_ImplOpenGL3_Init("#version 330"); ret = ::ImGui_ImplOpenGL3_Init("#version 330");

View file

@ -2,14 +2,14 @@
#include <imgui.h> #include <imgui.h>
#include <math.h> #include <math.h>
#include "kvm/kvm.h" #include "kvm/kvm.h"
#include <assert.h>" #include "common/passert.h"
int8_t gui::panel::render_performance_panel(gui::panel::performance_panel_t* panel, performance_data_t* data, int8_t gui::panel::render_performance_panel(gui::panel::performance_panel_t* panel, performance_data_t* data,
std::chrono::steady_clock::time_point* last_render) std::chrono::steady_clock::time_point* last_render)
{ {
assert(nullptr != panel); PVM_ASSERT(nullptr != panel);
assert(nullptr != data); PVM_ASSERT(nullptr != data);
assert(nullptr != last_render); PVM_ASSERT(nullptr != last_render);
bool is_visible = true; bool is_visible = true;
(void)::ImGui::Begin(PANEL_NAME_PERFORMANCE, &is_visible); (void)::ImGui::Begin(PANEL_NAME_PERFORMANCE, &is_visible);
@ -25,8 +25,8 @@ int8_t gui::panel::render_performance_panel(gui::panel::performance_panel_t* pan
if (duration.count() >= 100) if (duration.count() >= 100)
{ {
// Every 100ms // Every 100ms
data->fps = data->frame_count * 1000.0f / duration.count(); data->fps = (float)data->frame_count * 1000.0f / (float)duration.count();
data->frame_time = duration.count() / (float)data->frame_count; data->frame_time = (float)duration.count() / (float)data->frame_count;
panel->fps_history.push_back(data->fps); panel->fps_history.push_back(data->fps);
panel->frame_time_history.push_back(data->frame_time); panel->frame_time_history.push_back(data->frame_time);
@ -82,7 +82,7 @@ int8_t gui::panel::render_performance_panel(gui::panel::performance_panel_t* pan
int8_t gui::panel::render_cpu_panel(bool* show_cpu_result_popup) int8_t gui::panel::render_cpu_panel(bool* show_cpu_result_popup)
{ {
assert(nullptr != show_cpu_result_popup); PVM_ASSERT(nullptr != show_cpu_result_popup);
bool is_visible = true; bool is_visible = true;
(void)::ImGui::Begin(PANEL_NAME_CPU, &is_visible, ImGuiWindowFlags_NoCollapse); (void)::ImGui::Begin(PANEL_NAME_CPU, &is_visible, ImGuiWindowFlags_NoCollapse);

View file

@ -1,5 +1,5 @@
#include "arena.h" #include "arena.h"
#include <cassert> #include "common/passert.h"
#include <cstring> #include <cstring>
#ifndef WIN32 #ifndef WIN32
#include <sys/mman.h> #include <sys/mman.h>
@ -33,22 +33,22 @@ arena_t arena_init(size_t capacity)
void* arena_allocate(memory::arena_t* arena, const std::size_t size) void* arena_allocate(memory::arena_t* arena, const std::size_t size)
{ {
assert(arena != nullptr); PVM_ASSERT(arena != nullptr);
assert(arena->size + size <= arena->capacity); PVM_ASSERT(arena->size + size <= arena->capacity);
void* const data = static_cast<uint8_t*>(arena->data) + arena->size; void* const data = static_cast<uint8_t*>(arena->data) + arena->size;
arena->size += size; arena->size += size;
return data; return data;
} }
void arena_reset(memory::arena_t* arena) void arena_reset(memory::arena_t* arena)
{ {
assert(nullptr != arena); PVM_ASSERT(nullptr != arena);
assert(nullptr != arena->data); PVM_ASSERT(nullptr != arena->data);
arena->size = 0; arena->size = 0;
(void)std::memset(arena->data, POISON_PATTERN, arena->capacity); (void)std::memset(arena->data, POISON_PATTERN, arena->capacity);
} }
void arena_free(memory::arena_t* arena) void arena_free(memory::arena_t* arena)
{ {
assert(arena != nullptr); PVM_ASSERT(arena != nullptr);
arena->capacity = 0; arena->capacity = 0;
arena->size = 0; arena->size = 0;
// TODO(GloriousTaco:memory): Replace free with a memory safe alternative. // TODO(GloriousTaco:memory): Replace free with a memory safe alternative.

View file

@ -1,12 +1,12 @@
#include "guest.h" #include "guest.h"
#include <cassert> #include "common/passert.h"
namespace pound::kvm::memory namespace pound::kvm::memory
{ {
guest_memory_t* guest_memory_create(pound::host::memory::arena_t* arena) guest_memory_t* guest_memory_create(pound::host::memory::arena_t* arena)
{ {
assert(nullptr != arena); PVM_ASSERT(nullptr != arena);
assert(nullptr != arena->data); PVM_ASSERT(nullptr != arena->data);
guest_memory_t* memory = (guest_memory_t*)pound::host::memory::arena_allocate(arena, sizeof(guest_memory_t)); guest_memory_t* memory = (guest_memory_t*)pound::host::memory::arena_allocate(arena, sizeof(guest_memory_t));
size_t ram_size = arena->capacity - arena->size; size_t ram_size = arena->capacity - arena->size;

View file

@ -1,9 +1,11 @@
#include "kvm.h" #include "kvm.h"
#include <cassert>
#include "common/Logging/Log.h"
#include "guest.h" #include "guest.h"
#include "common/passert.h"
#include "host/memory/arena.h" #include "host/memory/arena.h"
#define LOG_MODULE "kvm"
#include "common/logging.h"
namespace pound::kvm namespace pound::kvm
{ {
@ -11,7 +13,7 @@ uint8_t kvm_probe(kvm_t* kvm, enum target_type type)
{ {
if (type != KVM_TARGET_SWITCH1) if (type != KVM_TARGET_SWITCH1)
{ {
assert(!"Only Switch 1 is supported"); PVM_ASSERT_MSG(false, "Only Switch 1 is supported");
} }
kvm->ops = s1_ops; kvm->ops = s1_ops;
/* Go to targets/switch1/hardware/probe.cpp */ /* Go to targets/switch1/hardware/probe.cpp */
@ -21,11 +23,11 @@ uint8_t kvm_probe(kvm_t* kvm, enum target_type type)
void take_synchronous_exception(kvm_vcpu_t* vcpu, uint8_t exception_class, uint32_t iss, uint64_t faulting_address) void take_synchronous_exception(kvm_vcpu_t* vcpu, uint8_t exception_class, uint32_t iss, uint64_t faulting_address)
{ {
assert(nullptr != vcpu); PVM_ASSERT(nullptr != vcpu);
/* An EC holds 6 bits.*/ /* An EC holds 6 bits.*/
assert(0 == (exception_class & 11000000)); PVM_ASSERT(0 == (exception_class & 11000000));
/* An ISS holds 25 bits */ /* An ISS holds 25 bits */
assert(0 == (iss & 0xFE000000)); PVM_ASSERT(0 == (iss & 0xFE000000));
vcpu->elr_el1 = vcpu->pc; vcpu->elr_el1 = vcpu->pc;
vcpu->spsr_el1 = vcpu->pstate; vcpu->spsr_el1 = vcpu->pstate;
@ -69,11 +71,13 @@ void take_synchronous_exception(kvm_vcpu_t* vcpu, uint8_t exception_class, uint3
void cpuTest() void cpuTest()
{ {
#if 0
pound::host::memory::arena_t guest_memory_arena = pound::host::memory::arena_init(GUEST_RAM_SIZE); pound::host::memory::arena_t guest_memory_arena = pound::host::memory::arena_init(GUEST_RAM_SIZE);
assert(nullptr != guest_memory_arena.data); PVM_ASSERT(nullptr != guest_memory_arena.data);
memory::guest_memory_t* guest_ram = memory::guest_memory_create(&guest_memory_arena); memory::guest_memory_t* guest_ram = memory::guest_memory_create(&guest_memory_arena);
//(void)test_guest_ram_access(guest_ram); //(void)test_guest_ram_access(guest_ram);
#endif
} }
} // namespace pound::kvm } // namespace pound::kvm

View file

@ -1,5 +1,5 @@
#include "mmio.h" #include "mmio.h"
#include <cassert> #include "common/passert.h"
#include <algorithm> #include <algorithm>
namespace pound::kvm::memory namespace pound::kvm::memory
@ -17,11 +17,11 @@ bool mmio_compare_ranges(const mmio_range_t& a, const mmio_range_t& b)
int8_t mmio_db_register(mmio_db_t* db, const mmio_range_t range, const mmio_handler_t handler) int8_t mmio_db_register(mmio_db_t* db, const mmio_range_t range, const mmio_handler_t handler)
{ {
assert(nullptr != db); PVM_ASSERT(nullptr != db);
assert((db->address_ranges.size() + 1) <= MMIO_REGIONS); PVM_ASSERT((db->address_ranges.size() + 1) <= MMIO_REGIONS);
auto it = std::lower_bound(db->address_ranges.begin(), db->address_ranges.end(), range, mmio_compare_ranges); auto it = std::lower_bound(db->address_ranges.begin(), db->address_ranges.end(), range, mmio_compare_ranges);
size_t i = it - db->address_ranges.begin(); auto i = it - db->address_ranges.begin();
/* /*
* Scenario: UART is a current region, TIMER is a new region being * Scenario: UART is a current region, TIMER is a new region being
@ -34,7 +34,7 @@ int8_t mmio_db_register(mmio_db_t* db, const mmio_range_t range, const mmio_hand
*/ */
if (i > 0) if (i > 0)
{ {
if (range.gpa_base < db->address_ranges[i - 1].gpa_end) if (range.gpa_base < db->address_ranges[(size_t)i - 1].gpa_end)
{ {
return EADDRESS_OVERLAP; return EADDRESS_OVERLAP;
} }
@ -51,7 +51,7 @@ int8_t mmio_db_register(mmio_db_t* db, const mmio_range_t range, const mmio_hand
*/ */
if (i < db->address_ranges.size()) if (i < db->address_ranges.size())
{ {
if (db->address_ranges[i].gpa_base < range.gpa_end) if (db->address_ranges[(size_t)i].gpa_base < range.gpa_end)
{ {
return EADDRESS_OVERLAP; return EADDRESS_OVERLAP;
} }
@ -69,10 +69,10 @@ bool mmio_compare_addresses(const mmio_range_t& a, const mmio_range_t& b)
int8_t mmio_db_dispatch_write(mmio_db_t* db, kvm_t* kvm, uint64_t gpa, uint8_t* data, size_t len) int8_t mmio_db_dispatch_write(mmio_db_t* db, kvm_t* kvm, uint64_t gpa, uint8_t* data, size_t len)
{ {
assert(nullptr != db); PVM_ASSERT(nullptr != db);
assert(nullptr != kvm); PVM_ASSERT(nullptr != kvm);
assert(nullptr != data); PVM_ASSERT(nullptr != data);
assert(len > 0); PVM_ASSERT(len > 0);
mmio_range_t search_key = {.gpa_base = gpa, .gpa_end = 0}; mmio_range_t search_key = {.gpa_base = gpa, .gpa_end = 0};
/* Find the first region that starts after the target gpa */ /* Find the first region that starts after the target gpa */
@ -89,13 +89,13 @@ int8_t mmio_db_dispatch_write(mmio_db_t* db, kvm_t* kvm, uint64_t gpa, uint8_t*
/* base <= gpa < end */ /* base <= gpa < end */
if ((candidate.gpa_base <= gpa) && (gpa < candidate.gpa_end)) if ((candidate.gpa_base <= gpa) && (gpa < candidate.gpa_end))
{ {
size_t i = (it - 1) - db->address_ranges.begin(); auto i = (it - 1) - db->address_ranges.begin();
if (nullptr == db->handlers[i].write) if (nullptr == db->handlers[(size_t)i].write)
{ {
return EACCESS_DENIED; return EACCESS_DENIED;
} }
db->handlers[i].write(kvm, gpa, data, len); db->handlers[(size_t)i].write(kvm, gpa, data, len);
return MMIO_SUCCESS; return MMIO_SUCCESS;
} }
@ -105,10 +105,10 @@ int8_t mmio_db_dispatch_write(mmio_db_t* db, kvm_t* kvm, uint64_t gpa, uint8_t*
int8_t mmio_db_dispatch_read(mmio_db_t* db, kvm_t* kvm, uint64_t gpa, uint8_t* data, size_t len) int8_t mmio_db_dispatch_read(mmio_db_t* db, kvm_t* kvm, uint64_t gpa, uint8_t* data, size_t len)
{ {
assert(nullptr != db); PVM_ASSERT(nullptr != db);
assert(nullptr != kvm); PVM_ASSERT(nullptr != kvm);
assert(nullptr != data); PVM_ASSERT(nullptr != data);
assert(len > 0); PVM_ASSERT(len > 0);
mmio_range_t search_key = {.gpa_base = gpa, .gpa_end = 0}; mmio_range_t search_key = {.gpa_base = gpa, .gpa_end = 0};
/* Find the first region that starts after the target gpa */ /* Find the first region that starts after the target gpa */
@ -125,13 +125,13 @@ int8_t mmio_db_dispatch_read(mmio_db_t* db, kvm_t* kvm, uint64_t gpa, uint8_t* d
/* base <= gpa < end */ /* base <= gpa < end */
if ((candidate.gpa_base <= gpa) && (gpa < candidate.gpa_end)) if ((candidate.gpa_base <= gpa) && (gpa < candidate.gpa_end))
{ {
size_t i = (it - 1) - db->address_ranges.begin(); auto i = (it - 1) - db->address_ranges.begin();
if (nullptr == db->handlers[i].read) if (nullptr == db->handlers[(size_t)i].read)
{ {
return EACCESS_DENIED; return EACCESS_DENIED;
} }
db->handlers[i].read(kvm, gpa, data, len); db->handlers[(size_t)i].read(kvm, gpa, data, len);
return MMIO_SUCCESS; return MMIO_SUCCESS;
} }

View file

@ -1,6 +1,7 @@
#include "mmu.h" #include "mmu.h"
#include <limits.h>
#include "kvm.h" #include "kvm.h"
#include "common/passert.h"
#include <limits.h>
namespace pound::kvm::memory namespace pound::kvm::memory
{ {
@ -133,7 +134,7 @@ int mmu_gva_to_gpa(pound::kvm::kvm_vcpu_t* vcpu, guest_memory_t* memory, uint64_
* in bytes from the correct TGx field. * in bytes from the correct TGx field.
*/ */
uint64_t granule_size = 0; uint64_t granule_size = 0;
assert((true == is_ttbr0) || (true == is_ttbr1)); PVM_ASSERT((true == is_ttbr0) || (true == is_ttbr1));
if (true == is_ttbr0) if (true == is_ttbr0)
{ {
/* /*
@ -165,7 +166,7 @@ int mmu_gva_to_gpa(pound::kvm::kvm_vcpu_t* vcpu, guest_memory_t* memory, uint64_
* This is an illegal configuration. The hardware will fault. * This is an illegal configuration. The hardware will fault.
* For now, an assert will catch bad guest OS behaviour. * For now, an assert will catch bad guest OS behaviour.
*/ */
assert(!"Invalid TG0 value in TCR_EL1"); PVM_ASSERT_MSG(false, "Invalid TG0 value in TCR_EL1");
} }
} }
else else
@ -199,7 +200,7 @@ int mmu_gva_to_gpa(pound::kvm::kvm_vcpu_t* vcpu, guest_memory_t* memory, uint64_
granule_size = GRANULE_64KB; granule_size = GRANULE_64KB;
break; break;
default: default:
assert(!"Invalid TG1 value in TCR_EL1"); PVM_ASSERT_MSG(false, "Invalid TG1 value in TCR_EL1");
break; break;
} }
} }
@ -336,7 +337,7 @@ int mmu_gva_to_gpa(pound::kvm::kvm_vcpu_t* vcpu, guest_memory_t* memory, uint64_
level_index = (gva >> l3_shift) & page_table_index_mask; level_index = (gva >> l3_shift) & page_table_index_mask;
break; break;
default: default:
assert(!"Invalid page table configuration!"); PVM_ASSERT_MSG(false, "Invalid page table configuration!");
} }
const uint64_t level_entry_address = table_address + (level_index * page_table_entry_size); const uint64_t level_entry_address = table_address + (level_index * page_table_entry_size);
@ -388,7 +389,7 @@ int mmu_gva_to_gpa(pound::kvm::kvm_vcpu_t* vcpu, guest_memory_t* memory, uint64_
*/ */
else if (0b01 == (descriptor & 0b11)) else if (0b01 == (descriptor & 0b11))
{ {
assert(!"Block descriptors are not supported"); PVM_ASSERT_MSG(false, "Block descriptors are not supported");
} }
} }
return -1; return -1;

View file

@ -4,9 +4,9 @@
#include <memory> #include <memory>
#include <thread> #include <thread>
#include "common/Config.h" #define LOG_MODULE "main"
#include "common/Logging/Backend.h" #include "common/logging.h"
#include "common/Logging/Log.h" #include "common/passert.h"
#include "frontend/gui.h" #include "frontend/gui.h"
#include "host/memory/arena.h" #include "host/memory/arena.h"
@ -18,19 +18,12 @@
int main() int main()
{ {
Base::Log::Initialize();
Base::Log::Start();
const auto& config_dir = Base::FS::GetUserPath(Base::FS::PathType::BinaryDir);
Config::Load(config_dir / "config.toml");
// Create GUI manager
gui::window_t window = {.data = nullptr, .gl_context = nullptr}; gui::window_t window = {.data = nullptr, .gl_context = nullptr};
(void)gui::window_init(&window, "Pound Emulator", Config::windowWidth(), Config::windowHeight()); (void)gui::window_init(&window, "Pound Emulator", 640, 480);
if (bool return_code = gui::init_imgui(&window); false == return_code) if (bool return_code = gui::init_imgui(&window); false == return_code)
{ {
LOG_ERROR(Render, "Failed to initialize GUI"); LOG_ERROR( "Failed to initialize GUI");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -111,7 +104,7 @@ int main()
::ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ::ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
if (bool sdl_ret_code = ::SDL_GL_SwapWindow(gui.window.data); false == sdl_ret_code) if (bool sdl_ret_code = ::SDL_GL_SwapWindow(gui.window.data); false == sdl_ret_code)
{ {
LOG_ERROR(Render, "Failed to update window with OpenGL rendering: {}", SDL_GetError()); LOG_ERROR("Failed to update window with OpenGL rendering: {}", SDL_GetError());
is_running = false; is_running = false;
} }

View file

@ -1,5 +1,7 @@
#include "kvm/kvm.h" #include "kvm/kvm.h"
#include "common/Logging/Log.h"
#define LOG_MODULE "switch1"
#include "common/logging.h"
namespace pound::kvm namespace pound::kvm
{ {
@ -18,7 +20,7 @@ const kvm_ops_t s1_ops = {
static int8_t s1_init(kvm_t* kvm) static int8_t s1_init(kvm_t* kvm)
{ {
LOG_INFO(PROBE, "Initializing Switch 1 virtual machine"); LOG_INFO("Initializing Switch 1 virtual machine");
/* BOOTSTRAPPING CODE GOES HERE */ /* BOOTSTRAPPING CODE GOES HERE */
return 0; return 0;
} }