/* well-known capabilities */
extern struct capref cap_root, cap_monitorep, cap_irq, cap_io, cap_dispatcher,
cap_selfep, cap_kernel, cap_initep, cap_perfmon, cap_dispframe,
- cap_sessionid, cap_ipi, cap_vroot;
+ cap_sessionid, cap_ipi, cap_vroot, cap_argcn;
/**
* \brief Returns the number of valid bits in the CSpace address of a cap
#define INT_ROUTE_CLIENT_H_
errval_t int_route_client_connect(void);
+errval_t int_route_client_route(struct capref intsrc, struct capref intdest);
#endif /* INT_ROUTE_CLIENT_H_ */
#ifndef PCI_CLIENT_DEBUG_H
#define PCI_CLIENT_DEBUG_H
-#define PCI_LIB_DEBUG 1
+#define PCI_LIB_DEBUG
#if defined(PCI_LIB_DEBUG) || defined(GLOBAL_DEBUG)
-#define PCI_CLIENT_DEBUG(x...) printf("pci_client: " x)
+#define PCI_CLIENT_DEBUG(x...) debug_printf("pci_client: " x)
#else
#define PCI_CLIENT_DEBUG(x...) ((void)0)
#endif
int i;
bool i_usable = false;
- for (i = 0; i < NDISPATCH; i++) {
+ for (i = NEXCEPTIONS+1; i < NDISPATCH; i++) {
i_usable = true;
//Iterate over all kcbs
struct kcb *k = kcb_current;
.size_bits = DEFAULT_CNODE_BITS, \
.guard_size = 0 }
+/// Capability for ArgSpace
+struct capref cap_argcn = {
+ .cnode = ROOT_CNODE_INIT,
+ .slot = ROOTCN_SLOT_ARGCN
+};
+
/// Capability for monitor endpoint
struct capref cap_monitorep = {
.cnode = ROOT_CNODE_INIT,
case ObjType_IRQTable:
return snprintf(buf, len, "IRQTable cap");
+ case ObjType_IRQSrc:
+ return snprintf(buf, len, "IRQSrc cap (vec: %"PRIu64")",
+ cap->u.irqsrc.vector);
+
case ObjType_IRQDest:
return snprintf(buf, len, "IRQDest cap (vec: %"PRIu64", cpu: %"PRIu64")",
cap->u.irqdest.vector, cap->u.irqdest.cpu);
#include <int_route/int_route_debug.h>
#include <if/int_route_service_defs.h>
-//#include <if/int_route_service_rpcclient_defs.h>
+#include <if/int_route_service_rpcclient_defs.h>
static struct int_route_state {
bool request_done;
struct int_route_rpc_client * client;
struct int_route_service_binding * binding;
+ struct int_route_service_rpc_client rpc_client;
} int_route_state_st;
static void bind_cb(void *st, errval_t binderr, struct int_route_service_binding *b) {
assert(err_is_ok(binderr));
- get_int_route_state()->binding = b;
+ errval_t err;
+ int_route_state_st.binding = b;
+ int_route_state_st.request_done = true;
+
+ err = int_route_service_rpc_client_init(&(int_route_state_st.rpc_client), b);
+ assert(err_is_ok(err));
}
//errval_t int_route_add_controller(int bus, int dev, int fun,
// return b->tx_vtbl.route_call(b, NULL, intin, dest);
//}
+errval_t int_route_client_route(struct capref intsrc, struct capref intdest){
+ assert(int_route_state_st.request_done);
+ struct int_route_service_rpc_client * cl = &int_route_state_st.rpc_client;
+ errval_t msgerr, err;
+ msgerr = cl->vtbl.route(cl, intsrc, intdest, &err);
+ if(err_is_fail(msgerr)){
+ return msgerr;
+ }
+ return err;
+}
+
errval_t int_route_client_connect(void){
errval_t err;
iref_t iref;
err = skb_execute(query);
if(err_is_fail(err)){
DEBUG_ERR(err, "Error executing: %s.\n", query);
- b->rx_vtbl.route_response(b, err);
+ b->tx_vtbl.route_response(b, NOP_CONT, err);
return;
}
if(err_is_fail(err)){
DEBUG_ERR(err, "Error read_route_and_tell_controllers.\n");
}
- b->rx_vtbl.route_response(b, err);
+ b->tx_vtbl.route_response(b, NOP_CONT, err);
}
static void ctrl_register_controller(struct int_route_controller_binding *_binding,
}
- // HACK: Due to cyclic dependency, we must make sure the service has been exported before
+ // XXX: Due to cyclic dependency, we must make sure the service has been exported before
// returning.
while(exported != 2){
#include <if/acpi_rpcclient_defs.h>
#include <acpi_client/acpi_client.h>
#include <int_route/int_model.h>
+#include <int_route/int_route_client.h>
#define INVALID_VECTOR ((uint64_t)-1)
&nbars, caps_per_bar, caps_per_bar + 1, caps_per_bar + 2,
caps_per_bar + 3, caps_per_bar + 4, caps_per_bar + 5);
if (err_is_fail(err)) {
+ PCI_CLIENT_DEBUG("init pci device failed.\n");
return err;
} else if (err_is_fail(msgerr)) {
return msgerr;
}
- struct capref irq_src_cap;
- // Get vector 0 of the device.
- // For backward compatibility with function interface.
- err = pci_client->vtbl.get_irq_cap(pci_client, 0, &msgerr, &irq_src_cap);
- if (err_is_fail(err) || err_is_fail(msgerr)) {
- if (err_is_ok(err)) {
- err = msgerr;
- }
- DEBUG_ERR(err, "requesting cap for IRQ 0 of device");
- goto out;
+ // Check for cap argument
+ struct capability cap_argcn_data;
+ err = debug_cap_identify(cap_argcn, &cap_argcn_data);
+ if(err_is_fail(err) || cap_argcn_data.type == ObjType_Null){
+ PCI_CLIENT_DEBUG("No capabilites passed as argument. Driver not started by kaluga?");
+ }
+
+ // We use the first passed vector of the device,
+ // for backward compatibility with function interface.
+ struct capref irq_src_cap;
+ struct capability irq_src_cap_data;
+ irq_src_cap.cnode = build_cnoderef(cap_argcn, DEFAULT_CNODE_BITS);
+ irq_src_cap.slot = 0;
+ err = debug_cap_identify(irq_src_cap, &irq_src_cap_data);
+ if(err_is_fail(err)){
+ DEBUG_ERR(err, "Could not identify cap?");
+ }
+ if(irq_src_cap_data.type != ObjType_IRQSrc){
+ PCI_CLIENT_DEBUG("First cap argument ist not of type IRQSrc (is=%d)."
+ "Driver not started by kaluga?\n", cap_argcn_data.type);
}
uint64_t gsi = INVALID_VECTOR;
DEBUG_ERR(err, "Could not lookup GSI vector");
return err;
}
- PCI_CLIENT_DEBUG("Got irqsrc cap, gsi: %"PRIu32"\n", gsi);
+ PCI_CLIENT_DEBUG("Got irqsrc cap, gsi: %"PRIu64"\n", gsi);
// Get irq_dest_cap from monitor
struct capref irq_dest_cap;
DEBUG_ERR(err, "Could not lookup irq vector");
return err;
}
- PCI_CLIENT_DEBUG("Got dest cap, vector: %"PRIu32"\n", irq_dest_vec);
+ PCI_CLIENT_DEBUG("Got dest cap, vector: %"PRIu64"\n", irq_dest_vec);
- // Setup routing
- // TODO: Instead of getting the vectors of each cap and set up routing,
- // pass both to a routing service and let the service handle the setup.
- struct acpi_rpc_client* cl = get_acpi_rpc_client();
- errval_t ret_error;
- err = cl->vtbl.enable_and_route_interrupt(cl, gsi, disp_get_core_id(), irq_dest_vec, &ret_error);
- assert(err_is_ok(err));
- if (err_is_fail(ret_error)) {
- DEBUG_ERR(ret_error, "failed to route interrupt %d -> %d\n", gsi, irq_dest_vec);
- return err_push(ret_error, PCI_ERR_ROUTING_IRQ);
+ err = int_route_client_route(irq_src_cap, irq_dest_cap);
+ if(err_is_fail(err)){
+ DEBUG_ERR(err, "Could not set up route.");
+ return err;
+ } else {
+ PCI_CLIENT_DEBUG("Int route set-up success.\n");
}
+ //// Setup routing
+ //// TODO: Instead of getting the vectors of each cap and set up routing,
+ //// pass both to a routing service and let the service handle the setup.
+ //struct acpi_rpc_client* cl = get_acpi_rpc_client();
+ //errval_t ret_error;
+ //err = cl->vtbl.enable_and_route_interrupt(cl, gsi, disp_get_core_id(), irq_dest_vec, &ret_error);
+ //assert(err_is_ok(err));
+ //if (err_is_fail(ret_error)) {
+ // DEBUG_ERR(ret_error, "failed to route interrupt %d -> %d\n", gsi, irq_dest_vec);
+ // return err_push(ret_error, PCI_ERR_ROUTING_IRQ);
+ //}
+
// Connect endpoint to handler
if(handler != NULL){
err = inthandler_setup_movable_cap(irq_dest_cap, handler, handler_arg,
iref_t iref;
errval_t err, err2 = SYS_ERR_OK;
+ PCI_CLIENT_DEBUG("Connecting to acpi\n");
err = connect_to_acpi();
if(err_is_fail(err)){
return err;
}
+ PCI_CLIENT_DEBUG("Connected to ACPI\n");
/* Connect to the pci server */
+ PCI_CLIENT_DEBUG("Looking up pci iref\n");
err = nameservice_blocking_lookup("pci", &iref);
if (err_is_fail(err)) {
return err;
assert(iref != 0);
+ PCI_CLIENT_DEBUG("Connecting to pci\n");
/* Setup flounder connection with pci server */
err = pci_bind(iref, bind_cont, &err2, get_default_waitset(),
IDC_BIND_FLAG_RPC_CAP_TRANSFER);
messages_wait_and_handle_next();
}
+ if(err_is_ok(err2)){
+ PCI_CLIENT_DEBUG("PCI connection successful, connecting to int route service\n");
+ err = int_route_client_connect();
+ if(err_is_ok(err)){
+ PCI_CLIENT_DEBUG("Int route service connected.\n");
+ } else {
+ DEBUG_ERR(err, "Could not connect to int route service\n");
+ }
+ }
return err2;
}
#define BOOT_MODULES_H_
#include <barrelfish/barrelfish.h>
+#include <int_route/int_model.h>
struct module_info;
struct int_startup_argument;
+
+struct driver_argument {
+ struct capref arg_caps;
+ struct int_startup_argument int_arg;
+
+};
typedef errval_t(*module_start_fn)(coreid_t where, struct module_info* mi,
- char* record, struct int_startup_argument * int_arg);
+ char* record, struct driver_argument * int_arg);
#define MAX_DRIVER_INSTANCES 16
errval_t default_start_function(coreid_t where,
struct module_info* mi,
- char* record, struct int_startup_argument * int_arg)
+ char* record, struct driver_argument * arg)
{
assert(mi != NULL);
errval_t err = SYS_ERR_OK;
&bus, &dev, &fun, &vendor_id, &device_id);
char * int_arg_str = NULL;
- if(int_arg != NULL){
+ if(arg != NULL){
// This malloc int_arg_str
- int_startup_argument_to_string(int_arg, &int_arg_str);
+ int_startup_argument_to_string(&(arg->int_arg), &int_arg_str);
KALUGA_DEBUG("Adding int_arg_str: %s\n", int_arg_str);
argv_push(&argc, &argv, int_arg_str);
}
}
- err = spawn_program(core, mi->path, argv,
- environ, 0, get_did_ptr(mi));
+ //err = spawn_program(core, mi->path, argv,
+ // environ, 0, get_did_ptr(mi));
+
+ struct capref arg_cap = NULL_CAP;
+ if(arg != NULL){
+ arg_cap = arg->arg_caps;
+ }
+ err = spawn_program_with_caps(core, mi->path, argv,
+ environ, NULL_CAP, arg_cap, 0, get_did_ptr(mi));
if (err_is_fail(err)) {
DEBUG_ERR(err, "Spawning %s failed.", mi->path);
errval_t start_networking(coreid_t core,
struct module_info* driver,
- char* record, struct int_startup_argument * intarg)
+ char* record, struct driver_argument * arg)
{
assert(driver != NULL);
errval_t err = SYS_ERR_OK;
struct int_startup_argument;
errval_t default_start_function(coreid_t, struct module_info*, char*,
- struct int_startup_argument * int_arg);
+ struct driver_argument * arg);
errval_t start_networking(coreid_t, struct module_info*, char*,
- struct int_startup_argument * int_arg);
+ struct driver_argument * arg);
#endif /* DRIVER_STARTUP_H_ */
}
errval_t start_boot_driver(coreid_t where, struct module_info* mi,
- char* record, struct int_startup_argument * int_arg)
+ char* record, struct driver_argument * int_arg)
{
assert(mi != NULL);
errval_t err;
errval_t wait_for_all_spawnds(void);
errval_t start_boot_driver(coreid_t where,
struct module_info* mi,
- char* record, struct int_startup_argument * int_arg);
+ char* record, struct driver_argument * int_arg);
#endif /* START_CPU_H_ */
USER_PANIC_ERR(err, "Could not parse SKB output: %s\n", skb_get_output());
}
int_arg.model = int_model_in;
+
+ struct driver_argument driver_arg;
+ driver_arg.int_arg = int_arg;
if(int_arg.model == INT_MODEL_LEGACY){
KALUGA_DEBUG("Starting driver with legacy interrupts\n");
// No controller has to instantiated, but we need to get caps for the int numbers
struct list_parser_status pa_sta;
skb_read_list_init(&pa_sta);
int int_num;
- while(skb_read_list(&pa_sta, "int(%d)", &int_num)){
+ struct cnoderef argnode_ref;
+ err = cnode_create(&driver_arg.arg_caps, &argnode_ref,
+ DEFAULT_CNODE_SLOTS, NULL);
+
+ if(err_is_fail(err)){
+ USER_PANIC_ERR(err, "Could not create int_src cap");
+ }
+
+ for(int i=0; skb_read_list(&pa_sta, "int(%d)", &int_num); i++){
//Works
KALUGA_DEBUG("Interrupt for driver: %d\n", int_num);
+ struct capref cap;
+ cap.cnode = argnode_ref;
+ cap.slot = i;
+ err = sys_debug_create_irq_src_cap(cap, int_num);
+
+ if(err_is_fail(err)){
+ USER_PANIC_ERR(err, "Could not create int_src cap");
+ }
}
} else if(int_arg.model == INT_MODEL_MSI){
KALUGA_DEBUG("Starting driver with MSI interrupts");
// If we've come here the core where we spawn the driver
// is already up
- err = mi->start_function(core, mi, device_record, &int_arg);
+ err = mi->start_function(core, mi, device_record, &driver_arg);
switch (err_no(err)) {
case SYS_ERR_OK:
KALUGA_DEBUG("Spawned PCI driver: %s\n", mi->binary);
[ build application { target = "irqtest",
cFiles = [ "irqtest.c", "e1000n_helpers.c", "e1000n_hwinit.c" ],
- addLibraries = libDeps [ "pci" ],
+ addLibraries = libDeps [ "pci", "int_route_client" ],
mackerelDevices = [ "e1000" ]
}
]
{
errval_t err;
+ IRQ_DEBUG("Printing Caps:\n");
+ debug_my_cspace();
+ IRQ_DEBUG("Printing Caps Done\n");
+
/** Parse command line arguments. */
IRQ_DEBUG("irq test started.\n");
IRQ_DEBUG("Could not parse int argument");
}
+ if (argc > 1) {
+ uint32_t parsed = sscanf(argv[argc - 1], "%x:%x:%x:%x:%x", &vendor,
+ &deviceid, &bus, &device, &function);
+ if (parsed != 5) {
+ IRQ_DEBUG("Driver seems not to be started by Kaluga.\n");
+ vendor = PCI_DONT_CARE;
+ deviceid = PCI_DONT_CARE;
+ bus = PCI_DONT_CARE;
+ device = PCI_DONT_CARE;
+ function = PCI_DONT_CARE;
+ } else {
+ IRQ_DEBUG("Parsed Kaluga argument: PCI Device (%u, %u, %u) Vendor: 0x%04x, Device 0x%04x\n",
+ bus, device, function, vendor, deviceid);
+ // remove the last argument
+ argc--;
+ }
+ }
+
for (int i = 1; i < argc; i++) {
IRQ_DEBUG("arg %d = %s\n", i, argv[i]);
if (strcmp(argv[i], "auto") == 0) {
strcmp(argv[i], "--help") == 0) {
//exit_help(argv[0]);
} else {
- IRQ_DEBUG("Parsed Kaluga device address %s.\n", argv[i]);
+ IRQ_DEBUG("Ignoring %s.\n", argv[i]);
}
} // end for :
IRQ_DEBUG("Connecting to PCI.\n");
-
err = pci_client_connect();
assert(err_is_ok(err));
+ IRQ_DEBUG("########### Driver with interrupts ###########\n");
err = pci_register_driver_movable_irq(e1000_init_fn, class, subclass, program_interface,
vendor, deviceid, bus, device, function,
e1000_interrupt_handler_fn, NULL,
e1000_reregister_handler,
NULL);
- IRQ_DEBUG("########### Driver with interrupts ###########\n");
if (err_is_fail(err)) {