Verified Commit b8940bcd authored by Rahix's avatar Rahix
Browse files

feat(api): Add initial argument passing



This allows pycardium to learn which script it should start once it
boots.  Arguments can only be read before any API calls are made.
Afterward they are lost.

To ensure they won't collide with anything during a core 1 restart,
they are offset by 0x20 from the start of the API buffer.

Signed-off-by: Rahix's avatarRahix <rahix@rahix.de>
parent 32144f97
......@@ -53,3 +53,25 @@ void *_api_call_transact(void *buffer)
return API_CALL_MEM->buffer;
}
int api_fetch_args(char *buf, size_t cnt)
{
if (API_CALL_MEM->id != 0) {
/*
* When any call happened before the args are fetched, they are
* overwritten and no longer accessible.
*/
return (-1);
}
if (API_CALL_MEM->buffer[0x20] == '\0') {
return 0;
}
int i;
for (i = 0; i < cnt && API_CALL_MEM->buffer[i + 0x20] != '\0'; i++) {
buf[i] = API_CALL_MEM->buffer[i + 0x20];
}
return i - 1;
}
......@@ -27,3 +27,12 @@ void *_api_call_start(api_id_t id, uintptr_t size);
* - Pointer to a buffer containing the return value
*/
void *_api_call_transact(void *buffer);
/*
* Fetch arguments from the API buffer. This function will only work properly
* directly after startup of core 1. If api_fetch_args() is called after other
* calls have already happened, it will return -1.
*
* Otherwise it will return the length of data which was read.
*/
int api_fetch_args(char *buf, size_t cnt);
#include <stdlib.h>
#include "sema.h"
#include "api/dispatcher.h"
#include "max32665.h"
#include "sema.h"
#include <stdlib.h>
#include <string.h>
/* This function is defined by the generated dispatcher code */
void __api_dispatch_call(api_id_t id, void *buffer);
static volatile bool event_ready = false;
int api_dispatcher_init()
{
......@@ -20,8 +28,6 @@ int api_dispatcher_init()
return ret;
}
static bool event_ready = false;
bool api_dispatcher_poll_once()
{
if (event_ready) {
......@@ -68,3 +74,15 @@ api_id_t api_dispatcher_exec()
return id;
}
void api_prepare_args(char *args)
{
/*
* The args are stored with an offset of 0x20 to make sure they won't
* collide with any integer return value of API calls like epic_exec().
*/
API_CALL_MEM->id = 0;
for (int i = 0; i <= strlen(args); i++) {
API_CALL_MEM->buffer[i + 0x20] = args[i];
}
}
......@@ -22,5 +22,9 @@ bool api_dispatcher_poll();
*/
api_id_t api_dispatcher_exec();
/* This function is defined by the generated dispatcher code */
void __api_dispatch_call(api_id_t id, void *buffer);
/*
* Fill the API buffer with data for l0dable/pycardium startup.
*
* The data is a NULL-terminated string.
*/
void api_prepare_args(char *args);
#include "epicardium.h"
#include "api/caller.h"
#include "mphalport.h"
#include "card10-version.h"
......@@ -24,10 +25,19 @@ static const char header[] =
int main(void)
{
epic_uart_write_str(header, sizeof(header));
char script_name[128] = { 0 };
int cnt = api_fetch_args(script_name, sizeof(script_name));
pycardium_hal_init();
epic_uart_write_str(header, sizeof(header));
if (cnt < 0) {
printf("pycardium: Error fetching args: %d\n", cnt);
} else if (cnt > 0) {
printf(" Loading %s ...\n", script_name);
}
mp_stack_set_top(&__StackTop);
mp_stack_set_limit((mp_int_t)&__StackLimit);
......@@ -35,8 +45,13 @@ int main(void)
gc_init(&__HeapBase + 1024 * 10, &__HeapLimit);
mp_init();
pyexec_file_if_exists("main.py");
if (cnt > 0) {
pyexec_file_if_exists(script_name);
}
pyexec_friendly_repl();
mp_deinit();
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment