Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
67d32d9f4a | |||
b8269949ed | |||
4068524e00 | |||
78db00fef9 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -51,3 +51,4 @@ apps/loader
|
||||
apps/asciivju
|
||||
apps/justawindow
|
||||
runtests
|
||||
cov_t*.*
|
||||
|
9
README
9
README
@@ -103,6 +103,11 @@ Testing
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
# Build
|
||||
|
||||
Install toolchain for the 32-bit target, e.g. gcc-multilib, lib32-glibc,
|
||||
32-bit and develop packages of libfuse and libsdl2, fasm.
|
||||
|
||||
# umka_os
|
||||
|
||||
To create tap devices.
|
||||
@@ -117,6 +122,10 @@ Allow reading process_vm_readv syscall.
|
||||
|
||||
# sysctl -w kernel.yama.ptrace_scope=0
|
||||
|
||||
Insert msr linux kernel module to collect coverage.
|
||||
|
||||
# modprobe msr
|
||||
|
||||
|
||||
Links & Acknowledgements
|
||||
------------------------
|
||||
|
13
TODO
13
TODO
@@ -1,9 +1,10 @@
|
||||
make mkfs.* use config files (-c for mkfs.xfs)
|
||||
export and initialize mouse_delay and mouse_speed_factor (test and cover func mouse_acceleration)
|
||||
lsstat to decrease tests size
|
||||
separate dirs for each image and test
|
||||
separate dirs for each image
|
||||
include umka_os to tests
|
||||
tests with writing to block devices (read-only base image + discardable image for writing)
|
||||
library loader
|
||||
custom test runner
|
||||
make mkfs.xfs use config file via -c option
|
||||
writing tests
|
||||
compare with reference XFS implementation
|
||||
stressing via ref impl
|
||||
validate against the reference XFS implementation
|
||||
stressing via ref impl (how?)
|
||||
multithreaded: kofu one.t two.t
|
||||
|
66
img/gen.sh
66
img/gen.sh
@@ -30,7 +30,13 @@ gpt_large.qcow2 () {
|
||||
local img=$FUNCNAME
|
||||
qemu-img create -f qcow2 -o $QCOW2_OPTS,cluster_size=2097152 $img 2E > /dev/null
|
||||
sudo qemu-nbd -c $NBD_DEV $img
|
||||
|
||||
sleep 1
|
||||
# This is weird but the sleep above prevents the following error of the
|
||||
# sgdisk below. A better understanding and fix is needed.
|
||||
# Problem reading disk in BasicMBRData::ReadMBRData()!
|
||||
# Warning! Read error 22; strange behavior now likely!
|
||||
# Caution! Secondary header was placed beyond the disk's limits! Moving the
|
||||
# header, but other problems may occur!
|
||||
$SGDISK --clear --new=0:0:+1023MiB --new=0:0:+1023GiB --new=0:0:+1023TiB \
|
||||
--new=0:0:+1023PiB $NBD_DEV > /dev/null
|
||||
|
||||
@@ -427,6 +433,7 @@ xfs_v4_xattr.qcow2 () {
|
||||
}
|
||||
|
||||
xfs_v4_btrees_l2.qcow2 () {
|
||||
echo "[*] This can take about ten minutes"
|
||||
local img=$FUNCNAME
|
||||
local img_raw=$(basename $img .qcow2).raw
|
||||
|
||||
@@ -719,7 +726,7 @@ fat32_test0.raw () {
|
||||
sudo mount -o codepage=866,iocharset=utf8,umask=111,dmask=000 $p1 $TEMP_DIR
|
||||
|
||||
$RANDDIR $TEMP_DIR 1000 8 255 65536
|
||||
$DIRTOTEST $TEMP_DIR $img hd0 > "../test/045/run.us"
|
||||
$DIRTOTEST $TEMP_DIR $img hd0 > "../test/t045/run.us"
|
||||
|
||||
# tree $TEMP_DIR
|
||||
# du -sh $TEMP_DIR
|
||||
@@ -841,6 +848,7 @@ exfat_s05k_c8k_b8k.qcow2 () {
|
||||
}
|
||||
|
||||
xfs_samehash_s05k.raw () {
|
||||
echo "[*] This can take about one hour"
|
||||
local img=$FUNCNAME
|
||||
# local img_raw=$(basename $img .qcow2).raw
|
||||
local img_raw=$img
|
||||
@@ -888,7 +896,7 @@ ext2_s05k.qcow2 () {
|
||||
local p1="$LOOP_DEV"p1
|
||||
|
||||
$MKFS_EXT2 $EXT_MKFS_OPTS -N 1200000 $p1
|
||||
debugfs -w -R "set_super_value hash_seed $EXT_HASH_SEED" $p1 > /dev/null
|
||||
debugfs -w -R "set_super_value hash_seed $EXT_HASH_SEED" $p1
|
||||
sudo mount $p1 $TEMP_DIR
|
||||
sudo chown $USER $TEMP_DIR -R
|
||||
#
|
||||
@@ -918,6 +926,7 @@ ext2_s05k.qcow2 () {
|
||||
}
|
||||
|
||||
ext4_s05k.qcow2 () {
|
||||
echo "[*] This can take about ten minutes"
|
||||
local img=$FUNCNAME
|
||||
local img_raw=$(basename $img .qcow2).raw
|
||||
|
||||
@@ -927,7 +936,7 @@ ext4_s05k.qcow2 () {
|
||||
local p1="$LOOP_DEV"p1
|
||||
|
||||
$MKFS_EXT4 $EXT_MKFS_OPTS -N 1200000 $p1
|
||||
debugfs -w -R "set_super_value hash_seed $EXT_HASH_SEED" $p1 > /dev/null
|
||||
debugfs -w -R "set_super_value hash_seed $EXT_HASH_SEED" $p1
|
||||
sudo mount $p1 $TEMP_DIR
|
||||
sudo chown $USER $TEMP_DIR -R
|
||||
#
|
||||
@@ -1030,6 +1039,53 @@ fat16_s05k.qcow2 () {
|
||||
rm $img_raw
|
||||
}
|
||||
|
||||
iso9660_s2k_dir_all.qcow2 () {
|
||||
echo "[*] This can take about thirty minutes"
|
||||
local img=$FUNCNAME
|
||||
local img_raw=$(basename $img .qcow2).raw
|
||||
|
||||
sudo chown $USER $TEMP_DIR -R
|
||||
|
||||
mkdir $TEMP_DIR/dir_ls_a
|
||||
|
||||
mkdir $TEMP_DIR/dir_ls_b
|
||||
$MKDIRRANGE $TEMP_DIR/dir_ls_b 0 3 0 2
|
||||
|
||||
mkdir $TEMP_DIR/dir_ls_c
|
||||
$MKDIRRANGE $TEMP_DIR/dir_ls_c 0 5 201 43
|
||||
|
||||
mkdir $TEMP_DIR/dir_ls_d
|
||||
$MKDIRRANGE $TEMP_DIR/dir_ls_d 0 50 201 43
|
||||
|
||||
mkdir $TEMP_DIR/dir_ls_e
|
||||
$MKDIRRANGE $TEMP_DIR/dir_ls_e 0 1000 201 43
|
||||
|
||||
mkdir $TEMP_DIR/dir_ls_f
|
||||
$MKDIRRANGE $TEMP_DIR/dir_ls_f 0 5000 231 13
|
||||
|
||||
mkdir $TEMP_DIR/dir_ls_g
|
||||
$MKDIRRANGE $TEMP_DIR/dir_ls_g 0 46656 231 13
|
||||
|
||||
mkdir $TEMP_DIR/dir_stat_a
|
||||
|
||||
mkdir $TEMP_DIR/dir_stat_b
|
||||
$MKDOUBLEDIRS $TEMP_DIR/dir_stat_b d 3
|
||||
|
||||
mkdir $TEMP_DIR/dir_stat_c
|
||||
$MKDOUBLEDIRS $TEMP_DIR/dir_stat_c d 100
|
||||
|
||||
mkdir $TEMP_DIR/dir_stat_d
|
||||
$MKDOUBLEDIRS $TEMP_DIR/dir_stat_d d 5000
|
||||
|
||||
mkdir $TEMP_DIR/dir_stat_e
|
||||
$MKDOUBLEDIRS $TEMP_DIR/dir_stat_e d 3861
|
||||
|
||||
mkisofs -J -R -T -V 'KolibriOS' -input-charset 'UTF-8' -quiet $TEMP_DIR > $img_raw
|
||||
rm $TEMP_DIR/* -rf
|
||||
qemu-img convert -m 2 -O qcow2 -o $QCOW2_OPTS $img_raw $img
|
||||
rm $img_raw
|
||||
}
|
||||
|
||||
images=(gpt_large.qcow2 gpt_partitions_s05k.qcow2 gpt_partitions_s4k.qcow2
|
||||
kolibri.raw jfs.qcow2 xfs_lookup_v4.qcow2 xfs_lookup_v5.qcow2
|
||||
xfs_nrext64.qcow2 xfs_bigtime.qcow2 xfs_borg_bit.qcow2
|
||||
@@ -1041,7 +1097,7 @@ images=(gpt_large.qcow2 gpt_partitions_s05k.qcow2 gpt_partitions_s4k.qcow2
|
||||
xfs_v5_files_s05k_b4k_n8k.qcow2 fat32_test0.raw
|
||||
exfat_s05k_c16k_b16k.qcow2 exfat_s05k_c8k_b8k.qcow2
|
||||
xfs_samehash_s05k.raw ext2_s05k.qcow2 ext4_s05k.qcow2 fat12_s05k.qcow2
|
||||
fat16_s05k.qcow2)
|
||||
fat16_s05k.qcow2 iso9660_s2k_dir_all.qcow2)
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
LOOP_DEV=$(losetup --find)
|
||||
|
7
makefile
7
makefile
@@ -3,7 +3,7 @@ ifndef KOLIBRIOS
|
||||
endif
|
||||
|
||||
FASM_EXE ?= fasm
|
||||
FASM_FLAGS=-dUEFI=1 -dextended_primary_loader=1 -dUMKA=1 -dHOST=$(HOST) -m 2000000
|
||||
FASM_FLAGS=-dUEFI=1 -dextended_primary_loader=1 -dUMKA=1 -dHOST=$(HOST) -m 2000000 -dlang=en_US
|
||||
|
||||
HOST ?= linux
|
||||
CC ?= gcc
|
||||
@@ -28,7 +28,8 @@ else
|
||||
endif
|
||||
|
||||
CFLAGS=$(WARNINGS) $(NOWARNINGS) -std=c11 -g -O0 -DNDEBUG -masm=intel \
|
||||
-D_POSIX_C_SOURCE=200809L -I$(HOST) -Ideps -I. -fno-pie -D_POSIX
|
||||
-D_POSIX_C_SOURCE=200809L -I$(HOST) -Ideps -I. -fno-pie -D_POSIX \
|
||||
-fno-common
|
||||
CFLAGS_32=$(CFLAGS) -m32 -D_FILE_OFFSET_BITS=64 -D__USE_TIME_BITS64
|
||||
LDFLAGS=-no-pie
|
||||
LDFLAGS_32=$(LDFLAGS) -m32
|
||||
@@ -83,7 +84,7 @@ umka_os: umka_os.o umka.o shell.o deps/lodepng/lodepng.o vdisk.o vdisk/raw.o \
|
||||
vnet/file.o vnet/null.o trace.o trace_lbr.o $(HOST)/pci.o \
|
||||
$(HOST)/thread.o umkaio.o umkart.o deps/isocline/src/isocline.o \
|
||||
deps/optparse/optparse.o
|
||||
$(CC) $(LDFLAGS_32) `sdl2-config --libs` $^ -o $@ -T umka.ld
|
||||
$(CC) $(LDFLAGS_32) $^ `sdl2-config --libs` -o $@ -T umka.ld
|
||||
|
||||
umka_gen_devices_dat: umka_gen_devices_dat.o umka.o $(HOST)/pci.o \
|
||||
$(HOST)/thread.o umkart.o
|
||||
|
34
runtests.c
34
runtests.c
@@ -37,6 +37,7 @@ _Thread_local char reffname[PATH_MAX];
|
||||
_Thread_local char outfname[PATH_MAX];
|
||||
|
||||
int coverage = 0;
|
||||
int no_timeout = 0;
|
||||
int silent_success = 1;
|
||||
|
||||
static int
|
||||
@@ -125,7 +126,7 @@ struct test_wait_arg {
|
||||
pthread_cond_t *cond;
|
||||
};
|
||||
|
||||
static unsigned
|
||||
static time_t
|
||||
get_test_timeout(const char *testname) {
|
||||
sprintf(timeoutfname, "%s/%s", testname, TIMEOUT_FILENAME);
|
||||
FILE *f = fopen(timeoutfname, "rb");
|
||||
@@ -178,21 +179,33 @@ run_test(const void *arg) {
|
||||
int child;
|
||||
if (!(child = fork())) {
|
||||
chdir(test_name);
|
||||
execl("../../umka_shell", "../../umka_shell", "-ri", "run.us", "-o",
|
||||
"out.log", NULL);
|
||||
if (coverage) {
|
||||
char covfile[64];
|
||||
sprintf(covfile, "../cov_%s", test_name);
|
||||
execl("/usr/bin/taskset", "taskset", "1", "sudo",
|
||||
"../../umka_shell", "-ri", "run.us", "-o", "out.log", "-c",
|
||||
covfile, NULL);
|
||||
} else {
|
||||
execl("../../umka_shell", "../../umka_shell", "-ri", "run.us", "-o",
|
||||
"out.log", NULL);
|
||||
}
|
||||
fprintf(stderr, "Can't run test command: %s\n", strerror(errno));
|
||||
return (void *)-1;
|
||||
}
|
||||
pthread_t t;
|
||||
struct test_wait_arg wa = {.pid = child, .cond = &cond};
|
||||
pthread_create(&t, NULL, thread_wait, &wa);
|
||||
unsigned tout = get_test_timeout(test_name);
|
||||
time_t tout = get_test_timeout(test_name);
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
ts.tv_sec += tout;
|
||||
if (no_timeout) {
|
||||
ts.tv_sec += 60*60*24*7; // a week
|
||||
} else {
|
||||
ts.tv_sec += tout;
|
||||
}
|
||||
int status;
|
||||
if ((status = pthread_cond_timedwait(&cond, &mutex, &ts))) {
|
||||
fprintf(stderr, "[!] %s: timeout (%um%us)\n", test_name,
|
||||
fprintf(stderr, "[!] %s: timeout (%llim%llis)\n", test_name,
|
||||
tout/60, tout % 60);
|
||||
kill(child, SIGKILL);
|
||||
result = (void *)(intptr_t)status;
|
||||
@@ -270,19 +283,24 @@ main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
// int action = ACTION_RUN;
|
||||
size_t nthreads = 1;
|
||||
|
||||
struct optparse opts;
|
||||
optparse_init(&opts, argv);
|
||||
int opt;
|
||||
|
||||
while ((opt = optparse(&opts, "j:s")) != -1) {
|
||||
while ((opt = optparse(&opts, "cj:st")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
coverage = 1;
|
||||
break;
|
||||
case 'j':
|
||||
nthreads = strtoul(opts.optarg, NULL, 0);
|
||||
break;
|
||||
case 's':
|
||||
silent_success = 0;
|
||||
break;
|
||||
case 't':
|
||||
no_timeout = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[!] Unknown option: '%c'\n", opt);
|
||||
exit(1);
|
||||
|
183
shell.c
183
shell.c
@@ -51,124 +51,12 @@
|
||||
|
||||
#define SHELL_CMD_BUF_LEN 0x10
|
||||
|
||||
enum {
|
||||
UMKA_CMD_NONE,
|
||||
UMKA_CMD_SET_MOUSE_DATA,
|
||||
UMKA_CMD_WAIT_FOR_IDLE,
|
||||
UMKA_CMD_WAIT_FOR_OS_IDLE,
|
||||
UMKA_CMD_WAIT_FOR_WINDOW,
|
||||
UMKA_CMD_SYS_CSLEEP,
|
||||
UMKA_CMD_SYS_PROCESS_INFO,
|
||||
UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN,
|
||||
UMKA_CMD_SYS_LFN,
|
||||
};
|
||||
|
||||
enum {
|
||||
SHELL_CMD_STATUS_EMPTY,
|
||||
SHELL_CMD_STATUS_READY,
|
||||
SHELL_CMD_STATUS_DONE,
|
||||
};
|
||||
|
||||
struct cmd_set_mouse_data_arg {
|
||||
uint32_t btn_state;
|
||||
int32_t xmoving;
|
||||
int32_t ymoving;
|
||||
int32_t vscroll;
|
||||
int32_t hscroll;
|
||||
};
|
||||
|
||||
struct cmd_set_mouse_data_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_set_mouse_data {
|
||||
struct cmd_set_mouse_data_arg arg;
|
||||
struct cmd_set_mouse_data_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_sys_lfn_arg {
|
||||
f70or80_t f70or80;
|
||||
f7080s1arg_t *bufptr;
|
||||
f7080ret_t *r;
|
||||
};
|
||||
|
||||
struct cmd_sys_lfn_ret {
|
||||
f7080ret_t status;
|
||||
};
|
||||
|
||||
struct cmd_sys_lfn {
|
||||
struct cmd_sys_lfn_arg arg;
|
||||
struct cmd_sys_lfn_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_sys_process_info_arg {
|
||||
int32_t pid;
|
||||
void *param;
|
||||
};
|
||||
|
||||
struct cmd_sys_process_info_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_sys_process_info {
|
||||
struct cmd_sys_process_info_arg arg;
|
||||
struct cmd_sys_process_info_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_sys_get_mouse_pos_screen_arg {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_sys_get_mouse_pos_screen_ret {
|
||||
struct point16s pos;
|
||||
};
|
||||
|
||||
struct cmd_sys_get_mouse_pos_screen {
|
||||
struct cmd_sys_get_mouse_pos_screen_arg arg;
|
||||
struct cmd_sys_get_mouse_pos_screen_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_sys_csleep_arg {
|
||||
uint32_t csec;
|
||||
};
|
||||
|
||||
struct cmd_sys_csleep_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_sys_csleep {
|
||||
struct cmd_sys_csleep_arg arg;
|
||||
struct cmd_sys_csleep_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_wait_for_window_arg {
|
||||
char *wnd_title;
|
||||
};
|
||||
|
||||
struct cmd_wait_for_window_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_wait_for_window {
|
||||
struct cmd_wait_for_window_arg arg;
|
||||
struct cmd_wait_for_window_ret ret;
|
||||
};
|
||||
|
||||
struct umka_cmd {
|
||||
atomic_int status;
|
||||
uint32_t type;
|
||||
union {
|
||||
// internal funcs
|
||||
struct cmd_set_mouse_data set_mouse_data;
|
||||
struct cmd_wait_for_window wait_for_window;
|
||||
// syscalls
|
||||
struct cmd_sys_csleep sys_csleep;
|
||||
struct cmd_sys_process_info sys_process_info;
|
||||
struct cmd_sys_lfn sys_lfn;
|
||||
struct cmd_sys_get_mouse_pos_screen sys_get_mouse_pos_screen;
|
||||
};
|
||||
};
|
||||
|
||||
struct umka_cmd umka_cmd_buf[SHELL_CMD_BUF_LEN];
|
||||
|
||||
char prompt_line[PATH_MAX];
|
||||
@@ -181,21 +69,6 @@ typedef struct {
|
||||
void (*func) (struct shell_ctx *, int, char **);
|
||||
} func_table_t;
|
||||
|
||||
void
|
||||
shell_run_cmd_sync(struct shell_ctx *ctx);
|
||||
|
||||
static void
|
||||
shell_run_cmd(struct shell_ctx *ctx) {
|
||||
struct umka_cmd *cmd = umka_cmd_buf;
|
||||
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
|
||||
memory_order_release);
|
||||
if (atomic_load_explicit(ctx->running, memory_order_acquire) == UMKA_RUNNING_YES) {
|
||||
pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex);
|
||||
} else {
|
||||
shell_run_cmd_sync(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
shell_run_cmd_wait_test(void /* struct appdata * with wait_param is in ebx */) {
|
||||
appdata_t *app;
|
||||
@@ -204,6 +77,9 @@ shell_run_cmd_wait_test(void /* struct appdata * with wait_param is in ebx */) {
|
||||
return (uint32_t)(atomic_load_explicit(&cmd->status, memory_order_acquire) == SHELL_CMD_STATUS_READY);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_run_cmd_sync(struct shell_ctx *ctx);
|
||||
|
||||
static void
|
||||
thread_cmd_runner(void *arg) {
|
||||
umka_sti();
|
||||
@@ -544,11 +420,16 @@ cmd_send_scancode(struct shell_ctx *ctx, int argc, char **argv) {
|
||||
argc -= 1;
|
||||
argv += 1;
|
||||
|
||||
struct umka_cmd *cmd = shell_get_cmd(ctx);
|
||||
cmd->type = UMKA_CMD_SEND_SCANCODE;
|
||||
struct cmd_send_scancode_arg *c = &cmd->send_scancode.arg;
|
||||
while (argc) {
|
||||
char *endptr;
|
||||
size_t code = strtoul(argv[0], &endptr, 0);
|
||||
if (*endptr == '\0') {
|
||||
umka_set_keyboard_data(code);
|
||||
c->scancode = code;
|
||||
shell_run_cmd(ctx);
|
||||
shell_clear_cmd(cmd);
|
||||
argc--;
|
||||
argv++;
|
||||
} else {
|
||||
@@ -831,6 +712,8 @@ disk_list_partitions(struct shell_ctx *ctx, disk_t *d) {
|
||||
fsname = "exfat";
|
||||
} else if (p->fs_user_functions == ntfs_user_functions) {
|
||||
fsname = "ntfs";
|
||||
} else if (p->fs_user_functions == iso9660_user_functions) {
|
||||
fsname = "iso9660";
|
||||
} else {
|
||||
fsname = "???";
|
||||
}
|
||||
@@ -1385,17 +1268,16 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) {
|
||||
}
|
||||
uint32_t btn_state = lbheld + (rbheld << 1) + (mbheld << 2) + (yabs << 30)
|
||||
+ (xabs << 31);
|
||||
struct umka_cmd *cmd = umka_cmd_buf;
|
||||
struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg;
|
||||
struct umka_cmd *cmd = shell_get_cmd(ctx);
|
||||
cmd->type = UMKA_CMD_SET_MOUSE_DATA;
|
||||
struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg;
|
||||
c->btn_state = btn_state;
|
||||
c->xmoving = xmoving;
|
||||
c->ymoving = ymoving;
|
||||
c->vscroll = vscroll;
|
||||
c->hscroll = hscroll;
|
||||
shell_run_cmd(ctx);
|
||||
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
|
||||
memory_order_release);
|
||||
shell_clear_cmd(cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4328,7 +4210,7 @@ func_table_t cmd_cmds[] = {
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
void
|
||||
static void
|
||||
shell_run_cmd_sync(struct shell_ctx *ctx) {
|
||||
struct umka_cmd *cmd = umka_cmd_buf;
|
||||
switch (cmd->type) {
|
||||
@@ -4366,9 +4248,18 @@ shell_run_cmd_sync(struct shell_ctx *ctx) {
|
||||
COVERAGE_OFF();
|
||||
break;
|
||||
}
|
||||
case UMKA_CMD_SEND_SCANCODE: {
|
||||
struct cmd_send_scancode_arg *c = &cmd->send_scancode.arg;
|
||||
COVERAGE_ON();
|
||||
umka_set_keyboard_data(c->scancode);
|
||||
COVERAGE_OFF();
|
||||
break;
|
||||
}
|
||||
case UMKA_CMD_SYS_LFN: {
|
||||
struct cmd_sys_lfn_arg *c = &cmd->sys_lfn.arg;
|
||||
COVERAGE_ON();
|
||||
umka_sys_lfn(c->bufptr, c->r, c->f70or80);
|
||||
COVERAGE_OFF();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -4380,6 +4271,30 @@ shell_run_cmd_sync(struct shell_ctx *ctx) {
|
||||
pthread_cond_signal(&ctx->cmd_done);
|
||||
}
|
||||
|
||||
struct umka_cmd *
|
||||
shell_get_cmd(struct shell_ctx *shell) {
|
||||
(void)shell;
|
||||
return umka_cmd_buf;
|
||||
}
|
||||
|
||||
void
|
||||
shell_run_cmd(struct shell_ctx *ctx) {
|
||||
struct umka_cmd *cmd = umka_cmd_buf;
|
||||
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
|
||||
memory_order_release);
|
||||
if (atomic_load_explicit(ctx->running, memory_order_acquire) == UMKA_RUNNING_YES) {
|
||||
pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex);
|
||||
} else {
|
||||
shell_run_cmd_sync(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shell_clear_cmd(struct umka_cmd *cmd) {
|
||||
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
|
||||
memory_order_release);
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_help(struct shell_ctx *ctx, int argc, char **argv) {
|
||||
const char *usage = \
|
||||
@@ -4428,7 +4343,7 @@ run_test(struct shell_ctx *ctx) {
|
||||
|
||||
pthread_mutex_lock(&ctx->cmd_mutex);
|
||||
int is_tty = isatty(fileno(stdin));
|
||||
char **argv = (char**)calloc(sizeof(char*), (MAX_COMMAND_ARGS + 1));
|
||||
char **argv = (char**)calloc(MAX_COMMAND_ARGS + 1, sizeof(char*));
|
||||
ic_set_default_completer(completer, NULL);
|
||||
ic_set_default_highlighter(highlighter, NULL);
|
||||
ic_enable_auto_tab(1);
|
||||
|
135
shell.h
135
shell.h
@@ -59,7 +59,140 @@ shell_close(struct shell_ctx *shell);
|
||||
void *
|
||||
run_test(struct shell_ctx *ctx);
|
||||
|
||||
enum {
|
||||
UMKA_CMD_NONE,
|
||||
UMKA_CMD_SET_MOUSE_DATA,
|
||||
UMKA_CMD_WAIT_FOR_IDLE,
|
||||
UMKA_CMD_WAIT_FOR_OS_IDLE,
|
||||
UMKA_CMD_WAIT_FOR_WINDOW,
|
||||
UMKA_CMD_SYS_CSLEEP,
|
||||
UMKA_CMD_SYS_PROCESS_INFO,
|
||||
UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN,
|
||||
UMKA_CMD_SYS_LFN,
|
||||
UMKA_CMD_SEND_SCANCODE,
|
||||
};
|
||||
|
||||
struct cmd_set_mouse_data_arg {
|
||||
uint32_t btn_state;
|
||||
int32_t xmoving;
|
||||
int32_t ymoving;
|
||||
int32_t vscroll;
|
||||
int32_t hscroll;
|
||||
};
|
||||
|
||||
struct cmd_set_mouse_data_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_set_mouse_data {
|
||||
struct cmd_set_mouse_data_arg arg;
|
||||
struct cmd_set_mouse_data_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_sys_lfn_arg {
|
||||
f70or80_t f70or80;
|
||||
f7080s1arg_t *bufptr;
|
||||
f7080ret_t *r;
|
||||
};
|
||||
|
||||
struct cmd_sys_lfn_ret {
|
||||
f7080ret_t status;
|
||||
};
|
||||
|
||||
struct cmd_sys_lfn {
|
||||
struct cmd_sys_lfn_arg arg;
|
||||
struct cmd_sys_lfn_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_sys_process_info_arg {
|
||||
int32_t pid;
|
||||
void *param;
|
||||
};
|
||||
|
||||
struct cmd_sys_process_info_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_sys_process_info {
|
||||
struct cmd_sys_process_info_arg arg;
|
||||
struct cmd_sys_process_info_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_sys_get_mouse_pos_screen_arg {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_sys_get_mouse_pos_screen_ret {
|
||||
struct point16s pos;
|
||||
};
|
||||
|
||||
struct cmd_sys_get_mouse_pos_screen {
|
||||
struct cmd_sys_get_mouse_pos_screen_arg arg;
|
||||
struct cmd_sys_get_mouse_pos_screen_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_sys_csleep_arg {
|
||||
uint32_t csec;
|
||||
};
|
||||
|
||||
struct cmd_sys_csleep_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_sys_csleep {
|
||||
struct cmd_sys_csleep_arg arg;
|
||||
struct cmd_sys_csleep_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_wait_for_window_arg {
|
||||
char *wnd_title;
|
||||
};
|
||||
|
||||
struct cmd_wait_for_window_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_wait_for_window {
|
||||
struct cmd_wait_for_window_arg arg;
|
||||
struct cmd_wait_for_window_ret ret;
|
||||
};
|
||||
|
||||
struct cmd_send_scancode_arg {
|
||||
int scancode;
|
||||
};
|
||||
|
||||
struct cmd_send_scancode_ret {
|
||||
char stub;
|
||||
};
|
||||
|
||||
struct cmd_send_scancode {
|
||||
struct cmd_send_scancode_arg arg;
|
||||
struct cmd_send_scancode_ret ret;
|
||||
};
|
||||
|
||||
struct umka_cmd {
|
||||
atomic_int status;
|
||||
uint32_t type;
|
||||
union {
|
||||
// internal funcs
|
||||
struct cmd_set_mouse_data set_mouse_data;
|
||||
struct cmd_send_scancode send_scancode;
|
||||
struct cmd_wait_for_window wait_for_window;
|
||||
// syscalls
|
||||
struct cmd_sys_csleep sys_csleep;
|
||||
struct cmd_sys_process_info sys_process_info;
|
||||
struct cmd_sys_lfn sys_lfn;
|
||||
struct cmd_sys_get_mouse_pos_screen sys_get_mouse_pos_screen;
|
||||
};
|
||||
};
|
||||
|
||||
struct umka_cmd *
|
||||
shell_get_cmd(struct shell_ctx *shell);
|
||||
|
||||
void
|
||||
umka_run_cmd_sync(struct shell_ctx *ctx);
|
||||
shell_run_cmd(struct shell_ctx *ctx);
|
||||
|
||||
void
|
||||
shell_clear_cmd(struct umka_cmd *cmd);
|
||||
|
||||
#endif // SHELL_H_INCLUDED
|
||||
|
@@ -1 +1 @@
|
||||
45s
|
||||
55s
|
||||
|
53991
test/t068/ref.log
Normal file
53991
test/t068/ref.log
Normal file
File diff suppressed because it is too large
Load Diff
62
test/t068/run.us
Normal file
62
test/t068/run.us
Normal file
@@ -0,0 +1,62 @@
|
||||
umka_boot
|
||||
disk_add ../../img/iso9660_s2k_dir_all.qcow2 hd0 -c 524288
|
||||
|
||||
ls70 /hd0/1/dir_ls_a
|
||||
ls70 /hd0/1/dir_ls_b
|
||||
ls70 /hd0/1/dir_ls_c
|
||||
ls70 /hd0/1/dir_ls_d
|
||||
ls70 /hd0/1/dir_ls_e
|
||||
ls70 /hd0/1/dir_ls_f
|
||||
ls70 /hd0/1/dir_ls_g
|
||||
|
||||
ls70 /hd0/1/dir_ls_g -f 0 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 1 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 2 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 3 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 4 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 46651 -c 10
|
||||
ls70 /hd0/1/dir_ls_g -f 46658 -c 10
|
||||
ls70 /hd0/1/dir_ls_g -f 46659 -c 10
|
||||
ls70 /hd0/1/dir_ls_g -f 46660 -c 10
|
||||
ls70 /hd0/1/dir_ls_g -f 46661 -c 10
|
||||
ls70 /hd0/1/dir_ls_g -f 46662 -c 10
|
||||
ls70 /hd0/1/dir_ls_g -f 0 -c 0
|
||||
ls70 /hd0/1/dir_ls_g -f 1 -c 0
|
||||
ls70 /hd0/1/dir_ls_g -f 2 -c 0
|
||||
ls70 /hd0/1/dir_ls_g -f 3 -c 0
|
||||
ls70 /hd0/1/dir_ls_g -f 4 -c 0
|
||||
ls70 /hd0/1/dir_ls_g -f 0 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 1 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 2 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 3 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 4 -c 1
|
||||
ls70 /hd0/1/dir_ls_g -f 0 -c 2
|
||||
ls70 /hd0/1/dir_ls_g -f 1 -c 2
|
||||
ls70 /hd0/1/dir_ls_g -f 2 -c 2
|
||||
ls70 /hd0/1/dir_ls_g -f 3 -c 2
|
||||
ls70 /hd0/1/dir_ls_g -f 4 -c 2
|
||||
ls70 /hd0/1/dir_ls_g -f 0 -c 3
|
||||
ls70 /hd0/1/dir_ls_g -f 1 -c 3
|
||||
ls70 /hd0/1/dir_ls_g -f 2 -c 3
|
||||
ls70 /hd0/1/dir_ls_g -f 3 -c 3
|
||||
ls70 /hd0/1/dir_ls_g -f 4 -c 3
|
||||
ls70 /hd0/1/dir_ls_g -f 0 -c 4
|
||||
ls70 /hd0/1/dir_ls_g -f 1 -c 4
|
||||
ls70 /hd0/1/dir_ls_g -f 2 -c 4
|
||||
ls70 /hd0/1/dir_ls_g -f 3 -c 4
|
||||
ls70 /hd0/1/dir_ls_g -f 4 -c 4
|
||||
|
||||
stat70 /hd0/1/dir_stat_a
|
||||
ls70 /hd0/1/dir_stat_a
|
||||
stat70 /hd0/1/dir_stat_b
|
||||
ls70 /hd0/1/dir_stat_a
|
||||
stat70 /hd0/1/dir_stat_c
|
||||
ls70 /hd0/1/dir_stat_a
|
||||
stat70 /hd0/1/dir_stat_d
|
||||
ls70 /hd0/1/dir_stat_a
|
||||
stat70 /hd0/1/dir_stat_e
|
||||
ls70 /hd0/1/dir_stat_a
|
||||
stat70 /hd0/1/dir_stat_f
|
||||
stat70 /hd0/1/dir_stat_g
|
||||
|
||||
disk_del hd0
|
2
test/t068/tags.txt
Normal file
2
test/t068/tags.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
fs: iso9660
|
||||
iso9660:
|
1
test/t068/timeout.txt
Normal file
1
test/t068/timeout.txt
Normal file
@@ -0,0 +1 @@
|
||||
30s
|
24
trace.c
24
trace.c
@@ -8,24 +8,22 @@
|
||||
|
||||
#include "trace_lbr.h"
|
||||
|
||||
uint32_t coverage;
|
||||
|
||||
void
|
||||
trace_begin(void) {
|
||||
trace_lbr_begin();
|
||||
trace_enable(void) {
|
||||
trace_lbr_enable();
|
||||
}
|
||||
|
||||
void
|
||||
trace_end(void) {
|
||||
trace_lbr_end();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
trace_pause(void) {
|
||||
return trace_lbr_pause();
|
||||
trace_disable(void) {
|
||||
trace_lbr_disable();
|
||||
}
|
||||
|
||||
void
|
||||
trace_resume(uint32_t value) {
|
||||
trace_lbr_resume(value);
|
||||
trace_on(void) {
|
||||
trace_lbr_on();
|
||||
}
|
||||
|
||||
void
|
||||
trace_off(void) {
|
||||
trace_lbr_off();
|
||||
}
|
||||
|
16
trace.h
16
trace.h
@@ -9,17 +9,13 @@
|
||||
#ifndef TRACE_H_INCLUDED
|
||||
#define TRACE_H_INCLUDED
|
||||
|
||||
#include <inttypes.h>
|
||||
#define COVERAGE_ON() do { trace_on(); } while (0)
|
||||
|
||||
extern uint32_t coverage;
|
||||
#define COVERAGE_OFF() do { trace_off(); } while (0)
|
||||
|
||||
#define COVERAGE_ON() do { trace_resume(coverage); } while (0)
|
||||
|
||||
#define COVERAGE_OFF() do { coverage = trace_pause(); } while (0)
|
||||
|
||||
void trace_begin(void);
|
||||
void trace_end(void);
|
||||
uint32_t trace_pause(void);
|
||||
void trace_resume(uint32_t value);
|
||||
void trace_enable(void);
|
||||
void trace_disable(void);
|
||||
void trace_on(void);
|
||||
void trace_off(void);
|
||||
|
||||
#endif
|
||||
|
31
trace_lbr.c
31
trace_lbr.c
@@ -24,10 +24,11 @@
|
||||
#define MSR_IA32_LASTBRANCHFROMIP 0x1db
|
||||
#define MSR_IA32_LASTBRANCHTOIP 0x1dc
|
||||
|
||||
int coverage = 0;
|
||||
int msrfd;
|
||||
|
||||
uint64_t rdmsr(uint32_t reg)
|
||||
{
|
||||
static uint64_t
|
||||
rdmsr(uint32_t reg) {
|
||||
uint64_t data = 0;
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -43,8 +44,8 @@ uint64_t rdmsr(uint32_t reg)
|
||||
return data;
|
||||
}
|
||||
|
||||
void wrmsr(uint32_t reg, uint64_t data)
|
||||
{
|
||||
static void
|
||||
wrmsr(uint32_t reg, uint64_t data) {
|
||||
#ifndef _WIN32
|
||||
int fd;
|
||||
fd = open("/dev/cpu/0/msr", O_WRONLY);
|
||||
@@ -66,7 +67,8 @@ void wrmsr(uint32_t reg, uint64_t data)
|
||||
#endif
|
||||
}
|
||||
|
||||
void handle_sigtrap(int signo) {
|
||||
static void
|
||||
handle_sigtrap(int signo) {
|
||||
(void)signo;
|
||||
#ifndef _WIN32
|
||||
uint64_t from = rdmsr(MSR_IA32_LASTBRANCHFROMIP);
|
||||
@@ -86,13 +88,13 @@ void handle_sigtrap(int signo) {
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t set_eflags_tf(uint32_t tf);
|
||||
|
||||
void trace_lbr_begin(void) {
|
||||
void
|
||||
trace_lbr_enable(void) {
|
||||
#ifndef _WIN32
|
||||
struct sigaction action;
|
||||
action.sa_handler = &handle_sigtrap;
|
||||
action.sa_flags = 0;
|
||||
coverage = 1;
|
||||
sigaction(SIGTRAP, &action, NULL);
|
||||
|
||||
wrmsr(MSR_IA32_DEBUGCTL, MSR_IA32_DEBUGCTL_LBR + MSR_IA32_DEBUGCTL_BTF);
|
||||
@@ -106,7 +108,8 @@ void trace_lbr_begin(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void trace_lbr_end(void) {
|
||||
void
|
||||
trace_lbr_disable(void) {
|
||||
#ifndef _WIN32
|
||||
wrmsr(MSR_IA32_DEBUGCTL, 0);
|
||||
close(msrfd);
|
||||
@@ -115,10 +118,12 @@ void trace_lbr_end(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t trace_lbr_pause(void) {
|
||||
return set_eflags_tf(0u);
|
||||
void
|
||||
trace_lbr_on(void) {
|
||||
set_eflags_tf(coverage);
|
||||
}
|
||||
|
||||
void trace_lbr_resume(uint32_t value) {
|
||||
set_eflags_tf(value);
|
||||
void
|
||||
trace_lbr_off(void) {
|
||||
set_eflags_tf(0u);
|
||||
}
|
||||
|
10
trace_lbr.h
10
trace_lbr.h
@@ -9,11 +9,9 @@
|
||||
#ifndef TRACE_LBR_H_INCLUDED
|
||||
#define TRACE_LBR_H_INCLUDED
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void trace_lbr_begin(void);
|
||||
void trace_lbr_end(void);
|
||||
uint32_t trace_lbr_pause(void);
|
||||
void trace_lbr_resume(uint32_t value);
|
||||
void trace_lbr_enable(void);
|
||||
void trace_lbr_disable(void);
|
||||
void trace_lbr_on(void);
|
||||
void trace_lbr_off(void);
|
||||
|
||||
#endif
|
||||
|
4
umka.asm
4
umka.asm
@@ -124,6 +124,7 @@ pubsym ext_user_functions
|
||||
pubsym fat_user_functions
|
||||
pubsym exFAT_user_functions, 'exfat_user_functions'
|
||||
pubsym ntfs_user_functions
|
||||
pubsym iso9660_user_functions
|
||||
|
||||
pubsym i40, no_mangle
|
||||
|
||||
@@ -231,8 +232,6 @@ macro sti {
|
||||
iretd equ retd
|
||||
iret equ ret
|
||||
|
||||
lang fix en
|
||||
|
||||
macro int n {
|
||||
if n eq 0x40
|
||||
call i40
|
||||
@@ -638,7 +637,6 @@ proc set_eflags_tf c uses ebx esi edi ebp, tf
|
||||
rol eax, 8
|
||||
push eax
|
||||
popfd
|
||||
mov eax, edx
|
||||
ret
|
||||
endp
|
||||
|
||||
|
6
umka.h
6
umka.h
@@ -265,6 +265,7 @@ typedef struct {
|
||||
uint32_t flags;
|
||||
uint32_t sector_size;
|
||||
uint64_t capacity; // in sectors
|
||||
uint32_t last_session_sector;
|
||||
} diskmediainfo_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -297,6 +298,7 @@ typedef struct {
|
||||
STDCALL int (*flush)(void *userdata);
|
||||
STDCALL unsigned int (*adjust_cache_size)(void *userdata,
|
||||
size_t suggested_size);
|
||||
STDCALL int (*loadtray)(void *userdata, int flags);
|
||||
} diskfunc_t;
|
||||
|
||||
struct disk_t {
|
||||
@@ -603,6 +605,7 @@ extern uint8_t ext_user_functions[];
|
||||
extern uint8_t fat_user_functions[];
|
||||
extern uint8_t exfat_user_functions[];
|
||||
extern uint8_t ntfs_user_functions[];
|
||||
extern uint8_t iso9660_user_functions[];
|
||||
|
||||
extern char kos_ramdisk[RAMDISK_MAX_LEN];
|
||||
|
||||
@@ -862,6 +865,9 @@ umka_cli(void);
|
||||
void
|
||||
umka_sti(void);
|
||||
|
||||
void
|
||||
set_eflags_tf(uint32_t tf);
|
||||
|
||||
#define COVERAGE_TABLE_SIZE (512*1024)
|
||||
|
||||
struct coverage_branch {
|
||||
|
151
umka_os.c
151
umka_os.c
@@ -154,6 +154,17 @@ hw_int(int signo) {
|
||||
umka_sti();
|
||||
}
|
||||
|
||||
void (*copy_display)(void *);
|
||||
|
||||
static void
|
||||
update_display(SDL_Surface *window_surface, SDL_Window *window) {
|
||||
SDL_LockSurface(window_surface);
|
||||
copy_display(window_surface->pixels);
|
||||
SDL_UnlockSurface(window_surface);
|
||||
SDL_UpdateWindowSurface(window);
|
||||
return;
|
||||
}
|
||||
|
||||
static void *
|
||||
umka_display(void *arg) {
|
||||
(void)arg;
|
||||
@@ -164,8 +175,8 @@ umka_display(void *arg) {
|
||||
}
|
||||
|
||||
char title[64];
|
||||
sprintf(title, "umka0 %ux%u %ubpp", kos_display.width, kos_display.height,
|
||||
kos_display.bits_per_pixel);
|
||||
sprintf(title, "umka %ux%u %ubpp, press Ctrl-Alt-g to (un)grab input",
|
||||
kos_display.width, kos_display.height, kos_display.bits_per_pixel);
|
||||
SDL_Window *window = SDL_CreateWindow(title,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
@@ -187,8 +198,6 @@ umka_display(void *arg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void (*copy_display)(void *) = NULL;
|
||||
|
||||
switch (window_surface->format->format) {
|
||||
case SDL_PIXELFORMAT_RGB888:
|
||||
copy_display = copy_display_to_rgb888;
|
||||
@@ -199,12 +208,115 @@ umka_display(void *arg) {
|
||||
break;
|
||||
}
|
||||
|
||||
bool input_grabbed = false;
|
||||
|
||||
SDL_Event event;
|
||||
while (1) {
|
||||
SDL_LockSurface(window_surface);
|
||||
copy_display(window_surface->pixels);
|
||||
SDL_UnlockSurface(window_surface);
|
||||
SDL_UpdateWindowSurface(window);
|
||||
sleep(1);
|
||||
update_display(window_surface, window);
|
||||
if (SDL_WaitEventTimeout(&event, 1000 /* ms */)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP: {
|
||||
if (!input_grabbed) {
|
||||
break;
|
||||
}
|
||||
struct umka_cmd *cmd = shell_get_cmd(os->shell);
|
||||
cmd->type = UMKA_CMD_SET_MOUSE_DATA;
|
||||
struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg;
|
||||
c->btn_state = event.button.state;
|
||||
c->xmoving = 0;
|
||||
c->ymoving = 0;
|
||||
c->vscroll = 0;
|
||||
c->hscroll = 0;
|
||||
shell_run_cmd(os->shell);
|
||||
shell_clear_cmd(cmd);
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEMOTION: {
|
||||
if (!input_grabbed) {
|
||||
break;
|
||||
}
|
||||
struct umka_cmd *cmd = shell_get_cmd(os->shell);
|
||||
cmd->type = UMKA_CMD_SET_MOUSE_DATA;
|
||||
struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg;
|
||||
c->btn_state = 0;
|
||||
c->xmoving = event.motion.xrel;
|
||||
c->ymoving = -event.motion.yrel;
|
||||
c->vscroll = 0;
|
||||
c->hscroll = 0;
|
||||
shell_run_cmd(os->shell);
|
||||
shell_clear_cmd(cmd);
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEWHEEL: {
|
||||
if (!input_grabbed) {
|
||||
break;
|
||||
}
|
||||
uint32_t btn_state = SDL_GetMouseState(NULL, NULL);
|
||||
struct umka_cmd *cmd = shell_get_cmd(os->shell);
|
||||
cmd->type = UMKA_CMD_SET_MOUSE_DATA;
|
||||
struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg;
|
||||
c->btn_state = 0;
|
||||
if ((btn_state & SDL_BUTTON_LMASK)) {
|
||||
c->btn_state |= 0x01;
|
||||
}
|
||||
/*
|
||||
if ((btn_state & SDL_BUTTON_RMASK)) {
|
||||
c->btn_state |= 0x02;
|
||||
}
|
||||
if ((btn_state & SDL_BUTTON_MMASK)) {
|
||||
c->btn_state |= 0x04;
|
||||
}
|
||||
*/
|
||||
c->xmoving = 0;
|
||||
c->ymoving = 0;
|
||||
c->vscroll = event.wheel.y;
|
||||
c->hscroll = event.wheel.x;
|
||||
shell_run_cmd(os->shell);
|
||||
shell_clear_cmd(cmd);
|
||||
break;
|
||||
}
|
||||
case SDL_KEYDOWN: {
|
||||
if ((event.key.keysym.scancode == SDL_SCANCODE_G)
|
||||
&& (event.key.keysym.mod & KMOD_CTRL)
|
||||
&& (event.key.keysym.mod & KMOD_ALT)) {
|
||||
input_grabbed = !input_grabbed;
|
||||
SDL_SetWindowMouseGrab(window, input_grabbed);
|
||||
SDL_SetWindowKeyboardGrab(window, input_grabbed);
|
||||
SDL_SetRelativeMouseMode(input_grabbed);
|
||||
}
|
||||
if (!input_grabbed) {
|
||||
break;
|
||||
}
|
||||
struct umka_cmd *cmd = shell_get_cmd(os->shell);
|
||||
cmd->type = UMKA_CMD_SEND_SCANCODE;
|
||||
struct cmd_send_scancode_arg *c = &cmd->send_scancode.arg;
|
||||
shell_run_cmd(os->shell);
|
||||
shell_clear_cmd(cmd);
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP:
|
||||
if (!input_grabbed) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
if (!input_grabbed) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[sdl] unknown event type: 0x%x\n", event.type);
|
||||
update_display(window_surface, window);
|
||||
}
|
||||
} else {
|
||||
update_display(window_surface, window);
|
||||
}
|
||||
// sleep(1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -233,11 +345,9 @@ int
|
||||
main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
const char *usage = "umka_os [-i <infile>] [-o <outfile>]"
|
||||
" [-b <boardlog>] [-s <startupfile>]\n";
|
||||
if (coverage) {
|
||||
trace_begin();
|
||||
}
|
||||
" [-b <boardlog>] [-s <startupfile>] [-c covfile]\n";
|
||||
|
||||
int coverage = 0;
|
||||
int show_display = 0;
|
||||
|
||||
umka_sti();
|
||||
@@ -248,6 +358,7 @@ main(int argc, char *argv[]) {
|
||||
const char *infile = NULL;
|
||||
const char *outfile = NULL;
|
||||
const char *boardlogfile = NULL;
|
||||
const char *covfile = NULL;
|
||||
FILE *fstartup = NULL;
|
||||
FILE *fin = stdin;
|
||||
FILE *fout = stdout;
|
||||
@@ -257,11 +368,15 @@ main(int argc, char *argv[]) {
|
||||
int opt;
|
||||
optparse_init(&options, argv);
|
||||
|
||||
while ((opt = optparse(&options, "b:di:o:s:")) != -1) {
|
||||
while ((opt = optparse(&options, "b:c:di:o:s:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'b':
|
||||
boardlogfile = options.optarg;
|
||||
break;
|
||||
case 'c':
|
||||
coverage = 1;
|
||||
covfile = options.optarg;
|
||||
break;
|
||||
case 'd':
|
||||
show_display = 1;
|
||||
break;
|
||||
@@ -281,6 +396,10 @@ main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (coverage) {
|
||||
trace_enable();
|
||||
}
|
||||
|
||||
if (startupfile) {
|
||||
fstartup = fopen(startupfile, "rb");
|
||||
if (!fstartup) {
|
||||
@@ -429,7 +548,9 @@ main(int argc, char *argv[]) {
|
||||
umka_osloop(); // doesn't return
|
||||
|
||||
if (coverage)
|
||||
trace_end();
|
||||
trace_disable();
|
||||
|
||||
(void)covfile;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
16
umka_shell.c
16
umka_shell.c
@@ -63,7 +63,9 @@ main(int argc, char **argv) {
|
||||
" -i infile file with commands\n"
|
||||
" -o outfile file for logs\n"
|
||||
" -r reproducible logs (without pointers and datetime)\n"
|
||||
" -c collect coverage\n";
|
||||
" -c covfile collect coverage to the file\n";
|
||||
|
||||
char covfile[64];
|
||||
|
||||
const char *infile = NULL, *outfile = NULL;
|
||||
FILE *fin = stdin;
|
||||
@@ -75,13 +77,14 @@ main(int argc, char **argv) {
|
||||
kos_boot.memmap_blocks[1] = (e820entry_t){(uintptr_t)mem1, 128*1024*1024, 1};
|
||||
kos_boot.memmap_blocks[2] = (e820entry_t){(uintptr_t)mem2, 256*1024*1024, 1};
|
||||
*/
|
||||
int coverage = 0;
|
||||
int reproducible = 0;
|
||||
|
||||
struct optparse options;
|
||||
optparse_init(&options, argv);
|
||||
int opt;
|
||||
|
||||
while ((opt = optparse(&options, "i:o:rc")) != -1) {
|
||||
while ((opt = optparse(&options, "i:o:rc:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
infile = options.optarg;
|
||||
@@ -94,6 +97,7 @@ main(int argc, char **argv) {
|
||||
break;
|
||||
case 'c':
|
||||
coverage = 1;
|
||||
sprintf(covfile, "%s.%i", options.optarg, getpid());
|
||||
break;
|
||||
case 'h':
|
||||
fputs(usage, stderr);
|
||||
@@ -123,15 +127,13 @@ main(int argc, char **argv) {
|
||||
struct umka_shell_ctx *ctx = umka_shell_init(reproducible, fin);
|
||||
|
||||
if (coverage)
|
||||
trace_begin();
|
||||
trace_enable();
|
||||
|
||||
run_test(ctx->shell);
|
||||
|
||||
if (coverage) {
|
||||
trace_end();
|
||||
char coverage_filename[32];
|
||||
sprintf(coverage_filename, "coverage.%i", getpid());
|
||||
FILE *f = fopen(coverage_filename, "w");
|
||||
trace_disable();
|
||||
FILE *f = fopen(covfile, "w");
|
||||
fwrite(coverage_table,
|
||||
COVERAGE_TABLE_SIZE * sizeof(struct coverage_branch), 1, f);
|
||||
fclose(f);
|
||||
|
7
vdisk.c
7
vdisk.c
@@ -45,10 +45,13 @@ vdisk_init(const char *fname, const int adjust_cache_size,
|
||||
const size_t cache_size, const void *io) {
|
||||
size_t fname_len = strlen(fname);
|
||||
size_t dot_raw_len = strlen(RAW_SUFFIX);
|
||||
size_t dot_iso_len = strlen(ISO_SUFFIX);
|
||||
size_t dot_qcow2_len = strlen(QCOW2_SUFFIX);
|
||||
struct vdisk *disk;
|
||||
if (fname_len > dot_raw_len
|
||||
&& !strcmp(fname + fname_len - dot_raw_len, RAW_SUFFIX)) {
|
||||
if ((fname_len > dot_raw_len
|
||||
&& !strcmp(fname + fname_len - dot_raw_len, RAW_SUFFIX))
|
||||
|| (fname_len > dot_iso_len
|
||||
&& !strcmp(fname + fname_len - dot_iso_len, ISO_SUFFIX))) {
|
||||
disk = (struct vdisk*)vdisk_init_raw(fname, io);
|
||||
} else if (fname_len > dot_qcow2_len
|
||||
&& !strcmp(fname + fname_len - dot_qcow2_len, QCOW2_SUFFIX)) {
|
||||
|
@@ -222,6 +222,8 @@ vdisk_init_qcow2(const char *fname, const struct umka_io *io) {
|
||||
d->vdisk.sect_size = 512;
|
||||
if (strstr(fname, "s4096") != NULL || strstr(fname, "s4k") != NULL) {
|
||||
d->vdisk.sect_size = 4096;
|
||||
} else if (strstr(fname, "s2048") != NULL || strstr(fname, "s2k") != NULL) {
|
||||
d->vdisk.sect_size = 2048;
|
||||
}
|
||||
|
||||
struct qcow2_header header;
|
||||
|
@@ -65,6 +65,8 @@ vdisk_init_raw(const char *fname, const struct umka_io *io) {
|
||||
size_t sect_size = 512;
|
||||
if (strstr(fname, "s4096") != NULL || strstr(fname, "s4k") != NULL) {
|
||||
sect_size = 4096;
|
||||
} else if (strstr(fname, "s2048") != NULL || strstr(fname, "s2k") != NULL) {
|
||||
sect_size = 2048;
|
||||
}
|
||||
struct vdisk_raw *disk = (struct vdisk_raw*)malloc(sizeof(struct vdisk_raw));
|
||||
*disk = (struct vdisk_raw){
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "umkaio.h"
|
||||
|
||||
#define RAW_SUFFIX ".raw"
|
||||
#define ISO_SUFFIX ".iso"
|
||||
|
||||
struct vdisk*
|
||||
vdisk_init_raw(const char *fname, const struct umka_io *io);
|
||||
|
Reference in New Issue
Block a user