diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build/linker/linker.C | 2 | ||||
-rw-r--r-- | src/include/arch/ppc.H | 7 | ||||
-rw-r--r-- | src/include/sys/mm.h | 10 | ||||
-rw-r--r-- | src/include/sys/vfs.h | 38 | ||||
-rw-r--r-- | src/include/usr/hbotcompid.H | 10 | ||||
-rw-r--r-- | src/include/usr/initservice/initsvcreasoncodes.H | 1 | ||||
-rw-r--r-- | src/include/usr/vfs/vfs.H | 41 | ||||
-rw-r--r-- | src/include/usr/vfs/vfs_reasoncodes.H | 22 | ||||
-rw-r--r-- | src/include/util/align.H | 3 | ||||
-rw-r--r-- | src/lib/syscall_mm.C | 32 | ||||
-rw-r--r-- | src/makefile | 2 | ||||
-rw-r--r-- | src/sys/init/init_main.C | 9 | ||||
-rw-r--r-- | src/sys/vfs/vfs_init.C | 31 | ||||
-rw-r--r-- | src/sys/vfs/vfs_main.C | 94 | ||||
-rw-r--r-- | src/usr/cxxtest/cxxtestexec.C | 2 | ||||
-rw-r--r-- | src/usr/initservice/baseinitsvc/initservice.C | 104 | ||||
-rw-r--r-- | src/usr/initservice/baseinitsvc/initsvctasks.H | 21 | ||||
-rw-r--r-- | src/usr/initservice/common/initsvcstructs.H | 12 | ||||
-rw-r--r-- | src/usr/initservice/extinitsvc/extinitsvc.C | 21 | ||||
-rw-r--r-- | src/usr/initservice/extinitsvc/extinitsvctasks.H | 7 | ||||
-rw-r--r-- | src/usr/makefile | 4 | ||||
-rw-r--r-- | src/usr/vfs/makefile | 8 | ||||
-rw-r--r-- | src/usr/vfs/vfsrp.C | 317 | ||||
-rw-r--r-- | src/usr/vfs/vfsrp.H | 90 |
24 files changed, 787 insertions, 101 deletions
diff --git a/src/build/linker/linker.C b/src/build/linker/linker.C index 8e7b2f71c..de2694fdd 100644 --- a/src/build/linker/linker.C +++ b/src/build/linker/linker.C @@ -23,7 +23,9 @@ #include <stdexcept> #include <sstream> +#define LINKER_C #include "../../include/sys/vfs.h" +#undef LINKER_C using std::cout; using std::cerr; diff --git a/src/include/arch/ppc.H b/src/include/arch/ppc.H index bed75b258..212f32d1f 100644 --- a/src/include/arch/ppc.H +++ b/src/include/arch/ppc.H @@ -210,6 +210,13 @@ inline void dcbf(void* _ptr) } ALWAYS_INLINE +inline void dcbst(void* _ptr) +{ + register void* ptr = _ptr; + asm volatile("dcbst 0, %0" : : "b" (ptr) : "memory"); +} + +ALWAYS_INLINE inline void dcbz(void* _ptr) { register void* ptr = _ptr; diff --git a/src/include/sys/mm.h b/src/include/sys/mm.h index 4719ff7df..71e41d24c 100644 --- a/src/include/sys/mm.h +++ b/src/include/sys/mm.h @@ -2,6 +2,7 @@ #define __SYS_MM_H #include <stdint.h> +#include <limits.h> #include <sys/msg.h> #ifdef __cplusplus @@ -24,4 +25,13 @@ int mm_alloc_block(msg_q_t mq,void* va,uint64_t size); } #endif +/** @fs mm_icache_invalidate() + * @brief Invalidate the ICACHE for the given memory + * + * @param[in] i_addr - Destination address + * @param[in] i_cpu_word_count - number of CPU_WORDs (uint64_t) + */ +void mm_icache_invalidate(void * i_addr, size_t i_cpu_word_count); + + #endif diff --git a/src/include/sys/vfs.h b/src/include/sys/vfs.h index 5c28e29b8..27337f469 100644 --- a/src/include/sys/vfs.h +++ b/src/include/sys/vfs.h @@ -2,12 +2,20 @@ #define __SYS_VFS_H #include <stdint.h> +// NOTE!. This file is included by linker.C and can't include non standard header files +#ifndef LINKER_C +// other includes not visable to the linker +#include <sys/task.h> +#endif // make TODO VFS_MODULE_MAX equal to the actual number of modules in the base image (+ 2?) #define VFS_MODULE_MAX 64 // Extended use 4 4k pages +// Extended Module Virtual address at 1GB +#define VFS_EXTENDED_MODULE_VADDR (1 * 1024 * 1024 * 1024) +#define VFS_EXTENDED_MODULE_TABLE_ADDRESS (VFS_EXTENDED_MODULE_VADDR) +#define VFS_EXTENDED_MODULE_TABLE_OFFSET 0 #define VFS_EXTENDED_MODULE_MAX 128 -#define VFS_EXTENDED_MODULE_TABLE_ADDRESS 0x0000000040000000UL #define VFS_MODULE_NAME_MAX 64 #define VFS_SYMBOL_INIT _init #define VFS_SYMBOL_START _start @@ -32,12 +40,15 @@ extern const char* VFS_ROOT; extern const char* VFS_ROOT_BIN; extern const char* VFS_ROOT_DATA; extern const char* VFS_ROOT_MSG; +extern const char* VFS_MSG; enum VfsMessages { - VFS_MSG_REGISTER_MSGQ, - VFS_MSG_RESOLVE_MSGQ, - VFS_MSG_EXEC, + VFS_MSG_REGISTER_MSGQ, //!< Message to VFS_ROOT to register a message queue + VFS_MSG_RESOLVE_MSGQ, //!< Message to VFS_ROOT to find a message queue + VFS_MSG_EXEC, //!< Message to VFS_ROOT execute a module + VFS_MSG_LOAD, //!< Message to VFS_MSG to load a module + VFS_MSG_UNLOAD, //!< Message to VFS_MSG to unload a module }; struct VfsSystemModule @@ -52,10 +63,29 @@ struct VfsSystemModule }; extern VfsSystemModule VFS_MODULES[VFS_MODULE_MAX]; + extern uint64_t VFS_LAST_ADDRESS; #ifdef __cplusplus } #endif +#ifndef LINKER_C +/** + * Find the VfsSystemModule data for the given module name + * @param[in] i_table VFS module table + * @param[in] i_name name of module to find + * @return VfsSystemModule ptr to data | NULL if not found + */ +VfsSystemModule * vfs_find_module(VfsSystemModule * i_table, const char * i_name); + +/** + * Call the module start routine + * @param[in] i_module VfsSystemModule data for the module + * @param[in] i_param parameter to pass to task_create() for this module + * @return tid_t of started task | -1 if i_module is NULL | -2 if there is no start() + */ +tid_t vfs_exec(VfsSystemModule * i_module, void* i_param); +#endif + #endif diff --git a/src/include/usr/hbotcompid.H b/src/include/usr/hbotcompid.H index f39479148..fb75595e3 100644 --- a/src/include/usr/hbotcompid.H +++ b/src/include/usr/hbotcompid.H @@ -60,7 +60,7 @@ const char SCOM_COMP_NAME[] = "scom"; //@{ const compId_t XSCOM_COMP_ID = 0x0400; const char XSCOM_COMP_NAME[] = "xscom"; - +//@} /** @name INITSERVICE * Initialization Service component */ @@ -85,4 +85,12 @@ const compId_t I2C_COMP_ID = 0x0700; const char I2C_COMP_NAME[] = "i2c"; //@} +/** @name VFS + * Virtual File System component + */ +//@{ +const compId_t VFS_COMP_ID = 0x0800; +const char VFS_COMP_NAME[] = "vfs"; +//@} + #endif diff --git a/src/include/usr/initservice/initsvcreasoncodes.H b/src/include/usr/initservice/initsvcreasoncodes.H index 83d1c9f28..9d5484e42 100644 --- a/src/include/usr/initservice/initsvcreasoncodes.H +++ b/src/include/usr/initservice/initsvcreasoncodes.H @@ -45,6 +45,7 @@ enum InitServiceModuleID VERIFY_ERRL_IDEC_ERRL_ID, DISABLE_WATCHDOG_ERRL_ID, EXECUTE_ISTEPS_ERRL_ID, + START_VFS_ERRL_ID, ISTEP_1_ERRL_ID, ISTEP_2_ERRL_ID, diff --git a/src/include/usr/vfs/vfs.H b/src/include/usr/vfs/vfs.H new file mode 100644 index 000000000..bffbddaa0 --- /dev/null +++ b/src/include/usr/vfs/vfs.H @@ -0,0 +1,41 @@ +#ifndef __USR_VFS_H +#define __USR_VFS_H + +#include <errl/errlentry.H> +#include <sys/vfs.h> + +namespace VFS +{ + /** + * Load or unload a module from the extended image. + * @param[in] i_module Module name + * @param[in] i_msgtype [VFS_MSG_LOAD | VFS_MSG_UNLOAD] + * @return errlHandl_t on error + */ + errlHndl_t module_load_unload(const char * i_module, VfsMessages i_msgtype); + + /** + * Loads a module from the extended image and initializes it + * @param[in] i_module Module name + * @return errlHndl_t on error + */ + ALWAYS_INLINE + inline errlHndl_t module_load(const char * i_module) + { + return VFS::module_load_unload(i_module,VFS_MSG_LOAD); + } + + /** + * Destroys and unloads module. + * @param[in] i_module Module name + * @return errlHndl_t on error + */ + ALWAYS_INLINE + inline errlHndl_t module_unload(const char * i_module) + { + return VFS::module_load_unload(i_module, VFS_MSG_UNLOAD); + } + +}; + +#endif diff --git a/src/include/usr/vfs/vfs_reasoncodes.H b/src/include/usr/vfs/vfs_reasoncodes.H new file mode 100644 index 000000000..eed6c5ad5 --- /dev/null +++ b/src/include/usr/vfs/vfs_reasoncodes.H @@ -0,0 +1,22 @@ +#ifndef VFS_REASONCODES_H +#define VFS_REASONCODES_H + +#include <hbotcompid.H> + +namespace VFS +{ + enum VfsModuleID + { + UNDEFINED_MODULE_ERRL_ID = 0, + VFS_MODULE_ID, + }; + + enum VfsReasonCode + { + VFS_LOAD_FAILED = VFS_COMP_ID | 0x01, + VFS_UNLOAD_FAILED = VFS_COMP_ID | 0x02, + VFS_ALLOC_VMEM_FAILED = VFS_COMP_ID | 0x03, + }; +}; + +#endif diff --git a/src/include/util/align.H b/src/include/util/align.H index 3edbff09a..d95cdae0f 100644 --- a/src/include/util/align.H +++ b/src/include/util/align.H @@ -1,6 +1,9 @@ #ifndef __UTIL_ALIGN_H #define __UTIL_ALIGN_H +#include <limits.h> + #define ALIGN_4(u) ((u + 0x3ull) & ~0x3ull) +#define ALIGN_PAGE(u) ((u + (PAGESIZE-1)) & ~(PAGESIZE-1)) #endif diff --git a/src/lib/syscall_mm.C b/src/lib/syscall_mm.C index 187cdced2..ba527073f 100644 --- a/src/lib/syscall_mm.C +++ b/src/lib/syscall_mm.C @@ -1,5 +1,6 @@ #include <sys/syscall.h> #include <sys/mm.h> +#include <arch/ppc.H> using namespace Systemcalls; @@ -10,3 +11,34 @@ int mm_alloc_block(msg_q_t mq,void* va,uint64_t size) { return (int64_t)_syscall3(MM_ALLOC_BLOCK, mq, va, (void*)size); } + + +/* + * Call to flush out the instruction cache + * From the PowerPC ISA book II, section 1.8 + * Instruction Storage + */ +void mm_icache_invalidate(void * i_addr, size_t i_cpu_word_count) +{ + // Make sure 8 byte boundary + uint64_t addr = (uint64_t)i_addr & ~0x7ull; + uint64_t * dest = (uint64_t*)addr; + + for(size_t i = 0; i < i_cpu_word_count; ++i) + { + dcbst(dest); + ++dest; + } + + lwsync(); + + dest = (uint64_t*)addr; + for(size_t i = 0; i < i_cpu_word_count; ++i) + { + icbi(dest); + ++dest; + } + + isync(); +} + diff --git a/src/makefile b/src/makefile index afe0e5339..5de8aef96 100644 --- a/src/makefile +++ b/src/makefile @@ -36,7 +36,7 @@ DIRECT_BOOT_OBJECTS = start.o kernel.o taskmgr.o cpumgr.o syscall.o \ RUNTIME_OBJECTS = -BASE_MODULES = trace errl devicefw scom xscom initservice taskargs pnor i2c +BASE_MODULES = trace errl devicefw scom xscom initservice taskargs pnor vfs i2c EXTENDED_MODULES = targeting ecmddatabuffer hwpf fapi hwp plat \ extinitsvc istepdisp isteps DIRECT_BOOT_MODULES = example diff --git a/src/sys/init/init_main.C b/src/sys/init/init_main.C index 6292500e3..da83838e4 100644 --- a/src/sys/init/init_main.C +++ b/src/sys/init/init_main.C @@ -15,16 +15,15 @@ void vfs_main(void*); void init_main(void* unused) { tid_t tidrc = 0; + barrier_t l_barrier; + barrier_init(&l_barrier,2); printk("Starting init!\n"); printk("Bringing up VFS..."); - task_create( &vfs_main, NULL ); - - // TODO... add a barrier to ensure VFS is fully up. - while (NULL == _syscall0(Systemcalls::MSGQ_RESOLVE_ROOT)) - task_yield(); + task_create( &vfs_main, &l_barrier ); + barrier_wait(&l_barrier); // run initialization service to start up everything else. printk("init_main: Starting Initialization Service...\n"); diff --git a/src/sys/vfs/vfs_init.C b/src/sys/vfs/vfs_init.C index 259252171..77ce140d7 100644 --- a/src/sys/vfs/vfs_init.C +++ b/src/sys/vfs/vfs_init.C @@ -1,9 +1,15 @@ +/** + * @file vfs_init.C + * @brief function definitions for funtions used to initialize modules + */ #include <sys/vfs.h> #include <kernel/console.H> VfsSystemModule VFS_MODULES[VFS_MODULE_MAX]; uint64_t VFS_LAST_ADDRESS; +// ---------------------------------------------------------------------------- + void vfs_module_init() { printk("Initializing modules.\n"); @@ -22,18 +28,23 @@ void vfs_module_init() printk("Modules initialized.\n"); } -void (*vfs_module_find_start(const char* modName))(void*) +// ---------------------------------------------------------------------------- + +VfsSystemModule * vfs_find_module(VfsSystemModule * i_table, + const char * i_name) { - VfsSystemModule* module = &VFS_MODULES[0]; + VfsSystemModule* module = i_table; + VfsSystemModule* ret = NULL; while ('\0' != module->module[0]) { - if (0 == strcmp(modName, module->module)) - { - return module->start; - } - - module++; + if (0 == strcmp(i_name,module->module)) + { + ret = module; + break; + } + module++; } - - return NULL; + return ret; } + + diff --git a/src/sys/vfs/vfs_main.C b/src/sys/vfs/vfs_main.C index 36d6ddcff..4308da8d4 100644 --- a/src/sys/vfs/vfs_main.C +++ b/src/sys/vfs/vfs_main.C @@ -3,6 +3,7 @@ #include <sys/msg.h> #include <sys/vfs.h> #include <sys/task.h> +#include <sys/sync.h> #include <util/locked/list.H> #include <kernel/console.H> // TODO : Remove this. @@ -11,9 +12,18 @@ const char* VFS_ROOT = "/"; const char* VFS_ROOT_BIN = "/bin/"; const char* VFS_ROOT_DATA = "/data/"; const char* VFS_ROOT_MSG = "/msg/"; +const char* VFS_MSG = "/vfs/"; void vfs_module_init(); +/** + * Call the module start routine + * @param[in] i_module VfsSystemModule data for the module + * @param[in] i_param parameter to pass to task_create() for this module + * @return tid_t of started task | -1 if i_module is NULL | -2 if there is no start() + */ +tid_t vfs_exec(VfsSystemModule * i_module, void* i_param); + struct VfsPath { char key[64]; @@ -31,14 +41,16 @@ struct VfsEntry VfsEntry* prev; }; -void vfs_main(void* unused) +void vfs_main(void* i_barrier) { + barrier_t * barrier = (barrier_t *)i_barrier; // Create message queue, register with kernel. msg_q_t vfsMsgQ = msg_q_create(); msg_q_register(vfsMsgQ, VFS_ROOT); printk("done.\n"); - // TODO... barrier with init. + + barrier_wait(barrier); // Initalize modules. vfs_module_init(); @@ -81,28 +93,40 @@ void vfs_main(void* unused) { printk("VFS: Got exec request of %s\n", (const char*)msg->data[0]); - VfsSystemModule* module = &VFS_MODULES[0]; - tid_t child = -1; - while ('\0' != module->module[0]) - { - if (0 == strcmp((const char*) msg->data[0], - module->module)) - { - if ( module->start == NULL) - { - // module has no _start() routine, - // return child = -2 - child = -2; - break; - } - child = task_create(module->start, - (void*) msg->data[1]); - break; - } - module++; - } - msg->data[0] = child; - msg_respond(vfsMsgQ, msg); + + VfsSystemModule* module = + vfs_find_module(VFS_MODULES, + (const char *) msg->data[0]); + + tid_t child = vfs_exec(module,(void*) msg->data[1]); + + // child == -1 means module not found in base image so send + // a message to VFS_MSG queue to look in the extended image + // VFS_MSG queue will handle the msg_respond() + if( child == -1 ) // forward msg to usr vfs + { + VfsEntry::key_type k; + strcpy(k.key, VFS_MSG); + VfsEntry* e = vfsContents.find(k); + if(e != NULL) + { + msg_t* emsg = msg_allocate(); + emsg->type = msg->type; + emsg->data[0] = (uint64_t) msg; + emsg->data[1] = (uint64_t) vfsMsgQ; + msg_send(e->msg_q, emsg); // send async msg + } + else // Cant find VFS_MSG queue - not started yet + { + msg->data[0] = child; + msg_respond(vfsMsgQ, msg); + } + } + else // send back child (or errno) + { + msg->data[0] = child; + msg_respond(vfsMsgQ, msg); + } } break; @@ -112,3 +136,25 @@ void vfs_main(void* unused) } } // end while(1) } + +// ---------------------------------------------------------------------------- + +tid_t vfs_exec(VfsSystemModule * i_module, void* i_param) +{ + tid_t child = -1; + if(i_module != NULL) + { + if (i_module->start == NULL) + { + child = -2; // module has no start() routine + } + else + { + child = task_create(i_module->start, i_param); + } + } + return child; +} + + + diff --git a/src/usr/cxxtest/cxxtestexec.C b/src/usr/cxxtest/cxxtestexec.C index 5470b718a..645858c95 100644 --- a/src/usr/cxxtest/cxxtestexec.C +++ b/src/usr/cxxtest/cxxtestexec.C @@ -56,6 +56,8 @@ TRAC_INIT(&g_trac_cxxtest, "CXXTEST", 1024 ); extern "C" void _start(void *io_pArgs) { + // TODO These modules will eventually all be in the extended binary. + // VfsSystemModule* vfsItr = (VfsSystemModule*) VFS_EXTENDED_MODULE_TABLE_ADDRESS; VfsSystemModule* vfsItr = &VFS_MODULES[0]; tid_t tidrc = 0; uint64_t totalmodules = 0; diff --git a/src/usr/initservice/baseinitsvc/initservice.C b/src/usr/initservice/baseinitsvc/initservice.C index dc8380f19..55e395c49 100644 --- a/src/usr/initservice/baseinitsvc/initservice.C +++ b/src/usr/initservice/baseinitsvc/initservice.C @@ -25,6 +25,7 @@ #include <kernel/console.H> #include <sys/vfs.h> +#include <vfs/vfs.H> #include <sys/task.h> #include <trace/interface.H> #include <errl/errlentry.H> @@ -77,54 +78,66 @@ errlHndl_t InitService::startTask( const TaskInfo *i_ptask, assert(i_ptask->taskflags.task_type == START_TASK); - tidrc = task_exec( i_ptask->taskname, io_pargs ); // launch the child - if ( static_cast<int16_t>(tidrc) < 0 ) + // Base modules have already been loaded and initialized, + // extended modules have not. + if(i_ptask->taskflags.module_type == EXT_IMAGE) { - // task failed to launch, post an errorlog and dump some trace - /*@ errorlog tag - * @errortype ERRL_SEV_CRITICAL_SYS_TERM - * @moduleid see task list - * @reasoncode START_TASK_FAILED - * @userdata1 task id or task return code - * @userdata2 0 - * - * @devdesc Initialization Service failed to start a task. - * The module id will identify the task. - * - */ - lo_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, // severity - i_ptask->taskflags.module_id, // moduleid - INITSERVICE::START_TASK_FAILED, // reason Code - tidrc, // user1 = tidrc - 0 - ); - TRACDBIN( g_trac_initsvc, - "ERROR starting task:", - i_ptask->taskname, - strlen(i_ptask->taskname) ); - TRACDCOMP( g_trac_initsvc, - "tidrc=%d, errlog p = %p" , - (int16_t)tidrc, lo_errl ); + // load module and call _init() + lo_errl = VFS::module_load( i_ptask->taskname ); + } - } // endif tidrc - else + if( !lo_errl) { - // task launched OK. - TRACDBIN( g_trac_initsvc, - "Task finished OK :", - i_ptask->taskname, - strlen(i_ptask->taskname) ); - TRACDCOMP( g_trac_initsvc, - "task number %d, errlog p = %p", - tidrc, lo_errl ); + tidrc = task_exec( i_ptask->taskname, io_pargs ); // launch the child - if ( io_pargs ) + if ( static_cast<int16_t>(tidrc) < 0 ) { - io_pargs->waitParentSync(); // sync up childtask - } + // task failed to launch, post an errorlog and dump some trace + /*@ errorlog tag + * @errortype ERRL_SEV_CRITICAL_SYS_TERM + * @moduleid see task list + * @reasoncode START_TASK_FAILED + * @userdata1 task id or task return code + * @userdata2 0 + * + * @devdesc Initialization Service failed to start a task. + * The module id will identify the task. + * + */ + lo_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, // severity + i_ptask->taskflags.module_id, // moduleid + INITSERVICE::START_TASK_FAILED, // reason Code + tidrc, // user1 = tidrc + 0 + ); + TRACDBIN( g_trac_initsvc, + "ERROR starting task:", + i_ptask->taskname, + strlen(i_ptask->taskname) ); + TRACDCOMP( g_trac_initsvc, + "tidrc=%d, errlog p = %p" , + (int16_t)tidrc, lo_errl ); + + } // endif tidrc + else + { + // task launched OK. + TRACDBIN( g_trac_initsvc, + "Task finished OK :", + i_ptask->taskname, + strlen(i_ptask->taskname) ); + TRACDCOMP( g_trac_initsvc, + "task number %d, errlog p = %p", + tidrc, lo_errl ); + if ( io_pargs ) + { + io_pargs->waitParentSync(); // sync up childtask + } + } } + // else module load failed. have error log return lo_errl; } @@ -315,6 +328,15 @@ void InitService::init( void *i_ptr ) "task_type==BARRIER" ); // $$TODO break; + + case UNINIT_TASK: + TRACDBIN( g_trac_initsvc, + "task_type=UNINIT_TASK : ", + ptask->taskname, + strlen(ptask->taskname) ); + errl = VFS::module_unload( ptask->taskname ); + break; + default: TRACDCOMP( g_trac_initsvc, "Invalid task_type %d: ", diff --git a/src/usr/initservice/baseinitsvc/initsvctasks.H b/src/usr/initservice/baseinitsvc/initsvctasks.H index bf9c925f4..297386ab7 100644 --- a/src/usr/initservice/baseinitsvc/initsvctasks.H +++ b/src/usr/initservice/baseinitsvc/initsvctasks.H @@ -61,18 +61,31 @@ const TaskInfo g_taskinfolist[] = { } }, + /** + * @brief Extended VFS module + */ + { + "libvfs.so", // taskname + NULL, + { + START_TASK, // start task + BASE_IMAGE, // Base Module + START_VFS_ERRL_ID, // module id for error log + } + }, + // ----- Extended Image ----------------------------------------------------- /** * @brief extinitsvc, initializes extended module area */ { - "libextinitsvc.so" , // taskname + "libextinitsvc.so" , // taskname NULL, // no pointer to fn { - START_TASK, // don't start - EXT_IMAGE, // Ext Module - START_EXTINITSVC_ERRL_ID, // module id for errorlog + START_TASK, // call start() + BASE_IMAGE, // TODO EXT_IMAGE + START_EXTINITSVC_ERRL_ID, // module id for errorlog } }, diff --git a/src/usr/initservice/common/initsvcstructs.H b/src/usr/initservice/common/initsvcstructs.H index f78c093b8..9d169c676 100644 --- a/src/usr/initservice/common/initsvcstructs.H +++ b/src/usr/initservice/common/initsvcstructs.H @@ -43,21 +43,25 @@ namespace INITSERVICE /** * @enum TaskType * - NONE == placeholder, no task - * - START_TASK == task with _start() function entry point + * - INIT_TASK == load and initialize task, but task has no _start() + * (extended image only) + * - START_TASK == BASE_IMAGE: call _start() function entry point + * EXT_IMAGE: call _init(), then _start() * - START_FN == task with function pointer entry point * - BARRIER == set barrier for next N tasks. - * - STOP_TASK == Execute the destructor on the task in extended image. - * ( not implemented yet) + * - UNINIT_TASK == call _fini() to call static destructor(s) on the task. + * (extended image only) * - END_TASK_LIST == last entry in the task list. */ enum TaskType { UNDEFINED_TT = 0, NONE, + INIT_TASK, START_TASK, START_FN, BARRIER, - STOP_TASK, + UNINIT_TASK, END_TASK_LIST, }; diff --git a/src/usr/initservice/extinitsvc/extinitsvc.C b/src/usr/initservice/extinitsvc/extinitsvc.C index db1baef50..1b5612645 100644 --- a/src/usr/initservice/extinitsvc/extinitsvc.C +++ b/src/usr/initservice/extinitsvc/extinitsvc.C @@ -24,7 +24,7 @@ */ #include <kernel/console.H> -#include <sys/vfs.h> +#include <vfs/vfs.H> #include <sys/task.h> #include <sys/sync.h> #include <sys/misc.h> @@ -132,7 +132,15 @@ void ExtInitSvc::init( void *i_ptr ) ptask->taskname, strlen(ptask->taskname) ); break; - case START_TASK: + case INIT_TASK: + TRACDBIN( g_trac_initsvc, + "task_type==INIT_TASK : ", + ptask->taskname, + strlen(ptask->taskname) ); + errl = VFS::module_load( ptask->taskname ); + break; + + case START_TASK: // call _init(), _start(), stay resident TRACDBIN( g_trac_initsvc, "task_type=START_TASK : ", ptask->taskname, @@ -140,6 +148,7 @@ void ExtInitSvc::init( void *i_ptr ) errl = InitService::getTheInstance().startTask( ptask, &args ); break; + case START_FN: TRACDCOMP( g_trac_initsvc, "task_type==START_FN : %p", @@ -154,6 +163,14 @@ void ExtInitSvc::init( void *i_ptr ) // $$TODO break; + case UNINIT_TASK: + TRACDBIN( g_trac_initsvc, + "task_type=UNINIT_TASK : ", + ptask->taskname, + strlen(ptask->taskname) ); + errl = VFS::module_unload( ptask->taskname ); + break; + default: TRACDCOMP( g_trac_initsvc, "Invalid task_type: %d", diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H index 9c31bc81d..d65abb914 100644 --- a/src/usr/initservice/extinitsvc/extinitsvctasks.H +++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H @@ -30,6 +30,7 @@ namespace INITSERVICE { + // TODO all these will eventuall be in BASE_IMAGE instead of BASE_IMAGE const uint64_t MAX_EXT_TASKS = 25; @@ -45,7 +46,7 @@ const TaskInfo g_exttaskinfolist[] = { NULL, // no pointer to fn { START_TASK, // task type - EXT_IMAGE, // Extended Module + BASE_IMAGE, // Extended Module START_TARGETING_ERRL_ID, // module id } }, @@ -58,7 +59,7 @@ const TaskInfo g_exttaskinfolist[] = { NULL, // no pointer to fn { START_TASK, // task type - EXT_IMAGE, // Extended Module + BASE_IMAGE, // Extended Module EXECUTE_ISTEPS_ERRL_ID, // module id } }, @@ -89,7 +90,7 @@ const TaskInfo CXXTEST_TASK = { NULL, // no pointer to fn { START_TASK, // task type - EXT_IMAGE, // Extended Module + BASE_IMAGE, // Extended Module START_CXXTEST_ERRL_ID, // module id } }; diff --git a/src/usr/makefile b/src/usr/makefile index dc1bffa15..25bf96d4d 100644 --- a/src/usr/makefile +++ b/src/usr/makefile @@ -3,7 +3,7 @@ ROOTPATH = ../.. OBJS = module_init.o SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \ - scom.d xscom.d targeting.d initservice.d hwpf.d \ - ecmddatabuffer.d isteps.d pnor.d i2c.d + scom.d xscom.d targeting.d initservice.d hwpf.d \ + ecmddatabuffer.d isteps.d pnor.d vfs.d i2c.d include ${ROOTPATH}/config.mk diff --git a/src/usr/vfs/makefile b/src/usr/vfs/makefile new file mode 100644 index 000000000..2212d9d4f --- /dev/null +++ b/src/usr/vfs/makefile @@ -0,0 +1,8 @@ +ROOTPATH = ../../.. +MODULE = vfs + +OBJS = vfsrp.o + +#SUBDIRS = test.d + +include ${ROOTPATH}/config.mk diff --git a/src/usr/vfs/vfsrp.C b/src/usr/vfs/vfsrp.C new file mode 100644 index 000000000..04e90ecc0 --- /dev/null +++ b/src/usr/vfs/vfsrp.C @@ -0,0 +1,317 @@ +/** + * @file vfsrp.C + * @brief Virtual File system Extended image support + */ + +#include <limits.h> +#include <string.h> +#include <errno.h> +#include <sys/msg.h> +#include <sys/vfs.h> +#include <vfs/vfs.H> +#include <vfs/vfs_reasoncodes.H> +#include <sys/task.h> +#include <sys/mm.h> +#include <initservice/taskargs.H> +#include <trace/interface.H> +#include "vfsrp.H" +#include <pnor/pnorif.H> +#include <util/align.H> + +using namespace VFS; + +// Trace definitions +trace_desc_t * g_trac_vfs = NULL; +TRAC_INIT(&g_trac_vfs, VFS_COMP_NAME, 1024); + +/** + * setup _start and handle barrier + */ +TASK_ENTRY_MACRO( VfsRp::init ); + +// ---------------------------------------------------------------------------- + +VfsRp::~VfsRp() +{ + // Unloading of this module currently not supported. + // unregister msg queue? Currently can't do that + // msg_q_destroy(iv_msgQ); +} + +// ---------------------------------------------------------------------------- + +/** + * STATIC initializer of vfs resource provider entry point + */ +void VfsRp::init( void * i_taskArgs ) +{ + errlHndl_t err = NULL; + err = Singleton<VfsRp>::instance()._init(); + INITSERVICE::TaskArgs::TaskArgs* args = (INITSERVICE::TaskArgs::TaskArgs*)i_taskArgs; + if(err) + { + args->postErrorLog(err); + } +} + +// ---------------------------------------------------------------------------- + +/** + * Helper function to start vfs messge handler + */ +void VfsRp::msg_handler(void * unused) +{ + Singleton<VfsRp>::instance().msgHandler(); +} + +// ---------------------------------------------------------------------------- + +void VfsRp::load_unload(void * i_msg) +{ + Singleton<VfsRp>::instance()._load_unload((msg_t*)i_msg); + task_end(); +} + +// ---------------------------------------------------------------------------- + +void VfsRp::exec(void * i_msg) +{ + Singleton<VfsRp>::instance()._exec((msg_t*)i_msg); + task_end(); +} + +// ---------------------------------------------------------------------------- + +/** + * Initialze the vfs resource provider + */ +errlHndl_t VfsRp::_init() +{ + errlHndl_t err = NULL; + size_t rc = 0; + iv_msgQ = msg_q_create(); + rc = msg_q_register(iv_msgQ, VFS_MSG); + + // Discover PNOR virtual address of extended image + PNOR::SectionInfo_t l_pnor_info; + + // How will SIDE eventually be determined? TODO + err = PNOR::getSectionInfo(PNOR::HB_EXT_CODE, PNOR::SIDE_A, l_pnor_info); + if(!err) + { + iv_pnor_vaddr = l_pnor_info.vaddr; + + rc = mm_alloc_block + (iv_msgQ, + (void *)VFS_EXTENDED_MODULE_VADDR, + ALIGN_PAGE(l_pnor_info.size) + ); + if(rc == 0) + { + // Start msg_handler + // NOTE: This would be a weak consistancy issues if + // task_create were not a system call. + task_create(VfsRp::msg_handler, NULL); + } + else + { + err = new ERRORLOG::ErrlEntry + ( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, // severity + VFS::VFS_MODULE_ID, // moduleid + VFS::VFS_ALLOC_VMEM_FAILED, // reason Code + rc, // user1 = rc + 0 // user2 + ); + } + } + + return err; +} + + +// ---------------------------------------------------------------------------- + +void VfsRp::msgHandler() +{ + while(1) + { + msg_t* msg = msg_wait(iv_msgQ); + + switch(msg->type) + { + case VFS_MSG_LOAD: + { + TRACDBIN(g_trac_vfs, "INFO: load module ", + (const char *) msg->data[0], + strlen((const char *) msg->data[0])); + + // run in own task so page faults can be handled + task_create(load_unload, msg); + } + break; + + case VFS_MSG_UNLOAD: + { + TRACDBIN(g_trac_vfs, "INFO: unload module ", + (const char *) msg->data[0], + strlen((const char *) msg->data[0])); + + // run in own task so page faults can be handled + task_create(load_unload, msg); + + } + break; + + case VFS_MSG_EXEC: + { + msg_t * msg1 = (msg_t *) msg->data[0]; + TRACDCOMP(g_trac_vfs, "VFS: Got exec request of %s", + (const char*)msg1->data[0]); + + // run in own task so page faults can be handled + task_create(exec, msg); + + } + break; + + case MSG_MM_RP_READ: + { + uint64_t vaddr = msg->data[0]; + uint64_t paddr = msg->data[1]; //page aligned + + vaddr -= vaddr % PAGE_SIZE; + vaddr -= VFS_EXTENDED_MODULE_VADDR; + memcpy((void *)paddr, (void *)(iv_pnor_vaddr+vaddr), + PAGE_SIZE); + + mm_icache_invalidate((void*)paddr,PAGE_SIZE/8); + + } + msg->data[1] = 0; + msg_respond(iv_msgQ, msg); + break; + + case MSG_MM_RP_WRITE: + assert(0); // not supported now + //msg->data[1] = 0; + //msg_respond(iv_msgQ, msg); + break; + + case MSG_MM_RP_PERM: + msg->data[1] = -EINVAL; + msg_respond(iv_msgQ, msg); + break; + + default: + msg_free(msg); + break; + } + } // while(1) +} + +// ---------------------------------------------------------------------------- + +void VfsRp::_load_unload(msg_t * i_msg) +{ + errlHndl_t err = NULL; + // Find VfsSystemModule + // The TOC for the extended image sits at the start of the image and is + // not location dependant, so just use the one pointed to by iv_pnor_vaddr + // to avoid having to copy it to this block + VfsSystemModule * module = + vfs_find_module + ( + (VfsSystemModule *)iv_pnor_vaddr, //VFS_EXTENDED_MODULE_TABLE_ADDRESS, + (const char *) i_msg->data[0] + ); + + if(module) + { + // TODO mark text page(s) as ro/executable + // TODO mark data page(s) as rw + if(i_msg->type == VFS_MSG_LOAD) + { + if(module->init) + { + (module->init)(NULL); + } + } + else // unload + { + if(module->fini) + { + (module->fini)(NULL); + } + + // TODO mark pages as no access + } + } + else + { + // TODO error log? for now it's probably in the base + // and is aready loaded and initialized. + TRACFBIN(g_trac_vfs, ERR_MRK"Module not found: ", + (const char *) i_msg->data[0], + strlen((const char *) i_msg->data[0]) ); + } + i_msg->data[0] = (uint64_t) err; + msg_respond(iv_msgQ, i_msg); +} + +// ---------------------------------------------------------------------------- + +void VfsRp::_exec(msg_t * i_msg) +{ + msg_t * msg1 = (msg_t *) i_msg->data[0]; + + // The TOC for the extended image sits at the start of the image and is + // not location dependant, so just use the one pointed to by iv_pnor_vaddr + // to avoid having to copy it to this block + VfsSystemModule * module = + vfs_find_module((VfsSystemModule *)(iv_pnor_vaddr + + VFS_EXTENDED_MODULE_TABLE_OFFSET), + (const char*) msg1->data[0]); + + tid_t child = vfs_exec(module, (void*) msg1->data[1]); + + msg_q_t vfsRmsgQ = (msg_q_t) i_msg->data[1]; + + msg1->data[0] = child; + + msg_respond(vfsRmsgQ,msg1); + msg_free(i_msg); +} + + +// -- External interface ------------------------------------------------------ + +errlHndl_t VFS::module_load_unload(const char * i_module, VfsMessages i_msgtype) +{ + errlHndl_t err = NULL; + msg_q_t vfsQ = msg_q_resolve(VFS_MSG); + msg_t* msg = msg_allocate(); + msg->type = i_msgtype; + msg->data[0] = (uint64_t) i_module; + int rc = msg_sendrecv(vfsQ, msg); + + if (0 == rc) + { + err = (errlHndl_t) msg->data[0]; + } + else + { + err = new ERRORLOG::ErrlEntry + ( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, // severity + VFS::VFS_MODULE_ID, // moduleid + VFS::VFS_LOAD_FAILED, // reason Code + rc, // user1 = msg_sendrecv rc + i_msgtype // user2 = message type + ); + } + + msg_free(msg); + return err; +} + diff --git a/src/usr/vfs/vfsrp.H b/src/usr/vfs/vfsrp.H new file mode 100644 index 000000000..456979e2d --- /dev/null +++ b/src/usr/vfs/vfsrp.H @@ -0,0 +1,90 @@ +#ifndef VFSRP_H +#define VFSRP_H + +#include <stdint.h> +#include <builtins.h> +#include <errl/errltypes.H> + +struct msg_t; + +namespace VFS +{ + void vfs_msg_handler(void * unused); + + /** + * Virtual File System Service + */ + class VfsRp + { + public: + + /** + * static init + * @param[in] task args + */ + static void init(void * i_taskArgs); + + protected: + /** + * Ctor + */ + VfsRp() : iv_msgQ(NULL), iv_pnor_vaddr(0) {} + + /** + * Dtor + */ + ~VfsRp(); + + /** + * Start message handler + */ + static void msg_handler(void * unused); + + /** + * Load or Unload a module + * @param[in] i_msg the message + * @note Does not return. calls task_end() + */ + static void load_unload(void * i_msg); + + /** + * Call _start on module + * @param[in] i_msg the message + * @note Does not return. calls task_end() + */ + static void exec(void * i_msg); + + private: // functions + + /** + * Initialize this object + * @return return code on error + */ + errlHndl_t _init(); + + /** + * Message handler + */ + void msgHandler(); + + /** + * Load or Unload a module + * @param[in] i_msg the message + */ + void _load_unload(msg_t * i_msg); + + /** + * Call _start on module + * @param[in] i_msg the message + */ + void _exec(msg_t * i_msg); + + private: // data + + msg_q_t iv_msgQ; //!< message queue + uint64_t iv_pnor_vaddr; //!< virtual address of ext image in PFNOR + }; + +}; // VFS namepsace + +#endif |