From b892aeaeb6b4f8c2be4ea492a5dbace016f207e4 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 25 May 2022 16:01:24 +0200 Subject: [PATCH] shelly interrupt handler working --- include/spawn/spawn.h | 1 + lib/spawn/spawn.c | 29 +++++++++++++++++++---- usr/shelly/shelly.c | 55 ++++++++++++++++++++++++++++++++++++------- usr/shelly/shelly.h | 12 ++++++++-- 4 files changed, 81 insertions(+), 16 deletions(-) diff --git a/include/spawn/spawn.h b/include/spawn/spawn.h index 8258421..6c9c51d 100644 --- a/include/spawn/spawn.h +++ b/include/spawn/spawn.h @@ -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_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_irq; // < the irq capability for interrupts struct capref vspace_cap_l0_pagetable; diff --git a/lib/spawn/spawn.c b/lib/spawn/spawn.c index 4b2be44..e579ac8 100644 --- a/lib/spawn/spawn.c +++ b/lib/spawn/spawn.c @@ -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.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); 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); @@ -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); 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 lmp_chan_init(&si->init_chan); 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. size_t arg0_base = 0; size_t arg0_size = 0; + size_t arg1_base = 0; + size_t arg1_size = 0; if (strcmp(argv[0], "enet") == 0) { arg0_base = IMX8X_ENET_BASE; arg0_size = IMX8X_ENET_SIZE; } else if (strcmp(argv[0], "shelly") == 0) { arg0_base = IMX8X_UART3_BASE; 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 @@ -523,15 +533,24 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, .cnode = si->cspace_l2_cnode_argcn, .slot = 0 }; - char buf[256]; - debug_print_cap_at_capref(buf, 256, cap_io); - debug_printf(buf); - printf("\n"); - debug_printf("offset=%x\n", arg0_base - IMX8X_START_DEV_RANGE); + // char buf[256]; + // debug_print_cap_at_capref(buf, 256, cap_io); + // debug_printf(buf); + // printf("\n"); + // 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); 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 // afeer: create level 0 page table // the l0 page table is in the first slot (PAGECN_SLOT_VROOT) of the pagecn cnode. diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 9469dfe..9922ce4 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -17,7 +17,7 @@ __attribute__((__used__)) static void shelly_interrupt_handler(void * arg) { // struct shelly_st * shelly_s = (struct shelly_st *) arg; - debug_printf("[shelly_interrupt_handler]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + SHELLY_DEBUG("[shelly_interrupt_handler]\n"); return; } @@ -27,40 +27,77 @@ int main(int argc, char *argv[]) debug_printf("welcome to shelly!\n"); struct shelly_st shelly_s; - //afeer: map device registers + + //afeer: map lpuart registers struct capref cap_arg0 = { .cnode = cnode_arg, .slot = 0 }; 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); - 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; - //TODO: map gic space - err = gic_dist_init(&gic_s, NULL); + err = gic_dist_init(&gic_s, shelly_s.gic_base); 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; - err = lpuart_init(&uart_s, shelly_s.dev_base); + err = lpuart_init(&uart_s, shelly_s.lpuart_base); if (err_is_fail(err)) { USER_PANIC_ERR(err, "couldn't init lpuart"); } + SHELLY_DEBUG("initialized lpuart driver\n"); + struct capref 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"); - struct waitset * ws = get_default_waitset(); - // waitset_init(&ws); + SHELLY_DEBUG("created interrupt cap\n"); + 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)); 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); 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); 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(); + } + } } \ No newline at end of file diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h index 67341eb..8ea68fc 100644 --- a/usr/shelly/shelly.h +++ b/usr/shelly/shelly.h @@ -10,9 +10,17 @@ #ifndef 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 { - void * dev_base; - size_t dev_size; + void * lpuart_base; // < virtual address of the lpuart device registers + void * gic_base; // < virtual address of the gic device registers }; #endif // ndef SHELLY_H_