summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordgilbert <dgilbert@us.ibm.com>2011-07-28 16:42:28 -0500
committerDouglas R. Gilbert <dgilbert@us.ibm.com>2011-08-17 14:22:39 -0500
commitc56648379cde6ea3bcfac07923bb560734c6e16f (patch)
tree81ee3d5abaa130d0f1e36e038c3a344e11f55ce0 /src
parent20b03fdaeb7414fdf9d43634976ca1ab5fbac7f1 (diff)
downloadtalos-hostboot-c56648379cde6ea3bcfac07923bb560734c6e16f.tar.gz
talos-hostboot-c56648379cde6ea3bcfac07923bb560734c6e16f.zip
Virtual File System module load and unload
Change-Id: Iaa6a256a8a15ac48bfba5bc1cab292c5ac246166 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/253 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/build/linker/linker.C2
-rw-r--r--src/include/arch/ppc.H7
-rw-r--r--src/include/sys/mm.h10
-rw-r--r--src/include/sys/vfs.h38
-rw-r--r--src/include/usr/hbotcompid.H10
-rw-r--r--src/include/usr/initservice/initsvcreasoncodes.H1
-rw-r--r--src/include/usr/vfs/vfs.H41
-rw-r--r--src/include/usr/vfs/vfs_reasoncodes.H22
-rw-r--r--src/include/util/align.H3
-rw-r--r--src/lib/syscall_mm.C32
-rw-r--r--src/makefile2
-rw-r--r--src/sys/init/init_main.C9
-rw-r--r--src/sys/vfs/vfs_init.C31
-rw-r--r--src/sys/vfs/vfs_main.C94
-rw-r--r--src/usr/cxxtest/cxxtestexec.C2
-rw-r--r--src/usr/initservice/baseinitsvc/initservice.C104
-rw-r--r--src/usr/initservice/baseinitsvc/initsvctasks.H21
-rw-r--r--src/usr/initservice/common/initsvcstructs.H12
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvc.C21
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvctasks.H7
-rw-r--r--src/usr/makefile4
-rw-r--r--src/usr/vfs/makefile8
-rw-r--r--src/usr/vfs/vfsrp.C317
-rw-r--r--src/usr/vfs/vfsrp.H90
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
OpenPOWER on IntegriCloud