From 7dddf500675b599fa4d371dfa24539454009524a Mon Sep 17 00:00:00 2001 From: phani Date: Thu, 7 Mar 2019 19:09:33 -0500 Subject: [PATCH 1/7] scb and dcb capabilities and resources * Have SCB capability and resource working. * TODO: DCB capabilities to work. * TODO: Fix the API around SCB frontier. * SCB address in a component will be the start of the heap pointer and the INIT DCB (initial dcb caps that are used when creating the INIT threads in those components) are next to SCB and statically set to be NUM_CPU number of pages. This is the idea to fix their addresses and avoid passing in component_information structure. --- .../tests/unit_defcompinfo/unit_defcompinfo.c | 11 +- .../lib/component/arch/x86/cos_component.h | 21 ++++ src/components/lib/kernel/cos_defkernel_api.c | 49 +++++--- src/components/lib/kernel/cos_defkernel_api.h | 23 ++-- src/components/lib/kernel/cos_kernel_api.c | 117 ++++++++++++++---- src/components/lib/kernel/cos_kernel_api.h | 24 +++- src/components/lib/sl/sl_sched.c | 7 ++ src/kernel/capinv.c | 63 +++++++++- src/kernel/include/captbl.h | 2 +- src/kernel/include/component.h | 35 ++++-- src/kernel/include/dcb.h | 101 +++++++++++++++ src/kernel/include/scb.h | 100 +++++++++++++++ src/kernel/include/shared/cos_types.h | 31 ++++- src/kernel/include/thd.h | 2 + src/platform/i386/boot_comp.c | 112 ++++++++++++++++- 15 files changed, 619 insertions(+), 79 deletions(-) create mode 100644 src/kernel/include/dcb.h create mode 100644 src/kernel/include/scb.h diff --git a/src/components/implementation/tests/unit_defcompinfo/unit_defcompinfo.c b/src/components/implementation/tests/unit_defcompinfo/unit_defcompinfo.c index cd3a55e8f4..262e3fb098 100644 --- a/src/components/implementation/tests/unit_defcompinfo/unit_defcompinfo.c +++ b/src/components/implementation/tests/unit_defcompinfo/unit_defcompinfo.c @@ -56,7 +56,7 @@ test_aeps(void) asndcap_t snd; printc("\tCreating AEP [%lu]\n", i); - ret = cos_aep_tcap_alloc(&(test_aep[i]), BOOT_CAPTBL_SELF_INITTCAP_BASE, aep_thd_fn, (void *)i); + ret = cos_aep_tcap_alloc(&(test_aep[i]), BOOT_CAPTBL_SELF_INITTCAP_BASE, aep_thd_fn, (void *)i, 0, 0); assert(ret == 0); snd = cos_asnd_alloc(ci, test_aep[i].rcv, ci->captbl_cap); @@ -125,7 +125,7 @@ cos_init(void) cos_defcompinfo_init(); for (id = 0; id < CHILD_COMP_COUNT; id++) { - vaddr_t vm_range, addr; + vaddr_t vm_range, addr, dcbaddr; pgtblcap_t child_utpt; int is_sched = ((id == CHILD_SCHED_ID) ? 1 : 0); struct cos_compinfo *child_ci = cos_compinfo_get(&child_defci[id]); @@ -135,8 +135,10 @@ cos_init(void) assert(child_utpt); cos_meminfo_init(&(child_ci->mi), BOOT_MEM_KM_BASE, CHILD_UNTYPED_SIZE, child_utpt); - cos_defcompinfo_child_alloc(&child_defci[id], (vaddr_t)&__cosrt_upcall_entry, - (vaddr_t)BOOT_MEM_VM_BASE, BOOT_CAPTBL_FREE, is_sched); + //cos_defcompinfo_child_alloc(&child_defci[id], (vaddr_t)&__cosrt_upcall_entry, + // (vaddr_t)BOOT_MEM_VM_BASE, BOOT_CAPTBL_FREE, is_sched); + cos_defcompinfo_child_alloc(&child_defci[id], (vaddr_t)&cosrt_upcall_entry, + (vaddr_t)BOOT_MEM_VM_BASE, BOOT_CAPTBL_FREE, is_sched, &dcbaddr); printc("\t\tCopying new capabilities\n"); ret = cos_cap_cpy_at(child_ci, BOOT_CAPTBL_SELF_CT, ci, child_ci->captbl_cap); @@ -147,6 +149,7 @@ cos_init(void) assert(ret == 0); ret = cos_cap_cpy_at(child_ci, BOOT_CAPTBL_SELF_COMP, ci, child_ci->comp_cap); assert(ret == 0); + /* FIXME: copy BOOT_CAPTBL_SELF_SCB cap?? */ ret = cos_cap_cpy_at(child_ci, BOOT_CAPTBL_SELF_INITTHD_BASE, ci, cos_sched_aep_get(&child_defci[id])->thd); diff --git a/src/components/lib/component/arch/x86/cos_component.h b/src/components/lib/component/arch/x86/cos_component.h index ac4431c22d..fcaacc7582 100644 --- a/src/components/lib/component/arch/x86/cos_component.h +++ b/src/components/lib/component/arch/x86/cos_component.h @@ -259,6 +259,27 @@ cos_get_heap_ptr(void) return (void *)__cosrt_comp_info.cos_heap_ptr; } +static inline struct cos_scb_info * +cos_scb_info_get(void) +{ + return (struct cos_scb_info *)(cos_comp_info.cos_heap_ptr); +} + +static inline struct cos_scb_info * +cos_scb_info_get_core(void) +{ + return cos_scb_info_get() + cos_cpuid(); +} + +static inline struct cos_dcb_info * +cos_init_dcb_get(void) +{ + /* created at boot-time for the first component in the system! */ + if (cos_spd_id() == 0) return (struct cos_dcb_info *)(cos_comp_info.cos_heap_ptr + COS_SCB_SIZE + (PAGE_SIZE * cos_cpuid())); + + return NULL; +} + static inline void cos_set_heap_ptr(void *addr) { diff --git a/src/components/lib/kernel/cos_defkernel_api.c b/src/components/lib/kernel/cos_defkernel_api.c index cfb7597e98..f367ca25fc 100644 --- a/src/components/lib/kernel/cos_defkernel_api.c +++ b/src/components/lib/kernel/cos_defkernel_api.c @@ -91,7 +91,7 @@ cos_defcompinfo_sched_init(void) } static int -cos_aep_alloc_intern(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, tcap_t tc, struct cos_aep_info *sched, cos_aepthd_fn_t fn, void *data, thdclosure_index_t idx) +cos_aep_alloc_intern(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, tcap_t tc, struct cos_aep_info *sched, cos_aepthd_fn_t fn, void *data, thdclosure_index_t idx, dcbcap_t dcbcap, dcboff_t dcboff) { struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); struct cos_compinfo *ci = cos_compinfo_get(defci); @@ -101,9 +101,9 @@ cos_aep_alloc_intern(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, assert(curr_defci_init_status == INITIALIZED); memset(aep, 0, sizeof(struct cos_aep_info)); - if (is_init) aep->thd = cos_initthd_alloc(ci, dst_ci->comp_cap); - else if (idx > 0) aep->thd = cos_thd_alloc_ext(ci, dst_ci->comp_cap, idx); - else aep->thd = cos_thd_alloc(ci, dst_ci->comp_cap, cos_aepthd_fn, (void *)aep); + if (is_init) aep->thd = cos_initthd_alloc(ci, dst_ci->comp_cap, dcbcap); + else if (idx > 0) aep->thd = cos_thd_alloc_ext(ci, dst_ci->comp_cap, idx, dcbcap, dcboff); + else aep->thd = cos_thd_alloc(ci, dst_ci->comp_cap, cos_aepthd_fn, (void *)aep, dcbcap, dcboff); assert(aep->thd); aep->tid = cos_introspect(ci, aep->thd, THD_GET_TID); if (!sched && is_init) return 0; @@ -125,7 +125,7 @@ cos_aep_alloc_intern(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, int cos_defcompinfo_child_alloc(struct cos_defcompinfo *child_defci, vaddr_t entry, vaddr_t heap_ptr, capid_t cap_frontier, - int is_sched) + int is_sched, dcbcap_t *initdcbcap) { int ret; struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); @@ -133,11 +133,22 @@ cos_defcompinfo_child_alloc(struct cos_defcompinfo *child_defci, vaddr_t entry, struct cos_compinfo *ci = cos_compinfo_get(defci); struct cos_compinfo *child_ci = cos_compinfo_get(child_defci); struct cos_aep_info *child_aep = cos_sched_aep_get(child_defci); + vaddr_t dcbaddr = 0; + dcbcap_t dcbcap = 0; + scbcap_t scbcap = 0; + + scbcap = cos_scb_alloc(ci); + assert(scbcap); assert(curr_defci_init_status == INITIALIZED); - ret = cos_compinfo_alloc(child_ci, heap_ptr, cap_frontier, entry, ci); + ret = cos_compinfo_alloc(child_ci, scbcap, heap_ptr, cap_frontier, entry, ci); if (ret) return ret; - ret = cos_aep_alloc_intern(child_aep, child_defci, 0, is_sched ? sched_aep : NULL, NULL, NULL, 0); + dcbaddr = (vaddr_t)cos_page_bump_intern_valloc(child_ci, PAGE_SIZE); + assert(dcbaddr); + dcbcap = cos_dcb_alloc(ci, child_ci->pgtbl_cap, dcbaddr); + assert(dcbcap); + ret = cos_aep_alloc_intern(child_aep, child_defci, 0, is_sched ? sched_aep : NULL, NULL, NULL, 0, dcbcap, 0); + *initdcbcap = dcbcap; return ret; } @@ -151,29 +162,29 @@ cos_defcompinfo_childid_init(struct cos_defcompinfo *child_defci, spdid_t c) } int -cos_initaep_alloc(struct cos_defcompinfo *dst_dci, struct cos_aep_info *sched, int is_sched) +cos_initaep_alloc(struct cos_defcompinfo *dst_dci, struct cos_aep_info *sched, int is_sched, dcbcap_t dcap) { struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); struct cos_aep_info *sched_aep = cos_sched_aep_get(defci); struct cos_aep_info *child_aep = cos_sched_aep_get(dst_dci); struct cos_aep_info *sched_use = is_sched ? (sched ? sched : sched_aep) : NULL; - return cos_aep_alloc_intern(child_aep, dst_dci, 0, sched_use, NULL, NULL, 0); + return cos_aep_alloc_intern(child_aep, dst_dci, 0, sched_use, NULL, NULL, 0, dcap, 0); } int -cos_initaep_tcap_alloc(struct cos_defcompinfo *dst_dci, tcap_t tc, struct cos_aep_info *sched) +cos_initaep_tcap_alloc(struct cos_defcompinfo *dst_dci, tcap_t tc, struct cos_aep_info *sched, dcbcap_t dcap) { struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); struct cos_aep_info *sched_aep = cos_sched_aep_get(defci); struct cos_aep_info *child_aep = cos_sched_aep_get(dst_dci); struct cos_aep_info *sched_use = sched ? sched : sched_aep; - return cos_aep_alloc_intern(child_aep, dst_dci, tc, sched_use, NULL, NULL, 0); + return cos_aep_alloc_intern(child_aep, dst_dci, tc, sched_use, NULL, NULL, 0, dcap, 0); } int -cos_aep_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, struct cos_aep_info *sched, thdclosure_index_t idx) +cos_aep_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, struct cos_aep_info *sched, thdclosure_index_t idx, dcbcap_t dcap, dcboff_t doff) { struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); struct cos_aep_info *sched_aep = cos_sched_aep_get(defci); @@ -182,11 +193,11 @@ cos_aep_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, str if (!sched) sched_aep = cos_sched_aep_get(dst_dci); else sched_aep = sched; - return cos_aep_alloc_intern(aep, dst_dci, 0, sched_aep, NULL, NULL, idx); + return cos_aep_alloc_intern(aep, dst_dci, 0, sched_aep, NULL, NULL, idx, dcap, doff); } int -cos_aep_tcap_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, struct cos_aep_info *sched, tcap_t tc, thdclosure_index_t idx) +cos_aep_tcap_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci, struct cos_aep_info *sched, tcap_t tc, thdclosure_index_t idx, dcbcap_t dcap, dcboff_t doff) { struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); struct cos_aep_info *sched_aep = cos_sched_aep_get(defci); @@ -196,25 +207,25 @@ cos_aep_tcap_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *dst_dci if (!sched) sched_aep = cos_sched_aep_get(dst_dci); else sched_aep = sched; - return cos_aep_alloc_intern(aep, dst_dci, tc, sched_aep, NULL, NULL, idx); + return cos_aep_alloc_intern(aep, dst_dci, tc, sched_aep, NULL, NULL, idx, dcap, doff); } int -cos_aep_alloc(struct cos_aep_info *aep, cos_aepthd_fn_t fn, void *data) +cos_aep_alloc(struct cos_aep_info *aep, cos_aepthd_fn_t fn, void *data, dcbcap_t dcap, dcboff_t doff) { struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); struct cos_aep_info *sched_aep = cos_sched_aep_get(defci); - return cos_aep_alloc_intern(aep, defci, 0, sched_aep, fn, data, 0); + return cos_aep_alloc_intern(aep, defci, 0, sched_aep, fn, data, 0, dcap, doff); } int -cos_aep_tcap_alloc(struct cos_aep_info *aep, tcap_t tc, cos_aepthd_fn_t fn, void *data) +cos_aep_tcap_alloc(struct cos_aep_info *aep, tcap_t tc, cos_aepthd_fn_t fn, void *data, dcbcap_t dcap, dcboff_t doff) { struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); struct cos_aep_info *sched_aep = cos_sched_aep_get(defci); - return cos_aep_alloc_intern(aep, defci, tc, sched_aep, fn, data, 0); + return cos_aep_alloc_intern(aep, defci, tc, sched_aep, fn, data, 0, dcap, doff); } int diff --git a/src/components/lib/kernel/cos_defkernel_api.h b/src/components/lib/kernel/cos_defkernel_api.h index fa083c27ef..35e1cb888f 100644 --- a/src/components/lib/kernel/cos_defkernel_api.h +++ b/src/components/lib/kernel/cos_defkernel_api.h @@ -36,7 +36,7 @@ struct cos_aep_info { thdid_t tid; arcvcap_t rcv; cos_aepthd_fn_t fn; - void * data; + void *data; }; /* Default Component information */ @@ -53,7 +53,7 @@ cos_aepthd_fn(void *data) { struct cos_aep_info *aep_info = (struct cos_aep_info *)data; cos_aepthd_fn_t aep_fn = aep_info->fn; - void * fn_data = aep_info->data; + void *fn_data = aep_info->data; (aep_fn)(aep_info->rcv, fn_data); @@ -96,44 +96,49 @@ void cos_defcompinfo_sched_init(void); * cos_defcompinfo_child_alloc: called to create a new child component including initial capabilities like pgtbl, * captbl, compcap, aep. if is_sched is set, scheduling end-point will also be created for the child component, else, * the current component's scheduler will remain the scheduler for the child component. + * TODO: initdcb cap and initdcb addr? */ int cos_defcompinfo_child_alloc(struct cos_defcompinfo *child_defci, vaddr_t entry, vaddr_t heap_ptr, - capid_t cap_frontier, int is_sched); + capid_t cap_frontier, int is_sched, dcbcap_t *initdcbcap); /* * cos_aep_alloc: creates a new async activation end-point which includes thread, tcap and rcv capabilities. * struct cos_aep_info passed in, must not be stack allocated. */ -int cos_aep_alloc(struct cos_aep_info *aep, cos_aepthd_fn_t fn, void *data); +int cos_aep_alloc(struct cos_aep_info *aep, cos_aepthd_fn_t fn, void *data, dcbcap_t dcap, dcboff_t doff); /* * cos_aep_alloc: creates a new async activation end-point, using an existing tcap. * struct cos_aep_info passed in, must not be stack allocated. */ -int cos_aep_tcap_alloc(struct cos_aep_info *aep, tcap_t tc, cos_aepthd_fn_t fn, void *data); +int cos_aep_tcap_alloc(struct cos_aep_info *aep, tcap_t tc, cos_aepthd_fn_t fn, void *data, dcbcap_t dcap, dcboff_t doff); /* * cos_initaep_alloc: create an initaep in the @child_dci and using sched->rcv as the parent, sets up cos_sched_ape_get(@child_dci) with the init capabilities. * if @sched == NULL, use the current scheduler in cos_sched_aep_get(cos_defcompinfo_get_cur()). * if @is_sched == 0, creates only the init thread (does not need @sched parameter) + * NOTE: dcbuaddr is the address in child_dci page-table. */ -int cos_initaep_alloc(struct cos_defcompinfo *child_dci, struct cos_aep_info *sched, int is_sched); +int cos_initaep_alloc(struct cos_defcompinfo *child_dci, struct cos_aep_info *sched, int is_sched, dcbcap_t dcap); /* * cos_initaep_tcap_alloc: same as cos_initaep_alloc with is_sched == 1, except it doesn't create a new tcap, * uses the tcap passed in @tc. + * NOTE: dcbuaddr is the address in child_dci page-table. */ -int cos_initaep_tcap_alloc(struct cos_defcompinfo *child_dci, tcap_t tc, struct cos_aep_info *sched); +int cos_initaep_tcap_alloc(struct cos_defcompinfo *child_dci, tcap_t tc, struct cos_aep_info *sched, dcbcap_t dcap); /* * cos_aep_alloc_ext: creates a new async activation end-point which includes thread, tcap and rcv capabilities in the child_dci component using sched_aep->rcv. * if @child_dci == NULL, create in the current component. + * NOTE: dcbuaddr is the address in child_dci page-table. */ -int cos_aep_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *child_dci, struct cos_aep_info *sched_aep, thdclosure_index_t idx); +int cos_aep_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *child_dci, struct cos_aep_info *sched_aep, thdclosure_index_t idx, dcbcap_t dcap, dcboff_t doff); /* * cos_aep_alloc_ext: creates a new async activation end-point which includes thread, tcap and rcv capabilities in the child_dci component using sched_aep->rcv. * if @child_dci == NULL, create in the current component. + * NOTE: dcbuaddr is the address in child_dci page-table. */ -int cos_aep_tcap_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *child_dci, struct cos_aep_info *sched_aep, tcap_t tc, thdclosure_index_t idx); +int cos_aep_tcap_alloc_ext(struct cos_aep_info *aep, struct cos_defcompinfo *child_dci, struct cos_aep_info *sched_aep, tcap_t tc, thdclosure_index_t idx, dcbcap_t dcap, dcboff_t doff); /* * cos_defswitch: thread switch api using the default scheduling tcap and rcv. diff --git a/src/components/lib/kernel/cos_kernel_api.c b/src/components/lib/kernel/cos_kernel_api.c index e23a2b7141..b3696c509f 100644 --- a/src/components/lib/kernel/cos_kernel_api.c +++ b/src/components/lib/kernel/cos_kernel_api.c @@ -663,7 +663,7 @@ __page_bump_valloc(struct cos_compinfo *ci, size_t sz) } static vaddr_t -__page_bump_alloc(struct cos_compinfo *ci, size_t sz) +__page_bump_alloc(struct cos_compinfo *ci, size_t sz, int shared) { struct cos_compinfo *meta = __compinfo_metacap(ci); vaddr_t heap_vaddr, heap_cursor, heap_limit; @@ -688,7 +688,7 @@ __page_bump_alloc(struct cos_compinfo *ci, size_t sz) for (heap_cursor = heap_vaddr; heap_cursor < heap_limit; heap_cursor += PAGE_SIZE) { vaddr_t umem; - umem = __umem_bump_alloc(ci); + umem = shared ? __kmem_bump_alloc(ci) : __umem_bump_alloc(ci); if (!umem) return 0; /* Actually map in the memory. */ @@ -730,7 +730,7 @@ __alloc_mem_cap(struct cos_compinfo *ci, cap_t ct, vaddr_t *kmem, capid_t *cap) } static thdcap_t -__cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, thdclosure_index_t init_data) +__cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, thdclosure_index_t init_data, dcbcap_t dc, dcboff_t off) { vaddr_t kmem; capid_t cap; @@ -742,10 +742,12 @@ __cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, thdclosure_index_t init if (__alloc_mem_cap(ci, CAP_THD, &kmem, &cap)) return 0; assert(!(init_data & ~((1 << 16) - 1))); - /* TODO: Add cap size checking */ - ret = call_cap_op(ci->captbl_cap, CAPTBL_OP_THDACTIVATE, (init_data << 16) | cap, - __compinfo_metacap(ci)->mi.pgtbl_cap, kmem, comp); - if (ret) BUG(); + assert(!(off & ~((1 << 9) - 1))); + assert(kmem && (round_to_page(kmem) == kmem)); + + if (call_cap_op(ci->captbl_cap, CAPTBL_OP_THDACTIVATE, __compinfo_metacap(ci)->mi.pgtbl_cap | (cap << 16), + kmem, comp << 16 | dc, off << 16 | init_data)) + BUG(); return cap; } @@ -753,30 +755,61 @@ __cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, thdclosure_index_t init #include thdcap_t -cos_thd_alloc_ext(struct cos_compinfo *ci, compcap_t comp, thdclosure_index_t idx) +cos_thd_alloc_ext(struct cos_compinfo *ci, compcap_t comp, thdclosure_index_t idx, dcbcap_t dc, dcboff_t off) { if (idx < 1) return 0; - return __cos_thd_alloc(ci, comp, idx); + return __cos_thd_alloc(ci, comp, idx, dc, off); } thdcap_t -cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, cos_thd_fn_t fn, void *data) +cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, cos_thd_fn_t fn, void *data, dcbcap_t dc, dcboff_t off) { int idx = cos_thd_init_alloc(fn, data); thdcap_t ret; if (idx < 1) return 0; - ret = __cos_thd_alloc(ci, comp, idx); + ret = __cos_thd_alloc(ci, comp, idx, dc, off); if (!ret) cos_thd_init_free(idx); return ret; } thdcap_t -cos_initthd_alloc(struct cos_compinfo *ci, compcap_t comp) +cos_initthd_alloc(struct cos_compinfo *ci, compcap_t comp, dcbcap_t dc) +{ + return __cos_thd_alloc(ci, comp, 0, dc, 0); +} + +int +cos_thd_migrate(struct cos_compinfo *ci, thdcap_t t, cpuid_t c) +{ + return call_cap_op(ci->captbl_cap, CAPTBL_OP_THDMIGRATE, t, c, 0, 0); +} + +int +cos_thdcap_migrate(struct cos_compinfo *ci, thdcap_t t) { - return __cos_thd_alloc(ci, comp, 0); + return call_cap_op(ci->captbl_cap, CAPTBL_OP_THDMIGRATE, t, 0, 1, 0); +} + +dcbcap_t +cos_dcb_alloc(struct cos_compinfo *ci, pgtblcap_t ptcap, vaddr_t uaddr) +{ + vaddr_t kmem; + capid_t cap; + u32_t lid = livenessid_bump_alloc(); + + printd("cos_dcb_alloc\n"); + + assert(ci); + + if (__alloc_mem_cap(ci, CAP_DCB, &kmem, &cap)) return 0; + assert(kmem && (round_to_page(kmem) == kmem)); + if (call_cap_op(ci->captbl_cap, CAPTBL_OP_DCB_ACTIVATE, cap << 16 | lid, (__compinfo_metacap(ci)->mi.pgtbl_cap) << 16 | ptcap, kmem, uaddr)) + BUG(); + + return cap; } captblcap_t @@ -813,38 +846,61 @@ cos_pgtbl_alloc(struct cos_compinfo *ci) return cap; } +scbcap_t +cos_scb_alloc(struct cos_compinfo *ci) +{ + vaddr_t kmem; + capid_t cap; + u32_t lid = livenessid_bump_alloc(); + + printd("cos_scb_alloc\n"); + + assert(ci && lid); + + if (__alloc_mem_cap(ci, CAP_SCB, &kmem, &cap)) return 0; + assert(kmem && (round_to_page(kmem) == kmem)); + if (call_cap_op(ci->captbl_cap, CAPTBL_OP_SCB_ACTIVATE, cap, __compinfo_metacap(ci)->mi.pgtbl_cap, kmem, lid)) + BUG(); + + return cap; +} + int -cos_comp_alloc_with(struct cos_compinfo *ci, compcap_t comp, u32_t lid, captblcap_t ctc, pgtblcap_t ptc, vaddr_t entry) +cos_comp_alloc_with(struct cos_compinfo *ci, compcap_t comp, u32_t lid, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry, vaddr_t uaddr) { - if (call_cap_op(ci->captbl_cap, CAPTBL_OP_COMPACTIVATE, comp, (ctc << 16) | ptc, lid, entry)) return 1; + if (call_cap_op(ci->captbl_cap, CAPTBL_OP_COMPACTIVATE, (lid << 16) | comp, (ctc << 16) | ptc, uaddr | scbc, entry)) return 1; return 0; } compcap_t -cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, vaddr_t entry) +cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry, vaddr_t uaddr) { capid_t cap; + /* FIXME: same or diff liveness ids in scb and comp resources? */ u32_t lid = livenessid_bump_alloc(); printd("cos_comp_alloc\n"); assert(ci && ctc && ptc && lid); + /* FIXME: packing scbc in 12 bits */ + assert(scbc < (1 << 12)); cap = __capid_bump_alloc(ci, CAP_COMP); if (!cap) return 0; - if (cos_comp_alloc_with(ci, cap, lid, ctc, ptc, entry)) BUG(); + if (cos_comp_alloc_with(ci, cap, lid, ctc, ptc, scbc, entry, uaddr)) BUG(); return cap; } int -cos_compinfo_alloc(struct cos_compinfo *ci, vaddr_t heap_ptr, capid_t cap_frontier, vaddr_t entry, +cos_compinfo_alloc(struct cos_compinfo *ci, scbcap_t sc, vaddr_t heap_ptr, capid_t cap_frontier, vaddr_t entry, struct cos_compinfo *ci_resources) { pgtblcap_t ptc; captblcap_t ctc; compcap_t compc; + vaddr_t scb_vaddr; int pgtbl_lvl; printd("cos_compinfo_alloc\n"); @@ -853,7 +909,7 @@ cos_compinfo_alloc(struct cos_compinfo *ci, vaddr_t heap_ptr, capid_t cap_fronti assert(ptc); ctc = cos_captbl_alloc(ci_resources); assert(ctc); - compc = cos_comp_alloc(ci_resources, ctc, ptc, entry); + compc = cos_comp_alloc(ci_resources, ctc, ptc, sc, entry, scb_vaddr); assert(compc); cos_compinfo_init(ci, ptc, ctc, compc, heap_ptr, cap_frontier, ci_resources); @@ -938,10 +994,29 @@ cos_hw_alloc(struct cos_compinfo *ci, u32_t bitmap) return cap; } +/* TODO: Can we alias/etc on this page with this logic? */ +void * +cos_dcbpg_bump_allocn(struct cos_compinfo *ci, size_t sz) +{ + assert(sz == PAGE_SIZE); + /* assert(sz % PAGE_SIZE == 0); */ + + return (void *)__page_bump_alloc(ci, sz, 1); +} + +void * +cos_scbpg_bump_allocn(struct cos_compinfo *ci, size_t sz) +{ + assert(sz == PAGE_SIZE); + /* assert(sz % PAGE_SIZE == 0); */ + + return (void *)__page_bump_alloc(ci, sz, 1); +} + void * cos_page_bump_alloc(struct cos_compinfo *ci) { - return (void *)__page_bump_alloc(ci, PAGE_SIZE); + return (void *)__page_bump_alloc(ci, PAGE_SIZE, 0); } void * @@ -949,7 +1024,7 @@ cos_page_bump_allocn(struct cos_compinfo *ci, size_t sz) { assert(sz % PAGE_SIZE == 0); - return (void *)__page_bump_alloc(ci, sz); + return (void *)__page_bump_alloc(ci, sz, 0); } capid_t diff --git a/src/components/lib/kernel/cos_kernel_api.h b/src/components/lib/kernel/cos_kernel_api.h index 3ed0a6ae38..48a290f7e2 100644 --- a/src/components/lib/kernel/cos_kernel_api.h +++ b/src/components/lib/kernel/cos_kernel_api.h @@ -54,6 +54,9 @@ typedef capid_t compcap_t; typedef capid_t captblcap_t; typedef capid_t pgtblcap_t; typedef capid_t hwcap_t; +typedef capid_t scbcap_t; +typedef capid_t dcbcap_t; +typedef unsigned short dcboff_t; /* Memory source information */ struct cos_meminfo { @@ -107,18 +110,26 @@ int cos_pgtbl_intern_expandwith(struct cos_compinfo *ci, pgtblcap_t intern, vadd * This uses the next three functions to allocate a new component and * correctly populate ci (allocating all resources from ci_resources). */ -int cos_compinfo_alloc(struct cos_compinfo *ci, vaddr_t heap_ptr, capid_t cap_frontier, vaddr_t entry, +int cos_compinfo_alloc(struct cos_compinfo *ci, scbcap_t sc, vaddr_t heap_ptr, capid_t cap_frontier, vaddr_t entry, struct cos_compinfo *ci_resources); captblcap_t cos_captbl_alloc(struct cos_compinfo *ci); pgtblcap_t cos_pgtbl_alloc(struct cos_compinfo *ci); -compcap_t cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, vaddr_t entry); +compcap_t cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry, + vaddr_t scb_addr); +scbcap_t cos_scb_alloc(struct cos_compinfo *ci); +dcbcap_t cos_dcb_alloc(struct cos_compinfo *ci, pgtblcap_t ptc, vaddr_t dcb_uaddr); void cos_comp_capfrontier_update(struct cos_compinfo *ci, capid_t cap_frontier); typedef void (*cos_thd_fn_t)(void *); -thdcap_t cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, cos_thd_fn_t fn, void *data); -thdcap_t cos_thd_alloc_ext(struct cos_compinfo *ci, compcap_t comp, thdclosure_index_t idx); +thdcap_t cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, cos_thd_fn_t fn, void *data, dcbcap_t dc, + dcboff_t dcboff); +thdcap_t cos_thd_alloc_ext(struct cos_compinfo *ci, compcap_t comp, thdclosure_index_t idx, dcbcap_t dc, + dcboff_t dcboff); /* Create the initial (cos_init) thread */ -thdcap_t cos_initthd_alloc(struct cos_compinfo *ci, compcap_t comp); +thdcap_t cos_initthd_alloc(struct cos_compinfo *ci, compcap_t comp, dcbcap_t dc); +int cos_thd_migrate(struct cos_compinfo *ci, thdcap_t thdc, cpuid_t core); +/* update the thdcap to migrated core */ +int cos_thdcap_migrate(struct cos_compinfo *ci, thdcap_t thdc); sinvcap_t cos_sinv_alloc(struct cos_compinfo *srcci, compcap_t dstcomp, vaddr_t entry, invtoken_t token); arcvcap_t cos_arcv_alloc(struct cos_compinfo *ci, thdcap_t thdcap, tcap_t tcapcap, compcap_t compcap, arcvcap_t enotif); asndcap_t cos_asnd_alloc(struct cos_compinfo *ci, arcvcap_t arcvcap, captblcap_t ctcap); @@ -126,6 +137,9 @@ asndcap_t cos_asnd_alloc(struct cos_compinfo *ci, arcvcap_t arcvcap, captblcap_t void *cos_page_bump_alloc(struct cos_compinfo *ci); void *cos_page_bump_allocn(struct cos_compinfo *ci, size_t sz); +void *cos_dcbpg_bump_allocn(struct cos_compinfo *ci, size_t sz); +void *cos_scbpg_bump_allocn(struct cos_compinfo *ci, size_t sz); + capid_t cos_cap_cpy(struct cos_compinfo *dstci, struct cos_compinfo *srcci, cap_t srcctype, capid_t srccap); int cos_cap_cpy_at(struct cos_compinfo *dstci, capid_t dstcap, struct cos_compinfo *srcci, capid_t srccap); diff --git a/src/components/lib/sl/sl_sched.c b/src/components/lib/sl/sl_sched.c index b2d34f59b8..0cca739b1a 100644 --- a/src/components/lib/sl/sl_sched.c +++ b/src/components/lib/sl/sl_sched.c @@ -732,3 +732,10 @@ sl_sched_loop_nonblock(void) { sl_sched_loop_intern(1); } + +int +sl_thd_kern_dispatch(thdcap_t t) +{ + //return cos_switch(t, sl__globals_cpu()->sched_tcap, 0, sl__globals_cpu()->timeout_next, sl__globals_cpu()->sched_rcv, cos_sched_sync()); + return cos_thd_switch(t); +} diff --git a/src/kernel/capinv.c b/src/kernel/capinv.c index fd93314983..aeea7589c4 100644 --- a/src/kernel/capinv.c +++ b/src/kernel/capinv.c @@ -16,6 +16,8 @@ #include "include/chal/defs.h" #include "include/hw.h" #include "include/chal/chal_proto.h" +#include "include/scb.h" +//#include "include/dcb.h" #define COS_DEFAULT_RET_CAP 0 @@ -1210,10 +1212,13 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * case CAPTBL_OP_COMPACTIVATE: { capid_t captbl_cap = __userregs_get2(regs) >> 16; capid_t pgtbl_cap = __userregs_get2(regs) & 0xFFFF; - livenessid_t lid = __userregs_get3(regs); + livenessid_t lid = (capin >> 16); + capid_t comp_cap = (capin << 16) >> 16; + vaddr_t scb_uaddr = __userregs_get3(regs) | ~((1 << 12) - 1); vaddr_t entry_addr = __userregs_get4(regs); + capid_t scb_cap = __userregs_get3(regs) & ((1 << 12) - 1); - ret = comp_activate(ct, cap, capin, captbl_cap, pgtbl_cap, lid, entry_addr); + ret = comp_activate(ct, cap, comp_cap, captbl_cap, pgtbl_cap, scb_cap, lid, entry_addr, scb_uaddr); break; } case CAPTBL_OP_COMPDEACTIVATE: { @@ -1322,6 +1327,60 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * ret = hw_deactivate(op_cap, capin, lid); break; } + case CAPTBL_OP_SCB_ACTIVATE: { + capid_t ptcap = __userregs_get2(regs); + livenessid_t lid = __userregs_get3(regs); + vaddr_t addr = __userregs_get4(regs); + unsigned long *pte; + struct cos_scb_info *scb; + + ret = cap_kmem_activate(ct, ptcap, addr, (unsigned long *)&scb, &pte); + if (ret) cos_throw(err, ret); + + ret = scb_activate(ct, cap, capin, (vaddr_t)scb, lid); + + break; + } + case CAPTBL_OP_SCB_DEACTIVATE: { + u32_t r2 = __userregs_get2(regs); + livenessid_t lid = r2 >> 16; + capid_t ptcap = (r2 << 16) >> 16; + capid_t cf_addr = __userregs_get3(regs); + + ret = scb_deactivate(op_cap, capin, ptcap, cf_addr, lid); + + break; + } +// case CAPTBL_OP_DCB_ACTIVATE: { +// u32_t r1 = __userregs_get1(regs); +// u32_t r2 = __userregs_get2(regs); +// u32_t r3 = __userregs_get3(regs); +// u32_t r4 = __userregs_get4(regs); +// capid_t dcbcap = r1 >> 16; +// capid_t ptcap = (r1 << 16) >> 16; +// livenessid_t lid = r2 >> 16; +// capid_t ptcapin = (r2 << 16) >> 16; +// vaddr_t kaddr = r3; +// vaddr_t uaddrin = r4; +// +// ret = dcb_activate(ct, cap, dcbcap, ptcap, kaddr, lid, ptcapin, uaddr); +// +// break; +// } +// case CAPTBL_OP_DCB_DEACTIVATE: { +// u32_t r2 = __userregs_get2(regs); +// u32_t r3 = __userregs_get3(regs); +// u32_t r4 = __userregs_get4(regs); +// livenessid_t lid = r2 >> 16; +// capid_t ptcap = (r2 << 16) >> 16; +// vaddr_t cf_addr = r3 & (~0 << 12); +// vaddr_t uaddrin = r4 & (~0 << 12); +// capid_t ptcapin = (r4 << 20) >> 12 | ((r3 << 20) >> 20); +// +// ret = dcb_deactivate(ct, capin, lid, ptcap, cf_addr, ptcapin, uaddrin); +// +// break; +// } default: goto err; } diff --git a/src/kernel/include/captbl.h b/src/kernel/include/captbl.h index 8ca57029af..3c1f01437b 100644 --- a/src/kernel/include/captbl.h +++ b/src/kernel/include/captbl.h @@ -55,7 +55,7 @@ typedef enum { #define CAP_HEAD_AMAP_SZ 4 #define CAP_HEAD_SZ_SZ 2 #define CAP_HEAD_FLAGS_SZ 3 -#define CAP_HEAD_TYPE_SZ 7 +#define CAP_HEAD_TYPE_SZ CAP_TYPE_MAXBITS /* * This is the header for each capability. Includes information about diff --git a/src/kernel/include/component.h b/src/kernel/include/component.h index ef335bc944..2293a586bb 100644 --- a/src/kernel/include/component.h +++ b/src/kernel/include/component.h @@ -18,34 +18,42 @@ struct comp_info { struct liveness_data liveness; struct pgtbl_info pgtblinfo; struct captbl * captbl; + struct cos_scb_info *scb_data; } __attribute__((packed)); struct cap_comp { struct cap_header h; vaddr_t entry_addr; - struct cap_pgtbl * pgd; + struct cap_pgtbl *pgd; struct cap_captbl *ct_top; struct comp_info info; } __attribute__((packed)); +#include "scb.h" + static int -comp_activate(struct captbl *t, capid_t cap, capid_t capin, capid_t captbl_cap, capid_t pgtbl_cap, livenessid_t lid, - vaddr_t entry_addr) +comp_activate(struct captbl *t, capid_t cap, capid_t capin, capid_t captbl_cap, capid_t pgtbl_cap, capid_t scbcap, + livenessid_t lid, vaddr_t entry_addr, vaddr_t scb_uaddr) { - struct cap_comp * compc; - struct cap_pgtbl * ptc; + struct cap_comp *compc; + struct cap_pgtbl *ptc; struct cap_captbl *ctc; u32_t v; int ret = 0; + struct cap_scb *scbc = NULL; ctc = (struct cap_captbl *)captbl_lkup(t, captbl_cap); if (unlikely(!ctc || ctc->h.type != CAP_CAPTBL || ctc->lvl > 0)) return -EINVAL; ptc = (struct cap_pgtbl *)captbl_lkup(t, pgtbl_cap); if (unlikely(!ptc || ptc->h.type != CAP_PGTBL || ptc->lvl > 0)) return -EINVAL; + if (likely(scbcap)) { + scbc = (struct cap_scb *)captbl_lkup(t, scbcap); + if (unlikely(!scbc || scbc->h.type != CAP_SCB)) return -EINVAL; + } v = ptc->refcnt_flags; if (v & CAP_MEM_FROZEN_FLAG) return -EINVAL; - if (cos_cas_32((u32_t *)&ptc->refcnt_flags, v, v + 1) != CAS_SUCCESS) return -ECASFAIL; + if (cos_cas((unsigned long *)&ptc->refcnt_flags, v, v + 1) != CAS_SUCCESS) return -ECASFAIL; v = ctc->refcnt_flags; if (v & CAP_MEM_FROZEN_FLAG) cos_throw(undo_ptc, -EINVAL); @@ -53,10 +61,14 @@ comp_activate(struct captbl *t, capid_t cap, capid_t capin, capid_t captbl_cap, /* undo before return */ cos_throw(undo_ptc, -ECASFAIL); } - compc = (struct cap_comp *)__cap_capactivate_pre(t, cap, capin, CAP_COMP, &ret); if (!compc) cos_throw(undo_ctc, ret); + if (likely(scbc)) { + ret = scb_comp_update(t, scbc, compc, ptc, scb_uaddr); + if (ret) cos_throw(undo_capact, ret); + } + compc->entry_addr = entry_addr; compc->info.pgtblinfo.pgtbl = ptc->pgtbl; compc->info.pgtblinfo.asid = chal_asid_alloc(); @@ -68,6 +80,9 @@ comp_activate(struct captbl *t, capid_t cap, capid_t capin, capid_t captbl_cap, return 0; +/*undo_scb: + scb_comp_remove(t, scbc, pgtbl_cap, scb_uaddr);*/ +undo_capact: undo_ctc: cos_faa((int *)&ctc->refcnt_flags, -1); undo_ptc: @@ -79,8 +94,8 @@ static int comp_deactivate(struct cap_captbl *ct, capid_t capin, livenessid_t lid) { int ret; - struct cap_comp * compc; - struct cap_pgtbl * pgd; + struct cap_comp *compc; + struct cap_pgtbl *pgd; struct cap_captbl *ct_top; compc = (struct cap_comp *)captbl_lkup(ct->captbl, capin); @@ -89,6 +104,8 @@ comp_deactivate(struct cap_captbl *ct, capid_t capin, livenessid_t lid) ltbl_expire(&compc->info.liveness); pgd = compc->pgd; ct_top = compc->ct_top; + /* TODO: right way to remove scb info */ + if (likely(compc->info.scb_data)) scb_comp_remove(ct, 0, 0, 0); ret = cap_capdeactivate(ct, capin, CAP_COMP, lid); if (ret) return ret; diff --git a/src/kernel/include/dcb.h b/src/kernel/include/dcb.h new file mode 100644 index 0000000000..3b64c4477e --- /dev/null +++ b/src/kernel/include/dcb.h @@ -0,0 +1,101 @@ +/** + * Copyright 2019 by Phani Gadepalli, phanikishoreg@gwu.edu + * + * Redistribution of this file is permitted under the GNU General Public License v2. + */ + +#ifndef DCB_H +#define DCB_H + +#include "cap_ops.h" +#include "pgtbl.h" +#include "retype_tbl.h" +#include "component.h" + +#define DCB_ENTRIES_MAX_PER_PAGE (PAGE_SIZE/sizeof(struct cos_dcb_info)) + +struct cap_dcb { + struct cap_header h; + struct liveness_data liveness; + unsigned int refcnt; + vaddr_t kern_addr; + cpuid_t cpuid; +} __attribute__((packed)); + +static int +dcb_activate(struct captbl *t, capid_t ctcap, capid_t dcbcap, capid_t ptcap, vaddr_t kaddr, livenessid_t lid, capid_t ptcapin, vaddr_t uaddr) +{ + struct cap_dcb *dc; + struct cap_pgtbl *ptc; + unsigned long *tpte; + struct cos_dcb_info *di; + int ret; + + ret = cap_kmem_activate(t, ptcap, kaddr, (unsigned long *)&di, &tpte); + if (unlikely(ret)) return -EINVAL; + assert(di && tpte); + + /* TODO: memactivate kaddr -> uaddr in ptcapin */ + + dc = (struct cap_dcb *)__cap_capactivate_pre(t, ctcap, dcbcap, CAP_DCB, &ret); + if (!dc) return -EINVAL; + + ltbl_get(lid, &dc->liveness); + dc->kern_addr = (vaddr_t)di; + dc->refcnt = 0; + dc->cpuid = get_cpuid(); + + __cap_capactivate_post(&dc->h, CAP_DCB); + + return 0; +} + +static int +dcb_deactivate(struct cap_captbl *ct, capid_t dcbcap, livenessid_t lid, capid_t ptcap, capid_t cosframe_addr, capid_t ptcapin, vaddr_t uaddrin) +{ + struct cap_dcb *dc; + int ret; + + dc = (struct cap_comp *)captbl_lkup(ct->captbl, dcbcap); + if (dc->h.type != CAP_DCB) return -EINVAL; + + if (dc->refcnt) return -EPERM; + /* TODO: verify uaddrin in ptcapin maps to kaddr for this dcb and then unmap from ptcapin at uaddrin */ + + ltbl_expire(&dc->liveness); + ret = kmem_deact_pre(dc, ct, ptcap, cosframe_addr, &pte, &old_v); + if (ret) return ret; + ret = kmem_deact_post(pte, old_v); + if (ret) return ret; + dc->kern_addr = 0; + + return cap_capdeactivate(ct, dcbcap, CAP_DCB, lid); +} + +static inline int +dcb_thd_ref(struct cap_dcb *dc, struct thread *thd) +{ + if (dc->refcnt >= DCB_ENTRIES_MAX_PER_PAGE) return -EINVAL; + if (dc->cpuid != thd->cpuid) return -EINVAL; + if (!ltbl_isalive(&dc->liveness)) return -EPERM; + + dc->refcnt++; + + return 0; +} + +static inline int +dcb_thd_deref(struct cap_dcb *dc, struct thread *thd) +{ + if (!dc->refcnt) return -EINVAL; + if (dc->cpuid != thd->cpuid) return -EINVAL; + if (!ltbl_isalive(&dc->liveness)) return -EPERM; + + assert((vaddr_t)thd->dcbinfo >= dc->kern_addr && (vaddr_t)thd->dcbinfo < (dc->kern_addr + PAGE_SIZE)); + + dc->refcnt--; + + return 0; +} + +#endif /* DCB_H */ diff --git a/src/kernel/include/scb.h b/src/kernel/include/scb.h new file mode 100644 index 0000000000..b3618bed12 --- /dev/null +++ b/src/kernel/include/scb.h @@ -0,0 +1,100 @@ +/** + * Copyright 2019 by Phani Gadepalli, phanikishoreg@gwu.edu + * + * Redistribution of this file is permitted under the GNU General Public License v2. + */ + +#ifndef SCB_H +#define SCB_H + +#include "component.h" +#include "cap_ops.h" +#include "pgtbl.h" +#include "retype_tbl.h" + +struct comp_info; + +struct cap_scb { + struct cap_header h; + struct liveness_data liveness; + struct cap_comp *compc; + vaddr_t kern_addr; +} __attribute__((packed)); + +static int +scb_activate(struct captbl *t, capid_t ctcap, capid_t scbcap, vaddr_t kaddr, livenessid_t lid) +{ + struct cap_scb *sc; + int ret; + + sc = (struct cap_scb *)__cap_capactivate_pre(t, ctcap, scbcap, CAP_SCB, &ret); + if (!sc) return -EINVAL; + + ltbl_get(lid, &sc->liveness); + sc->kern_addr = kaddr; + sc->compc = NULL; + memset((void *)kaddr, 0, COS_SCB_SIZE); + + __cap_capactivate_post(&sc->h, CAP_SCB); + + return 0; +} + +static int +scb_deactivate(struct cap_captbl *ct, capid_t scbcap, capid_t ptcap, capid_t cosframe_addr, livenessid_t lid) +{ + struct cap_scb *sc; + unsigned long old_v = 0, *pte = NULL; + int ret; + + sc = (struct cap_scb *)captbl_lkup(ct->captbl, scbcap); + if (sc->h.type != CAP_SCB) return -EINVAL; + + /* FIXME: component using this scbcap is still active! how to handle this? */ + if (sc->compc) return -EPERM; + + ltbl_expire(&sc->liveness); + ret = kmem_deact_pre((struct cap_header *)sc, ct->captbl, ptcap, cosframe_addr, &pte, &old_v); + if (ret) return ret; + ret = kmem_deact_post(pte, old_v); + if (ret) return ret; + + return cap_capdeactivate(ct, scbcap, CAP_SCB, lid); +} + +static inline int +scb_comp_update(struct captbl *ct, struct cap_scb *sc, struct cap_comp *compc, struct cap_pgtbl *ptcin, vaddr_t uaddrin) +{ + paddr_t pf = chal_va2pa((void *)(sc->kern_addr)); + + if (unlikely(!ltbl_isalive(&sc->liveness))) return -EPERM; + if (pgtbl_mapping_add(ptcin->pgtbl, uaddrin, pf, PGTBL_USER_DEF)) return -EINVAL; + + sc->compc = compc; + compc->info.scb_data = (struct cos_scb_info *)(sc->kern_addr); + + return 0; +} + +static inline int +scb_comp_remove(struct cap_captbl *ct, struct cap_scb *sc, capid_t ptcapin, vaddr_t uaddrin) +{ + int ret; + + if (unlikely(!ct || !sc || !ptcapin || !uaddrin)) return -EINVAL; + + if (unlikely(!ltbl_isalive(&sc->liveness))) return -EPERM; + if (unlikely(!sc->compc)) return -EINVAL; + + /* TODO: unmap uaddrin in the user-land */ + + return 0; +} + +static inline struct liveness_data * +scb_liveness(struct cap_scb *sc) +{ + return &sc->liveness; +} + +#endif /* SCB_H */ diff --git a/src/kernel/include/shared/cos_types.h b/src/kernel/include/shared/cos_types.h index 215f0fa383..01251d0890 100644 --- a/src/kernel/include/shared/cos_types.h +++ b/src/kernel/include/shared/cos_types.h @@ -143,6 +143,12 @@ typedef enum { CAPTBL_OP_HW_TLBFLUSH, CAPTBL_OP_HW_TLBSTALL, CAPTBL_OP_HW_TLBSTALL_RECOUNT + + CAPTBL_OP_SCB_ACTIVATE, + CAPTBL_OP_SCB_DEACTIVATE, + + CAPTBL_OP_DCB_ACTIVATE, + CAPTBL_OP_DCB_DEACTIVATE, } syscall_op_t; typedef enum { @@ -160,8 +166,13 @@ typedef enum { CAP_QUIESCENCE, /* when deactivating, set to track quiescence state */ CAP_TCAP, /* tcap captable entry */ CAP_HW, /* hardware (interrupt) */ + CAP_SCB, /* Scheduler control block (SCB) */ + CAP_DCB, /* Dispatch control block (DCB) */ } cap_t; +/* maximum size allowed for CAP TYPE in a capability header */ +#define CAP_TYPE_MAXBITS 7 +#define CAP_TYPE_MAX (1 << CAP_TYPE_MAXBITS - 1) /* TODO: pervasive use of these macros */ /* v \in struct cap_* *, type \in cap_t */ #define CAP_TYPECHK(v, t) ((v) && (v)->h.type == (t)) @@ -210,6 +221,8 @@ typedef int cpuid_t; static inline cap_sz_t __captbl_cap2sz(cap_t c) { + /* if (unlikely(c > CAP_TYPE_MAX)) return CAP_SZ_ERR; */ + /* TODO: optimize for invocation and return */ switch (c) { case CAP_SRET: @@ -217,6 +230,8 @@ __captbl_cap2sz(cap_t c) case CAP_TCAP: return CAP_SZ_16B; case CAP_HW: /* TODO: 256bits = 32B * 8b */ + case CAP_SCB: + case CAP_DCB: return CAP_SZ_32B; case CAP_SINV: case CAP_COMP: @@ -270,13 +285,15 @@ enum BOOT_CAPTBL_KM_PTE = 28, BOOT_CAPTBL_SINV_CAP = 32, - BOOT_CAPTBL_SELF_INITHW_BASE = 36, - BOOT_CAPTBL_SELF_INITTHD_BASE = 40, + BOOT_CAPTBL_SELF_SCB = 36, /* FIXME: Do we need this? */ + BOOT_CAPTBL_SELF_INITHW_BASE = 40, + BOOT_CAPTBL_SELF_INITTHD_BASE = 44, /* * NOTE: kernel doesn't support sharing a cache-line across cores, * so optimize to place INIT THD/TCAP on same cache line and bump by 64B for next CPU + * Update: add per-core INIT DCB cap in to the same cache-line. */ - BOOT_CAPTBL_SELF_INITTCAP_BASE = round_up_to_pow2(BOOT_CAPTBL_SELF_INITTHD_BASE + NUM_CPU * CAP16B_IDSZ, CAPMAX_ENTRY_SZ), + BOOT_CAPTBL_SELF_INITTCAP_BASE = round_up_to_pow2(BOOT_CAPTBL_SELF_INITTHD_BASE + NUM_CPU * CAP64B_IDSZ, CAPMAX_ENTRY_SZ), BOOT_CAPTBL_SELF_INITRCV_BASE = round_up_to_pow2(BOOT_CAPTBL_SELF_INITTCAP_BASE + NUM_CPU * CAP16B_IDSZ, CAPMAX_ENTRY_SZ), BOOT_CAPTBL_LAST_CAP = BOOT_CAPTBL_SELF_INITRCV_BASE + NUM_CPU * CAP64B_IDSZ, @@ -284,13 +301,17 @@ enum BOOT_CAPTBL_FREE = round_up_to_pow2(BOOT_CAPTBL_LAST_CAP, CAPMAX_ENTRY_SZ) }; -#define BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITTHD_BASE + cpuid * CAP16B_IDSZ) +#define BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITTHD_BASE + cpuid * CAP64B_IDSZ) #define BOOT_CAPTBL_SELF_INITTCAP_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITTCAP_BASE + cpuid * CAP16B_IDSZ) #define BOOT_CAPTBL_SELF_INITRCV_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITRCV_BASE + cpuid * CAP64B_IDSZ) +#define BOOT_CAPTBL_SELF_INITDCB_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cpuid) + CAP32B_IDSZ) + +#define BOOT_CAPTBL_SELF_INITDCB_BASE (BOOT_CAPTBL_SELF_INITTHD_BASE + CAP32B_IDSZ) #define BOOT_CAPTBL_SELF_INITTHD_CPU_BASE (BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cos_cpuid())) #define BOOT_CAPTBL_SELF_INITTCAP_CPU_BASE (BOOT_CAPTBL_SELF_INITTCAP_BASE_CPU(cos_cpuid())) #define BOOT_CAPTBL_SELF_INITRCV_CPU_BASE (BOOT_CAPTBL_SELF_INITRCV_BASE_CPU(cos_cpuid())) +#define BOOT_CAPTBL_SELF_INITDCB_CPU_BASE (BOOT_CAPTBL_SELF_INITDCB_BASE_CPU(cos_cpuid())) /* * The half of the first page of init captbl is devoted to root node. So, the @@ -513,4 +534,4 @@ typedef unsigned short int cos_channelkey_t; /* 0 == PRIVATE KEY. >= 1 GLOBAL KE */ #define PRINT_CAP_TEMP (BOOT_CAPTBL_PRINT_HACK) -#endif /* TYPES_H */ \ No newline at end of file +#endif /* TYPES_H */ diff --git a/src/kernel/include/thd.h b/src/kernel/include/thd.h index fd0ec066b3..51b80d5bab 100644 --- a/src/kernel/include/thd.h +++ b/src/kernel/include/thd.h @@ -356,6 +356,7 @@ thd_activate(struct captbl *t, capid_t cap, capid_t capin, struct thread *thd, c tc->t = thd; tc->cpuid = get_cpuid(); __cap_capactivate_post(&tc->h, CAP_THD); + /* TODO: dcb_thd_ref() */ return 0; } @@ -412,6 +413,7 @@ thd_deactivate(struct captbl *ct, struct cap_captbl *dest_ct, unsigned long capi ret = kmem_deact_post(pte, old_v); if (ret) cos_throw(err, ret); } + /* TODO: dcb_thd_deref() */ return 0; err: diff --git a/src/platform/i386/boot_comp.c b/src/platform/i386/boot_comp.c index db4832a55f..99451f9a7a 100644 --- a/src/platform/i386/boot_comp.c +++ b/src/platform/i386/boot_comp.c @@ -19,6 +19,105 @@ extern u8_t *boot_comp_pgd; void *thd_mem[NUM_CPU], *tcap_mem[NUM_CPU]; struct captbl *glb_boot_ct; +int +boot_nptes(unsigned int sz) +{ + return round_up_to_pow2(sz, PGD_RANGE) / PGD_RANGE; +} + +int +boot_pgtbl_mappings_add(struct captbl *ct, capid_t pgdcap, capid_t ptecap, const char *label, void *kern_vaddr, + unsigned long user_vaddr, unsigned int range, int uvm, unsigned long *scb_uaddr) +{ + int ret; + u8_t * ptes; + unsigned int nptes = 0, i; + struct cap_pgtbl *pte_cap, *pgd_cap; + pgtbl_t pgtbl; + + pgd_cap = (struct cap_pgtbl *)captbl_lkup(ct, pgdcap); + if (!pgd_cap || !CAP_TYPECHK(pgd_cap, CAP_PGTBL)) assert(0); + pgtbl = (pgtbl_t)pgd_cap->pgtbl; + if (!uvm) nptes = boot_nptes(range); + else nptes = boot_nptes(range + COS_SCB_SIZE); + ptes = mem_boot_alloc(nptes); + assert(ptes); + + if (!uvm && range < COS_MEM_KERN_PA_SZ) { + printk("Insufficient %s memory! Available:%luMB, Required:%luMB\n", label, range >> 20, COS_MEM_KERN_PA_SZ >> 20); + printk("Reconfigure \"COS_MEM_KERN_PA_SZ\" to %luMB\n", range >> 20); + assert(0); + } + + printk("\tCreating %d %s PTEs for PGD @ 0x%x from [%x,%x) to [%x,%x).\n", nptes, label, + chal_pa2va((paddr_t)pgtbl), kern_vaddr, kern_vaddr + range, user_vaddr, user_vaddr + range); + + /* + * Note the use of NULL here. We aren't actually adding a PTE + * currently. This is a hack and only used on boot-up. We'll + * reuse this capability entry to create _multiple_ ptes. We + * won't create captbl entries for each of them, so they + * cannot be aliased/removed later. The only adverse + * side-effect I can think of from this is that we cannot + * reclaim all of the boot-time memory, but that is so far + * into the future, I don't think we care. + */ + if (pgtbl_activate(ct, BOOT_CAPTBL_SELF_CT, ptecap, NULL, 1)) assert(0); + pte_cap = (struct cap_pgtbl *)captbl_lkup(ct, ptecap); + assert(pte_cap); + + /* Hook in the PTEs */ + for (i = 0; i < nptes; i++) { + u8_t * p = ptes + i * PAGE_SIZE; + paddr_t pf = chal_va2pa(p); + + pgtbl_init_pte(p); + pte_cap->pgtbl = (pgtbl_t)p; + + /* hook the pte into the boot component's page tables */ + ret = cap_cons(ct, pgdcap, ptecap, (capid_t)(user_vaddr + i * PGD_RANGE)); + assert(!ret); + } + + printk("\tMapping in %s.\n", label); + /* Map in the actual memory. */ + for (i = 0; i < range / PAGE_SIZE; i++) { + u8_t * p = kern_vaddr + i * PAGE_SIZE; + paddr_t pf = chal_va2pa(p); + u32_t mapat = (u32_t)user_vaddr + i * PAGE_SIZE, flags = 0; + + if (uvm && pgtbl_mapping_add(pgtbl, mapat, pf, PGTBL_USER_DEF)) assert(0); + if (!uvm && pgtbl_cosframe_add(pgtbl, mapat, pf, PGTBL_COSFRAME)) assert(0); + assert((void *)p == pgtbl_lkup(pgtbl, user_vaddr + i * PAGE_SIZE, &flags)); + } + if (uvm) { + unsigned int j; + u8_t *p; + paddr_t pf; + u32_t mapat = (u32_t)user_vaddr + i * PAGE_SIZE, flags = 0; + + assert(i == range / PAGE_SIZE); + assert(COS_SCB_SIZE == PAGE_SIZE); /* FIXME: for prototype impl! */ + *scb_uaddr = (unsigned long)mapat; + i++; + + for (j = 0; j < NUM_CPU; j++, i++) { + unsigned long *pte = NULL, flags; + mapat = (u32_t)user_vaddr + i * PAGE_SIZE; + p = mem_boot_alloc(1); + assert(p); + pf = chal_va2pa(p); + if (pgtbl_mapping_add(pgtbl, mapat, pf, PGTBL_USER_DEF)) assert(0); + + dcb_addr[j] = (unsigned long)p; + pte = pgtbl_lkup(pgtbl, mapat, (u32_t *)&flags); + assert((void *)p == pte); + } + } + + return 0; +} + /* FIXME: loops to create threads/tcaps/rcv caps per core. */ static void kern_boot_thd(struct captbl *ct, void *thd_mem, void *tcap_mem, const cpuid_t cpu_id) @@ -244,7 +343,9 @@ kern_boot_comp(const cpuid_t cpu_id) unsigned int i; u8_t * boot_comp_captbl; pgtbl_t pgtbl = (pgtbl_t)chal_va2pa(&boot_comp_pgd), boot_vm_pgd; + u32_t hw_bitmap = ~0; + vaddr_t scb_uaddr = 0, scb_kaddr = 0; assert(cpu_id >= 0); if (NUM_CPU > 1 && cpu_id > 0) { @@ -285,6 +386,8 @@ kern_boot_comp(const cpuid_t cpu_id) hw_asndcap_init(); if (hw_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_INITHW_BASE, hw_bitmap)) assert(0); + scb_kaddr = (vaddr_t)mem_boot_alloc(1); + assert(scb_kaddr); /* * separate pgd for boot component virtual memory */ @@ -323,14 +426,15 @@ kern_boot_comp(const cpuid_t cpu_id) assert(ret == 0); - printk("\tCapability table and page-table created.\n"); - /* Shut off further bump allocations */ glb_memlayout.allocs_avail = 0; + if (scb_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_SCB, scb_kaddr, 0)) assert(0); + printk("\tCapability table and page-table created.\n"); - if (comp_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_PT, 0, - mem_bootc_entry())) + if (comp_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_PT, + BOOT_CAPTBL_SELF_SCB, 0, (vaddr_t)mem_bootc_entry(), scb_uaddr)) assert(0); + printk("\tCreated boot component structure from page-table and capability-table.\n"); kern_boot_thd(glb_boot_ct, thd_mem[cpu_id], tcap_mem[cpu_id], cpu_id); From 3dd6a37eb59b65301f6f6b8d5bc9e9e6c6f05c19 Mon Sep 17 00:00:00 2001 From: WenyuanShao Date: Sun, 27 Feb 2022 20:55:27 -0500 Subject: [PATCH 2/7] Almost finish merge. Capmgr still have some problem. --- src/components/implementation/sched/sched.c | 4 +- .../implementation/sched/sched_info.c | 2 +- .../tests/kernel_tests/k_perf_tests.c | 6 +- .../tests/kernel_tests/k_test_async.c | 4 +- .../tests/kernel_tests/k_test_captbl.c | 2 +- .../tests/kernel_tests/k_test_inv.c | 2 +- .../tests/kernel_tests/k_test_tcap.c | 6 +- .../tests/kernel_tests/k_test_thd.c | 8 +- .../tests/kernel_tests/kernel_test_booter.c | 11 +- .../tests/micro_xcores/micro_xcores.c | 2 +- .../micro_xcores/test_ipi_interference.c | 6 +- .../tests/micro_xcores/test_ipi_n_n.c | 2 +- .../tests/micro_xcores/test_ipi_roundtrip.c | 4 +- .../tests/micro_xcores/test_ipi_switch.c | 6 +- .../tests/unit_defcompinfo/unit_defcompinfo.c | 2 +- .../lib/component/arch/x86/cos_component.h | 11 +- src/components/lib/crt/crt.c | 12 +- src/components/lib/dcb/Makefile | 63 ++++ src/components/lib/dcb/cos_dcb.c | 96 ++++++ src/components/lib/dcb/cos_dcb.h | 28 ++ src/components/lib/dcb/doc.md | 9 + src/components/lib/kernel/cos_kernel_api.c | 7 + src/components/lib/kernel/cos_kernel_api.h | 1 + src/components/lib/sl/sl.h | 84 +++++- src/components/lib/sl/sl_thd.h | 14 + src/components/lib/sl_capmgr/Makefile | 2 +- src/components/lib/sl_capmgr/sl_capmgr.c | 64 ++-- src/components/lib/sl_kernel/Makefile | 4 +- src/components/lib/sl_kernel/sl_raw.c | 91 ++++-- src/composer/src/resources.rs | 2 +- src/kernel/capinv.c | 281 +++++++++++++----- src/kernel/include/component.h | 14 + src/kernel/include/dcb.h | 39 ++- src/kernel/include/scb.h | 5 +- src/kernel/include/shared/cos_sched.h | 52 ++++ src/kernel/include/shared/cos_types.h | 49 ++- src/kernel/include/thd.h | 228 ++++++++++---- src/platform/i386/boot_comp.c | 79 ++--- src/platform/i386/chal/shared/cos_config.h | 1 + 39 files changed, 988 insertions(+), 315 deletions(-) create mode 100644 src/components/lib/dcb/Makefile create mode 100644 src/components/lib/dcb/cos_dcb.c create mode 100644 src/components/lib/dcb/cos_dcb.h create mode 100644 src/components/lib/dcb/doc.md create mode 100644 src/kernel/include/shared/cos_sched.h diff --git a/src/components/implementation/sched/sched.c b/src/components/implementation/sched/sched.c index dbb4028ff9..f4a1f224c8 100644 --- a/src/components/implementation/sched/sched.c +++ b/src/components/implementation/sched/sched.c @@ -88,7 +88,7 @@ sched_thd_create_closure(thdclosure_index_t idx) dci = sched_child_defci_get(sched_childinfo_find(c)); if (!dci) return 0; - t = sl_thd_aep_alloc_ext(dci, NULL, idx, 0, 0, 0, 0, 0, NULL); + t = sl_thd_aep_alloc_ext(dci, NULL, idx, 0, 0, 0, 0, 0, NULL, NULL); if (!t) return 0; return sl_thd_thdid(t); @@ -105,7 +105,7 @@ sched_aep_create_closure(thdclosure_index_t id, int owntc, cos_channelkey_t key, dci = sched_child_defci_get(sched_childinfo_find(c)); if (!dci) return 0; - t = sl_thd_aep_alloc_ext(dci, NULL, id, 1, owntc, key, ipiwin, ipimax, rcv); + t = sl_thd_aep_alloc_ext(dci, NULL, id, 1, owntc, key, ipiwin, ipimax, NULL, rcv); if (!t) return 0; return sl_thd_thdid(t); diff --git a/src/components/implementation/sched/sched_info.c b/src/components/implementation/sched/sched_info.c index 34b4619d42..679c4255f1 100644 --- a/src/components/implementation/sched/sched_info.c +++ b/src/components/implementation/sched/sched_info.c @@ -91,7 +91,7 @@ sched_childinfo_init_component(compid_t id) } assert(bitmap_check(schedinfo->cpubmp, cos_cpuid())); - initthd = sl_thd_initaep_alloc(child_dci, NULL, childflags & COMP_FLAG_SCHED, childflags & COMP_FLAG_SCHED ? 1 : 0, 0, 0, 0); /* TODO: rate information */ + initthd = sl_thd_initaep_alloc(child_dci, NULL, childflags & COMP_FLAG_SCHED, childflags & COMP_FLAG_SCHED ? 1 : 0, 0, 0, 0, NULL); /* TODO: rate information */ assert(initthd); /* Failure here? Capability manager likely needs to be depended on with capmgr_create */ sched_child_initthd_set(schedinfo, initthd); diff --git a/src/components/implementation/tests/kernel_tests/k_perf_tests.c b/src/components/implementation/tests/kernel_tests/k_perf_tests.c index 6696a8714b..8bfc75ef44 100644 --- a/src/components/implementation/tests/kernel_tests/k_perf_tests.c +++ b/src/components/implementation/tests/kernel_tests/k_perf_tests.c @@ -39,7 +39,7 @@ test_thds_create_switch(void) perfdata_init(&pd[cos_cpuid()], "COS THD => COS_THD_SWITCH", test_results, ARRAY_SIZE); - ts = cos_thd_alloc(&booter_info, booter_info.comp_cap, bounceback, NULL); + ts = cos_thd_alloc(&booter_info, booter_info.comp_cap, bounceback, NULL, 0, 0); if (EXPECT_LL_LT(1, ts, "Thread Creation: Cannot Allocate")) { return; } @@ -152,7 +152,7 @@ test_async_endpoints_perf(void) /* parent rcv capabilities */ tcp = cos_thd_alloc(&booter_info, booter_info.comp_cap, async_thd_parent_perf, - (void *)BOOT_CAPTBL_SELF_INITTHD_CPU_BASE); + (void *)BOOT_CAPTBL_SELF_INITTHD_CPU_BASE, 0, 0); if(EXPECT_LL_LT(1, tcp, "Test Async Endpoints")) return; tccp = cos_tcap_alloc(&booter_info); if(EXPECT_LL_LT(1, tccp, "Test Async Endpoints")) return; @@ -164,7 +164,7 @@ test_async_endpoints_perf(void) } /* child rcv capabilities */ - tcc = cos_thd_alloc(&booter_info, booter_info.comp_cap, async_thd_fn_perf, (void *)tcp); + tcc = cos_thd_alloc(&booter_info, booter_info.comp_cap, async_thd_fn_perf, (void *)tcp, 0, 0); if(EXPECT_LL_LT(1, tcc, "Test Async Endpoints")) return; tccc = cos_tcap_alloc(&booter_info); if(EXPECT_LL_LT(1, tccc, "Test Async Endpoints")) return; diff --git a/src/components/implementation/tests/kernel_tests/k_test_async.c b/src/components/implementation/tests/kernel_tests/k_test_async.c index 27203b6504..9d8a4a74f9 100644 --- a/src/components/implementation/tests/kernel_tests/k_test_async.c +++ b/src/components/implementation/tests/kernel_tests/k_test_async.c @@ -100,7 +100,7 @@ test_async_endpoints(void) /* parent rcv capabilities */ tcp = cos_thd_alloc(&booter_info, booter_info.comp_cap, async_thd_parent, - (void *)BOOT_CAPTBL_SELF_INITTHD_CPU_BASE); + (void *)BOOT_CAPTBL_SELF_INITTHD_CPU_BASE, 0, 0); if (EXPECT_LL_LT(1, tcp, "Test Async Endpoints")) { return; } @@ -118,7 +118,7 @@ test_async_endpoints(void) } /* child rcv capabilities */ - tcc = cos_thd_alloc(&booter_info, booter_info.comp_cap, async_thd_fn, (void *)tcp); + tcc = cos_thd_alloc(&booter_info, booter_info.comp_cap, async_thd_fn, (void *)tcp, 0, 0); if (EXPECT_LL_LT(1, tcc, "Test Async Endpoints")) { return; } diff --git a/src/components/implementation/tests/kernel_tests/k_test_captbl.c b/src/components/implementation/tests/kernel_tests/k_test_captbl.c index 4365195e08..d1d3d18551 100644 --- a/src/components/implementation/tests/kernel_tests/k_test_captbl.c +++ b/src/components/implementation/tests/kernel_tests/k_test_captbl.c @@ -17,7 +17,7 @@ test_captbl_expands(void) int i; compcap_t cc; - cc = cos_comp_alloc(&booter_info, booter_info.captbl_cap, booter_info.pgtbl_cap, (vaddr_t)NULL); + cc = cos_comp_alloc(&booter_info, booter_info.captbl_cap, booter_info.pgtbl_cap, 0, (vaddr_t)NULL, (vaddr_t)NULL); if (EXPECT_LL_LT(1, cc, "Capability Table Expansion")) { return; } diff --git a/src/components/implementation/tests/kernel_tests/k_test_inv.c b/src/components/implementation/tests/kernel_tests/k_test_inv.c index fe40eb2c5c..d465099990 100644 --- a/src/components/implementation/tests/kernel_tests/k_test_inv.c +++ b/src/components/implementation/tests/kernel_tests/k_test_inv.c @@ -88,7 +88,7 @@ test_inv(void) perfdata_init(&result, "SINV", test_results, ARRAY_SIZE); - cc = cos_comp_alloc(&booter_info, booter_info.captbl_cap, booter_info.pgtbl_cap, (vaddr_t)NULL); + cc = cos_comp_alloc(&booter_info, booter_info.captbl_cap, booter_info.pgtbl_cap, 0, (vaddr_t)NULL, (vaddr_t)NULL); if (EXPECT_LL_LT(1, cc, "Invocation: Cannot Allocate")) return; ic = cos_sinv_alloc(&booter_info, cc, (vaddr_t)__inv_test_serverfn, 0xdead); if (EXPECT_LL_LT(1, ic, "Invocation: Cannot Allocate")) return; diff --git a/src/components/implementation/tests/kernel_tests/k_test_tcap.c b/src/components/implementation/tests/kernel_tests/k_test_tcap.c index 817302c6a8..7a8ae3364f 100644 --- a/src/components/implementation/tests/kernel_tests/k_test_tcap.c +++ b/src/components/implementation/tests/kernel_tests/k_test_tcap.c @@ -48,8 +48,8 @@ test_timer(void) long long time, mask; tcap_time_t timer, thd_timeout; - tc = cos_thd_alloc(&booter_info, booter_info.comp_cap, spinner, NULL); - + tc = cos_thd_alloc(&booter_info, booter_info.comp_cap, spinner, NULL, 0, 0); + printc("thd alloc done\n"); perfdata_init(&result, "COS THD => COS_THD_SWITCH", test_results, ARRAY_SIZE); for (i = 0; i <= TEST_ITER; i++){ @@ -139,7 +139,7 @@ exec_cluster_alloc(struct exec_cluster *e, cos_thd_fn_t fn, void *d, arcvcap_t p { e->tcc = cos_tcap_alloc(&booter_info); if (EXPECT_LL_LT(1, e->tcc, "Cluster Allocation: TCAP ALLOC")) return -1; - e->tc = cos_thd_alloc(&booter_info, booter_info.comp_cap, fn, d); + e->tc = cos_thd_alloc(&booter_info, booter_info.comp_cap, fn, d, 0, 0); if (EXPECT_LL_LT(1, e->tc, "Cluster Allocation: THD ALLOC")) return -1; e->rc = cos_arcv_alloc(&booter_info, e->tc, e->tcc, booter_info.comp_cap, parentc); if (EXPECT_LL_LT(1, e->rc, "Cluster Allocation: ARCV ALLOC")) return -1; diff --git a/src/components/implementation/tests/kernel_tests/k_test_thd.c b/src/components/implementation/tests/kernel_tests/k_test_thd.c index 38fb99a749..f369b42190 100644 --- a/src/components/implementation/tests/kernel_tests/k_test_thd.c +++ b/src/components/implementation/tests/kernel_tests/k_test_thd.c @@ -25,7 +25,7 @@ test_thds_create_switch(void) intptr_t i = THD_ARG; int ret; - ts = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_thd_arg, (void *)i); + ts = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_thd_arg, (void *)i, 0, 0); if (EXPECT_LL_LT(1, ts, "Thread Creation: Cannot Allocate")) { return; } @@ -72,7 +72,7 @@ test_mthds_ring(void) count = 0; for (i = 0; i < TEST_NTHDS; i++) { - thd_test[i] = cos_thd_alloc(&booter_info, booter_info.comp_cap, thd_fn_mthds_ring, (void *)i); + thd_test[i] = cos_thd_alloc(&booter_info, booter_info.comp_cap, thd_fn_mthds_ring, (void *)i, 0, 0); if (EXPECT_LL_LT(1, thd_test[i], "Thread Ring: Cannot Allocate")) { return; } @@ -113,7 +113,7 @@ test_mthds_classic(void) thdcap_t ts; int i, ret; - ts = cos_thd_alloc(&booter_info, booter_info.comp_cap, thd_fn_mthds_classic, NULL); + ts = cos_thd_alloc(&booter_info, booter_info.comp_cap, thd_fn_mthds_classic, NULL, 0, 0); if (EXPECT_LL_LT(1, ts, "Thread Classic: Cannot Allocate")) { return; } @@ -151,7 +151,7 @@ test_thds_tls(void) int ret; for (i = 0; i < TEST_NTHDS; i++) { - ts[i] = cos_thd_alloc(&booter_info, booter_info.comp_cap, thd_tls, (void *)i); + ts[i] = cos_thd_alloc(&booter_info, booter_info.comp_cap, thd_tls, (void *)i, 0, 0); if (EXPECT_LL_LT(1, ts[i], "Thread TLS: Cannot Allocate")) { return; } diff --git a/src/components/implementation/tests/kernel_tests/kernel_test_booter.c b/src/components/implementation/tests/kernel_tests/kernel_test_booter.c index d1bf38345d..2b55cff77e 100644 --- a/src/components/implementation/tests/kernel_tests/kernel_test_booter.c +++ b/src/components/implementation/tests/kernel_tests/kernel_test_booter.c @@ -37,13 +37,22 @@ test_run_unit_kernel(void) /* Kernel Tests */ printc("\n"); PRINTC("Unit Test Started:\n\n"); + PRINTC("timer:\n"); test_timer(); + PRINTC("test_tcap_budgets: \n"); test_tcap_budgets(); + PRINTC("2timers:\n"); test_2timers(); + test_2timers(); + PRINTC("thds:\n"); test_thds(); + PRINTC("mem_alloc:\n"); test_mem_alloc(); + PRINTC("endpoints:\n"); test_async_endpoints(); + PRINTC("inv:\n"); test_inv(); + PRINTC("captbl_expands:\n"); test_captbl_expands(); } @@ -53,7 +62,7 @@ main(void) int i; PRINTC("Kernel Tests\n"); - termthd[cos_cpuid()] = cos_thd_alloc(&booter_info, booter_info.comp_cap, term_fn, NULL); + termthd[cos_cpuid()] = cos_thd_alloc(&booter_info, booter_info.comp_cap, term_fn, NULL, 0, 0); assert(termthd[cos_cpuid()]); cyc_per_usec = cos_hw_cycles_per_usec(BOOT_CAPTBL_SELF_INITHW_BASE); diff --git a/src/components/implementation/tests/micro_xcores/micro_xcores.c b/src/components/implementation/tests/micro_xcores/micro_xcores.c index b1b744c42b..1bd98c126c 100644 --- a/src/components/implementation/tests/micro_xcores/micro_xcores.c +++ b/src/components/implementation/tests/micro_xcores/micro_xcores.c @@ -36,7 +36,7 @@ cos_init(void) while (!init_done); - termthd[cos_cpuid()] = cos_thd_alloc(&booter_info, booter_info.comp_cap, term_fn, NULL); + termthd[cos_cpuid()] = cos_thd_alloc(&booter_info, booter_info.comp_cap, term_fn, NULL, 0, 0); assert(termthd[cos_cpuid()]); if (cos_cpuid() == 0) PRINTC("Micro Booter Xcore started.\n"); diff --git a/src/components/implementation/tests/micro_xcores/test_ipi_interference.c b/src/components/implementation/tests/micro_xcores/test_ipi_interference.c index f301f9d873..f96dd84ad7 100644 --- a/src/components/implementation/tests/micro_xcores/test_ipi_interference.c +++ b/src/components/implementation/tests/micro_xcores/test_ipi_interference.c @@ -190,7 +190,7 @@ test_ipi_interference(void) if (EXPECT_LL_LT(1, tcc, "IPI Interference: TCAP Allocation")) return; - t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_rcv_fn, NULL); + t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_rcv_fn, NULL, 0, 0); if (EXPECT_LL_LT(1, t, "IPI Inteference: Thread Allocation")) return; @@ -205,7 +205,7 @@ test_ipi_interference(void) rcv[cos_cpuid()] = r; while (!rcv[TEST_SND_CORE]) ; - t = cos_thd_alloc(&booter_info, booter_info.comp_cap, rcv_spinner, NULL); + t = cos_thd_alloc(&booter_info, booter_info.comp_cap, rcv_spinner, NULL, 0, 0); if (EXPECT_LL_LT(1, t, "IPI Interference: Thread Allocation")) return; @@ -230,7 +230,7 @@ test_ipi_interference(void) if (EXPECT_LL_LT(1, tcc, "IPI Interference: TCAP Allocation")) return; - t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_asnd_fn, NULL); + t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_asnd_fn, NULL, 0, 0); if (EXPECT_LL_LT(1, t, "IPI Interference: Thread Allocation")) return; diff --git a/src/components/implementation/tests/micro_xcores/test_ipi_n_n.c b/src/components/implementation/tests/micro_xcores/test_ipi_n_n.c index 73d57ec9e0..25da1d99eb 100644 --- a/src/components/implementation/tests/micro_xcores/test_ipi_n_n.c +++ b/src/components/implementation/tests/micro_xcores/test_ipi_n_n.c @@ -49,7 +49,7 @@ test_rcv_crt(void) asndcap_t snd = 0; if ((word_t)cos_cpuid() == i) continue; - thd = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_ipi_fn, (void *)i); + thd = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_ipi_fn, (void *)i, 0, 0); assert(thd); rcv = cos_arcv_alloc(&booter_info, thd, BOOT_CAPTBL_SELF_INITTCAP_CPU_BASE, booter_info.comp_cap, BOOT_CAPTBL_SELF_INITRCV_CPU_BASE); diff --git a/src/components/implementation/tests/micro_xcores/test_ipi_roundtrip.c b/src/components/implementation/tests/micro_xcores/test_ipi_roundtrip.c index 24dd2c13ad..d503f3a496 100644 --- a/src/components/implementation/tests/micro_xcores/test_ipi_roundtrip.c +++ b/src/components/implementation/tests/micro_xcores/test_ipi_roundtrip.c @@ -167,7 +167,7 @@ test_ipi_roundtrip(void) return; - t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_rcv_fn, NULL); + t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_rcv_fn, NULL, 0, 0); if (EXPECT_LL_LT(1, t, "IPI ROUNDTRIP: Thread Allocation")) return; @@ -196,7 +196,7 @@ test_ipi_roundtrip(void) /* Test Sender Time */ - t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_asnd_fn, NULL); + t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_asnd_fn, NULL, 0, 0); if (EXPECT_LL_LT(1, t, "IPI ROUNDTRIP: Thread Allocation")) return; diff --git a/src/components/implementation/tests/micro_xcores/test_ipi_switch.c b/src/components/implementation/tests/micro_xcores/test_ipi_switch.c index e13dbda15d..e92b551770 100644 --- a/src/components/implementation/tests/micro_xcores/test_ipi_switch.c +++ b/src/components/implementation/tests/micro_xcores/test_ipi_switch.c @@ -192,7 +192,7 @@ test_ipi_switch(void) if (EXPECT_LL_LT(1, tcc, "IPI SWITCH: TCAP Allocation")) return; - t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_rcv_fn, NULL); + t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_rcv_fn, NULL, 0, 0); if (EXPECT_LL_LT(1, t, "IPI SWITCH: Thread Allocation")) return; @@ -207,7 +207,7 @@ test_ipi_switch(void) rcv[cos_cpuid()] = r; while (!rcv[TEST_SND_CORE]) ; - t = cos_thd_alloc(&booter_info, booter_info.comp_cap, rcv_spinner, NULL); + t = cos_thd_alloc(&booter_info, booter_info.comp_cap, rcv_spinner, NULL, 0, 0); if (EXPECT_LL_LT(1, t, "IPI SWITCH: Thread Allocation")) return; @@ -226,7 +226,7 @@ test_ipi_switch(void) /* Test RCV1: Corresponding Send */ - t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_asnd_fn, NULL); + t = cos_thd_alloc(&booter_info, booter_info.comp_cap, test_asnd_fn, NULL, 0, 0); if (EXPECT_LL_LT(1, t, "IPI SWITCH: Thread Allocation")) return; diff --git a/src/components/implementation/tests/unit_defcompinfo/unit_defcompinfo.c b/src/components/implementation/tests/unit_defcompinfo/unit_defcompinfo.c index 262e3fb098..8c321dd13d 100644 --- a/src/components/implementation/tests/unit_defcompinfo/unit_defcompinfo.c +++ b/src/components/implementation/tests/unit_defcompinfo/unit_defcompinfo.c @@ -137,7 +137,7 @@ cos_init(void) cos_meminfo_init(&(child_ci->mi), BOOT_MEM_KM_BASE, CHILD_UNTYPED_SIZE, child_utpt); //cos_defcompinfo_child_alloc(&child_defci[id], (vaddr_t)&__cosrt_upcall_entry, // (vaddr_t)BOOT_MEM_VM_BASE, BOOT_CAPTBL_FREE, is_sched); - cos_defcompinfo_child_alloc(&child_defci[id], (vaddr_t)&cosrt_upcall_entry, + cos_defcompinfo_child_alloc(&child_defci[id], (vaddr_t)&__cosrt_upcall_entry, (vaddr_t)BOOT_MEM_VM_BASE, BOOT_CAPTBL_FREE, is_sched, &dcbaddr); printc("\t\tCopying new capabilities\n"); diff --git a/src/components/lib/component/arch/x86/cos_component.h b/src/components/lib/component/arch/x86/cos_component.h index fcaacc7582..b5d4d25aba 100644 --- a/src/components/lib/component/arch/x86/cos_component.h +++ b/src/components/lib/component/arch/x86/cos_component.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -256,13 +257,17 @@ cos_compid_set(compid_t cid) static inline void * cos_get_heap_ptr(void) { - return (void *)__cosrt_comp_info.cos_heap_ptr; + /* page at heap_ptr is actually the SCB_PAGE for any component. */ + unsigned int off = COS_SCB_SIZE + (PAGE_SIZE * NUM_CPU); + void *heap_ptr = (void *)(__cosrt_comp_info.cos_heap_ptr + off); + + return heap_ptr; } static inline struct cos_scb_info * cos_scb_info_get(void) { - return (struct cos_scb_info *)(cos_comp_info.cos_heap_ptr); + return (struct cos_scb_info *)(__cosrt_comp_info.cos_heap_ptr); } static inline struct cos_scb_info * @@ -275,7 +280,7 @@ static inline struct cos_dcb_info * cos_init_dcb_get(void) { /* created at boot-time for the first component in the system! */ - if (cos_spd_id() == 0) return (struct cos_dcb_info *)(cos_comp_info.cos_heap_ptr + COS_SCB_SIZE + (PAGE_SIZE * cos_cpuid())); + if (cos_spd_id() == 0) return (struct cos_dcb_info *)(__cosrt_comp_info.cos_heap_ptr + COS_SCB_SIZE + (PAGE_SIZE * cos_cpuid())); return NULL; } diff --git a/src/components/lib/crt/crt.c b/src/components/lib/crt/crt.c index 3cc35911a0..cb23911ac5 100644 --- a/src/components/lib/crt/crt.c +++ b/src/components/lib/crt/crt.c @@ -266,7 +266,7 @@ crt_comp_create_from(struct crt_comp *c, char *name, compid_t id, struct crt_chk assert(inv.server->id != chkpt->c->id); } - ret = cos_compinfo_alloc(ci, c->ro_addr, BOOT_CAPTBL_FREE, c->entry_addr, root_ci); + ret = cos_compinfo_alloc(ci, 0, c->ro_addr, BOOT_CAPTBL_FREE, c->entry_addr, root_ci); assert(!ret); mem = cos_page_bump_allocn(root_ci, chkpt->tot_sz_mem); @@ -333,7 +333,7 @@ crt_comp_create(struct crt_comp *c, char *name, compid_t id, void *elf_hdr, vadd printc("\t\t elf obj: ro [0x%lx, 0x%lx), data [0x%lx, 0x%lx), bss [0x%lx, 0x%lx).\n", c->ro_addr, c->ro_addr + ro_sz, c->rw_addr, c->rw_addr + data_sz, c->rw_addr + data_sz, c->rw_addr + data_sz + bss_sz); - ret = cos_compinfo_alloc(ci, c->ro_addr, BOOT_CAPTBL_FREE, c->entry_addr, root_ci); + ret = cos_compinfo_alloc(ci, 0, c->ro_addr, BOOT_CAPTBL_FREE, c->entry_addr, root_ci); assert(!ret); tot_sz = round_up_to_page(round_up_to_page(ro_sz) + data_sz + bss_sz); @@ -656,11 +656,11 @@ crt_thd_create_in(struct crt_thd *t, struct crt_comp *c, thdclosure_index_t clos crt_refcnt_take(&c->refcnt); assert(target_ci->comp_cap); - thdcap = target_aep->thd = cos_initthd_alloc(ci, target_ci->comp_cap); + thdcap = target_aep->thd = cos_initthd_alloc(ci, target_ci->comp_cap, 0); assert(target_aep->thd); } else { crt_refcnt_take(&c->refcnt); - thdcap = cos_thd_alloc_ext(ci, target_ci->comp_cap, closure_id); + thdcap = cos_thd_alloc_ext(ci, target_ci->comp_cap, closure_id, 0, 0); assert(thdcap); } @@ -771,9 +771,9 @@ crt_rcv_create_in(struct crt_rcv *r, struct crt_comp *c, struct crt_rcv *sched, crt_refcnt_take(&c->refcnt); assert(target_ci->comp_cap); if (closure_id == 0) { - thdcap = cos_initthd_alloc(cos_compinfo_get(defci), target_ci->comp_cap); + thdcap = cos_initthd_alloc(cos_compinfo_get(defci), target_ci->comp_cap, 0); } else { - thdcap = cos_thd_alloc_ext(cos_compinfo_get(defci), target_ci->comp_cap, closure_id); + thdcap = cos_thd_alloc_ext(cos_compinfo_get(defci), target_ci->comp_cap, closure_id, 0, 0); } assert(thdcap); diff --git a/src/components/lib/dcb/Makefile b/src/components/lib/dcb/Makefile new file mode 100644 index 0000000000..e1589570b2 --- /dev/null +++ b/src/components/lib/dcb/Makefile @@ -0,0 +1,63 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The library names associated with .a files output that are linked +# (via, for example, -ldcb) into dependents. This list should be +# "dcb" for output files such as libdcb.a. +LIBRARY_OUTPUT = dcb +# The .o files that are mandatorily linked into dependents. This is +# rarely used, and only when normal .a linking rules will avoid +# linking some necessary objects. This list is of names (for example, +# dcb) which will generate dcb.lib.o. Do NOT include the list of .o +# files here. Please note that using this list is *very rare* and +# should only be used when the .a support above is not appropriate. +OBJECT_OUTPUT = +# The path within this directory that holds the .h files for +# dependents to compile with (./ by default). Will be fed into the -I +# compiler arguments. +INCLUDE_PATHS = . +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +# There are two different *types* of Makefiles for libraries. +# 1. Those that are Composite-specific, and simply need an easy way to +# compile and itegrate their code. +# 2. Those that aim to integrate external libraries into +# Composite. These focus on "driving" the build process of the +# external library, then pulling out the resulting files and +# directories. These need to be flexible as all libraries are +# different. + +# Type 1, Composite library: This is the default Makefile for +# libraries written for composite. Get rid of this if you require a +# custom Makefile (e.g. if you use an existing +# (non-composite-specific) library. An example of this is `kernel`. +include Makefile.lib + +## Type 2, external library: If you need to specialize the Makefile +## for an external library, you can add the external code as a +## subdirectory, and drive its compilation, and integration with the +## system using a specialized Makefile. The Makefile must generate +## lib$(LIBRARY_OUTPUT).a and $(OBJECT_OUTPUT).lib.o, and have all of +## the necessary include paths in $(INCLUDE_PATHS). +## +## To access the Composite Makefile definitions, use the following. An +## example of a Makefile written in this way is in `ps/`. +# +# include Makefile.src Makefile.comp Makefile.dependencies +# .PHONY: all clean init distclean +## Fill these out with your implementation +# all: +# clean: +# +## Default rules: +# init: clean all +# distclean: clean diff --git a/src/components/lib/dcb/cos_dcb.c b/src/components/lib/dcb/cos_dcb.c new file mode 100644 index 0000000000..e73069af8f --- /dev/null +++ b/src/components/lib/dcb/cos_dcb.c @@ -0,0 +1,96 @@ +#include +#include +#include + +static struct cos_dcbinfo_data _cos_dcbinfo[NUM_CPU]; + +void +cos_dcb_info_init_ext(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci, + dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t start_off) +{ + memset(cdi, 0, sizeof(struct cos_dcbinfo_data)); + + cdi->dcbcaps[0] = initdcbcap; + cdi->dcbaddr[0] = initdcbaddr; + cdi->curr_cap_off = start_off; + cdi->curr_cap = 0; +} + +void +cos_dcb_info_init(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci) +{ + if (cos_spd_id() == 0) { + cos_dcb_info_init_ext(cdi, ci, LLBOOT_CAPTBL_CPU_INITDCB, + (vaddr_t)cos_init_dcb_get(), 1); + } else { + cos_dcb_info_init_ext(cdi, ci, 0, 0, 0); + } +} + +void +cos_dcb_info_init_curr(void) +{ + cos_dcb_info_init_curr_ext(0, 0, 0); +} + +void +cos_dcb_info_init_curr_ext(dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t st_off) +{ + struct cos_compinfo *ci = cos_compinfo_get(cos_defcompinfo_curr_get()); + + if (initdcbcap == 0 && initdcbaddr == 0) { + + if (cos_spd_id() == 0) { + cos_dcb_info_init_ext(&_cos_dcbinfo[cos_cpuid()], ci, + LLBOOT_CAPTBL_CPU_INITDCB, (vaddr_t)cos_init_dcb_get(), 1); + + return; + } else { + initdcbaddr = cos_page_bump_intern_valloc(ci, PAGE_SIZE); + assert(initdcbaddr); + initdcbcap = cos_dcb_alloc(ci, ci->pgtbl_cap, initdcbaddr); + assert(initdcbcap); + st_off = 0; + } + } + cos_dcb_info_init_ext(&_cos_dcbinfo[cos_cpuid()], ci, initdcbcap, initdcbaddr, st_off); +} + +dcbcap_t +cos_dcb_info_alloc_curr(dcboff_t *dcboff, vaddr_t *dcbaddr) +{ + return cos_dcb_info_alloc(&_cos_dcbinfo[cos_cpuid()], dcboff, dcbaddr); +} + +dcbcap_t +cos_dcb_info_alloc(struct cos_dcbinfo_data *cdi, dcboff_t *dcboff, vaddr_t *dcbaddr) +{ + if (unlikely(cdi->dcbcaps[cdi->curr_cap] == 0)) { + *dcboff = 0; + *dcbaddr = 0; + + return 0; + } + if (cdi->curr_cap_off >= COS_DCB_PERPG_MAX) { + int ret; + unsigned short curr_off = cdi->curr_cap; + + assert(curr_off + 1 < (unsigned short)COS_DCB_MAX_CAPS && cdi->dcbcaps[curr_off + 1] == 0); + + cdi->dcbaddr[curr_off + 1] = cos_page_bump_intern_valloc(cdi->ci, PAGE_SIZE); + assert(cdi->dcbaddr[curr_off + 1]); + cdi->dcbcaps[curr_off + 1] = cos_dcb_alloc(cos_compinfo_get(cos_defcompinfo_curr_get()), + cdi->ci->pgtbl_cap, cdi->dcbaddr[curr_off + 1]); + + assert(cdi->dcbcaps[curr_off + 1]); + ret = ps_cas((unsigned long *)&cdi->curr_cap, curr_off, curr_off + 1); + assert(ret); + ret = ps_cas((unsigned long *)&cdi->curr_cap_off, cdi->curr_cap_off, 0); + assert(ret); + } + + *dcboff = ps_faa((unsigned long *)&cdi->curr_cap_off, 1); + *dcbaddr = cdi->dcbaddr[cdi->curr_cap] + (sizeof(struct cos_dcb_info) * (*dcboff)); + + return cdi->dcbcaps[cdi->curr_cap]; +} diff --git a/src/components/lib/dcb/cos_dcb.h b/src/components/lib/dcb/cos_dcb.h new file mode 100644 index 0000000000..1fc6298da6 --- /dev/null +++ b/src/components/lib/dcb/cos_dcb.h @@ -0,0 +1,28 @@ +#ifndef COS_DCB_H +#define COS_DCB_H + +#include +#include + +#define COS_DCB_PERPG_MAX (PAGE_SIZE / sizeof(struct cos_dcb_info)) + +#define COS_DCB_MAX_CAPS (MAX_NUM_THREADS / COS_DCB_PERPG_MAX + 1) + +struct cos_dcbinfo_data { + dcbcap_t dcbcaps[COS_DCB_MAX_CAPS]; + vaddr_t dcbaddr[COS_DCB_MAX_CAPS]; + dcboff_t curr_cap_off; + unsigned short curr_cap; + + struct cos_compinfo *ci; +} CACHE_ALIGNED; + +void cos_dcb_info_init(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci); +void cos_dcb_info_init_ext(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci, dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t start_off); +dcbcap_t cos_dcb_info_alloc(struct cos_dcbinfo_data *cdi, dcboff_t *dcboff, vaddr_t *dcbaddr); + +void cos_dcb_info_init_curr(void); +void cos_dcb_info_init_curr_ext(dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t st_off); +dcbcap_t cos_dcb_info_alloc_curr(dcboff_t *dcboff, vaddr_t *dcbaddr); + +#endif /* COS_DCB_H */ diff --git a/src/components/lib/dcb/doc.md b/src/components/lib/dcb/doc.md new file mode 100644 index 0000000000..614aa37dc8 --- /dev/null +++ b/src/components/lib/dcb/doc.md @@ -0,0 +1,9 @@ +## dcb + +This is the skeleton library used by the `mklib.sh` script to aid in the creation of a new library. +It provides no functionality, and should never be depended on! +This documentation should be *replaced* in the documentation for a new library. + +### Description + +### Usage and Assumptions diff --git a/src/components/lib/kernel/cos_kernel_api.c b/src/components/lib/kernel/cos_kernel_api.c index b3696c509f..a483ea782b 100644 --- a/src/components/lib/kernel/cos_kernel_api.c +++ b/src/components/lib/kernel/cos_kernel_api.c @@ -662,6 +662,12 @@ __page_bump_valloc(struct cos_compinfo *ci, size_t sz) return ret_addr; } +vaddr_t +cos_page_bump_intern_valloc(struct cos_compinfo *ci, size_t sz) +{ + return __page_bump_valloc(ci, sz); +} + static vaddr_t __page_bump_alloc(struct cos_compinfo *ci, size_t sz, int shared) { @@ -770,6 +776,7 @@ cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, cos_thd_fn_t fn, void *da if (idx < 1) return 0; ret = __cos_thd_alloc(ci, comp, idx, dc, off); + printc("__cos_thd_alloc success: %d\n", ret); if (!ret) cos_thd_init_free(idx); return ret; diff --git a/src/components/lib/kernel/cos_kernel_api.h b/src/components/lib/kernel/cos_kernel_api.h index 48a290f7e2..04e1b38a2f 100644 --- a/src/components/lib/kernel/cos_kernel_api.h +++ b/src/components/lib/kernel/cos_kernel_api.h @@ -214,5 +214,6 @@ void cos_hw_shutdown(hwcap_t hwc); capid_t cos_capid_bump_alloc(struct cos_compinfo *ci, cap_t cap); +vaddr_t cos_page_bump_intern_valloc(struct cos_compinfo *ci, size_t sz); #endif /* COS_KERNEL_API_H */ diff --git a/src/components/lib/sl/sl.h b/src/components/lib/sl/sl.h index 9108a9467d..50baf54c3d 100644 --- a/src/components/lib/sl/sl.h +++ b/src/components/lib/sl/sl.h @@ -66,6 +66,7 @@ struct sl_global_cpu { cycles_t timer_next; tcap_time_t timeout_next; + struct cos_scb_info *scb_info; struct ps_list_head event_head; /* all pending events for sched end-point */ }; @@ -77,6 +78,12 @@ sl__globals_cpu(void) return &(sl_global_cpu_data[cos_cpuid()]); } +static inline struct cos_scb_info * +sl_scb_info_cpu(void) +{ + return (sl__globals_cpu()->scb_info); +} + static inline void sl_thd_setprio(struct sl_thd *t, tcap_prio_t p) { @@ -282,8 +289,10 @@ struct sl_thd *sl_thd_aep_alloc(cos_aepthd_fn_t fn, void *data, int own_tcap, co */ struct sl_thd *sl_thd_comp_init(struct cos_defcompinfo *comp, int is_sched); -struct sl_thd *sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax); -struct sl_thd *sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv); +struct sl_thd *sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax,dcbcap_t dcap); +struct sl_thd *sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, dcbcap_t dcap, dcboff_t doff, arcvcap_t *extrcv); +struct sl_thd *sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbaddr); +struct sl_thd *sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbaddr, arcvcap_t *extrcv); struct sl_thd *sl_thd_init_ext(struct cos_aep_info *aep, struct sl_thd *sched_thd); @@ -341,6 +350,8 @@ sl_timeout_oneshot(cycles_t absolute_us) { sl__globals_cpu()->timer_next = absolute_us; sl__globals_cpu()->timeout_next = tcap_cyc2time(absolute_us); + + sl_scb_info_cpu()->timer_next = absolute_us; } static inline void @@ -395,6 +406,60 @@ sl_thd_is_runnable(struct sl_thd *t) return (t->state == SL_THD_RUNNABLE || t->state == SL_THD_WOKEN); } +int sl_thd_kern_dispatch(thdcap_t t); + +static inline int +sl_thd_dispatch(struct sl_thd *next, sched_tok_t tok, struct sl_thd *curr) +{ + struct cos_scb_info *scb = sl_scb_info_cpu(); + + /* + * jump labels in the asm routine: + * + * 1: slowpath dispatch using cos_thd_switch to switch to a thread + * if the dcb sp of the next thread is reset. + * (inlined slowpath sysenter to debug preemption problem) + * + * 2: if user-level dispatch routine completed successfully so + * the register states still retained and in the dispatched thread + * we reset its dcb sp! + * + * 3: if user-level dispatch was either preempted in the middle + * of this routine or kernel at some point had to switch to a + * thread that co-operatively switched away from this routine. + * NOTE: kernel takes care of resetting dcb sp in this case! + */ + + __asm__ __volatile__ ( \ + "movl $2f, (%%eax)\n\t" \ + "movl %%esp, 4(%%eax)\n\t" \ + "cmp $0, 4(%%ebx)\n\t" \ + "je 1f\n\t" \ + "movl %%edx, (%%ecx)\n\t" \ + "movl 4(%%ebx), %%esp\n\t" \ + "jmp *(%%ebx)\n\t" \ + "1:\n\t" \ + "pushl %%ebp\n\t" \ + "movl %%esp, %%ebp\n\t" \ + "pushl %%edx\n\t" \ + "call sl_thd_kern_dispatch\n\t" \ + "addl $4, %%esp\n\t" \ + "popl %%ebp\n\t" \ + "jmp 3f\n\t" \ + ".align 4\n\t" \ + "2:\n\t" \ + "movl $0, 4(%%ebx)\n\t" \ + ".align 4\n\t" \ + "3:\n\t" \ + : + : "a" (sl_thd_dcbinfo(curr)), "b" (sl_thd_dcbinfo(next)), + "S" ((u32_t)((u64_t)tok >> 32)), "D" ((u32_t)(((u64_t)tok << 32) >> 32)), + "c" (&(scb->curr_thd)), "d" (sl_thd_thdcap(next)) + : "memory", "cc"); + + return sl_scb_info_cpu()->sched_tok != tok ? -EAGAIN : 0; +} + static inline int sl_thd_activate(struct sl_thd *t, sched_tok_t tok) { @@ -409,16 +474,10 @@ sl_thd_activate(struct sl_thd *t, sched_tok_t tok) return cos_switch(sl_thd_thdcap(t), sl_thd_tcap(t), t->prio, g->timeout_next, g->sched_rcv, tok); } else { - ret = cos_defswitch(sl_thd_thdcap(t), t->prio, t == g->sched_thd ? - TCAP_TIME_NIL : g->timeout_next, tok); - if (likely(t != g->sched_thd && t != g->idle_thd)) return ret; - if (unlikely(ret != -EPERM)) return ret; - - /* - * Attempting to activate scheduler thread or idle thread failed for no budget in it's tcap. - * Force switch to the scheduler with current tcap. - */ - return cos_switch(sl_thd_thdcap(g->sched_thd), 0, t->prio, 0, g->sched_rcv, tok); + /* TODO: can't use if you're reprogramming a timer/prio */ + return sl_thd_dispatch(t, tok, sl_thd_curr()); + //return cos_switch(sl_thd_thdcap(t), g->sched_tcap, t->prio, + // g->timeout_next, g->sched_rcv, tok); } } @@ -512,6 +571,7 @@ sl_cs_exit_schedule_nospin_arg(struct sl_thd *to) assert(sl_thd_is_runnable(t)); sl_cs_exit(); + if (t == sl_thd_curr()) return 0; ret = sl_thd_activate(t, tok); /* diff --git a/src/components/lib/sl/sl_thd.h b/src/components/lib/sl/sl_thd.h index bd1035f27c..67c1d97ff1 100644 --- a/src/components/lib/sl/sl_thd.h +++ b/src/components/lib/sl/sl_thd.h @@ -95,8 +95,22 @@ struct sl_thd { struct event_info event_info; struct ps_list SL_THD_EVENT_LIST; /* list of events for the scheduler end-point */ + + struct cos_dcb_info *dcb; }; +static inline struct cos_dcb_info * +sl_thd_dcbinfo(struct sl_thd *t) +{ return t->dcb; } + +static inline unsigned long * +sl_thd_ip(struct sl_thd *t) +{ return &t->dcb->ip; } + +static inline unsigned long * +sl_thd_sp(struct sl_thd *t) +{ return &t->dcb->sp; } + static inline struct cos_aep_info * sl_thd_aepinfo(struct sl_thd *t) { return (t->aepinfo); } diff --git a/src/components/lib/sl_capmgr/Makefile b/src/components/lib/sl_capmgr/Makefile index 26146aa8ad..1c61e8ddb8 100644 --- a/src/components/lib/sl_capmgr/Makefile +++ b/src/components/lib/sl_capmgr/Makefile @@ -21,7 +21,7 @@ INCLUDE_PATHS = . INTERFACE_DEPENDENCIES = capmgr memmgr # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = component ps sl kernel util +LIBRARY_DEPENDENCIES = component ps sl kernel util dcb # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/lib/sl_capmgr/sl_capmgr.c b/src/components/lib/sl_capmgr/sl_capmgr.c index 011cb58113..8fc4eaf17e 100644 --- a/src/components/lib/sl_capmgr/sl_capmgr.c +++ b/src/components/lib/sl_capmgr/sl_capmgr.c @@ -14,6 +14,7 @@ #include "../../interface/capmgr/memmgr.h" #include #include +#include extern void sl_thd_event_info_reset(struct sl_thd *t); extern void sl_thd_free_no_cs(struct sl_thd *t); @@ -55,7 +56,7 @@ sl_xcpu_asnd_alloc(void) } struct sl_thd * -sl_thd_alloc_init(struct cos_aep_info *aep, asndcap_t sndcap, sl_thd_property_t prps) +sl_thd_alloc_init(struct cos_aep_info *aep, asndcap_t sndcap, sl_thd_property_t prps, struct cos_dcb_info *dcb) { struct sl_thd_policy *tp = NULL; struct sl_thd *t = NULL; @@ -64,6 +65,7 @@ sl_thd_alloc_init(struct cos_aep_info *aep, asndcap_t sndcap, sl_thd_property_t if (!tp) goto done; t = sl_mod_thd_get(tp); + t->dcb = dcb; t->properties = prps; t->aepinfo = aep; t->sndcap = sndcap; @@ -88,20 +90,21 @@ struct sl_thd * sl_thd_alloc_no_cs(cos_thd_fn_t fn, void *data) { struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); - struct cos_compinfo *ci = &dci->ci; + struct cos_compinfo *ci = cos_compinfo_get(dci); struct sl_thd *t = NULL; struct cos_aep_info *aep = NULL; + struct cos_dcb_info *dcb = NULL; thdcap_t thdcap = 0; thdid_t tid = 0; aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; - aep->thd = capmgr_thd_create(fn, data, &tid); + aep->thd = capmgr_thd_create(fn, data, &tid, &dcb); if (!aep->thd) goto done; aep->tid = tid; - t = sl_thd_alloc_init(aep, 0, 0); + t = sl_thd_alloc_init(aep, 0, 0, dcb); sl_mod_thd_create(sl_mod_thd_policy_get(t)); done: @@ -128,7 +131,7 @@ sl_thd_comp_init_no_cs(struct cos_defcompinfo *comp, sl_thd_property_t prps, asn assert(snd); } - t = sl_thd_alloc_init(aep, snd, prps); + t = sl_thd_alloc_init(aep, snd, prps, NULL); sl_mod_thd_create(sl_mod_thd_policy_get(t)); done: @@ -136,7 +139,7 @@ sl_thd_comp_init_no_cs(struct cos_defcompinfo *comp, sl_thd_property_t prps, asn } static struct sl_thd * -sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx) +sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx, vaddr_t *dcbuaddr) { struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); struct cos_compinfo *ci = cos_compinfo_get(dci); @@ -150,11 +153,11 @@ sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx) aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; - aep->thd = capmgr_thd_create_ext(comp->id, idx, &aep->tid); + aep->thd = capmgr_thd_create_ext(comp->id, idx, &aep->tid, (struct cos_dcb_info **)dcbuaddr); if (!aep->thd) goto done; aep->tc = sl_thd_tcap(sl__globals_cpu()->sched_thd); - t = sl_thd_alloc_init(aep, 0, 0); + t = sl_thd_alloc_init(aep, 0, 0, NULL); sl_mod_thd_create(sl_mod_thd_policy_get(t)); } else { struct cos_aep_info *compaep = cos_sched_aep_get(comp); @@ -173,7 +176,7 @@ sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx) } static struct sl_thd * -sl_thd_aep_alloc_ext_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, thdclosure_index_t idx, sl_thd_property_t prps, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) +sl_thd_aep_alloc_ext_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, thdclosure_index_t idx, sl_thd_property_t prps, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbuaddr, arcvcap_t *extrcv) { struct cos_aep_info *aep = NULL; struct sl_thd *t = NULL; @@ -198,10 +201,10 @@ sl_thd_aep_alloc_ext_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, t if (!aep) goto done; if (prps & SL_THD_PROPERTY_OWN_TCAP) owntc = 1; - capmgr_aep_create_ext(comp->id, aep, idx, owntc, key, ipiwin, ipimax, extrcv); + capmgr_aep_create_ext(comp->id, aep, idx, owntc, key, ipiwin, ipimax, (struct cos_dcb_info **)dcbuaddr, extrcv); if (!aep->thd) goto done; - t = sl_thd_alloc_init(aep, 0, prps); + t = sl_thd_alloc_init(aep, 0, prps, NULL); sl_mod_thd_create(sl_mod_thd_policy_get(t)); } @@ -214,16 +217,17 @@ sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, c { struct sl_thd *t = NULL; struct cos_aep_info *aep = NULL; + struct cos_dcb_info *dcb = NULL; int owntc = 0; aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; if (prps & SL_THD_PROPERTY_OWN_TCAP) owntc = 1; - capmgr_aep_create(aep, fn, data, owntc, key, ipiwin, ipimax); + capmgr_aep_create(aep, fn, data, owntc, key, ipiwin, ipimax, &dcb); if (aep->thd == 0) goto done; - t = sl_thd_alloc_init(aep, 0, prps); + t = sl_thd_alloc_init(aep, 0, prps, dcb); sl_mod_thd_create(sl_mod_thd_policy_get(t)); done: @@ -270,7 +274,15 @@ sl_thd_comp_init(struct cos_defcompinfo *comp, int is_sched) } struct sl_thd * -sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) +sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, dcbcap_t dcap) +{ + PRINTC("UNIMPLEMENTED: Using CAPMGR API which should manage the DCB capabilities\n"); + + return NULL; +} + +struct sl_thd * +sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbuaddr) { struct sl_thd *t = NULL; @@ -278,18 +290,27 @@ sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int sl_cs_enter(); if (!is_sched) { - t = sl_thd_alloc_ext_no_cs(comp, 0); + t = sl_thd_alloc_ext_no_cs(comp, 0, dcbuaddr); } else { t = sl_thd_aep_alloc_ext_no_cs(comp, sched_thd, 0, (is_sched ? SL_THD_PROPERTY_SEND : 0) - | (own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0), key, ipiwin, ipimax, NULL); + | (own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0), key, ipiwin, ipimax, dcbuaddr, NULL); } sl_cs_exit(); return t; } + +struct sl_thd * +sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, dcbcap_t dcap, dcboff_t doff, arcvcap_t *extrcv) +{ + PRINTC("UNIMPLEMENTED: Using CAPMGR API which should manage the DCB capabilities\n"); + + return NULL; +} + struct sl_thd * -sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) +sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbuaddr, arcvcap_t *extrcv) { struct sl_thd *t = NULL; @@ -299,9 +320,9 @@ sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thd sl_cs_enter(); if (!is_aep) own_tcap = 0; if (is_aep) { - t = sl_thd_aep_alloc_ext_no_cs(comp, sched_thd, idx, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, key, ipiwin, ipimax, extrcv); + t = sl_thd_aep_alloc_ext_no_cs(comp, sched_thd, idx, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, key, ipiwin, ipimax, dcbuaddr, extrcv); } else { - t = sl_thd_alloc_ext_no_cs(comp, idx); + t = sl_thd_alloc_ext_no_cs(comp, idx, dcbuaddr); } sl_cs_exit(); @@ -318,7 +339,7 @@ sl_thd_init_ext_no_cs(struct cos_aep_info *aepthd, struct sl_thd *sched) if (!aep) goto done; *aep = *aepthd; - t = sl_thd_alloc_init(aep, 0, 0); + t = sl_thd_alloc_init(aep, 0, 0, NULL); if (!t) goto done; /* use sched info for parent -> child notifications */ @@ -371,8 +392,7 @@ sl_thd_retrieve(thdid_t tid) /* sl_cs_enter(); */ } - assert(0); - //aep.thd = capmgr_thd_retrieve(client, tid, &itid); + aep.thd = capmgr_thd_retrieve(client, tid, &itid); assert(aep.thd && itid); /* this thread must be a child thread and capmgr must know it! */ /* "client"'s initthd must be initialized! */ it = sl_thd_try_lkup(itid); diff --git a/src/components/lib/sl_kernel/Makefile b/src/components/lib/sl_kernel/Makefile index 2b82bbb314..cc942809a5 100644 --- a/src/components/lib/sl_kernel/Makefile +++ b/src/components/lib/sl_kernel/Makefile @@ -15,13 +15,13 @@ OBJECT_OUTPUT = # The path within this directory that holds the .h files for # dependents to compile with (./ by default). Will be fed into the -I # compiler arguments. -INCLUDE_PATHS = . +INCLUDE_PATHS = # The interfaces this component is dependent on for compilation (this # is a list of directory names in interface/) INTERFACE_DEPENDENCIES = # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = component kernel sl ps util +LIBRARY_DEPENDENCIES = component kernel sl ps util dcb # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/lib/sl_kernel/sl_raw.c b/src/components/lib/sl_kernel/sl_raw.c index 26d800f0ef..24b50dac4a 100644 --- a/src/components/lib/sl_kernel/sl_raw.c +++ b/src/components/lib/sl_kernel/sl_raw.c @@ -11,6 +11,7 @@ #include #include #include +#include extern void sl_thd_event_info_reset(struct sl_thd *t); extern void sl_thd_free_no_cs(struct sl_thd *t); @@ -30,8 +31,8 @@ sl_shm_map(cbuf_t id) void sl_xcpu_asnd_alloc(void) { - struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); - struct cos_compinfo *ci = cos_compinfo_get(dci); + struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); + struct cos_compinfo *ci = cos_compinfo_get(dci); int i; for (i = 0; i < NUM_CPU; i++) { @@ -47,7 +48,7 @@ sl_xcpu_asnd_alloc(void) } struct sl_thd * -sl_thd_alloc_init(struct cos_aep_info *aep, asndcap_t sndcap, sl_thd_property_t prps) +sl_thd_alloc_init(struct cos_aep_info *aep, asndcap_t sndcap, sl_thd_property_t prps, struct cos_dcb_info *dcb) { struct sl_thd_policy *tp = NULL; struct sl_thd *t = NULL; @@ -57,6 +58,7 @@ sl_thd_alloc_init(struct cos_aep_info *aep, asndcap_t sndcap, sl_thd_property_t if (!tp) goto done; t = sl_mod_thd_get(tp); + t->dcb = dcb; t->properties = prps; t->aepinfo = aep; t->sndcap = sndcap; @@ -84,15 +86,21 @@ sl_thd_alloc_no_cs(cos_thd_fn_t fn, void *data) struct cos_compinfo *ci = cos_compinfo_get(dci); struct sl_thd *t = NULL; struct cos_aep_info *aep = NULL; + struct cos_dcb_info *dcb = NULL; + dcbcap_t dcap; + dcboff_t doff; aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; + dcap = cos_dcb_info_alloc_curr(&doff, (vaddr_t *)&dcb); + assert(dcap); - aep->thd = cos_thd_alloc(ci, ci->comp_cap, fn, data); + aep->thd = cos_thd_alloc(ci, ci->comp_cap, fn, data, dcap, doff); if (!aep->thd) goto done; aep->tid = cos_introspect(ci, aep->thd, THD_GET_TID); if (!aep->tid) goto done; - t = sl_thd_alloc_init(aep, 0, 0); + + t = sl_thd_alloc_init(aep, 0, 0, dcb); sl_mod_thd_create(sl_mod_thd_policy_get(t)); done: @@ -118,7 +126,7 @@ sl_thd_comp_init_no_cs(struct cos_defcompinfo *comp, sl_thd_property_t prps, asn assert(snd); } - t = sl_thd_alloc_init(aep, snd, prps); + t = sl_thd_alloc_init(aep, snd, prps, NULL); sl_mod_thd_create(sl_mod_thd_policy_get(t)); done: @@ -126,7 +134,7 @@ sl_thd_comp_init_no_cs(struct cos_defcompinfo *comp, sl_thd_property_t prps, asn } static struct sl_thd * -sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx) +sl_thd_alloc_ext_dcb_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx, dcbcap_t dcbcap, dcboff_t dcboff) { struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); struct cos_compinfo *ci = cos_compinfo_get(dci); @@ -139,16 +147,16 @@ sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx) aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; - aep->thd = cos_thd_alloc_ext(ci, compci->comp_cap, idx); + aep->thd = cos_thd_alloc_ext(ci, compci->comp_cap, idx, dcbcap, dcboff); if (!aep->thd) goto done; aep->tid = cos_introspect(ci, aep->thd, THD_GET_TID); if (!aep->tid) goto done; - t = sl_thd_alloc_init(aep, 0, 0); + t = sl_thd_alloc_init(aep, 0, 0, NULL); sl_mod_thd_create(sl_mod_thd_policy_get(t)); } else { assert(idx == 0); - ret = cos_initaep_alloc(comp, NULL, 0); + ret = cos_initaep_alloc(comp, NULL, 0, dcbcap); if (ret) goto done; t = sl_thd_comp_init_no_cs(comp, 0, 0); @@ -159,23 +167,28 @@ sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx) } static struct sl_thd * -sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) +sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, cos_channelkey_t key) { struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); struct sl_thd *t = NULL; struct cos_aep_info *aep = NULL; + struct cos_dcb_info *dcb = NULL; int ret; + dcbcap_t dcap; + dcboff_t doff; aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; + dcap = cos_dcb_info_alloc_curr(&doff, (vaddr_t *)&dcb); + assert(dcap); /* NOTE: Cannot use stack-allocated cos_aep_info struct here */ - if (prps & SL_THD_PROPERTY_OWN_TCAP) ret = cos_aep_alloc(aep, fn, data); + if (prps & SL_THD_PROPERTY_OWN_TCAP) ret = cos_aep_alloc(aep, fn, data, dcap, doff); else ret = cos_aep_tcap_alloc(aep, sl_thd_aepinfo(sl__globals_cpu()->sched_thd)->tc, - fn, data); + fn, data, dcap, doff); if (ret) goto done; - t = sl_thd_alloc_init(aep, 0, prps); + t = sl_thd_alloc_init(aep, 0, prps, dcb); sl_mod_thd_create(sl_mod_thd_policy_get(t)); done: @@ -183,7 +196,7 @@ sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, c } static struct sl_thd * -sl_thd_aep_alloc_ext_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, thdclosure_index_t idx, sl_thd_property_t prps, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) +sl_thd_aep_alloc_ext_dcb_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, thdclosure_index_t idx, sl_thd_property_t prps, cos_channelkey_t key, dcbcap_t dcap, dcboff_t doff, arcvcap_t *extrcv) { struct cos_aep_info *aep = NULL; struct sl_thd *t = NULL; @@ -191,11 +204,11 @@ sl_thd_aep_alloc_ext_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, t int ret = 0; if (prps & SL_THD_PROPERTY_SEND) { - assert(sched); + assert(sched && !doff); if (prps & SL_THD_PROPERTY_OWN_TCAP) { - ret = cos_initaep_alloc(comp, sl_thd_aepinfo(sched), prps & SL_THD_PROPERTY_SEND); + ret = cos_initaep_alloc(comp, sl_thd_aepinfo(sched), prps & SL_THD_PROPERTY_SEND, dcap); } else { - ret = cos_initaep_tcap_alloc(comp, sl_thd_tcap(sched), sl_thd_aepinfo(sched)); + ret = cos_initaep_tcap_alloc(comp, sl_thd_tcap(sched), sl_thd_aepinfo(sched), dcap); } if (ret) goto done; @@ -207,13 +220,13 @@ sl_thd_aep_alloc_ext_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, t if (!aep) goto done; if (prps & SL_THD_PROPERTY_OWN_TCAP) { - ret = cos_aep_alloc_ext(aep, comp, sl_thd_aepinfo(sched), idx); + ret = cos_aep_alloc_ext(aep, comp, sl_thd_aepinfo(sched), idx, dcap, doff); } else { - ret = cos_aep_tcap_alloc_ext(aep, comp, sl_thd_aepinfo(sched), sl_thd_tcap(sched), idx); + ret = cos_aep_tcap_alloc_ext(aep, comp, sl_thd_aepinfo(sched), sl_thd_tcap(sched), idx, dcap, doff); } if (ret) goto done; - t = sl_thd_alloc_init(aep, 0, prps); + t = sl_thd_alloc_init(aep, 0, prps, NULL); sl_mod_thd_create(sl_mod_thd_policy_get(t)); if (extrcv) *extrcv = sl_thd_rcvcap(t); @@ -236,12 +249,12 @@ sl_thd_alloc(cos_thd_fn_t fn, void *data) } struct sl_thd * -sl_thd_aep_alloc(cos_aepthd_fn_t fn, void *data, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) +sl_thd_aep_alloc(cos_aepthd_fn_t fn, void *data, int own_tcap, cos_channelkey_t key) { struct sl_thd *t = NULL; sl_cs_enter(); - t = sl_thd_aep_alloc_no_cs(fn, data, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, 0, ipiwin, ipimax); + t = sl_thd_aep_alloc_no_cs(fn, data, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, 0); sl_cs_exit(); return t; @@ -263,23 +276,39 @@ sl_thd_comp_init(struct cos_defcompinfo *comp, int is_sched) } struct sl_thd * -sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) +sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, vaddr_t *dcbaddr) +{ + PRINTC("UNIMPLEMENTED: Using RAW API which cannot manage DCB resource for child components\n"); + + return NULL; +} + +struct sl_thd * +sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, dcbcap_t dcap) { struct sl_thd *t = NULL; if (!comp) return NULL; sl_cs_enter(); - if (!is_sched) t = sl_thd_alloc_ext_no_cs(comp, 0); - else t = sl_thd_aep_alloc_ext_no_cs(comp, sched_thd, 0, (is_sched ? SL_THD_PROPERTY_SEND : 0) - | (own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0), key, ipiwin, ipimax, NULL); + if (!is_sched) t = sl_thd_alloc_ext_dcb_no_cs(comp, 0, dcap, 0); + else t = sl_thd_aep_alloc_ext_dcb_no_cs(comp, sched_thd, 0, (is_sched ? SL_THD_PROPERTY_SEND : 0) + | (own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0), key, dcap, 0, NULL); sl_cs_exit(); return t; } struct sl_thd * -sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) +sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, vaddr_t *dcbaddr, arcvcap_t *extrcv) +{ + PRINTC("UNIMPLEMENTED: Using RAW API which cannot manage DCB resource for child components\n"); + + return NULL; +} + +struct sl_thd * +sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, dcbcap_t dcap, dcboff_t doff, arcvcap_t *extrcv) { struct sl_thd *t = NULL; @@ -287,9 +316,9 @@ sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thd sl_cs_enter(); if (!is_aep) own_tcap = 0; if (is_aep) { - t = sl_thd_aep_alloc_ext_no_cs(comp, sched_thd, idx, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, key, ipiwin, ipimax, extrcv); + t = sl_thd_aep_alloc_ext_dcb_no_cs(comp, sched_thd, idx, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, key, dcap, doff, extrcv); } else { - t = sl_thd_alloc_ext_no_cs(comp, idx); + t = sl_thd_alloc_ext_dcb_no_cs(comp, idx, dcap, doff); } sl_cs_exit(); @@ -310,7 +339,7 @@ sl_thd_init_ext(struct cos_aep_info *aepthd, struct sl_thd *sched) *aep = *aepthd; /* TODO: use sched info for parent -> child notifications */ - t = sl_thd_alloc_init(aep, 0, 0); + t = sl_thd_alloc_init(aep, 0, 0, NULL); done: sl_cs_exit(); diff --git a/src/composer/src/resources.rs b/src/composer/src/resources.rs index cabf7be0a2..0ca46a286e 100644 --- a/src/composer/src/resources.rs +++ b/src/composer/src/resources.rs @@ -15,7 +15,7 @@ enum CapRes { Comp(ComponentId), } -const BOOT_CAPTBL_FREE: u32 = 52; +const BOOT_CAPTBL_FREE: u32 = 56; // The equivalent of the C __captbl_cap2sz(c) fn cap_sz(cap: &CapRes) -> u32 { diff --git a/src/kernel/capinv.c b/src/kernel/capinv.c index aeea7589c4..eb208aaa29 100644 --- a/src/kernel/capinv.c +++ b/src/kernel/capinv.c @@ -85,6 +85,94 @@ printfn(struct pt_regs *regs) return 0; } +/* TODO: inline fast path and force non-inlined slow-path */ +static inline struct thread * +cap_ulthd_lazyupdate(struct pt_regs *regs, struct cos_cpu_local_info *cos_info, int interrupt, struct comp_info **ci_ptr) +{ + struct thread *thd = thd_current(cos_info); + struct cap_thd *ch_ult = NULL; + struct thread *ulthd = NULL; + capid_t ultc = 0; + int invstk_top = 0; + struct cos_scb_info *scb_core = NULL; /* per-core scb_info */ + + *ci_ptr = thd_invstk_current_compinfo(thd, cos_info, &invstk_top); + + assert(*ci_ptr && (*ci_ptr)->captbl); + + if (unlikely(!(*ci_ptr)->scb_data)) goto done; + scb_core = (((*ci_ptr)->scb_data) + get_cpuid()); + ultc = scb_core->curr_thd; + /* reset inconsistency from user-level thd! */ + scb_core->curr_thd = 0; + if (!ultc && !interrupt) goto done; + + if (likely(ultc)) { + ch_ult = (struct cap_thd *)captbl_lkup((*ci_ptr)->captbl, ultc); + if (unlikely(!CAP_TYPECHK_CORE(ch_ult, CAP_THD))) ch_ult = NULL; + else ulthd = ch_ult->t; + } + + if (unlikely(interrupt)) { + struct thread *fixthd = thd; + + assert(scb_core->sched_tok < ~0U); + cos_faa((int *)&(scb_core->sched_tok), 1); + + if (ulthd) fixthd = ulthd; + + if (unlikely(fixthd->dcbinfo && fixthd->dcbinfo->sp)) { + regs->ip = fixthd->dcbinfo->ip + DCB_IP_KERN_OFF; + regs->sp = fixthd->dcbinfo->sp; + regs->dx = 0; /* sched token is in edx! */ + + fixthd->dcbinfo->sp = 0; + } + } + if (unlikely(!ultc || !ulthd || ulthd->dcbinfo == NULL)) goto done; + if (ulthd == thd) goto done; + /* check if kcurr and ucurr threads are both in the same page-table(component) */ + if (thd_current_pgtbl(ulthd) != thd_current_pgtbl(thd)) goto done; + thd_current_update(ulthd, thd, cos_info); + thd = ulthd; + +done: + return thd; +} + +void +cos_cap_ipi_handling(void) +{ + int idx, end; + struct IPI_receiving_rings *receiver_rings; + struct xcore_ring * ring; + + receiver_rings = &IPI_cap_dest[get_cpuid()]; + + /* We need to scan the entire buffer once. */ + idx = receiver_rings->start; + end = receiver_rings->start - 1; // end is int type. could be -1. + receiver_rings->start = (receiver_rings->start + 1) % NUM_CPU; + + /* scan the first half */ + for (; idx < NUM_CPU; idx++) { + ring = &receiver_rings->IPI_source[idx]; + if (ring->sender != ring->receiver) { + process_ring(ring); + } + } + + /* and scan the second half */ + for (idx = 0; idx <= end; idx++) { + ring = &receiver_rings->IPI_source[idx]; + if (ring->sender != ring->receiver) { + process_ring(ring); + } + } + + return; +} + void kmem_unalloc(unsigned long *pte) { @@ -248,6 +336,8 @@ cap_cpy(struct captbl *t, capid_t cap_to, capid_t capin_to, capid_t cap_from, ca type = ctfrom->type; sz = __captbl_cap2bytes(type); + /* don't allow cap copy on SCB/DCB */ + if (type == CAP_SCB || type == CAP_DCB) return -EINVAL; ctto = __cap_capactivate_pre(t, cap_to, capin_to, type, &ret); if (!ctto) return -EINVAL; @@ -464,7 +554,7 @@ asnd_process(struct thread *rcv_thd, struct thread *thd, struct tcap *rcv_tcap, { struct thread *next; - thd_rcvcap_pending_inc(rcv_thd); + thd_rcvcap_pending_set(rcv_thd); next = notify_process(rcv_thd, thd, rcv_tcap, tcap, tcap_next, yield); /* @@ -550,11 +640,20 @@ cap_switch(struct pt_regs *regs, struct thread *curr, struct thread *next, struc static int cap_sched_tok_validate(struct thread *rcvt, sched_tok_t usr_tok, struct comp_info *ci, struct cos_cpu_local_info *cos_info) { + assert(ci->scb_data); + struct cos_scb_info *scb_core = ci->scb_data + get_cpuid(); + assert(rcvt && usr_tok < ~0U); - /* race-condition check for user-level thread switches */ - if (thd_rcvcap_get_counter(rcvt) > usr_tok) return -EAGAIN; - thd_rcvcap_set_counter(rcvt, usr_tok); + /* + * Kernel increments the sched_tok on preemption only. + * The rest is all co-operative, so if sched_tok in scb page + * increments after someone fetching a tok, then check for that! + * + * FIXME: make sure we're checking the scb of the scheduling component and not in any other component. + * I don't know if the comp_info here is of the scheduling component! + */ + if (unlikely(scb_core->sched_tok != usr_tok)) return -EAGAIN; return 0; } @@ -583,6 +682,10 @@ cap_thd_op(struct cap_thd *thd_cap, struct thread *thd, struct pt_regs *regs, st int ret; if (thd_cap->cpuid != get_cpuid() || thd_cap->cpuid != next->cpuid) return -EINVAL; + if (unlikely(thd->dcbinfo && thd->dcbinfo->sp)) { + assert((unsigned long)regs->cx == thd->dcbinfo->ip + DCB_IP_KERN_OFF); + assert((unsigned long)regs->bp == thd->dcbinfo->sp); + } if (arcv) { struct cap_arcv *arcv_cap; @@ -619,7 +722,6 @@ cap_thd_op(struct cap_thd *thd_cap, struct thread *thd, struct pt_regs *regs, st if (!tcap_rcvcap_thd(tcap)) return -EINVAL; if (unlikely(!tcap_is_active(tcap))) return -EPERM; } - ret = cap_switch(regs, thd, next, tcap, timeout, ci, cos_info); if (tc && tcap_current(cos_info) == tcap) tcap_setprio(tcap, prio); @@ -651,13 +753,11 @@ cap_ipi_process(struct pt_regs *regs) struct tcap *tcap_curr, *tcap_next; struct comp_info *ci; int i, scan_base; - unsigned long ip, sp; - thd_curr = thd_next = thd_current(cos_info); + thd_next = thd_curr = cap_ulthd_lazyupdate(regs, cos_info, 1, &ci); + assert(ci && ci->captbl); receiver_rings = &IPI_cap_dest[get_cpuid()]; tcap_curr = tcap_next = tcap_current(cos_info); - ci = thd_invstk_current(thd_curr, &ip, &sp, cos_info); - assert(ci && ci->captbl); scan_base = receiver_rings->start; receiver_rings->start = (receiver_rings->start + 1) % NUM_CPU; @@ -765,12 +865,11 @@ int cap_hw_asnd(struct cap_asnd *asnd, struct pt_regs *regs) { int curr_cpu = get_cpuid(); - struct cap_arcv * arcv; + struct cap_arcv *arcv; struct cos_cpu_local_info *cos_info; - struct thread * rcv_thd, *next, *thd; - struct tcap * rcv_tcap, *tcap, *tcap_next; - struct comp_info * ci; - unsigned long ip, sp; + struct thread *rcv_thd, *next, *thd; + struct tcap *rcv_tcap, *tcap, *tcap_next; + struct comp_info *ci; if (!CAP_TYPECHK(asnd, CAP_ASND)) return 1; assert(asnd->arcv_capid); @@ -786,12 +885,10 @@ cap_hw_asnd(struct cap_asnd *asnd, struct pt_regs *regs) cos_info = cos_cpu_local_info(); assert(cos_info); - thd = thd_current(cos_info); - tcap = tcap_current(cos_info); - assert(thd); - ci = thd_invstk_current(thd, &ip, &sp, cos_info); - assert(ci && ci->captbl); + thd = cap_ulthd_lazyupdate(regs, cos_info, 1, &ci); + assert(thd && ci && ci->captbl); assert(!(thd->state & THD_STATE_PREEMPTED)); + tcap = tcap_current(cos_info); rcv_thd = arcv->thd; rcv_tcap = rcv_thd->rcvcap.rcvcap_tcap; assert(rcv_tcap && tcap); @@ -834,16 +931,13 @@ int timer_process(struct pt_regs *regs) { struct cos_cpu_local_info *cos_info; - struct thread * thd_curr; - struct comp_info * comp; - unsigned long ip, sp; - cycles_t now; + struct thread *thd_curr; + struct comp_info *comp = NULL; cos_info = cos_cpu_local_info(); assert(cos_info); - thd_curr = thd_current(cos_info); + thd_curr = cap_ulthd_lazyupdate(regs, cos_info, 1, &comp); assert(thd_curr && thd_curr->cpuid == get_cpuid()); - comp = thd_invstk_current(thd_curr, &ip, &sp, cos_info); assert(comp); return expended_process(regs, thd_curr, comp, cos_info, 1); @@ -859,14 +953,14 @@ cap_arcv_op(struct cap_arcv *arcv, struct thread *thd, struct pt_regs *regs, str rcv_flags_t rflags = __userregs_get1(regs); tcap_time_t swtimeout = TCAP_TIME_NIL; tcap_time_t timeout = __userregs_get2(regs); - int all_pending = (!!(rflags & RCV_ALL_PENDING)); + //int all_pending = (!!(rflags & RCV_ALL_PENDING)); if (unlikely(arcv->thd != thd || arcv->cpuid != get_cpuid())) return -EINVAL; /* deliver pending notifications? */ if (thd_rcvcap_pending(thd)) { __userregs_set(regs, 0, __userregs_getsp(regs), __userregs_getip(regs)); - thd_rcvcap_all_pending_set(thd, all_pending); + //thd_rcvcap_all_pending_set(thd, all_pending); thd_rcvcap_pending_deliver(thd, regs); return 0; @@ -910,7 +1004,7 @@ cap_arcv_op(struct cap_arcv *arcv, struct thread *thd, struct pt_regs *regs, str if (likely(thd != next)) { assert(!(thd->state & THD_STATE_PREEMPTED)); thd->state |= THD_STATE_RCVING; - thd_rcvcap_all_pending_set(thd, all_pending); + //thd_rcvcap_all_pending_set(thd, all_pending); thd->timeout = timeout; } @@ -931,6 +1025,8 @@ cap_introspect(struct captbl *ct, capid_t capid, u32_t op, unsigned long *retval return tcap_introspect(((struct cap_tcap *)ch)->tcap, op, retval); case CAP_ARCV: return arcv_introspect(((struct cap_arcv *)ch), op, retval); + case CAP_COMP: + return comp_introspect(((struct cap_comp *)ch), op, retval); default: return -EINVAL; } @@ -947,7 +1043,6 @@ composite_syscall_handler(struct pt_regs *regs) struct comp_info * ci; struct thread * thd; capid_t cap; - unsigned long ip, sp; /* * We lookup this struct (which is on stack) only once, and @@ -957,8 +1052,15 @@ composite_syscall_handler(struct pt_regs *regs) int ret = -ENOENT; int thd_switch = 0; + /* Definitely do it for all the fast-path calls. */ + thd = cap_ulthd_lazyupdate(regs, cos_info, 0, &ci); + assert(thd); cap = __userregs_getcap(regs); - thd = thd_current(cos_info); + + /* printk("thd %d calling cap %d (ip %x, sp %x), operation %d: %x, %x, %x, %x\n", thd->tid, cap, + * __userregs_getip(regs), __userregs_getsp(regs), __userregs_getop(regs), + * __userregs_get1(regs), __userregs_get2(regs), __userregs_get3(regs), __userregs_get4(regs)); + */ /* fast path: invocation return (avoiding captbl accesses) */ if (cap == COS_DEFAULT_RET_CAP) { @@ -973,14 +1075,12 @@ composite_syscall_handler(struct pt_regs *regs) return 0; } - ci = thd_invstk_current(thd, &ip, &sp, cos_info); - assert(ci && ci->captbl); - /* * We don't check the liveness of the current component * because it's guaranteed by component quiescence period, * which is at timer tick granularity. */ + assert(ci && ci->captbl); ch = captbl_lkup(ci->captbl, cap); if (unlikely(!ch)) { printk("cos: cap %d not found!\n", (int)cap); @@ -1147,22 +1247,38 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * break; } case CAPTBL_OP_THDACTIVATE: { - thdclosure_index_t init_data = __userregs_get1(regs) >> 16; - capid_t thd_cap = __userregs_get1(regs) & 0xFFFF; - capid_t pgtbl_cap = __userregs_get2(regs); - capid_t pgtbl_addr = __userregs_get3(regs); - capid_t compcap = __userregs_get4(regs); - - struct thread *thd; - unsigned long *pte = NULL; - - ret = cap_kmem_activate(ct, pgtbl_cap, pgtbl_addr, (unsigned long *)&thd, &pte); + u32_t reg3 = __userregs_get3(regs); + u32_t reg4 = __userregs_get4(regs); + capid_t pgtbl_addr = __userregs_get2(regs); + thdclosure_index_t init_data = (reg4 << 16) >> 16; + capid_t thd_cap = (capin >> 16); + capid_t pgtbl_cap = (capin << 16) >> 16; + capid_t compcap = (reg3 >> 16); + capid_t dcb_cap = (reg3 << 16) >> 16; + unsigned short dcboff = reg4 >> 16; + unsigned long *tpte = NULL, flags; + struct thread *thd; + struct cap_header *ctfrom; + + ret = cap_kmem_activate(ct, pgtbl_cap, pgtbl_addr, (unsigned long *)&thd, &tpte); if (unlikely(ret)) cos_throw(err, ret); - assert(thd && pte); + assert(thd && tpte); /* ret is returned by the overall function */ - ret = thd_activate(ct, cap, thd_cap, thd, compcap, init_data); - if (ret) kmem_unalloc(pte); + ret = thd_activate(ct, cap, thd_cap, thd, compcap, init_data, dcb_cap, dcboff); + if (ret) kmem_unalloc(tpte); + + break; + } + case CAPTBL_OP_THDMIGRATE: { + u32_t reg2 = __userregs_get2(regs); + u32_t reg3 = __userregs_get3(regs); + + if (reg3) { + ret = thd_migrate_cap(ct, capin); + } else { + ret = thd_migrate(ct, capin, reg2); + } break; } @@ -1184,7 +1300,7 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * case CAPTBL_OP_THDDEACTIVATE: { livenessid_t lid = __userregs_get2(regs); - ret = thd_deactivate(ct, op_cap, capin, lid, 0, 0, 0); + ret = thd_deactivate(ct, op_cap, capin, lid, 0, 0, 0, 0); break; } case CAPTBL_OP_THDTLSSET: { @@ -1200,7 +1316,7 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * capid_t pgtbl_cap = __userregs_get3(regs); capid_t cosframe_addr = __userregs_get4(regs); - ret = thd_deactivate(ct, op_cap, capin, lid, pgtbl_cap, cosframe_addr, 1); + ret = thd_deactivate(ct, op_cap, capin, lid, pgtbl_cap, cosframe_addr, 0, 1); break; } case CAPTBL_OP_CAPKMEM_FREEZE: { @@ -1212,9 +1328,9 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * case CAPTBL_OP_COMPACTIVATE: { capid_t captbl_cap = __userregs_get2(regs) >> 16; capid_t pgtbl_cap = __userregs_get2(regs) & 0xFFFF; - livenessid_t lid = (capin >> 16); + livenessid_t lid = capin >> 16; capid_t comp_cap = (capin << 16) >> 16; - vaddr_t scb_uaddr = __userregs_get3(regs) | ~((1 << 12) - 1); + vaddr_t scb_uaddr = __userregs_get3(regs) & (~0 << 12); vaddr_t entry_addr = __userregs_get4(regs); capid_t scb_cap = __userregs_get3(regs) & ((1 << 12) - 1); @@ -1351,36 +1467,41 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * break; } -// case CAPTBL_OP_DCB_ACTIVATE: { -// u32_t r1 = __userregs_get1(regs); -// u32_t r2 = __userregs_get2(regs); -// u32_t r3 = __userregs_get3(regs); -// u32_t r4 = __userregs_get4(regs); -// capid_t dcbcap = r1 >> 16; -// capid_t ptcap = (r1 << 16) >> 16; -// livenessid_t lid = r2 >> 16; -// capid_t ptcapin = (r2 << 16) >> 16; -// vaddr_t kaddr = r3; -// vaddr_t uaddrin = r4; -// -// ret = dcb_activate(ct, cap, dcbcap, ptcap, kaddr, lid, ptcapin, uaddr); -// -// break; -// } -// case CAPTBL_OP_DCB_DEACTIVATE: { -// u32_t r2 = __userregs_get2(regs); -// u32_t r3 = __userregs_get3(regs); -// u32_t r4 = __userregs_get4(regs); -// livenessid_t lid = r2 >> 16; -// capid_t ptcap = (r2 << 16) >> 16; -// vaddr_t cf_addr = r3 & (~0 << 12); -// vaddr_t uaddrin = r4 & (~0 << 12); -// capid_t ptcapin = (r4 << 20) >> 12 | ((r3 << 20) >> 20); -// -// ret = dcb_deactivate(ct, capin, lid, ptcap, cf_addr, ptcapin, uaddrin); -// -// break; -// } + case CAPTBL_OP_DCB_ACTIVATE: { + u32_t r1 = __userregs_get1(regs); + u32_t r2 = __userregs_get2(regs); + u32_t r3 = __userregs_get3(regs); + u32_t r4 = __userregs_get4(regs); + capid_t dcbcap = r1 >> 16; + capid_t ptcap = r2 >> 16; + livenessid_t lid = (r1 << 16) >> 16; + capid_t ptcapin = (r2 << 16) >> 16; + vaddr_t kaddr = r3; + vaddr_t uaddrin = r4; + struct cos_dcb_info *dcb; + unsigned long *pte; + + ret = cap_kmem_activate(ct, ptcap, kaddr, (unsigned long *)&dcb, &pte); + if (ret) cos_throw(err, ret); + + ret = dcb_activate(ct, cap, dcbcap, (vaddr_t)dcb, lid, ptcapin, uaddrin); + + break; + } + case CAPTBL_OP_DCB_DEACTIVATE: { + u32_t r2 = __userregs_get2(regs); + u32_t r3 = __userregs_get3(regs); + u32_t r4 = __userregs_get4(regs); + livenessid_t lid = r2 >> 16; + capid_t ptcap = (r2 << 16) >> 16; + vaddr_t cf_addr = r3 & (~0 << 12); + vaddr_t uaddrin = r4 & (~0 << 12); + capid_t ptcapin = (r4 << 20) >> 12 | ((r3 << 20) >> 20); + + ret = dcb_deactivate(op_cap, capin, lid, ptcap, cf_addr, ptcapin, uaddrin); + + break; + } default: goto err; } diff --git a/src/kernel/include/component.h b/src/kernel/include/component.h index 2293a586bb..a049363e7e 100644 --- a/src/kernel/include/component.h +++ b/src/kernel/include/component.h @@ -12,6 +12,7 @@ #include "captbl.h" #include "pgtbl.h" #include "cap_ops.h" +#include "shared/cos_sched.h" /* 24B */ struct comp_info { @@ -124,4 +125,17 @@ comp_init(void) assert(sizeof(struct cap_comp) <= __captbl_cap2bytes(CAP_COMP)); } +static inline int +comp_introspect(struct cap_comp *t, unsigned long op, unsigned long *retval) +{ + switch (op) { + case COMP_GET_SCB_CURTHD: + *retval = t->info.scb_data->curr_thd; + break; + default: + return -EINVAL; + } + return 0; +} + #endif /* COMPONENT_H */ diff --git a/src/kernel/include/dcb.h b/src/kernel/include/dcb.h index 3b64c4477e..77bc231db3 100644 --- a/src/kernel/include/dcb.h +++ b/src/kernel/include/dcb.h @@ -11,6 +11,7 @@ #include "pgtbl.h" #include "retype_tbl.h" #include "component.h" +#include "thd.h" #define DCB_ENTRIES_MAX_PER_PAGE (PAGE_SIZE/sizeof(struct cos_dcb_info)) @@ -23,25 +24,25 @@ struct cap_dcb { } __attribute__((packed)); static int -dcb_activate(struct captbl *t, capid_t ctcap, capid_t dcbcap, capid_t ptcap, vaddr_t kaddr, livenessid_t lid, capid_t ptcapin, vaddr_t uaddr) +dcb_activate(struct captbl *t, capid_t ctcap, capid_t dcbcap, vaddr_t kaddr, livenessid_t lid, capid_t ptcapin, vaddr_t uaddr) { struct cap_dcb *dc; - struct cap_pgtbl *ptc; - unsigned long *tpte; - struct cos_dcb_info *di; + struct cap_pgtbl *ptcin; int ret; + paddr_t pf = chal_va2pa((void *)kaddr); - ret = cap_kmem_activate(t, ptcap, kaddr, (unsigned long *)&di, &tpte); - if (unlikely(ret)) return -EINVAL; - assert(di && tpte); + ptcin = (struct cap_pgtbl *)captbl_lkup(t, ptcapin); + if (!ptcin || ptcin->h.type != CAP_PGTBL) return -EINVAL; - /* TODO: memactivate kaddr -> uaddr in ptcapin */ + /* FIXME: hard coded page order */ + if (pgtbl_mapping_add(ptcin->pgtbl, uaddr, pf, PGTBL_USER_DEF, 12)) return -EINVAL; dc = (struct cap_dcb *)__cap_capactivate_pre(t, ctcap, dcbcap, CAP_DCB, &ret); if (!dc) return -EINVAL; ltbl_get(lid, &dc->liveness); - dc->kern_addr = (vaddr_t)di; + dc->kern_addr = kaddr; + memset((void *)kaddr, 0, PAGE_SIZE); dc->refcnt = 0; dc->cpuid = get_cpuid(); @@ -54,16 +55,24 @@ static int dcb_deactivate(struct cap_captbl *ct, capid_t dcbcap, livenessid_t lid, capid_t ptcap, capid_t cosframe_addr, capid_t ptcapin, vaddr_t uaddrin) { struct cap_dcb *dc; + struct cap_pgtbl *ptcin; + unsigned long *pte, addr, flags, old_v; int ret; - dc = (struct cap_comp *)captbl_lkup(ct->captbl, dcbcap); - if (dc->h.type != CAP_DCB) return -EINVAL; + dc = (struct cap_dcb *)captbl_lkup(ct->captbl, dcbcap); + if (!dc || dc->h.type != CAP_DCB) return -EINVAL; + + if (!ptcapin || !uaddrin) return -EINVAL; + ptcin = (struct cap_pgtbl *)captbl_lkup(ct->captbl, ptcapin); + if (!ptcin || ptcin->h.type != CAP_PGTBL) return -EINVAL; + pte = pgtbl_lkup(ptcin->pgtbl, uaddrin, (u32_t *)&flags); + if (!pte) return -EINVAL; + if ((vaddr_t)pte != dc->kern_addr) return -EINVAL; if (dc->refcnt) return -EPERM; - /* TODO: verify uaddrin in ptcapin maps to kaddr for this dcb and then unmap from ptcapin at uaddrin */ ltbl_expire(&dc->liveness); - ret = kmem_deact_pre(dc, ct, ptcap, cosframe_addr, &pte, &old_v); + ret = kmem_deact_pre((struct cap_header *)dc, ct->captbl, ptcap, cosframe_addr, &pte, &old_v); if (ret) return ret; ret = kmem_deact_post(pte, old_v); if (ret) return ret; @@ -89,9 +98,9 @@ dcb_thd_deref(struct cap_dcb *dc, struct thread *thd) { if (!dc->refcnt) return -EINVAL; if (dc->cpuid != thd->cpuid) return -EINVAL; - if (!ltbl_isalive(&dc->liveness)) return -EPERM; - assert((vaddr_t)thd->dcbinfo >= dc->kern_addr && (vaddr_t)thd->dcbinfo < (dc->kern_addr + PAGE_SIZE)); + if ((vaddr_t)thd->dcbinfo < dc->kern_addr || (vaddr_t)thd->dcbinfo > (dc->kern_addr + PAGE_SIZE)) return -EINVAL; + if (!ltbl_isalive(&dc->liveness)) return -EPERM; dc->refcnt--; diff --git a/src/kernel/include/scb.h b/src/kernel/include/scb.h index b3618bed12..599f4faacb 100644 --- a/src/kernel/include/scb.h +++ b/src/kernel/include/scb.h @@ -48,7 +48,7 @@ scb_deactivate(struct cap_captbl *ct, capid_t scbcap, capid_t ptcap, capid_t cos int ret; sc = (struct cap_scb *)captbl_lkup(ct->captbl, scbcap); - if (sc->h.type != CAP_SCB) return -EINVAL; + if (!sc || sc->h.type != CAP_SCB) return -EINVAL; /* FIXME: component using this scbcap is still active! how to handle this? */ if (sc->compc) return -EPERM; @@ -68,7 +68,8 @@ scb_comp_update(struct captbl *ct, struct cap_scb *sc, struct cap_comp *compc, s paddr_t pf = chal_va2pa((void *)(sc->kern_addr)); if (unlikely(!ltbl_isalive(&sc->liveness))) return -EPERM; - if (pgtbl_mapping_add(ptcin->pgtbl, uaddrin, pf, PGTBL_USER_DEF)) return -EINVAL; + /* FIXME: hard coded pgtbl order */ + if (pgtbl_mapping_add(ptcin->pgtbl, uaddrin, pf, PGTBL_USER_DEF, 12)) return -EINVAL; sc->compc = compc; compc->info.scb_data = (struct cos_scb_info *)(sc->kern_addr); diff --git a/src/kernel/include/shared/cos_sched.h b/src/kernel/include/shared/cos_sched.h new file mode 100644 index 0000000000..eef5664464 --- /dev/null +++ b/src/kernel/include/shared/cos_sched.h @@ -0,0 +1,52 @@ +#ifndef COS_SCHED_H +#define COS_SCHED_H + +#include "./cos_types.h" + +struct cos_thd_event { + u16_t blocked; + u32_t next_timeout; + u64_t elapsed_cycs; +} __attribute__((packed)); + +struct cos_sched_event { + thdid_t tid; + struct cos_thd_event evt; +} __attribute__((packed)); + +#define COS_SCHED_EVENT_RING_SIZE 16 + +struct cos_sched_ring { + int head, tail; + struct cos_sched_event event_buf[COS_SCHED_EVENT_RING_SIZE]; +} __attribute__((packed)); + +struct cos_scb_info { + capid_t curr_thd; + cycles_t timer_next; + sched_tok_t sched_tok; + struct cos_sched_ring sched_events; +} CACHE_ALIGNED; + +struct cos_dcb_info { + unsigned long ip; + unsigned long sp; + unsigned long pending; /* binary value. TODO: move it to ip or sp */ +} __attribute__((packed)); + +/* + * This is the "ip" the kernel uses to update the thread when it sees that the + * thread is still in user-level dispatch routine. + * This is the offset of instruction after resetting the "next" thread's "sp" to zero + * in a purely user-level dispatch. + * + * Whenever kernel is switching to a thread which has "sp" non-zero, it would switch + * to the "ip" saved in the dcb_info and reset the "sp" of the thread that the kernel + * is dispatching to! + * This is necessary because, if the kernel is dispatching to a thread that was in the + * user-level dispatch routine before, then the only registers that it can restore are + * "ip" and "sp", everything else is either clobbered or saved/loaded at user-level. + */ +#define DCB_IP_KERN_OFF 8 + +#endif /* COS_SCHED_H */ diff --git a/src/kernel/include/shared/cos_types.h b/src/kernel/include/shared/cos_types.h index 01251d0890..86b2c0bc5f 100644 --- a/src/kernel/include/shared/cos_types.h +++ b/src/kernel/include/shared/cos_types.h @@ -96,6 +96,7 @@ typedef enum { CAPTBL_OP_THDACTIVATE, CAPTBL_OP_THDDEACTIVATE, CAPTBL_OP_THDTLSSET, + CAPTBL_OP_THDMIGRATE, CAPTBL_OP_COMPACTIVATE, CAPTBL_OP_COMPDEACTIVATE, CAPTBL_OP_SINVACTIVATE, @@ -142,7 +143,7 @@ typedef enum { CAPTBL_OP_HW_L1FLUSH, CAPTBL_OP_HW_TLBFLUSH, CAPTBL_OP_HW_TLBSTALL, - CAPTBL_OP_HW_TLBSTALL_RECOUNT + CAPTBL_OP_HW_TLBSTALL_RECOUNT, CAPTBL_OP_SCB_ACTIVATE, CAPTBL_OP_SCB_DEACTIVATE, @@ -291,9 +292,8 @@ enum /* * NOTE: kernel doesn't support sharing a cache-line across cores, * so optimize to place INIT THD/TCAP on same cache line and bump by 64B for next CPU - * Update: add per-core INIT DCB cap in to the same cache-line. */ - BOOT_CAPTBL_SELF_INITTCAP_BASE = round_up_to_pow2(BOOT_CAPTBL_SELF_INITTHD_BASE + NUM_CPU * CAP64B_IDSZ, CAPMAX_ENTRY_SZ), + BOOT_CAPTBL_SELF_INITTCAP_BASE = round_up_to_pow2(BOOT_CAPTBL_SELF_INITTHD_BASE + NUM_CPU * CAP16B_IDSZ, CAPMAX_ENTRY_SZ), BOOT_CAPTBL_SELF_INITRCV_BASE = round_up_to_pow2(BOOT_CAPTBL_SELF_INITTCAP_BASE + NUM_CPU * CAP16B_IDSZ, CAPMAX_ENTRY_SZ), BOOT_CAPTBL_LAST_CAP = BOOT_CAPTBL_SELF_INITRCV_BASE + NUM_CPU * CAP64B_IDSZ, @@ -313,6 +313,16 @@ enum #define BOOT_CAPTBL_SELF_INITRCV_CPU_BASE (BOOT_CAPTBL_SELF_INITRCV_BASE_CPU(cos_cpuid())) #define BOOT_CAPTBL_SELF_INITDCB_CPU_BASE (BOOT_CAPTBL_SELF_INITDCB_BASE_CPU(cos_cpuid())) +enum llboot_scb_dcb_caps +{ + LLBOOT_CAPTBL_SCB = round_up_to_pow2(BOOT_CAPTBL_LAST_CAP, CAPMAX_ENTRY_SZ), + LLBOOT_CAPTBL_INITDCB = LLBOOT_CAPTBL_SCB + CAP32B_IDSZ, + LLBOOT_CAPTBL_FREE = round_up_to_pow2(LLBOOT_CAPTBL_INITDCB + (CAP32B_IDSZ * NUM_CPU), CAPMAX_ENTRY_SZ), +}; + +#define LLBOOT_CAPTBL_INITDCB_CPU(cpuid) (LLBOOT_CAPTBL_INITDCB + (CAP32B_IDSZ * cpuid)) +#define LLBOOT_CAPTBL_CPU_INITDCB (LLBOOT_CAPTBL_INITDCB_CPU(cos_cpuid())) + /* * The half of the first page of init captbl is devoted to root node. So, the * first page of captbl can contain 128 caps, and every extra page can hold 256 @@ -327,6 +337,8 @@ enum { /* thread id */ THD_GET_TID, + THD_GET_DCB_IP, + THD_GET_DCB_SP, }; enum @@ -343,6 +355,12 @@ enum ARCV_GET_THDID, }; +enum +{ + /* get current thread info from scb */ + COMP_GET_SCB_CURTHD, +}; + /* Macro used to define per core variables */ #define PERCPU(type, name) \ PERCPU_DECL(type, name); \ @@ -434,6 +452,31 @@ struct cos_stack_freelists { /* #error "Assembly in requires that COMP_INFO_STACK_FREELISTS != 1 || * COMP_INFO_TMEM_STK_RELINQ != 0. Change the defines, or change the assembly" */ /* #endif */ +/*struct cos_scb_info { + capid_t curr_thd; + cycles_t timer_next; + sched_tok_t sched_tok; +} CACHE_ALIGNED; + +struct cos_dcb_info { + unsigned long ip; + unsigned long sp; +} __attribute__((packed));*/ + +/* + * This is the "ip" the kernel uses to update the thread when it sees that the + * thread is still in user-level dispatch routine. + * This is the offset of instruction after resetting the "next" thread's "sp" to zero + * in a purely user-level dispatch. + * + * Whenever kernel is switching to a thread which has "sp" non-zero, it would switch + * to the "ip" saved in the dcb_info and reset the "sp" of the thread that the kernel + * is dispatching to! + * This is necessary because, if the kernel is dispatching to a thread that was in the + * user-level dispatch routine before, then the only registers that it can restore are + * "ip" and "sp", everything else is either clobbered or saved/loaded at user-level. + */ +#define DCB_IP_KERN_OFF 8 struct cos_component_information { struct cos_stack_freelists cos_stacks; diff --git a/src/kernel/include/thd.h b/src/kernel/include/thd.h index 51b80d5bab..1ceab89d43 100644 --- a/src/kernel/include/thd.h +++ b/src/kernel/include/thd.h @@ -34,7 +34,7 @@ struct invstk_entry { */ struct rcvcap_info { /* how many other arcv end-points send notifications to this one? */ - int isbound, pending, refcnt, is_all_pending; + int isbound, pending, refcnt, is_init; sched_tok_t sched_count; struct tcap * rcvcap_tcap; /* This rcvcap's tcap */ struct thread *rcvcap_thd_notif; /* The parent rcvcap thread for notifications */ @@ -69,6 +69,7 @@ struct thread { tcap_time_t timeout; struct thread *interrupted_thread; struct thread *scheduler_thread; + struct cos_dcb_info *dcbinfo; /* rcv end-point data-structures */ struct rcvcap_info rcvcap; @@ -89,6 +90,8 @@ struct cap_thd { cpuid_t cpuid; } __attribute__((packed)); +#include "dcb.h" + static void thd_upcall_setup(struct thread *thd, vaddr_t entry_addr, int option, int arg1, int arg2, int arg3) { @@ -177,13 +180,13 @@ thd_next_thdinfo_update(struct cos_cpu_local_info *cli, struct thread *thd, stru } static void -thd_rcvcap_init(struct thread *t) +thd_rcvcap_init(struct thread *t, int is_init) { struct rcvcap_info *rc = &t->rcvcap; rc->isbound = rc->pending = rc->refcnt = 0; - rc->is_all_pending = 0; rc->sched_count = 0; + rc->is_init = is_init; rc->rcvcap_thd_notif = NULL; } @@ -216,36 +219,11 @@ thd_track_exec(struct thread *t) return !list_empty(&t->event_list); } -static void -thd_rcvcap_all_pending_set(struct thread *t, int val) -{ - t->rcvcap.is_all_pending = val; -} - -static int -thd_rcvcap_all_pending_get(struct thread *t) -{ - return t->rcvcap.is_all_pending; -} - -static int -thd_rcvcap_all_pending(struct thread *t) -{ - int pending = t->rcvcap.pending; - - /* receive all pending */ - t->rcvcap.pending = 0; - thd_rcvcap_all_pending_set(t, 0); - - return ((pending << 1) | !list_isempty(&t->event_head)); -} - static int thd_rcvcap_pending(struct thread *t) { if (t->rcvcap.pending) return t->rcvcap.pending; return !list_isempty(&t->event_head); - ; } static sched_tok_t @@ -261,20 +239,17 @@ thd_rcvcap_set_counter(struct thread *t, sched_tok_t cntr) } static void -thd_rcvcap_pending_inc(struct thread *arcvt) +thd_rcvcap_pending_set(struct thread *arcvt) { - arcvt->rcvcap.pending++; + if (likely(arcvt->dcbinfo)) arcvt->dcbinfo->pending = 1; + else arcvt->rcvcap.pending = 1; } -static int -thd_rcvcap_pending_dec(struct thread *arcvt) +static void +thd_rcvcap_pending_reset(struct thread *arcvt) { - int pending = arcvt->rcvcap.pending; - - if (pending == 0) return 0; - arcvt->rcvcap.pending--; - - return pending; + arcvt->rcvcap.pending = 0; + if (likely(arcvt->dcbinfo)) arcvt->dcbinfo->pending = 0; } static inline int @@ -322,16 +297,22 @@ thd_scheduler_set(struct thread *thd, struct thread *sched) } static int -thd_activate(struct captbl *t, capid_t cap, capid_t capin, struct thread *thd, capid_t compcap, thdclosure_index_t init_data) +thd_activate(struct captbl *t, capid_t cap, capid_t capin, struct thread *thd, capid_t compcap, thdclosure_index_t init_data, capid_t dcbcap, unsigned short dcboff) { struct cos_cpu_local_info *cli = cos_cpu_local_info(); - struct cap_thd *tc; - struct cap_comp *compc; + struct cap_thd *tc = NULL; + struct cap_comp *compc = NULL; + struct cap_dcb *dc = NULL; int ret; memset(thd, 0, sizeof(struct thread)); compc = (struct cap_comp *)captbl_lkup(t, compcap); if (unlikely(!compc || compc->h.type != CAP_COMP)) return -EINVAL; + if (likely(dcbcap)) { + dc = (struct cap_dcb *)captbl_lkup(t, dcbcap); + if (unlikely(!dc || dc->h.type != CAP_DCB)) return -EINVAL; + if (dcboff > PAGE_SIZE / sizeof(struct cos_dcb_info)) return -EINVAL; + } tc = (struct cap_thd *)__cap_capactivate_pre(t, cap, capin, CAP_THD, &ret); if (!tc) return ret; @@ -343,10 +324,17 @@ thd_activate(struct captbl *t, capid_t cap, capid_t capin, struct thread *thd, c thd->refcnt = 1; thd->invstk_top = 0; thd->cpuid = get_cpuid(); + if (likely(dc)) { + ret = dcb_thd_ref(dc, thd); + if (ret) goto err; /* TODO: cleanup captbl slot */ + thd->dcbinfo = (struct cos_dcb_info *)(dc->kern_addr + (dcboff * sizeof(struct cos_dcb_info))); + memset(thd->dcbinfo, 0, sizeof(struct cos_dcb_info)); + } assert(thd->tid <= MAX_NUM_THREADS); thd_scheduler_set(thd, thd_current(cli)); - thd_rcvcap_init(thd); + /* TODO: fix the way to specify scheduler in a component! */ + thd_rcvcap_init(thd, !init_data); list_head_init(&thd->event_head); list_init(&thd->event_list, thd); @@ -356,18 +344,71 @@ thd_activate(struct captbl *t, capid_t cap, capid_t capin, struct thread *thd, c tc->t = thd; tc->cpuid = get_cpuid(); __cap_capactivate_post(&tc->h, CAP_THD); - /* TODO: dcb_thd_ref() */ + + return 0; + +err: + return ret; +} + +static inline int +thd_migrate_cap(struct captbl *ct, capid_t thd_cap) +{ + struct thread *thd; + struct cap_thd *tc; + + /* we migrated the capability to core */ + tc = (struct cap_thd *)captbl_lkup(ct, thd_cap); + if (!tc || tc->h.type != CAP_THD || get_cpuid() != tc->cpuid) return -EINVAL; + thd = tc->t; + tc->cpuid = thd->cpuid; + + return 0; +} + +static inline int +thd_migrate(struct captbl *ct, capid_t thd_cap, cpuid_t core) +{ + struct thread *thd; + struct cap_thd *tc; + + tc = (struct cap_thd *)captbl_lkup(ct, thd_cap); + if (!tc || tc->h.type != CAP_THD || get_cpuid() != tc->cpuid) return -EINVAL; + thd = tc->t; + if (NUM_CPU < 2 || core >= NUM_CPU || core < 0) return -EINVAL; + if (tc->cpuid != thd->cpuid) return -EINVAL; /* outdated capability */ + if (thd->cpuid == core) return -EINVAL; /* already migrated. invalid req */ + if (thd->cpuid != get_cpuid()) return -EPERM; /* only push migration */ + + if (thd_current(cos_cpu_local_info()) == thd) return -EPERM; /* not a running thread! */ + if (thd->invstk_top > 0) return -EPERM; /* not if its in an invocation */ + if (thd_bound2rcvcap(thd) || thd->rcvcap.rcvcap_thd_notif) return -EPERM; /* not if it's an AEP */ + if (thd->rcvcap.rcvcap_tcap) return -EPERM; /* not if it has its own tcap on this core */ + + thd->scheduler_thread = NULL; + thd->cpuid = core; + /* we also migrated the capability to core */ + tc->cpuid = core; + + /* + * TODO: + * given that the thread is not running right now, + * and we don't allow migrating a thread that's in an invocation for now, + * i think we can find the COREID_OFFSET/CPUID_OFFSET on stack and fix the + * core id right here?? + */ return 0; } static int thd_deactivate(struct captbl *ct, struct cap_captbl *dest_ct, unsigned long capin, livenessid_t lid, capid_t pgtbl_cap, - capid_t cosframe_addr, const int root) + capid_t cosframe_addr, capid_t dcbcap, const int root) { struct cos_cpu_local_info *cli = cos_cpu_local_info(); - struct cap_header * thd_header; - struct thread * thd; + struct cap_header *thd_header; + struct thread *thd; + struct cap_dcb *dcb = NULL; unsigned long old_v = 0, *pte = NULL; int ret; @@ -375,6 +416,10 @@ thd_deactivate(struct captbl *ct, struct cap_captbl *dest_ct, unsigned long capi if (!thd_header || thd_header->type != CAP_THD) cos_throw(err, -EINVAL); thd = ((struct cap_thd *)thd_header)->t; assert(thd->refcnt); + if (dcbcap) { + dcb = (struct cap_dcb *)captbl_lkup(ct, dcbcap); + if (!dcb || dcb->h.type != CAP_DCB) cos_throw(err, -EINVAL); + } if (thd->refcnt == 1) { if (!root) cos_throw(err, -EINVAL); @@ -400,6 +445,10 @@ thd_deactivate(struct captbl *ct, struct cap_captbl *dest_ct, unsigned long capi } } + if (dcb) { + ret = dcb_thd_deref(dcb, thd); + if (ret) cos_throw(err, ret); + } ret = cap_capdeactivate(dest_ct, capin, CAP_THD, lid); if (ret) cos_throw(err, ret); @@ -413,7 +462,6 @@ thd_deactivate(struct captbl *ct, struct cap_captbl *dest_ct, unsigned long capi ret = kmem_deact_post(pte, old_v); if (ret) cos_throw(err, ret); } - /* TODO: dcb_thd_deref() */ return 0; err: @@ -463,6 +511,21 @@ curr_invstk_top(struct cos_cpu_local_info *cos_info) return cos_info->invstk_top; } +static inline struct comp_info * +thd_invstk_peek_compinfo(struct thread *curr_thd, struct cos_cpu_local_info *cos_info, int peek_index) +{ + /* curr_thd should be the current thread! We are using cached invstk_top. */ + return &(curr_thd->invstk[peek_index].comp_info); +} + +static inline struct comp_info * +thd_invstk_current_compinfo(struct thread *curr_thd, struct cos_cpu_local_info *cos_info, int *invstk_top) +{ + *invstk_top = curr_invstk_top(cos_info); + + return &(curr_thd->invstk[*invstk_top].comp_info); +} + static inline struct comp_info * thd_invstk_current(struct thread *curr_thd, unsigned long *ip, unsigned long *sp, struct cos_cpu_local_info *cos_info) { @@ -522,26 +585,60 @@ thd_preemption_state_update(struct thread *curr, struct thread *next, struct pt_ memcpy(&curr->regs, regs, sizeof(struct pt_regs)); } +static int +thd_sched_events_produce(struct thread *thd, struct cos_cpu_local_info *cos_info) +{ + int delta = 0, inv_top = curr_invstk_top(cos_info); + struct cos_scb_info *scb = NULL; + struct cos_sched_ring *r = NULL; + struct comp_info *c = NULL; + + if (unlikely(inv_top != 0 || thd->rcvcap.is_init == 0)) return 0; + + c = thd_invstk_peek_compinfo(thd, cos_info, inv_top); + if (unlikely(!c || !c->scb_data)) return 0; + + scb = ((c->scb_data) + get_cpuid()); + r = &(scb->sched_events); + /* + * only produce more if the ring is empty! + * so the user only calls after dequeueing all previous events. + */ + if (unlikely(r->head != r->tail)) return -EAGAIN; + + r->head = r->tail = 0; + while (delta < COS_SCHED_EVENT_RING_SIZE) { + struct cos_sched_event *e = &(r->event_buf[delta]); + unsigned long thd_state; + + if (!thd_state_evt_deliver(thd, &thd_state, (unsigned long *)&(e->evt.elapsed_cycs), + (unsigned long *)&(e->evt.next_timeout))) break; + e->tid = (thd_state << 1) >> 1; + e->evt.blocked = (thd_state >> 31); + + delta++; + } + + r->tail += delta; + + return delta; +} + static inline void thd_rcvcap_pending_deliver(struct thread *thd, struct pt_regs *regs) { - unsigned long thd_state = 0, cycles = 0, timeout = 0, pending = 0; - int all_pending = thd_rcvcap_all_pending_get(thd); + unsigned long thd_state = 0, cycles = 0, timeout = 0; thd_state_evt_deliver(thd, &thd_state, &cycles, &timeout); - if (all_pending) { - pending = thd_rcvcap_all_pending(thd); - } else { - thd_rcvcap_pending_dec(thd); - pending = thd_rcvcap_pending(thd); - } - __userregs_setretvals(regs, pending, thd_state, cycles, timeout); + thd_rcvcap_pending_reset(thd); + thd_sched_events_produce(thd, cos_cpu_local_info()); + __userregs_setretvals(regs, thd_rcvcap_pending(thd), thd_state, cycles, timeout); } static inline int thd_switch_update(struct thread *thd, struct pt_regs *regs, int issame) { - int preempt = 0; + int preempt = 0, pending = 0; /* TODO: check FPU */ /* fpu_save(thd); */ @@ -553,7 +650,7 @@ thd_switch_update(struct thread *thd, struct pt_regs *regs, int issame) assert(!(thd->state & THD_STATE_PREEMPTED)); thd->state &= ~THD_STATE_RCVING; thd_rcvcap_pending_deliver(thd, regs); - + pending = thd_rcvcap_pending(thd); /* * If a scheduler thread was running using child tcap and blocked on RCVING * and budget expended logic decided to run the scheduler thread with it's @@ -561,8 +658,15 @@ thd_switch_update(struct thread *thd, struct pt_regs *regs, int issame) */ } + if (unlikely(thd->dcbinfo && thd->dcbinfo->sp)) { + assert(preempt == 0); + regs->dx = regs->ip = thd->dcbinfo->ip + DCB_IP_KERN_OFF; + regs->cx = regs->sp = thd->dcbinfo->sp; + thd->dcbinfo->sp = 0; + } + if (issame && preempt == 0) { - __userregs_set(regs, 0, __userregs_getsp(regs), __userregs_getip(regs)); + __userregs_set(regs, pending, __userregs_getsp(regs), __userregs_getip(regs)); } return preempt; @@ -575,6 +679,12 @@ thd_introspect(struct thread *t, unsigned long op, unsigned long *retval) case THD_GET_TID: *retval = t->tid; break; + case THD_GET_DCB_IP: + *retval = t->dcbinfo->ip; + break; + case THD_GET_DCB_SP: + *retval = t->dcbinfo->sp; + break; default: return -EINVAL; } diff --git a/src/platform/i386/boot_comp.c b/src/platform/i386/boot_comp.c index 99451f9a7a..31cd0b3567 100644 --- a/src/platform/i386/boot_comp.c +++ b/src/platform/i386/boot_comp.c @@ -11,15 +11,18 @@ #include #include #include +#include +#include #include #include extern u8_t *boot_comp_pgd; +//vaddr_t dcb_addr[NUM_CPU], dcb_uaddr[NUM_CPU]; void *thd_mem[NUM_CPU], *tcap_mem[NUM_CPU]; struct captbl *glb_boot_ct; -int +/*int boot_nptes(unsigned int sz) { return round_up_to_pow2(sz, PGD_RANGE) / PGD_RANGE; @@ -27,7 +30,7 @@ boot_nptes(unsigned int sz) int boot_pgtbl_mappings_add(struct captbl *ct, capid_t pgdcap, capid_t ptecap, const char *label, void *kern_vaddr, - unsigned long user_vaddr, unsigned int range, int uvm, unsigned long *scb_uaddr) + unsigned long user_vaddr, unsigned int range, int uvm) { int ret; u8_t * ptes; @@ -52,21 +55,21 @@ boot_pgtbl_mappings_add(struct captbl *ct, capid_t pgdcap, capid_t ptecap, const printk("\tCreating %d %s PTEs for PGD @ 0x%x from [%x,%x) to [%x,%x).\n", nptes, label, chal_pa2va((paddr_t)pgtbl), kern_vaddr, kern_vaddr + range, user_vaddr, user_vaddr + range); - /* - * Note the use of NULL here. We aren't actually adding a PTE - * currently. This is a hack and only used on boot-up. We'll - * reuse this capability entry to create _multiple_ ptes. We - * won't create captbl entries for each of them, so they - * cannot be aliased/removed later. The only adverse - * side-effect I can think of from this is that we cannot - * reclaim all of the boot-time memory, but that is so far - * into the future, I don't think we care. - */ + // + // Note the use of NULL here. We aren't actually adding a PTE + // currently. This is a hack and only used on boot-up. We'll + // reuse this capability entry to create _multiple_ ptes. We + // won't create captbl entries for each of them, so they + // cannot be aliased/removed later. The only adverse + // side-effect I can think of from this is that we cannot + // reclaim all of the boot-time memory, but that is so far + // into the future, I don't think we care. + if (pgtbl_activate(ct, BOOT_CAPTBL_SELF_CT, ptecap, NULL, 1)) assert(0); pte_cap = (struct cap_pgtbl *)captbl_lkup(ct, ptecap); assert(pte_cap); - /* Hook in the PTEs */ + // Hook in the PTEs for (i = 0; i < nptes; i++) { u8_t * p = ptes + i * PAGE_SIZE; paddr_t pf = chal_va2pa(p); @@ -74,49 +77,25 @@ boot_pgtbl_mappings_add(struct captbl *ct, capid_t pgdcap, capid_t ptecap, const pgtbl_init_pte(p); pte_cap->pgtbl = (pgtbl_t)p; - /* hook the pte into the boot component's page tables */ + // hook the pte into the boot component's page tables ret = cap_cons(ct, pgdcap, ptecap, (capid_t)(user_vaddr + i * PGD_RANGE)); assert(!ret); } printk("\tMapping in %s.\n", label); - /* Map in the actual memory. */ + // Map in the actual memory. for (i = 0; i < range / PAGE_SIZE; i++) { u8_t * p = kern_vaddr + i * PAGE_SIZE; paddr_t pf = chal_va2pa(p); u32_t mapat = (u32_t)user_vaddr + i * PAGE_SIZE, flags = 0; - if (uvm && pgtbl_mapping_add(pgtbl, mapat, pf, PGTBL_USER_DEF)) assert(0); - if (!uvm && pgtbl_cosframe_add(pgtbl, mapat, pf, PGTBL_COSFRAME)) assert(0); + if (uvm && pgtbl_mapping_add(pgtbl, mapat, pf, PGTBL_USER_DEF, PAGE_ORDER)) assert(0); + if (!uvm && pgtbl_cosframe_add(pgtbl, mapat, pf, PGTBL_COSFRAME, PAGE_ORDER)) assert(0); assert((void *)p == pgtbl_lkup(pgtbl, user_vaddr + i * PAGE_SIZE, &flags)); } - if (uvm) { - unsigned int j; - u8_t *p; - paddr_t pf; - u32_t mapat = (u32_t)user_vaddr + i * PAGE_SIZE, flags = 0; - - assert(i == range / PAGE_SIZE); - assert(COS_SCB_SIZE == PAGE_SIZE); /* FIXME: for prototype impl! */ - *scb_uaddr = (unsigned long)mapat; - i++; - - for (j = 0; j < NUM_CPU; j++, i++) { - unsigned long *pte = NULL, flags; - mapat = (u32_t)user_vaddr + i * PAGE_SIZE; - p = mem_boot_alloc(1); - assert(p); - pf = chal_va2pa(p); - if (pgtbl_mapping_add(pgtbl, mapat, pf, PGTBL_USER_DEF)) assert(0); - - dcb_addr[j] = (unsigned long)p; - pte = pgtbl_lkup(pgtbl, mapat, (u32_t *)&flags); - assert((void *)p == pte); - } - } return 0; -} +}*/ /* FIXME: loops to create threads/tcaps/rcv caps per core. */ static void @@ -136,7 +115,9 @@ kern_boot_thd(struct captbl *ct, void *thd_mem, void *tcap_mem, const cpuid_t cp cos_info->cpuid = cpu_id; cos_info->invstk_top = 0; cos_info->overflow_check = 0xDEADBEEF; - ret = thd_activate(ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cpu_id), thd_mem, BOOT_CAPTBL_SELF_COMP, 0); + //ret = dcb_activate(ct, BOOT_CAPTBL_SELF_CT, LLBOOT_CAPTBL_INITDCB_CPU(cpu_id), NULL, 0, BOOT_CAPTBL_SELF_PT, NULL); + //assert(!ret); + ret = thd_activate(ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cpu_id), thd_mem, BOOT_CAPTBL_SELF_COMP, 0, 0, 0); assert(!ret); tcap_active_init(cos_info); @@ -263,7 +244,7 @@ boot_pgtbl_mappings_add(struct captbl *ct, capid_t pgdcap, capid_t ptecap, const pgtbl = (pgtbl_t)pgd_cap->pgtbl; printk("\tMapping in %s (@ [0x%p, 0x%p))\n", label, user_vaddr, user_vaddr + range); - /* Map in the actual memory. */ + // Map in the actual memory. for (i = 0; i < round_up_to_page(range) / PAGE_SIZE; i++) { u8_t * p = kern_vaddr + i * PAGE_SIZE; paddr_t pf = chal_va2pa(p); @@ -345,7 +326,6 @@ kern_boot_comp(const cpuid_t cpu_id) pgtbl_t pgtbl = (pgtbl_t)chal_va2pa(&boot_comp_pgd), boot_vm_pgd; u32_t hw_bitmap = ~0; - vaddr_t scb_uaddr = 0, scb_kaddr = 0; assert(cpu_id >= 0); if (NUM_CPU > 1 && cpu_id > 0) { @@ -377,6 +357,9 @@ kern_boot_comp(const cpuid_t cpu_id) assert(thd_mem[i]); tcap_mem[i] = mem_boot_alloc(1); assert(tcap_mem[i]); + //dcb_addr[i] = mem_boot_alloc(1); + //assert(dcb_addr[i]); + //assert(thd_mem[i] && tcap_mem[i] && dcb_addr[i]); assert(thd_mem[i] && tcap_mem[i]); } @@ -386,8 +369,6 @@ kern_boot_comp(const cpuid_t cpu_id) hw_asndcap_init(); if (hw_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_INITHW_BASE, hw_bitmap)) assert(0); - scb_kaddr = (vaddr_t)mem_boot_alloc(1); - assert(scb_kaddr); /* * separate pgd for boot component virtual memory */ @@ -428,11 +409,11 @@ kern_boot_comp(const cpuid_t cpu_id) /* Shut off further bump allocations */ glb_memlayout.allocs_avail = 0; - if (scb_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_SCB, scb_kaddr, 0)) assert(0); + //if (scb_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_SCB, scb_kaddr, 0)) assert(0); printk("\tCapability table and page-table created.\n"); if (comp_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_PT, - BOOT_CAPTBL_SELF_SCB, 0, (vaddr_t)mem_bootc_entry(), scb_uaddr)) + 0, 0, (vaddr_t)mem_bootc_entry(), 0)) assert(0); printk("\tCreated boot component structure from page-table and capability-table.\n"); diff --git a/src/platform/i386/chal/shared/cos_config.h b/src/platform/i386/chal/shared/cos_config.h index 1a95ff362c..96c1b0faba 100644 --- a/src/platform/i386/chal/shared/cos_config.h +++ b/src/platform/i386/chal/shared/cos_config.h @@ -89,6 +89,7 @@ /* Composite user memory uses physical memory above this. */ #define COS_MEM_START COS_MEM_KERN_PA +#define COS_SCB_SIZE (PAGE_SIZE) /* NUM_CPU_SOCKETS defined in cpu_ghz.h. The information is used for * intelligent IPI distribution. */ From eec3a0871b1b0166969d057fabfce984064fe23c Mon Sep 17 00:00:00 2001 From: WenyuanShao Date: Mon, 28 Feb 2022 23:43:46 -0500 Subject: [PATCH 3/7] further merge sl lib and clean up capmgr --- .../implementation/capmgr/simple/capmgr.c | 2 +- .../tests/unit_capmgr/unit_capmgr.c | 3 +- src/components/interface/capmgr/capmgr.h | 25 +++--- src/components/interface/capmgr/lib.c | 8 +- .../interface/capmgr/stubs/c_stub.c | 55 +++++++++++--- .../interface/capmgr/stubs/s_stub.c | 41 ++++++++-- src/components/interface/capmgr/stubs/stubs.S | 3 + src/components/lib/sl/sl.h | 76 ++++++++++++++----- src/components/lib/sl/sl_plugins.h | 1 + src/components/lib/sl/sl_thd_static_backend.c | 55 +++++++++++--- src/components/lib/sl_capmgr/sl_capmgr.c | 40 +++++++++- src/components/lib/sl_kernel/sl_raw.c | 71 +++++++++++++---- 12 files changed, 301 insertions(+), 79 deletions(-) diff --git a/src/components/implementation/capmgr/simple/capmgr.c b/src/components/implementation/capmgr/simple/capmgr.c index 17fd7a6556..97aae38349 100644 --- a/src/components/implementation/capmgr/simple/capmgr.c +++ b/src/components/implementation/capmgr/simple/capmgr.c @@ -530,7 +530,7 @@ capmgr_initthd_create(spdid_t client, thdid_t *tid) thdcap_t capmgr_initaep_create(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret) { BUG(); return 0; } thdcap_t -capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid) +capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb) { compid_t client = (compid_t)cos_inv_token(); struct cm_thd *t; diff --git a/src/components/implementation/tests/unit_capmgr/unit_capmgr.c b/src/components/implementation/tests/unit_capmgr/unit_capmgr.c index 5da92baeb4..f176f9248a 100644 --- a/src/components/implementation/tests/unit_capmgr/unit_capmgr.c +++ b/src/components/implementation/tests/unit_capmgr/unit_capmgr.c @@ -32,7 +32,8 @@ test_thds(void) int failure = 0; for (; i < TEST_N_THDS; i++) { - test_ts[cos_cpuid()][i] = capmgr_thd_create(__test_thd_fn, (void *)i, &tid); + /* Hard coded dcb address for now */ + test_ts[cos_cpuid()][i] = capmgr_thd_create(__test_thd_fn, (void *)i, &tid, NULL); assert(test_ts[cos_cpuid()][i]); if (cos_thd_switch(test_ts[cos_cpuid()][i])) { diff --git a/src/components/interface/capmgr/capmgr.h b/src/components/interface/capmgr/capmgr.h index 268ec4d43e..ae5a45cbb9 100644 --- a/src/components/interface/capmgr/capmgr.h +++ b/src/components/interface/capmgr/capmgr.h @@ -28,20 +28,23 @@ thdcap_t COS_STUB_DECL(capmgr_initthd_create)(spdid_t child, thdid_t *tid); thdcap_t capmgr_initaep_create(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret); thdcap_t COS_STUB_DECL(capmgr_initaep_create)(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret); -thdcap_t capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid); -thdcap_t capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax); +thdcap_t capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info **dcb); +thdcap_t capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); -thdcap_t capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid); -thdcap_t COS_STUB_DECL(capmgr_thd_create_thunk)(thdclosure_index_t idx, thdid_t *tid); +thdcap_t capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); +thdcap_t COS_STUB_DECL(capmgr_thd_create_thunk)(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); -thdcap_t capmgr_aep_create_thunk(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax); -thdcap_t COS_STUB_DECL(capmgr_aep_create_thunk)(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax); +thdcap_t capmgr_aep_create_thunk(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); +thdcap_t COS_STUB_DECL(capmgr_aep_create_thunk)(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); -thdcap_t capmgr_thd_create_ext(spdid_t child, thdclosure_index_t idx, thdid_t *tid); -thdcap_t COS_STUB_DECL(capmgr_thd_create_ext)(spdid_t child, thdclosure_index_t idx, thdid_t *tid); +thdcap_t capmgr_thd_create_ext(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); +thdcap_t COS_STUB_DECL(capmgr_thd_create_ext)(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); -thdcap_t capmgr_aep_create_ext(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv); -thdcap_t COS_STUB_DECL(capmgr_aep_create_ext)(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv); +thdcap_t capmgr_aep_create_ext(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv); +thdcap_t COS_STUB_DECL(capmgr_aep_create_ext)(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv); + +thdcap_t capmgr_thd_retrieve(spdid_t child, thdid_t t, thdid_t *inittid); +thdcap_t capmgr_thd_retrieve_next(spdid_t child, thdid_t *tid); arcvcap_t capmgr_rcv_create(spdid_t child, thdid_t tid, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax); arcvcap_t COS_STUB_DECL(capmgr_rcv_create)(spdid_t child, thdid_t tid, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax); @@ -55,4 +58,6 @@ asndcap_t COS_STUB_DECL(capmgr_asnd_rcv_create)(arcvcap_t rcv); asndcap_t capmgr_asnd_key_create(cos_channelkey_t key); asndcap_t COS_STUB_DECL(capmgr_asnd_key_create)(cos_channelkey_t key); +int capmgr_thd_migrate(thdid_t tid, thdcap_t tc, cpuid_t core); + #endif /* CAPMGR_H */ diff --git a/src/components/interface/capmgr/lib.c b/src/components/interface/capmgr/lib.c index d190ceed4c..e000076387 100644 --- a/src/components/interface/capmgr/lib.c +++ b/src/components/interface/capmgr/lib.c @@ -2,17 +2,17 @@ #include thdcap_t -capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid) +capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info **dcb) { thdclosure_index_t idx = cos_thd_init_alloc(fn, data); if (idx < 1) return 0; - return capmgr_thd_create_thunk(idx, tid); + return capmgr_thd_create_thunk(idx, tid, dcb); } thdcap_t -capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) +capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb) { thdclosure_index_t idx = cos_thd_init_alloc(cos_aepthd_fn, (void *)a); @@ -20,5 +20,5 @@ capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int ow a->fn = fn; a->data = data; - return capmgr_aep_create_thunk(a, idx, owntc, key, ipiwin, ipimax); + return capmgr_aep_create_thunk(a, idx, owntc, key, ipiwin, ipimax, dcb); } diff --git a/src/components/interface/capmgr/stubs/c_stub.c b/src/components/interface/capmgr/stubs/c_stub.c index 938cf425a3..d197729476 100644 --- a/src/components/interface/capmgr/stubs/c_stub.c +++ b/src/components/interface/capmgr/stubs/c_stub.c @@ -21,7 +21,19 @@ COS_CLIENT_STUB(arcvcap_t, capmgr_rcv_create, spdid_t child, thdid_t tid, cos_ch return cos_sinv(uc->cap_no, spd_tid, key_ipimax, ipiwin32b, 0); } -COS_CLIENT_STUB(thdcap_t, capmgr_initthd_create, spdid_t child, thdid_t *tid) +COS_CLIENT_STUB(thdcap_t, capmgr_thd_retrieve, spdid_t child, thdid_t tid, thdid_t *inittid) +{ + COS_CLIENT_INVCAP; + word_t unused, tid_ret; + thdcap_t ret; + + ret = cos_sinv_2rets(uc->cap_no, child, tid, 0, 0, &tid_ret, &unused); + *inittid = tid_ret; + + return ret; +} + +COS_CLIENT_STUB(thdcap_t, capmgr_thd_retrieve_next, spdid_t child, thdid_t *tid) { COS_CLIENT_INVCAP; word_t unused, tid_ret; @@ -33,34 +45,49 @@ COS_CLIENT_STUB(thdcap_t, capmgr_initthd_create, spdid_t child, thdid_t *tid) return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_thunk, thdclosure_index_t id, thdid_t *tid) +COS_CLIENT_STUB(thdcap_t, capmgr_initthd_create, spdid_t child, thdid_t *tid) { COS_CLIENT_INVCAP; word_t unused, tid_ret; thdcap_t ret; - ret = cos_sinv_2rets(uc->cap_no, id, 0, 0, 0, &tid_ret, &unused); + ret = cos_sinv_2rets(uc->cap_no, child, 0, 0, 0, &tid_ret, &unused); *tid = tid_ret; return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_ext, spdid_t child, thdclosure_index_t idx, thdid_t *tid) +COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_thunk, thdclosure_index_t id, thdid_t *tid, struct cos_dcb_info **dcb) { COS_CLIENT_INVCAP; - word_t unused, tid_ret; + word_t dcb_ret, tid_ret; thdcap_t ret; - ret = cos_sinv_2rets(uc->cap_no, child, idx, 0, 0, &tid_ret, &unused); + ret = cos_sinv_2rets(uc->cap_no, id, 0, 0, 0, &tid_ret, &dcb_ret); + *dcb = &dcb_ret; *tid = tid_ret; return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) +COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_ext, spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb) { COS_CLIENT_INVCAP; - word_t tcrcvret = 0; + word_t dcb_ret, tid_ret; + thdcap_t ret; + + ret = cos_sinv_2rets(uc->cap_no, child, idx, 0, 0, &tid_ret, &dcb_ret); + *dcb = &dcb_ret; + + return ret; +} + +COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb) +{ + COS_CLIENT_INVCAP; + word_t tcrcvret = 0; + word_t thdtidret = 0; + word_t dcb_ret = 0; thdcap_t thd = 0; thdid_t tid = 0; u32_t owntc_idx = (owntc << 16) | idx; @@ -69,18 +96,24 @@ COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thd if (idx < 1) return 0; - thd = cos_sinv_2rets(uc->cap_no, owntc_idx, key_ipimax, ipiwin32b, 0, &tid, &tcrcvret); - if (!thd) return 0; + thdtidret = cos_sinv_2rets(uc->cap_no, owntc_idx, key_ipimax, ipiwin32b, 0, &dcb_ret, &tcrcvret); + if (!thdtidret) return 0; + thd = thdtidret >> 16; + tid = (thdtidret << 16) >> 16; + if (!thd || !tid) return 0; aep->thd = thd; aep->rcv = (tcrcvret << 16) >> 16; aep->tc = (tcrcvret >> 16); aep->tid = tid; + *dcb = &dcb_ret; + return thd; } -COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_ext, spdid_t child, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) +/* FIXME: Won't work now */ +COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_ext, spdid_t child, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv) { COS_CLIENT_INVCAP; word_t drcvtidret = 0; diff --git a/src/components/interface/capmgr/stubs/s_stub.c b/src/components/interface/capmgr/stubs/s_stub.c index a71bf74033..ea0fe71d91 100644 --- a/src/components/interface/capmgr/stubs/s_stub.c +++ b/src/components/interface/capmgr/stubs/s_stub.c @@ -13,14 +13,37 @@ COS_SERVER_3RET_STUB(arcvcap_t, capmgr_rcv_create) return capmgr_rcv_create(child, tid, key, ipiwin, ipimax); } +COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_retrieve) +{ + thdid_t retthd = 0; + thdcap_t ret; + + ret = capmgr_thd_retrieve(p0, p1, &retthd); + *r1 = retthd; + + return ret; +} + +COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_retrieve_next) +{ + thdid_t retthd = 0; + thdcap_t ret; + + ret = capmgr_thd_retrieve_next(p0, &retthd); + *r1 = retthd; + + return ret; +} COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_thunk) { thdid_t retthd = 0; + struct cos_dcb_info *retdcb; thdcap_t ret; - ret = capmgr_thd_create_thunk(p0, &retthd); + ret = capmgr_thd_create_thunk(p0, &retthd, &retdcb); *r1 = retthd; + *r2 = &retdcb; return ret; } @@ -28,10 +51,12 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_thunk) COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_ext) { thdid_t retthd = 0; + struct cos_dcb_info *retdcb; thdcap_t ret; - ret = capmgr_thd_create_ext(p0, p1, &retthd); + ret = capmgr_thd_create_ext(p0, p1, &retthd, &retdcb); *r1 = retthd; + *r2 = &retdcb; return ret; } @@ -73,14 +98,15 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_aep_create_thunk) u32_t ipimax = (p1 << 16) >> 16; u32_t ipiwin32b = (u32_t)p2; struct cos_aep_info aep; + struct cos_dcb_info *dcb; asndcap_t snd; - thdcap_t thd; + thdcap_t thdtidret; - thd = capmgr_aep_create_thunk(&aep, thunk, owntc, key, ipimax, ipiwin32b); - *r1 = aep.tid; + thdtidret = capmgr_aep_create_thunk(&aep, thunk, owntc, key, ipimax, ipiwin32b, &dcb); + *r1 = &dcb; *r2 = (aep.rcv << 16) | aep.tc; - return thd; + return thdtidret; } COS_SERVER_3RET_STUB(thdcap_t, capmgr_aep_create_ext) @@ -93,9 +119,10 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_aep_create_ext) microsec_t ipiwin = p3; u32_t ipimax = ((p2 << 16) >> 16); arcvcap_t extrcv = 0; + struct cos_dcb_info *dcbret; thdcap_t ret; - ret = capmgr_aep_create_ext(child, &aep, idx, owntc, key, ipiwin, ipimax, &extrcv); + ret = capmgr_aep_create_ext(child, &aep, idx, owntc, key, ipiwin, ipimax, &dcbret, &extrcv); *r1 = aep.tid | (extrcv << 16); *r2 = (aep.rcv << 16) | aep.tc; diff --git a/src/components/interface/capmgr/stubs/stubs.S b/src/components/interface/capmgr/stubs/stubs.S index 6af692eec4..4d8df14b18 100644 --- a/src/components/interface/capmgr/stubs/stubs.S +++ b/src/components/interface/capmgr/stubs/stubs.S @@ -7,6 +7,9 @@ #include +cos_asm_stub_indirect(capmgr_thd_retrieve) +cos_asm_stub_indirect(capmgr_thd_retrieve_next) + cos_asm_stub_indirect(capmgr_initthd_create) cos_asm_stub_indirect(capmgr_thd_create_thunk) cos_asm_stub_indirect(capmgr_thd_create_ext) diff --git a/src/components/lib/sl/sl.h b/src/components/lib/sl/sl.h index 50baf54c3d..11435a0a1b 100644 --- a/src/components/lib/sl/sl.h +++ b/src/components/lib/sl/sl.h @@ -289,8 +289,8 @@ struct sl_thd *sl_thd_aep_alloc(cos_aepthd_fn_t fn, void *data, int own_tcap, co */ struct sl_thd *sl_thd_comp_init(struct cos_defcompinfo *comp, int is_sched); -struct sl_thd *sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax,dcbcap_t dcap); -struct sl_thd *sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, dcbcap_t dcap, dcboff_t doff, arcvcap_t *extrcv); +struct sl_thd *sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, dcbcap_t dcap, microsec_t ipiwin, u32_t ipimax); +struct sl_thd *sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, dcbcap_t dcap, dcboff_t doff, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv); struct sl_thd *sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbaddr); struct sl_thd *sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbaddr, arcvcap_t *extrcv); @@ -350,8 +350,6 @@ sl_timeout_oneshot(cycles_t absolute_us) { sl__globals_cpu()->timer_next = absolute_us; sl__globals_cpu()->timeout_next = tcap_cyc2time(absolute_us); - - sl_scb_info_cpu()->timer_next = absolute_us; } static inline void @@ -408,10 +406,42 @@ sl_thd_is_runnable(struct sl_thd *t) int sl_thd_kern_dispatch(thdcap_t t); +static inline int +sl_thd_activate(struct sl_thd *t, sched_tok_t tok, tcap_time_t timeout) +{ + struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); + struct cos_compinfo *ci = &dci->ci; + struct sl_global_cpu *g = sl__globals_cpu(); + int ret = 0; + + if (t->properties & SL_THD_PROPERTY_SEND) { + return cos_sched_asnd(t->sndcap, timeout, g->sched_rcv, tok); + } else if (t->properties & SL_THD_PROPERTY_OWN_TCAP) { + return cos_switch(sl_thd_thdcap(t), sl_thd_tcap(t), t->prio, + timeout, g->sched_rcv, tok); + } else { + ret = cos_defswitch(sl_thd_thdcap(t), t->prio, t == g->sched_thd ? + TCAP_TIME_NIL : timeout, tok); + if (likely(t != g->sched_thd && t != g->idle_thd)) return ret; + if (unlikely(ret != -EPERM)) return ret; + + /* + * Attempting to activate scheduler thread or idle thread failed for no budget in it's tcap. + * Force switch to the scheduler with current tcap. + */ + return cos_switch(g->sched_thdcap, g->sched_tcap, t->prio, + timeout, g->sched_rcv, tok); + } +} + static inline int sl_thd_dispatch(struct sl_thd *next, sched_tok_t tok, struct sl_thd *curr) { - struct cos_scb_info *scb = sl_scb_info_cpu(); + volatile struct cos_scb_info *scb = sl_scb_info_cpu(); + struct cos_dcb_info *cd = sl_thd_dcbinfo(curr), *nd = sl_thd_dcbinfo(next); + + assert(curr != next); + if (unlikely(!cd || !nd)) return sl_thd_activate(next, tok, sl__globals_cpu()->timeout_next); /* * jump labels in the asm routine: @@ -431,6 +461,8 @@ sl_thd_dispatch(struct sl_thd *next, sched_tok_t tok, struct sl_thd *curr) */ __asm__ __volatile__ ( \ + "pushl %%ebp\n\t" \ + "movl %%esp, %%ebp\n\t" \ "movl $2f, (%%eax)\n\t" \ "movl %%esp, 4(%%eax)\n\t" \ "cmp $0, 4(%%ebx)\n\t" \ @@ -438,29 +470,37 @@ sl_thd_dispatch(struct sl_thd *next, sched_tok_t tok, struct sl_thd *curr) "movl %%edx, (%%ecx)\n\t" \ "movl 4(%%ebx), %%esp\n\t" \ "jmp *(%%ebx)\n\t" \ + ".align 4\n\t" \ "1:\n\t" \ - "pushl %%ebp\n\t" \ - "movl %%esp, %%ebp\n\t" \ - "pushl %%edx\n\t" \ - "call sl_thd_kern_dispatch\n\t" \ - "addl $4, %%esp\n\t" \ - "popl %%ebp\n\t" \ + "movl $3f, %%ecx\n\t" \ + "movl %%edx, %%eax\n\t" \ + "inc %%eax\n\t" \ + "shl $16, %%eax\n\t" \ + "movl $0, %%ebx\n\t" \ + "movl $0, %%esi\n\t" \ + "movl $0, %%edi\n\t" \ + "movl $0, %%edx\n\t" \ + "sysenter\n\t" \ "jmp 3f\n\t" \ ".align 4\n\t" \ "2:\n\t" \ "movl $0, 4(%%ebx)\n\t" \ ".align 4\n\t" \ "3:\n\t" \ + "popl %%ebp\n\t" \ : - : "a" (sl_thd_dcbinfo(curr)), "b" (sl_thd_dcbinfo(next)), + : "a" (cd), "b" (nd), "S" ((u32_t)((u64_t)tok >> 32)), "D" ((u32_t)(((u64_t)tok << 32) >> 32)), "c" (&(scb->curr_thd)), "d" (sl_thd_thdcap(next)) : "memory", "cc"); - return sl_scb_info_cpu()->sched_tok != tok ? -EAGAIN : 0; + scb = sl_scb_info_cpu(); + if (unlikely(ps_load(&scb->sched_tok) != tok)) return -EAGAIN; + + return 0; } -static inline int +/*static inline int sl_thd_activate(struct sl_thd *t, sched_tok_t tok) { struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); @@ -474,12 +514,12 @@ sl_thd_activate(struct sl_thd *t, sched_tok_t tok) return cos_switch(sl_thd_thdcap(t), sl_thd_tcap(t), t->prio, g->timeout_next, g->sched_rcv, tok); } else { - /* TODO: can't use if you're reprogramming a timer/prio */ + // TODO: can't use if you're reprogramming a timer/prio return sl_thd_dispatch(t, tok, sl_thd_curr()); //return cos_switch(sl_thd_thdcap(t), g->sched_tcap, t->prio, // g->timeout_next, g->sched_rcv, tok); } -} +}*/ /* * Do a few things: 1. take the critical section if it isn't already @@ -573,7 +613,7 @@ sl_cs_exit_schedule_nospin_arg(struct sl_thd *to) sl_cs_exit(); if (t == sl_thd_curr()) return 0; - ret = sl_thd_activate(t, tok); + ret = sl_thd_activate(t, tok, globals->timeout_next); /* * dispatch failed with -EPERM because tcap associated with thread t does not have budget. * Block the thread until it's next replenishment and return to the scheduler thread. @@ -584,7 +624,7 @@ sl_cs_exit_schedule_nospin_arg(struct sl_thd *to) if (unlikely(ret == -EPERM)) { assert(t != globals->sched_thd && t != globals->idle_thd); sl_thd_block_expiry(t); - if (unlikely(sl_thd_curr() != globals->sched_thd)) ret = sl_thd_activate(globals->sched_thd, tok); + if (unlikely(sl_thd_curr() != globals->sched_thd)) ret = sl_thd_activate(globals->sched_thd, tok, globals->timeout_next); } return ret; diff --git a/src/components/lib/sl/sl_plugins.h b/src/components/lib/sl/sl_plugins.h index 0a7d22db3f..74b860233a 100644 --- a/src/components/lib/sl/sl_plugins.h +++ b/src/components/lib/sl/sl_plugins.h @@ -16,6 +16,7 @@ */ struct sl_thd_policy *sl_thd_alloc_backend(thdid_t tid); void sl_thd_free_backend(struct sl_thd_policy *t); +struct sl_thd_policy *sl_thd_migrate_backend(struct sl_thd_policy *t, cpuid_t core); /* * cos_aep_info structs cannot be stack allocated! * The thread_alloc_backened needs to provide struct cos_aep_info without diff --git a/src/components/lib/sl/sl_thd_static_backend.c b/src/components/lib/sl/sl_thd_static_backend.c index 86aa4eac66..2985f8f5e5 100644 --- a/src/components/lib/sl/sl_thd_static_backend.c +++ b/src/components/lib/sl/sl_thd_static_backend.c @@ -17,26 +17,63 @@ static struct cos_aep_info __sl_aep_infos[NUM_CPU][SL_MAX_NUM_THDS]; static u32_t __sl_aep_free_off[NUM_CPU]; /* Default implementations of backend functions */ -struct sl_thd_policy * -sl_thd_alloc_backend(thdid_t tid) +static inline struct sl_thd_policy * +sl_thd_alloc_backend_core(cpuid_t core, thdid_t tid) { - assert(tid < SL_MAX_NUM_THDS); + assert(tid < SL_MAX_NUM_THDS && core >= 0 && core < NUM_CPU); - return &(__sl_threads[cos_cpuid()][tid]); + return &(__sl_threads[core][tid]); } -struct cos_aep_info * -sl_thd_alloc_aep_backend(void) +static inline struct cos_aep_info * +sl_thd_alloc_aep_backend_core(cpuid_t core) { + int off = 0; struct cos_aep_info *aep = NULL; - assert(__sl_aep_free_off[cos_cpuid()] < SL_MAX_NUM_THDS); - aep = &(__sl_aep_infos[cos_cpuid()][__sl_aep_free_off[cos_cpuid()]]); - ps_faa((unsigned long *)&(__sl_aep_free_off[cos_cpuid()]), 1); + assert(core < NUM_CPU && core >= 0); + off = ps_faa((unsigned long *)&__sl_aep_free_off[core], 1); + assert(off < SL_MAX_NUM_THDS); + aep = &__sl_aep_infos[core][off]; return aep; } +struct sl_thd_policy * +sl_thd_migrate_backend(struct sl_thd_policy *t, cpuid_t core) +{ + assert(core != cos_cpuid() && core >= 0 && core < NUM_CPU); + + struct cos_aep_info *a = sl_thd_alloc_aep_backend_core(core); + struct cos_aep_info *b = sl_thd_aepinfo(sl_mod_thd_get(t)); + struct sl_thd_policy *tc = sl_thd_alloc_backend_core(core, b->tid); + struct sl_thd *x = sl_mod_thd_get(tc), *y = sl_mod_thd_get(t); + + memset(a, 0, sizeof(struct cos_aep_info)); + a->tid = b->tid; + a->thd = b->thd; + assert(b->rcv == 0 && b->tc == 0); + memset(b, 0, sizeof(struct cos_aep_info)); + + memcpy(tc, t, sizeof(struct sl_thd_policy)); + x->aepinfo = a; + memset(t, 0, sizeof(struct sl_thd_policy)); + + return tc; +} + +struct sl_thd_policy * +sl_thd_alloc_backend(thdid_t tid) +{ + return sl_thd_alloc_backend_core(cos_cpuid(), tid); +} + +struct cos_aep_info * +sl_thd_alloc_aep_backend(void) +{ + return sl_thd_alloc_aep_backend_core(cos_cpuid()); +} + void sl_thd_free_backend(struct sl_thd_policy *t) { } diff --git a/src/components/lib/sl_capmgr/sl_capmgr.c b/src/components/lib/sl_capmgr/sl_capmgr.c index 8fc4eaf17e..7c32d27f77 100644 --- a/src/components/lib/sl_capmgr/sl_capmgr.c +++ b/src/components/lib/sl_capmgr/sl_capmgr.c @@ -274,7 +274,7 @@ sl_thd_comp_init(struct cos_defcompinfo *comp, int is_sched) } struct sl_thd * -sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, dcbcap_t dcap) +sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, dcbcap_t dcap, microsec_t ipiwin, u32_t ipimax) { PRINTC("UNIMPLEMENTED: Using CAPMGR API which should manage the DCB capabilities\n"); @@ -302,7 +302,7 @@ sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int struct sl_thd * -sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, dcbcap_t dcap, dcboff_t doff, arcvcap_t *extrcv) +sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, dcbcap_t dcap, dcboff_t doff, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) { PRINTC("UNIMPLEMENTED: Using CAPMGR API which should manage the DCB capabilities\n"); @@ -415,3 +415,39 @@ sl_thd_free(struct sl_thd *t) sl_thd_free_no_cs(t); sl_cs_exit(); } + +int +sl_thd_migrate_no_cs(struct sl_thd *t, cpuid_t core) +{ + struct sl_thd_policy *x = NULL; + int ret; + + if (t->properties) return -1; + if (t->state != SL_THD_RUNNABLE) return -1; + /* capmgr should migrate the thdcap as well */ + ret = capmgr_thd_migrate(sl_thd_thdid(t), sl_thd_thdcap(t), core); + if (ret) return -1; + sl_mod_thd_delete(sl_mod_thd_policy_get(t)); + //ps_faa(&(sl__globals()->nthds_running[cos_cpuid()]), -1); + + x = sl_thd_migrate_backend(sl_mod_thd_policy_get(t), core); + if (!x) return -1; + + return 0; +} + +int +sl_thd_migrate(thdid_t tid, cpuid_t core) +{ + int ret; + struct sl_thd *c = sl_thd_curr(), *t = sl_thd_lkup(tid); + + if (core == cos_cpuid()) return -1; + if (sl_thd_rcvcap(t) || sl_thd_tcap(t)) return -1; + assert(c != t); + sl_cs_enter(); + ret = sl_thd_migrate_no_cs(t, core); + sl_cs_exit(); + + return ret; +} diff --git a/src/components/lib/sl_kernel/sl_raw.c b/src/components/lib/sl_kernel/sl_raw.c index 24b50dac4a..f854960a8d 100644 --- a/src/components/lib/sl_kernel/sl_raw.c +++ b/src/components/lib/sl_kernel/sl_raw.c @@ -31,8 +31,8 @@ sl_shm_map(cbuf_t id) void sl_xcpu_asnd_alloc(void) { - struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); - struct cos_compinfo *ci = cos_compinfo_get(dci); + struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); + struct cos_compinfo *ci = cos_compinfo_get(dci); int i; for (i = 0; i < NUM_CPU; i++) { @@ -93,7 +93,7 @@ sl_thd_alloc_no_cs(cos_thd_fn_t fn, void *data) aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; dcap = cos_dcb_info_alloc_curr(&doff, (vaddr_t *)&dcb); - assert(dcap); + if (dcb && doff) assert(dcap); aep->thd = cos_thd_alloc(ci, ci->comp_cap, fn, data, dcap, doff); if (!aep->thd) goto done; @@ -167,7 +167,7 @@ sl_thd_alloc_ext_dcb_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx, } static struct sl_thd * -sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, cos_channelkey_t key) +sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) { struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); struct sl_thd *t = NULL; @@ -180,7 +180,7 @@ sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, c aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; dcap = cos_dcb_info_alloc_curr(&doff, (vaddr_t *)&dcb); - assert(dcap); + if (dcb && doff) assert(dcap); /* NOTE: Cannot use stack-allocated cos_aep_info struct here */ if (prps & SL_THD_PROPERTY_OWN_TCAP) ret = cos_aep_alloc(aep, fn, data, dcap, doff); @@ -196,7 +196,7 @@ sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, c } static struct sl_thd * -sl_thd_aep_alloc_ext_dcb_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, thdclosure_index_t idx, sl_thd_property_t prps, cos_channelkey_t key, dcbcap_t dcap, dcboff_t doff, arcvcap_t *extrcv) +sl_thd_aep_alloc_ext_dcb_no_cs(struct cos_defcompinfo *comp, struct sl_thd *sched, thdclosure_index_t idx, sl_thd_property_t prps, cos_channelkey_t key, dcbcap_t dcap, dcboff_t doff, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) { struct cos_aep_info *aep = NULL; struct sl_thd *t = NULL; @@ -249,12 +249,12 @@ sl_thd_alloc(cos_thd_fn_t fn, void *data) } struct sl_thd * -sl_thd_aep_alloc(cos_aepthd_fn_t fn, void *data, int own_tcap, cos_channelkey_t key) +sl_thd_aep_alloc(cos_aepthd_fn_t fn, void *data, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) { struct sl_thd *t = NULL; sl_cs_enter(); - t = sl_thd_aep_alloc_no_cs(fn, data, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, 0); + t = sl_thd_aep_alloc_no_cs(fn, data, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, 0, ipiwin, ipimax); sl_cs_exit(); return t; @@ -276,7 +276,7 @@ sl_thd_comp_init(struct cos_defcompinfo *comp, int is_sched) } struct sl_thd * -sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, vaddr_t *dcbaddr) +sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbaddr) { PRINTC("UNIMPLEMENTED: Using RAW API which cannot manage DCB resource for child components\n"); @@ -284,7 +284,7 @@ sl_thd_initaep_alloc(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int } struct sl_thd * -sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, dcbcap_t dcap) +sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, int is_sched, int own_tcap, cos_channelkey_t key, dcbcap_t dcap, microsec_t ipiwin, u32_t ipimax) { struct sl_thd *t = NULL; @@ -293,14 +293,14 @@ sl_thd_initaep_alloc_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, sl_cs_enter(); if (!is_sched) t = sl_thd_alloc_ext_dcb_no_cs(comp, 0, dcap, 0); else t = sl_thd_aep_alloc_ext_dcb_no_cs(comp, sched_thd, 0, (is_sched ? SL_THD_PROPERTY_SEND : 0) - | (own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0), key, dcap, 0, NULL); + | (own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0), key, dcap, 0, ipiwin, ipimax, NULL); sl_cs_exit(); return t; } struct sl_thd * -sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, vaddr_t *dcbaddr, arcvcap_t *extrcv) +sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, vaddr_t *dcbaddr, arcvcap_t *extrcv) { PRINTC("UNIMPLEMENTED: Using RAW API which cannot manage DCB resource for child components\n"); @@ -308,7 +308,7 @@ sl_thd_aep_alloc_ext(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thd } struct sl_thd * -sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, dcbcap_t dcap, dcboff_t doff, arcvcap_t *extrcv) +sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, thdclosure_index_t idx, int is_aep, int own_tcap, cos_channelkey_t key, dcbcap_t dcap, dcboff_t doff, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) { struct sl_thd *t = NULL; @@ -316,7 +316,7 @@ sl_thd_aep_alloc_ext_dcb(struct cos_defcompinfo *comp, struct sl_thd *sched_thd, sl_cs_enter(); if (!is_aep) own_tcap = 0; if (is_aep) { - t = sl_thd_aep_alloc_ext_dcb_no_cs(comp, sched_thd, idx, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, key, dcap, doff, extrcv); + t = sl_thd_aep_alloc_ext_dcb_no_cs(comp, sched_thd, idx, own_tcap ? SL_THD_PROPERTY_OWN_TCAP : 0, key, dcap, doff, ipiwin, ipimax, extrcv); } else { t = sl_thd_alloc_ext_dcb_no_cs(comp, idx, dcap, doff); } @@ -348,9 +348,11 @@ sl_thd_init_ext(struct cos_aep_info *aepthd, struct sl_thd *sched) } struct sl_thd * -sl_thd_retrieve(thdid_t tid) +sl_thd_retrieve_lazy(thdid_t tid) { - return sl_mod_thd_get(sl_thd_lookup_backend(tid)); + /* without capmgr, there is no lazy retrieval of threads! */ + assert(0); + return NULL; } void @@ -362,3 +364,40 @@ sl_thd_free(struct sl_thd *t) sl_thd_free_no_cs(t); sl_cs_exit(); } + +int +sl_thd_migrate_no_cs(struct sl_thd *t, cpuid_t core) +{ + struct cos_defcompinfo *dci = cos_defcompinfo_curr_get(); + struct cos_compinfo *ci = cos_compinfo_get(dci); + struct sl_thd_policy *x = NULL; + int ret; + + if (t->properties) return -1; + if (t->state != SL_THD_RUNNABLE) return -1; + ret = cos_thd_migrate(ci, sl_thd_thdcap(t), core); + if (ret) return -1; + sl_mod_thd_delete(sl_mod_thd_policy_get(t)); + //ps_faa(&(sl__globals()->nthds_running[cos_cpuid()]), -1); + + x = sl_thd_migrate_backend(sl_mod_thd_policy_get(t), core); + if (!x) return -1; + + return 0; +} + +int +sl_thd_migrate(thdid_t tid, cpuid_t core) +{ + int ret; + struct sl_thd *c = sl_thd_curr(), *t = sl_thd_lkup(tid); + + if (core == cos_cpuid()) return -1; + assert(c != t); + sl_cs_enter(); + ret = sl_thd_migrate_no_cs(t, core); + sl_cs_exit(); + + return ret; +} + From 7c6563ded41a76cc6cad6ab8006627bc7ae803f8 Mon Sep 17 00:00:00 2001 From: WenyuanShao Date: Sun, 13 Mar 2022 23:29:31 -0400 Subject: [PATCH 4/7] fix kernel_test, part of tcap tests and async endpoints still doesn't work --- src/components/lib/kernel/cos_kernel_api.c | 1 - src/kernel/include/captbl.h | 2 +- src/kernel/include/shared/cos_types.h | 21 ++++++++------------- src/platform/i386/boot_comp.c | 14 +++++++++----- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/components/lib/kernel/cos_kernel_api.c b/src/components/lib/kernel/cos_kernel_api.c index a483ea782b..3c5ddcce63 100644 --- a/src/components/lib/kernel/cos_kernel_api.c +++ b/src/components/lib/kernel/cos_kernel_api.c @@ -776,7 +776,6 @@ cos_thd_alloc(struct cos_compinfo *ci, compcap_t comp, cos_thd_fn_t fn, void *da if (idx < 1) return 0; ret = __cos_thd_alloc(ci, comp, idx, dc, off); - printc("__cos_thd_alloc success: %d\n", ret); if (!ret) cos_thd_init_free(idx); return ret; diff --git a/src/kernel/include/captbl.h b/src/kernel/include/captbl.h index 3c1f01437b..cec4fbc063 100644 --- a/src/kernel/include/captbl.h +++ b/src/kernel/include/captbl.h @@ -513,4 +513,4 @@ cap_init(void) assert(CAPTBL_EXPAND_SZ == 1 << CAPTBL_LEAF_ORD); } -#endif /* CAPTBL_H */ \ No newline at end of file +#endif /* CAPTBL_H */ diff --git a/src/kernel/include/shared/cos_types.h b/src/kernel/include/shared/cos_types.h index 86b2c0bc5f..e99fbaa6a6 100644 --- a/src/kernel/include/shared/cos_types.h +++ b/src/kernel/include/shared/cos_types.h @@ -286,9 +286,8 @@ enum BOOT_CAPTBL_KM_PTE = 28, BOOT_CAPTBL_SINV_CAP = 32, - BOOT_CAPTBL_SELF_SCB = 36, /* FIXME: Do we need this? */ - BOOT_CAPTBL_SELF_INITHW_BASE = 40, - BOOT_CAPTBL_SELF_INITTHD_BASE = 44, + BOOT_CAPTBL_SELF_INITHW_BASE = 36, + BOOT_CAPTBL_SELF_INITTHD_BASE = 40, /* * NOTE: kernel doesn't support sharing a cache-line across cores, * so optimize to place INIT THD/TCAP on same cache line and bump by 64B for next CPU @@ -298,30 +297,26 @@ enum BOOT_CAPTBL_LAST_CAP = BOOT_CAPTBL_SELF_INITRCV_BASE + NUM_CPU * CAP64B_IDSZ, /* round up to next entry */ - BOOT_CAPTBL_FREE = round_up_to_pow2(BOOT_CAPTBL_LAST_CAP, CAPMAX_ENTRY_SZ) + BOOT_CAPTBL_FREE = round_up_to_pow2(BOOT_CAPTBL_LAST_CAP+CAPMAX_ENTRY_SZ, CAPMAX_ENTRY_SZ) }; -#define BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITTHD_BASE + cpuid * CAP64B_IDSZ) +#define BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITTHD_BASE + cpuid * CAP16B_IDSZ) #define BOOT_CAPTBL_SELF_INITTCAP_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITTCAP_BASE + cpuid * CAP16B_IDSZ) #define BOOT_CAPTBL_SELF_INITRCV_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITRCV_BASE + cpuid * CAP64B_IDSZ) -#define BOOT_CAPTBL_SELF_INITDCB_BASE_CPU(cpuid) (BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cpuid) + CAP32B_IDSZ) - -#define BOOT_CAPTBL_SELF_INITDCB_BASE (BOOT_CAPTBL_SELF_INITTHD_BASE + CAP32B_IDSZ) #define BOOT_CAPTBL_SELF_INITTHD_CPU_BASE (BOOT_CAPTBL_SELF_INITTHD_BASE_CPU(cos_cpuid())) #define BOOT_CAPTBL_SELF_INITTCAP_CPU_BASE (BOOT_CAPTBL_SELF_INITTCAP_BASE_CPU(cos_cpuid())) #define BOOT_CAPTBL_SELF_INITRCV_CPU_BASE (BOOT_CAPTBL_SELF_INITRCV_BASE_CPU(cos_cpuid())) -#define BOOT_CAPTBL_SELF_INITDCB_CPU_BASE (BOOT_CAPTBL_SELF_INITDCB_BASE_CPU(cos_cpuid())) enum llboot_scb_dcb_caps { LLBOOT_CAPTBL_SCB = round_up_to_pow2(BOOT_CAPTBL_LAST_CAP, CAPMAX_ENTRY_SZ), - LLBOOT_CAPTBL_INITDCB = LLBOOT_CAPTBL_SCB + CAP32B_IDSZ, - LLBOOT_CAPTBL_FREE = round_up_to_pow2(LLBOOT_CAPTBL_INITDCB + (CAP32B_IDSZ * NUM_CPU), CAPMAX_ENTRY_SZ), + LLBOOT_CAPTBL_INITDCB = LLBOOT_CAPTBL_SCB + CAP64B_IDSZ, + LLBOOT_CAPTBL_FREE = round_up_to_pow2(LLBOOT_CAPTBL_INITDCB + (CAP64B_IDSZ * NUM_CPU), CAPMAX_ENTRY_SZ), }; -#define LLBOOT_CAPTBL_INITDCB_CPU(cpuid) (LLBOOT_CAPTBL_INITDCB + (CAP32B_IDSZ * cpuid)) -#define LLBOOT_CAPTBL_CPU_INITDCB (LLBOOT_CAPTBL_INITDCB_CPU(cos_cpuid())) +#define LLBOOT_CAPTBL_INITDCB_CPU(cpuid) (LLBOOT_CAPTBL_INITDCB + (CAP64B_IDSZ * cpuid)) +#define LLBOOT_CAPTBL_CPU_INITDCB LLBOOT_CAPTBL_INITDCB_CPU(cos_cpuid()) /* * The half of the first page of init captbl is devoted to root node. So, the diff --git a/src/platform/i386/boot_comp.c b/src/platform/i386/boot_comp.c index 31cd0b3567..0fed49f49e 100644 --- a/src/platform/i386/boot_comp.c +++ b/src/platform/i386/boot_comp.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -324,8 +323,8 @@ kern_boot_comp(const cpuid_t cpu_id) unsigned int i; u8_t * boot_comp_captbl; pgtbl_t pgtbl = (pgtbl_t)chal_va2pa(&boot_comp_pgd), boot_vm_pgd; - u32_t hw_bitmap = ~0; + vaddr_t scb_uaddr = 0, scb_kaddr = 0; assert(cpu_id >= 0); if (NUM_CPU > 1 && cpu_id > 0) { @@ -352,6 +351,9 @@ kern_boot_comp(const cpuid_t cpu_id) assert(!ret); } + scb_kaddr = (vaddr_t)mem_boot_alloc(1); + assert(scb_kaddr); + for (i = 0; i < NUM_CPU; i++) { thd_mem[i] = mem_boot_alloc(1); assert(thd_mem[i]); @@ -382,6 +384,7 @@ kern_boot_comp(const cpuid_t cpu_id) ret = boot_elf_process(glb_boot_ct, BOOT_CAPTBL_SELF_PT, BOOT_CAPTBL_BOOTVM_PTE, "booter VM", mem_bootc_start(), mem_bootc_end() - mem_bootc_start()); assert(ret == 0); + scb_uaddr = (vaddr_t)mem_bootc_end(); /* * Map in the untyped memory. This is more complicated as we @@ -407,13 +410,14 @@ kern_boot_comp(const cpuid_t cpu_id) assert(ret == 0); + printk("\tCapability table and page-table created.\n"); + /* Shut off further bump allocations */ glb_memlayout.allocs_avail = 0; - //if (scb_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_SCB, scb_kaddr, 0)) assert(0); - printk("\tCapability table and page-table created.\n"); + if (scb_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, LLBOOT_CAPTBL_SCB, scb_kaddr, 0)) assert(0); if (comp_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_PT, - 0, 0, (vaddr_t)mem_bootc_entry(), 0)) + LLBOOT_CAPTBL_SCB, 0, (vaddr_t)mem_bootc_entry(), scb_uaddr)) assert(0); printk("\tCreated boot component structure from page-table and capability-table.\n"); From 6a7ae746fa56dc8111807fb97a088307aae47a6d Mon Sep 17 00:00:00 2001 From: WenyuanShao Date: Thu, 31 Mar 2022 16:11:22 -0400 Subject: [PATCH 5/7] enable scb creation in capmgr, still working on get dcb management working in dcb --- composition_scripts/sched.toml | 4 +- src/components/implementation/capmgr/Makefile | 2 +- .../implementation/capmgr/simple/Makefile | 2 +- .../implementation/capmgr/simple/capmgr.c | 56 ++++++++++- .../no_interface/llbooter/Makefile | 2 +- .../no_interface/llbooter/llbooter.c | 18 +++- .../implementation/sched/root_fprr/Makefile | 2 +- .../implementation/sched/root_fprr/init.c | 3 + .../tests/kernel_tests/k_test_captbl.c | 2 +- .../tests/kernel_tests/k_test_inv.c | 2 +- .../tests/kernel_tests/kernel_test_booter.c | 26 +++-- .../tests/micro_xcores/micro_xcores.c | 2 +- .../tests/unit_pingpong/Makefile | 2 +- src/components/interface/capmgr/Makefile | 2 +- src/components/interface/capmgr/capmgr.h | 24 +++-- src/components/interface/capmgr/lib.c | 4 +- .../interface/capmgr/stubs/c_stub.c | 24 +++-- .../interface/capmgr/stubs/s_stub.c | 20 +++- src/components/interface/capmgr/stubs/stubs.S | 6 +- .../lib/component/arch/x86/cos_component.h | 5 +- src/components/lib/crt/crt.c | 25 ++++- src/components/lib/crt/crt.h | 1 + src/components/lib/dcb/cos_dcb.c | 96 ------------------- src/components/lib/dcb/cos_dcb.h | 28 ------ src/components/lib/kernel/cos_defkernel_api.c | 2 +- src/components/lib/kernel/cos_kernel_api.c | 34 +++++-- src/components/lib/kernel/cos_kernel_api.h | 9 +- src/components/lib/sl/Makefile | 2 +- src/components/lib/sl_capmgr/Makefile | 2 +- src/components/lib/sl_capmgr/sl_capmgr.c | 11 ++- src/components/lib/sl_kernel/Makefile | 2 +- src/components/lib/sl_kernel/sl_raw.c | 12 ++- src/kernel/capinv.c | 45 ++++++++- src/kernel/include/component.h | 4 +- src/kernel/include/scb.h | 18 +++- src/kernel/include/shared/cos_types.h | 1 + src/platform/i386/boot_comp.c | 4 +- 37 files changed, 284 insertions(+), 220 deletions(-) delete mode 100644 src/components/lib/dcb/cos_dcb.c delete mode 100644 src/components/lib/dcb/cos_dcb.h diff --git a/composition_scripts/sched.toml b/composition_scripts/sched.toml index 2e6d05e6b2..42fc9cc7ae 100644 --- a/composition_scripts/sched.toml +++ b/composition_scripts/sched.toml @@ -4,14 +4,14 @@ description = "Simplest system with both capability manager and scheduler, from [[components]] name = "booter" img = "no_interface.llbooter" -implements = [{interface = "init"}, {interface = "addr"}] +implements = [{interface = "init"}, {interface = "addr"}, {interface = "scb_mapping"}] deps = [{srv = "kernel", interface = "init", variant = "kernel"}] constructor = "kernel" [[components]] name = "capmgr" img = "capmgr.simple" -deps = [{srv = "booter", interface = "init"}, {srv = "booter", interface = "addr"}] +deps = [{srv = "booter", interface = "init"}, {srv = "booter", interface = "addr"}, {srv = "booter", interface = "scb_mapping"}] implements = [{interface = "capmgr"}, {interface = "init"}, {interface = "memmgr"}, {interface = "capmgr_create"}] constructor = "booter" diff --git a/src/components/implementation/capmgr/Makefile b/src/components/implementation/capmgr/Makefile index 72bb34a16b..8925e464d4 100644 --- a/src/components/implementation/capmgr/Makefile +++ b/src/components/implementation/capmgr/Makefile @@ -9,7 +9,7 @@ INTERFACE_EXPORTS = capmgr INTERFACE_DEPENDENCIES = # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = component +LIBRARY_DEPENDENCIES = component dcb # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/implementation/capmgr/simple/Makefile b/src/components/implementation/capmgr/simple/Makefile index 6c5aa6bfa9..77d8326a62 100644 --- a/src/components/implementation/capmgr/simple/Makefile +++ b/src/components/implementation/capmgr/simple/Makefile @@ -9,7 +9,7 @@ INTERFACE_EXPORTS = capmgr capmgr_create init INTERFACE_DEPENDENCIES = init addr # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = component sl_kernel initargs crt util +LIBRARY_DEPENDENCIES = component sl_kernel initargs crt util dcb # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/implementation/capmgr/simple/capmgr.c b/src/components/implementation/capmgr/simple/capmgr.c index 97aae38349..eb10a74326 100644 --- a/src/components/implementation/capmgr/simple/capmgr.c +++ b/src/components/implementation/capmgr/simple/capmgr.c @@ -16,6 +16,7 @@ #include #include #include +#include struct cm_rcv { struct crt_rcv rcv; @@ -41,6 +42,11 @@ struct cm_asnd { struct crt_asnd asnd; }; +struct cm_dcb { + dcbcap_t dcb_cap; + vaddr_t dcb_addr; +}; + /* * Shared memory should be manager -> client, and between * point-to-point channel recipients @@ -76,6 +82,9 @@ SS_STATIC_SLAB(asnd, struct cm_asnd, MAX_NUM_THREADS); SS_STATIC_SLAB(page, struct mm_page, MM_NPAGES); SS_STATIC_SLAB(span, struct mm_span, MM_NPAGES); +#define MAX_DCB_NUM PAGE_SIZE/sizeof(struct cos_dcb_info) +SS_STATIC_SLAB(dcb, struct cm_dcb, MAX_DCB_NUM); + static struct cm_comp * cm_self(void) { @@ -155,6 +164,18 @@ cm_thd_alloc_in(struct cm_comp *c, struct cm_comp *sched, thdclosure_index_t clo return t; } +struct cm_dcb * +cm_dcb_alloc_in(struct cm_comp *sched) +{ + compid_t id = (compid_t)cos_inv_token(); + struct cm_dcb *d = ss_dcb_alloc_at_id(id); + + d->dcb_cap = crt_dcb_create_in(sched, &d->dcb_addr); + + ss_dcb_activate(d); + return d; +} + /** * Allocate a page from the pool of physical memory into a component. * @@ -339,6 +360,24 @@ capmgr_comp_sched_get(compid_t cid) return atoi(sched); } +extern scbcap_t scb_mapping(compid_t id); + +int +capmgr_scb_mapping(void) +{ + compid_t schedid = (compid_t)cos_inv_token(); + printc("\tschedid: %d\n", schedid); + struct cm_comp *s; + struct cos_compinfo *ci; + + s = ss_comp_get(schedid); + assert(s); + + ci = cos_compinfo_get(s->comp.comp_res); + assert(ci); + return scb_mapping(schedid); +} + static void capmgr_comp_init(void) { @@ -500,6 +539,7 @@ capmgr_thd_create_ext(spdid_t client, thdclosure_index_t idx, thdid_t *tid) compid_t schedid = (compid_t)cos_inv_token(); struct cm_thd *t; struct cm_comp *s, *c; + struct cm_dcb *d; if (schedid != capmgr_comp_sched_get(client)) { /* don't have permission to create execution in that component. */ @@ -510,6 +550,9 @@ capmgr_thd_create_ext(spdid_t client, thdclosure_index_t idx, thdid_t *tid) c = ss_comp_get(client); s = ss_comp_get(schedid); + + d = cm_dcb_alloc_in(s); + if (!c || !s) return 0; t = cm_thd_alloc_in(c, s, idx); if (!t) { @@ -530,20 +573,25 @@ capmgr_initthd_create(spdid_t client, thdid_t *tid) thdcap_t capmgr_initaep_create(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret) { BUG(); return 0; } thdcap_t -capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb) +capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb) { compid_t client = (compid_t)cos_inv_token(); - struct cm_thd *t; + struct cm_thd *t; struct cm_comp *c; + struct cm_dcb *d; assert(client > 0 && client <= MAX_NUM_COMPS); c = ss_comp_get(client); + d = cm_dcb_alloc_in(c); + assert(d); t = cm_thd_alloc_in(c, c, idx); + if (!t) { /* TODO: release resources */ return 0; } *tid = t->thd.tid; + dcb = (struct cos_dcb_info *)d->dcb_addr; return t->aliased_cap; } @@ -581,8 +629,10 @@ cos_init(void) if (!cm_comp_self_alloc("capmgr")) BUG(); /* Initialize the other component's for which we're responsible */ + scbcap_t scbc = cos_scb_alloc(ci); + assert(scbc); + if (cos_scb_mapping(ci, ci->comp_cap, ci->pgtbl_cap, scbc)) BUG(); capmgr_comp_init(); - sl_init(SL_MIN_PERIOD_US); return; diff --git a/src/components/implementation/no_interface/llbooter/Makefile b/src/components/implementation/no_interface/llbooter/Makefile index 4ea23edb09..8dd9a68ef2 100644 --- a/src/components/implementation/no_interface/llbooter/Makefile +++ b/src/components/implementation/no_interface/llbooter/Makefile @@ -3,7 +3,7 @@ # # The set of interfaces that this component exports for use by other # components. This is a list of the interface names. -INTERFACE_EXPORTS = init addr +INTERFACE_EXPORTS = init addr scb_mapping # The interfaces this component is dependent on for compilation (this # is a list of directory names in interface/) INTERFACE_DEPENDENCIES = init diff --git a/src/components/implementation/no_interface/llbooter/llbooter.c b/src/components/implementation/no_interface/llbooter/llbooter.c index 188cbd4d4f..2d570be13b 100644 --- a/src/components/implementation/no_interface/llbooter/llbooter.c +++ b/src/components/implementation/no_interface/llbooter/llbooter.c @@ -17,6 +17,7 @@ #include #include +#include #ifndef BOOTER_MAX_SINV #define BOOTER_MAX_SINV 256 @@ -411,6 +412,21 @@ addr_get(compid_t id, addr_t type) } } +int +scb_mapping(compid_t id) +{ + struct cos_compinfo *ci; + struct crt_comp *target; + + target = boot_comp_get(id); + + ci = cos_compinfo_get(target->comp_res); + + if (cos_scb_mapping(ci, ci->comp_cap, ci->pgtbl_cap, ci->scb_cap)) BUG(); + return 0; +} + + static void booter_init(void) { @@ -418,7 +434,7 @@ booter_init(void) cos_meminfo_init(&(boot_info->mi), BOOT_MEM_KM_BASE, COS_MEM_KERN_PA_SZ, BOOT_CAPTBL_SELF_UNTYPED_PT); cos_defcompinfo_init(); - + if (cos_scb_mapping(boot_info, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_PT, LLBOOT_CAPTBL_SCB)) BUG(); cos_hw_cycles_per_usec(BOOT_CAPTBL_SELF_INITHW_BASE); } diff --git a/src/components/implementation/sched/root_fprr/Makefile b/src/components/implementation/sched/root_fprr/Makefile index ad4a79925a..327c6bebe0 100644 --- a/src/components/implementation/sched/root_fprr/Makefile +++ b/src/components/implementation/sched/root_fprr/Makefile @@ -9,7 +9,7 @@ INTERFACE_EXPORTS = sched init INTERFACE_DEPENDENCIES = capmgr # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = component sl_capmgr +LIBRARY_DEPENDENCIES = component sl_capmgr dcb # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/implementation/sched/root_fprr/init.c b/src/components/implementation/sched/root_fprr/init.c index db98616b61..4000af28cd 100644 --- a/src/components/implementation/sched/root_fprr/init.c +++ b/src/components/implementation/sched/root_fprr/init.c @@ -73,6 +73,8 @@ static compid_t init_schedule[MAX_NUM_COMPS] = { 0 }; /* internalizer threads simply orchestrate the initialization */ static struct sl_thd *__initializer_thd[NUM_CPU] CACHE_ALIGNED; +extern int capmgr_scb_mapping(void); + void schedinit_next(compid_t cid) { @@ -233,6 +235,7 @@ cos_init(void) cos_meminfo_init(&(ci->mi), BOOT_MEM_KM_BASE, COS_MEM_KERN_PA_SZ, BOOT_CAPTBL_SELF_UNTYPED_PT); cos_defcompinfo_init(); cos_init_args_cpubmp(cpubmp); + if (capmgr_scb_mapping()) BUG(); } void diff --git a/src/components/implementation/tests/kernel_tests/k_test_captbl.c b/src/components/implementation/tests/kernel_tests/k_test_captbl.c index d1d3d18551..1f0dadfd90 100644 --- a/src/components/implementation/tests/kernel_tests/k_test_captbl.c +++ b/src/components/implementation/tests/kernel_tests/k_test_captbl.c @@ -17,7 +17,7 @@ test_captbl_expands(void) int i; compcap_t cc; - cc = cos_comp_alloc(&booter_info, booter_info.captbl_cap, booter_info.pgtbl_cap, 0, (vaddr_t)NULL, (vaddr_t)NULL); + cc = cos_comp_alloc(&booter_info, booter_info.captbl_cap, booter_info.pgtbl_cap, 0, (vaddr_t)NULL); if (EXPECT_LL_LT(1, cc, "Capability Table Expansion")) { return; } diff --git a/src/components/implementation/tests/kernel_tests/k_test_inv.c b/src/components/implementation/tests/kernel_tests/k_test_inv.c index d465099990..6e0b59ee98 100644 --- a/src/components/implementation/tests/kernel_tests/k_test_inv.c +++ b/src/components/implementation/tests/kernel_tests/k_test_inv.c @@ -88,7 +88,7 @@ test_inv(void) perfdata_init(&result, "SINV", test_results, ARRAY_SIZE); - cc = cos_comp_alloc(&booter_info, booter_info.captbl_cap, booter_info.pgtbl_cap, 0, (vaddr_t)NULL, (vaddr_t)NULL); + cc = cos_comp_alloc(&booter_info, booter_info.captbl_cap, booter_info.pgtbl_cap, 0, (vaddr_t)NULL); if (EXPECT_LL_LT(1, cc, "Invocation: Cannot Allocate")) return; ic = cos_sinv_alloc(&booter_info, cc, (vaddr_t)__inv_test_serverfn, 0xdead); if (EXPECT_LL_LT(1, ic, "Invocation: Cannot Allocate")) return; diff --git a/src/components/implementation/tests/kernel_tests/kernel_test_booter.c b/src/components/implementation/tests/kernel_tests/kernel_test_booter.c index 2b55cff77e..351970c4d0 100644 --- a/src/components/implementation/tests/kernel_tests/kernel_test_booter.c +++ b/src/components/implementation/tests/kernel_tests/kernel_test_booter.c @@ -27,8 +27,22 @@ cos_init(void) cos_hw_cycles_per_usec(BOOT_CAPTBL_SELF_INITHW_BASE); cos_meminfo_init(&booter_info.mi, BOOT_MEM_KM_BASE, COS_MEM_KERN_PA_SZ, BOOT_CAPTBL_SELF_UNTYPED_PT); - cos_compinfo_init(&booter_info, BOOT_CAPTBL_SELF_PT, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, + //scbcap_t scbc = cos_scb_alloc(&booter_info); + cos_compinfo_init(&booter_info, BOOT_CAPTBL_SELF_PT, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, LLBOOT_CAPTBL_SCB, (vaddr_t)cos_get_heap_ptr(), BOOT_CAPTBL_FREE, &booter_info); + cos_scb_mapping(&booter_info, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_PT, LLBOOT_CAPTBL_SCB); +} + +void +test_scb(void) +{ + thdcap_t thdc; + struct cos_scb_info *scb_info = cos_scb_info_get(); + + scb_info->curr_thd = BOOT_CAPTBL_SELF_INITTHD_CPU_BASE; + thdc = cos_introspect(&booter_info, booter_info.comp_cap, COMP_GET_SCB_CURTHD); + if (thdc == (thdcap_t)BOOT_CAPTBL_SELF_INITTHD_CPU_BASE) PRINTC("Success: Kernel and user have consistent thdcap set in SCB\n"); + else PRINTC("Failure: Kernel and user don't have a consistent thdcap in SCB\n"); } void @@ -37,22 +51,14 @@ test_run_unit_kernel(void) /* Kernel Tests */ printc("\n"); PRINTC("Unit Test Started:\n\n"); - PRINTC("timer:\n"); + test_scb(); test_timer(); - PRINTC("test_tcap_budgets: \n"); test_tcap_budgets(); - PRINTC("2timers:\n"); - test_2timers(); test_2timers(); - PRINTC("thds:\n"); test_thds(); - PRINTC("mem_alloc:\n"); test_mem_alloc(); - PRINTC("endpoints:\n"); test_async_endpoints(); - PRINTC("inv:\n"); test_inv(); - PRINTC("captbl_expands:\n"); test_captbl_expands(); } diff --git a/src/components/implementation/tests/micro_xcores/micro_xcores.c b/src/components/implementation/tests/micro_xcores/micro_xcores.c index 1bd98c126c..87865b3004 100644 --- a/src/components/implementation/tests/micro_xcores/micro_xcores.c +++ b/src/components/implementation/tests/micro_xcores/micro_xcores.c @@ -29,7 +29,7 @@ cos_init(void) if (first_init) { first_init = 0; cos_meminfo_init(&booter_info.mi, BOOT_MEM_KM_BASE, COS_MEM_KERN_PA_SZ, BOOT_CAPTBL_SELF_UNTYPED_PT); - cos_compinfo_init(&booter_info, BOOT_CAPTBL_SELF_PT, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, + cos_compinfo_init(&booter_info, BOOT_CAPTBL_SELF_PT, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, 0, (vaddr_t)cos_get_heap_ptr(), BOOT_CAPTBL_FREE, &booter_info); init_done = 1; } diff --git a/src/components/implementation/tests/unit_pingpong/Makefile b/src/components/implementation/tests/unit_pingpong/Makefile index 6a48f05d9d..5b033dc93c 100644 --- a/src/components/implementation/tests/unit_pingpong/Makefile +++ b/src/components/implementation/tests/unit_pingpong/Makefile @@ -9,7 +9,7 @@ INTERFACE_EXPORTS = INTERFACE_DEPENDENCIES = init pong # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = kernel ps +LIBRARY_DEPENDENCIES = kernel ps dcb # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/interface/capmgr/Makefile b/src/components/interface/capmgr/Makefile index d53ead973c..1ba243b30c 100644 --- a/src/components/interface/capmgr/Makefile +++ b/src/components/interface/capmgr/Makefile @@ -21,7 +21,7 @@ INCLUDE_PATHS = . INTERFACE_DEPENDENCIES = # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = kernel stubs +LIBRARY_DEPENDENCIES = kernel stubs dcb # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/interface/capmgr/capmgr.h b/src/components/interface/capmgr/capmgr.h index ae5a45cbb9..b0fd9cdbbf 100644 --- a/src/components/interface/capmgr/capmgr.h +++ b/src/components/interface/capmgr/capmgr.h @@ -28,20 +28,20 @@ thdcap_t COS_STUB_DECL(capmgr_initthd_create)(spdid_t child, thdid_t *tid); thdcap_t capmgr_initaep_create(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret); thdcap_t COS_STUB_DECL(capmgr_initaep_create)(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret); -thdcap_t capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info **dcb); -thdcap_t capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); +thdcap_t capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info *dcb); +thdcap_t capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb); -thdcap_t capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); -thdcap_t COS_STUB_DECL(capmgr_thd_create_thunk)(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); +thdcap_t capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb); +thdcap_t COS_STUB_DECL(capmgr_thd_create_thunk)(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb); -thdcap_t capmgr_aep_create_thunk(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); -thdcap_t COS_STUB_DECL(capmgr_aep_create_thunk)(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); +thdcap_t capmgr_aep_create_thunk(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb); +thdcap_t COS_STUB_DECL(capmgr_aep_create_thunk)(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb); -thdcap_t capmgr_thd_create_ext(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); -thdcap_t COS_STUB_DECL(capmgr_thd_create_ext)(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); +thdcap_t capmgr_thd_create_ext(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb); +thdcap_t COS_STUB_DECL(capmgr_thd_create_ext)(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb); -thdcap_t capmgr_aep_create_ext(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv); -thdcap_t COS_STUB_DECL(capmgr_aep_create_ext)(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv); +thdcap_t capmgr_aep_create_ext(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb, arcvcap_t *extrcv); +thdcap_t COS_STUB_DECL(capmgr_aep_create_ext)(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb, arcvcap_t *extrcv); thdcap_t capmgr_thd_retrieve(spdid_t child, thdid_t t, thdid_t *inittid); thdcap_t capmgr_thd_retrieve_next(spdid_t child, thdid_t *tid); @@ -55,9 +55,13 @@ asndcap_t COS_STUB_DECL(capmgr_asnd_create)(spdid_t child, thdid_t t); asndcap_t capmgr_asnd_rcv_create(arcvcap_t rcv); asndcap_t COS_STUB_DECL(capmgr_asnd_rcv_create)(arcvcap_t rcv); +int capmgr_scb_mapping(void); +int COS_STUB_DECL(capmgr_scb_mapping)(void); + asndcap_t capmgr_asnd_key_create(cos_channelkey_t key); asndcap_t COS_STUB_DECL(capmgr_asnd_key_create)(cos_channelkey_t key); int capmgr_thd_migrate(thdid_t tid, thdcap_t tc, cpuid_t core); + #endif /* CAPMGR_H */ diff --git a/src/components/interface/capmgr/lib.c b/src/components/interface/capmgr/lib.c index e000076387..f6df4210c9 100644 --- a/src/components/interface/capmgr/lib.c +++ b/src/components/interface/capmgr/lib.c @@ -2,7 +2,7 @@ #include thdcap_t -capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info **dcb) +capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info *dcb) { thdclosure_index_t idx = cos_thd_init_alloc(fn, data); @@ -12,7 +12,7 @@ capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info } thdcap_t -capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb) +capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb) { thdclosure_index_t idx = cos_thd_init_alloc(cos_aepthd_fn, (void *)a); diff --git a/src/components/interface/capmgr/stubs/c_stub.c b/src/components/interface/capmgr/stubs/c_stub.c index d197729476..b30811bff8 100644 --- a/src/components/interface/capmgr/stubs/c_stub.c +++ b/src/components/interface/capmgr/stubs/c_stub.c @@ -21,6 +21,14 @@ COS_CLIENT_STUB(arcvcap_t, capmgr_rcv_create, spdid_t child, thdid_t tid, cos_ch return cos_sinv(uc->cap_no, spd_tid, key_ipimax, ipiwin32b, 0); } +/*COS_CLIENT_STUB(scbcap_t, capmgr_scb_mapping, spdid_t child) +{ + COS_CLIENT_INVCAP; + word_t spd_tid = (u32_t)child; + + return cos_sinv(uc->cap_no, child, 0, 0, 0); +} + COS_CLIENT_STUB(thdcap_t, capmgr_thd_retrieve, spdid_t child, thdid_t tid, thdid_t *inittid) { COS_CLIENT_INVCAP; @@ -43,7 +51,7 @@ COS_CLIENT_STUB(thdcap_t, capmgr_thd_retrieve_next, spdid_t child, thdid_t *tid) *tid = tid_ret; return ret; -} +}*/ COS_CLIENT_STUB(thdcap_t, capmgr_initthd_create, spdid_t child, thdid_t *tid) { @@ -57,32 +65,32 @@ COS_CLIENT_STUB(thdcap_t, capmgr_initthd_create, spdid_t child, thdid_t *tid) return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_thunk, thdclosure_index_t id, thdid_t *tid, struct cos_dcb_info **dcb) +COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_thunk, thdclosure_index_t id, thdid_t *tid, struct cos_dcb_info *dcb) { COS_CLIENT_INVCAP; word_t dcb_ret, tid_ret; thdcap_t ret; ret = cos_sinv_2rets(uc->cap_no, id, 0, 0, 0, &tid_ret, &dcb_ret); - *dcb = &dcb_ret; + dcb = dcb_ret; *tid = tid_ret; return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_ext, spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb) +COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_ext, spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb) { COS_CLIENT_INVCAP; word_t dcb_ret, tid_ret; thdcap_t ret; ret = cos_sinv_2rets(uc->cap_no, child, idx, 0, 0, &tid_ret, &dcb_ret); - *dcb = &dcb_ret; + dcb = dcb_ret; return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb) +COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb) { COS_CLIENT_INVCAP; word_t tcrcvret = 0; @@ -107,13 +115,13 @@ COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thd aep->tc = (tcrcvret >> 16); aep->tid = tid; - *dcb = &dcb_ret; + dcb = dcb_ret; return thd; } /* FIXME: Won't work now */ -COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_ext, spdid_t child, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv) +COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_ext, spdid_t child, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb, arcvcap_t *extrcv) { COS_CLIENT_INVCAP; word_t drcvtidret = 0; diff --git a/src/components/interface/capmgr/stubs/s_stub.c b/src/components/interface/capmgr/stubs/s_stub.c index ea0fe71d91..d7efeeca9a 100644 --- a/src/components/interface/capmgr/stubs/s_stub.c +++ b/src/components/interface/capmgr/stubs/s_stub.c @@ -13,6 +13,16 @@ COS_SERVER_3RET_STUB(arcvcap_t, capmgr_rcv_create) return capmgr_rcv_create(child, tid, key, ipiwin, ipimax); } +/*COS_SERVER_3RET_STUB(scbcap_t, capmgr_scb_mapping) +{ + spdid_t child = p0; + scbcap_t ret; + + ret = capmgr_scb_mapping(child); + + return ret; +} + COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_retrieve) { thdid_t retthd = 0; @@ -33,12 +43,12 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_retrieve_next) *r1 = retthd; return ret; -} +}*/ COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_thunk) { thdid_t retthd = 0; - struct cos_dcb_info *retdcb; + struct cos_dcb_info retdcb; thdcap_t ret; ret = capmgr_thd_create_thunk(p0, &retthd, &retdcb); @@ -51,7 +61,7 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_thunk) COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_ext) { thdid_t retthd = 0; - struct cos_dcb_info *retdcb; + struct cos_dcb_info retdcb; thdcap_t ret; ret = capmgr_thd_create_ext(p0, p1, &retthd, &retdcb); @@ -98,7 +108,7 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_aep_create_thunk) u32_t ipimax = (p1 << 16) >> 16; u32_t ipiwin32b = (u32_t)p2; struct cos_aep_info aep; - struct cos_dcb_info *dcb; + struct cos_dcb_info dcb; asndcap_t snd; thdcap_t thdtidret; @@ -119,7 +129,7 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_aep_create_ext) microsec_t ipiwin = p3; u32_t ipimax = ((p2 << 16) >> 16); arcvcap_t extrcv = 0; - struct cos_dcb_info *dcbret; + struct cos_dcb_info dcbret; thdcap_t ret; ret = capmgr_aep_create_ext(child, &aep, idx, owntc, key, ipiwin, ipimax, &dcbret, &extrcv); diff --git a/src/components/interface/capmgr/stubs/stubs.S b/src/components/interface/capmgr/stubs/stubs.S index 4d8df14b18..6999b31416 100644 --- a/src/components/interface/capmgr/stubs/stubs.S +++ b/src/components/interface/capmgr/stubs/stubs.S @@ -7,8 +7,8 @@ #include -cos_asm_stub_indirect(capmgr_thd_retrieve) -cos_asm_stub_indirect(capmgr_thd_retrieve_next) +//cos_asm_stub_indirect(capmgr_thd_retrieve) +//cos_asm_stub_indirect(capmgr_thd_retrieve_next) cos_asm_stub_indirect(capmgr_initthd_create) cos_asm_stub_indirect(capmgr_thd_create_thunk) @@ -20,6 +20,8 @@ cos_asm_stub_indirect(capmgr_aep_create_ext) cos_asm_stub_indirect(capmgr_rcv_create) +cos_asm_stub(capmgr_scb_mapping) cos_asm_stub(capmgr_asnd_create) cos_asm_stub(capmgr_asnd_rcv_create) cos_asm_stub(capmgr_asnd_key_create) + diff --git a/src/components/lib/component/arch/x86/cos_component.h b/src/components/lib/component/arch/x86/cos_component.h index b5d4d25aba..cbd2a25e7f 100644 --- a/src/components/lib/component/arch/x86/cos_component.h +++ b/src/components/lib/component/arch/x86/cos_component.h @@ -258,8 +258,9 @@ static inline void * cos_get_heap_ptr(void) { /* page at heap_ptr is actually the SCB_PAGE for any component. */ - unsigned int off = COS_SCB_SIZE + (PAGE_SIZE * NUM_CPU); - void *heap_ptr = (void *)(__cosrt_comp_info.cos_heap_ptr + off); + //unsigned int off = COS_SCB_SIZE + (PAGE_SIZE * NUM_CPU); + //void *heap_ptr = (void *)(__cosrt_comp_info.cos_heap_ptr + off); + void *heap_ptr = (void *)(__cosrt_comp_info.cos_heap_ptr); return heap_ptr; } diff --git a/src/components/lib/crt/crt.c b/src/components/lib/crt/crt.c index cb23911ac5..a2c8d9928b 100644 --- a/src/components/lib/crt/crt.c +++ b/src/components/lib/crt/crt.c @@ -217,7 +217,7 @@ crt_comp_create_with(struct crt_comp *c, char *name, compid_t id, struct crt_com if (crt_comp_init(c, name, id, NULL, r->info)) BUG(); cos_compinfo_init(cos_compinfo_get(c->comp_res), - r->ptc, r->ctc, r->compc, r->heap_ptr, r->captbl_frontier, + r->ptc, r->ctc, r->compc, 0, r->heap_ptr, r->captbl_frontier, cos_compinfo_get(cos_defcompinfo_curr_get())); return 0; } @@ -332,8 +332,10 @@ crt_comp_create(struct crt_comp *c, char *name, compid_t id, void *elf_hdr, vadd printc("\t\t elf obj: ro [0x%lx, 0x%lx), data [0x%lx, 0x%lx), bss [0x%lx, 0x%lx).\n", c->ro_addr, c->ro_addr + ro_sz, c->rw_addr, c->rw_addr + data_sz, c->rw_addr + data_sz, c->rw_addr + data_sz + bss_sz); - - ret = cos_compinfo_alloc(ci, 0, c->ro_addr, BOOT_CAPTBL_FREE, c->entry_addr, root_ci); + + /* FIXME: This is a hack making every component has SCB by default. */ + scbcap_t scbc = cos_scb_alloc(root_ci); + ret = cos_compinfo_alloc(ci, scbc, c->ro_addr, BOOT_CAPTBL_FREE, c->entry_addr, root_ci); assert(!ret); tot_sz = round_up_to_page(round_up_to_page(ro_sz) + data_sz + bss_sz); @@ -362,6 +364,8 @@ crt_comp_create(struct crt_comp *c, char *name, compid_t id, void *elf_hdr, vadd /* FIXME: cos_time.h assumes we have access to this... */ ret = cos_cap_cpy_at(ci, BOOT_CAPTBL_SELF_INITHW_BASE, root_ci, BOOT_CAPTBL_SELF_INITHW_BASE); assert(ret == 0); + //ret = cos_scb_mapping(ci, ci->comp_cap, ci->pgtbl_cap, scbc); + //assert(ret == 0); return 0; } @@ -1303,3 +1307,18 @@ crt_compinit_exit(struct crt_comp *c, int retval) while (1) ; } +dcbcap_t +crt_dcb_create_in(struct crt_comp *c, vaddr_t *dcb_addr) +{ + struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); + struct cos_compinfo *ci = cos_compinfo_get(defci); + struct cos_compinfo *target_ci = cos_compinfo_get(c->comp_res); + dcbcap_t dcb_cap; + + dcb_addr = cos_page_bump_intern_valloc(target_ci, PAGE_SIZE); + assert(dcb_addr); + dcb_cap = cos_dcb_alloc(ci, target_ci->pgtbl_cap, dcb_addr); + assert(dcb_cap); + + return dcb_cap; +} diff --git a/src/components/lib/crt/crt.h b/src/components/lib/crt/crt.h index 6877ed59cc..18408c98e0 100644 --- a/src/components/lib/crt/crt.h +++ b/src/components/lib/crt/crt.h @@ -213,5 +213,6 @@ void crt_compinit_exit(struct crt_comp *c, int retval); int crt_chkpt_create(struct crt_chkpt *chkpt, struct crt_comp *c); int crt_chkpt_restore(struct crt_chkpt *chkpt, struct crt_comp *c); +dcbcap_t crt_dcb_create_in(struct crt_comp *c, vaddr_t *dcb_addr); #endif /* CRT_H */ diff --git a/src/components/lib/dcb/cos_dcb.c b/src/components/lib/dcb/cos_dcb.c deleted file mode 100644 index e73069af8f..0000000000 --- a/src/components/lib/dcb/cos_dcb.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include - -static struct cos_dcbinfo_data _cos_dcbinfo[NUM_CPU]; - -void -cos_dcb_info_init_ext(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci, - dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t start_off) -{ - memset(cdi, 0, sizeof(struct cos_dcbinfo_data)); - - cdi->dcbcaps[0] = initdcbcap; - cdi->dcbaddr[0] = initdcbaddr; - cdi->curr_cap_off = start_off; - cdi->curr_cap = 0; -} - -void -cos_dcb_info_init(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci) -{ - if (cos_spd_id() == 0) { - cos_dcb_info_init_ext(cdi, ci, LLBOOT_CAPTBL_CPU_INITDCB, - (vaddr_t)cos_init_dcb_get(), 1); - } else { - cos_dcb_info_init_ext(cdi, ci, 0, 0, 0); - } -} - -void -cos_dcb_info_init_curr(void) -{ - cos_dcb_info_init_curr_ext(0, 0, 0); -} - -void -cos_dcb_info_init_curr_ext(dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t st_off) -{ - struct cos_compinfo *ci = cos_compinfo_get(cos_defcompinfo_curr_get()); - - if (initdcbcap == 0 && initdcbaddr == 0) { - - if (cos_spd_id() == 0) { - cos_dcb_info_init_ext(&_cos_dcbinfo[cos_cpuid()], ci, - LLBOOT_CAPTBL_CPU_INITDCB, (vaddr_t)cos_init_dcb_get(), 1); - - return; - } else { - initdcbaddr = cos_page_bump_intern_valloc(ci, PAGE_SIZE); - assert(initdcbaddr); - initdcbcap = cos_dcb_alloc(ci, ci->pgtbl_cap, initdcbaddr); - assert(initdcbcap); - st_off = 0; - } - } - cos_dcb_info_init_ext(&_cos_dcbinfo[cos_cpuid()], ci, initdcbcap, initdcbaddr, st_off); -} - -dcbcap_t -cos_dcb_info_alloc_curr(dcboff_t *dcboff, vaddr_t *dcbaddr) -{ - return cos_dcb_info_alloc(&_cos_dcbinfo[cos_cpuid()], dcboff, dcbaddr); -} - -dcbcap_t -cos_dcb_info_alloc(struct cos_dcbinfo_data *cdi, dcboff_t *dcboff, vaddr_t *dcbaddr) -{ - if (unlikely(cdi->dcbcaps[cdi->curr_cap] == 0)) { - *dcboff = 0; - *dcbaddr = 0; - - return 0; - } - if (cdi->curr_cap_off >= COS_DCB_PERPG_MAX) { - int ret; - unsigned short curr_off = cdi->curr_cap; - - assert(curr_off + 1 < (unsigned short)COS_DCB_MAX_CAPS && cdi->dcbcaps[curr_off + 1] == 0); - - cdi->dcbaddr[curr_off + 1] = cos_page_bump_intern_valloc(cdi->ci, PAGE_SIZE); - assert(cdi->dcbaddr[curr_off + 1]); - cdi->dcbcaps[curr_off + 1] = cos_dcb_alloc(cos_compinfo_get(cos_defcompinfo_curr_get()), - cdi->ci->pgtbl_cap, cdi->dcbaddr[curr_off + 1]); - - assert(cdi->dcbcaps[curr_off + 1]); - ret = ps_cas((unsigned long *)&cdi->curr_cap, curr_off, curr_off + 1); - assert(ret); - ret = ps_cas((unsigned long *)&cdi->curr_cap_off, cdi->curr_cap_off, 0); - assert(ret); - } - - *dcboff = ps_faa((unsigned long *)&cdi->curr_cap_off, 1); - *dcbaddr = cdi->dcbaddr[cdi->curr_cap] + (sizeof(struct cos_dcb_info) * (*dcboff)); - - return cdi->dcbcaps[cdi->curr_cap]; -} diff --git a/src/components/lib/dcb/cos_dcb.h b/src/components/lib/dcb/cos_dcb.h deleted file mode 100644 index 1fc6298da6..0000000000 --- a/src/components/lib/dcb/cos_dcb.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef COS_DCB_H -#define COS_DCB_H - -#include -#include - -#define COS_DCB_PERPG_MAX (PAGE_SIZE / sizeof(struct cos_dcb_info)) - -#define COS_DCB_MAX_CAPS (MAX_NUM_THREADS / COS_DCB_PERPG_MAX + 1) - -struct cos_dcbinfo_data { - dcbcap_t dcbcaps[COS_DCB_MAX_CAPS]; - vaddr_t dcbaddr[COS_DCB_MAX_CAPS]; - dcboff_t curr_cap_off; - unsigned short curr_cap; - - struct cos_compinfo *ci; -} CACHE_ALIGNED; - -void cos_dcb_info_init(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci); -void cos_dcb_info_init_ext(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci, dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t start_off); -dcbcap_t cos_dcb_info_alloc(struct cos_dcbinfo_data *cdi, dcboff_t *dcboff, vaddr_t *dcbaddr); - -void cos_dcb_info_init_curr(void); -void cos_dcb_info_init_curr_ext(dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t st_off); -dcbcap_t cos_dcb_info_alloc_curr(dcboff_t *dcboff, vaddr_t *dcbaddr); - -#endif /* COS_DCB_H */ diff --git a/src/components/lib/kernel/cos_defkernel_api.c b/src/components/lib/kernel/cos_defkernel_api.c index f367ca25fc..3ae0c5e7f4 100644 --- a/src/components/lib/kernel/cos_defkernel_api.c +++ b/src/components/lib/kernel/cos_defkernel_api.c @@ -59,7 +59,7 @@ cos_defcompinfo_init_ext(tcap_t sched_tc, thdcap_t sched_thd, arcvcap_t sched_rc if (curr_defci_init_status == INITIALIZED) return; - cos_compinfo_init(ci, pgtbl_cap, captbl_cap, comp_cap, heap_ptr, cap_frontier, ci); + cos_compinfo_init(ci, pgtbl_cap, captbl_cap, comp_cap, 0, heap_ptr, cap_frontier, ci); curr_defci_init_status = INITIALIZED; cos_defcompinfo_sched_init_ext(sched_tc, sched_thd, sched_rcv); } diff --git a/src/components/lib/kernel/cos_kernel_api.c b/src/components/lib/kernel/cos_kernel_api.c index 3c5ddcce63..eb28285e7d 100644 --- a/src/components/lib/kernel/cos_kernel_api.c +++ b/src/components/lib/kernel/cos_kernel_api.c @@ -168,7 +168,7 @@ cos_comp_capfrontier_update(struct cos_compinfo *ci, capid_t cap_frontier) cos_capfrontier_init(ci, cap_frontier); } void -cos_compinfo_init(struct cos_compinfo *ci, pgtblcap_t pgtbl_cap, captblcap_t captbl_cap, compcap_t comp_cap, +cos_compinfo_init(struct cos_compinfo *ci, pgtblcap_t pgtbl_cap, captblcap_t captbl_cap, compcap_t comp_cap, scbcap_t scb_cap, vaddr_t heap_ptr, capid_t cap_frontier, struct cos_compinfo *ci_resources) { assert(ci && ci_resources); @@ -180,6 +180,7 @@ cos_compinfo_init(struct cos_compinfo *ci, pgtblcap_t pgtbl_cap, captblcap_t cap ci->pgtbl_cap = pgtbl_cap; ci->captbl_cap = captbl_cap; ci->comp_cap = comp_cap; + ci->scb_cap = scb_cap; ci->cap_frontier = 0; cos_vasfrontier_init(ci, heap_ptr); cos_capfrontier_init(ci, cap_frontier); @@ -872,15 +873,28 @@ cos_scb_alloc(struct cos_compinfo *ci) } int -cos_comp_alloc_with(struct cos_compinfo *ci, compcap_t comp, u32_t lid, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry, vaddr_t uaddr) +cos_scb_mapping(struct cos_compinfo *ci, compcap_t comp, pgtblcap_t ptc, scbcap_t scbc) { - if (call_cap_op(ci->captbl_cap, CAPTBL_OP_COMPACTIVATE, (lid << 16) | comp, (ctc << 16) | ptc, uaddr | scbc, entry)) return 1; + vaddr_t scb_uaddr; + + scb_uaddr = cos_page_bump_intern_valloc(ci, COS_SCB_SIZE); + assert(scb_uaddr); + + if (call_cap_op(ci->captbl_cap, CAPTBL_OP_SCB_MAPPING, comp, ptc, scbc, scb_uaddr)) return 1; + + return 0; +} + +compcap_t +cos_comp_alloc_with(struct cos_compinfo *ci, compcap_t comp, u32_t lid, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry) +{ + if (call_cap_op(ci->captbl_cap, CAPTBL_OP_COMPACTIVATE, (lid << 16) | comp, (ctc << 16) | ptc, scbc, entry)) return 1; return 0; } compcap_t -cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry, vaddr_t uaddr) +cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry) { capid_t cap; /* FIXME: same or diff liveness ids in scb and comp resources? */ @@ -894,7 +908,7 @@ cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, scbcap_ cap = __capid_bump_alloc(ci, CAP_COMP); if (!cap) return 0; - if (cos_comp_alloc_with(ci, cap, lid, ctc, ptc, scbc, entry, uaddr)) BUG(); + if (cos_comp_alloc_with(ci, cap, lid, ctc, ptc, scbc, entry)) BUG(); return cap; } @@ -915,10 +929,12 @@ cos_compinfo_alloc(struct cos_compinfo *ci, scbcap_t sc, vaddr_t heap_ptr, capid assert(ptc); ctc = cos_captbl_alloc(ci_resources); assert(ctc); - compc = cos_comp_alloc(ci_resources, ctc, ptc, sc, entry, scb_vaddr); + + //scb_vaddr = (vaddr_t)__page_bump_valloc(ci, COS_SCB_SIZE); + compc = cos_comp_alloc(ci_resources, ctc, ptc, sc, entry); assert(compc); - cos_compinfo_init(ci, ptc, ctc, compc, heap_ptr, cap_frontier, ci_resources); + cos_compinfo_init(ci, ptc, ctc, compc, sc, heap_ptr, cap_frontier, ci_resources); /* This is to make sure that "the address below vas_frontier has been allocated, follow the assumption we put in cos_vasfrontier_init()"*/ for (pgtbl_lvl = 0; pgtbl_lvl < COS_PGTBL_DEPTH - 1; pgtbl_lvl++) { @@ -1077,9 +1093,7 @@ cos_thd_wakeup(thdcap_t thd, tcap_t tc, tcap_prio_t prio, tcap_res_t res) sched_tok_t cos_sched_sync(void) { - static sched_tok_t stok[NUM_CPU] CACHE_ALIGNED; - - return ps_faa((unsigned long *)&stok[cos_cpuid()], 1); + return ps_load(&cos_scb_info_get_core()->sched_tok); } int diff --git a/src/components/lib/kernel/cos_kernel_api.h b/src/components/lib/kernel/cos_kernel_api.h index 04e1b38a2f..bb4158f143 100644 --- a/src/components/lib/kernel/cos_kernel_api.h +++ b/src/components/lib/kernel/cos_kernel_api.h @@ -68,7 +68,7 @@ struct cos_meminfo { /* Component captbl/pgtbl allocation information */ struct cos_compinfo { /* capabilities to higher-order capability tables (or -1) */ - capid_t pgtbl_cap, captbl_cap, comp_cap; + capid_t pgtbl_cap, captbl_cap, comp_cap, scb_cap; /* the frontier of unallocated caps, and the allocated captbl range */ capid_t cap_frontier, caprange_frontier; /* the frontier for each of the various sizes of capability per core! */ @@ -85,7 +85,7 @@ struct cos_compinfo { }; void cos_compinfo_init(struct cos_compinfo *ci, pgtblcap_t pgtbl_cap, captblcap_t captbl_cap, compcap_t comp_cap, - vaddr_t heap_ptr, capid_t cap_frontier, struct cos_compinfo *ci_resources);/* + scbcap_t scb_cap, vaddr_t heap_ptr, capid_t cap_frontier, struct cos_compinfo *ci_resources);/* * This only needs be called on compinfos that are managing resources * (i.e. likely only one). All of the capabilities will be relative * to this component's captbls. @@ -114,9 +114,10 @@ int cos_compinfo_alloc(struct cos_compinfo *ci, scbcap_t sc, vaddr_t hea struct cos_compinfo *ci_resources); captblcap_t cos_captbl_alloc(struct cos_compinfo *ci); pgtblcap_t cos_pgtbl_alloc(struct cos_compinfo *ci); -compcap_t cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry, - vaddr_t scb_addr); +compcap_t cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry); scbcap_t cos_scb_alloc(struct cos_compinfo *ci); +int cos_scb_mapping(struct cos_compinfo *ci, compcap_t comp, pgtblcap_t ptc, scbcap_t scbc); + dcbcap_t cos_dcb_alloc(struct cos_compinfo *ci, pgtblcap_t ptc, vaddr_t dcb_uaddr); void cos_comp_capfrontier_update(struct cos_compinfo *ci, capid_t cap_frontier); diff --git a/src/components/lib/sl/Makefile b/src/components/lib/sl/Makefile index a9fe194416..68479147fb 100644 --- a/src/components/lib/sl/Makefile +++ b/src/components/lib/sl/Makefile @@ -21,7 +21,7 @@ INCLUDE_PATHS = . INTERFACE_DEPENDENCIES = capmgr # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = component kernel ck +LIBRARY_DEPENDENCIES = component kernel ck dcb # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/lib/sl_capmgr/Makefile b/src/components/lib/sl_capmgr/Makefile index 1c61e8ddb8..26146aa8ad 100644 --- a/src/components/lib/sl_capmgr/Makefile +++ b/src/components/lib/sl_capmgr/Makefile @@ -21,7 +21,7 @@ INCLUDE_PATHS = . INTERFACE_DEPENDENCIES = capmgr memmgr # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = component ps sl kernel util dcb +LIBRARY_DEPENDENCIES = component ps sl kernel util # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/lib/sl_capmgr/sl_capmgr.c b/src/components/lib/sl_capmgr/sl_capmgr.c index 7c32d27f77..01e48c5e9d 100644 --- a/src/components/lib/sl_capmgr/sl_capmgr.c +++ b/src/components/lib/sl_capmgr/sl_capmgr.c @@ -14,7 +14,7 @@ #include "../../interface/capmgr/memmgr.h" #include #include -#include +#include extern void sl_thd_event_info_reset(struct sl_thd *t); extern void sl_thd_free_no_cs(struct sl_thd *t); @@ -392,7 +392,8 @@ sl_thd_retrieve(thdid_t tid) /* sl_cs_enter(); */ } - aep.thd = capmgr_thd_retrieve(client, tid, &itid); + assert(0); + //aep.thd = capmgr_thd_retrieve(client, tid, &itid); assert(aep.thd && itid); /* this thread must be a child thread and capmgr must know it! */ /* "client"'s initthd must be initialized! */ it = sl_thd_try_lkup(itid); @@ -416,7 +417,7 @@ sl_thd_free(struct sl_thd *t) sl_cs_exit(); } -int +/*int sl_thd_migrate_no_cs(struct sl_thd *t, cpuid_t core) { struct sl_thd_policy *x = NULL; @@ -424,7 +425,7 @@ sl_thd_migrate_no_cs(struct sl_thd *t, cpuid_t core) if (t->properties) return -1; if (t->state != SL_THD_RUNNABLE) return -1; - /* capmgr should migrate the thdcap as well */ + // capmgr should migrate the thdcap as well ret = capmgr_thd_migrate(sl_thd_thdid(t), sl_thd_thdcap(t), core); if (ret) return -1; sl_mod_thd_delete(sl_mod_thd_policy_get(t)); @@ -450,4 +451,4 @@ sl_thd_migrate(thdid_t tid, cpuid_t core) sl_cs_exit(); return ret; -} +}*/ diff --git a/src/components/lib/sl_kernel/Makefile b/src/components/lib/sl_kernel/Makefile index cc942809a5..c4f47ab301 100644 --- a/src/components/lib/sl_kernel/Makefile +++ b/src/components/lib/sl_kernel/Makefile @@ -15,7 +15,7 @@ OBJECT_OUTPUT = # The path within this directory that holds the .h files for # dependents to compile with (./ by default). Will be fed into the -I # compiler arguments. -INCLUDE_PATHS = +INCLUDE_PATHS = . # The interfaces this component is dependent on for compilation (this # is a list of directory names in interface/) INTERFACE_DEPENDENCIES = diff --git a/src/components/lib/sl_kernel/sl_raw.c b/src/components/lib/sl_kernel/sl_raw.c index f854960a8d..e38c278067 100644 --- a/src/components/lib/sl_kernel/sl_raw.c +++ b/src/components/lib/sl_kernel/sl_raw.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include extern void sl_thd_event_info_reset(struct sl_thd *t); extern void sl_thd_free_no_cs(struct sl_thd *t); @@ -92,7 +92,7 @@ sl_thd_alloc_no_cs(cos_thd_fn_t fn, void *data) aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; - dcap = cos_dcb_info_alloc_curr(&doff, (vaddr_t *)&dcb); + //dcap = cos_dcb_info_alloc_curr(&doff, (vaddr_t *)&dcb); if (dcb && doff) assert(dcap); aep->thd = cos_thd_alloc(ci, ci->comp_cap, fn, data, dcap, doff); @@ -179,7 +179,7 @@ sl_thd_aep_alloc_no_cs(cos_aepthd_fn_t fn, void *data, sl_thd_property_t prps, c aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; - dcap = cos_dcb_info_alloc_curr(&doff, (vaddr_t *)&dcb); + //dcap = cos_dcb_info_alloc_curr(&doff, (vaddr_t *)&dcb); if (dcb && doff) assert(dcap); /* NOTE: Cannot use stack-allocated cos_aep_info struct here */ @@ -355,6 +355,12 @@ sl_thd_retrieve_lazy(thdid_t tid) return NULL; } +struct sl_thd * +sl_thd_retrieve(thdid_t tid) +{ + return sl_mod_thd_get(sl_thd_lookup_backend(tid)); +} + void sl_thd_free(struct sl_thd *t) { diff --git a/src/kernel/capinv.c b/src/kernel/capinv.c index eb208aaa29..d24570dd74 100644 --- a/src/kernel/capinv.c +++ b/src/kernel/capinv.c @@ -1054,6 +1054,7 @@ composite_syscall_handler(struct pt_regs *regs) /* Definitely do it for all the fast-path calls. */ thd = cap_ulthd_lazyupdate(regs, cos_info, 0, &ci); + assert(thd); cap = __userregs_getcap(regs); @@ -1330,11 +1331,10 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * capid_t pgtbl_cap = __userregs_get2(regs) & 0xFFFF; livenessid_t lid = capin >> 16; capid_t comp_cap = (capin << 16) >> 16; - vaddr_t scb_uaddr = __userregs_get3(regs) & (~0 << 12); + capid_t scb_cap = __userregs_get3(regs); vaddr_t entry_addr = __userregs_get4(regs); - capid_t scb_cap = __userregs_get3(regs) & ((1 << 12) - 1); - ret = comp_activate(ct, cap, comp_cap, captbl_cap, pgtbl_cap, scb_cap, lid, entry_addr, scb_uaddr); + ret = comp_activate(ct, cap, comp_cap, captbl_cap, pgtbl_cap, scb_cap, lid, entry_addr); break; } case CAPTBL_OP_COMPDEACTIVATE: { @@ -1444,19 +1444,54 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * break; } case CAPTBL_OP_SCB_ACTIVATE: { + capid_t scbcap = __userregs_get1(regs); capid_t ptcap = __userregs_get2(regs); - livenessid_t lid = __userregs_get3(regs); - vaddr_t addr = __userregs_get4(regs); + vaddr_t addr = __userregs_get3(regs); + livenessid_t lid = __userregs_get4(regs); + unsigned long *pte; struct cos_scb_info *scb; + struct cap_scb *scbc; ret = cap_kmem_activate(ct, ptcap, addr, (unsigned long *)&scb, &pte); if (ret) cos_throw(err, ret); ret = scb_activate(ct, cap, capin, (vaddr_t)scb, lid); + scbc = (struct cap_scb *)captbl_lkup(ci->captbl, scbcap); + if (unlikely(!scbc || scbc->h.type != CAP_SCB)) return -EINVAL; + + break; } + case CAPTBL_OP_SCB_MAPPING: { + capid_t comp_cap = __userregs_get1(regs); + capid_t ptcap = __userregs_get2(regs); + capid_t scbcap = __userregs_get3(regs); + vaddr_t scb_uaddr = __userregs_get4(regs); + + struct cap_scb *scbc = NULL; + struct cap_comp *compc = NULL; + struct cap_pgtbl *ptc = NULL; + + //struct cos_cpu_local_info *cos_info = cos_cpu_local_info(); + //struct thread *thd = thd_current(cos_info); + //int invstk_top = 0; + //struct comp_info *ci_ptr = thd_invstk_current_compinfo(thd, cos_info, &invstk_top); + + scbc = (struct cap_scb *)captbl_lkup(ct, scbcap); + if ((unlikely(!scbc || scbc->h.type != CAP_SCB))) assert(0); // return -EINVAL; + + compc = (struct cap_comp *)captbl_lkup(ct, comp_cap); + assert(compc); + + ptc = (struct cap_pgtbl *)captbl_lkup(ct, ptcap); + assert(ptc); + + ret = scb_mapping(ct, scbc, ptc, compc, scb_uaddr); + + return ret; + } case CAPTBL_OP_SCB_DEACTIVATE: { u32_t r2 = __userregs_get2(regs); livenessid_t lid = r2 >> 16; diff --git a/src/kernel/include/component.h b/src/kernel/include/component.h index a049363e7e..719761d5c9 100644 --- a/src/kernel/include/component.h +++ b/src/kernel/include/component.h @@ -34,7 +34,7 @@ struct cap_comp { static int comp_activate(struct captbl *t, capid_t cap, capid_t capin, capid_t captbl_cap, capid_t pgtbl_cap, capid_t scbcap, - livenessid_t lid, vaddr_t entry_addr, vaddr_t scb_uaddr) + livenessid_t lid, vaddr_t entry_addr) { struct cap_comp *compc; struct cap_pgtbl *ptc; @@ -66,7 +66,7 @@ comp_activate(struct captbl *t, capid_t cap, capid_t capin, capid_t captbl_cap, if (!compc) cos_throw(undo_ctc, ret); if (likely(scbc)) { - ret = scb_comp_update(t, scbc, compc, ptc, scb_uaddr); + ret = scb_comp_update(t, scbc, compc); if (ret) cos_throw(undo_capact, ret); } diff --git a/src/kernel/include/scb.h b/src/kernel/include/scb.h index 599f4faacb..2e569fe3cb 100644 --- a/src/kernel/include/scb.h +++ b/src/kernel/include/scb.h @@ -63,16 +63,26 @@ scb_deactivate(struct cap_captbl *ct, capid_t scbcap, capid_t ptcap, capid_t cos } static inline int -scb_comp_update(struct captbl *ct, struct cap_scb *sc, struct cap_comp *compc, struct cap_pgtbl *ptcin, vaddr_t uaddrin) +scb_comp_update(struct captbl *ct, struct cap_scb *sc, struct cap_comp *compc) { - paddr_t pf = chal_va2pa((void *)(sc->kern_addr)); + //paddr_t pf = chal_va2pa((void *)(sc->kern_addr)); if (unlikely(!ltbl_isalive(&sc->liveness))) return -EPERM; /* FIXME: hard coded pgtbl order */ - if (pgtbl_mapping_add(ptcin->pgtbl, uaddrin, pf, PGTBL_USER_DEF, 12)) return -EINVAL; + //if (pgtbl_mapping_add(ptcin->pgtbl, uaddrin, pf, PGTBL_USER_DEF, 12)) return -EINVAL; - sc->compc = compc; + //sc->compc = compc; compc->info.scb_data = (struct cos_scb_info *)(sc->kern_addr); + return 0; +} + +static inline int +scb_mapping(struct captbl *ct, struct cap_scb *sc, struct cap_pgtbl *ptcin, struct cap_comp *compc, vaddr_t uaddrin) +{ + assert(sc->compc == compc || !sc->compc); + paddr_t pf = chal_va2pa((void *)(sc->kern_addr)); + + if (pgtbl_mapping_add(ptcin->pgtbl, uaddrin, pf, PGTBL_USER_DEF, 12)) return -EINVAL; return 0; } diff --git a/src/kernel/include/shared/cos_types.h b/src/kernel/include/shared/cos_types.h index e99fbaa6a6..b6817b1a2f 100644 --- a/src/kernel/include/shared/cos_types.h +++ b/src/kernel/include/shared/cos_types.h @@ -146,6 +146,7 @@ typedef enum { CAPTBL_OP_HW_TLBSTALL_RECOUNT, CAPTBL_OP_SCB_ACTIVATE, + CAPTBL_OP_SCB_MAPPING, CAPTBL_OP_SCB_DEACTIVATE, CAPTBL_OP_DCB_ACTIVATE, diff --git a/src/platform/i386/boot_comp.c b/src/platform/i386/boot_comp.c index 0fed49f49e..08baeb8ff0 100644 --- a/src/platform/i386/boot_comp.c +++ b/src/platform/i386/boot_comp.c @@ -384,7 +384,7 @@ kern_boot_comp(const cpuid_t cpu_id) ret = boot_elf_process(glb_boot_ct, BOOT_CAPTBL_SELF_PT, BOOT_CAPTBL_BOOTVM_PTE, "booter VM", mem_bootc_start(), mem_bootc_end() - mem_bootc_start()); assert(ret == 0); - scb_uaddr = (vaddr_t)mem_bootc_end(); + //scb_uaddr = (vaddr_t)mem_bootc_end(); /* * Map in the untyped memory. This is more complicated as we @@ -417,7 +417,7 @@ kern_boot_comp(const cpuid_t cpu_id) if (scb_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, LLBOOT_CAPTBL_SCB, scb_kaddr, 0)) assert(0); if (comp_activate(glb_boot_ct, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_PT, - LLBOOT_CAPTBL_SCB, 0, (vaddr_t)mem_bootc_entry(), scb_uaddr)) + LLBOOT_CAPTBL_SCB, 0, (vaddr_t)mem_bootc_entry())) assert(0); printk("\tCreated boot component structure from page-table and capability-table.\n"); From 1897e9608be329b7b721edcdd25f1c0ceedaabba Mon Sep 17 00:00:00 2001 From: WenyuanShao Date: Thu, 31 Mar 2022 16:12:13 -0400 Subject: [PATCH 6/7] Push libdcb --- src/components/lib/dcb/dcb.c | 102 +++++++++++++++++++++++++++++++++++ src/components/lib/dcb/dcb.h | 29 ++++++++++ 2 files changed, 131 insertions(+) create mode 100644 src/components/lib/dcb/dcb.c create mode 100644 src/components/lib/dcb/dcb.h diff --git a/src/components/lib/dcb/dcb.c b/src/components/lib/dcb/dcb.c new file mode 100644 index 0000000000..260959db89 --- /dev/null +++ b/src/components/lib/dcb/dcb.c @@ -0,0 +1,102 @@ +#include +#include +#include + +static struct cos_dcbinfo_data _cos_dcbinfo[NUM_CPU]; + +int +cos_dcb_test_111(void) { + assert(0); + return 1; +} + +void +cos_dcb_info_init_ext(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci, + dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t start_off) +{ + memset(cdi, 0, sizeof(struct cos_dcbinfo_data)); + + cdi->dcbcaps[0] = initdcbcap; + cdi->dcbaddr[0] = initdcbaddr; + cdi->curr_cap_off = start_off; + cdi->curr_cap = 0; +} + +void +cos_dcb_info_init(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci) +{ + if (cos_spd_id() == 0) { + cos_dcb_info_init_ext(cdi, ci, LLBOOT_CAPTBL_CPU_INITDCB, + (vaddr_t)cos_init_dcb_get(), 1); + } else { + cos_dcb_info_init_ext(cdi, ci, 0, 0, 0); + } +} + +void +cos_dcb_info_init_curr(void) +{ + cos_dcb_info_init_curr_ext(0, 0, 0); +} + +void +cos_dcb_info_init_curr_ext(dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t st_off) +{ + struct cos_compinfo *ci = cos_compinfo_get(cos_defcompinfo_curr_get()); + + if (initdcbcap == 0 && initdcbaddr == 0) { + + if (cos_spd_id() == 0) { + cos_dcb_info_init_ext(&_cos_dcbinfo[cos_cpuid()], ci, + LLBOOT_CAPTBL_CPU_INITDCB, (vaddr_t)cos_init_dcb_get(), 1); + + return; + } else { + initdcbaddr = cos_page_bump_intern_valloc(ci, PAGE_SIZE); + assert(initdcbaddr); + initdcbcap = cos_dcb_alloc(ci, ci->pgtbl_cap, initdcbaddr); + assert(initdcbcap); + st_off = 0; + } + } + cos_dcb_info_init_ext(&_cos_dcbinfo[cos_cpuid()], ci, initdcbcap, initdcbaddr, st_off); +} + +dcbcap_t +cos_dcb_info_alloc_curr(dcboff_t *dcboff, vaddr_t *dcbaddr) +{ + return cos_dcb_info_alloc(&_cos_dcbinfo[cos_cpuid()], dcboff, dcbaddr); +} + +dcbcap_t +cos_dcb_info_alloc(struct cos_dcbinfo_data *cdi, dcboff_t *dcboff, vaddr_t *dcbaddr) +{ + if (unlikely(cdi->dcbcaps[cdi->curr_cap] == 0)) { + *dcboff = 0; + *dcbaddr = 0; + + return 0; + } + if (cdi->curr_cap_off >= COS_DCB_PERPG_MAX) { + int ret; + unsigned short curr_off = cdi->curr_cap; + + assert(curr_off + 1 < (unsigned short)COS_DCB_MAX_CAPS && cdi->dcbcaps[curr_off + 1] == 0); + + cdi->dcbaddr[curr_off + 1] = cos_page_bump_intern_valloc(cdi->ci, PAGE_SIZE); + assert(cdi->dcbaddr[curr_off + 1]); + cdi->dcbcaps[curr_off + 1] = cos_dcb_alloc(cos_compinfo_get(cos_defcompinfo_curr_get()), + cdi->ci->pgtbl_cap, cdi->dcbaddr[curr_off + 1]); + + assert(cdi->dcbcaps[curr_off + 1]); + ret = ps_cas((unsigned long *)&cdi->curr_cap, curr_off, curr_off + 1); + assert(ret); + ret = ps_cas((unsigned long *)&cdi->curr_cap_off, cdi->curr_cap_off, 0); + assert(ret); + } + + *dcboff = ps_faa((unsigned long *)&cdi->curr_cap_off, 1); + *dcbaddr = cdi->dcbaddr[cdi->curr_cap] + (sizeof(struct cos_dcb_info) * (*dcboff)); + + return cdi->dcbcaps[cdi->curr_cap]; +} diff --git a/src/components/lib/dcb/dcb.h b/src/components/lib/dcb/dcb.h new file mode 100644 index 0000000000..93294645ff --- /dev/null +++ b/src/components/lib/dcb/dcb.h @@ -0,0 +1,29 @@ +#ifndef DCB_H +#define DCB_H + +#include +#include + +#define COS_DCB_PERPG_MAX (PAGE_SIZE / sizeof(struct cos_dcb_info)) + +#define COS_DCB_MAX_CAPS (MAX_NUM_THREADS / COS_DCB_PERPG_MAX + 1) + +struct cos_dcbinfo_data { + dcbcap_t dcbcaps[COS_DCB_MAX_CAPS]; + vaddr_t dcbaddr[COS_DCB_MAX_CAPS]; + dcboff_t curr_cap_off; + unsigned short curr_cap; + + struct cos_compinfo *ci; +} CACHE_ALIGNED; + +int cos_dcb_test_111(void); +void cos_dcb_info_init(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci); +void cos_dcb_info_init_ext(struct cos_dcbinfo_data *cdi, struct cos_compinfo *ci, dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t start_off); +dcbcap_t cos_dcb_info_alloc(struct cos_dcbinfo_data *cdi, dcboff_t *dcboff, vaddr_t *dcbaddr); + +void cos_dcb_info_init_curr(void); +void cos_dcb_info_init_curr_ext(dcbcap_t initdcbcap, vaddr_t initdcbaddr, dcboff_t st_off); +dcbcap_t cos_dcb_info_alloc_curr(dcboff_t *dcboff, vaddr_t *dcbaddr); + +#endif /* COS_DCB_H */ From 6fb75e5187db5247568d3e65de97c3ed5244ba5e Mon Sep 17 00:00:00 2001 From: WenyuanShao Date: Sun, 10 Apr 2022 23:54:58 -0400 Subject: [PATCH 7/7] cleanup environment, and rewind modifications on asnd --- .../implementation/capmgr/simple/capmgr.c | 41 +++++++---- .../no_interface/llbooter/llbooter.c | 8 +-- .../tests/kernel_tests/k_test_tcap.c | 1 - .../tests/kernel_tests/kernel_test_booter.c | 19 +++-- src/components/interface/capmgr/capmgr.h | 20 +++--- src/components/interface/capmgr/lib.c | 4 +- .../interface/capmgr/stubs/c_stub.c | 15 ++-- .../interface/capmgr/stubs/s_stub.c | 18 ++--- src/components/lib/crt/crt.c | 8 ++- src/components/lib/kernel/cos_kernel_api.c | 7 +- src/components/lib/kernel/cos_kernel_api.h | 2 +- src/components/lib/sl/sl.h | 1 + src/components/lib/sl_capmgr/sl_capmgr.c | 3 +- src/kernel/capinv.c | 12 ++-- src/kernel/include/component.h | 1 + src/kernel/include/dcb.h | 1 - src/kernel/include/scb.h | 6 +- src/kernel/include/thd.h | 70 ++++++++++++++----- 18 files changed, 145 insertions(+), 92 deletions(-) diff --git a/src/components/implementation/capmgr/simple/capmgr.c b/src/components/implementation/capmgr/simple/capmgr.c index eb10a74326..025bb4c5ee 100644 --- a/src/components/implementation/capmgr/simple/capmgr.c +++ b/src/components/implementation/capmgr/simple/capmgr.c @@ -168,11 +168,15 @@ struct cm_dcb * cm_dcb_alloc_in(struct cm_comp *sched) { compid_t id = (compid_t)cos_inv_token(); - struct cm_dcb *d = ss_dcb_alloc_at_id(id); - - d->dcb_cap = crt_dcb_create_in(sched, &d->dcb_addr); + struct cm_dcb *d = ss_dcb_alloc(); + dcbcap_t dcbcap; + vaddr_t dcbaddr = 0; + dcbcap = crt_dcb_create_in(&sched->comp, &dcbaddr); + d->dcb_addr = dcbaddr; + d->dcb_cap = dcbcap; ss_dcb_activate(d); + return d; } @@ -360,22 +364,26 @@ capmgr_comp_sched_get(compid_t cid) return atoi(sched); } -extern scbcap_t scb_mapping(compid_t id); +extern scbcap_t scb_mapping(compid_t id, vaddr_t scb_uaddr); int capmgr_scb_mapping(void) { compid_t schedid = (compid_t)cos_inv_token(); - printc("\tschedid: %d\n", schedid); - struct cm_comp *s; struct cos_compinfo *ci; + struct cm_comp *s; + vaddr_t scb_uaddr; s = ss_comp_get(schedid); assert(s); ci = cos_compinfo_get(s->comp.comp_res); assert(ci); - return scb_mapping(schedid); + + scb_uaddr = cos_page_bump_intern_valloc(ci, COS_SCB_SIZE); + assert(scb_uaddr); + + return scb_mapping(schedid, scb_uaddr); } static void @@ -534,7 +542,8 @@ init_exit(int retval) } thdcap_t -capmgr_thd_create_ext(spdid_t client, thdclosure_index_t idx, thdid_t *tid) +capmgr_thd_create_ext(spdid_t client, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb) +//capmgr_thd_create_ext(spdid_t client, thdclosure_index_t idx, thdid_t *tid) { compid_t schedid = (compid_t)cos_inv_token(); struct cm_thd *t; @@ -560,6 +569,7 @@ capmgr_thd_create_ext(spdid_t client, thdclosure_index_t idx, thdid_t *tid) return 0; } *tid = t->thd.tid; + *dcb = (struct cos_dcb_info *)d->dcb_addr; return t->aliased_cap; } @@ -567,13 +577,15 @@ capmgr_thd_create_ext(spdid_t client, thdclosure_index_t idx, thdid_t *tid) thdcap_t capmgr_initthd_create(spdid_t client, thdid_t *tid) { - return capmgr_thd_create_ext(client, 0, tid); + struct cos_dcb_info *dcb; + + return capmgr_thd_create_ext(client, 0, tid, &dcb); } thdcap_t capmgr_initaep_create(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret) { BUG(); return 0; } thdcap_t -capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb) +capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb) { compid_t client = (compid_t)cos_inv_token(); struct cm_thd *t; @@ -591,13 +603,13 @@ capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_inf return 0; } *tid = t->thd.tid; - dcb = (struct cos_dcb_info *)d->dcb_addr; + *dcb = (struct cos_dcb_info *)d->dcb_addr; return t->aliased_cap; } -thdcap_t capmgr_aep_create_thunk(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) { BUG(); return 0; } -thdcap_t capmgr_aep_create_ext(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, arcvcap_t *extrcv) { BUG(); return 0; } +thdcap_t capmgr_aep_create_thunk(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb) { BUG(); return 0; } +thdcap_t capmgr_aep_create_ext(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv) { BUG(); return 0; } arcvcap_t capmgr_rcv_create(spdid_t child, thdid_t tid, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax) { BUG(); return 0; } asndcap_t capmgr_asnd_create(spdid_t child, thdid_t t) { BUG(); return 0; } asndcap_t capmgr_asnd_rcv_create(arcvcap_t rcv) { BUG(); return 0; } @@ -631,7 +643,8 @@ cos_init(void) /* Initialize the other component's for which we're responsible */ scbcap_t scbc = cos_scb_alloc(ci); assert(scbc); - if (cos_scb_mapping(ci, ci->comp_cap, ci->pgtbl_cap, scbc)) BUG(); + vaddr_t scb_uaddr = cos_page_bump_intern_valloc(ci, COS_SCB_SIZE); + if (cos_scb_mapping(ci, ci->comp_cap, ci->pgtbl_cap, scbc, scb_uaddr)) BUG(); capmgr_comp_init(); sl_init(SL_MIN_PERIOD_US); diff --git a/src/components/implementation/no_interface/llbooter/llbooter.c b/src/components/implementation/no_interface/llbooter/llbooter.c index 2d570be13b..94850d9656 100644 --- a/src/components/implementation/no_interface/llbooter/llbooter.c +++ b/src/components/implementation/no_interface/llbooter/llbooter.c @@ -413,7 +413,7 @@ addr_get(compid_t id, addr_t type) } int -scb_mapping(compid_t id) +scb_mapping(compid_t id, vaddr_t scb_uaddr) { struct cos_compinfo *ci; struct crt_comp *target; @@ -421,8 +421,7 @@ scb_mapping(compid_t id) target = boot_comp_get(id); ci = cos_compinfo_get(target->comp_res); - - if (cos_scb_mapping(ci, ci->comp_cap, ci->pgtbl_cap, ci->scb_cap)) BUG(); + if (cos_scb_mapping(ci, ci->comp_cap, ci->pgtbl_cap, ci->scb_cap, scb_uaddr)) BUG(); return 0; } @@ -434,7 +433,8 @@ booter_init(void) cos_meminfo_init(&(boot_info->mi), BOOT_MEM_KM_BASE, COS_MEM_KERN_PA_SZ, BOOT_CAPTBL_SELF_UNTYPED_PT); cos_defcompinfo_init(); - if (cos_scb_mapping(boot_info, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_PT, LLBOOT_CAPTBL_SCB)) BUG(); + vaddr_t scb_uaddr = cos_page_bump_intern_valloc(boot_info, COS_SCB_SIZE); + if (cos_scb_mapping(boot_info, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_PT, LLBOOT_CAPTBL_SCB, scb_uaddr)) BUG(); cos_hw_cycles_per_usec(BOOT_CAPTBL_SELF_INITHW_BASE); } diff --git a/src/components/implementation/tests/kernel_tests/k_test_tcap.c b/src/components/implementation/tests/kernel_tests/k_test_tcap.c index 7a8ae3364f..e16353c4be 100644 --- a/src/components/implementation/tests/kernel_tests/k_test_tcap.c +++ b/src/components/implementation/tests/kernel_tests/k_test_tcap.c @@ -49,7 +49,6 @@ test_timer(void) tcap_time_t timer, thd_timeout; tc = cos_thd_alloc(&booter_info, booter_info.comp_cap, spinner, NULL, 0, 0); - printc("thd alloc done\n"); perfdata_init(&result, "COS THD => COS_THD_SWITCH", test_results, ARRAY_SIZE); for (i = 0; i <= TEST_ITER; i++){ diff --git a/src/components/implementation/tests/kernel_tests/kernel_test_booter.c b/src/components/implementation/tests/kernel_tests/kernel_test_booter.c index 351970c4d0..2a8a863dde 100644 --- a/src/components/implementation/tests/kernel_tests/kernel_test_booter.c +++ b/src/components/implementation/tests/kernel_tests/kernel_test_booter.c @@ -30,19 +30,29 @@ cos_init(void) //scbcap_t scbc = cos_scb_alloc(&booter_info); cos_compinfo_init(&booter_info, BOOT_CAPTBL_SELF_PT, BOOT_CAPTBL_SELF_CT, BOOT_CAPTBL_SELF_COMP, LLBOOT_CAPTBL_SCB, (vaddr_t)cos_get_heap_ptr(), BOOT_CAPTBL_FREE, &booter_info); - cos_scb_mapping(&booter_info, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_PT, LLBOOT_CAPTBL_SCB); + vaddr_t scb_uaddr = cos_page_bump_intern_valloc(&booter_info, COS_SCB_SIZE); + cos_scb_mapping(&booter_info, BOOT_CAPTBL_SELF_COMP, BOOT_CAPTBL_SELF_PT, LLBOOT_CAPTBL_SCB, scb_uaddr); } void test_scb(void) { thdcap_t thdc; - struct cos_scb_info *scb_info = cos_scb_info_get(); + struct cos_scb_info *scb_info = cos_scb_info_get_core(); scb_info->curr_thd = BOOT_CAPTBL_SELF_INITTHD_CPU_BASE; thdc = cos_introspect(&booter_info, booter_info.comp_cap, COMP_GET_SCB_CURTHD); - if (thdc == (thdcap_t)BOOT_CAPTBL_SELF_INITTHD_CPU_BASE) PRINTC("Success: Kernel and user have consistent thdcap set in SCB\n"); - else PRINTC("Failure: Kernel and user don't have a consistent thdcap in SCB\n"); + if (thdc == (thdcap_t)BOOT_CAPTBL_SELF_INITTHD_CPU_BASE) PRINTC("\t%s: \t\t\tSuccess\n", "SCB => Basic test"); + else PRINTC("\t%s: \t\t\tFail\n", "SCB"); +} + +void +test_dcb(void) +{ + struct cos_dcb_info *init_dcbpg = cos_init_dcb_get(); + + assert(init_dcbpg); + PRINTC("\t%s: \t\t\tSuccess\n", "DCB => Basic test"); } void @@ -52,6 +62,7 @@ test_run_unit_kernel(void) printc("\n"); PRINTC("Unit Test Started:\n\n"); test_scb(); + test_dcb(); test_timer(); test_tcap_budgets(); test_2timers(); diff --git a/src/components/interface/capmgr/capmgr.h b/src/components/interface/capmgr/capmgr.h index b0fd9cdbbf..20fcf2fa3b 100644 --- a/src/components/interface/capmgr/capmgr.h +++ b/src/components/interface/capmgr/capmgr.h @@ -28,20 +28,20 @@ thdcap_t COS_STUB_DECL(capmgr_initthd_create)(spdid_t child, thdid_t *tid); thdcap_t capmgr_initaep_create(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret); thdcap_t COS_STUB_DECL(capmgr_initaep_create)(spdid_t child, struct cos_aep_info *aep, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, asndcap_t *sndret); -thdcap_t capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info *dcb); -thdcap_t capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb); +thdcap_t capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info **dcb); +thdcap_t capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); -thdcap_t capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb); -thdcap_t COS_STUB_DECL(capmgr_thd_create_thunk)(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb); +thdcap_t capmgr_thd_create_thunk(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); +thdcap_t COS_STUB_DECL(capmgr_thd_create_thunk)(thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); -thdcap_t capmgr_aep_create_thunk(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb); -thdcap_t COS_STUB_DECL(capmgr_aep_create_thunk)(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb); +thdcap_t capmgr_aep_create_thunk(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); +thdcap_t COS_STUB_DECL(capmgr_aep_create_thunk)(struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb); -thdcap_t capmgr_thd_create_ext(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb); -thdcap_t COS_STUB_DECL(capmgr_thd_create_ext)(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb); +thdcap_t capmgr_thd_create_ext(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); +thdcap_t COS_STUB_DECL(capmgr_thd_create_ext)(spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb); -thdcap_t capmgr_aep_create_ext(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb, arcvcap_t *extrcv); -thdcap_t COS_STUB_DECL(capmgr_aep_create_ext)(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb, arcvcap_t *extrcv); +thdcap_t capmgr_aep_create_ext(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv); +thdcap_t COS_STUB_DECL(capmgr_aep_create_ext)(spdid_t child, struct cos_aep_info *a, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv); thdcap_t capmgr_thd_retrieve(spdid_t child, thdid_t t, thdid_t *inittid); thdcap_t capmgr_thd_retrieve_next(spdid_t child, thdid_t *tid); diff --git a/src/components/interface/capmgr/lib.c b/src/components/interface/capmgr/lib.c index f6df4210c9..e000076387 100644 --- a/src/components/interface/capmgr/lib.c +++ b/src/components/interface/capmgr/lib.c @@ -2,7 +2,7 @@ #include thdcap_t -capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info *dcb) +capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info **dcb) { thdclosure_index_t idx = cos_thd_init_alloc(fn, data); @@ -12,7 +12,7 @@ capmgr_thd_create(cos_thd_fn_t fn, void *data, thdid_t *tid, struct cos_dcb_info } thdcap_t -capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb) +capmgr_aep_create(struct cos_aep_info *a, cos_aepthd_fn_t fn, void *data, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb) { thdclosure_index_t idx = cos_thd_init_alloc(cos_aepthd_fn, (void *)a); diff --git a/src/components/interface/capmgr/stubs/c_stub.c b/src/components/interface/capmgr/stubs/c_stub.c index b30811bff8..d37e20c0b6 100644 --- a/src/components/interface/capmgr/stubs/c_stub.c +++ b/src/components/interface/capmgr/stubs/c_stub.c @@ -65,32 +65,33 @@ COS_CLIENT_STUB(thdcap_t, capmgr_initthd_create, spdid_t child, thdid_t *tid) return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_thunk, thdclosure_index_t id, thdid_t *tid, struct cos_dcb_info *dcb) +COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_thunk, thdclosure_index_t id, thdid_t *tid, struct cos_dcb_info **dcb) { COS_CLIENT_INVCAP; word_t dcb_ret, tid_ret; thdcap_t ret; ret = cos_sinv_2rets(uc->cap_no, id, 0, 0, 0, &tid_ret, &dcb_ret); - dcb = dcb_ret; + *dcb = (struct cos_dcb_info *)dcb_ret; *tid = tid_ret; return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_ext, spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info *dcb) +COS_CLIENT_STUB(thdcap_t, capmgr_thd_create_ext, spdid_t child, thdclosure_index_t idx, thdid_t *tid, struct cos_dcb_info **dcb) { COS_CLIENT_INVCAP; word_t dcb_ret, tid_ret; thdcap_t ret; ret = cos_sinv_2rets(uc->cap_no, child, idx, 0, 0, &tid_ret, &dcb_ret); - dcb = dcb_ret; + *dcb = (struct cos_dcb_info *)dcb_ret; + *tid = tid_ret; return ret; } -COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb) +COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb) { COS_CLIENT_INVCAP; word_t tcrcvret = 0; @@ -115,13 +116,13 @@ COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_thunk, struct cos_aep_info *aep, thd aep->tc = (tcrcvret >> 16); aep->tid = tid; - dcb = dcb_ret; + *dcb = (struct cos_dcb_info *)dcb_ret; return thd; } /* FIXME: Won't work now */ -COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_ext, spdid_t child, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info *dcb, arcvcap_t *extrcv) +COS_CLIENT_STUB(thdcap_t, capmgr_aep_create_ext, spdid_t child, struct cos_aep_info *aep, thdclosure_index_t idx, int owntc, cos_channelkey_t key, microsec_t ipiwin, u32_t ipimax, struct cos_dcb_info **dcb, arcvcap_t *extrcv) { COS_CLIENT_INVCAP; word_t drcvtidret = 0; diff --git a/src/components/interface/capmgr/stubs/s_stub.c b/src/components/interface/capmgr/stubs/s_stub.c index d7efeeca9a..23e10fba8d 100644 --- a/src/components/interface/capmgr/stubs/s_stub.c +++ b/src/components/interface/capmgr/stubs/s_stub.c @@ -48,12 +48,12 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_retrieve_next) COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_thunk) { thdid_t retthd = 0; - struct cos_dcb_info retdcb; + struct cos_dcb_info *retdcb; thdcap_t ret; ret = capmgr_thd_create_thunk(p0, &retthd, &retdcb); *r1 = retthd; - *r2 = &retdcb; + *r2 = (word_t)retdcb; return ret; } @@ -61,12 +61,12 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_thunk) COS_SERVER_3RET_STUB(thdcap_t, capmgr_thd_create_ext) { thdid_t retthd = 0; - struct cos_dcb_info retdcb; + struct cos_dcb_info *retdcb; thdcap_t ret; ret = capmgr_thd_create_ext(p0, p1, &retthd, &retdcb); *r1 = retthd; - *r2 = &retdcb; + *r2 = (word_t)retdcb; return ret; } @@ -108,13 +108,14 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_aep_create_thunk) u32_t ipimax = (p1 << 16) >> 16; u32_t ipiwin32b = (u32_t)p2; struct cos_aep_info aep; - struct cos_dcb_info dcb; + struct cos_dcb_info *retdcb; asndcap_t snd; thdcap_t thdtidret; - thdtidret = capmgr_aep_create_thunk(&aep, thunk, owntc, key, ipimax, ipiwin32b, &dcb); - *r1 = &dcb; + thdtidret = capmgr_aep_create_thunk(&aep, thunk, owntc, key, ipimax, ipiwin32b, &retdcb); + *r1 = (word_t)retdcb; *r2 = (aep.rcv << 16) | aep.tc; + assert(0); return thdtidret; } @@ -129,8 +130,9 @@ COS_SERVER_3RET_STUB(thdcap_t, capmgr_aep_create_ext) microsec_t ipiwin = p3; u32_t ipimax = ((p2 << 16) >> 16); arcvcap_t extrcv = 0; - struct cos_dcb_info dcbret; + struct cos_dcb_info *dcbret; thdcap_t ret; + assert(0); ret = capmgr_aep_create_ext(child, &aep, idx, owntc, key, ipiwin, ipimax, &dcbret, &extrcv); *r1 = aep.tid | (extrcv << 16); diff --git a/src/components/lib/crt/crt.c b/src/components/lib/crt/crt.c index a2c8d9928b..a7bbca5e5a 100644 --- a/src/components/lib/crt/crt.c +++ b/src/components/lib/crt/crt.c @@ -1314,11 +1314,13 @@ crt_dcb_create_in(struct crt_comp *c, vaddr_t *dcb_addr) struct cos_compinfo *ci = cos_compinfo_get(defci); struct cos_compinfo *target_ci = cos_compinfo_get(c->comp_res); dcbcap_t dcb_cap; + vaddr_t dcbaddr; - dcb_addr = cos_page_bump_intern_valloc(target_ci, PAGE_SIZE); - assert(dcb_addr); - dcb_cap = cos_dcb_alloc(ci, target_ci->pgtbl_cap, dcb_addr); + dcbaddr = cos_page_bump_intern_valloc(target_ci, PAGE_SIZE); + assert(dcbaddr); + dcb_cap = cos_dcb_alloc(ci, target_ci->pgtbl_cap, dcbaddr); assert(dcb_cap); + *dcb_addr = dcbaddr; return dcb_cap; } diff --git a/src/components/lib/kernel/cos_kernel_api.c b/src/components/lib/kernel/cos_kernel_api.c index eb28285e7d..8cdf4afd0a 100644 --- a/src/components/lib/kernel/cos_kernel_api.c +++ b/src/components/lib/kernel/cos_kernel_api.c @@ -873,13 +873,8 @@ cos_scb_alloc(struct cos_compinfo *ci) } int -cos_scb_mapping(struct cos_compinfo *ci, compcap_t comp, pgtblcap_t ptc, scbcap_t scbc) +cos_scb_mapping(struct cos_compinfo *ci, compcap_t comp, pgtblcap_t ptc, scbcap_t scbc, vaddr_t scb_uaddr) { - vaddr_t scb_uaddr; - - scb_uaddr = cos_page_bump_intern_valloc(ci, COS_SCB_SIZE); - assert(scb_uaddr); - if (call_cap_op(ci->captbl_cap, CAPTBL_OP_SCB_MAPPING, comp, ptc, scbc, scb_uaddr)) return 1; return 0; diff --git a/src/components/lib/kernel/cos_kernel_api.h b/src/components/lib/kernel/cos_kernel_api.h index bb4158f143..1bc20c8ff2 100644 --- a/src/components/lib/kernel/cos_kernel_api.h +++ b/src/components/lib/kernel/cos_kernel_api.h @@ -116,7 +116,7 @@ captblcap_t cos_captbl_alloc(struct cos_compinfo *ci); pgtblcap_t cos_pgtbl_alloc(struct cos_compinfo *ci); compcap_t cos_comp_alloc(struct cos_compinfo *ci, captblcap_t ctc, pgtblcap_t ptc, scbcap_t scbc, vaddr_t entry); scbcap_t cos_scb_alloc(struct cos_compinfo *ci); -int cos_scb_mapping(struct cos_compinfo *ci, compcap_t comp, pgtblcap_t ptc, scbcap_t scbc); +int cos_scb_mapping(struct cos_compinfo *ci, compcap_t comp, pgtblcap_t ptc, scbcap_t scbc, vaddr_t scb_uaddr); dcbcap_t cos_dcb_alloc(struct cos_compinfo *ci, pgtblcap_t ptc, vaddr_t dcb_uaddr); void cos_comp_capfrontier_update(struct cos_compinfo *ci, capid_t cap_frontier); diff --git a/src/components/lib/sl/sl.h b/src/components/lib/sl/sl.h index 11435a0a1b..3852a1e195 100644 --- a/src/components/lib/sl/sl.h +++ b/src/components/lib/sl/sl.h @@ -439,6 +439,7 @@ sl_thd_dispatch(struct sl_thd *next, sched_tok_t tok, struct sl_thd *curr) { volatile struct cos_scb_info *scb = sl_scb_info_cpu(); struct cos_dcb_info *cd = sl_thd_dcbinfo(curr), *nd = sl_thd_dcbinfo(next); + assert(0); assert(curr != next); if (unlikely(!cd || !nd)) return sl_thd_activate(next, tok, sl__globals_cpu()->timeout_next); diff --git a/src/components/lib/sl_capmgr/sl_capmgr.c b/src/components/lib/sl_capmgr/sl_capmgr.c index 01e48c5e9d..ff05b68ff9 100644 --- a/src/components/lib/sl_capmgr/sl_capmgr.c +++ b/src/components/lib/sl_capmgr/sl_capmgr.c @@ -146,6 +146,7 @@ sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx, vad struct cos_compinfo *compci = cos_compinfo_get(comp); struct sl_thd *t = NULL; struct cos_aep_info *aep = NULL; + struct cos_dcb_info *dcb = NULL; if (comp == NULL || comp->id == 0) goto done; @@ -153,7 +154,7 @@ sl_thd_alloc_ext_no_cs(struct cos_defcompinfo *comp, thdclosure_index_t idx, vad aep = sl_thd_alloc_aep_backend(); if (!aep) goto done; - aep->thd = capmgr_thd_create_ext(comp->id, idx, &aep->tid, (struct cos_dcb_info **)dcbuaddr); + aep->thd = capmgr_thd_create_ext(comp->id, idx, &aep->tid, &dcb); if (!aep->thd) goto done; aep->tc = sl_thd_tcap(sl__globals_cpu()->sched_thd); diff --git a/src/kernel/capinv.c b/src/kernel/capinv.c index d24570dd74..0bd4bec7db 100644 --- a/src/kernel/capinv.c +++ b/src/kernel/capinv.c @@ -104,7 +104,6 @@ cap_ulthd_lazyupdate(struct pt_regs *regs, struct cos_cpu_local_info *cos_info, scb_core = (((*ci_ptr)->scb_data) + get_cpuid()); ultc = scb_core->curr_thd; /* reset inconsistency from user-level thd! */ - scb_core->curr_thd = 0; if (!ultc && !interrupt) goto done; if (likely(ultc)) { @@ -554,7 +553,7 @@ asnd_process(struct thread *rcv_thd, struct thread *thd, struct tcap *rcv_tcap, { struct thread *next; - thd_rcvcap_pending_set(rcv_thd); + thd_rcvcap_pending_inc(rcv_thd); next = notify_process(rcv_thd, thd, rcv_tcap, tcap, tcap_next, yield); /* @@ -722,6 +721,7 @@ cap_thd_op(struct cap_thd *thd_cap, struct thread *thd, struct pt_regs *regs, st if (!tcap_rcvcap_thd(tcap)) return -EINVAL; if (unlikely(!tcap_is_active(tcap))) return -EPERM; } + ret = cap_switch(regs, thd, next, tcap, timeout, ci, cos_info); if (tc && tcap_current(cos_info) == tcap) tcap_setprio(tcap, prio); @@ -953,14 +953,14 @@ cap_arcv_op(struct cap_arcv *arcv, struct thread *thd, struct pt_regs *regs, str rcv_flags_t rflags = __userregs_get1(regs); tcap_time_t swtimeout = TCAP_TIME_NIL; tcap_time_t timeout = __userregs_get2(regs); - //int all_pending = (!!(rflags & RCV_ALL_PENDING)); + int all_pending = (!!(rflags & RCV_ALL_PENDING)); if (unlikely(arcv->thd != thd || arcv->cpuid != get_cpuid())) return -EINVAL; /* deliver pending notifications? */ if (thd_rcvcap_pending(thd)) { __userregs_set(regs, 0, __userregs_getsp(regs), __userregs_getip(regs)); - //thd_rcvcap_all_pending_set(thd, all_pending); + thd_rcvcap_all_pending_set(thd, all_pending); thd_rcvcap_pending_deliver(thd, regs); return 0; @@ -1004,7 +1004,7 @@ cap_arcv_op(struct cap_arcv *arcv, struct thread *thd, struct pt_regs *regs, str if (likely(thd != next)) { assert(!(thd->state & THD_STATE_PREEMPTED)); thd->state |= THD_STATE_RCVING; - //thd_rcvcap_all_pending_set(thd, all_pending); + thd_rcvcap_all_pending_set(thd, all_pending); thd->timeout = timeout; } @@ -1518,9 +1518,7 @@ static int __attribute__((noinline)) composite_syscall_slowpath(struct pt_regs * ret = cap_kmem_activate(ct, ptcap, kaddr, (unsigned long *)&dcb, &pte); if (ret) cos_throw(err, ret); - ret = dcb_activate(ct, cap, dcbcap, (vaddr_t)dcb, lid, ptcapin, uaddrin); - break; } case CAPTBL_OP_DCB_DEACTIVATE: { diff --git a/src/kernel/include/component.h b/src/kernel/include/component.h index 719761d5c9..492e403a07 100644 --- a/src/kernel/include/component.h +++ b/src/kernel/include/component.h @@ -131,6 +131,7 @@ comp_introspect(struct cap_comp *t, unsigned long op, unsigned long *retval) switch (op) { case COMP_GET_SCB_CURTHD: *retval = t->info.scb_data->curr_thd; + break; default: return -EINVAL; diff --git a/src/kernel/include/dcb.h b/src/kernel/include/dcb.h index 77bc231db3..2d5bc1ceac 100644 --- a/src/kernel/include/dcb.h +++ b/src/kernel/include/dcb.h @@ -33,7 +33,6 @@ dcb_activate(struct captbl *t, capid_t ctcap, capid_t dcbcap, vaddr_t kaddr, liv ptcin = (struct cap_pgtbl *)captbl_lkup(t, ptcapin); if (!ptcin || ptcin->h.type != CAP_PGTBL) return -EINVAL; - /* FIXME: hard coded page order */ if (pgtbl_mapping_add(ptcin->pgtbl, uaddr, pf, PGTBL_USER_DEF, 12)) return -EINVAL; diff --git a/src/kernel/include/scb.h b/src/kernel/include/scb.h index 2e569fe3cb..08fb06f8a4 100644 --- a/src/kernel/include/scb.h +++ b/src/kernel/include/scb.h @@ -65,14 +65,12 @@ scb_deactivate(struct cap_captbl *ct, capid_t scbcap, capid_t ptcap, capid_t cos static inline int scb_comp_update(struct captbl *ct, struct cap_scb *sc, struct cap_comp *compc) { - //paddr_t pf = chal_va2pa((void *)(sc->kern_addr)); - if (unlikely(!ltbl_isalive(&sc->liveness))) return -EPERM; /* FIXME: hard coded pgtbl order */ - //if (pgtbl_mapping_add(ptcin->pgtbl, uaddrin, pf, PGTBL_USER_DEF, 12)) return -EINVAL; - //sc->compc = compc; + sc->compc = compc; compc->info.scb_data = (struct cos_scb_info *)(sc->kern_addr); + return 0; } diff --git a/src/kernel/include/thd.h b/src/kernel/include/thd.h index 1ceab89d43..2643214379 100644 --- a/src/kernel/include/thd.h +++ b/src/kernel/include/thd.h @@ -34,7 +34,7 @@ struct invstk_entry { */ struct rcvcap_info { /* how many other arcv end-points send notifications to this one? */ - int isbound, pending, refcnt, is_init; + int isbound, pending, refcnt, is_all_pending, is_init; sched_tok_t sched_count; struct tcap * rcvcap_tcap; /* This rcvcap's tcap */ struct thread *rcvcap_thd_notif; /* The parent rcvcap thread for notifications */ @@ -180,13 +180,13 @@ thd_next_thdinfo_update(struct cos_cpu_local_info *cli, struct thread *thd, stru } static void -thd_rcvcap_init(struct thread *t, int is_init) +thd_rcvcap_init(struct thread *t) { struct rcvcap_info *rc = &t->rcvcap; rc->isbound = rc->pending = rc->refcnt = 0; + rc->is_all_pending = 0; rc->sched_count = 0; - rc->is_init = is_init; rc->rcvcap_thd_notif = NULL; } @@ -219,11 +219,36 @@ thd_track_exec(struct thread *t) return !list_empty(&t->event_list); } +static void +thd_rcvcap_all_pending_set(struct thread *t, int val) +{ + t->rcvcap.is_all_pending = val; +} + +static int +thd_rcvcap_all_pending_get(struct thread *t) +{ + return t->rcvcap.is_all_pending; +} + +static int +thd_rcvcap_all_pending(struct thread *t) +{ + int pending = t->rcvcap.pending; + + /* receive all pending */ + t->rcvcap.pending = 0; + thd_rcvcap_all_pending_set(t, 0); + + return ((pending << 1) | !list_isempty(&t->event_head)); +} + static int thd_rcvcap_pending(struct thread *t) { if (t->rcvcap.pending) return t->rcvcap.pending; return !list_isempty(&t->event_head); + ; } static sched_tok_t @@ -239,17 +264,20 @@ thd_rcvcap_set_counter(struct thread *t, sched_tok_t cntr) } static void -thd_rcvcap_pending_set(struct thread *arcvt) +thd_rcvcap_pending_inc(struct thread *arcvt) { - if (likely(arcvt->dcbinfo)) arcvt->dcbinfo->pending = 1; - else arcvt->rcvcap.pending = 1; + arcvt->rcvcap.pending++; } -static void -thd_rcvcap_pending_reset(struct thread *arcvt) +static int +thd_rcvcap_pending_dec(struct thread *arcvt) { - arcvt->rcvcap.pending = 0; - if (likely(arcvt->dcbinfo)) arcvt->dcbinfo->pending = 0; + int pending = arcvt->rcvcap.pending; + + if (pending == 0) return 0; + arcvt->rcvcap.pending--; + + return pending; } static inline int @@ -333,8 +361,7 @@ thd_activate(struct captbl *t, capid_t cap, capid_t capin, struct thread *thd, c assert(thd->tid <= MAX_NUM_THREADS); thd_scheduler_set(thd, thd_current(cli)); - /* TODO: fix the way to specify scheduler in a component! */ - thd_rcvcap_init(thd, !init_data); + thd_rcvcap_init(thd); list_head_init(&thd->event_head); list_init(&thd->event_list, thd); @@ -627,18 +654,23 @@ thd_sched_events_produce(struct thread *thd, struct cos_cpu_local_info *cos_info static inline void thd_rcvcap_pending_deliver(struct thread *thd, struct pt_regs *regs) { - unsigned long thd_state = 0, cycles = 0, timeout = 0; + unsigned long thd_state = 0, cycles = 0, timeout = 0, pending = 0; + int all_pending = thd_rcvcap_all_pending_get(thd); thd_state_evt_deliver(thd, &thd_state, &cycles, &timeout); - thd_rcvcap_pending_reset(thd); - thd_sched_events_produce(thd, cos_cpu_local_info()); - __userregs_setretvals(regs, thd_rcvcap_pending(thd), thd_state, cycles, timeout); + if (all_pending) { + pending = thd_rcvcap_all_pending(thd); + } else { + thd_rcvcap_pending_dec(thd); + pending = thd_rcvcap_pending(thd); + } + __userregs_setretvals(regs, pending, thd_state, cycles, timeout); } static inline int thd_switch_update(struct thread *thd, struct pt_regs *regs, int issame) { - int preempt = 0, pending = 0; + int preempt = 0; /* TODO: check FPU */ /* fpu_save(thd); */ @@ -650,7 +682,7 @@ thd_switch_update(struct thread *thd, struct pt_regs *regs, int issame) assert(!(thd->state & THD_STATE_PREEMPTED)); thd->state &= ~THD_STATE_RCVING; thd_rcvcap_pending_deliver(thd, regs); - pending = thd_rcvcap_pending(thd); + /* * If a scheduler thread was running using child tcap and blocked on RCVING * and budget expended logic decided to run the scheduler thread with it's @@ -666,7 +698,7 @@ thd_switch_update(struct thread *thd, struct pt_regs *regs, int issame) } if (issame && preempt == 0) { - __userregs_set(regs, pending, __userregs_getsp(regs), __userregs_getip(regs)); + __userregs_set(regs, 0, __userregs_getsp(regs), __userregs_getip(regs)); } return preempt;