shelly interrupt handler working
This commit is contained in:
parent
1a600c2409
commit
b892aeaeb6
@ -53,6 +53,7 @@ struct spawninfo {
|
|||||||
struct capref cspace_cap_dispframe; // < A capability to the dispatcher frame, used to communicate between a process and the CPU driver.
|
struct capref cspace_cap_dispframe; // < A capability to the dispatcher frame, used to communicate between a process and the CPU driver.
|
||||||
struct capref cspace_cap_argspage; // < A page containing a list of command line arguments.
|
struct capref cspace_cap_argspage; // < A page containing a list of command line arguments.
|
||||||
struct capref cspace_cap_vspace; // < The frame capability used to store the serialized vspace
|
struct capref cspace_cap_vspace; // < The frame capability used to store the serialized vspace
|
||||||
|
struct capref cspace_cap_irq; // < the irq capability for interrupts
|
||||||
|
|
||||||
struct capref vspace_cap_l0_pagetable;
|
struct capref vspace_cap_l0_pagetable;
|
||||||
|
|
||||||
|
|||||||
@ -468,6 +468,9 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
si->cspace_cap_vspace.cnode = si->cspace_l2_cnode_taskcn;
|
si->cspace_cap_vspace.cnode = si->cspace_l2_cnode_taskcn;
|
||||||
si->cspace_cap_vspace.slot = TASKCN_SLOT_VSPACE;
|
si->cspace_cap_vspace.slot = TASKCN_SLOT_VSPACE;
|
||||||
|
|
||||||
|
si->cspace_cap_irq.cnode = si->cspace_l2_cnode_taskcn;
|
||||||
|
si->cspace_cap_irq.slot = TASKCN_SLOT_IRQ;
|
||||||
|
|
||||||
err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC0, &si->cspace_l2_cnode_slot_alloc_0);
|
err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC0, &si->cspace_l2_cnode_slot_alloc_0);
|
||||||
if (err_is_fail(err)) return err;
|
if (err_is_fail(err)) return err;
|
||||||
err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC1, &si->cspace_l2_cnode_slot_alloc_1);
|
err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC1, &si->cspace_l2_cnode_slot_alloc_1);
|
||||||
@ -495,6 +498,9 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
err = cap_retype(si->cspace_cap_selfep, si->cspace_cap_dispatcher, 0, ObjType_EndPointLMP, 0, 1);
|
err = cap_retype(si->cspace_cap_selfep, si->cspace_cap_dispatcher, 0, ObjType_EndPointLMP, 0, 1);
|
||||||
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_CREATE_SELFEP);
|
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_CREATE_SELFEP);
|
||||||
|
|
||||||
|
err = cap_copy(si->cspace_cap_irq, cap_irq);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
|
||||||
// give the child an endpoint to talk to init
|
// give the child an endpoint to talk to init
|
||||||
lmp_chan_init(&si->init_chan);
|
lmp_chan_init(&si->init_chan);
|
||||||
err = endpoint_create(DEFAULT_LMP_BUF_WORDS, &si->init_chan.local_cap, &si->init_chan.endpoint);
|
err = endpoint_create(DEFAULT_LMP_BUF_WORDS, &si->init_chan.local_cap, &si->init_chan.endpoint);
|
||||||
@ -506,12 +512,16 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
// Set up capability arguments. This would ideally be passed somehow as an argument to spawn instead.
|
// Set up capability arguments. This would ideally be passed somehow as an argument to spawn instead.
|
||||||
size_t arg0_base = 0;
|
size_t arg0_base = 0;
|
||||||
size_t arg0_size = 0;
|
size_t arg0_size = 0;
|
||||||
|
size_t arg1_base = 0;
|
||||||
|
size_t arg1_size = 0;
|
||||||
if (strcmp(argv[0], "enet") == 0) {
|
if (strcmp(argv[0], "enet") == 0) {
|
||||||
arg0_base = IMX8X_ENET_BASE;
|
arg0_base = IMX8X_ENET_BASE;
|
||||||
arg0_size = IMX8X_ENET_SIZE;
|
arg0_size = IMX8X_ENET_SIZE;
|
||||||
} else if (strcmp(argv[0], "shelly") == 0) {
|
} else if (strcmp(argv[0], "shelly") == 0) {
|
||||||
arg0_base = IMX8X_UART3_BASE;
|
arg0_base = IMX8X_UART3_BASE;
|
||||||
arg0_size = IMX8X_UART_SIZE;
|
arg0_size = IMX8X_UART_SIZE;
|
||||||
|
arg1_base = IMX8X_GIC_DIST_BASE;
|
||||||
|
arg1_size = IMX8X_GIC_DIST_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: also map GIC (interrupt controller) for shelly
|
//TODO: also map GIC (interrupt controller) for shelly
|
||||||
@ -523,15 +533,24 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
.cnode = si->cspace_l2_cnode_argcn,
|
.cnode = si->cspace_l2_cnode_argcn,
|
||||||
.slot = 0
|
.slot = 0
|
||||||
};
|
};
|
||||||
char buf[256];
|
// char buf[256];
|
||||||
debug_print_cap_at_capref(buf, 256, cap_io);
|
// debug_print_cap_at_capref(buf, 256, cap_io);
|
||||||
debug_printf(buf);
|
// debug_printf(buf);
|
||||||
printf("\n");
|
// printf("\n");
|
||||||
debug_printf("offset=%x\n", arg0_base - IMX8X_START_DEV_RANGE);
|
// debug_printf("offset=%x\n", arg0_base - IMX8X_START_DEV_RANGE);
|
||||||
err = cap_retype(arg0_cap, cap_io, (arg0_base - IMX8X_START_DEV_RANGE), ObjType_DevFrame, arg0_size, 1);
|
err = cap_retype(arg0_cap, cap_io, (arg0_base - IMX8X_START_DEV_RANGE), ObjType_DevFrame, arg0_size, 1);
|
||||||
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_RETYPE);
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_RETYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg1_base != 0) {
|
||||||
|
struct capref arg1_cap = {
|
||||||
|
.cnode = si->cspace_l2_cnode_argcn,
|
||||||
|
.slot = 1
|
||||||
|
};
|
||||||
|
err = cap_retype(arg1_cap, cap_io, (arg1_base - IMX8X_START_DEV_RANGE), ObjType_DevFrame, arg1_size, 1);
|
||||||
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_RETYPE);
|
||||||
|
}
|
||||||
|
|
||||||
// - Setup the child's vspace
|
// - Setup the child's vspace
|
||||||
// afeer: create level 0 page table
|
// afeer: create level 0 page table
|
||||||
// the l0 page table is in the first slot (PAGECN_SLOT_VROOT) of the pagecn cnode.
|
// the l0 page table is in the first slot (PAGECN_SLOT_VROOT) of the pagecn cnode.
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
__attribute__((__used__))
|
__attribute__((__used__))
|
||||||
static void shelly_interrupt_handler(void * arg) {
|
static void shelly_interrupt_handler(void * arg) {
|
||||||
// struct shelly_st * shelly_s = (struct shelly_st *) arg;
|
// struct shelly_st * shelly_s = (struct shelly_st *) arg;
|
||||||
debug_printf("[shelly_interrupt_handler]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
SHELLY_DEBUG("[shelly_interrupt_handler]\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,40 +27,77 @@ int main(int argc, char *argv[])
|
|||||||
debug_printf("welcome to shelly!\n");
|
debug_printf("welcome to shelly!\n");
|
||||||
|
|
||||||
struct shelly_st shelly_s;
|
struct shelly_st shelly_s;
|
||||||
//afeer: map device registers
|
|
||||||
|
//afeer: map lpuart registers
|
||||||
struct capref cap_arg0 = {
|
struct capref cap_arg0 = {
|
||||||
.cnode = cnode_arg,
|
.cnode = cnode_arg,
|
||||||
.slot = 0
|
.slot = 0
|
||||||
};
|
};
|
||||||
err = paging_map_frame_attr(get_current_paging_state(),
|
err = paging_map_frame_attr(get_current_paging_state(),
|
||||||
(void **) &shelly_s.dev_base, IMX8X_UART_SIZE,
|
(void **) &shelly_s.lpuart_base, IMX8X_UART_SIZE,
|
||||||
cap_arg0, VREGION_FLAGS_READ_WRITE_NOCACHE);
|
cap_arg0, VREGION_FLAGS_READ_WRITE_NOCACHE);
|
||||||
if (err_is_fail(err)) return err;
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "while mapping lpuart registers");
|
||||||
|
|
||||||
|
SHELLY_DEBUG("mapped lpuart\n");
|
||||||
|
|
||||||
|
//afeer: map gic registers
|
||||||
|
struct capref cap_arg1 = {
|
||||||
|
.cnode = cnode_arg,
|
||||||
|
.slot = 1
|
||||||
|
};
|
||||||
|
err = paging_map_frame_attr(get_current_paging_state(),
|
||||||
|
(void**) &shelly_s.gic_base, IMX8X_GIC_DIST_SIZE,
|
||||||
|
cap_arg1, VREGION_FLAGS_READ_WRITE_NOCACHE);
|
||||||
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "while mapping gic registers");
|
||||||
|
|
||||||
|
SHELLY_DEBUG("mapped gic\n");
|
||||||
|
|
||||||
|
//afeer: init gic driver
|
||||||
struct gic_dist_s * gic_s;
|
struct gic_dist_s * gic_s;
|
||||||
//TODO: map gic space
|
err = gic_dist_init(&gic_s, shelly_s.gic_base);
|
||||||
err = gic_dist_init(&gic_s, NULL);
|
|
||||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't init gic_dist interrupts");
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't init gic_dist interrupts");
|
||||||
|
|
||||||
|
SHELLY_DEBUG("initialized gic driver\n");
|
||||||
|
|
||||||
|
//afeer: init lpuart driver
|
||||||
struct lpuart_s * uart_s;
|
struct lpuart_s * uart_s;
|
||||||
err = lpuart_init(&uart_s, shelly_s.dev_base);
|
err = lpuart_init(&uart_s, shelly_s.lpuart_base);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
USER_PANIC_ERR(err, "couldn't init lpuart");
|
USER_PANIC_ERR(err, "couldn't init lpuart");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHELLY_DEBUG("initialized lpuart driver\n");
|
||||||
|
|
||||||
struct capref inter_cap;
|
struct capref inter_cap;
|
||||||
err = inthandler_alloc_dest_irq_cap(IMX8X_UART3_INT, &inter_cap);
|
err = inthandler_alloc_dest_irq_cap(IMX8X_UART3_INT, &inter_cap);
|
||||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't alloc dest cap");
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't alloc dest cap");
|
||||||
|
|
||||||
struct waitset * ws = get_default_waitset();
|
SHELLY_DEBUG("created interrupt cap\n");
|
||||||
// waitset_init(&ws);
|
char buf[256];
|
||||||
|
debug_print_cap_at_capref(buf, 256, inter_cap);
|
||||||
|
debug_printf(buf);
|
||||||
|
|
||||||
|
struct waitset * ws = get_default_waitset();
|
||||||
err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, (void *) &shelly_s));
|
err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, (void *) &shelly_s));
|
||||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler");
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler");
|
||||||
|
|
||||||
|
SHELLY_DEBUG("setup interrupt handler\n");
|
||||||
|
|
||||||
err = gic_dist_enable_interrupt(gic_s, IMX8X_UART3_INT, 0b11111111, 0);
|
err = gic_dist_enable_interrupt(gic_s, IMX8X_UART3_INT, 0b11111111, 0);
|
||||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable gic interrupts");
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable gic interrupts");
|
||||||
|
|
||||||
|
SHELLY_DEBUG("enabled gic interrupt\n");
|
||||||
|
|
||||||
err = lpuart_enable_interrupt(uart_s);
|
err = lpuart_enable_interrupt(uart_s);
|
||||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable lpuart interrupts");
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable lpuart interrupts");
|
||||||
|
|
||||||
|
SHELLY_DEBUG("enabled lpuart interrupt\n");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
err = event_dispatch(ws);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
DEBUG_ERR(err, "in event_dispatch");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -10,9 +10,17 @@
|
|||||||
#ifndef SHELLY_H_
|
#ifndef SHELLY_H_
|
||||||
#define SHELLY_H_
|
#define SHELLY_H_
|
||||||
|
|
||||||
|
#define SHELLY_DEBUG_ON 1
|
||||||
|
|
||||||
|
#if defined(SHELLY_DEBUG_ON)
|
||||||
|
#define SHELLY_DEBUG(x...) debug_printf("[SHELLY_DEBUG] " x);
|
||||||
|
#else
|
||||||
|
#define SHELLY_DEBUG(x, ...) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct shelly_st {
|
struct shelly_st {
|
||||||
void * dev_base;
|
void * lpuart_base; // < virtual address of the lpuart device registers
|
||||||
size_t dev_size;
|
void * gic_base; // < virtual address of the gic device registers
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ndef SHELLY_H_
|
#endif // ndef SHELLY_H_
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user