243 lines
6.0 KiB
C
243 lines
6.0 KiB
C
//---
|
|
// fxBoot:builtin:hyp - Hypervisor utility
|
|
//---
|
|
#include "fxBoot/builtin.h"
|
|
#include "fxBoot/terminal.h"
|
|
#include "fxBoot/fs/smemfs.h"
|
|
#include "fxBoot/hypervisor.h"
|
|
|
|
#include <gint/std/string.h>
|
|
#include <gint/std/stdlib.h>
|
|
#include <gint/gint.h>
|
|
|
|
/* internal structiure used to handle the hypervisor module */
|
|
#define HYP_INFO_WATERMARK (0xdeadbeef)
|
|
struct {
|
|
struct himage *images;
|
|
uint32_t watermark;
|
|
uint32_t installed;
|
|
} hypinfo;
|
|
|
|
#if 0
|
|
//---
|
|
// SMEM abstraction
|
|
//---
|
|
static void smemfs_find(struct smemfs_inode *inode, char *buffer, int *counter)
|
|
{
|
|
const char *ext;
|
|
|
|
if (inode == NULL)
|
|
return;
|
|
smemfs_find(inode->child, buffer, counter);
|
|
ext = strrchr(inode->name, '.');
|
|
if (ext != NULL) {
|
|
if (strcmp(ext, ".elf") == 0) {
|
|
terminal_write("[%d] %s\n", *counter, inode->name);
|
|
*counter += 1;
|
|
}
|
|
}
|
|
smemfs_find(inode->sibling, buffer, counter);
|
|
}
|
|
|
|
static struct smemfs_inode *smemfs_get(struct smemfs_inode *inode,
|
|
int *counter, int id)
|
|
{
|
|
struct smemfs_inode *file;
|
|
const char *ext;
|
|
|
|
if (inode == NULL)
|
|
return (NULL);
|
|
file = smemfs_get(inode->child, counter, id);
|
|
if (file != NULL)
|
|
return (file);
|
|
ext = strrchr(inode->name, '.');
|
|
if (ext != NULL) {
|
|
if (strcmp(ext, ".elf") == 0) {
|
|
if (*counter == id)
|
|
return (inode);
|
|
*counter += 1;
|
|
}
|
|
}
|
|
return (smemfs_get(inode->sibling, counter, id));
|
|
}
|
|
#endif
|
|
|
|
//---
|
|
// Module management
|
|
//---
|
|
|
|
static int hyp_img_module(int argc, char **argv)
|
|
{
|
|
if (argc < 2)
|
|
goto error;
|
|
if (strcmp(argv[2], "ls") == 0) {
|
|
int counter = 0;
|
|
struct himage *img = hypinfo.images;
|
|
while (img != NULL) {
|
|
terminal_write("[%d] %s\n", counter, img->name);
|
|
counter = counter + 1;
|
|
img = img->next;
|
|
}
|
|
return (0);
|
|
}
|
|
#if 0
|
|
if (strcmp(argv[2], "load") == 0) {
|
|
if (argc < 3) {
|
|
terminal_write("image ID missing\n");
|
|
return (84);
|
|
}
|
|
int id = 0;
|
|
struct smemfs_inode *file;
|
|
int counter = 0;
|
|
id = atoi(argv[3]);
|
|
file = smemfs_get(smemfs_superblock.root_inode,
|
|
&counter, id);
|
|
if (file == NULL) {
|
|
terminal_write("image ID invalid\n");
|
|
return (84);
|
|
}
|
|
struct worldctx *worldctx = calloc(sizeof(struct worldctx), 1);
|
|
if (hypervisor_loader(worldctx, file) != 0)
|
|
return (84);
|
|
worldctx->private.next = hyp_info.os_list;
|
|
hyp_info.os_list = worldctx;
|
|
terminal_write("image successfully loaded\n");
|
|
return (0);
|
|
}
|
|
#endif
|
|
|
|
error:
|
|
terminal_write("\"hyp img\" requires at least 1 argument\n");
|
|
terminal_write("\n");
|
|
terminal_write("Manage image\n");
|
|
terminal_write("\n");
|
|
terminal_write("commands:\n");
|
|
terminal_write(" ls List images available on the device\n");
|
|
terminal_write(" load Load image on memory\n");
|
|
return (1);
|
|
}
|
|
|
|
#if 0
|
|
static int hyp_os_module(int argc, char **argv)
|
|
{
|
|
if (argc < 2)
|
|
goto error;
|
|
if (strcmp(argv[2], "ls") == 0) {
|
|
int counter = 0;
|
|
struct worldctx *worldctx = hyp_info.os_list;
|
|
while (worldctx != NULL) {
|
|
terminal_write("[%d] - %s\n", counter, worldctx->private.file->name);
|
|
terminal_write("|-- cpu context:\n");
|
|
for (int i = 0; i < 16; ++i)
|
|
terminal_write("| |-- r%d: %p\n", i, worldctx->context.cpu.reg[i]);
|
|
terminal_write("| |-- gbr: %p\n", worldctx->context.cpu.gbr);
|
|
terminal_write("| |-- macl: %p\n", worldctx->context.cpu.macl);
|
|
terminal_write("| |-- mach: %p\n", worldctx->context.cpu.mach);
|
|
terminal_write("| |-- ssr: %p\n", worldctx->context.cpu.ssr);
|
|
terminal_write("| |-- spc: %p\n", worldctx->context.cpu.spc);
|
|
terminal_write("| `-- pr: %p\n", worldctx->context.cpu.pr);
|
|
terminal_write("`-- memory:\n");
|
|
terminal_write(" |-- entry: %p\n", worldctx->memory.program.start);
|
|
terminal_write(" `-- size : %do\n", worldctx->memory.program.size);
|
|
worldctx = worldctx->private.next;
|
|
counter = counter + 1;
|
|
}
|
|
return (0);
|
|
}
|
|
if (strcmp(argv[2], "run") == 0) {
|
|
if (argc < 3) {
|
|
terminal_write("OS ID missing\n");
|
|
return (84);
|
|
}
|
|
int id = atoi(argv[3]);
|
|
int counter = 0;
|
|
struct worldctx *worldctx = hyp_info.os_list;
|
|
while (worldctx != NULL) {
|
|
if (counter == id)
|
|
break;
|
|
worldctx = worldctx->private.next;
|
|
counter = counter + 1;
|
|
}
|
|
if (worldctx == NULL) {
|
|
terminal_write("OS ID invalid\n");
|
|
return (84);
|
|
}
|
|
/* Switch from gint to the OS after a short wait */
|
|
gint_switch_to_casio();
|
|
|
|
/* call Casio's specific code */
|
|
((void(*)(void))(uintptr_t)worldctx->context.cpu.spc)();
|
|
|
|
/* Then switch back to gint once the OS finishes working */
|
|
gint_switch_to_gint();
|
|
return (0);
|
|
}
|
|
|
|
error:
|
|
terminal_write("\"hyp os\" requiere at least 1 argument\n");
|
|
terminal_write("\n");
|
|
terminal_write("Manage image\n");
|
|
terminal_write("\n");
|
|
terminal_write("commands:\n");
|
|
terminal_write(" ls List images available on the device\n");
|
|
terminal_write(" run Run image (you cannot return to fxBoot)\n");
|
|
return (1);
|
|
}
|
|
|
|
/* install the hypervisor */
|
|
static int hyp_install(void)
|
|
{
|
|
/* extern void *bhyp_rom;
|
|
extern void *bhyp_ram;
|
|
extern void *zhyp;
|
|
|
|
// check if the hypervisor is already installed.
|
|
if (hyp_info.installed == 0xdeb0cad0) {
|
|
terminal_write("hypervisor already installed\n");
|
|
return (1);
|
|
}
|
|
|
|
// install the hypervisor
|
|
if (hyperisor_install() != 0) {
|
|
terminal_write("hypervisor installation fail :(\n");
|
|
return (84);
|
|
}*/
|
|
return (0);
|
|
}
|
|
#endif
|
|
|
|
//---
|
|
// Entry
|
|
//---
|
|
|
|
/* hyp_main(): hypervisor helper */
|
|
int hyp_main(int argc, char **argv)
|
|
{
|
|
/* initialize the buildtin (TODO: better way) */
|
|
if (hypinfo.watermark != HYP_INFO_WATERMARK) {
|
|
hypinfo.watermark = HYP_INFO_WATERMARK;
|
|
hypervisor_loader_list(&hypinfo.images);
|
|
}
|
|
|
|
/* handle arguments */
|
|
if (argc > 1) {
|
|
if (strcmp(argv[1], "img") == 0)
|
|
return (hyp_img_module(argc, argv));
|
|
//if (strcmp(argv[1], "os") == 0)
|
|
// return (hyp_os_module(argc, argv));
|
|
//if (strcmp(argv[1], "install") == 0)
|
|
// return (hyp_install());
|
|
}
|
|
|
|
/* error or helper */
|
|
terminal_write("Usage: hyp [OPTION] commands\n");
|
|
terminal_write("\n");
|
|
terminal_write("Manage image loading\n");
|
|
terminal_write("\n");
|
|
terminal_write("commands:\n");
|
|
terminal_write(" img Image management\n");
|
|
terminal_write(" os OS loading management\n");
|
|
terminal_write(" install Hypervisor installation\n");
|
|
return (0);
|
|
}
|