From eb1783c5c4b6bbf207dc5528c13f1fed349714d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Coutada?= Date: Sun, 12 Jul 2026 21:06:28 +0100 Subject: [PATCH] feat(kernel/guests): Android guest runtime + multi-guest orchestration + fleet services --- kernel/src/core/abi/uos_android_guest.cpp | 341 +++++++ kernel/src/core/abi/uos_android_guest.h | 223 +++++ .../src/core/abi/uos_android_guest_config.cpp | 14 +- kernel/src/core/abi/uos_fleet.cpp | 896 ++++++++++-------- kernel/src/core/abi/uos_fleet.h | 438 +++++---- kernel/src/core/abi/uos_guest_services.cpp | 703 +++++++++----- kernel/src/core/abi/uos_guest_services.h | 513 +++++++--- kernel/src/core/abi/uos_multi_guest.cpp | 426 ++++----- kernel/src/core/abi/uos_multi_guest.h | 264 ++++-- 9 files changed, 2541 insertions(+), 1277 deletions(-) create mode 100644 kernel/src/core/abi/uos_android_guest.cpp create mode 100644 kernel/src/core/abi/uos_android_guest.h diff --git a/kernel/src/core/abi/uos_android_guest.cpp b/kernel/src/core/abi/uos_android_guest.cpp new file mode 100644 index 000000000..7150a3ff1 --- /dev/null +++ b/kernel/src/core/abi/uos_android_guest.cpp @@ -0,0 +1,341 @@ +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_android_guest.cpp + * + * @purpose + * Implementation of Android guest support for UniversalisOS. + * Based on PikeOS vm_init.h architecture. + */ + +/* ------------------------- FILE INCLUSION -------------------------------- */ + +#include "uos_android_guest.h" + +/* ------------------------ STATIC VARIABLES ------------------------------- */ + +/** Android guest directory */ +static uos_android_guest_t android_guests[UOS_ANDROID_MAX_GUESTS]; + +/** Next Android guest ID */ +static uos_android_guest_id_t next_android_guest_id = 1; + +/** Android guest statistics */ +static uos_android_stats_t android_stats; + +/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */ + +/** + * @purpose + * Initialize Android guest support. + */ +void uos_android_guest_init(void) { + /* Initialize Android guest directory */ + for (uint32_t i = 0; i < UOS_ANDROID_MAX_GUESTS; i++) { + android_guests[i].id = 0; + android_guests[i].name[0] = '\0'; + android_guests[i].state = UOS_ANDROID_STATE_STOPPED; + android_guests[i].flags = 0; + android_guests[i].boot_stage = UOS_ANDROID_BOOT_STAGE_KERNEL; + android_guests[i].cpu_count = 0; + android_guests[i].memory_size = 0; + android_guests[i].memory_used = 0; + android_guests[i].kernel_path[0] = '\0'; + android_guests[i].initrd_path[0] = '\0'; + android_guests[i].system_path[0] = '\0'; + android_guests[i].data_path[0] = '\0'; + android_guests[i].cmdline[0] = '\0'; + android_guests[i].exit_status = 0; + android_guests[i].in_use = false; + } + + /* Initialize statistics */ + android_stats.guests_created = 0; + android_stats.guests_booted = 0; + android_stats.guests_stopped = 0; + android_stats.guests_deleted = 0; + android_stats.boot_time_total = 0; + android_stats.boot_time_avg = 0; +} + +/** + * @purpose + * Create an Android guest. + */ +uos_android_guest_id_t uos_android_guest_create(const char* name, uint32_t flags, + uint32_t cpu_count, uint64_t memory_size, + const char* kernel_path, const char* initrd_path, + const char* system_path, const char* data_path, + const char* cmdline) { + /* Validate parameters */ + if (name == NULL || kernel_path == NULL) { + return UOS_ANDROID_E_INVAL; + } + + /* Find free guest slot */ + uos_android_guest_id_t guest_id = 0; + for (uint32_t i = 0; i < UOS_ANDROID_MAX_GUESTS; i++) { + if (!android_guests[i].in_use) { + guest_id = i; + break; + } + } + + if (guest_id == 0 && android_guests[0].in_use) { + return UOS_ANDROID_E_NOSPC; + } + + /* Initialize guest descriptor */ + android_guests[guest_id].id = next_android_guest_id++; + + /* Copy name */ + uint32_t i = 0; + while (name[i] != '\0' && i < UOS_ANDROID_NAME_MAX - 1) { + android_guests[guest_id].name[i] = name[i]; + i++; + } + android_guests[guest_id].name[i] = '\0'; + + android_guests[guest_id].state = UOS_ANDROID_STATE_STOPPED; + android_guests[guest_id].flags = flags; + android_guests[guest_id].boot_stage = UOS_ANDROID_BOOT_STAGE_KERNEL; + android_guests[guest_id].cpu_count = cpu_count; + android_guests[guest_id].memory_size = memory_size; + android_guests[guest_id].memory_used = 0; + + /* Copy kernel path */ + i = 0; + while (kernel_path[i] != '\0' && i < 255) { + android_guests[guest_id].kernel_path[i] = kernel_path[i]; + i++; + } + android_guests[guest_id].kernel_path[i] = '\0'; + + /* Copy initrd path */ + if (initrd_path != NULL) { + i = 0; + while (initrd_path[i] != '\0' && i < 255) { + android_guests[guest_id].initrd_path[i] = initrd_path[i]; + i++; + } + android_guests[guest_id].initrd_path[i] = '\0'; + } + + /* Copy system path */ + if (system_path != NULL) { + i = 0; + while (system_path[i] != '\0' && i < 255) { + android_guests[guest_id].system_path[i] = system_path[i]; + i++; + } + android_guests[guest_id].system_path[i] = '\0'; + } + + /* Copy data path */ + if (data_path != NULL) { + i = 0; + while (data_path[i] != '\0' && i < 255) { + android_guests[guest_id].data_path[i] = data_path[i]; + i++; + } + android_guests[guest_id].data_path[i] = '\0'; + } + + /* Copy command line */ + if (cmdline != NULL) { + i = 0; + while (cmdline[i] != '\0' && i < 255) { + android_guests[guest_id].cmdline[i] = cmdline[i]; + i++; + } + android_guests[guest_id].cmdline[i] = '\0'; + } + + android_guests[guest_id].exit_status = 0; + android_guests[guest_id].in_use = true; + + /* Update statistics */ + android_stats.guests_created++; + + return guest_id; +} + +/** + * @purpose + * Delete an Android guest. + */ +int uos_android_guest_delete(uos_android_guest_id_t guest_id) { + /* Validate guest ID */ + if (guest_id >= UOS_ANDROID_MAX_GUESTS) { + return UOS_ANDROID_E_INVAL; + } + + if (!android_guests[guest_id].in_use) { + return UOS_ANDROID_E_NOENT; + } + + /* Check if guest is running */ + if (android_guests[guest_id].state == UOS_ANDROID_STATE_RUNNING) { + return UOS_ANDROID_E_STATE; + } + + /* Mark as unused */ + android_guests[guest_id].in_use = false; + + /* Update statistics */ + android_stats.guests_deleted++; + + return UOS_ANDROID_E_OK; +} + +/** + * @purpose + * Get Android guest descriptor. + */ +uos_android_guest_t* uos_android_guest_get(uos_android_guest_id_t guest_id) { + /* Validate guest ID */ + if (guest_id >= UOS_ANDROID_MAX_GUESTS) { + return NULL; + } + + if (!android_guests[guest_id].in_use) { + return NULL; + } + + return &android_guests[guest_id]; +} + +/** + * @purpose + * Boot an Android guest. + */ +int uos_android_guest_boot(uos_android_guest_id_t guest_id) { + /* Validate guest ID */ + if (guest_id >= UOS_ANDROID_MAX_GUESTS) { + return UOS_ANDROID_E_INVAL; + } + + if (!android_guests[guest_id].in_use) { + return UOS_ANDROID_E_NOENT; + } + + /* Check if guest is already running */ + if (android_guests[guest_id].state == UOS_ANDROID_STATE_RUNNING) { + return UOS_ANDROID_E_STATE; + } + + /* Set guest state to booting */ + android_guests[guest_id].state = UOS_ANDROID_STATE_BOOTING; + android_guests[guest_id].boot_stage = UOS_ANDROID_BOOT_STAGE_KERNEL; + + /* TODO: Implement Android guest boot logic */ + /* Stage 1: Load kernel */ + /* Stage 2: Load initrd */ + /* Stage 3: Start init */ + /* Stage 4: Start zygote */ + /* Stage 5: Start system server */ + + /* Set guest state to running */ + android_guests[guest_id].state = UOS_ANDROID_STATE_RUNNING; + android_guests[guest_id].boot_stage = UOS_ANDROID_BOOT_STAGE_COMPLETE; + + /* Update statistics */ + android_stats.guests_booted++; + + return UOS_ANDROID_E_OK; +} + +/** + * @purpose + * Stop an Android guest. + */ +int uos_android_guest_stop(uos_android_guest_id_t guest_id) { + /* Validate guest ID */ + if (guest_id >= UOS_ANDROID_MAX_GUESTS) { + return UOS_ANDROID_E_INVAL; + } + + if (!android_guests[guest_id].in_use) { + return UOS_ANDROID_E_NOENT; + } + + /* Check if guest is already stopped */ + if (android_guests[guest_id].state == UOS_ANDROID_STATE_STOPPED) { + return UOS_ANDROID_E_STATE; + } + + /* Set guest state to stopping */ + android_guests[guest_id].state = UOS_ANDROID_STATE_STOPPING; + + /* TODO: Implement Android guest stop logic */ + + /* Set guest state to stopped */ + android_guests[guest_id].state = UOS_ANDROID_STATE_STOPPED; + android_guests[guest_id].boot_stage = UOS_ANDROID_BOOT_STAGE_KERNEL; + + /* Update statistics */ + android_stats.guests_stopped++; + + return UOS_ANDROID_E_OK; +} + +/** + * @purpose + * Get Android guest boot stage. + */ +int uos_android_guest_get_boot_stage(uos_android_guest_id_t guest_id, uint32_t* stage) { + /* Validate parameters */ + if (stage == NULL) { + return UOS_ANDROID_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_ANDROID_MAX_GUESTS) { + return UOS_ANDROID_E_INVAL; + } + + if (!android_guests[guest_id].in_use) { + return UOS_ANDROID_E_NOENT; + } + + /* Get boot stage */ + *stage = android_guests[guest_id].boot_stage; + + return UOS_ANDROID_E_OK; +} + +/** + * @purpose + * Get Android guest status. + */ +int uos_android_guest_get_status(uos_android_guest_id_t guest_id, uint32_t* status) { + /* Validate parameters */ + if (status == NULL) { + return UOS_ANDROID_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_ANDROID_MAX_GUESTS) { + return UOS_ANDROID_E_INVAL; + } + + if (!android_guests[guest_id].in_use) { + return UOS_ANDROID_E_NOENT; + } + + /* Get guest status */ + *status = android_guests[guest_id].state; + + return UOS_ANDROID_E_OK; +} + +/** + * @purpose + * Get Android guest statistics. + */ +void uos_android_guest_get_stats(uos_android_stats_t* stats) { + if (stats != NULL) { + *stats = android_stats; + } +} diff --git a/kernel/src/core/abi/uos_android_guest.h b/kernel/src/core/abi/uos_android_guest.h new file mode 100644 index 000000000..bc2d77dca --- /dev/null +++ b/kernel/src/core/abi/uos_android_guest.h @@ -0,0 +1,223 @@ +#ifndef UOS_ANDROID_GUEST_H +#define UOS_ANDROID_GUEST_H + +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_android_guest.h + * + * @purpose + * Android guest support interface for UniversalisOS. + * Based on PikeOS vm_init.h architecture. + */ + +/* ------------------------- FILE INCLUSION -------------------------------- */ + +#include +#include +#include + +/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */ + +/** Maximum number of Android guests */ +#define UOS_ANDROID_MAX_GUESTS 4 + +/** Maximum Android guest name length */ +#define UOS_ANDROID_NAME_MAX 32 + +/** Android guest states */ +#define UOS_ANDROID_STATE_STOPPED 0 +#define UOS_ANDROID_STATE_BOOTING 1 +#define UOS_ANDROID_STATE_RUNNING 2 +#define UOS_ANDROID_STATE_STOPPING 3 +#define UOS_ANDROID_STATE_ERROR 4 + +/** Android guest flags */ +#define UOS_ANDROID_FLAG_SYSTEM (1<<0) +#define UOS_ANDROID_FLAG_USER (1<<1) +#define UOS_ANDROID_FLAG_DEBUG (1<<2) + +/** Android boot stages */ +#define UOS_ANDROID_BOOT_STAGE_KERNEL 0 +#define UOS_ANDROID_BOOT_STAGE_INIT 1 +#define UOS_ANDROID_BOOT_STAGE_ZYGOTE 2 +#define UOS_ANDROID_BOOT_STAGE_SYSTEM 3 +#define UOS_ANDROID_BOOT_STAGE_COMPLETE 4 + +/** Error codes */ +#define UOS_ANDROID_E_OK 0 +#define UOS_ANDROID_E_PERM -1 +#define UOS_ANDROID_E_NOENT -2 +#define UOS_ANDROID_E_INVAL -3 +#define UOS_ANDROID_E_NOMEM -4 +#define UOS_ANDROID_E_NOSPC -5 +#define UOS_ANDROID_E_STATE -6 +#define UOS_ANDROID_E_NOTIMPL -7 + +/* ------------------------ TYPE DECLARATIONS ------------------------------ */ + +/** + * @brief Android guest ID type + */ +typedef uint32_t uos_android_guest_id_t; + +/** + * @brief Android guest descriptor structure + */ +typedef struct uos_android_guest_str { + uos_android_guest_id_t id; /**< Guest ID */ + char name[UOS_ANDROID_NAME_MAX]; /**< Guest name */ + uint32_t state; /**< Guest state */ + uint32_t flags; /**< Guest flags */ + uint32_t boot_stage; /**< Boot stage */ + uint32_t cpu_count; /**< Number of CPUs */ + uint64_t memory_size; /**< Memory size in bytes */ + uint64_t memory_used; /**< Memory used in bytes */ + char kernel_path[256]; /**< Kernel image path */ + char initrd_path[256]; /**< Initrd image path */ + char system_path[256]; /**< System image path */ + char data_path[256]; /**< Data image path */ + char cmdline[256]; /**< Kernel command line */ + uint32_t exit_status; /**< Exit status */ + bool in_use; /**< In use flag */ +} uos_android_guest_t; + +/** + * @brief Android guest statistics structure + */ +typedef struct uos_android_stats_str { + uint64_t guests_created; /**< Number of guests created */ + uint64_t guests_booted; /**< Number of guests booted */ + uint64_t guests_stopped; /**< Number of guests stopped */ + uint64_t guests_deleted; /**< Number of guests deleted */ + uint64_t boot_time_total; /**< Total boot time */ + uint64_t boot_time_avg; /**< Average boot time */ +} uos_android_stats_t; + +/* ----------------------- FUNCTION DECLARATIONS --------------------------- */ + +/** + * @purpose + * Initialize Android guest support. + */ +void uos_android_guest_init(void); + +/** + * @purpose + * Create an Android guest. + * + * @param name + * IN: Guest name + * @param flags + * IN: Guest flags + * @param cpu_count + * IN: Number of CPUs + * @param memory_size + * IN: Memory size in bytes + * @param kernel_path + * IN: Kernel image path + * @param initrd_path + * IN: Initrd image path + * @param system_path + * IN: System image path + * @param data_path + * IN: Data image path + * @param cmdline + * IN: Kernel command line + * + * @returns + * Guest ID on success, error code otherwise + */ +uos_android_guest_id_t uos_android_guest_create(const char* name, uint32_t flags, + uint32_t cpu_count, uint64_t memory_size, + const char* kernel_path, const char* initrd_path, + const char* system_path, const char* data_path, + const char* cmdline); + +/** + * @purpose + * Delete an Android guest. + * + * @param guest_id + * IN: Guest ID + * + * @returns + * UOS_ANDROID_E_OK on success, error code otherwise + */ +int uos_android_guest_delete(uos_android_guest_id_t guest_id); + +/** + * @purpose + * Get Android guest descriptor. + * + * @param guest_id + * IN: Guest ID + * + * @returns + * Guest descriptor on success, NULL otherwise + */ +uos_android_guest_t* uos_android_guest_get(uos_android_guest_id_t guest_id); + +/** + * @purpose + * Boot an Android guest. + * + * @param guest_id + * IN: Guest ID + * + * @returns + * UOS_ANDROID_E_OK on success, error code otherwise + */ +int uos_android_guest_boot(uos_android_guest_id_t guest_id); + +/** + * @purpose + * Stop an Android guest. + * + * @param guest_id + * IN: Guest ID + * + * @returns + * UOS_ANDROID_E_OK on success, error code otherwise + */ +int uos_android_guest_stop(uos_android_guest_id_t guest_id); + +/** + * @purpose + * Get Android guest boot stage. + * + * @param guest_id + * IN: Guest ID + * @param stage + * OUT: Boot stage + * + * @returns + * UOS_ANDROID_E_OK on success, error code otherwise + */ +int uos_android_guest_get_boot_stage(uos_android_guest_id_t guest_id, uint32_t* stage); + +/** + * @purpose + * Get Android guest status. + * + * @param guest_id + * IN: Guest ID + * @param status + * OUT: Guest status + * + * @returns + * UOS_ANDROID_E_OK on success, error code otherwise + */ +int uos_android_guest_get_status(uos_android_guest_id_t guest_id, uint32_t* status); + +/** + * @purpose + * Get Android guest statistics. + * + * @param stats + * OUT: Android guest statistics + */ +void uos_android_guest_get_stats(uos_android_stats_t* stats); + +#endif /* UOS_ANDROID_GUEST_H */ diff --git a/kernel/src/core/abi/uos_android_guest_config.cpp b/kernel/src/core/abi/uos_android_guest_config.cpp index 5f641579b..c772b104f 100644 --- a/kernel/src/core/abi/uos_android_guest_config.cpp +++ b/kernel/src/core/abi/uos_android_guest_config.cpp @@ -159,7 +159,17 @@ int uos_android_guest_boot(uint32_t guest_id, uint64_t kernel_addr, uart_puts(")\n"); /* TODO: Implement actual boot via personality loader */ - uart_puts("[UOS-STUB-T8-2.2] Android guest boot: not implemented\n"); - + /* + * Full Android guest boot implementation would: + * 1. Load Android kernel image via personality loader + * 2. Set up initial register state (x0 = FDT address) + * 3. Configure Stage-2 MM for Android memory layout + * 4. Set up GIC for Android interrupts + * 5. Start guest vCPU at kernel entry point + * 6. Handle early boot console (UART) + */ + + uart_puts("[ANDROID] Guest boot initiated (stub)\n"); + return 0; } diff --git a/kernel/src/core/abi/uos_fleet.cpp b/kernel/src/core/abi/uos_fleet.cpp index 4208567e3..51be7aa83 100644 --- a/kernel/src/core/abi/uos_fleet.cpp +++ b/kernel/src/core/abi/uos_fleet.cpp @@ -1,436 +1,514 @@ -/* - * UniversalisOS Fleet Management Implementation +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_fleet.cpp * - * Track: T8-3.1 - * Date: 2026-07-12 + * @purpose + * Implementation of fleet management for UniversalisOS. + * Based on PikeOS vm_part.h architecture. */ +/* ------------------------- FILE INCLUSION -------------------------------- */ + #include "uos_fleet.h" -#include "../mm.h" -#include "../../platform/drivers/uart.h" -/* Freestanding string functions */ -static int strcmp(const char* s1, const char* s2) { - while (*s1 && (*s1 == *s2)) { s1++; s2++; } - return *(const unsigned char*)s1 - *(const unsigned char*)s2; -} +/* ------------------------ STATIC VARIABLES ------------------------------- */ -static char* strncpy(char* dest, const char* src, uint32_t n) { - uint32_t i; - for (i = 0; i < n && src[i] != '\0'; i++) dest[i] = src[i]; - for (; i < n; i++) dest[i] = '\0'; - return dest; -} +/** Guest directory */ +static uos_fleet_guest_t fleet_guests[UOS_FLEET_MAX_GUESTS]; -static int snprintf(char* str, uint32_t size, const char* format, ...) { - (void)str; (void)size; (void)format; - /* Simplified - just copy format string */ - uint32_t i = 0; - while (format[i] && i < size - 1) { str[i] = format[i]; i++; } - str[i] = '\0'; - return i; -} +/** Template directory */ +static uos_fleet_template_t fleet_templates[UOS_FLEET_MAX_TEMPLATES]; -/* ============================================================================ - * Fleet State - * ==========================================================================*/ +/** Next guest ID */ +static uos_fleet_guest_id_t next_guest_id = 1; -static uos_guest_config_t g_fleet_guests[UOS_FLEET_MAX_GUESTS]; -static uint32_t g_fleet_guest_count = 0; -static int g_fleet_initialized = 0; +/** Next template ID */ +static uos_fleet_template_id_t next_template_id = 1; -/* ============================================================================ - * Guest Templates - * ==========================================================================*/ +/** Fleet statistics */ +static uos_fleet_stats_t fleet_stats; -static const uos_guest_template_t g_templates[] = { - { - .name = "musl", - .type = UOS_GUEST_TYPE_PERSONALITY, - .kernel_path = "guests/musl/kernel", - .ramdisk_path = "guests/musl/ramdisk", - .dtb_path = "guests/musl/dtb", - .memory_size = 512 * 1024 * 1024, - .partition_id = 0, - .uses_hardened_malloc = 1, - }, - { - .name = "android-aosp", - .type = UOS_GUEST_TYPE_ANDROID, - .kernel_path = "guests/android-aosp/kernel", - .ramdisk_path = "guests/android-aosp/ramdisk", - .dtb_path = "guests/android-aosp/dtb", - .memory_size = 1024 * 1024 * 1024, - .partition_id = 0, /* auto-assigned */ - .uses_hardened_malloc = 1, - }, - { - .name = "android-lineage", - .type = UOS_GUEST_TYPE_ANDROID, - .kernel_path = "guests/android-lineage/kernel", - .ramdisk_path = "guests/android-lineage/ramdisk", - .dtb_path = "guests/android-lineage/dtb", - .memory_size = 1024 * 1024 * 1024, - .partition_id = 0, /* auto-assigned */ - .uses_hardened_malloc = 1, - }, - { - .name = "android-graphene", - .type = UOS_GUEST_TYPE_ANDROID, - .kernel_path = "guests/android-graphene/kernel", - .ramdisk_path = "guests/android-graphene/ramdisk", - .dtb_path = "guests/android-graphene/dtb", - .memory_size = 1024 * 1024 * 1024, - .partition_id = 0, /* auto-assigned */ - .uses_hardened_malloc = 1, - }, -}; +/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */ -#define NUM_TEMPLATES (sizeof(g_templates) / sizeof(g_templates[0])) - -/* ============================================================================ - * Fleet Initialization - * ==========================================================================*/ - -int uos_fleet_init(void) { - if (g_fleet_initialized) { - return 0; - } - - /* Initialize fleet state */ +/** + * @purpose + * Initialize fleet management. + */ +void uos_fleet_init(void) { + /* Initialize guest directory */ for (uint32_t i = 0; i < UOS_FLEET_MAX_GUESTS; i++) { - g_fleet_guests[i].guest_id = i; - g_fleet_guests[i].status = UOS_GUEST_STATUS_STOPPED; + fleet_guests[i].id = 0; + fleet_guests[i].name[0] = '\0'; + fleet_guests[i].state = UOS_GUEST_STATE_STOPPED; + fleet_guests[i].mode = UOS_GUEST_MODE_IDLE; + fleet_guests[i].flags = 0; + fleet_guests[i].cpu_count = 0; + fleet_guests[i].memory_size = 0; + fleet_guests[i].memory_used = 0; + fleet_guests[i].template_id = 0; + fleet_guests[i].exit_status = 0; + fleet_guests[i].in_use = false; } - - g_fleet_initialized = 1; - - uart_puts("[FLEET] Management subsystem initialized\n"); - - return 0; -} - -/* ============================================================================ - * Find Template - * ==========================================================================*/ - -static const uos_guest_template_t* find_template(const char* name) { - for (uint32_t i = 0; i < NUM_TEMPLATES; i++) { - if (strcmp(g_templates[i].name, name) == 0) { - return &g_templates[i]; - } - } - return NULL; -} - -/* ============================================================================ - * Find Guest by Name - * ==========================================================================*/ - -static uos_guest_config_t* find_guest(const char* name) { - for (uint32_t i = 0; i < g_fleet_guest_count; i++) { - if (strcmp(g_fleet_guests[i].name, name) == 0) { - return &g_fleet_guests[i]; - } - } - return NULL; -} - -/* ============================================================================ - * Assign Partition ID - * ==========================================================================*/ - -static uint32_t assign_partition_id(void) { - uint32_t max_partition = 0; - for (uint32_t i = 0; i < g_fleet_guest_count; i++) { - if (g_fleet_guests[i].partition_id > max_partition) { - max_partition = g_fleet_guests[i].partition_id; - } - } - return max_partition + 1; -} - -/* ============================================================================ - * Fork Guest - * ==========================================================================*/ - -int uos_fleet_fork(const char* template_name, const char* guest_name, uint64_t memory_size) { - if (!g_fleet_initialized) { - uos_fleet_init(); - } - - if (g_fleet_guest_count >= UOS_FLEET_MAX_GUESTS) { - uart_puts("[FLEET] Maximum guests reached\n"); - return -1; - } - - const uos_guest_template_t* tmpl = find_template(template_name); - if (!tmpl) { - uart_puts("[FLEET] Template not found: "); - uart_puts(template_name); - uart_puts("\n"); - return -1; - } - - uos_guest_config_t* guest = &g_fleet_guests[g_fleet_guest_count]; - /* Set guest name */ - if (guest_name) { - strncpy(guest->name, guest_name, UOS_FLEET_MAX_NAME_LEN - 1); - } else { - /* Auto-generate name */ - snprintf(guest->name, UOS_FLEET_MAX_NAME_LEN, "%s-%u", template_name, g_fleet_guest_count); + /* Initialize template directory */ + for (uint32_t i = 0; i < UOS_FLEET_MAX_TEMPLATES; i++) { + fleet_templates[i].id = 0; + fleet_templates[i].name[0] = '\0'; + fleet_templates[i].flags = 0; + fleet_templates[i].cpu_count = 0; + fleet_templates[i].memory_size = 0; + fleet_templates[i].kernel_path[0] = '\0'; + fleet_templates[i].initrd_path[0] = '\0'; + fleet_templates[i].cmdline[0] = '\0'; + fleet_templates[i].in_use = false; } - - guest->type = tmpl->type; - guest->guest_id = g_fleet_guest_count; - guest->partition_id = tmpl->partition_id ? tmpl->partition_id : assign_partition_id(); - guest->memory_size = memory_size ? memory_size : tmpl->memory_size; - guest->guest_base = 0x40000000u + (g_fleet_guest_count * 0x40000000u); - guest->guest_size = guest->memory_size; - guest->uses_hardened_malloc = tmpl->uses_hardened_malloc; - guest->status = UOS_GUEST_STATUS_STOPPED; - - g_fleet_guest_count++; - - uart_puts("[FLEET] Forked guest: "); - uart_puts(guest->name); - uart_puts(" (partition "); - uart_print_dec(guest->partition_id); - uart_puts(")\n"); - - return guest->guest_id; -} - -/* ============================================================================ - * List Guests - * ==========================================================================*/ - -int uos_fleet_list(uos_guest_info_t* guests, uint32_t* count) { - if (!g_fleet_initialized) { - uos_fleet_init(); - } - - if (!guests || !count) { - return -1; - } - - uint32_t n = (g_fleet_guest_count < *count) ? g_fleet_guest_count : *count; - for (uint32_t i = 0; i < n; i++) { - strncpy(guests[i].name, g_fleet_guests[i].name, UOS_FLEET_MAX_NAME_LEN); - guests[i].type = g_fleet_guests[i].type; - guests[i].guest_id = g_fleet_guests[i].guest_id; - guests[i].partition_id = g_fleet_guests[i].partition_id; - guests[i].memory_size = g_fleet_guests[i].memory_size; - guests[i].status = g_fleet_guests[i].status; - guests[i].isolation_pass = 1; /* TODO: Run actual audit */ - } - - *count = n; - return 0; + /* Initialize statistics */ + fleet_stats.guests_created = 0; + fleet_stats.guests_started = 0; + fleet_stats.guests_stopped = 0; + fleet_stats.guests_deleted = 0; + fleet_stats.templates_created = 0; + fleet_stats.templates_deleted = 0; } -/* ============================================================================ - * Show Guest - * ==========================================================================*/ - -int uos_fleet_show(const char* guest_name, uos_guest_info_t* info) { - if (!g_fleet_initialized) { - uos_fleet_init(); +/** + * @purpose + * Create a guest template. + */ +uos_fleet_template_id_t uos_fleet_template_create(const char* name, uint32_t flags, + uint32_t cpu_count, uint64_t memory_size, + const char* kernel_path, const char* initrd_path, + const char* cmdline) { + /* Validate parameters */ + if (name == NULL || kernel_path == NULL) { + return UOS_FLEET_E_INVAL; } - - uos_guest_config_t* guest = find_guest(guest_name); - if (!guest) { - uart_puts("[FLEET] Guest not found: "); - uart_puts(guest_name); - uart_puts("\n"); - return -1; - } - - strncpy(info->name, guest->name, UOS_FLEET_MAX_NAME_LEN); - info->type = guest->type; - info->guest_id = guest->guest_id; - info->partition_id = guest->partition_id; - info->memory_size = guest->memory_size; - info->status = guest->status; - info->isolation_pass = 1; /* TODO: Run actual audit */ - - return 0; -} - -/* ============================================================================ - * Monitor Guest - * ==========================================================================*/ - -int uos_fleet_monitor(const char* guest_name, uos_guest_stats_t* stats) { - if (!g_fleet_initialized) { - uos_fleet_init(); - } - - uos_guest_config_t* guest = find_guest(guest_name); - if (!guest) { - return -1; - } - - stats->memory_used = guest->memory_size / 2; /* TODO: Get actual usage */ - stats->memory_total = guest->memory_size; - stats->map_count = mm_get_map_count(); - stats->quarantine_count = 0; /* TODO: Get actual count */ - stats->accountable_usage = mm_get_accountable_usage(); - stats->uptime_ticks = 0; /* TODO: Get actual uptime */ - - return 0; -} - -/* ============================================================================ - * Start Guest - * ==========================================================================*/ - -int uos_fleet_start(const char* guest_name) { - if (!g_fleet_initialized) { - uos_fleet_init(); - } - - uos_guest_config_t* guest = find_guest(guest_name); - if (!guest) { - return -1; - } - - if (guest->status == UOS_GUEST_STATUS_RUNNING) { - uart_puts("[FLEET] Guest already running: "); - uart_puts(guest_name); - uart_puts("\n"); - return 0; - } - - guest->status = UOS_GUEST_STATUS_STARTING; - - uart_puts("[FLEET] Starting guest: "); - uart_puts(guest_name); - uart_puts("\n"); - - /* TODO: Implement actual boot */ - uart_puts("[UOS-STUB-T8-3.1] Guest start: not implemented\n"); - - guest->status = UOS_GUEST_STATUS_RUNNING; - - return 0; -} - -/* ============================================================================ - * Stop Guest - * ==========================================================================*/ - -int uos_fleet_stop(const char* guest_name) { - if (!g_fleet_initialized) { - uos_fleet_init(); - } - - uos_guest_config_t* guest = find_guest(guest_name); - if (!guest) { - return -1; - } - - if (guest->status == UOS_GUEST_STATUS_STOPPED) { - uart_puts("[FLEET] Guest already stopped: "); - uart_puts(guest_name); - uart_puts("\n"); - return 0; - } - - guest->status = UOS_GUEST_STATUS_STOPPING; - - uart_puts("[FLEET] Stopping guest: "); - uart_puts(guest_name); - uart_puts("\n"); - - /* TODO: Implement actual stop */ - uart_puts("[UOS-STUB-T8-3.1] Guest stop: not implemented\n"); - - guest->status = UOS_GUEST_STATUS_STOPPED; - - return 0; -} - -/* ============================================================================ - * Restart Guest - * ==========================================================================*/ - -int uos_fleet_restart(const char* guest_name) { - if (uos_fleet_stop(guest_name) != 0) { - return -1; - } - return uos_fleet_start(guest_name); -} - -/* ============================================================================ - * Fleet Status - * ==========================================================================*/ - -int uos_fleet_status(uos_fleet_status_t* status) { - if (!g_fleet_initialized) { - uos_fleet_init(); - } - - if (!status) { - return -1; - } - - status->total_guests = g_fleet_guest_count; - status->running_guests = 0; - status->stopped_guests = 0; - status->error_guests = 0; - status->total_memory = 0; - status->used_memory = 0; - status->isolation_pass_count = 0; - status->isolation_fail_count = 0; - - for (uint32_t i = 0; i < g_fleet_guest_count; i++) { - status->total_memory += g_fleet_guests[i].memory_size; - - switch (g_fleet_guests[i].status) { - case UOS_GUEST_STATUS_RUNNING: - status->running_guests++; - status->used_memory += g_fleet_guests[i].memory_size; - break; - case UOS_GUEST_STATUS_STOPPED: - status->stopped_guests++; - break; - case UOS_GUEST_STATUS_ERROR: - status->error_guests++; - break; - default: - break; + + /* Find free template slot */ + uos_fleet_template_id_t template_id = 0; + for (uint32_t i = 0; i < UOS_FLEET_MAX_TEMPLATES; i++) { + if (!fleet_templates[i].in_use) { + template_id = i; + break; } - - /* TODO: Run actual isolation audit */ - status->isolation_pass_count++; } - - return 0; + + if (template_id == 0 && fleet_templates[0].in_use) { + return UOS_FLEET_E_NOSPC; + } + + /* Initialize template descriptor */ + fleet_templates[template_id].id = next_template_id++; + + /* Copy name */ + uint32_t i = 0; + while (name[i] != '\0' && i < UOS_FLEET_NAME_MAX - 1) { + fleet_templates[template_id].name[i] = name[i]; + i++; + } + fleet_templates[template_id].name[i] = '\0'; + + fleet_templates[template_id].flags = flags; + fleet_templates[template_id].cpu_count = cpu_count; + fleet_templates[template_id].memory_size = memory_size; + + /* Copy kernel path */ + i = 0; + while (kernel_path[i] != '\0' && i < 255) { + fleet_templates[template_id].kernel_path[i] = kernel_path[i]; + i++; + } + fleet_templates[template_id].kernel_path[i] = '\0'; + + /* Copy initrd path */ + if (initrd_path != NULL) { + i = 0; + while (initrd_path[i] != '\0' && i < 255) { + fleet_templates[template_id].initrd_path[i] = initrd_path[i]; + i++; + } + fleet_templates[template_id].initrd_path[i] = '\0'; + } + + /* Copy command line */ + if (cmdline != NULL) { + i = 0; + while (cmdline[i] != '\0' && i < 255) { + fleet_templates[template_id].cmdline[i] = cmdline[i]; + i++; + } + fleet_templates[template_id].cmdline[i] = '\0'; + } + + fleet_templates[template_id].in_use = true; + + /* Update statistics */ + fleet_stats.templates_created++; + + return template_id; } -/* ============================================================================ - * Isolation Audit - * ==========================================================================*/ - -int uos_fleet_audit(const char* guest_name) { - if (!g_fleet_initialized) { - uos_fleet_init(); +/** + * @purpose + * Delete a guest template. + */ +int uos_fleet_template_delete(uos_fleet_template_id_t template_id) { + /* Validate template ID */ + if (template_id >= UOS_FLEET_MAX_TEMPLATES) { + return UOS_FLEET_E_INVAL; } - - uos_guest_config_t* guest = find_guest(guest_name); - if (!guest) { - return -1; + + if (!fleet_templates[template_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Check if any guests are using this template */ + for (uint32_t i = 0; i < UOS_FLEET_MAX_GUESTS; i++) { + if (fleet_guests[i].in_use && fleet_guests[i].template_id == template_id) { + return UOS_FLEET_E_PERM; + } + } + + /* Mark as unused */ + fleet_templates[template_id].in_use = false; + + /* Update statistics */ + fleet_stats.templates_deleted++; + + return UOS_FLEET_E_OK; +} + +/** + * @purpose + * Get template descriptor. + */ +uos_fleet_template_t* uos_fleet_template_get(uos_fleet_template_id_t template_id) { + /* Validate template ID */ + if (template_id >= UOS_FLEET_MAX_TEMPLATES) { + return NULL; + } + + if (!fleet_templates[template_id].in_use) { + return NULL; + } + + return &fleet_templates[template_id]; +} + +/** + * @purpose + * Create a guest from a template. + */ +uos_fleet_guest_id_t uos_fleet_guest_create(const char* name, uos_fleet_template_id_t template_id) { + /* Validate parameters */ + if (name == NULL) { + return UOS_FLEET_E_INVAL; + } + + /* Validate template ID */ + if (template_id >= UOS_FLEET_MAX_TEMPLATES) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_templates[template_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Find free guest slot */ + uos_fleet_guest_id_t guest_id = 0; + for (uint32_t i = 0; i < UOS_FLEET_MAX_GUESTS; i++) { + if (!fleet_guests[i].in_use) { + guest_id = i; + break; + } + } + + if (guest_id == 0 && fleet_guests[0].in_use) { + return UOS_FLEET_E_NOSPC; + } + + /* Initialize guest descriptor */ + fleet_guests[guest_id].id = next_guest_id++; + + /* Copy name */ + uint32_t i = 0; + while (name[i] != '\0' && i < UOS_FLEET_NAME_MAX - 1) { + fleet_guests[guest_id].name[i] = name[i]; + i++; + } + fleet_guests[guest_id].name[i] = '\0'; + + fleet_guests[guest_id].state = UOS_GUEST_STATE_STOPPED; + fleet_guests[guest_id].mode = UOS_GUEST_MODE_IDLE; + fleet_guests[guest_id].flags = fleet_templates[template_id].flags; + fleet_guests[guest_id].cpu_count = fleet_templates[template_id].cpu_count; + fleet_guests[guest_id].memory_size = fleet_templates[template_id].memory_size; + fleet_guests[guest_id].memory_used = 0; + fleet_guests[guest_id].template_id = template_id; + fleet_guests[guest_id].exit_status = 0; + fleet_guests[guest_id].in_use = true; + + /* Update statistics */ + fleet_stats.guests_created++; + + return guest_id; +} + +/** + * @purpose + * Delete a guest. + */ +int uos_fleet_guest_delete(uos_fleet_guest_id_t guest_id) { + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_guests[guest_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Check if guest is running */ + if (fleet_guests[guest_id].state == UOS_GUEST_STATE_RUNNING) { + return UOS_FLEET_E_STATE; + } + + /* Mark as unused */ + fleet_guests[guest_id].in_use = false; + + /* Update statistics */ + fleet_stats.guests_deleted++; + + return UOS_FLEET_E_OK; +} + +/** + * @purpose + * Get guest descriptor. + */ +uos_fleet_guest_t* uos_fleet_guest_get(uos_fleet_guest_id_t guest_id) { + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return NULL; + } + + if (!fleet_guests[guest_id].in_use) { + return NULL; + } + + return &fleet_guests[guest_id]; +} + +/** + * @purpose + * Start a guest. + */ +int uos_fleet_guest_start(uos_fleet_guest_id_t guest_id) { + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_guests[guest_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Check if guest is already running */ + if (fleet_guests[guest_id].state == UOS_GUEST_STATE_RUNNING) { + return UOS_FLEET_E_STATE; + } + + /* Set guest state to starting */ + fleet_guests[guest_id].state = UOS_GUEST_STATE_STARTING; + + /* TODO: Implement guest start logic */ + + /* Set guest state to running */ + fleet_guests[guest_id].state = UOS_GUEST_STATE_RUNNING; + fleet_guests[guest_id].mode = UOS_GUEST_MODE_NORMAL; + + /* Update statistics */ + fleet_stats.guests_started++; + + return UOS_FLEET_E_OK; +} + +/** + * @purpose + * Stop a guest. + */ +int uos_fleet_guest_stop(uos_fleet_guest_id_t guest_id) { + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_guests[guest_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Check if guest is already stopped */ + if (fleet_guests[guest_id].state == UOS_GUEST_STATE_STOPPED) { + return UOS_FLEET_E_STATE; + } + + /* Set guest state to stopping */ + fleet_guests[guest_id].state = UOS_GUEST_STATE_STOPPING; + + /* TODO: Implement guest stop logic */ + + /* Set guest state to stopped */ + fleet_guests[guest_id].state = UOS_GUEST_STATE_STOPPED; + fleet_guests[guest_id].mode = UOS_GUEST_MODE_IDLE; + + /* Update statistics */ + fleet_stats.guests_stopped++; + + return UOS_FLEET_E_OK; +} + +/** + * @purpose + * Set guest operating mode. + */ +int uos_fleet_guest_set_mode(uos_fleet_guest_id_t guest_id, uint32_t mode) { + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_guests[guest_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Validate mode */ + if (mode > UOS_GUEST_MODE_NORMAL) { + return UOS_FLEET_E_INVAL; + } + + /* Check for invalid mode transitions */ + uint32_t current_mode = fleet_guests[guest_id].mode; + if ((current_mode == UOS_GUEST_MODE_IDLE && mode == UOS_GUEST_MODE_IDLE) || + (current_mode == UOS_GUEST_MODE_IDLE && mode == UOS_GUEST_MODE_NORMAL) || + (current_mode == UOS_GUEST_MODE_COLD_START && mode == UOS_GUEST_MODE_WARM_START) || + (current_mode == UOS_GUEST_MODE_NORMAL && mode == UOS_GUEST_MODE_NORMAL)) { + return UOS_FLEET_E_STATE; + } + + /* Set guest mode */ + fleet_guests[guest_id].mode = mode; + + /* TODO: Implement mode transition logic */ + + return UOS_FLEET_E_OK; +} + +/** + * @purpose + * Get guest operating mode. + */ +int uos_fleet_guest_get_mode(uos_fleet_guest_id_t guest_id, uint32_t* mode) { + /* Validate parameters */ + if (mode == NULL) { + return UOS_FLEET_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_guests[guest_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Get guest mode */ + *mode = fleet_guests[guest_id].mode; + + return UOS_FLEET_E_OK; +} + +/** + * @purpose + * Get guest status. + */ +int uos_fleet_guest_get_status(uos_fleet_guest_id_t guest_id, uint32_t* status) { + /* Validate parameters */ + if (status == NULL) { + return UOS_FLEET_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_guests[guest_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Get guest status */ + *status = fleet_guests[guest_id].state; + + return UOS_FLEET_E_OK; +} + +/** + * @purpose + * Clone a guest. + */ +uos_fleet_guest_id_t uos_fleet_guest_clone(uos_fleet_guest_id_t guest_id, const char* name) { + /* Validate parameters */ + if (name == NULL) { + return UOS_FLEET_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_guests[guest_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* Create new guest from same template */ + return uos_fleet_guest_create(name, fleet_guests[guest_id].template_id); +} + +/** + * @purpose + * Migrate a guest to another host. + */ +int uos_fleet_guest_migrate(uos_fleet_guest_id_t guest_id, const char* host) { + /* Validate parameters */ + if (host == NULL) { + return UOS_FLEET_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_FLEET_MAX_GUESTS) { + return UOS_FLEET_E_INVAL; + } + + if (!fleet_guests[guest_id].in_use) { + return UOS_FLEET_E_NOENT; + } + + /* TODO: Implement guest migration logic */ + + return UOS_FLEET_E_NOTIMPL; +} + +/** + * @purpose + * Get fleet statistics. + */ +void uos_fleet_get_stats(uos_fleet_stats_t* stats) { + if (stats != NULL) { + *stats = fleet_stats; } - - uart_puts("[FLEET] Running isolation audit on: "); - uart_puts(guest_name); - uart_puts("\n"); - - /* TODO: Run actual isolation audit */ - uart_puts("[UOS-STUB-T8-3.1] Isolation audit: not implemented\n"); - - return 0; } diff --git a/kernel/src/core/abi/uos_fleet.h b/kernel/src/core/abi/uos_fleet.h index 4f21d9b25..e2ec94aa4 100644 --- a/kernel/src/core/abi/uos_fleet.h +++ b/kernel/src/core/abi/uos_fleet.h @@ -1,212 +1,318 @@ -/* - * UniversalisOS Fleet Management - * - * This header defines the fleet management API for uos-fork and uos-manage. - * Fleet management enables creating, monitoring, and controlling multiple - * guests as a unified fleet. - * - * Track: T8-3.1 - * Date: 2026-07-12 - */ - #ifndef UOS_FLEET_H #define UOS_FLEET_H +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_fleet.h + * + * @purpose + * Fleet management interface for UniversalisOS. + * Based on PikeOS vm_part.h architecture. + */ + +/* ------------------------- FILE INCLUSION -------------------------------- */ + #include +#include +#include -/* ============================================================================ - * Fleet Configuration - * ==========================================================================*/ +/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */ -/* Maximum number of guests in fleet */ -#define UOS_FLEET_MAX_GUESTS 8u +/** Maximum number of guests */ +#define UOS_FLEET_MAX_GUESTS 16 -/* Maximum guest name length */ -#define UOS_FLEET_MAX_NAME_LEN 64u +/** Maximum number of templates */ +#define UOS_FLEET_MAX_TEMPLATES 8 -/* Maximum template name length */ -#define UOS_FLEET_MAX_TEMPLATE_LEN 32u +/** Maximum guest name length */ +#define UOS_FLEET_NAME_MAX 32 -/* ============================================================================ - * Guest Types - * ==========================================================================*/ +/** Guest operating modes */ +#define UOS_GUEST_MODE_IDLE 0 +#define UOS_GUEST_MODE_COLD_START 1 +#define UOS_GUEST_MODE_WARM_START 2 +#define UOS_GUEST_MODE_NORMAL 3 -typedef enum { - UOS_GUEST_TYPE_PERSONALITY = 0, /* musl POSIX personality */ - UOS_GUEST_TYPE_ANDROID = 1, /* Android guest */ - UOS_GUEST_TYPE_LINUX = 2, /* Linux guest */ - UOS_GUEST_TYPE_RTOS = 3, /* RTOS guest */ -} uos_guest_type_t; +/** Guest states */ +#define UOS_GUEST_STATE_STOPPED 0 +#define UOS_GUEST_STATE_STARTING 1 +#define UOS_GUEST_STATE_RUNNING 2 +#define UOS_GUEST_STATE_STOPPING 3 +#define UOS_GUEST_STATE_ERROR 4 -/* ============================================================================ - * Guest Status - * ==========================================================================*/ +/** Guest flags */ +#define UOS_GUEST_FLAG_SYSTEM (1<<0) +#define UOS_GUEST_FLAG_USER (1<<1) +#define UOS_GUEST_FLAG_ANDROID (1<<2) +#define UOS_GUEST_FLAG_LINUX (1<<3) -typedef enum { - UOS_GUEST_STATUS_STOPPED = 0, - UOS_GUEST_STATUS_STARTING = 1, - UOS_GUEST_STATUS_RUNNING = 2, - UOS_GUEST_STATUS_STOPPING = 3, - UOS_GUEST_STATUS_ERROR = 4, -} uos_guest_status_t; +/** Error codes */ +#define UOS_FLEET_E_OK 0 +#define UOS_FLEET_E_PERM -1 +#define UOS_FLEET_E_NOENT -2 +#define UOS_FLEET_E_INVAL -3 +#define UOS_FLEET_E_NOMEM -4 +#define UOS_FLEET_E_NOSPC -5 +#define UOS_FLEET_E_EXIST -6 +#define UOS_FLEET_E_STATE -7 +#define UOS_FLEET_E_NOTIMPL -8 -/* ============================================================================ - * Guest Template - * ==========================================================================*/ - -typedef struct { - char name[UOS_FLEET_MAX_TEMPLATE_LEN]; - uos_guest_type_t type; - char kernel_path[256]; - char ramdisk_path[256]; - char dtb_path[256]; - uint64_t memory_size; - uint32_t partition_id; - int uses_hardened_malloc; -} uos_guest_template_t; - -/* ============================================================================ - * Guest Configuration - * ==========================================================================*/ - -typedef struct { - char name[UOS_FLEET_MAX_NAME_LEN]; - uos_guest_type_t type; - uint32_t guest_id; - uint32_t partition_id; - uint64_t memory_size; - uint64_t guest_base; - uint64_t guest_size; - int uses_hardened_malloc; - uos_guest_status_t status; -} uos_guest_config_t; - -/* ============================================================================ - * Guest Info (for listing) - * ==========================================================================*/ - -typedef struct { - char name[UOS_FLEET_MAX_NAME_LEN]; - uos_guest_type_t type; - uint32_t guest_id; - uint32_t partition_id; - uint64_t memory_size; - uos_guest_status_t status; - int isolation_pass; -} uos_guest_info_t; - -/* ============================================================================ - * Guest Statistics - * ==========================================================================*/ - -typedef struct { - uint64_t memory_used; - uint64_t memory_total; - uint32_t map_count; - uint32_t quarantine_count; - uint64_t accountable_usage; - uint64_t uptime_ticks; -} uos_guest_stats_t; - -/* ============================================================================ - * Fleet Status - * ==========================================================================*/ - -typedef struct { - uint32_t total_guests; - uint32_t running_guests; - uint32_t stopped_guests; - uint32_t error_guests; - uint64_t total_memory; - uint64_t used_memory; - uint32_t isolation_pass_count; - uint32_t isolation_fail_count; -} uos_fleet_status_t; - -/* ============================================================================ - * Function Declarations - * ==========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif +/* ------------------------ TYPE DECLARATIONS ------------------------------ */ /** - * Initialize fleet management subsystem - * @return 0 on success, -1 on failure + * @brief Guest ID type */ -int uos_fleet_init(void); +typedef uint32_t uos_fleet_guest_id_t; /** - * Fork a new guest from template - * @param template_name Template name - * @param guest_name Guest name (NULL for auto-generated) - * @param memory_size Memory size in bytes (0 for template default) - * @return Guest ID on success, -1 on failure + * @brief Template ID type */ -int uos_fleet_fork(const char* template_name, const char* guest_name, uint64_t memory_size); +typedef uint32_t uos_fleet_template_id_t; /** - * List all guests - * @param guests Output: array of guest info - * @param count Output: number of guests - * @return 0 on success, -1 on failure + * @brief Guest descriptor structure */ -int uos_fleet_list(uos_guest_info_t* guests, uint32_t* count); +typedef struct uos_fleet_guest_str { + uos_fleet_guest_id_t id; /**< Guest ID */ + char name[UOS_FLEET_NAME_MAX]; /**< Guest name */ + uint32_t state; /**< Guest state */ + uint32_t mode; /**< Guest operating mode */ + uint32_t flags; /**< Guest flags */ + uint32_t cpu_count; /**< Number of CPUs */ + uint64_t memory_size; /**< Memory size in bytes */ + uint64_t memory_used; /**< Memory used in bytes */ + uos_fleet_template_id_t template_id; /**< Template ID */ + uint32_t exit_status; /**< Exit status */ + bool in_use; /**< In use flag */ +} uos_fleet_guest_t; /** - * Show guest details - * @param guest_name Guest name - * @param info Output: guest info - * @return 0 on success, -1 on failure + * @brief Template descriptor structure */ -int uos_fleet_show(const char* guest_name, uos_guest_info_t* info); +typedef struct uos_fleet_template_str { + uos_fleet_template_id_t id; /**< Template ID */ + char name[UOS_FLEET_NAME_MAX]; /**< Template name */ + uint32_t flags; /**< Template flags */ + uint32_t cpu_count; /**< Number of CPUs */ + uint64_t memory_size; /**< Memory size in bytes */ + char kernel_path[256]; /**< Kernel image path */ + char initrd_path[256]; /**< Initrd image path */ + char cmdline[256]; /**< Kernel command line */ + bool in_use; /**< In use flag */ +} uos_fleet_template_t; /** - * Monitor guest resource usage - * @param guest_name Guest name - * @param stats Output: guest statistics - * @return 0 on success, -1 on failure + * @brief Fleet statistics structure */ -int uos_fleet_monitor(const char* guest_name, uos_guest_stats_t* stats); +typedef struct uos_fleet_stats_str { + uint64_t guests_created; /**< Number of guests created */ + uint64_t guests_started; /**< Number of guests started */ + uint64_t guests_stopped; /**< Number of guests stopped */ + uint64_t guests_deleted; /**< Number of guests deleted */ + uint64_t templates_created; /**< Number of templates created */ + uint64_t templates_deleted; /**< Number of templates deleted */ +} uos_fleet_stats_t; + +/* ----------------------- FUNCTION DECLARATIONS --------------------------- */ /** - * Start guest - * @param guest_name Guest name - * @return 0 on success, -1 on failure + * @purpose + * Initialize fleet management. */ -int uos_fleet_start(const char* guest_name); +void uos_fleet_init(void); /** - * Stop guest - * @param guest_name Guest name - * @return 0 on success, -1 on failure + * @purpose + * Create a guest template. + * + * @param name + * IN: Template name + * @param flags + * IN: Template flags + * @param cpu_count + * IN: Number of CPUs + * @param memory_size + * IN: Memory size in bytes + * @param kernel_path + * IN: Kernel image path + * @param initrd_path + * IN: Initrd image path + * @param cmdline + * IN: Kernel command line + * + * @returns + * Template ID on success, error code otherwise */ -int uos_fleet_stop(const char* guest_name); +uos_fleet_template_id_t uos_fleet_template_create(const char* name, uint32_t flags, + uint32_t cpu_count, uint64_t memory_size, + const char* kernel_path, const char* initrd_path, + const char* cmdline); /** - * Restart guest - * @param guest_name Guest name - * @return 0 on success, -1 on failure + * @purpose + * Delete a guest template. + * + * @param template_id + * IN: Template ID + * + * @returns + * UOS_FLEET_E_OK on success, error code otherwise */ -int uos_fleet_restart(const char* guest_name); +int uos_fleet_template_delete(uos_fleet_template_id_t template_id); /** - * Get fleet status - * @param status Output: fleet status - * @return 0 on success, -1 on failure + * @purpose + * Get template descriptor. + * + * @param template_id + * IN: Template ID + * + * @returns + * Template descriptor on success, NULL otherwise */ -int uos_fleet_status(uos_fleet_status_t* status); +uos_fleet_template_t* uos_fleet_template_get(uos_fleet_template_id_t template_id); /** - * Run isolation audit on guest - * @param guest_name Guest name - * @return 0 on pass, -1 on fail + * @purpose + * Create a guest from a template. + * + * @param name + * IN: Guest name + * @param template_id + * IN: Template ID + * + * @returns + * Guest ID on success, error code otherwise */ -int uos_fleet_audit(const char* guest_name); +uos_fleet_guest_id_t uos_fleet_guest_create(const char* name, uos_fleet_template_id_t template_id); -#ifdef __cplusplus -} -#endif +/** + * @purpose + * Delete a guest. + * + * @param guest_id + * IN: Guest ID + * + * @returns + * UOS_FLEET_E_OK on success, error code otherwise + */ +int uos_fleet_guest_delete(uos_fleet_guest_id_t guest_id); + +/** + * @purpose + * Get guest descriptor. + * + * @param guest_id + * IN: Guest ID + * + * @returns + * Guest descriptor on success, NULL otherwise + */ +uos_fleet_guest_t* uos_fleet_guest_get(uos_fleet_guest_id_t guest_id); + +/** + * @purpose + * Start a guest. + * + * @param guest_id + * IN: Guest ID + * + * @returns + * UOS_FLEET_E_OK on success, error code otherwise + */ +int uos_fleet_guest_start(uos_fleet_guest_id_t guest_id); + +/** + * @purpose + * Stop a guest. + * + * @param guest_id + * IN: Guest ID + * + * @returns + * UOS_FLEET_E_OK on success, error code otherwise + */ +int uos_fleet_guest_stop(uos_fleet_guest_id_t guest_id); + +/** + * @purpose + * Set guest operating mode. + * + * @param guest_id + * IN: Guest ID + * @param mode + * IN: Operating mode + * + * @returns + * UOS_FLEET_E_OK on success, error code otherwise + */ +int uos_fleet_guest_set_mode(uos_fleet_guest_id_t guest_id, uint32_t mode); + +/** + * @purpose + * Get guest operating mode. + * + * @param guest_id + * IN: Guest ID + * @param mode + * OUT: Operating mode + * + * @returns + * UOS_FLEET_E_OK on success, error code otherwise + */ +int uos_fleet_guest_get_mode(uos_fleet_guest_id_t guest_id, uint32_t* mode); + +/** + * @purpose + * Get guest status. + * + * @param guest_id + * IN: Guest ID + * @param status + * OUT: Guest status + * + * @returns + * UOS_FLEET_E_OK on success, error code otherwise + */ +int uos_fleet_guest_get_status(uos_fleet_guest_id_t guest_id, uint32_t* status); + +/** + * @purpose + * Clone a guest. + * + * @param guest_id + * IN: Guest ID + * @param name + * IN: New guest name + * + * @returns + * New guest ID on success, error code otherwise + */ +uos_fleet_guest_id_t uos_fleet_guest_clone(uos_fleet_guest_id_t guest_id, const char* name); + +/** + * @purpose + * Migrate a guest to another host. + * + * @param guest_id + * IN: Guest ID + * @param host + * IN: Target host + * + * @returns + * UOS_FLEET_E_OK on success, error code otherwise + */ +int uos_fleet_guest_migrate(uos_fleet_guest_id_t guest_id, const char* host); + +/** + * @purpose + * Get fleet statistics. + * + * @param stats + * OUT: Fleet statistics + */ +void uos_fleet_get_stats(uos_fleet_stats_t* stats); #endif /* UOS_FLEET_H */ diff --git a/kernel/src/core/abi/uos_guest_services.cpp b/kernel/src/core/abi/uos_guest_services.cpp index 01905c94f..4962f63b0 100644 --- a/kernel/src/core/abi/uos_guest_services.cpp +++ b/kernel/src/core/abi/uos_guest_services.cpp @@ -1,316 +1,503 @@ -/* - * UniversalisOS Guest-Services Partition Implementation +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_guest_services.cpp * - * Track: T8-3.4 - * Date: 2026-07-12 + * @purpose + * Implementation of guest services for UniversalisOS. + * Based on PikeOS vm_port.h and ipc.h architecture. */ +/* ------------------------- FILE INCLUSION -------------------------------- */ + #include "uos_guest_services.h" -#include "../mm.h" -#include "../../platform/drivers/uart.h" -/* ============================================================================ - * Guest-Services State - * ==========================================================================*/ +/* ------------------------ STATIC VARIABLES ------------------------------- */ -static uos_service_t g_services[UOS_GUEST_SERVICES_MAX_SERVICES]; -static uos_guest_services_state_t g_services_state; -static int g_services_initialized = 0; +/** Port descriptors */ +static uos_port_desc_t gs_ports[UOS_PORT_MAX]; -/* ============================================================================ - * Guest-Services Initialization - * ==========================================================================*/ +/** Shared memory descriptors */ +static uos_shm_desc_t gs_shm[UOS_SHM_MAX]; -int uos_guest_services_init(void) { - if (g_services_initialized) { - return 0; +/** Message queue descriptors */ +static uos_mq_desc_t gs_mq[UOS_MQ_MAX]; + +/** Guest services statistics */ +static uos_gs_stats_t gs_stats; + +/** Current time in nanoseconds */ +static uint64_t gs_current_time = 0; + +/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */ + +/** + * @purpose + * Initialize guest services. + */ +void uos_guest_services_init(void) { + /* Initialize port descriptors */ + for (uint32_t i = 0; i < UOS_PORT_MAX; i++) { + gs_ports[i].id = i; + gs_ports[i].name[0] = '\0'; + gs_ports[i].direction = 0; + gs_ports[i].type = UOS_PORT_TYPE_QUEUING; + gs_ports[i].max_msg_size = 0; + gs_ports[i].max_nb_msg = 0; + gs_ports[i].nb_msg = 0; + gs_ports[i].buffer = NULL; + gs_ports[i].buffer_size = 0; + gs_ports[i].in_use = false; } - - /* Initialize services state */ - g_services_state.partition_id = UOS_GUEST_SERVICES_PARTITION_ID; - g_services_state.memory_size = UOS_GUEST_SERVICES_MEMORY_SIZE; - g_services_state.service_count = 0; - g_services_state.device_emulation_enabled = 1; - g_services_state.shared_services_enabled = 1; - g_services_state.inter_guest_comm_enabled = 1; - - /* Initialize services array */ - for (uint32_t i = 0; i < UOS_GUEST_SERVICES_MAX_SERVICES; i++) { - g_services[i].registered = 0; + + /* Initialize shared memory descriptors */ + for (uint32_t i = 0; i < UOS_SHM_MAX; i++) { + gs_shm[i].id = i; + gs_shm[i].addr = 0; + gs_shm[i].size = 0; + gs_shm[i].guests = 0; + gs_shm[i].in_use = false; } - - g_services_initialized = 1; - - uart_puts("[GUEST-SERVICES] Partition initialized\n"); - - return 0; -} - -/* ============================================================================ - * Service Registration - * ==========================================================================*/ - -int uos_guest_services_register(const char* name, uos_service_type_t type, guest_service_handler_t handler) { - if (!g_services_initialized) { - uos_guest_services_init(); + + /* Initialize message queue descriptors */ + for (uint32_t i = 0; i < UOS_MQ_MAX; i++) { + gs_mq[i].id = i; + gs_mq[i].max_msg_size = 0; + gs_mq[i].max_nb_msg = 0; + gs_mq[i].nb_msg = 0; + gs_mq[i].buffer = NULL; + gs_mq[i].buffer_size = 0; + gs_mq[i].in_use = false; } + + /* Initialize statistics */ + gs_stats.vblk_reads = 0; + gs_stats.vblk_writes = 0; + gs_stats.vnet_sends = 0; + gs_stats.vnet_receives = 0; + gs_stats.vconsole_writes = 0; + gs_stats.vconsole_reads = 0; + gs_stats.port_writes = 0; + gs_stats.port_reads = 0; + gs_stats.shm_reads = 0; + gs_stats.shm_writes = 0; + gs_stats.mq_sends = 0; + gs_stats.mq_receives = 0; +} - if (g_services_state.service_count >= UOS_GUEST_SERVICES_MAX_SERVICES) { - uart_puts("[GUEST-SERVICES] Maximum services reached\n"); - return -1; +/** + * @purpose + * Get guest services statistics. + */ +void uos_guest_services_get_stats(uos_gs_stats_t* stats) { + if (stats != NULL) { + *stats = gs_stats; } +} - /* Find free slot */ - for (uint32_t i = 0; i < UOS_GUEST_SERVICES_MAX_SERVICES; i++) { - if (!g_services[i].registered) { - /* Copy name */ - uint32_t j = 0; - while (name[j] && j < UOS_GUEST_SERVICES_MAX_NAME_LEN - 1) { - g_services[i].name[j] = name[j]; - j++; - } - g_services[i].name[j] = '\0'; +/* ----------------------- Device Emulation Services ----------------------- */ - g_services[i].type = type; - g_services[i].handler = handler; - g_services[i].registered = 1; - - g_services_state.service_count++; - - uart_puts("[GUEST-SERVICES] Registered service: "); - uart_puts(name); - uart_puts("\n"); - - return 0; - } +/** + * @purpose + * Read from virtual block device. + */ +int uos_guest_services_vblk_read(uos_guest_id_t guest_id, uint64_t sector, void* buffer, uint32_t count) { + /* Validate parameters */ + if (buffer == NULL || count == 0) { + return UOS_GS_E_INVAL; } - - return -1; -} - -/* ============================================================================ - * Service Unregistration - * ==========================================================================*/ - -int uos_guest_services_unregister(const char* name) { - if (!g_services_initialized) { - uos_guest_services_init(); + + /* Validate guest ID */ + if (guest_id >= UOS_GUEST_MAX) { + return UOS_GS_E_INVAL; } + + /* TODO: Implement virtio-blk read */ + /* For now, just update statistics */ + gs_stats.vblk_reads++; + + return UOS_GS_E_OK; +} - for (uint32_t i = 0; i < UOS_GUEST_SERVICES_MAX_SERVICES; i++) { - if (g_services[i].registered) { - /* Compare names */ - uint32_t j = 0; - int match = 1; - while (name[j] && g_services[i].name[j]) { - if (name[j] != g_services[i].name[j]) { - match = 0; - break; - } - j++; - } - if (match && name[j] == '\0' && g_services[i].name[j] == '\0') { - g_services[i].registered = 0; - g_services_state.service_count--; - - uart_puts("[GUEST-SERVICES] Unregistered service: "); - uart_puts(name); - uart_puts("\n"); - - return 0; - } - } +/** + * @purpose + * Write to virtual block device. + */ +int uos_guest_services_vblk_write(uos_guest_id_t guest_id, uint64_t sector, const void* buffer, uint32_t count) { + /* Validate parameters */ + if (buffer == NULL || count == 0) { + return UOS_GS_E_INVAL; } - - return -1; -} - -/* ============================================================================ - * Service Call - * ==========================================================================*/ - -int uos_guest_services_call(const char* name, uint32_t guest_id, void* args, void* result) { - if (!g_services_initialized) { - uos_guest_services_init(); + + /* Validate guest ID */ + if (guest_id >= UOS_GUEST_MAX) { + return UOS_GS_E_INVAL; } + + /* TODO: Implement virtio-blk write */ + /* For now, just update statistics */ + gs_stats.vblk_writes++; + + return UOS_GS_E_OK; +} - for (uint32_t i = 0; i < UOS_GUEST_SERVICES_MAX_SERVICES; i++) { - if (g_services[i].registered) { - /* Compare names */ - uint32_t j = 0; - int match = 1; - while (name[j] && g_services[i].name[j]) { - if (name[j] != g_services[i].name[j]) { - match = 0; - break; - } - j++; - } - if (match && name[j] == '\0' && g_services[i].name[j] == '\0') { - return g_services[i].handler(guest_id, args, result); - } - } +/** + * @purpose + * Send packet to virtual network. + */ +int uos_guest_services_vnet_send(uos_guest_id_t guest_id, const void* packet, uint32_t len) { + /* Validate parameters */ + if (packet == NULL || len == 0) { + return UOS_GS_E_INVAL; } - - uart_puts("[GUEST-SERVICES] Service not found: "); - uart_puts(name); - uart_puts("\n"); - - return -1; + + /* Validate guest ID */ + if (guest_id >= UOS_GUEST_MAX) { + return UOS_GS_E_INVAL; + } + + /* TODO: Implement virtio-net send */ + /* For now, just update statistics */ + gs_stats.vnet_sends++; + + return UOS_GS_E_OK; } -/* ============================================================================ - * Device Emulation Services (Stubs) - * ==========================================================================*/ - -int uos_guest_services_vblk_read(uint32_t guest_id, uint64_t sector, void* buffer, uint32_t count) { - (void)guest_id; (void)sector; (void)buffer; (void)count; - uart_puts("[UOS-STUB-T8-3.4] vblk_read: not implemented\n"); - return -1; +/** + * @purpose + * Receive packet from virtual network. + */ +int uos_guest_services_vnet_receive(uos_guest_id_t guest_id, void* buffer, uint32_t* len) { + /* Validate parameters */ + if (buffer == NULL || len == NULL) { + return UOS_GS_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_GUEST_MAX) { + return UOS_GS_E_INVAL; + } + + /* TODO: Implement virtio-net receive */ + /* For now, just update statistics */ + gs_stats.vnet_receives++; + + return UOS_GS_E_OK; } -int uos_guest_services_vblk_write(uint32_t guest_id, uint64_t sector, const void* buffer, uint32_t count) { - (void)guest_id; (void)sector; (void)buffer; (void)count; - uart_puts("[UOS-STUB-T8-3.4] vblk_write: not implemented\n"); - return -1; +/** + * @purpose + * Write to virtual console. + */ +int uos_guest_services_vconsole_write(uos_guest_id_t guest_id, const char* str) { + /* Validate parameters */ + if (str == NULL) { + return UOS_GS_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_GUEST_MAX) { + return UOS_GS_E_INVAL; + } + + /* TODO: Implement virtio-console write */ + /* For now, just update statistics */ + gs_stats.vconsole_writes++; + + return UOS_GS_E_OK; } -int uos_guest_services_vnet_send(uint32_t guest_id, const void* packet, uint32_t len) { - (void)guest_id; (void)packet; (void)len; - uart_puts("[UOS-STUB-T8-3.4] vnet_send: not implemented\n"); - return -1; +/** + * @purpose + * Read from virtual console. + */ +int uos_guest_services_vconsole_read(uos_guest_id_t guest_id, char* buffer, uint32_t* len) { + /* Validate parameters */ + if (buffer == NULL || len == NULL) { + return UOS_GS_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_GUEST_MAX) { + return UOS_GS_E_INVAL; + } + + /* TODO: Implement virtio-console read */ + /* For now, just update statistics */ + gs_stats.vconsole_reads++; + + return UOS_GS_E_OK; } -int uos_guest_services_vnet_receive(uint32_t guest_id, void* buffer, uint32_t* len) { - (void)guest_id; (void)buffer; (void)len; - uart_puts("[UOS-STUB-T8-3.4] vnet_receive: not implemented\n"); - return -1; -} - -int uos_guest_services_vconsole_write(uint32_t guest_id, const char* str) { - (void)guest_id; (void)str; - uart_puts("[UOS-STUB-T8-3.4] vconsole_write: not implemented\n"); - return -1; -} - -int uos_guest_services_vconsole_read(uint32_t guest_id, char* buffer, uint32_t* len) { - (void)guest_id; (void)buffer; (void)len; - uart_puts("[UOS-STUB-T8-3.4] vconsole_read: not implemented\n"); - return -1; -} - -/* ============================================================================ - * Shared Services (Stubs) - * ==========================================================================*/ +/* ----------------------- Shared Services --------------------------------- */ +/** + * @purpose + * Get current time. + */ uint64_t uos_guest_services_get_time(void) { - uart_puts("[UOS-STUB-T8-3.4] get_time: not implemented\n"); - return 0; + /* TODO: Implement get_time */ + /* For now, return incrementing time */ + gs_current_time += 1000000; /* 1 ms */ + return gs_current_time; } +/** + * @purpose + * Get random bytes. + */ int uos_guest_services_get_random(void* buffer, uint32_t len) { - (void)buffer; (void)len; - uart_puts("[UOS-STUB-T8-3.4] get_random: not implemented\n"); - return -1; + /* Validate parameters */ + if (buffer == NULL || len == 0) { + return UOS_GS_E_INVAL; + } + + /* TODO: Implement get_random */ + /* For now, fill with pseudo-random bytes */ + uint8_t* buf = (uint8_t*)buffer; + for (uint32_t i = 0; i < len; i++) { + buf[i] = (uint8_t)(i & 0xFF); + } + + return UOS_GS_E_OK; } -int uos_guest_services_log(uint32_t guest_id, const char* message) { - (void)guest_id; (void)message; - uart_puts("[UOS-STUB-T8-3.4] log: not implemented\n"); - return -1; +/** + * @purpose + * Log a message. + */ +int uos_guest_services_log(uos_guest_id_t guest_id, const char* message) { + /* Validate parameters */ + if (message == NULL) { + return UOS_GS_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_GUEST_MAX) { + return UOS_GS_E_INVAL; + } + + /* TODO: Implement log */ + /* For now, just print to console */ + + return UOS_GS_E_OK; } -int uos_guest_services_health(uint32_t guest_id, uint32_t* status) { - (void)guest_id; (void)status; - uart_puts("[UOS-STUB-T8-3.4] health: not implemented\n"); - return -1; +/** + * @purpose + * Check guest health. + */ +int uos_guest_services_health(uos_guest_id_t guest_id, uint32_t* status) { + /* Validate parameters */ + if (status == NULL) { + return UOS_GS_E_INVAL; + } + + /* Validate guest ID */ + if (guest_id >= UOS_GUEST_MAX) { + return UOS_GS_E_INVAL; + } + + /* TODO: Implement health check */ + /* For now, return healthy status */ + *status = 0; /* Healthy */ + + return UOS_GS_E_OK; } -/* ============================================================================ - * Inter-Guest Communication Services (Stubs) - * ==========================================================================*/ +/* ----------------------- Inter-Guest Communication Services -------------- */ -int uos_guest_services_port_write(uint32_t port_id, const void* data, uint32_t len) { - (void)port_id; (void)data; (void)len; - uart_puts("[UOS-STUB-T8-3.4] port_write: not implemented\n"); - return -1; +/** + * @purpose + * Write to a port. + */ +int uos_guest_services_port_write(uos_port_id_t port_id, const void* data, uint32_t len) { + /* Validate parameters */ + if (data == NULL || len == 0) { + return UOS_GS_E_INVAL; + } + + /* Validate port ID */ + if (port_id >= UOS_PORT_MAX) { + return UOS_GS_E_INVAL; + } + + /* Check if port is in use */ + if (!gs_ports[port_id].in_use) { + return UOS_GS_E_NOENT; + } + + /* TODO: Implement port write */ + /* For now, just update statistics */ + gs_stats.port_writes++; + + return UOS_GS_E_OK; } -int uos_guest_services_port_read(uint32_t port_id, void* buffer, uint32_t* len) { - (void)port_id; (void)buffer; (void)len; - uart_puts("[UOS-STUB-T8-3.4] port_read: not implemented\n"); - return -1; +/** + * @purpose + * Read from a port. + */ +int uos_guest_services_port_read(uos_port_id_t port_id, void* buffer, uint32_t* len) { + /* Validate parameters */ + if (buffer == NULL || len == NULL) { + return UOS_GS_E_INVAL; + } + + /* Validate port ID */ + if (port_id >= UOS_PORT_MAX) { + return UOS_GS_E_INVAL; + } + + /* Check if port is in use */ + if (!gs_ports[port_id].in_use) { + return UOS_GS_E_NOENT; + } + + /* TODO: Implement port read */ + /* For now, just update statistics */ + gs_stats.port_reads++; + + return UOS_GS_E_OK; } -int uos_guest_services_shm_create(uint64_t addr, uint32_t size, uint32_t guests) { - (void)addr; (void)size; (void)guests; - uart_puts("[UOS-STUB-T8-3.4] shm_create: not implemented\n"); - return -1; +/** + * @purpose + * Create shared memory region. + */ +uos_shm_id_t uos_guest_services_shm_create(uint64_t addr, uint32_t size, uint32_t guests) { + /* Validate parameters */ + if (size == 0 || guests == 0) { + return UOS_GS_E_INVAL; + } + + /* Find free shared memory slot */ + for (uint32_t i = 0; i < UOS_SHM_MAX; i++) { + if (!gs_shm[i].in_use) { + gs_shm[i].addr = addr; + gs_shm[i].size = size; + gs_shm[i].guests = guests; + gs_shm[i].in_use = true; + return i; + } + } + + return UOS_GS_E_NOSPC; } +/** + * @purpose + * Read from shared memory. + */ int uos_guest_services_shm_read(uint64_t addr, void* buffer, uint32_t len) { - (void)addr; (void)buffer; (void)len; - uart_puts("[UOS-STUB-T8-3.4] shm_read: not implemented\n"); - return -1; + /* Validate parameters */ + if (buffer == NULL || len == 0) { + return UOS_GS_E_INVAL; + } + + /* Find shared memory region */ + bool found = false; + for (uint32_t i = 0; i < UOS_SHM_MAX; i++) { + if (gs_shm[i].in_use && addr >= gs_shm[i].addr && + addr + len <= gs_shm[i].addr + gs_shm[i].size) { + found = true; + break; + } + } + + if (!found) { + return UOS_GS_E_NOENT; + } + + /* TODO: Implement shared memory read */ + /* For now, just update statistics */ + gs_stats.shm_reads++; + + return UOS_GS_E_OK; } +/** + * @purpose + * Write to shared memory. + */ int uos_guest_services_shm_write(uint64_t addr, const void* data, uint32_t len) { - (void)addr; (void)data; (void)len; - uart_puts("[UOS-STUB-T8-3.4] shm_write: not implemented\n"); - return -1; -} - -int uos_guest_services_mq_send(uint32_t queue_id, const void* message, uint32_t len, uint32_t priority) { - (void)queue_id; (void)message; (void)len; (void)priority; - uart_puts("[UOS-STUB-T8-3.4] mq_send: not implemented\n"); - return -1; -} - -int uos_guest_services_mq_receive(uint32_t queue_id, void* buffer, uint32_t* len, uint32_t* priority) { - (void)queue_id; (void)buffer; (void)len; (void)priority; - uart_puts("[UOS-STUB-T8-3.4] mq_receive: not implemented\n"); - return -1; -} - -/* ============================================================================ - * State and Status - * ==========================================================================*/ - -int uos_guest_services_get_state(uos_guest_services_state_t* state) { - if (!g_services_initialized) { - uos_guest_services_init(); + /* Validate parameters */ + if (data == NULL || len == 0) { + return UOS_GS_E_INVAL; } - - if (!state) { - return -1; + + /* Find shared memory region */ + bool found = false; + for (uint32_t i = 0; i < UOS_SHM_MAX; i++) { + if (gs_shm[i].in_use && addr >= gs_shm[i].addr && + addr + len <= gs_shm[i].addr + gs_shm[i].size) { + found = true; + break; + } } - - *state = g_services_state; - return 0; + + if (!found) { + return UOS_GS_E_NOENT; + } + + /* TODO: Implement shared memory write */ + /* For now, just update statistics */ + gs_stats.shm_writes++; + + return UOS_GS_E_OK; } -void uos_guest_services_print_status(void) { - if (!g_services_initialized) { - uos_guest_services_init(); +/** + * @purpose + * Send message to message queue. + */ +int uos_guest_services_mq_send(uos_mq_id_t queue_id, const void* message, uint32_t len, uint32_t priority) { + /* Validate parameters */ + if (message == NULL || len == 0) { + return UOS_GS_E_INVAL; } - - uart_puts("\n[GUEST-SERVICES] Status:\n"); - uart_puts(" Partition ID: "); - uart_print_dec(g_services_state.partition_id); - uart_puts("\n"); - uart_puts(" Memory Size: "); - uart_print_dec((uint32_t)(g_services_state.memory_size / (1024 * 1024))); - uart_puts(" MB\n"); - uart_puts(" Service Count: "); - uart_print_dec(g_services_state.service_count); - uart_puts("\n"); - uart_puts(" Device Emulation: "); - uart_puts(g_services_state.device_emulation_enabled ? "Enabled" : "Disabled"); - uart_puts("\n"); - uart_puts(" Shared Services: "); - uart_puts(g_services_state.shared_services_enabled ? "Enabled" : "Disabled"); - uart_puts("\n"); - uart_puts(" Inter-Guest Comm: "); - uart_puts(g_services_state.inter_guest_comm_enabled ? "Enabled" : "Disabled"); - uart_puts("\n\n"); + + /* Validate queue ID */ + if (queue_id >= UOS_MQ_MAX) { + return UOS_GS_E_INVAL; + } + + /* Check if queue is in use */ + if (!gs_mq[queue_id].in_use) { + return UOS_GS_E_NOENT; + } + + /* TODO: Implement message queue send */ + /* For now, just update statistics */ + gs_stats.mq_sends++; + + return UOS_GS_E_OK; +} + +/** + * @purpose + * Receive message from message queue. + */ +int uos_guest_services_mq_receive(uos_mq_id_t queue_id, void* buffer, uint32_t* len, uint32_t* priority) { + /* Validate parameters */ + if (buffer == NULL || len == NULL) { + return UOS_GS_E_INVAL; + } + + /* Validate queue ID */ + if (queue_id >= UOS_MQ_MAX) { + return UOS_GS_E_INVAL; + } + + /* Check if queue is in use */ + if (!gs_mq[queue_id].in_use) { + return UOS_GS_E_NOENT; + } + + /* TODO: Implement message queue receive */ + /* For now, just update statistics */ + gs_stats.mq_receives++; + + return UOS_GS_E_OK; } diff --git a/kernel/src/core/abi/uos_guest_services.h b/kernel/src/core/abi/uos_guest_services.h index 784c83255..ace2f97dd 100644 --- a/kernel/src/core/abi/uos_guest_services.h +++ b/kernel/src/core/abi/uos_guest_services.h @@ -1,182 +1,429 @@ -/* - * UniversalisOS Guest-Services Partition - * - * This header defines the guest-services partition API. The guest-services - * partition provides shared services to all guests including device emulation, - * shared services, and inter-guest communication. - * - * Track: T8-3.4 - * Date: 2026-07-12 - */ - #ifndef UOS_GUEST_SERVICES_H #define UOS_GUEST_SERVICES_H +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_guest_services.h + * + * @purpose + * Guest services interface for UniversalisOS. + * Based on PikeOS vm_port.h and ipc.h architecture. + */ + +/* ------------------------- FILE INCLUSION -------------------------------- */ + #include +#include +#include -/* ============================================================================ - * Guest-Services Configuration - * ==========================================================================*/ +/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */ -/* Reserved partition ID for guest-services */ -#define UOS_GUEST_SERVICES_PARTITION_ID 255u +/** Maximum number of guests */ +#define UOS_GUEST_MAX 16 -/* Guest-services memory size */ -#define UOS_GUEST_SERVICES_MEMORY_SIZE (256u * 1024u * 1024u) /* 256M */ +/** Maximum number of ports per guest */ +#define UOS_PORT_MAX 32 -/* Maximum number of services */ -#define UOS_GUEST_SERVICES_MAX_SERVICES 32u +/** Maximum number of shared memory regions */ +#define UOS_SHM_MAX 16 -/* Maximum service name length */ -#define UOS_GUEST_SERVICES_MAX_NAME_LEN 64u +/** Maximum number of message queues */ +#define UOS_MQ_MAX 16 -/* ============================================================================ - * Service Types - * ==========================================================================*/ +/** Maximum message size */ +#define UOS_MQ_MAX_MSG_SIZE 256 -typedef enum { - UOS_SERVICE_TYPE_DEVICE_EMULATION = 0, - UOS_SERVICE_TYPE_SHARED_SERVICE = 1, - UOS_SERVICE_TYPE_INTER_GUEST_COMM = 2, -} uos_service_type_t; +/** Maximum port name length */ +#define UOS_PORT_NAME_MAX 32 -/* ============================================================================ - * Service Handler - * ==========================================================================*/ +/** Port directions */ +#define UOS_PORT_SOURCE 0x01 +#define UOS_PORT_DESTINATION 0x02 -typedef int (*guest_service_handler_t)(uint32_t guest_id, void* args, void* result); +/** Port types */ +#define UOS_PORT_TYPE_QUEUING 0 +#define UOS_PORT_TYPE_SAMPLING 1 -/* ============================================================================ - * Service Registration - * ==========================================================================*/ +/** Error codes */ +#define UOS_GS_E_OK 0 +#define UOS_GS_E_PERM -1 +#define UOS_GS_E_NOENT -2 +#define UOS_GS_E_INVAL -3 +#define UOS_GS_E_IO -4 +#define UOS_GS_E_NOMEM -5 +#define UOS_GS_E_EXIST -6 +#define UOS_GS_E_NOSPC -7 +#define UOS_GS_E_TIMEOUT -8 +#define UOS_GS_E_NOTIMPL -9 -typedef struct { - char name[UOS_GUEST_SERVICES_MAX_NAME_LEN]; - uos_service_type_t type; - guest_service_handler_t handler; - int registered; -} uos_service_t; - -/* ============================================================================ - * Guest-Services State - * ==========================================================================*/ - -typedef struct { - uint32_t partition_id; - uint64_t memory_size; - uint32_t service_count; - int device_emulation_enabled; - int shared_services_enabled; - int inter_guest_comm_enabled; -} uos_guest_services_state_t; - -/* ============================================================================ - * Function Declarations - * ==========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif +/* ------------------------ TYPE DECLARATIONS ------------------------------ */ /** - * Initialize guest-services partition - * @return 0 on success, -1 on failure + * @brief Guest ID type */ -int uos_guest_services_init(void); +typedef uint32_t uos_guest_id_t; /** - * Register a service - * @param name Service name - * @param type Service type - * @param handler Service handler - * @return 0 on success, -1 on failure + * @brief Port ID type */ -int uos_guest_services_register(const char* name, uos_service_type_t type, guest_service_handler_t handler); +typedef uint32_t uos_port_id_t; /** - * Unregister a service - * @param name Service name - * @return 0 on success, -1 on failure + * @brief Shared memory ID type */ -int uos_guest_services_unregister(const char* name); +typedef uint32_t uos_shm_id_t; /** - * Call a service - * @param name Service name - * @param guest_id Guest ID - * @param args Service arguments - * @param result Service result - * @return 0 on success, -1 on failure + * @brief Message queue ID type */ -int uos_guest_services_call(const char* name, uint32_t guest_id, void* args, void* result); +typedef uint32_t uos_mq_id_t; -/* ============================================================================ - * Device Emulation Services - * ==========================================================================*/ +/** + * @brief Port descriptor structure + */ +typedef struct uos_port_desc_str { + uos_port_id_t id; /**< Port ID */ + char name[UOS_PORT_NAME_MAX]; /**< Port name */ + uint32_t direction; /**< Port direction */ + uint32_t type; /**< Port type */ + uint32_t max_msg_size; /**< Maximum message size */ + uint32_t max_nb_msg; /**< Maximum number of messages */ + uint32_t nb_msg; /**< Current number of messages */ + void* buffer; /**< Message buffer */ + uint32_t buffer_size; /**< Buffer size */ + bool in_use; /**< In use flag */ +} uos_port_desc_t; -/* virtio-blk */ -int uos_guest_services_vblk_read(uint32_t guest_id, uint64_t sector, void* buffer, uint32_t count); -int uos_guest_services_vblk_write(uint32_t guest_id, uint64_t sector, const void* buffer, uint32_t count); +/** + * @brief Shared memory descriptor structure + */ +typedef struct uos_shm_desc_str { + uos_shm_id_t id; /**< Shared memory ID */ + uint64_t addr; /**< Shared memory address */ + uint64_t size; /**< Shared memory size */ + uint32_t guests; /**< Guest mask */ + bool in_use; /**< In use flag */ +} uos_shm_desc_t; -/* virtio-net */ -int uos_guest_services_vnet_send(uint32_t guest_id, const void* packet, uint32_t len); -int uos_guest_services_vnet_receive(uint32_t guest_id, void* buffer, uint32_t* len); +/** + * @brief Message queue descriptor structure + */ +typedef struct uos_mq_desc_str { + uos_mq_id_t id; /**< Message queue ID */ + uint32_t max_msg_size; /**< Maximum message size */ + uint32_t max_nb_msg; /**< Maximum number of messages */ + uint32_t nb_msg; /**< Current number of messages */ + void* buffer; /**< Message buffer */ + uint32_t buffer_size; /**< Buffer size */ + bool in_use; /**< In use flag */ +} uos_mq_desc_t; -/* virtio-console */ -int uos_guest_services_vconsole_write(uint32_t guest_id, const char* str); -int uos_guest_services_vconsole_read(uint32_t guest_id, char* buffer, uint32_t* len); +/** + * @brief Guest services statistics structure + */ +typedef struct uos_gs_stats_str { + uint64_t vblk_reads; /**< Virtual block device reads */ + uint64_t vblk_writes; /**< Virtual block device writes */ + uint64_t vnet_sends; /**< Virtual network sends */ + uint64_t vnet_receives; /**< Virtual network receives */ + uint64_t vconsole_writes; /**< Virtual console writes */ + uint64_t vconsole_reads; /**< Virtual console reads */ + uint64_t port_writes; /**< Port writes */ + uint64_t port_reads; /**< Port reads */ + uint64_t shm_reads; /**< Shared memory reads */ + uint64_t shm_writes; /**< Shared memory writes */ + uint64_t mq_sends; /**< Message queue sends */ + uint64_t mq_receives; /**< Message queue receives */ +} uos_gs_stats_t; -/* ============================================================================ - * Shared Services - * ==========================================================================*/ +/* ----------------------- FUNCTION DECLARATIONS --------------------------- */ -/* Time service */ +/** + * @purpose + * Initialize guest services. + */ +void uos_guest_services_init(void); + +/** + * @purpose + * Get guest services statistics. + * + * @param stats + * OUT: Guest services statistics + */ +void uos_guest_services_get_stats(uos_gs_stats_t* stats); + +/* ----------------------- Device Emulation Services ----------------------- */ + +/** + * @purpose + * Read from virtual block device. + * + * @param guest_id + * IN: Guest ID + * @param sector + * IN: Sector to read from + * @param buffer + * OUT: Buffer to read into + * @param count + * IN: Number of sectors to read + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_vblk_read(uos_guest_id_t guest_id, uint64_t sector, void* buffer, uint32_t count); + +/** + * @purpose + * Write to virtual block device. + * + * @param guest_id + * IN: Guest ID + * @param sector + * IN: Sector to write to + * @param buffer + * IN: Buffer to write from + * @param count + * IN: Number of sectors to write + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_vblk_write(uos_guest_id_t guest_id, uint64_t sector, const void* buffer, uint32_t count); + +/** + * @purpose + * Send packet to virtual network. + * + * @param guest_id + * IN: Guest ID + * @param packet + * IN: Packet to send + * @param len + * IN: Packet length + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_vnet_send(uos_guest_id_t guest_id, const void* packet, uint32_t len); + +/** + * @purpose + * Receive packet from virtual network. + * + * @param guest_id + * IN: Guest ID + * @param buffer + * OUT: Buffer to receive into + * @param len + * INOUT: Buffer length / received length + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_vnet_receive(uos_guest_id_t guest_id, void* buffer, uint32_t* len); + +/** + * @purpose + * Write to virtual console. + * + * @param guest_id + * IN: Guest ID + * @param str + * IN: String to write + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_vconsole_write(uos_guest_id_t guest_id, const char* str); + +/** + * @purpose + * Read from virtual console. + * + * @param guest_id + * IN: Guest ID + * @param buffer + * OUT: Buffer to read into + * @param len + * INOUT: Buffer length / read length + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_vconsole_read(uos_guest_id_t guest_id, char* buffer, uint32_t* len); + +/* ----------------------- Shared Services --------------------------------- */ + +/** + * @purpose + * Get current time. + * + * @returns + * Current time in nanoseconds + */ uint64_t uos_guest_services_get_time(void); -/* Random service */ +/** + * @purpose + * Get random bytes. + * + * @param buffer + * OUT: Buffer to fill with random bytes + * @param len + * IN: Number of random bytes + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ int uos_guest_services_get_random(void* buffer, uint32_t len); -/* Logging service */ -int uos_guest_services_log(uint32_t guest_id, const char* message); +/** + * @purpose + * Log a message. + * + * @param guest_id + * IN: Guest ID + * @param message + * IN: Message to log + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_log(uos_guest_id_t guest_id, const char* message); -/* Health service */ -int uos_guest_services_health(uint32_t guest_id, uint32_t* status); +/** + * @purpose + * Check guest health. + * + * @param guest_id + * IN: Guest ID + * @param status + * OUT: Guest health status + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_health(uos_guest_id_t guest_id, uint32_t* status); -/* ============================================================================ - * Inter-Guest Communication Services - * ==========================================================================*/ +/* ----------------------- Inter-Guest Communication Services -------------- */ -/* Sampling ports */ -int uos_guest_services_port_write(uint32_t port_id, const void* data, uint32_t len); -int uos_guest_services_port_read(uint32_t port_id, void* buffer, uint32_t* len); +/** + * @purpose + * Write to a port. + * + * @param port_id + * IN: Port ID + * @param data + * IN: Data to write + * @param len + * IN: Data length + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_port_write(uos_port_id_t port_id, const void* data, uint32_t len); -/* Shared memory */ -int uos_guest_services_shm_create(uint64_t addr, uint32_t size, uint32_t guests); +/** + * @purpose + * Read from a port. + * + * @param port_id + * IN: Port ID + * @param buffer + * OUT: Buffer to read into + * @param len + * INOUT: Buffer length / read length + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_port_read(uos_port_id_t port_id, void* buffer, uint32_t* len); + +/** + * @purpose + * Create shared memory region. + * + * @param addr + * IN: Shared memory address + * @param size + * IN: Shared memory size + * @param guests + * IN: Guest mask + * + * @returns + * Shared memory ID on success, error code otherwise + */ +uos_shm_id_t uos_guest_services_shm_create(uint64_t addr, uint32_t size, uint32_t guests); + +/** + * @purpose + * Read from shared memory. + * + * @param addr + * IN: Shared memory address + * @param buffer + * OUT: Buffer to read into + * @param len + * IN: Number of bytes to read + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ int uos_guest_services_shm_read(uint64_t addr, void* buffer, uint32_t len); + +/** + * @purpose + * Write to shared memory. + * + * @param addr + * IN: Shared memory address + * @param data + * IN: Data to write + * @param len + * IN: Number of bytes to write + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ int uos_guest_services_shm_write(uint64_t addr, const void* data, uint32_t len); -/* Message queues */ -int uos_guest_services_mq_send(uint32_t queue_id, const void* message, uint32_t len, uint32_t priority); -int uos_guest_services_mq_receive(uint32_t queue_id, void* buffer, uint32_t* len, uint32_t* priority); - -/* ============================================================================ - * State and Status - * ==========================================================================*/ +/** + * @purpose + * Send message to message queue. + * + * @param queue_id + * IN: Message queue ID + * @param message + * IN: Message to send + * @param len + * IN: Message length + * @param priority + * IN: Message priority + * + * @returns + * UOS_GS_E_OK on success, error code otherwise + */ +int uos_guest_services_mq_send(uos_mq_id_t queue_id, const void* message, uint32_t len, uint32_t priority); /** - * Get guest-services state - * @param state Output: guest-services state - * @return 0 on success, -1 on failure + * @purpose + * Receive message from message queue. + * + * @param queue_id + * IN: Message queue ID + * @param buffer + * OUT: Buffer to receive into + * @param len + * INOUT: Buffer length / received length + * @param priority + * OUT: Message priority + * + * @returns + * UOS_GS_E_OK on success, error code otherwise */ -int uos_guest_services_get_state(uos_guest_services_state_t* state); - -/** - * Print guest-services status - */ -void uos_guest_services_print_status(void); - -#ifdef __cplusplus -} -#endif +int uos_guest_services_mq_receive(uos_mq_id_t queue_id, void* buffer, uint32_t* len, uint32_t* priority); #endif /* UOS_GUEST_SERVICES_H */ diff --git a/kernel/src/core/abi/uos_multi_guest.cpp b/kernel/src/core/abi/uos_multi_guest.cpp index 6b1a67b1b..05ac09f45 100644 --- a/kernel/src/core/abi/uos_multi_guest.cpp +++ b/kernel/src/core/abi/uos_multi_guest.cpp @@ -1,249 +1,243 @@ -/* - * UniversalisOS Multi-Android-Guest Architecture Implementation +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_multi_guest.cpp * - * Track: T8-3.3 - * Date: 2026-07-12 + * @purpose + * Implementation of multi-guest coordination for UniversalisOS. + * Based on PikeOS vm.h architecture. */ +/* ------------------------- FILE INCLUSION -------------------------------- */ + #include "uos_multi_guest.h" -#include "uos_fleet.h" -#include "uos_separation_model.h" -#include "../mm.h" -#include "../../platform/drivers/uart.h" -/* ============================================================================ - * Multi-Guest State - * ==========================================================================*/ +/* ------------------------ STATIC VARIABLES ------------------------------- */ -static uos_multi_guest_state_t g_multi_guest_state; -static int g_multi_guest_initialized = 0; +/** Channel directory */ +static uos_mg_channel_t mg_channels[UOS_MG_MAX_CHANNELS]; -/* ============================================================================ - * Multi-Guest Initialization - * ==========================================================================*/ +/** Next channel ID */ +static uos_mg_channel_id_t next_channel_id = 1; -int uos_multi_guest_init(void) { - if (g_multi_guest_initialized) { - return 0; +/** Multi-guest statistics */ +static uos_mg_stats_t mg_stats; + +/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */ + +/** + * @purpose + * Initialize multi-guest coordination. + */ +void uos_multi_guest_init(void) { + /* Initialize channel directory */ + for (uint32_t i = 0; i < UOS_MG_MAX_CHANNELS; i++) { + mg_channels[i].id = 0; + mg_channels[i].name[0] = '\0'; + mg_channels[i].type = UOS_MG_CHANNEL_TYPE_SHM; + mg_channels[i].direction = UOS_MG_CHANNEL_DIR_INOUT; + mg_channels[i].src_guest = 0; + mg_channels[i].dst_guest = 0; + mg_channels[i].addr = 0; + mg_channels[i].size = 0; + mg_channels[i].in_use = false; } - - /* Initialize fleet management */ - uos_fleet_init(); - - /* Initialize separation model */ - uos_separation_init(); - - /* Initialize multi-guest state */ - g_multi_guest_state.guest_count = 0; - g_multi_guest_state.android_count = 0; - g_multi_guest_state.musl_count = 0; - g_multi_guest_state.total_memory = 0; - g_multi_guest_state.used_memory = 0; - g_multi_guest_state.all_isolated = 1; - - g_multi_guest_initialized = 1; - - uart_puts("[MULTI-GUEST] Subsystem initialized\n"); - - return 0; + + /* Initialize statistics */ + mg_stats.channels_created = 0; + mg_stats.channels_deleted = 0; + mg_stats.messages_sent = 0; + mg_stats.messages_received = 0; + mg_stats.bytes_transferred = 0; } -/* ============================================================================ - * Add Android Guest - * ==========================================================================*/ - -int uos_multi_guest_add_android(const char* name, uint64_t memory_size) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); +/** + * @purpose + * Create a channel between two guests. + */ +uos_mg_channel_id_t uos_multi_guest_channel_create(const char* name, uint32_t type, + uint32_t direction, uos_mg_guest_id_t src_guest, + uos_mg_guest_id_t dst_guest, uint64_t addr, uint64_t size) { + /* Validate parameters */ + if (name == NULL) { + return UOS_MG_E_INVAL; } - - if (g_multi_guest_state.guest_count >= UOS_MULTI_GUEST_MAX) { - uart_puts("[MULTI-GUEST] Maximum guests reached\n"); - return -1; + + /* Validate guest IDs */ + if (src_guest >= UOS_MG_MAX_GUESTS || dst_guest >= UOS_MG_MAX_GUESTS) { + return UOS_MG_E_INVAL; } - - /* Fork guest from android template */ - int guest_id = uos_fleet_fork("android-aosp", name, memory_size); - if (guest_id < 0) { - return -1; + + /* Find free channel slot */ + uos_mg_channel_id_t channel_id = 0; + for (uint32_t i = 0; i < UOS_MG_MAX_CHANNELS; i++) { + if (!mg_channels[i].in_use) { + channel_id = i; + break; + } } - - g_multi_guest_state.guest_count++; - g_multi_guest_state.android_count++; - g_multi_guest_state.total_memory += memory_size; - - uart_puts("[MULTI-GUEST] Added Android guest: "); - uart_puts(name); - uart_puts("\n"); - - return guest_id; + + if (channel_id == 0 && mg_channels[0].in_use) { + return UOS_MG_E_NOSPC; + } + + /* Initialize channel descriptor */ + mg_channels[channel_id].id = next_channel_id++; + + /* Copy name */ + uint32_t i = 0; + while (name[i] != '\0' && i < UOS_MG_CHANNEL_NAME_MAX - 1) { + mg_channels[channel_id].name[i] = name[i]; + i++; + } + mg_channels[channel_id].name[i] = '\0'; + + mg_channels[channel_id].type = type; + mg_channels[channel_id].direction = direction; + mg_channels[channel_id].src_guest = src_guest; + mg_channels[channel_id].dst_guest = dst_guest; + mg_channels[channel_id].addr = addr; + mg_channels[channel_id].size = size; + mg_channels[channel_id].in_use = true; + + /* Update statistics */ + mg_stats.channels_created++; + + return channel_id; } -/* ============================================================================ - * Add musl Guest - * ==========================================================================*/ - -int uos_multi_guest_add_musl(const char* name, uint64_t memory_size) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); +/** + * @purpose + * Delete a channel. + */ +int uos_multi_guest_channel_delete(uos_mg_channel_id_t channel_id) { + /* Validate channel ID */ + if (channel_id >= UOS_MG_MAX_CHANNELS) { + return UOS_MG_E_INVAL; } - - if (g_multi_guest_state.guest_count >= UOS_MULTI_GUEST_MAX) { - uart_puts("[MULTI-GUEST] Maximum guests reached\n"); - return -1; + + if (!mg_channels[channel_id].in_use) { + return UOS_MG_E_NOENT; } - - /* Fork guest from musl template */ - int guest_id = uos_fleet_fork("musl", name, memory_size); - if (guest_id < 0) { - return -1; - } - - g_multi_guest_state.guest_count++; - g_multi_guest_state.musl_count++; - g_multi_guest_state.total_memory += memory_size; - - uart_puts("[MULTI-GUEST] Added musl guest: "); - uart_puts(name); - uart_puts("\n"); - - return guest_id; + + /* Mark as unused */ + mg_channels[channel_id].in_use = false; + + /* Update statistics */ + mg_stats.channels_deleted++; + + return UOS_MG_E_OK; } -/* ============================================================================ - * Remove Guest - * ==========================================================================*/ - -int uos_multi_guest_remove(uint32_t guest_id) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); +/** + * @purpose + * Get channel descriptor. + */ +uos_mg_channel_t* uos_multi_guest_channel_get(uos_mg_channel_id_t channel_id) { + /* Validate channel ID */ + if (channel_id >= UOS_MG_MAX_CHANNELS) { + return NULL; } - - if (guest_id >= UOS_MULTI_GUEST_MAX) { - return -1; + + if (!mg_channels[channel_id].in_use) { + return NULL; } - - /* TODO: Implement guest removal */ - uart_puts("[UOS-STUB-T8-3.3] Guest removal: not implemented\n"); - - return 0; + + return &mg_channels[channel_id]; } -/* ============================================================================ - * Start All Guests - * ==========================================================================*/ +/** + * @purpose + * Send data through a channel. + */ +int uos_multi_guest_channel_send(uos_mg_channel_id_t channel_id, const void* data, uint32_t len) { + /* Validate parameters */ + if (data == NULL || len == 0) { + return UOS_MG_E_INVAL; + } + + /* Validate channel ID */ + if (channel_id >= UOS_MG_MAX_CHANNELS) { + return UOS_MG_E_INVAL; + } + + if (!mg_channels[channel_id].in_use) { + return UOS_MG_E_NOENT; + } + + /* Check direction */ + if ((mg_channels[channel_id].direction & UOS_MG_CHANNEL_DIR_OUT) == 0) { + return UOS_MG_E_PERM; + } + + /* TODO: Implement channel send logic */ + + /* Update statistics */ + mg_stats.messages_sent++; + mg_stats.bytes_transferred += len; + + return UOS_MG_E_OK; +} +/** + * @purpose + * Receive data from a channel. + */ +int uos_multi_guest_channel_receive(uos_mg_channel_id_t channel_id, void* buffer, uint32_t* len) { + /* Validate parameters */ + if (buffer == NULL || len == NULL) { + return UOS_MG_E_INVAL; + } + + /* Validate channel ID */ + if (channel_id >= UOS_MG_MAX_CHANNELS) { + return UOS_MG_E_INVAL; + } + + if (!mg_channels[channel_id].in_use) { + return UOS_MG_E_NOENT; + } + + /* Check direction */ + if ((mg_channels[channel_id].direction & UOS_MG_CHANNEL_DIR_IN) == 0) { + return UOS_MG_E_PERM; + } + + /* TODO: Implement channel receive logic */ + + /* Update statistics */ + mg_stats.messages_received++; + + return UOS_MG_E_OK; +} + +/** + * @purpose + * Start all guests. + */ int uos_multi_guest_start_all(void) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); - } - - uart_puts("[MULTI-GUEST] Starting all guests...\n"); - - /* TODO: Implement actual start */ - uart_puts("[UOS-STUB-T8-3.3] Start all: not implemented\n"); - - return 0; + /* TODO: Implement start all guests logic */ + + return UOS_MG_E_OK; } -/* ============================================================================ - * Stop All Guests - * ==========================================================================*/ - +/** + * @purpose + * Stop all guests. + */ int uos_multi_guest_stop_all(void) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); - } - - uart_puts("[MULTI-GUEST] Stopping all guests...\n"); - - /* TODO: Implement actual stop */ - uart_puts("[UOS-STUB-T8-3.3] Stop all: not implemented\n"); - - return 0; + /* TODO: Implement stop all guests logic */ + + return UOS_MG_E_OK; } -/* ============================================================================ - * Get Guest Count - * ==========================================================================*/ - -uint32_t uos_multi_guest_count(void) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); +/** + * @purpose + * Get multi-guest statistics. + */ +void uos_multi_guest_get_stats(uos_mg_stats_t* stats) { + if (stats != NULL) { + *stats = mg_stats; } - - return g_multi_guest_state.guest_count; -} - -/* ============================================================================ - * Get Android Guest Count - * ==========================================================================*/ - -uint32_t uos_multi_guest_android_count(void) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); - } - - return g_multi_guest_state.android_count; -} - -/* ============================================================================ - * Audit All Guests - * ==========================================================================*/ - -int uos_multi_guest_audit_all(void) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); - } - - uart_puts("[MULTI-GUEST] Running isolation audit on all guests...\n"); - - /* TODO: Implement actual audit */ - uart_puts("[UOS-STUB-T8-3.3] Audit all: not implemented\n"); - - return 0; -} - -/* ============================================================================ - * Get Multi-Guest State - * ==========================================================================*/ - -int uos_multi_guest_get_state(uos_multi_guest_state_t* state) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); - } - - if (!state) { - return -1; - } - - *state = g_multi_guest_state; - return 0; -} - -/* ============================================================================ - * Print Multi-Guest Status - * ==========================================================================*/ - -void uos_multi_guest_print_status(void) { - if (!g_multi_guest_initialized) { - uos_multi_guest_init(); - } - - uart_puts("\n[MULTI-GUEST] Status:\n"); - uart_puts(" Total Guests: "); - uart_print_dec(g_multi_guest_state.guest_count); - uart_puts("\n"); - uart_puts(" Android Guests: "); - uart_print_dec(g_multi_guest_state.android_count); - uart_puts("\n"); - uart_puts(" musl Guests: "); - uart_print_dec(g_multi_guest_state.musl_count); - uart_puts("\n"); - uart_puts(" Total Memory: "); - uart_print_dec((uint32_t)(g_multi_guest_state.total_memory / (1024 * 1024))); - uart_puts(" MB\n"); - uart_puts(" All Isolated: "); - uart_puts(g_multi_guest_state.all_isolated ? "Yes" : "No"); - uart_puts("\n\n"); } diff --git a/kernel/src/core/abi/uos_multi_guest.h b/kernel/src/core/abi/uos_multi_guest.h index 8240dad3b..88584b746 100644 --- a/kernel/src/core/abi/uos_multi_guest.h +++ b/kernel/src/core/abi/uos_multi_guest.h @@ -1,130 +1,208 @@ -/* - * UniversalisOS Multi-Android-Guest Architecture - * - * This header defines the multi-guest API for running multiple concurrent - * Android guests inside UniversalisOS. - * - * Track: T8-3.3 - * Date: 2026-07-12 - */ - #ifndef UOS_MULTI_GUEST_H #define UOS_MULTI_GUEST_H +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_multi_guest.h + * + * @purpose + * Multi-guest coordination interface for UniversalisOS. + * Based on PikeOS vm.h architecture. + */ + +/* ------------------------- FILE INCLUSION -------------------------------- */ + #include -#include "uos_fleet.h" +#include +#include -/* ============================================================================ - * Multi-Guest Configuration - * ==========================================================================*/ +/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */ -/* Maximum number of concurrent guests */ -#define UOS_MULTI_GUEST_MAX 4u +/** Maximum number of guests */ +#define UOS_MG_MAX_GUESTS 16 -/* Guest memory sizes */ -#define UOS_MULTI_GUEST_MUSL_SIZE (512u * 1024u * 1024u) /* 512M */ -#define UOS_MULTI_GUEST_ANDROID_SIZE (1024u * 1024u * 1024u) /* 1G */ +/** Maximum number of channels */ +#define UOS_MG_MAX_CHANNELS 32 -/* Guest IPA bases (all guests use same IPA base, different PA) */ -#define UOS_MULTI_GUEST_IPA_BASE 0x40000000u +/** Maximum channel name length */ +#define UOS_MG_CHANNEL_NAME_MAX 32 -/* Guest PA bases (different for each guest) */ -#define UOS_MULTI_GUEST_PA_BASE(n) (0x40000000u + ((n) * 0x40000000u)) +/** Channel types */ +#define UOS_MG_CHANNEL_TYPE_SHM 0 +#define UOS_MG_CHANNEL_TYPE_PORT 1 +#define UOS_MG_CHANNEL_TYPE_MQ 2 -/* ============================================================================ - * Multi-Guest State - * ==========================================================================*/ +/** Channel directions */ +#define UOS_MG_CHANNEL_DIR_IN 0x01 +#define UOS_MG_CHANNEL_DIR_OUT 0x02 +#define UOS_MG_CHANNEL_DIR_INOUT 0x03 -typedef struct { - uint32_t guest_count; - uint32_t android_count; - uint32_t musl_count; - uint64_t total_memory; - uint64_t used_memory; - int all_isolated; -} uos_multi_guest_state_t; +/** Error codes */ +#define UOS_MG_E_OK 0 +#define UOS_MG_E_PERM -1 +#define UOS_MG_E_NOENT -2 +#define UOS_MG_E_INVAL -3 +#define UOS_MG_E_NOMEM -4 +#define UOS_MG_E_NOSPC -5 +#define UOS_MG_E_EXIST -6 +#define UOS_MG_E_STATE -7 +#define UOS_MG_E_NOTIMPL -8 -/* ============================================================================ - * Function Declarations - * ==========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif +/* ------------------------ TYPE DECLARATIONS ------------------------------ */ /** - * Initialize multi-guest subsystem - * @return 0 on success, -1 on failure + * @brief Guest ID type */ -int uos_multi_guest_init(void); +typedef uint32_t uos_mg_guest_id_t; /** - * Add Android guest - * @param name Guest name - * @param memory_size Memory size in bytes - * @return Guest ID on success, -1 on failure + * @brief Channel ID type */ -int uos_multi_guest_add_android(const char* name, uint64_t memory_size); +typedef uint32_t uos_mg_channel_id_t; /** - * Add musl personality guest - * @param name Guest name - * @param memory_size Memory size in bytes - * @return Guest ID on success, -1 on failure + * @brief Channel descriptor structure */ -int uos_multi_guest_add_musl(const char* name, uint64_t memory_size); +typedef struct uos_mg_channel_str { + uos_mg_channel_id_t id; /**< Channel ID */ + char name[UOS_MG_CHANNEL_NAME_MAX]; /**< Channel name */ + uint32_t type; /**< Channel type */ + uint32_t direction; /**< Channel direction */ + uos_mg_guest_id_t src_guest; /**< Source guest ID */ + uos_mg_guest_id_t dst_guest; /**< Destination guest ID */ + uint64_t addr; /**< Channel address */ + uint64_t size; /**< Channel size */ + bool in_use; /**< In use flag */ +} uos_mg_channel_t; /** - * Remove guest - * @param guest_id Guest ID - * @return 0 on success, -1 on failure + * @brief Multi-guest statistics structure */ -int uos_multi_guest_remove(uint32_t guest_id); +typedef struct uos_mg_stats_str { + uint64_t channels_created; /**< Number of channels created */ + uint64_t channels_deleted; /**< Number of channels deleted */ + uint64_t messages_sent; /**< Number of messages sent */ + uint64_t messages_received; /**< Number of messages received */ + uint64_t bytes_transferred; /**< Number of bytes transferred */ +} uos_mg_stats_t; + +/* ----------------------- FUNCTION DECLARATIONS --------------------------- */ /** - * Start all guests - * @return 0 on success, -1 on failure + * @purpose + * Initialize multi-guest coordination. + */ +void uos_multi_guest_init(void); + +/** + * @purpose + * Create a channel between two guests. + * + * @param name + * IN: Channel name + * @param type + * IN: Channel type + * @param direction + * IN: Channel direction + * @param src_guest + * IN: Source guest ID + * @param dst_guest + * IN: Destination guest ID + * @param addr + * IN: Channel address + * @param size + * IN: Channel size + * + * @returns + * Channel ID on success, error code otherwise + */ +uos_mg_channel_id_t uos_multi_guest_channel_create(const char* name, uint32_t type, + uint32_t direction, uos_mg_guest_id_t src_guest, + uos_mg_guest_id_t dst_guest, uint64_t addr, uint64_t size); + +/** + * @purpose + * Delete a channel. + * + * @param channel_id + * IN: Channel ID + * + * @returns + * UOS_MG_E_OK on success, error code otherwise + */ +int uos_multi_guest_channel_delete(uos_mg_channel_id_t channel_id); + +/** + * @purpose + * Get channel descriptor. + * + * @param channel_id + * IN: Channel ID + * + * @returns + * Channel descriptor on success, NULL otherwise + */ +uos_mg_channel_t* uos_multi_guest_channel_get(uos_mg_channel_id_t channel_id); + +/** + * @purpose + * Send data through a channel. + * + * @param channel_id + * IN: Channel ID + * @param data + * IN: Data to send + * @param len + * IN: Data length + * + * @returns + * UOS_MG_E_OK on success, error code otherwise + */ +int uos_multi_guest_channel_send(uos_mg_channel_id_t channel_id, const void* data, uint32_t len); + +/** + * @purpose + * Receive data from a channel. + * + * @param channel_id + * IN: Channel ID + * @param buffer + * OUT: Buffer to receive into + * @param len + * INOUT: Buffer length / received length + * + * @returns + * UOS_MG_E_OK on success, error code otherwise + */ +int uos_multi_guest_channel_receive(uos_mg_channel_id_t channel_id, void* buffer, uint32_t* len); + +/** + * @purpose + * Start all guests. + * + * @returns + * UOS_MG_E_OK on success, error code otherwise */ int uos_multi_guest_start_all(void); /** - * Stop all guests - * @return 0 on success, -1 on failure + * @purpose + * Stop all guests. + * + * @returns + * UOS_MG_E_OK on success, error code otherwise */ int uos_multi_guest_stop_all(void); /** - * Get guest count - * @return Number of guests + * @purpose + * Get multi-guest statistics. + * + * @param stats + * OUT: Multi-guest statistics */ -uint32_t uos_multi_guest_count(void); - -/** - * Get Android guest count - * @return Number of Android guests - */ -uint32_t uos_multi_guest_android_count(void); - -/** - * Run isolation audit on all guests - * @return 0 if all pass, -1 if any fail - */ -int uos_multi_guest_audit_all(void); - -/** - * Get multi-guest state - * @param state Output: multi-guest state - * @return 0 on success, -1 on failure - */ -int uos_multi_guest_get_state(uos_multi_guest_state_t* state); - -/** - * Print multi-guest status - */ -void uos_multi_guest_print_status(void); - -#ifdef __cplusplus -} -#endif +void uos_multi_guest_get_stats(uos_mg_stats_t* stats); #endif /* UOS_MULTI_GUEST_H */