call power_down_request();
response power_down_response();
+
+ call give_kcb_request(caprep kcb);
+ response give_kcb_response(errval err);
};
/* Scary */
rpc get_kernel_cap(out cap cap);
+
+ rpc forward_kcb_request(in coreid destination, in cap kcb, out errval err);
};
}
static inline errval_t invoke_perfmon_activate(struct capref perfmon_cap,
- uint8_t event, uint8_t perf_umask,
+ uint8_t event, uint8_t perf_umask,
bool kernel, uint8_t counter_id,
- uint64_t counter_value,
+ uint64_t counter_value,
capaddr_t ep_addr)
{
- return cap_invoke7(perfmon_cap, PerfmonCmd_Activate,
- event, perf_umask, counter_id, kernel,
+ return cap_invoke7(perfmon_cap, PerfmonCmd_Activate,
+ event, perf_umask, counter_id, kernel,
counter_value, ep_addr).error;
}
= (void *)((lvaddr_t)&_start_kernel - BASE_PAGE_SIZE);
struct dcb *init_dcb;
-
- kend = rdtscp();
- printf("Time it took to initialize the kernel = %lu\n", kend-kstart);
-
if (apic_is_bsp()) {
if (bsp_coreid != 0) {
my_core_id = bsp_coreid;
setup_default_idt();
idt_initialized = true;
+ kend = rdtscp();
+ printf("Time for the kernel after setup_default_idt = %lu [ms]: %lu\n",
+ kend-kstart, ((357*(kend-kstart))/1000000000));
+
+
// Enable machine check reporting
mcheck_init();
+ kend = rdtscp();
+ printf("Time for the kernel after mcheck_init = %lu [ms]: %lu\n",
+ kend-kstart, ((357*(kend-kstart))/1000000000));
+
+
// Initialize local APIC
apic_init();
+ kend = rdtscp();
+ printf("Time for the kernel after apic_init = %lu [ms]: %lu\n",
+ kend-kstart, ((357*(kend-kstart))/1000000000));
+
+
// do not remove/change this printf: needed by regression harness
//printf("Barrelfish CPU driver starting on x86_64 apic_id %u\n", apic_id);
#include <bench/bench.h>
-//#define DEBUG(x...) debug_printf(x)
-#define DEBUG(x...) ((void)0)
+#define DEBUG(x...) debug_printf(x)
+//#define DEBUG(x...) ((void)0)
uint64_t start = 0;
uint64_t end = 0;
DEBUG("%s:%s:%d: get capability\n",
__FILE__, __FUNCTION__, __LINE__);
- err = oct_get_capability("corexxx", &kcb);
+ int length = snprintf(NULL, 0, "kcb_id_%d", coreid) + 1; // +1 for \0
+ char* kcb_key = (char*)malloc(length);
+ assert (kcb_key != NULL);
+ snprintf(kcb_key, length+1, "kcb_id_%d", coreid);
+
+ DEBUG("%s:%s:%d: oct_get_capability for key = %s\n",
+ __FILE__, __FUNCTION__, __LINE__, kcb_key);
+
+ err = oct_get_capability(kcb_key, &kcb);
if (err_is_ok(err)) {
DEBUG("%s:%s:%d: kcb cap was cached\n",
__FILE__, __FUNCTION__, __LINE__);
DEBUG("%s:%s:%d: Store the kcb.\n",
__FILE__, __FUNCTION__, __LINE__);
- err = oct_put_capability("corexxx", kcb);
+ err = oct_put_capability(kcb_key, kcb);
if (err_is_fail(err)) {
DEBUG_ERR(err, "can not save the capability.");
}
return err;
}
+static errval_t give_kcb_to_new_core(coreid_t destination_id, struct capref new_kcb)
+{
+ struct monitor_blocking_rpc_client *mc = get_monitor_blocking_rpc_client();
+ printf("%s:%s:%d: Send KCB to local monitor for forwarding to destination_id = %"PRIuCOREID"\n",
+ __FILE__, __FUNCTION__, __LINE__, destination_id);
+
+ errval_t ret_err;
+ errval_t err = mc->vtbl.forward_kcb_request(mc, destination_id, new_kcb, &ret_err);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "forward_kcb_request failed.");
+ }
+ if (err_is_fail(ret_err)) {
+ USER_PANIC_ERR(ret_err, "forward_kcb_request failed.");
+ }
+
+ printf("%s:%s:%d: KCB forwarded\n", __FILE__, __FUNCTION__, __LINE__);
+ return SYS_ERR_OK;
+}
int main(int argc, char** argv)
{
start = bench_tsc();
- coreid_t destination = (coreid_t) atoi(argv[3]);
- assert(destination < MAX_COREID);
+ coreid_t target_id = (coreid_t) atoi(argv[3]);
+ assert(target_id < MAX_COREID);
err = oct_init();
if (err_is_fail(err)) {
USER_PANIC_ERR(err, "Octopus initialization failed.");
}
- err = create_or_get_kcb_cap(destination);
+ err = create_or_get_kcb_cap(target_id);
if (err_is_fail(err)) {
USER_PANIC_ERR(err, "Can not get kcb.");
}
memcpy(sched, s, i);
sched[i] = 0;
}
- err = spawn_xcore_monitor(destination, destination, CPU_X86_64, sched,
+ err = spawn_xcore_monitor(target_id, target_id, CPU_X86_64, sched,
"loglevel=0 logmask=1", &new_binding, &frame);
if (err_is_fail(err)) {
USER_PANIC_ERR(err, "spawn xcore monitor failed.");
__FILE__, __FUNCTION__, __LINE__, end-start, bench_tsc_to_ms(end-start));
struct monitor_binding *mb = get_monitor_binding();
- err = mb->tx_vtbl.boot_core_request(mb, NOP_CONT, destination, frame);
+ err = mb->tx_vtbl.boot_core_request(mb, NOP_CONT, target_id, frame);
}
else if (!strcmp(argv[2], "down")) {
DEBUG("%s:%d: Power it down...\n", __FILE__, __LINE__);
- err = st->tx_vtbl.power_down(st, NOP_CONT, destination);
+ err = st->tx_vtbl.power_down(st, NOP_CONT, target_id);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "power_down failed.");
+ }
+ }
+ else if (!strcmp(argv[2], "give")) {
+ assert (argc == 5);
+ DEBUG("%s:%d: Give kcb from core %s to core %s...\n",
+ __FILE__, __LINE__, argv[3], argv[4]);
+
+ coreid_t destination_id = (coreid_t) atoi(argv[4]);
+ assert(destination_id < MAX_COREID);
+
+ err = st->tx_vtbl.power_down(st, NOP_CONT, target_id);
if (err_is_fail(err)) {
USER_PANIC_ERR(err, "power_down failed.");
}
+
+ err = give_kcb_to_new_core(destination_id, kcb);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "Can not send KCB to another core.");
+ }
}
else if (!strcmp(argv[2], "resume")) {
DEBUG("%s:%s:%d: Resume...\n", __FILE__, __FUNCTION__, __LINE__);
//USER_PANIC("Return from power down request?");
}
+static void give_kcb_request(struct intermon_binding *b, intermon_caprep_t kcb_rep)
+{
+ struct capability kcb_cap;
+ caprep_to_capability(&kcb_rep, &kcb_cap);
+ assert(kcb_cap.type != ObjType_Null);
+
+ struct capref kcb_capref;
+ errval_t err = monitor_cap_create(kcb_capref, &kcb_cap, my_core_id);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "monitor_cap_create failed");
+ }
+
+ printf("%s:%s:%d: Remote monitor: give kcb to kernel\n",
+ __FILE__, __FUNCTION__, __LINE__);
+
+ // kcb.u.base ...
+ err = invoke_monitor_add_kcb((uintptr_t)kcb_cap.u.kernelcontrolblock.kcb);
+
+ err = b->tx_vtbl.give_kcb_response(b, NOP_CONT, SYS_ERR_OK);
+ assert(err_is_ok(err));
+}
+
+static void give_kcb_response(struct intermon_binding *b, errval_t error)
+{
+ printf("%s:%s:%d: Local montior received answer\n",
+ __FILE__, __FUNCTION__, __LINE__);
+
+}
+
extern struct monitor_binding* cpuboot_driver;
static void power_down_response(struct intermon_binding* b)
.power_down_request = power_down_request,
.power_down_response = power_down_response,
+
+ .give_kcb_request = give_kcb_request,
+ .give_kcb_response = give_kcb_response,
};
errval_t intermon_init(struct intermon_binding *b, coreid_t coreid)
}
}
+static void forward_kcb_request(struct monitor_blocking_binding *b,
+ coreid_t destination, struct capref kcb)
+{
+ printf("%s:%s:%d: forward_kcb_request in monitor\n",
+ __FILE__, __FUNCTION__, __LINE__);
+
+ errval_t err = SYS_ERR_OK;
+
+ struct capability kcb_cap;
+ err = monitor_cap_identify(kcb, &kcb_cap);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "monitor_cap_identify failed");
+ err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
+ assert(err_is_ok(err));
+ return;
+ }
+
+ if (destination == my_core_id) {
+ printf("%s:%s:%d: Invoke syscall directly, destination==my_core_id\n",
+ __FILE__, __FUNCTION__, __LINE__);
+ err = invoke_monitor_add_kcb((uintptr_t)kcb_cap.u.kernelcontrolblock.kcb);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "invoke_montitor_add_kcb failed.");
+ }
+
+ err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
+ assert(err_is_ok(err));
+ return;
+ }
+
+ struct intermon_binding *ib;
+ err = intermon_binding_get(destination, &ib);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "intermon_binding_get failed");
+ err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
+ assert(err_is_ok(err));
+ return;
+ }
+
+ intermon_caprep_t kcb_rep;
+ capability_to_caprep(&kcb_cap, &kcb_rep);
+
+ err = ib->tx_vtbl.give_kcb_request(ib, NOP_CONT, kcb_rep);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "give_kcb send failed");
+ err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
+ assert(err_is_ok(err));
+ return;
+ }
+}
+
/*------------------------- Initialization functions -------------------------*/
static struct monitor_blocking_rx_vtbl rx_vtbl = {
.cap_set_remote_call = cap_set_remote,
.get_kernel_cap_call = get_kernel_cap,
+
+ .forward_kcb_request_call = forward_kcb_request,
};
static void export_callback(void *st, errval_t err, iref_t iref)