Skip to content

Commit

Permalink
ports/qemu-{arm,riscv}: Use Picolibc 1.7.5 --crt0=semihost
Browse files Browse the repository at this point in the history
This new crt0 provides argc/argv from the semihost command line rather
than requiring parsing inside the application. Version 1.7.5 also
provides a working gettimeofday.

Signed-off-by: Keith Packard <keithp@keithp.com>
  • Loading branch information
keith-packard committed Mar 27, 2022
1 parent 74e19c3 commit 53a3d3c
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 43 deletions.
50 changes: 16 additions & 34 deletions chips/qemu/snek-qemu.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@
#include <snek.h>
#include <snek-io.h>
#ifdef HAVE_SEMIHOST
#define _HAVE_SEMIHOST
#endif
#ifdef _HAVE_SEMIHOST
#include <semihost.h>
#endif
#include <sys/time.h>

snek_poly_t
snek_builtin_exit(snek_poly_t a)
Expand Down Expand Up @@ -84,42 +88,36 @@ snek_builtin_random_randrange(snek_poly_t a)
return snek_float_to_poly(random_x % mod);
}

#ifdef HAVE_SEMIHOST
static uint32_t
centisecs(void)
{
/* QEMU uses real time for elapsed, but CPU time for clock */
uint64_t elapsed = sys_semihost_elapsed();
uint64_t tickfreq = sys_semihost_tickfreq();
#ifdef _HAVE_SEMIHOST
return (uint32_t) (sys_semihost_elapsed() / (sys_semihost_tickfreq()/100));
#else
struct timeval tv;
gettimeofday(&tv, NULL);

return (uint32_t) (elapsed / (tickfreq / 100));
}
uint32_t centi = tv.tv_sec * 100 + tv.tv_usec / 10000;
return centi;
#endif
}

snek_poly_t
snek_builtin_time_monotonic(void)
{
#ifdef HAVE_SEMIHOST
return snek_float_to_poly((float) centisecs() * 0.01f);
#else
static float now;
now += 0.01;
return snek_float_to_poly(now);
#endif
}

snek_poly_t
snek_builtin_time_sleep(snek_poly_t a)
{
#ifdef HAVE_SEMIHOST
if (snek_poly_type(a) == snek_float) {
int32_t csecs = floorf(snek_poly_to_float(a) * 100.0f);
uint32_t then = centisecs() + csecs;

while ((int32_t) (then - centisecs()) > 0)
;
}
#endif
return SNEK_NULL;
}

Expand All @@ -133,29 +131,15 @@ int snek_qemu_getc(void)
return snek_io_getc(stdin);
}

#ifdef HAVE_SEMIHOST
#define CMDLINE_SIZE 128
static char cmdline[CMDLINE_SIZE];
#endif

int
main(void)
main(int argc, char **argv)
{
snek_init();

#ifdef HAVE_SEMIHOST
char *file = NULL;

/* This returns the whole command line, including argv[0] */
if (sys_semihost_get_cmdline(cmdline, CMDLINE_SIZE - 1) == 0) {

/* Skip to the first argument. This assumes there
* are no spaces in the command name
*/
file = strchr(cmdline, ' ');
if (file)
file++;
}
if (argc > 1)
file = argv[1];

if (file) {
snek_file = file;
Expand All @@ -164,9 +148,7 @@ main(void)
printf("\"%s\": cannot open\n", file);
exit(1);
}
} else
#endif
{
} else {
snek_interactive = true;
printf("Welcome to snek " SNEK_VERSION "\n");
}
Expand Down
2 changes: 1 addition & 1 deletion chips/qemu/snek-qemu.defs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ PICOLIBC_CFLAGS= \

OPT?=-Os

CFLAGS=$(ARCH_CFLAGS) --oslib=semihost \
CFLAGS=$(ARCH_CFLAGS) --oslib=semihost --crt0=semihost \
-std=gnu99 $(OPT) -g \
-I. -I$(SNEK_QEMU) -I$(SNEK_ROOT) $(PICOLIBC_CFLAGS) $(SNEK_CFLAGS)

Expand Down
15 changes: 11 additions & 4 deletions ports/qemu-arm/snek-arm.in
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/bin/sh
here=`dirname $0`
args="arg='snek'"
args=""
extra=""
for i in "$@"; do
case "$i" in
-*)
extra="$extra $i"
;;
*)
args="$args,arg=$i"
case "$args" in
"")
args="$i"
;;
*)
args="$args $i"
;;
esac
;;
esac
done
Expand All @@ -19,5 +26,5 @@ cpu=cortex-m3
chardev="-chardev stdio,mux=on,id=stdio0"
serial="-serial none"
mon="-monitor none"
semihost="-semihosting-config enable=on,chardev=stdio0,$args"
$qemu $chardev $serial $mon $semihost -machine $machine -cpu $cpu -kernel $elf -nographic -bios none $extra
semihost="enable=on,chardev=stdio0,arg=$args"
$qemu $chardev $serial $mon -semihosting-config "$semihost" -machine $machine -cpu $cpu -kernel $elf -nographic -bios none $extra
15 changes: 11 additions & 4 deletions ports/qemu-riscv/snek-riscv.in
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/bin/sh
here=`dirname $0`
args="arg='snek'"
args=""
extra=""
for i in "$@"; do
case "$i" in
-*)
extra="$extra $i"
;;
*)
args="$args,arg=$i"
case "$args" in
"")
args="$i"
;;
*)
args="$args $i"
;;
esac
;;
esac
done
Expand All @@ -19,5 +26,5 @@ cpu=sifive-e31
chardev="-chardev stdio,mux=on,id=stdio0"
serial="-serial none"
mon="-monitor none"
semihost="-semihosting-config enable=on,chardev=stdio0,$args"
$qemu $chardev $serial $mon $semihost -machine $machine -cpu $cpu -kernel $elf -nographic -bios none $extra
semihost="enable=on,chardev=stdio0,arg=$args"
$qemu $chardev $serial $mon -semihosting-config "$semihost" -machine $machine -cpu $cpu -kernel $elf -nographic -bios none $extra

0 comments on commit 53a3d3c

Please sign in to comment.