DEBUG_GET_APIC_TIMER,
DEBUG_GET_APIC_TICKS_PER_SEC,
DEBUG_FEIGN_FRAME_CAP,
+ DEBUG_TRACE_PMEM_CTRL,
+ DEBUG_GET_APIC_ID
};
#endif //BARRELFISH_KPI_SYS_DEBUG_H
#include <init.h>
#include <arch/x86/kputchar.h>
#include "xapic_dev.h"
+ #ifdef __k1om__
+ #include <target/k1om/offsets_target.h>
+ #include <barrelfish_kpi/asm_inlines_arch.h>
+ #else
#include <target/x86_64/offsets_target.h>
+ #endif
#include <target/x86_32/offsets_target.h>
+ #ifdef __k1om__
+ #define STARTUP_TIMEOUT 0xffffff
+ #else
-#define STARTUP_TIMEOUT 0xffffff
+#define STARTUP_TIMEOUT 0xfffffff
-
+ #endif
/**
* start_ap and start_ap_end mark the start end the end point of the assembler
* startup code to be copied
retval.value = timing_get_apic_ticks_per_sec();
break;
+ case DEBUG_TRACE_PMEM_CTRL:
+#ifdef TRACE_PMEM_CAPS
+ if (arg1) {
+ caps_trace_ctrl(arg1, args[0], args[1]);
+ } else {
+ caps_trace_ctrl(arg1, 0, 0);
+ }
+#endif
+ retval.value = 0;
+ retval.error = SYS_ERR_OK;
+ break;
+
+
+ case DEBUG_GET_APIC_ID:
+ retval.value = apic_get_id();
+ break;
+
default:
printk(LOG_ERR, "invalid sys_debug msg type\n");
}
memset((void*)lvaddr, 0, 1UL << bits);
trace_event(TRACE_SUBSYS_KERNEL, TRACE_EVENT_KERNEL_BZERO, 0);
- for(size_t i = 0; i < numobjs; i++) {
+ for(dest_i = 0; dest_i < numobjs; dest_i++) {
// Initialize type specific fields
src_cap.u.vnode_x86_64_pml4.base =
- genpaddr + i * ((genpaddr_t)1 << objbits_vnode);
+ genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
+ #ifdef __k1om__
+ lpaddr_t var = gen_phys_to_local_phys(src_cap.u.vnode_x86_64_pml4.base);
+ paging_k1om_make_good_pml4(var);
+ #else
#ifdef __x86_64__
// Make it a good PML4 by inserting kernel/mem VSpaces
lpaddr_t var =
gen_phys_to_local_phys(src_cap.u.vnode_x86_64_pml4.base);
paging_x86_64_make_good_pml4(var);
#endif
+ #endif
// Insert the capability
- err = set_cap(&dest_caps[i].cap, &src_cap);
+ err = set_cap(&dest_caps[dest_i].cap, &src_cap);
if (err_is_fail(err)) {
- return err;
+ break;
}
}
bool present;
};
+ struct arrakis_bind_retst {
+ errval_t err;
+ struct arrakis_binding *b;
+ bool present;
+ };
+
static void spawn_bind_cont(void *st, errval_t err, struct spawn_binding *b)
{
+ debug_printf("bind_cont\n");
struct spawn_bind_retst *retst = st;
assert(retst != NULL);
assert(!retst->present);
struct waitset *mon_ws = mb->waitset;
mb->change_waitset(mb, &cl->rpc_waitset);
--
-
-
if (capref_is_null(inheritcn_cap) && capref_is_null(argcn_cap)) {
err = cl->vtbl.spawn_domain(cl, path, argstr, argstrlen,
- envstr, envstrlen,
+ envstr, envstrlen, flags,
&msgerr, &domain_id);
} else {
err = cl->vtbl.spawn_domain_with_caps(cl, path, argstr, argstrlen,
return msgerr;
}
+ errval_t spawn_arrakis_program(coreid_t coreid, const char *path,
+ char *const argv[], char *const envp[],
+ struct capref inheritcn_cap,
+ struct capref argcn_cap, spawn_flags_t flags,
+ domainid_t *ret_domainid)
+ {
+ struct arrakis_rpc_client *cl;
+ errval_t err, msgerr;
+
+ // default to copying our environment
+ if (envp == NULL) {
+ envp = environ;
+ }
+
+ // do we have a arrakis client connection for this core?
+ assert(coreid < MAX_CPUS);
+ cl = get_arrakis_rpc_client(coreid);
+ if (cl == NULL) {
+ char namebuf[16];
+ snprintf(namebuf, sizeof(namebuf), "arrakis.%u", coreid);
+ namebuf[sizeof(namebuf) - 1] = '\0';
+
+ iref_t iref;
+ err = nameservice_blocking_lookup(namebuf, &iref);
+ if (err_is_fail(err)) {
+ //DEBUG_ERR(err, "arrakis daemon on core %u not found\n", coreid);
+ return err;
+ }
+
+ // initiate bind
+ struct arrakis_bind_retst bindst = { .present = false };
+ err = arrakis_bind(iref, arrakis_bind_cont, &bindst, get_default_waitset(),
+ IDC_BIND_FLAGS_DEFAULT);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "arrakis_bind failed");
+ }
+
+ // XXX: block for bind completion
+ while (!bindst.present) {
+ messages_wait_and_handle_next();
+ }
+
+ if(err_is_fail(bindst.err)) {
+ USER_PANIC_ERR(bindst.err, "asynchronous error during arrakis_bind");
+ }
+ assert(bindst.b != NULL);
+
+ cl = malloc(sizeof(struct arrakis_rpc_client));
+ assert(cl != NULL);
+
+ err = arrakis_rpc_client_init(cl, bindst.b);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "arrakis_rpc_client_init failed");
+ }
+
+ set_arrakis_rpc_client(coreid, cl);
+ }
+
+ // construct argument "string"
+ // \0-separated strings in contiguous character buffer
+ // this is needed, as flounder can't send variable-length arrays of strings
+ size_t argstrlen = 0;
+ for (int i = 0; argv[i] != NULL; i++) {
+ argstrlen += strlen(argv[i]) + 1;
+ }
+
+ char argstr[argstrlen];
+ size_t argstrpos = 0;
+ for (int i = 0; argv[i] != NULL; i++) {
+ strcpy(&argstr[argstrpos], argv[i]);
+ argstrpos += strlen(argv[i]);
+ argstr[argstrpos++] = '\0';
+ }
+ assert(argstrpos == argstrlen);
+
+ // repeat for environment
+ size_t envstrlen = 0;
+ for (int i = 0; envp[i] != NULL; i++) {
+ envstrlen += strlen(envp[i]) + 1;
+ }
+
+ char envstr[envstrlen];
+ size_t envstrpos = 0;
+ for (int i = 0; envp[i] != NULL; i++) {
+ strcpy(&envstr[envstrpos], envp[i]);
+ envstrpos += strlen(envp[i]);
+ envstr[envstrpos++] = '\0';
+ }
+ assert(envstrpos == envstrlen);
+
+
+ domainid_t domain_id;
+
+ // make an unqualified path absolute using the $PATH variable
+ // TODO: implement search (currently assumes PATH is a single directory)
+ char *searchpath = getenv("PATH");
+ if (searchpath == NULL) {
+ searchpath = VFS_PATH_SEP_STR; // XXX: just put it in the root
+ }
+ size_t buflen = strlen(path) + strlen(searchpath) + 2;
+ char pathbuf[buflen];
+ if (path[0] != VFS_PATH_SEP) {
+ snprintf(pathbuf, buflen, "%s%c%s", searchpath, VFS_PATH_SEP, path);
+ pathbuf[buflen - 1] = '\0';
+ //vfs_path_normalise(pathbuf);
+ path = pathbuf;
+ }
+
+ err = cl->vtbl.spawn_arrakis_domain(cl, path, argstr, argstrlen,
+ envstr, envstrlen, &msgerr, &domain_id);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "error sending arrakis request");
+ } else if (err_is_fail(msgerr)) {
+ return msgerr;
+ }
+
+ if (ret_domainid != NULL) {
+ *ret_domainid = domain_id;
+ }
+
++out:
++ mb->change_waitset(mb, mon_ws);
+ return msgerr;
+ }
+
/**
* \brief Request the spawn daemon on a specific core to spawn a program
ram_set_affinity(old_minbase, old_maxlimit);
#endif
+
// Mark memory as remote
- err = monitor_cap_remote(cpu_memory_cap, true, &has_descendants);
+ err = monitor_remote_relations(cpu_memory_cap, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);
if (err_is_fail(err)) {
return err;
}
while (name_serv_iref == 0) {
messages_wait_and_handle_next();
}
+ #ifdef __k1om__
+ char args[40];
+ snprintf(args, sizeof(args), "0x%016lx 0x%02x", bi->host_msg,
+ bi->host_msg_bits);
+ char *mgr_argv[MAX_CMDLINE_ARGS + 1];
+ spawn_tokenize_cmdargs(args, mgr_argv, ARRAY_LENGTH(mgr_argv));
+ err = spawn_domain_with_args("xeon_phi", mgr_argv,environ);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "failed spawning xeon_phi");
+ return err;
+ }
+ #endif
- /* initialise rcap_db */
- err = rcap_db_init();
- if (err_is_fail(err)) {
- DEBUG_ERR(err, "monitor rcap_db init failed");
- return err;
- }
-
/* Spawn boot domains in menu.lst */
err = spawn_all_domains();
if (err_is_fail(err)) {
vfs_path_normalise(path);
err = spawn(path, argv, argbuf, argbytes, envp, inheritcn_cap, argcn_cap,
- domainid);
+ flags, &domainid);
+ // XXX: do we really want to delete the inheritcn and the argcn here? iaw:
+ // do we copy these somewhere? -SG
if (!capref_is_null(inheritcn_cap)) {
errval_t err2;
err2 = cap_delete(inheritcn_cap);
DEBUG_ERR(err, "spawn");
}
- err = spawn_reply(b, err, domainid);
-
- if (err_is_fail(err)) {
- // not much we can do about this
- DEBUG_ERR(err, "while sending reply in spawn_handler");
- }
-
free(envbuf);
free(path);
+
+ return err;
}
+static void spawn_with_caps_handler(struct spawn_binding *b, char *path,
+ char *argbuf, size_t argbytes,
+ char *envbuf, size_t envbytes,
+ struct capref inheritcn_cap,
+ struct capref argcn_cap)
+{
+ errval_t err;
+ domainid_t newdomid;
+ err = spawn_with_caps_common(path, argbuf, argbytes, envbuf, envbytes,
+ inheritcn_cap, argcn_cap, &newdomid);
+
+ err = spawn_with_caps_reply(b, err, newdomid);
+
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "while sending reply in spawn_with_caps_handler");
+ }
+}
static void spawn_handler(struct spawn_binding *b, char *path, char *argbuf,
- size_t argbytes, char *envbuf, size_t envbytes)
+ size_t argbytes, char *envbuf, size_t envbytes,
+ uint8_t flags)
{
- spawn_with_caps_handler(b, path, argbuf, argbytes, envbuf, envbytes,
- NULL_CAP, NULL_CAP, flags);
+ errval_t err;
+ domainid_t newdomid;
+ err = spawn_with_caps_common(path, argbuf, argbytes, envbuf, envbytes,
+ NULL_CAP, NULL_CAP, &newdomid);
+
+ err = spawn_reply(b, err, newdomid);
+
+ if (err_is_fail(err)) {
+ // not much we can do about this
+ DEBUG_ERR(err, "while sending reply in spawn_handler");
+ }
}
/**