VxKernel 0.6.0-1 : Rework the graphic pipeline

@add
<> board/fxcg50/fxcg50-dynamic.ld : add the "user/addin" linker script
<> include/vhex/display* : rework the graphic API/pipeline
<> include/vhex/driver/scree/r61524 : add hardware description and API
<> drivers/screen/r61524 : add r61524 driver
<> module/display/dstack : new pipeline

@update
<> board/fxcg50/board : explicitly set the DWIDTH/DHEIGHT define
<> board/fxcg50/hypervisor : API update (WIP)
<> include/vhex/driver :
   | update driver information (use bitfield instead of define and macros)
   | configure driver's primitive cannot be NULL
   | driver can embed module data (ex: r61524 embed display module primitives)
<> include/vhex/hypervisor :
   | update driver information (use bitfield instead of define and macros)
   | update world information (use bitfield instead of define and macros)
   | remove useless "restricted" keyword in prototype
<> make/Makefile : add the support of the vxSDK (0.12.0)
<> module/display/dclear  : support of the new pipeline
<> module/display/display : support of the new pipeline
<> module/display/dupdate : support of the new pipeline
<> module/hypervisor/switch : support new driver/world structure
<> module/hypervisor/table  : support new driver/world structure
<> vxsdk.toml : support of the vxSDK 0.12.0

@fix
<> drivers/mpu/sh/sh7305/cpu/cpu : mask interrupt by default (cpu_atomic_end)
This commit is contained in:
Yann MAGNIN 2022-05-27 11:57:55 +02:00
parent f851b73cba
commit a916120d66
48 changed files with 925 additions and 508 deletions

View File

@ -7,5 +7,5 @@ mpu=sh7305
[toolchain]
prefix=sh-elf-vhex-
cflags=-DFXCG50,-m4-nofpu,-mb
cflags=-DFXCG50,-m4-nofpu,-mb,-DWIDTH=396,-DHEIGHT=224
libs=-lgcc

View File

@ -0,0 +1,98 @@
/*
Linker script for the dynamic version of Vhex (fxcg50)
*/
OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")
OUTPUT_ARCH(sh4)
ENTRY(_main)
/*
** Linker script for user executables.
*/
MEMORY
{
/* virtual memory, read-write segment */
userram (WX) : o = 0x00000000, l = 1M
}
SECTIONS
{ /* Code */
.text : {
*(.text);
*(.text.*);
_bctors = . ;
*(.ctors .ctors.*)
_ectors = . ;
_bdtors = . ;
*(.dtors .dtors.*)
_edtors = . ;
} > userram
/* Read-only sections */
.rodata : {
/* Read-Only data */
*(.rodata);
*(.rodata.*);
} > userram
/* The GOT section is a bit exotic.
When I generate the PIE executable, all global variables are stored
is the *(.got) section and the __GLOBAL_OFFSET_TABLE__ object is
generated and inserted in the *(.got.plt) section.
But, neither of *(.plt*) or *(rela*) section are generated to help
me out for the "relocation" of each address stored in the GOT. The
result is that the content of the GOT is always absolute addresses,
which makes the machine crash.
So, the idea to bypass this limitation (probably due to the custom
GCC which not provide critical information for the relocation) is to
isolate the GOT in a standalone section and, after the loading of
the image, walk thought the relocalised table and manually patch
each address.
Moreover, the __GLOBAL_OFFSET_TABLE__ is used like a table, so, the
section ".got.plt" SHOULD be before the .got section. */
.got.plt : { *(.got.plt) *(.igot.plt) *(.igot) }
.got : { *(.got) }
/* readable / writable data */
.data ALIGN(4) : {
*(.data);
*(.data.*);
*(COMMON);
}
/* bss section included to avoid missaligned segment */
.bss ALIGN(4) : {
*(.bss);
*(.bss.*);
/* dynamic BSS information (move me ?) */
*(.dynbss)
} > userram
/* unwanted section */
/DISCARD/ : {
*(.rela.debug*)
*(.gnu.*)
*(.debug_info)
*(.debug_abbrev)
*(.debug_loc)
*(.debug_aranges)
*(.debug_ranges)
*(.debug_line)
*(.debug_str)
*(.debug_*)
*(.jcr)
*(.eh_frame_hdr)
*(.eh_frame)
*(.comment)
*(.interp)
}
}

View File

@ -1,8 +1,8 @@
//---
// vhex:core:hardware - Platform information and hardware detection
//---
#include "vhex/drivers/mpu/sh/sh7305/pfc.h"
#include "vhex/drivers/mmu.h"
#include "vhex/driver/mpu/sh/sh7305/pfc.h"
#include "vhex/driver/mmu.h"
#include "board/fxcg50/hardware.h"
#include "vhex/hardware.h"

View File

@ -3,15 +3,11 @@
/* hypervisor_init() : initialize the hypervisor module */
void hypervisor_init(void)
{
hyp_world_t casio = hypervisor_world_new(
"casio",
HYP_WORLD_STATUS_FLAG_UNDELETABLE
);
hyp_world_t vhex = hypervisor_world_new(
"vhex",
HYP_WORLD_STATUS_FLAG_UNDELETABLE
);
hyp_world_t casio = hypervisor_world_new("casio");
hyp_world_t vhex = hypervisor_world_new("vhex");
hypervisor_world_switch(casio, vhex);
}
/* hypervisor_quit() : quit the hypervisor module */

225
config
View File

@ -1,225 +0,0 @@
#! /bin/python3
import sys
import configparser
import os.path
import os
import shutil
help_string = f"""
usage: config [options...]
Configuration script for the Vhex unikernel. You should build out-of-tree by
creating a build directory and configuring from there.
Options:
-h,--help
display this message
--verbose
display more information during the compilation step
--format=FORMAT[,format[,...]]
select the format of the library generation. You can use two format:
<> static - generate a static library
<> dynamic - generate a dynamic library
<> all - same behaviour as "--format=static,dynamic"
By default, only "dynamic" is used.
--board[=BOARD,board[,...]]
select boards. If no board name is given, a list of all available board
will be printed.
--prefix=PATH
installation path for all generated libraries
""".strip()
#
# create and apply the arguments parser
#
def parse_arguments():
"""
The objectif of this function is to generate the "arguments object" with
all arguments passed throuth this script correctly isolated.
"""
args = {
'board' : [],
'format' : [],
'verbose': False,
'prefix': ''
}
arg_name = [
"-h",
"--help",
"--format",
"--verbose",
"--board",
"--prefix"
]
for arg in sys.argv[1:]:
info = arg.split("=")
if (info[0] in arg_name) == False:
print("%s: unreconized option '%s'" % (sys.argv[0],info[0]))
print("Try '%s --help' for more information" % sys.argv[0])
exit(84)
if (info[0] in ["-h", "--help"]) == True:
print(help_string)
exit(0)
if info[0] == "--verbose":
args["verbose"] = True
continue
if info[0] == "--prefix":
args["prefix"] = info[1]
continue
if len(info) > 1:
args[info[0][2:]] = info[1].split(",")
return args
#
# part handlers
#
def board_check(file, board_list):
boards = list(os.walk('../board'))[0][1]
archs = list(os.walk('../src/drivers/mpu'))[0][1]
if not board_list:
print('board available:')
for board in boards:
path = '../board/%s/board.ini' % board
if not os.path.exists(path):
print('board \'%s\' does not exists' % board)
continue
conf = configparser.ConfigParser()
conf.read(path)
if not ('meta' in conf) or not ('description' in conf['meta']):
print('<> %s\t\tNo description available' % board)
continue
print('<> %s\t\t%s' % (board, conf['meta']['description']))
exit(0)
valid_board_list = []
for board in board_list:
if not (board in boards):
print("board '%s' does not exist" % board)
continue
path = '../board/%s/board.ini' % board
if not os.path.exists(path):
print("board '%s' does not have INI descriptor file" % board)
continue
conf = configparser.ConfigParser()
conf.read(path)
if not ('drivers' in conf) or not ('mpu' in conf['drivers']):
print("board '%s' does not have MPU information" % board)
continue
arch = ''
mpu = conf['drivers']['mpu']
for _arch in archs:
if not os.path.exists('../src/drivers/mpu/%s/%s' % (_arch,mpu)):
continue
arch = _arch
break
if not arch:
print("board '%s': unreconized MPU '%s'" % (board,mpu))
continue
pathlist = [
'../board/%s' % board,
'../src/drivers/mpu/%s/%s' % (_arch,mpu)
]
for driver in conf['drivers']:
if driver == 'mpu':
continue
dpath = '../src/drivers/%s' % driver
if not os.path.exists(dpath):
print("board '%s': unreconized driver \'%s\'" % (board, dpath))
continue
for t in conf['drivers'][driver].split(','):
tpath = dpath + '/' + t
if not os.path.exists(tpath):
print("board '%s': unreconized driver \'%s\'" % (board, t))
continue
pathlist.append(tpath)
tpath = tpath + '/target/' + arch
if os.path.exists(tpath):
pathlist.append(tpath)
for dirent in os.listdir('../src'):
if not (dirent in ['drivers', 'arch']):
pathlist.append('../src/' + dirent)
ldflags,cflags,prefix,libs = [],[],[],[]
if 'toolchain' in conf:
if 'prefix' in conf['toolchain']:
prefix = conf['toolchain']['prefix']
if 'cflags' in conf['toolchain']:
cflags = conf['toolchain']['cflags'].split(',')
if 'libs' in conf['toolchain']:
libs = conf['toolchain']['libs'].split(',')
confstr = 'CONFIG.' + board;
file.write(
confstr + '.SRC-MODULE-PATH :=' + ' '.join(pathlist) + '\n'
+ confstr + '.TOOLCHAIN.LDFLAGS :=' + ' '.join(ldflags) + '\n'
+ confstr + '.TOOLCHAIN.CFLAGS :=' + ' '.join(cflags) + '\n'
+ confstr + '.TOOLCHAIN.PREFIX :=' + prefix + '\n'
+ confstr + '.LIBS :=' + ' '.join(libs) + '\n'
)
if not os.path.exists(board):
os.mkdir(board)
os.symlink(
'../../board/%s/%s.ld' % (board,board),
'%s/%s.ld' % (board,board)
)
valid_board_list.append(board)
file.write('CONFIG.BOARD-LIST := ' + ' '.join(valid_board_list) + '\n')
def format_check(file, format_list):
file.write('CONFIG.FORMAT-LIST :=')
for _format in format_list:
if not (_format in ["static", "dynamic", "all"]):
print("%s: unreconized format '%s'" % (sys.argv[0], _format))
exit(84)
if _format == 'all':
file.write(' dynamic static\n')
return
file.write(' ' + _format)
if not format_list:
file.write(' dynamic')
file.write('\n')
def prefix_check(file, prefix):
file.write('CONFIG.INSTALL-PREFIX :=' + prefix + '\n')
def verbose_check(file, verbose):
file.write(f"CONFIG.VERBOSE := {'true' if verbose else 'false'}\n")
#
# "real" entry of the script
#
def main():
args = parse_arguments()
if os.path.exists('../src') == False:
print('error: you should configure from a build directory, like this:')
print(' mkdir build && cd build && ../configure [options..]')
exit(84)
file = open('kernel.cfg', 'w')
board_check(file, args['board'])
format_check(file, args['format'])
prefix_check(file, args['prefix'])
verbose_check(file, args['verbose'])
if os.path.exists('Makefile'):
os.remove('Makefile')
os.symlink('../make/Makefile', 'Makefile')
main()

View File

@ -1,24 +1,38 @@
#ifndef __VHEX_DISPLAY__
# define __VHEX_DISPLAY__
//TODO: plate-form specific
enum {
/* Compatibility with fx9860g color names */
C_WHITE = 0xffff,
C_LIGHT = 0xad55,
C_DARK = 0x528a,
C_BLACK = 0x0000,
#include <vhex/defs/types.h>
#include <vhex/display/types.h>
#include <vhex/display/draw.h>
#include <vhex/display/color.h>
//#include <vhex/display/image.h>
//#include <vhex/display/text.h>
/* Other colors */
C_RED = 0xf800,
C_GREEN = 0x07e0,
C_BLUE = 0x001f,
//TODO: doc
C_NONE = -1,
C_INVERT = -2,
};
/* dclear(): Fill the screen with a single color */
extern did_t dclear(int color);
/* dupdate(): Generate the display frame on the screen */
extern void dupdate(void);
/* dwidth(): get the screen width */
extern size_t dwidth(void);
/* dheight(): get the heigth of the screen */
extern size_t dheight(void);
//---
// Text render API
//---
#if 0
/* Alignment settings for dtext_opt() and dprint_opt(). Combining a vertical
and a horizontal alignment option specifies where a given point (x,y) should
be relative to the rendered string. */
@ -42,14 +56,13 @@ extern void dtext_opt(
char const *str, int size
);
/* dpixel(): Change a pixel's color */
extern void dpixel(int x, int y, int color);
/* dupdate(): Push the video RAM to the display driver */
extern void dupdate(void);
/* dclear(): Fill the screen with a single color */
extern void dclear(int color);
/* dascii() : display one ASCII character */
extern void dascii(int x, int y, int fg, int bg, int n);
@ -78,4 +91,6 @@ extern void dhline(int x1, int x2, int y, int color);
/* dvline(): Draw vertical line */
extern void dvline(int y1, int y2, int x, int color);
#endif /* IF 0 */
#endif /*__VHEX_DISPLAY__*/

View File

@ -0,0 +1,20 @@
#ifndef __VHEX_DISPLAY_COLOR__
# define __VHEX_DISPLAY_COLOR__
//FIXME: this is plateform-specific :/
enum {
C_WHITE = 0xffff,
C_LIGHT = 0xad55,
C_DARK = 0x528a,
C_BLACK = 0x0000,
C_RED = 0xf800,
C_GREEN = 0x07e0,
C_BLUE = 0x001f,
C_NONE = -1,
C_INVERT = -2,
};
#endif /* __VHEX_DISPLAY_COLOR__ */

View File

@ -0,0 +1 @@
#include <vhex/display/draw/circle.h>

