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:
parent
f851b73cba
commit
a916120d66
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
225
config
|
@ -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()
|
|
@ -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__*/
|
||||
|
|
|
@ -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__ */
|
|
@ -0,0 +1 @@
|
|||
#include <vhex/display/draw/circle.h>
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __VHEX_DISPLAY_TYPES__
|
||||
# define __VHEX_DISPLAY_TYPES__
|
||||
|
||||
/* draw ID */
|
||||
typedef int did_t;
|
||||
|
||||
#endif /* __VHEX_DISPLAY_TYPES__ */
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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__ */
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"); }
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
Loading…
Reference in New Issue