failure I2C_WAIT_FOR_BUS "Wait for bus free timed out",
failure I2C_FAILURE "I2C subsystem failure",
+ // KCB and related errors
+ failure KCB_NOT_FOUND "Did not find the given kcb.",
};
// errors generated by libcaps
KernelCmd_GetGlobalPhys, ///< Get physical address of kernel variable struct global;
KernelCmd_StartCore, ///<
KernelCmd_Add_kcb, ///< add extra kcb to be scheduled
+ KernelCmd_Remove_kcb, ///< remove kcb from scheduling ring
KernelCmd_Count
};
static struct gate_descriptor idt[NIDT] __attribute__ ((aligned (16)));
static int timer_fired = 0;
-extern struct dcb *queue_tail; // from rbed scheduler
#if CONFIG_TRACE && NETWORK_STACK_TRACE
#define TRACE_ETHERSRV_MODE 1
// switch kcb every 5 time slices (SG: I just picked 5 arbitrarily)
if (timer_fired % 5 == 0 && kcb_current->next) {
printk(LOG_NOTE, "switching from kcb(%p) to kcb(%p)\n", kcb_current, kcb_current->next);
- kcb_current = kcb_current->next;
- mdb_init(kcb_current);
- // update queue tail to make associated assembly not choke
- queue_tail = kcb_current->queue_tail;
+ switch_kcb(kcb_current->next);
}
apic_eoi();
assert(kernel_ticks_enabled);
return SYSRET(SYS_ERR_OK);
}
+static struct sysret kernel_remove_kcb(struct capability *kern_cap,
+ int cmd, uintptr_t *args)
+{
+ uint64_t kcb_addr = args[0];
+
+ struct kcb *to_remove = (struct kcb *)kcb_addr;
+ struct kcb *k = kcb_current;
+
+ do {
+ if (k == to_remove) {
+ if (k == kcb_current) {
+ // switch to next available kcb if we're removing the kcb that
+ // is currently being scheduled.
+ switch_kcb(kcb_current->next);
+ }
+ // remove kcb from ring
+ k->prev->next = k->next;
+ k->next->prev = k->prev;
+ if (k->next->next == k->next) {
+ // clear ring to disable switching mechanism if only one kcb
+ // left
+ k->next->next = k->next->prev = NULL;
+ }
+ // clear next and prev of removed kcb to not leak other kcb addrs
+ k->next = k->prev = NULL;
+
+ // break out if we're done
+ return SYSRET(SYS_ERR_OK);
+ }
+ k = k->next;
+ } while (k != kcb_current);
+
+ return SYSRET(SYS_ERR_KCB_NOT_FOUND);
+}
+
+
static struct sysret monitor_get_core_id(struct capability *kernel_cap,
int cmd, uintptr_t *args)
[KernelCmd_GetGlobalPhys] = kernel_get_global_phys,
[KernelCmd_StartCore] = kernel_start_core,
[KernelCmd_Add_kcb] = kernel_add_kcb,
+ [KernelCmd_Remove_kcb] = kernel_remove_kcb,
},
[ObjType_IRQTable] = {
[IRQTableCmd_Set] = handle_irq_table_set,
#include <kernel.h>
#include <capabilities.h>
#include <irq.h>
+#include <mdb/mdb_tree.h>
struct cte;
struct dcb;
// TODO interrupt state
}
+// XXX: this is from RBED, don't know how to properly have this here -SG
+extern struct dcb *queue_tail;
+static inline void switch_kcb(struct kcb *next)
+{
+ kcb_current = next;
+ mdb_init(kcb_current);
+ // update queue tail to make associated assembly not choke
+ queue_tail = kcb_current->queue_tail;
+}
+
#endif
return cap_invoke2(cap_kernel, KernelCmd_Add_kcb, kcb_base).error;
}
+static inline errval_t
+invoke_monitor_remove_kcb(uintptr_t kcb_base)
+{
+ assert(kcb_base);
+
+ return cap_invoke2(cap_kernel, KernelCmd_Remove_kcb, kcb_base).error;
+}
+
#endif