View File

@ -0,0 +1,29 @@
#ifndef __VHEX_DISPLAY_DRAW_CIRCLE__
# define __VHEX_DISPLAY_DRAW_CIRCLE__
#include <vhex/display/shader.h>
#include <vhex/display/types.h>
/* dcircle_filled() : draw a filled circle
This function will add a filled circle drawing in the internal "draw queue"
handled by vhex display core. The "draw ID" will be returned and shader can
be added to the circle afterward.
Args:
( in) x : X position (horizontal middle of the circle)
( in) y : Y position (vertical middle of the circle)
( in) size : diameter of the circle
( in) color : filled color for the circle
Return:
> the "draw ID", which can be used to apply shader afterward */
extern did_t dcircle(int x, int y, size_t size, int mode, dshader_t *list);
//TODO: shader
//TODO: doc
//TODO: mode
#endif /* __VHEX_DISPLAY_DRAW_CIRCLE__ */

View File

@ -0,0 +1,90 @@
#ifndef __VHEX_DISPLAY_SHADER__
# define __VHEX_DISPLAY_SHADER__
#include <vhex/defs/attributes.h>
#include <vhex/defs/types.h>
/* dshader_call_arg_t: All types of arguments allowed in an indirect shader call
Because a function call cannot be easily pieced together, there are
restrictions on what arguments can be passed. The following union lists all
of the available types. Other types can be used if casted, mainly pointers;
see the description of DSHADER*() for details. */
typedef union dshader_call_arg {
int8_t i8;
uint8_t u8;
int16_t i16;
uint16_t u16;
/* 32-bit integers */
int i;
unsigned int u;
int32_t i32;
uint32_t u32;
/* 32-bit floating-point */
float f;
/* Pointers to most common types, in all possible const/volatile
qualifications */
#define POINTER(type, name) \
type *name; \
type const *name ## _c; \
type volatile *name ## _v; \
type volatile const *name ## _cv;
POINTER(void, pv)
POINTER(char, pc)
POINTER(unsigned char, puc)
POINTER(short, ps)
POINTER(unsigned short, pus)
POINTER(int, pi)
POINTER(unsigned int, pui)
POINTER(int8_t, pi8)
POINTER(uint8_t, pu8)
POINTER(int16_t, pi16)
POINTER(uint16_t, pu16)
POINTER(int32_t, pi32)
POINTER(uint32_t, pu32)
POINTER(int64_t, pi64)
POINTER(uint64_t, pu64)
POINTER(long long int, pll)
POINTER(unsigned long long int, pull)
POINTER(float, pf)
POINTER(double, pd)
#undef POINTER
} dshader_call_arg_t;
/* dshader_surface - Describe the surface */
struct dshader_surface {
void *draw;
void *frag;
size_t width;
size_t height;
unsigned int x;
unsigned int y;
};
/* dshader - display shader definition */
struct dshader_call {
int (*routine)(
struct dshader_surface *surface,
dshader_call_arg_t *draw_args,
dshader_call_arg_t *shader_args
);
dshader_call_arg_t args[8];
};
typedef struct dshader_call dshader_call_t;
typedef struct dshader_call dshader_t;
/* DSHADER_LIST - helper to create a list of shader "on-the-fly" */
#define DSHADER_LIST(shader_list) (dshader_call_t*)&{ shader_list }
/* DSHADER - helper to create a shader object */
#define DSHADER(fct, ...) (dshader_call_t){ \
.routine = fct, \
.args = { __VA_ARGS__ } \
}
#endif /* __VHEX_DISPLAY_SHADER__ */

View File

@ -0,0 +1,87 @@
#ifndef __VHEX_DISPLAY_STACK__
# define __VHEX_DISPLAY_STACK__
#include <vhex/display/shader.h>
#include <vhex/display/types.h>
/* dstack_call - dstack indirect call (same as dshader) */
struct dstack_call {
int (*routine)(
struct dshader_surface *surface,
dshader_call_arg_t *draw_args
);
dshader_call_arg_t args[12];
};
typedef struct dstack_call dstack_call_t;
/* dstack_action - dstack drawing action information */
struct dstack_action {
struct dstack_call call;
struct {
dshader_call_t *table;
int number;
int idx;
} shader;
};
/* DSTACK_CALL - display indirect call */
#pragma GCC diagnostic ignored "-Wmissing-braces"
#define DSTACK_CALL(fct, ...) (dstack_call_t){ \
.routine = (void*)fct, \
.args = { __VA_ARGS__ } \
}
/* dstack_config - dstack configuration structure */
struct dstack_config {
int default_icall_pool_slot;
int default_icall_args_nb;
int default_shader_per_action;
};
#ifndef DSTACK_DEFAULT_ICALL_SLOT
# define DSTACK_DEFAULT_ICALL_SLOT 32
#endif
#ifndef DSTACK_DEFAULT_ICALL_ARGS
# define DSTACK_DEFAULT_ICALL_ARGS 12
#endif
#ifndef DSTACK_DEFAULT_SHADER_PER_ACTION
# define DSTACK_DEFAULT_SHADER_PER_ACTION 4
#endif
/* dstack_drv_interface - driver interface */
struct dstack_drv_interface {
int (*frame_start)(struct dshader_surface *);
int (*frame_frag_next)(struct dshader_surface *);
int (*frame_frag_send)(struct dshader_surface *);
int (*frame_end)(struct dshader_surface *);
};
//---
// Display stack API
//---
/* dstack_init() : Initialise the draw stack (should not be involved) */
extern int dstack_init(struct dstack_config *config);
/* dstack_add_action() : add a new action in the draw stack */
extern did_t dstack_add_action(dstack_call_t *call, dshader_call_t *shaders);
/* dstack_get_action() : get display stack action using its ID */
extern struct dstack_action *dstack_get_action(did_t did);
/* dstack_render(): render a frame */
extern void dstack_render(void);
/* dstack_invalidate() : Invalidate the draw stack (reset) */
extern int dstack_invalidate(void);
/* dstack_quit() : Uninit the draw stack */
extern int dstack_quit(void);
#endif /* __VHEX_DISPLAY_STACK__ */

View File

@ -0,0 +1,7 @@
#ifndef __VHEX_DISPLAY_TYPES__
# define __VHEX_DISPLAY_TYPES__
/* draw ID */
typedef int did_t;
#endif /* __VHEX_DISPLAY_TYPES__ */

View File

@ -1,6 +1,7 @@
#ifndef __VHEX_DRIVER__
# define __VHEX_DRIVER__
#include <vhex/defs/attributes.h>
#include <vhex/defs/types.h>
/* Device drivers */
@ -31,7 +32,8 @@ struct vhex_driver
// Standard calls
/* Initialize the hardware for the driver to work in vhex. Usually
installs interrupt handlers and configures registers. May be NULL. */
installs interrupt handlers and configures registers. Cannot be
NULL */
void (*configure)(void *state);
// Internal information
@ -40,18 +42,20 @@ struct vhex_driver
uint16_t state_size;
/* default flags for the driver */
int default_flag;
};
byte_union(flags,
uint8_t :1;
uint8_t :1;
uint8_t :1;
uint8_t DISPLAY :1;
enum {
/* Driver is used by default (will be configured) */
VHEX_DRV_USED = 0x00,
uint8_t :1;
uint8_t :1;
uint8_t SHARED :1;
uint8_t UNUSED :1;
);
/* Driver is not used by the world */
VHEX_DRV_UNUSED = 0x01,
/* Driver does not require hardware state saves during world switches */
VHEX_DRV_SHARED = 0x02,
/* module related-internal data */
void *module_data;
};

