From b821cecc361144dfa665809b9ba0aae46d09a9dd Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 19 Dec 2005 13:40:15 +0000 Subject: [PATCH] Added of_interpret for interpreting arbitrary Forth code. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15588 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../boot/platform/openfirmware/openfirmware.c | 50 +++++++++++++++++++ .../boot/platform/openfirmware/openfirmware.h | 1 + 2 files changed, 51 insertions(+) diff --git a/src/system/boot/platform/openfirmware/openfirmware.c b/src/system/boot/platform/openfirmware/openfirmware.c index 8d1d55b665..1f958131c3 100644 --- a/src/system/boot/platform/openfirmware/openfirmware.c +++ b/src/system/boot/platform/openfirmware/openfirmware.c @@ -69,6 +69,56 @@ of_call_method(const char *method, int numArgs, int numReturns, ...) } +int +of_interpret(const char *command, int numArgs, int numReturns, ...) +{ + struct { + const char *name; + int num_args; + int num_returns; + // "IN: [string] cmd, stack_arg1, ..., stack_argP + // OUT: catch-result, stack_result1, ..., stack_resultQ + // [...] + // An implementation shall allow at least six stack_arg and six + // stack_result items." + const char *command; + void *args[13]; + } args = {"interpret", numArgs + 1, numReturns, command}; + va_list list; + int i; + + // iterate over all arguments and copy them into the + // structure passed over to the OpenFirmware + + va_start(list, numReturns); + for (i = 0; i < numArgs; i++) { + // copy args + args.args[i] = (void *)va_arg(list, void *); + } + for (i = numArgs; i < numArgs + numReturns + 1; i++) { + // clear return values + args.args[i] = NULL; + } + + // args.args[numArgs] is the "catch-result" return value + if (gCallOpenFirmware(&args) == OF_FAILED || args.args[numArgs]) + return OF_FAILED; + + if (numReturns > 0) { + // copy return values over to the provided location + + for (i = numArgs + 1; i < numArgs + 1 + numReturns; i++) { + void **store = va_arg(list, void **); + if (store) + *store = args.args[i]; + } + } + va_end(list); + + return 0; +} + + int of_finddevice(const char *device) { diff --git a/src/system/boot/platform/openfirmware/openfirmware.h b/src/system/boot/platform/openfirmware/openfirmware.h index 17029fdde0..75fe63371c 100644 --- a/src/system/boot/platform/openfirmware/openfirmware.h +++ b/src/system/boot/platform/openfirmware/openfirmware.h @@ -65,6 +65,7 @@ extern void *of_claim(void *virtualAddress, int size, int align); /* misc functions */ extern int of_call_method(const char *method, int numArgs, int numReturns, ...); +extern int of_interpret(const char *command, int numArgs, int numReturns, ...); extern int of_test(const char *service); extern int of_milliseconds(void); extern void of_exit(void);