vxKernel/src/hypervisor/switch.c

65 lines
1.8 KiB
C

#include <vhex/hypervisor.h>
#include <vhex/drivers/cpu.h>
#include <vhex/display.h>
/* hypervisor_world_switch() : perform a world switch */
//TODO: handle shared drivers
int hypervisor_world_switch(hyp_world_t out, hyp_world_t in)
{
struct vhex_world *win;
struct vhex_world *wout;
struct vhex_driver *dtable;
wout = hypervisor_world_get(out);
win = hypervisor_world_get(in);
#if 0
dclear(0xffff);
dprint(0, 0, C_BLACK, "je suis dans le worlds-sitch !");
dprint(0, 11, C_BLACK, "> out = %d (%p)", out, wout);
dprint(0, 22, C_BLACK, "> in = %d (%p)", in, win);
dprint(0, 33, C_BLACK, "> nb vhex drivers = %d", vhex_driver_count());
dupdate();
while (1) { __asm__ volatile ("sleep"); }
#endif
if (wout == NULL || win == NULL)
return (hyp_world_not_found);
if (in == out)
return (0);
cpu_atomic_start();
dtable = vhex_driver_table();
for (int i = 0; i < vhex_driver_count(); ++i) {
if (dtable[i].hpowered != NULL
&& dtable[i].hpowered() == false) {
wout->driver[i].flags = HYP_WORLD_DRV_UNUSED;
continue;
}
dtable[i].hsave(wout->driver[i].context);
wout->driver[i].flags = HYP_WORLD_DRV_USED;
}
for (int i = 0; i < vhex_driver_count(); ++i) {
if (HYP_WORLD_STATUS_STATE(win->status)
== HYP_WORLD_STATUS_STATE_UNINIT) {
if (dtable[i].configure != NULL)
dtable[i].configure(win->driver[i].context);
win->driver[i].flags = dtable[i].default_flag;
}
if (win->driver[i].flags == HYP_WORLD_DRV_UNUSED) {
if (dtable[i].hpowered() == true)
dtable[i].hpoweroff();
continue;
}
if (dtable[i].hpowered != NULL && dtable[i].hpowered() == false)
dtable[i].hpoweron();
dtable[i].hrestore(win->driver[i].context);
}
HYP_WORLD_STATUS_SET_STATE(win->status, HYP_WORLD_STATUS_STATE_USED);
HYP_WORLD_STATUS_SET_STATE(wout->status, HYP_WORLD_STATUS_STATE_USED);
cpu_atomic_end();
}