View File

@ -0,0 +1,52 @@
#ifndef __VHEX_DRIVER_SCREEN_R61524__
# define __VHEX_DRIVER_SCREEN_R61524__
#include <vhex/defs/attributes.h>
#include <vhex/defs/types.h>
/* Registers and operations */
enum {
device_code_read = 0x000,
driver_output_control = 0x001,
entry_mode = 0x003,
display_control_2 = 0x008,
low_power_control = 0x00b,
ram_address_horizontal = 0x200,
ram_address_vertical = 0x201,
write_data = 0x202,
horizontal_ram_start = 0x210,
horizontal_ram_end = 0x211,
vertical_ram_start = 0x212,
vertical_ram_end = 0x213,
};
VINLINE static void r61524_select(uint16_t reg)
{
/* Clear RS and write the register number */
*(volatile uint8_t *)0xa405013c &= ~0x10;
__asm__ volatile ("synco"::);
*(volatile uint16_t *)0xb4000000 = reg;
__asm__ volatile ("synco"::);
/* Set RS back. We don't do this in read()/write() because the display
driver is optimized for consecutive GRAM access. LCD-transfers will
be faster when executing select() followed by several calls to
write(). (Although most applications should use the DMA instead.) */
*(volatile uint8_t *)0xa405013c |= 0x10;
__asm__ volatile ("synco"::);
}
VINLINE static uint16_t r61524_read(void)
{
return *(volatile uint16_t *)0xb4000000;
}
VINLINE static void r61524_write(uint16_t data)
{
*(volatile uint16_t *)0xb4000000 = data;
}
#endif /* __VHEX_DRIVER_SCREEN_R61524__ */

View File

@ -1,10 +1,7 @@
#ifndef __VHEX_HYPERVISOR__
# define __VHEX_HYPERVISOR__
#include <stddef.h>
#include <stdint.h>
/* declare driver structure */
#include <vhex/defs/attributes.h>
#include <vhex/driver.h>
/* real Vhex world with driver bitmap and meta information for the hypervisor */
@ -12,49 +9,32 @@ struct vhex_world {
/* world driver information */
struct {
struct vhex_driver *context;
int flags;
byte_union(flags,
uint8_t :1;
uint8_t :1;
uint8_t :1;
uint8_t :1;
uint8_t :1;
uint8_t SHARED :1;
uint8_t INIT :1;
uint8_t UNUSED :1;
);
} *driver;
/* internal information used by the hypervisor */
char const * name;
uint8_t status;
};
byte_union(status,
uint8_t LOCKED :1;
uint8_t ACTIVE :1;
uint8_t :1;
uint8_t :1;
/* define world status states */
#define HYP_WORLD_STATUS_STATE_UNUSED (1 << 0)
#define HYP_WORLD_STATUS_STATE_UNINIT (1 << 1)
#define HYP_WORLD_STATUS_STATE_USED (1 << 2)
/* define world status flags */
#define HYP_WORLD_STATUS_FLAG_UNDELETABLE (1 << 0)
/* hypervisor world status helper */
#define HYP_WORLD_STATUS_SET(flags,state) \
(((flags & 0x0f) << 4) | ((state & 0x0f) << 0))
#define HYP_WORLD_STATUS_SET_STATE(status, state) \
do { \
status &= 0x0f; \
status |= (state & 0x0f) << 0; \
} while (0);
#define HYP_WORLD_STATUS_SET_FLAGS(status, flags) \
do { \
status &= 0xf0; \
status |= (state & 0x0f) << 4; \
} while (0);
/* hypervisor world status getter */
#define HYP_WORLD_STATUS_FLAGS(status) ((status & 0xf0) >> 4)
#define HYP_WORLD_STATUS_STATE(status) ((status & 0x0f) >> 0)
/* hypervisor driver status */
enum {
HYP_WORLD_DRV_UNUSED = VHEX_DRV_UNUSED,
HYP_WORLD_DRV_USED = VHEX_DRV_USED,
uint8_t :1;
uint8_t :1;
uint8_t INIT :1;
uint8_t USED :1;
);
};
/* hyp_word_t : hypervisor world ID */
@ -74,13 +54,10 @@ enum {
};
/* hypervisor_world_new() : create a new world with its name */
extern hyp_world_t hypervisor_world_new(
char const * const restrict name,
int flags
);
extern hyp_world_t hypervisor_world_new(char const * const name);
/* hypervisor_world_find() : find a world ID using its name */
extern hyp_world_t hypervisor_world_find(char const * const restrict name);
extern hyp_world_t hypervisor_world_find(char const * const name);
/* hypervisor_world_get() : get a word using its ID */
extern struct vhex_world *hypervisor_world_get(hyp_world_t id);

View File

@ -146,7 +146,7 @@ define generate-target-lib
# Because we generate rule "on-the-fly" we need to create unique variable
# definition because make is not a "scoped" language. (therefore, when a
# variable is created, it will never be destroyed until the end of the script)
t-$1-$2-build := $(VXSDK_BUILD_PREFIX)/$1/$2
t-$1-$2-build := $(VXSDK_PREFIX_BUILD)/$1/$2
# generate compilation flags
@ -163,20 +163,6 @@ t-$1-$2-gcc-header := $$(t-$1-$2-gcc-base)/include
t-$1-$2-cflags += -I../include -I.. -I$$(t-$1-$2-gcc-header)
t-$1-$2-cflags += -L../lib -L.. -L$$(t-$1-$2-gcc-base)
# generate format-specific flags
t-$1-$2-exec :=
ifeq ($2,static)
t-$1-$2-exec := $1/libvhex-$1.a
endif
ifeq ($2,dynamic)
t-$1-$2-ldflags += -shared -T $1/$1.ld
t-$1-$2-ldflags += -soname=libvhex-$1-$(VXSDK_PKG_VERSION).so
t-$1-$2-ldflags += -Map=$$(t-$1-$2-build)/map
t-$1-$2-exec := $1/libvhex-$1.so
endif
# generate file's sources list, based on the configuration step
t-$1-$2-dir := $$(foreach module,$$(CONFIG.$1.SRC-MODULE-PATH),\
@ -186,6 +172,20 @@ t-$1-$2-src := $$(foreach path,$$(t-$1-$2-dir),\
$$(wildcard $$(path)/*.S) \
$$(wildcard $$(path)/*.s))
# generate format-specific flags
t-$1-$2-exec :=
ifeq ($2,static)
t-$1-$2-exec := $1/libvhex-$1.a
endif
ifeq ($2,dynamic)
t-$1-$2-ldflags += -shared
t-$1-$2-ldflags += -soname=libvhex-$1-$(VXSDK_PKG_VERSION).so
t-$1-$2-ldflags += -Map=$$(t-$1-$2-build)/map
t-$1-$2-exec := $1/libvhex-$1.so
t-$1-$2-src := $(wildcard ../fake/*.c)
endif
# generate file's compilation rules and all object filename into an object
# list variable, this will be used by the `main` rule
@ -208,7 +208,7 @@ $$(t-$1-$2-exec): $$(t-$1-$2-obj)
@ mkdir -p $$(dir $$@)
@ printf "$(blue)Create the library $(red)$$@$(nocolor)\n"
ifeq ($2,dynamic)
$$(t-$1-$2-gcc) -shared $$(t-$1-$2-gcc-libs) -o $$@ $$^
$$(t-$1-$2-gcc) -shared $$(t-$1-$2-cflags) $$(t-$1-$2-gcc-libs) -o $$@ $$^
else
$$(t-$1-$2-ar) crs $$@ $$^
endif
@ -252,12 +252,12 @@ define generate-install-rule
# Generate the installation rule
$(basename $(notdir $1))-install:
install -d $(VXSDK_LIB_PREFIX)
install $1 -m 644 $(VXSDK_LIB_PREFIX)
install -d $(VXSDK_PREFIX_LIB)
install $1 -m 644 $(VXSDK_PREFIX_LIB)
# Generate the uninstallation rule
$(basename $(notdir $1))-uninstall:
rm -f $(VXSDK_LIB_PREFIX)/$(notdir $1)
rm -f $(VXSDK_PREFIX_LIB)/$(notdir $1)
# Register generated rules into their appropriate list
$2 += $(basename $(notdir $1))-install
@ -272,11 +272,12 @@ endef
define generate-board-install-rule
$1-install:
install -d $(VXSDK_LIB_PREFIX)
install ../board/$(strip $1)/$(strip $1).ld -m 644 $(VXSDK_LIB_PREFIX)
install -d $(VXSDK_PREFIX_LIB)
install ../board/$(strip $1)/*.ld -m 644 $(VXSDK_PREFIX_LIB)
$1-uninstall:
rm -f $(VXSDK_LIB_PREFIX)/$(strip $1).ld
rm -f $(VXSDK_PREFIX_LIB)/$(strip $1).ld
rm -f $(VXSDK_PREFIX_LIB)/$(strip $1)-dynamic.ld
$2 += $1-install
$3 += $1-uninstall
@ -303,7 +304,7 @@ $(foreach board,$(CONFIG.BOARD-LIST),$(eval \
))
# Generate the path where include directory will be installed.
target-install-hdr-dir := $(VXSDK_LIB_PREFIX)/include/
target-install-hdr-dir := $(VXSDK_PREFIX_LIB)/include/
ifeq ($(wildcard $(target-install-header-dir)vhex/.*),)
target-install-hdr-dir := $(target-install-hdr-dir)vhex
endif
@ -314,10 +315,11 @@ endif
# Installation rules
#---
install: $(target-install-rules)
mkdir -p $(dir $(target-install-hdr-dir))
cp -r ../include/vhex $(target-install-hdr-dir)
unsintall: $(target-uninstall_rules)
rm -rf $(VXSDK_LIB_PREFIX)/include/vhex
rm -rf $(VXSDK_PREFIX_LIB)/include/vhex
.PHONY: install uninstall

View File

@ -1,5 +1,5 @@
#include <vhex/drivers/cpu.h>
#include <vhex/drivers/mpu/sh/sh7305/cpu.h>
#include <vhex/driver/cpu.h>
#include <vhex/driver/mpu/sh/sh7305/cpu.h>
/* Value of IMASK when atomic mode is entered */
static int saved_IMASK = 0;

View File

@ -1,5 +1,5 @@
#include "vhex/driver.h"
#include "vhex/drivers/mpu/sh/sh7305/cpu.h"
#include <vhex/driver.h>
#include <vhex/driver/mpu/sh/sh7305/cpu.h>
#include <string.h>
@ -32,12 +32,12 @@ static void __cpu_configure(struct cpu_ctx *state)
/* configure the Status Register
<> force the privileged mode
<> enable DSP
<> allow interruptions */
<> mask interruptions (it will be unmasked in <hypervisor/switch>)*/
state->sr.MD = 1;
state->sr.RB = 0;
state->sr.BL = 0;
state->sr.DSP = 1;
state->sr.IMASK = 0b0000;
state->sr.IMASK = 0b1111;
}
/* hardware hypervisor call */
@ -67,4 +67,4 @@ struct vhex_driver drv_cpu = {
.configure = (void*)&__cpu_configure,
.state_size = sizeof(struct cpu_ctx)
};
VHEX_DECLARE_DRIVER(16, drv_cpu);
VHEX_DECLARE_DRIVER(02, drv_cpu);

View File

@ -1,4 +1,4 @@
#include <vhex/drivers/mpu/sh/sh7305/intc.h>
#include <vhex/driver/mpu/sh/sh7305/intc.h>
#include <vhex/defs/types.h>
#include <string.h>

View File

@ -1,5 +1,5 @@
#include "vhex/driver.h"
#include "vhex/drivers/mpu/sh/sh7305/intc.h"
#include <vhex/driver.h>
#include <vhex/driver/mpu/sh/sh7305/intc.h>
#include <string.h>

View File

@ -1,6 +1,6 @@
#include <vhex/keyboard.h>
#include <vhex/drivers/mpu/sh/sh7305/keysc.h>
#include <vhex/drivers/mpu/sh/sh7305/intc.h>
#include <vhex/driver/mpu/sh/sh7305/keysc.h>
#include <vhex/driver/mpu/sh/sh7305/intc.h>
/* Internal indicator used by high-level function to notice when the key list
is updated */

View File

@ -1,6 +1,6 @@
#include "vhex/drivers/mpu/sh/sh7305/keysc.h"
#include "vhex/drivers/mpu/sh/sh7305/intc.h"
#include "vhex/driver.h"
#include <vhex/driver/mpu/sh/sh7305/keysc.h>
#include <vhex/driver/mpu/sh/sh7305/intc.h>
#include <vhex/driver.h>
/* define the private KeyScan context structure */
struct keysc_ctx {

View File

@ -1,8 +1,8 @@
//---
// vhex:mmu:mmu - MMU driver definition and context management
//---
#include <vhex/drivers/mmu.h>
#include <vhex/drivers/mpu/sh/sh7305/mmu.h>
#include <vhex/driver/mmu.h>
#include <vhex/driver/mpu/sh/sh7305/mmu.h>
#include <vhex/defs/attributes.h>
/* utlb_addr() - get the P4 address of a UTLB address entry */

View File

@ -1,15 +1,167 @@
#if 0
#include <vhex/defs/types.h>
#include <vhex/driver.h>
#include <vhex/driver/screen/r61524.h>
#include <vhex/display/stack.h>
//---
// R61524 driver API
//---
/* r61524_clear_surface() - optimal way to clear the draw and render surface */
VINLINE void r61524_clear_surface(struct dshader_surface *surface)
{
//TODO: check cache behaviour:
// > full xram then yram
// > xram and yram
// > yram and xram
// > restrict / non-restrict
uint32_t * restrict xram = surface->draw;
uint32_t * restrict yram = surface->frag;
for (int i = 0; i < 2048; ++i) {
xram[i] = 0x00010001;
yram[i] = 0x00000000;
}
}
/* r61524_frame_start() - prepar the screen and reset surfaces */
int r61524_frame_start(struct dshader_surface *surface)
{
/* Set the windows size */
r61524_select(horizontal_ram_start);
r61524_write(0);
r61524_select(horizontal_ram_end);
r61524_write(395);
r61524_select(vertical_ram_start);
r61524_write(0);
r61524_select(vertical_ram_end);
r61524_write(223);
/* Set the RAM position */
r61524_select(ram_address_horizontal);
r61524_write(0);
r61524_select(ram_address_vertical);
r61524_write(0);
/* Bind address 0xb4000000 to the data write command */
r61524_select(write_data);
/* initialize surface information */
surface->draw = (void*)0xe5007000;
surface->frag = (void*)0xe5017000;
surface->width = 396;
surface->height = 10;
surface->x = 0;
surface->y = 0;
/* reset the two surfaces */
r61524_clear_surface(surface);
return (0);
}
int r61524_frame_frag_next(struct dshader_surface *surface)
{
surface->y += 10;
if (surface->y >= 224) {
surface->y -= 10;
return (-1);
}
r61524_clear_surface(surface);
return (0);
}
int r61524_frame_frag_send(struct dshader_surface *surface)
{
//TODO: assembly
//TODO: check cache behaviour:
// > full xram then yram
// > xram and yram
// > yram and xram
// > restrict / non-restrict
uint16_t pixel;
uint16_t * restrict xram = surface->draw;
uint16_t * restrict yram = surface->frag;
for (int i = 0; i < 4096; ++i) {
pixel = xram[i];
if (pixel & 0x0001) {
r61524_write(yram[i]);
continue;
}
r61524_write((pixel & 0xffc0) | ((pixel & 0x003e) >> 1));
}
return (0);
}
int r61524_frame_end(struct dshader_surface *surface)
{
(void)surface;
return (0);
}
//---
// Driver definition
//---
/* R61524 display (graphics RAM range) */
struct r61524_ctx {
uint16_t HSA;
uint16_t HEA;
uint16_t VSA;
uint16_t VEA;
};
static void __r61524_configure(struct r61524_ctx *s)
{
s->HSA = 0;
s->HEA = 395;
s->VSA = 0;
s->VEA = 223;
}
static void __r61524_hsave(struct r61524_ctx *s)
{
r61524_select(horizontal_ram_start);
s->HSA = r61524_read();
r61524_select(horizontal_ram_end);
s->HEA = r61524_read();
r61524_select(vertical_ram_start);
s->VSA = r61524_read();
r61524_select(vertical_ram_end);
s->VEA = r61524_read();
}
static void __r61524_hrestore(struct r61524_ctx const *s)
{
r61524_select(horizontal_ram_start);
r61524_write(s->HSA);
r61524_select(horizontal_ram_end);
r61524_write(s->HEA);
r61524_select(vertical_ram_start);
r61524_write(s->VSA);
r61524_select(vertical_ram_end);
r61524_write(s->VEA);
}
/* declare the CPU driver */
static struct dstack_drv_interface drv_r61524_dstack = {
.frame_start = &r61524_frame_start,
.frame_frag_next = &r61524_frame_frag_next,
.frame_frag_send = &r61524_frame_frag_send,
.frame_end = &r61524_frame_end
};
struct vhex_driver drv_r61524 = {
.name = "R61524",
.hsave = (void*)&__r61524_hsave,
.hrestore = (void*)&__r61524_hrestore,
.configure = (void*)&__r61524_configure,
.state_size = sizeof(struct r61524_ctx)
.state_size = sizeof(struct r61524_ctx),
.flags = {
.DISPLAY = 1,
.SHARED = 0,
.UNUSED = 0,
},
.module_data = &drv_r61524_dstack
};
VHEX_DECLARE_DRIVER(16, drv_r61524);
#endif

View File

@ -4,6 +4,7 @@
//TODO: add relocation information
void vhex_kernel_exch_panic(void)
{
#if 0
extern uint16_t vhex_vram[];
uint32_t PC;
uint32_t TEA;
@ -50,6 +51,7 @@ void vhex_kernel_exch_panic(void)
dtext(6, 108, C_BLACK, "Please press the RESET button to restart the");
dtext(6, 121, C_BLACK, "calculator.");
dupdate();
#endif
while (1) { __asm__ volatile ("sleep"); }
}

View File

@ -1,13 +1,24 @@
#include <vhex/display.h>
#include <vhex/defs/attributes.h>
#include <vhex/defs/types.h>
#include <vhex/display.h>
#include <vhex/display/stack.h>
/* expose Video RAM */
extern uint16_t vhex_vram[];
/* dclear_draw() : real drawing algorithm */
static void dclear_draw(
struct dshader_surface *surface,
dshader_call_arg_t *arg
)
{
uint32_t * restrict vram;
uint32_t color;
vram = surface->frag;
color = arg[0].u16 & 0xffff;
for (int i = 0; i < 2048; ++i)
vram[i] = (color << 16) | (color << 0);
}
/* dclear(): Fill the screen with a single color */
VWEAK void dclear(int color)
did_t dclear(int color)
{
for (int i = 0; i < 396 * 224 ; ++i)
vhex_vram[i] = color;
return dstack_add_action(&DSTACK_CALL(&dclear_draw, color), NULL);
}

View File

@ -1,4 +1,4 @@
#include "vhex/display.h"
#include "vhex/display/stack.h"
#include "vhex/module.h"
/* module init */
@ -6,13 +6,18 @@
/* __display_init() : initialize the display */
static void __display_init(void)
{
/* Nothing to do here ? */
struct dstack_config conf = {
.default_icall_pool_slot = DSTACK_DEFAULT_ICALL_SLOT,
.default_icall_args_nb = DSTACK_DEFAULT_ICALL_ARGS,
.default_shader_per_action = DSTACK_DEFAULT_SHADER_PER_ACTION
};
dstack_init(&conf);
}
/* __display_quit() : uninit the display */
static void __display_quit(void)
{
/* Nothing to do here ? */
dstack_quit();
}
/* declare the display module */

View File

@ -0,0 +1,148 @@
#include <vhex/display/stack.h>
#include <vhex/display/shader.h>
#include <vhex/driver.h>
#include <stdlib.h>
#include <string.h>
static struct {
struct {
struct dstack_action *action;
int slots;
int idx;
} pool;
struct dstack_drv_interface driver;
} dstack_info = {
.pool = {
.action = NULL,
.slots = 0,
.idx = 0
},
.driver = {
.frame_start = NULL,
.frame_frag_next = NULL,
.frame_frag_send = NULL,
.frame_end = NULL,
}
};
//
// Kernel API
//
/* dstack_init() : Initialise the draw stack (should not be involved) */
//TODO: safe
int dstack_init(struct dstack_config *config)
{
dstack_info.pool.action = calloc(
config->default_icall_pool_slot,
sizeof(dstack_call_t)
);
dstack_info.pool.slots = config->default_icall_pool_slot;
dstack_info.pool.idx = -1;
for (int i = 0; i < dstack_info.pool.slots; ++i) {
dstack_info.pool.action[i].shader.table = malloc(
config->default_shader_per_action
);
dstack_info.pool.action[i].shader.number =
config->default_shader_per_action;
dstack_info.pool.action[i].shader.idx = 0;
}
struct vhex_driver *driver = vhex_driver_table();
for (int i = 0; i < vhex_driver_count(); ++i) {
if (driver[i].flags.DISPLAY) {
memcpy(
&dstack_info.driver,
driver[i].module_data,
sizeof(struct dstack_drv_interface)
);
break;
}
}
}
/* dstack_quit() : Uninit the draw stack */
int dstack_quit(void)
{
for (int i = 0; i < dstack_info.pool.slots; ++i) {
free(dstack_info.pool.action[i].shader.table);
dstack_info.pool.action[i].shader.number = 0;
dstack_info.pool.action[i].shader.idx = 0;
}
}
//
// Internal API
//
static did_t dstack_action_alloc(dstack_call_t *call, dshader_call_t *shader)
{
struct dstack_action *action;
int i;
dstack_info.pool.idx += 1;
if (dstack_info.pool.idx >= dstack_info.pool.slots) {
dstack_info.pool.slots += dstack_info.pool.slots;
dstack_info.pool.action = realloc(
dstack_info.pool.action,
dstack_info.pool.slots
);
}
action = &dstack_info.pool.action[dstack_info.pool.idx];
memcpy(&action->call, call, sizeof(dstack_call_t));
if (shader != NULL) {
for (i = 0; shader[i].routine != NULL; ++i) {
if (i >= action->shader.number) {
action->shader.number += action->shader.number;
action->shader.table = realloc(
action->shader.table,
action->shader.number
);
}
memcpy(
&action->shader.table[i],
&shader[i],
sizeof(dshader_call_t)
);
}
}
action->shader.idx = i;
return dstack_info.pool.idx;
}
//
// Public API
//
/* dstack_add_action() : add a new action in the draw stack */
did_t dstack_add_action(dstack_call_t *call, dshader_call_t *shader)
{
return dstack_action_alloc(call, shader);
}
/* dstack_render(): render a frame */
void dstack_render(void)
{
struct dshader_surface surface;
struct dstack_action *action;
action = dstack_info.pool.action;
dstack_info.driver.frame_start(&surface);
do {
for (int i = 0; i <= dstack_info.pool.idx; ++i) {
action[i].call.routine(&surface, action[i].call.args);
for (int j = 0; j < action[i].shader.idx; j++) {
action[i].shader.table[j].routine(
&surface,
action[i].call.args,
action[i].shader.table[i].args
);
}
}
dstack_info.driver.frame_frag_send(&surface);
} while (dstack_info.driver.frame_frag_next(&surface) == 0);
dstack_info.driver.frame_end(&surface);
dstack_info.pool.idx = 0;
}

View File

@ -1,76 +1,8 @@
#include "vhex/display.h"
#include "vhex/defs/attributes.h"
#include "vhex/defs/types.h"
/* Registers and operations */
enum {
device_code_read = 0x000,
driver_output_control = 0x001,
entry_mode = 0x003,
display_control_2 = 0x008,
low_power_control = 0x00b,
ram_address_horizontal = 0x200,
ram_address_vertical = 0x201,
write_data = 0x202,
horizontal_ram_start = 0x210,
horizontal_ram_end = 0x211,
vertical_ram_start = 0x212,
vertical_ram_end = 0x213,
};
/* Interface with the controller */
static volatile uint16_t *intf = (void *)0xb4000000;
/* Bit 4 of Port R controls the RS bit of the display driver */
static volatile uint8_t *PRDR = (void *)0xa405013c;
static void select(uint16_t reg)
{
/* Clear RS and write the register number */
*PRDR &= ~0x10;
__asm__ volatile ("synco"::);
*intf = reg;
__asm__ volatile ("synco"::);
/* Set RS back. We don't do this in read()/write() because the display
driver is optimized for consecutive GRAM access. LCD-transfers will
be faster when executing select() followed by several calls to
write(). (Although most applications should use the DMA instead.) */
*PRDR |= 0x10;
__asm__ volatile ("synco"::);
}
static void write(uint16_t data)
{
*intf = data;
}
#include "vhex/display/stack.h"
/* dupdate(): Push the video RAM to the display driver */
VWEAK void dupdate(void)
void dupdate(void)
{
extern uint16_t vhex_vram[];
/* Set the windows size */
select(horizontal_ram_start);
write(0);
select(horizontal_ram_end);
write(395);
select(vertical_ram_start);
write(0);
select(vertical_ram_end);
write(223);
/* Set the RAM position */
select(ram_address_horizontal);
write(0);
select(ram_address_vertical);
write(0);
/* Bind address 0xb4000000 to the data write command */
select(write_data);
/* force-fill manualy the screen */
for (int i = 0; i < 396 * 224; ++i)
write(vhex_vram[i]);
dstack_render();
}

View File

@ -1,3 +1,4 @@
#if 0
#include "vhex/display.h"
#include "vhex/defs/types.h"
@ -38,3 +39,4 @@ void dascii(int x, int y, int fg, int bg, int n)
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if 0
#include "vhex/display.h"
#include "vhex/defs/types.h"
@ -55,3 +56,4 @@ void dprint(int x, int y, int fg, char const * const text, ...)
dtext_opt(x, y, fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, buff, -1);
}
#endif

View File

@ -1,3 +1,4 @@
#if 0
#include <vhex/display.h>
#include <vhex/defs/types.h>
@ -28,3 +29,4 @@ void dnsize(char const *str, int n, int *w, int *h)
if (w != NULL) *w = strnlen(str, n) * (font8x9.width + 1);
if (h != NULL) *h = font8x9.height;
}
#endif

View File

@ -1,6 +1,5 @@
#include <vhex/hypervisor.h>
#include <vhex/drivers/cpu.h>
#include <vhex/driver/cpu.h>
#include <vhex/display.h>
/* hypervisor_world_switch() : perform a world switch */
@ -11,7 +10,6 @@ int hypervisor_world_switch(hyp_world_t out, hyp_world_t in)
struct vhex_world *wout;
struct vhex_driver *dtable;
wout = hypervisor_world_get(out);
win = hypervisor_world_get(in);
if (wout == NULL || win == NULL)
@ -24,29 +22,33 @@ int hypervisor_world_switch(hyp_world_t out, hyp_world_t in)
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;
wout->driver[i].flags.UNUSED = 1;
continue;
}
dtable[i].hsave(wout->driver[i].context);
wout->driver[i].flags = HYP_WORLD_DRV_USED;
wout->driver[i].flags.UNUSED = 0;
}
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->status.INIT == 0) {
dtable[i].configure(win->driver[i].context);
win->driver[i].flags.UNUSED = dtable[i].flags.UNUSED;
win->driver[i].flags.SHARED = dtable[i].flags.SHARED;
}
if (win->driver[i].flags == HYP_WORLD_DRV_UNUSED) {
//FIXME : check shared driver
if (win->driver[i].flags.UNUSED == 1) {
if (dtable[i].hpowered() == true)
dtable[i].hpoweroff();
continue;
}
//FIXME : check if the driver is unused
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);
win->status.INIT = 1;
win->status.ACTIVE = 1;
wout->status.ACTIVE = 0;
wout->status.INIT = 1;
cpu_atomic_end();
}

View File

@ -8,68 +8,73 @@
/* internal world table */
static struct {
struct vhex_world *table;
size_t table_slot;
struct {
struct vhex_world *table;
int number;
} world;
} hyp = {
.table = NULL,
.table_slot = 0
.world = {
.table = NULL,
.number = 0
}
};
/* hypervisor_world_new() : create a new world with its name */
hyp_world_t hypervisor_world_new(char const * const restrict name, int flags)
hyp_world_t hypervisor_world_new(char const * const restrict name)
{
struct vhex_driver *dtable;
hyp_world_t id;
/* try to find free world */
id = 0xb0cad0;
if (hyp.table != NULL) {
for (size_t i = 0; i < hyp.table_slot; ++i) {
if (HYP_WORLD_STATUS_STATE(hyp.table[i].status)
== HYP_WORLD_STATUS_STATE_UNUSED) {
id = i;
continue;
}
if (strcmp(hyp.table[i].name, name) == 0)
return (hyp_world_already_exists);
id = -1;
for (int i = 0; i < hyp.world.number; ++i) {
if (hyp.world.table[i].status.USED == 0) {
id = i;
continue;
}
if (strcmp(hyp.world.table[i].name, name) == 0)
return (hyp_world_already_exists);
}
/* if no world is found, update the table */
if (id == 0xb0cad0) {
id = hyp.table_slot;
if (id == -1) {
id = hyp.world.number;
if (hyp.table_slot == 0)
hyp.table_slot = 1;
hyp.world.number += hyp.world.number;
if (hyp.world.number == 0)
hyp.world.number = 2;
hyp.table = reallocarray(
hyp.table,
hyp.table_slot * 2,
hyp.world.table = reallocarray(
hyp.world.table,
hyp.world.number,
sizeof(struct vhex_world)
);
for (size_t i = hyp.table_slot; i < hyp.table_slot * 2; ++i) {
hyp.table[i].status = HYP_WORLD_STATUS_STATE_UNUSED;
hyp.table[i].driver = NULL;
hyp.table[i].name = NULL;
}
hyp.table_slot = hyp.table_slot * 2;
for (int i = id; i < hyp.world.number; ++i) {
hyp.world.table[i].driver = NULL;
hyp.world.table[i].name = NULL;
hyp.world.table[id].status.LOCKED = 0;
hyp.world.table[id].status.ACTIVE = 0;
hyp.world.table[id].status.INIT = 0;
hyp.world.table[id].status.USED = 0;
}
}
/* initialize the world */
hyp.table[id].name = strdup(name);
hyp.table[id].status = HYP_WORLD_STATUS_SET(
flags,
HYP_WORLD_STATUS_STATE_UNINIT
);
if (hyp.table[id].driver == NULL) {
hyp.table[id].driver = malloc(
vhex_driver_count() * sizeof(*hyp.table[id].driver)
hyp.world.table[id].name = strdup(name);
hyp.world.table[id].status.LOCKED = 0;
hyp.world.table[id].status.ACTIVE = 0;
hyp.world.table[id].status.INIT = 0;
hyp.world.table[id].status.USED = 1;
if (hyp.world.table[id].driver == NULL) {
hyp.world.table[id].driver = calloc(
vhex_driver_count(),
sizeof(*hyp.world.table[id].driver)
);
dtable = vhex_driver_table();
for (int i = 0; i < vhex_driver_count(); ++i) {
hyp.table[id].driver[i].context = malloc(
hyp.world.table[id].driver[i].context = malloc(
dtable[i].state_size
);
}
@ -82,9 +87,9 @@ hyp_world_t hypervisor_world_new(char const * const restrict name, int flags)
/* hypervisor_world_find() : find a world using its name */
hyp_world_t hypervisor_world_find(char const * const restrict name)
{
if (hyp.table != NULL) {
for (size_t i = 0; i < hyp.table_slot; ++i) {
if (strcmp(hyp.table[i].name, name) == 0)
if (hyp.world.table != NULL) {
for (int i = 0; i < hyp.world.number; ++i) {
if (strcmp(hyp.world.table[i].name, name) == 0)
return (i);
}
}
@ -94,26 +99,23 @@ hyp_world_t hypervisor_world_find(char const * const restrict name)
/* hypervisor_world_get() : get a word using its ID */
struct vhex_world *hypervisor_world_get(hyp_world_t id)
{
if (id < 0 || (size_t)id >= hyp.table_slot)
if (id < 0 || id >= hyp.world.number)
return (NULL);
if (HYP_WORLD_STATUS_STATE(hyp.table[id].status)
== HYP_WORLD_STATUS_STATE_UNUSED) {
if (hyp.world.table[id].status.USED == 0) {
return (NULL);
}
return (&hyp.table[id]);
return (&hyp.world.table[id]);
}
/* hypervisor_world_delete() : remove world */
hyp_world_t hypervisor_world_delete(hyp_world_t id)
{
if (id < 0 || (size_t)id >= hyp.table_slot)
if (id < 0 || id >= hyp.world.number)
return (hyp_world_bad_id);
if (HYP_WORLD_STATUS_FLAGS(hyp.table[id].status)
== HYP_WORLD_STATUS_FLAG_UNDELETABLE) {
if (hyp.world.table[id].status.LOCKED == 1)
return (hyp_world_undeletable);
}
hyp.table[id].status = HYP_WORLD_STATUS_STATE_UNUSED;
hyp.world.table[id].status.USED = 0;
}

View File

@ -1,5 +1,5 @@
#include "vhex/keyboard.h"
#include "vhex/module.h"
#include <vhex/keyboard.h>
#include <vhex/module.h>
/* module init */
@ -23,4 +23,4 @@ struct vhex_module mod_keyboard = {
.init = &__keyboard_init,
.quit = &__keyboard_quit,
};
VHEX_DECLARE_MODULE(03, mod_keyboard);
VHEX_DECLARE_MODULE(04, mod_keyboard);

View File

@ -1,5 +1,5 @@
#include <vhex/keyboard.h>
#include <vhex/drivers/cpu.h>
#include <vhex/driver/cpu.h>
/* Internal cache, used like chained list.
@note:

View File

@ -1,9 +1,13 @@
[package]
[project]
name = 'vxkernel'
version = '0.5.0'
[build]
configure = 'mkdir -p build && cd build && ../config --board=fxcg50 --format=static --verbose'
configure = 'mkdir -p build && cd build && ../configure --board=fxcg50'
build = 'cd build && make'
install = 'cd build && make install'
uninstall = 'cd build && make uninstall'
[dependencies]
sh-elf-vhex = 'master'