summaryrefslogtreecommitdiffstats
path: root/src/occ_405/aplt/appletManager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/occ_405/aplt/appletManager.c')
-rwxr-xr-xsrc/occ_405/aplt/appletManager.c1336
1 files changed, 1336 insertions, 0 deletions
diff --git a/src/occ_405/aplt/appletManager.c b/src/occ_405/aplt/appletManager.c
new file mode 100755
index 0000000..e2e70df
--- /dev/null
+++ b/src/occ_405/aplt/appletManager.c
@@ -0,0 +1,1336 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ/aplt/appletManager.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include "ssx.h"
+#include <trac_interface.h>
+#include <appletManager.h>
+#include <aplt_service_codes.h>
+#include <occ_service_codes.h>
+#include <occ_common.h>
+#include <comp_ids.h>
+#include <thread.h>
+#include <trac.h>
+#include <errl.h>
+#include <state.h>
+#include "pba_firmware_registers.h"
+#include "pgp_pba.h"
+#include "pgp_async.h"
+#include "ppc405_mmu.h"
+#include "pgp.h"
+#include "cmdh_fsp.h"
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+#define TEST_APPLET_ADDR (uint32_t)&_APPLET1_SECTION_BASE
+#define PRDT_APPLET_ADDR (uint32_t)&_APPLET0_SECTION_BASE
+#define TEST_APPLET_MAX_SIZE (uint32_t)&_APPLET1_SECTION_SIZE
+#define PRDT_APPLET_MAX_SIZE (uint32_t)&_APPLET0_SECTION_SIZE
+#define APPLET_IMG_SIZE_ALIGN 256
+#define APPLET_RO_SIZE_ALIGN 1024
+#define SRAM_START_ADDRESS 0xFFF80000
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+typedef struct
+{
+ // Running Semaphore (tells user if there is an applet running)
+ SsxSemaphore Running;
+ // Wake up Semaphore (wakes up the applet manager thread)
+ SsxSemaphore Wakeup;
+ // Finished Semaphore (tells caller, if blocking, when applet is done)
+ SsxSemaphore Finished;
+} ApltSem_t;
+
+// Applet information structure
+//
+// Added callerSem to hold caller semaphore parameter to the
+// runApplet call. This semaphore will be used by startApplet to notify
+// user of completion of the applet execution.
+// Added status to get back error status from startApplet and
+// return it to the caller for the blocking call.
+struct ApltInfo
+{
+ void * param;
+ bool isBlocking;
+ OCC_APLT appId;
+ OCC_APLT previousAppId;
+ errlHndl_t errorHandle;
+ // Applet has readonly and writable sections
+ Ppc405MmuMap mmuMapWritePermission;
+ Ppc405MmuMap mmuMapReadPermission;
+ SsxSemaphore * callerSem;
+ OCC_APLT_STATUS_CODES status;
+} __attribute__ ((__packed__));
+
+typedef struct ApltInfo ApltInfo_t;
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+// Global semaphores for product and test applet
+ApltSem_t G_ApltSemaphore;
+ApltSem_t G_TestApltSemaphore;
+
+// Applet Id global array
+ApltAddress_t G_ApltAddressTable[ OCC_APLT_LAST];
+
+// Global product applet information with defaults
+ApltInfo_t G_ApltInfo =
+{
+ .param = NULL,
+ .isBlocking = FALSE,
+ .appId = OCC_APLT_INVALID,
+ .previousAppId = OCC_APLT_INVALID,
+ .errorHandle = NULL,
+ .mmuMapWritePermission = 0,
+ .mmuMapReadPermission = 0,
+ .callerSem = NULL,
+ .status = OCC_APLT_SUCCESS
+};
+
+// Global test applet information with defaults
+ApltInfo_t G_TestApltInfo =
+{
+ .param = NULL,
+ .isBlocking = FALSE,
+ .appId = OCC_APLT_INVALID,
+ .previousAppId = OCC_APLT_INVALID,
+ .errorHandle = NULL,
+ .mmuMapWritePermission = 0,
+ .mmuMapReadPermission = 0,
+ .callerSem = NULL,
+ .status = OCC_APLT_SUCCESS
+};
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+// Have to have this declaration here so the pre-processor handles the
+// section attribute correctly.
+errlHndl_t initAppletAddr( void ) INIT_SECTION;
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+// Function Specification
+//
+// Name: initAppletAddr
+//
+// Description: initialize the Applet address by traversing through OCC signed
+// image in main memory
+//
+// End Function Specification
+//
+
+// NOTE: Optimization of O1 is needed for this function due to the l_bootLoaderHeader pointer
+// pointing to a 0 address (which is considered NULL by the compiler) and thus with newer
+// gcc compilers (4.9.0 and above), a new optimization flag issolate-erroneous-paths-dereference
+// the compiler will set a trap in the code that will stop it from running.
+// Setting the Optimization to 1 will disable this flag when compiling with gcc 4.9 and above.
+
+errlHndl_t __attribute__((optimize("O1"))) initAppletAddr( void )
+{
+ errlHndl_t l_err = NULL;
+ // 1. Applets count = OCC_APLT_TEST
+ // 2. Start reading header addresses
+ // 3. Skip first 2 ( boot, main ) addresses
+ imageHdr_t *l_bootLoaderHeader = (void *) 0;
+ imageHdr_t *l_mainAppHeader = (void *)l_bootLoaderHeader +
+ l_bootLoaderHeader->image_size;
+ imageHdr_t *l_appHeader = (void *) l_mainAppHeader +
+ l_mainAppHeader->image_size;
+
+ // 4. Save off each applet start address and size to global applet array
+ // 5. Verify before saving off info (save off only valid addresses)
+ uint32_t l_cnt = 0;
+ bool l_foundInvalid = FALSE;
+
+ for (; l_cnt < OCC_APLT_TEST ; l_cnt++ )
+ {
+ // Enable if debug is neeed:
+ // TRAC_INFO("%s: Validating applet %d; address: %p", __FUNCTION__, l_cnt, l_appHeader);
+
+ // 5a. Value of l_appHeader should be reasonable.
+ // Means that image sizes should be non-zero.
+ // TODO: Check l_appHeader vs. max. sane memory address.
+ if( l_bootLoaderHeader->image_size == 0 )
+ {
+ l_foundInvalid = TRUE;
+ TRAC_ERR("Bad image size in boot loader header. applet count: %d", l_cnt);
+ break;
+ }
+ else if( l_mainAppHeader->image_size == 0 )
+ {
+ l_foundInvalid = TRUE;
+ TRAC_ERR("Bad image size in main app header. applet count: %d", l_cnt);
+ break;
+ }
+
+ // 5b. sram_repair_reserved holds APLT_MAGIC_NUMBER
+ uint8_t l_magic_num[SRAM_REPAIR_RESERVE_SZ] = APLT_MAGIC_NUMBER; // Identifies this as a production applet
+ int i=0;
+
+ for(; i < SRAM_REPAIR_RESERVE_SZ; i++)
+ {
+ if(l_appHeader->sram_repair_reserved[i] != l_magic_num[i])
+ {
+ l_foundInvalid = TRUE;
+ break;
+ }
+ }
+ if(l_foundInvalid == TRUE)
+ {
+#ifndef NO_TRAC_STRINGS
+ uint32_t l_srr_0 = CONVERT_UINT8_ARRAY_UINT32(l_appHeader->sram_repair_reserved[0],
+ l_appHeader->sram_repair_reserved[1],
+ l_appHeader->sram_repair_reserved[2],
+ l_appHeader->sram_repair_reserved[3]);
+
+ uint32_t l_srr_1 = CONVERT_UINT8_ARRAY_UINT32(l_appHeader->sram_repair_reserved[4],
+ l_appHeader->sram_repair_reserved[5],
+ l_appHeader->sram_repair_reserved[6],
+ l_appHeader->sram_repair_reserved[7]);
+
+ uint32_t l_srr_2 = CONVERT_UINT8_ARRAY_UINT32(l_appHeader->sram_repair_reserved[8],
+ l_appHeader->sram_repair_reserved[9],
+ l_appHeader->sram_repair_reserved[10],
+ l_appHeader->sram_repair_reserved[11]);
+
+ uint32_t l_srr_3 = CONVERT_UINT8_ARRAY_UINT32(l_appHeader->sram_repair_reserved[12],
+ l_appHeader->sram_repair_reserved[13],
+ l_appHeader->sram_repair_reserved[14],
+ l_appHeader->sram_repair_reserved[15]);
+
+ TRAC_ERR("wrong magic number. applet count: %d, header addr: %p, magic no: 0x%08x%08x%08x%08x",
+ l_cnt, l_appHeader, l_srr_0, l_srr_1, l_srr_2, l_srr_3);
+#endif
+ break;
+ }
+
+ // 5c. verify that aplt_id < OCC_APLT_TEST
+ if( l_appHeader->aplt_id >= OCC_APLT_TEST )
+ {
+ l_foundInvalid = TRUE;
+ TRAC_ERR("applet ID out of range. applet count: %d, header addr: %p, id: %d",
+ l_cnt, l_appHeader, l_appHeader->aplt_id);
+ break;
+ }
+
+ // 5d. 0 < image_size <= PRDT_APPLET_MAX_SIZE
+ if( (l_appHeader->image_size == 0) || (l_appHeader->image_size > PRDT_APPLET_MAX_SIZE) )
+ {
+ l_foundInvalid = TRUE;
+ TRAC_ERR("bad image_size. applet count: %d, applet ID: 0x%02x, header addr: %p, image_size: %d, avail space: %d",
+ l_cnt, l_appHeader->aplt_id, l_appHeader, l_appHeader->image_size, PRDT_APPLET_MAX_SIZE);
+ break;
+ }
+
+ // 5e. image_size is APPLET_IMG_SIZE_ALIGN byte aligned
+ if( (l_appHeader->image_size % APPLET_IMG_SIZE_ALIGN) > 0 )
+ {
+ l_foundInvalid = TRUE;
+ TRAC_ERR("image size not aligned. applet count: %d, applet ID: 0x%02x, header addr: %p, image_size: %d",
+ l_cnt, l_appHeader->aplt_id, l_appHeader, l_appHeader->image_size);
+ break;
+ }
+
+ // 5f. readonly_size is APPLET_RO_SIZE_ALIGN byte aligned
+ if( (l_appHeader->readonly_size % APPLET_RO_SIZE_ALIGN) > 0 )
+ {
+ l_foundInvalid = TRUE;
+ TRAC_ERR("readonly size not aligned. applet count: %d, applet ID: 0x%02x, header addr: %p, readonly_size: %d",
+ l_cnt, l_appHeader->aplt_id, l_appHeader, l_appHeader->readonly_size);
+ break;
+ }
+
+ // Each applet is loaded at address PRDT_APPLET_ADDR, and executed on-demand.
+
+ // 5g. start_addr == the applet load address in SRAM
+ if( l_appHeader->start_addr != PRDT_APPLET_ADDR )
+ {
+ l_foundInvalid = TRUE;
+ TRAC_ERR("bad start_addr. applet count: %d, applet ID: 0x%02x, header addr: %p, expected addr: 0x%08x, actual addr: 0x%08x",
+ l_cnt, l_appHeader->aplt_id, l_appHeader, PRDT_APPLET_ADDR, l_appHeader->start_addr);
+ break;
+ }
+
+ // 5h. ep_addr is between the header and the end of the applet image
+ uint32_t l_ep_addr_min = PRDT_APPLET_ADDR + sizeof(imageHdr_t); // Lowest entry point an applet can reference
+ uint32_t l_ep_addr_max = PRDT_APPLET_ADDR + l_appHeader->image_size; // Upper bound on applet entry point
+
+ if( (l_appHeader->ep_addr < l_ep_addr_min) || (l_appHeader->ep_addr >= l_ep_addr_max) )
+ {
+ l_foundInvalid = TRUE;
+ TRAC_ERR("entry point out of range. applet count: %d, applet ID: 0x%02x, header addr: %p, ep_addr: 0x%08x, ep_range: 0x%08x - 0x%08x",
+ l_cnt, l_appHeader->aplt_id, l_appHeader, l_appHeader->ep_addr, l_ep_addr_min, l_ep_addr_max);
+ break;
+ }
+
+ // 5i. we haven't already seen this applet before
+ // (note the '!' at the start of the test condition)
+ if( !((G_ApltAddressTable[l_appHeader->aplt_id].iv_aplt_address == 0x00000000) &&
+ (G_ApltAddressTable[l_appHeader->aplt_id].iv_size == 0x00000000)) )
+ {
+ // This entry in the global table is not in its initialized state.
+ l_foundInvalid = TRUE;
+ TRAC_ERR("Duplicate applet. applet count: %d, applet ID: 0x%02x, header addr: %p",
+ l_cnt, l_appHeader->aplt_id, l_appHeader);
+ break;
+ }
+
+ // The gauntlet is run. This image is good.
+
+ // Load the G_ApltAddressTable.
+ G_ApltAddressTable[l_appHeader->aplt_id].iv_aplt_address = (uint32_t)l_appHeader;
+ G_ApltAddressTable[l_appHeader->aplt_id].iv_size = l_appHeader->image_size;
+
+ // Jump to the next applet.
+ l_appHeader = (void *) l_appHeader + l_appHeader->image_size;
+
+ } // end for loop
+
+ // did we find any problems?
+ if ( l_foundInvalid )
+ {
+ // We will want to return the ID of the failing applet in our error log,
+ // if that ID exists. Otherwise, return the "invalid" ID.
+ uint16_t l_errApltId = OCC_APLT_INVALID;
+
+ if( l_appHeader )
+ {
+ l_errApltId = l_appHeader->aplt_id;
+ }
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_INIT_APPLET_ADDR
+ * @reasoncode INTERNAL_FAILURE
+ * @userdata1 failing applet ID
+ * @userdata2 failing applet main store address
+ * @userdata4 ERC_APLT_INIT_FAILURE
+ * @devdesc Internal initialization failure in energy management
+ */
+ l_err = createErrl(APLT_MID_INIT_APPLET_ADDR, //modId
+ INTERNAL_FAILURE, //reasoncode
+ ERC_APLT_INIT_FAILURE, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ NULL, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ l_errApltId, //userdata1
+ (uint32_t)l_appHeader); //userdata2
+
+ // Callout to firmware
+ addCalloutToErrl(l_err,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_FIRMWARE,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+ }
+ else
+ {
+ // No problems with any production applets.
+ // 6. Save off the test applet start address and size to global applet array
+ G_ApltAddressTable[OCC_APLT_TEST].iv_aplt_address = (uint32_t)l_appHeader;
+ G_ApltAddressTable[OCC_APLT_TEST].iv_size = TEST_APPLET_MAX_SIZE;
+ }
+
+ // copy SSX mmu map to ApltInfo structure
+ // startApplet() will use it to clear tlb entry
+ G_ApltInfo.mmuMapWritePermission = G_applet0_mmu_map;
+ G_TestApltInfo.mmuMapWritePermission = G_applet1_mmu_map;
+
+ // Clear SSX mmu map.
+ // The original tlb indexes may point to different SRAM regions when OCC runs
+ // mmu map/unmap several times.
+ G_applet0_mmu_map = 0;
+ G_applet1_mmu_map = 0;
+
+ return l_err;
+}
+
+// Function Specification
+//
+// Name: initAppletManager
+//
+// Description: initialize the Applet Manager, called by main
+//
+// End Function Specification
+void initAppletManager( void )
+{
+ errlHndl_t l_rc = NULL;
+ Ppc405MmuMap l_mmuMap;
+ bool l_mmuUnmap = FALSE;
+ do
+ {
+ // initialized all the semaphores applet manager controls
+ // create the Running Semaphore, starting at 1 with a max count of 1
+ int l_ssxrc1 = ssx_semaphore_create(&G_ApltSemaphore.Running, 1, 1);
+ // create the Wake Up Semaphore, starting at 0 with a max count of 1
+ int l_ssxrc2 = ssx_semaphore_create(&G_ApltSemaphore.Wakeup, 0, 1);
+ // create the Finished Semaphore, starting at 0 with a max count of 1
+ int l_ssxrc3 = ssx_semaphore_create(&G_ApltSemaphore.Finished, 0, 1);
+ // create the Running Semaphore, starting at 1 with a max count of 1
+ int l_ssxrc4 = ssx_semaphore_create(&G_TestApltSemaphore.Running, 1, 1);
+ // create the Wake Up Semaphore, starting at 0 with a max count of 1
+ int l_ssxrc5 = ssx_semaphore_create(&G_TestApltSemaphore.Wakeup, 0, 1);
+ // create the Finished Semaphore, starting at 0 with a max count of 1
+ int l_ssxrc6 = ssx_semaphore_create(&G_TestApltSemaphore.Finished, 0,1);
+ // check for any errors from initializing our semaphores
+ // NOTE: Applet Global Array list is left empty if semaphores
+ // are not initialized correctly
+ if (( l_ssxrc1 != SSX_OK ) || ( l_ssxrc2 != SSX_OK ) ||
+ ( l_ssxrc3 != SSX_OK ) || ( l_ssxrc4 != SSX_OK ) ||
+ ( l_ssxrc5 != SSX_OK ) || ( l_ssxrc6 != SSX_OK ))
+ {
+ TRAC_INFO("Running Semaphore SsxRc[0x%08X]", -l_ssxrc1 );
+ TRAC_INFO("Wakeup Semaphore SsxRc[0x%08X]", -l_ssxrc2 );
+ TRAC_INFO("Finished Semaphore SsxRc[0x%08X]", -l_ssxrc3 );
+ TRAC_INFO("Running Test Semaphore SsxRc[0x%08X]", -l_ssxrc4);
+ TRAC_INFO("Wakeup Test Semaphore SsxRc[0x%08X]", -l_ssxrc5 );
+ TRAC_INFO("Finished Test Semaphore SsxRc[0x%08X]", -l_ssxrc6 );
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_INIT_APPLET_MNGR
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Create Running product aplt semaphore rc
+ * @userdata2 Create Finished product aplt semaphore rc
+ * @userdata4 ERC_CREATE_SEM_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ l_rc = createErrl(APLT_MID_INIT_APPLET_MNGR, //modId
+ SSX_GENERIC_FAILURE, //reasoncode
+ ERC_CREATE_SEM_FAILURE, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ NULL, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ l_ssxrc1, //userdata1
+ l_ssxrc3); //userdata2
+ break;
+ }
+
+ CHECKPOINT(APP_SEMS_CREATED);
+
+ // Map mainstore to oci space so that we can walk through
+ // OCC signed image to get applet addresses
+ int l_ssxRc = ppc405_mmu_map(0, //Mainstore address 0x0
+ 0, //OCI address 0x0
+ 1048576, //Max size = 1 Mb
+ 0, // TLB hi flags
+ 0, // TLB lo flags
+ &l_mmuMap);// map pointer
+
+ if ( l_ssxRc != SSX_OK )
+ {
+ TRAC_ERR("mmu map failure SsxRc[0x%08X]", -l_ssxRc );
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_INIT_APPLET_MNGR
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 MMU map return code
+ * @userdata4 ERC_MMU_MAP_FAILURE
+ * @devdesc Failure mapping OCI space
+ */
+ l_rc = createErrl(APLT_MID_INIT_APPLET_MNGR, //modId
+ SSX_GENERIC_FAILURE, //reasoncode
+ ERC_MMU_MAP_FAILURE, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ NULL, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ l_ssxRc, //userdata1
+ 0); //userdata2
+ break;
+ }
+
+ CHECKPOINT(APP_MEM_MAPPED);
+
+ // set to indicate to do mmu unmap after we are done using it.
+ l_mmuUnmap = TRUE;
+
+ // Traverse through OCC signed image to get applet address
+ l_rc = initAppletAddr();
+
+ CHECKPOINT(APP_ADDR_INITIALIZED);
+
+ if( NULL != l_rc)
+ {
+ TRAC_ERR("Failure initializing applet addresses");
+ break;
+ }
+
+ }while(FALSE);
+
+ if( TRUE == l_mmuUnmap)
+ {
+ CHECKPOINT(APP_MEM_UNMAP);
+
+ // Unmap mmu mapping for main store to oci space.
+ // NOTE: This needs to be unmapped because 1) PowerBus disruptions
+ // could leave OCC hung for several uS if main memory accessed at
+ // some later point. 2) Any thing accessing address 0 should result
+ // in 405 exception so need to unmap it.
+ int l_ssxRc = ppc405_mmu_unmap(&l_mmuMap);
+
+ if ( l_ssxRc != SSX_OK )
+ {
+ TRAC_ERR("mmu unmap failure SsxRc[0x%08X]", -l_ssxRc );
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_INIT_APPLET_MNGR
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 MMU unmap return code
+ * @userdata4 ERC_MMU_UNMAP_FAILURE
+ * @devdesc Failure unmapping OCI space
+ */
+ errlHndl_t l_err = createErrl(APLT_MID_INIT_APPLET_MNGR, //modId
+ SSX_GENERIC_FAILURE, //reasoncode
+ ERC_MMU_UNMAP_FAILURE, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ NULL, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ l_ssxRc, //userdata1
+ 0); //userdata2
+ // If there were not previous errors, return this error to the
+ // caller. Otherwise, log this error and return previous error to
+ // the caller.
+ if( l_rc == NULL)
+ {
+ l_rc = l_err;
+ deleteErrl(&l_err);
+ }
+ else
+ {
+ commitErrl(&l_err);
+ }
+ }
+ }
+
+ if( NULL != l_rc )
+ {
+ REQUEST_RESET(l_rc);
+ }
+
+}
+
+
+// Function Specification
+//
+// Name: runApplet
+//
+// Description: run an Applet
+//
+// End Function Specification
+void runApplet( OCC_APLT i_applet,
+ void * i_parms,
+ bool i_block,
+ SsxSemaphore *io_appletComplete,
+ errlHndl_t *o_errHndl,
+ OCC_APLT_STATUS_CODES *o_status )
+{
+ uint32_t l_reasonCode = 0;
+ uint32_t l_extReasonCode = 0;
+ int l_ssxrc = 0;
+ bool l_postStartFailure = FALSE;
+
+ // Depending on applet id use product or test applet globals
+ ApltSem_t * l_sem =
+ (i_applet == OCC_APLT_TEST? &G_TestApltSemaphore : &G_ApltSemaphore);
+ ApltInfo_t * l_info =
+ (i_applet == OCC_APLT_TEST? &G_TestApltInfo : &G_ApltInfo);
+
+ //Block other runApplet caller until this request is complete
+ l_ssxrc = ssx_semaphore_pend(&l_sem->Running, SSX_WAIT_FOREVER);
+
+ if ( l_ssxrc != SSX_OK )
+ {
+ /*
+ * @errortype
+ * @moduleid APLT_MID_RUN_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Failing applet ID
+ * @userdata2 Caller parameter to determine block or not.
+ * @userdata4 ERC_RUNNING_SEM_PENDING_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ TRAC_ERR("Running Semaphore Pending Failure on blocking caller: SsxRc[0x%08X]", -l_ssxrc );
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_RUNNING_SEM_PENDING_FAILURE;
+ l_info->status = OCC_APLT_PRE_START_FAILURE;
+ }
+ else
+ {
+ // First save off all the Globals
+
+ // Save off the current Applet user wants to run
+ l_info->appId = i_applet;
+
+ // Save off whether or not we are blocking on this applet execution
+ l_info->isBlocking = i_block;
+
+ // save off pointer to parameters
+ l_info->param = i_parms;
+
+ // Point callerSem to the caller passed in semaphore
+ l_info->callerSem = io_appletComplete;
+
+ // clean out the handle
+ l_info->errorHandle = NULL;
+
+ l_info->status = OCC_APLT_SUCCESS;
+
+ // This happens too often, we cannot trace it
+ // TRAC_INFO("Waking up the Applet Manager Thread" );
+
+ // Post wakeup semaphore so that applet manager can start
+ // applet
+ l_ssxrc = ssx_semaphore_post( &l_sem->Wakeup );
+ if ( l_ssxrc != SSX_OK )
+ {
+ /*
+ * @errortype
+ * @moduleid APLT_MID_RUN_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Failing applet ID
+ * @userdata2 Caller parameter to determine block or not.
+ * @userdata4 ERC_WAKEUP_SEM_POSTING_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ TRAC_ERR("Wakeup Semaphore Post Failure: SsxRc[0x%08X]", -l_ssxrc );
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_WAKEUP_SEM_POSTING_FAILURE;
+
+ //post on Running Semaphore so that user can retry
+ l_ssxrc = ssx_semaphore_post( &l_sem->Running );
+ if ( l_ssxrc != SSX_OK )
+ {
+ /*
+ * @errortype
+ * @moduleid APLT_MID_RUN_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Failing applet ID
+ * @userdata2 Caller parameter to determine block or not.
+ * @userdata4 ERC_RUNNING_SEM_POSTING_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ TRAC_ERR("Error posting the Applet running semaphore rc=[%08X]",l_ssxrc);
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_RUNNING_SEM_POSTING_FAILURE;
+ }
+ // set rc to failed to start
+ l_info->status = OCC_APLT_PRE_START_FAILURE;
+ }
+ // is caller expecting us to block then wait for finished semaphore
+ // to be posted. Finished semaphore is posted after applet execution
+ // is done.
+ else if ( i_block )
+ {
+ l_ssxrc = ssx_semaphore_pend(&l_sem->Finished, SSX_WAIT_FOREVER);
+ if ( l_ssxrc != SSX_OK )
+ {
+ /*
+ * @errortype
+ * @moduleid APLT_MID_RUN_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Failing applet ID
+ * @userdata2 Caller parameter to determine block or not.
+ * @userdata4 ERC_FINISHED_SEM_PENDING_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ TRAC_ERR("Finished Semaphore Pending Failure: SsxRc[0x%08X]", -l_ssxrc );
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_FINISHED_SEM_PENDING_FAILURE;
+ // set flag to return post start failure status
+ l_postStartFailure = TRUE;
+ }
+ }
+ }
+
+ if ( (l_reasonCode != 0) && (o_errHndl != NULL))
+ {
+ // TODO use correct trace
+ tracDesc_t l_trace = NULL;
+ // Error from runApplet
+ *o_errHndl = createErrl(APLT_MID_RUN_APPLET, //modId
+ l_reasonCode, //reasoncode
+ l_extReasonCode, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ l_trace, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ i_applet, //userdata1
+ i_block); //userdata2
+
+ // Callout firmware
+ addCalloutToErrl(*o_errHndl,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_FIRMWARE,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+
+ }
+ else if ( (l_info->errorHandle) && (o_errHndl != NULL))
+ {
+ // Error handle from start applet
+ *o_errHndl = l_info->errorHandle;
+ }
+
+ // set the status if requested by caller.
+ if( o_status != NULL )
+ {
+ if(l_postStartFailure == TRUE )
+ {
+ *o_status = OCC_APLT_POST_START_FAILURE;
+ }
+ else
+ {
+ // Return status to the caller
+ *o_status = l_info->status;
+ }
+ }
+
+ //Running, Finished/user passed in semaphore is posted by start applet
+};
+
+
+// Function Specification
+//
+// Name: startApplet
+//
+// Description: Start Applet
+//
+// End Function Specification
+void startApplet( const OCC_APLT_TYPE i_isTestAplt )
+{
+ errlHndl_t l_rc = NULL;
+ int l_ssxrc = 0;
+ uint32_t l_reasonCode = 0;
+ uint32_t l_extReasonCode = 0;
+ // Depending on i_isTestAplt use product or test applet globals
+ ApltInfo_t * l_info =
+ (i_isTestAplt == TRUE ? &G_TestApltInfo : &G_ApltInfo);
+ ApltSem_t * l_sem =
+ (i_isTestAplt == TRUE ? &G_TestApltSemaphore : &G_ApltSemaphore);
+
+ OCC_APLT_STATUS_CODES l_status = OCC_APLT_SUCCESS;
+
+ // Get default applet section size for mmu
+ size_t l_applet_section_size =
+ (i_isTestAplt == TRUE ? (size_t)&_APPLET1_SECTION_SIZE : (size_t)&_APPLET0_SECTION_SIZE);
+
+ // For storing applet readonly size, this value is located in applet header in SRAM.
+ // The value should be stored in another place before unmapping the applet memory region.
+ size_t l_applet_readonly_size = 0;
+
+ // 1. set tlb protection to write to SRAM:
+ // currently already writable
+
+ do
+ {
+ // Get SRAM applet address depending on the applet type
+ uint32_t l_apltSramAddress =
+ (i_isTestAplt == TRUE? TEST_APPLET_ADDR: PRDT_APPLET_ADDR);
+
+ // Set header to point to SRAM address
+ imageHdr_t * l_apltHeader = (void *) l_apltSramAddress;
+ imageHdr_t *l_mainAppHeader = (void *) SRAM_START_ADDRESS;
+
+ // This happens too often, we cannot trace it
+ //TRAC_INFO("Attempting to run applet at address [0x%08X], size: 0x%x",
+ // G_ApltAddressTable[l_info->appId].iv_aplt_address,
+ // G_ApltAddressTable[l_info->appId].iv_size);
+
+ // check that we are not calling what is already saved off
+ // re-load the test applet every time since they all use the same applet ID.
+ if ( (l_info->appId == OCC_APLT_TEST) || (l_info->appId != l_info->previousAppId) )
+ {
+ // 1a. check applet read-only/executable permissions, unmap it if existed.
+ // whole applet memory region in SRAM should be free first, then set it to
+ // writable for copyimage and calculate checksum.
+ if ( l_info->mmuMapReadPermission != 0 )
+ {
+ l_ssxrc = ppc405_mmu_unmap(&l_info->mmuMapReadPermission);
+
+ if(l_ssxrc)
+ {
+ TRAC_ERR("Error unmapping/changing permissions on applet text/data section rc=[%08X]", -l_ssxrc);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_MMU_UNMAP_APPLET_READ_FAILURE
+ * @devdesc Failure unmapping applet read-only/executable permissions
+ */
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_MMU_UNMAP_APPLET_READ_FAILURE;
+
+ // bail out
+ break;
+ }
+ }
+
+ // 1b. check applet writable section permissions, unmap it if existed
+ // whole applet memory region in SRAM should be free first, then set it to
+ // writable for copyimage and calculate checksum.
+ if ( l_info->mmuMapWritePermission != 0 )
+ {
+ l_ssxrc = ppc405_mmu_unmap(&l_info->mmuMapWritePermission);
+
+ if(l_ssxrc)
+ {
+ TRAC_ERR("Error unmapping/changing permissions on applet text/data section rc=[%08X]", -l_ssxrc);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_MMU_UNMAP_APPLET_WRITE_FAILURE
+ * @devdesc Failure unmapping applet rwdata section permissions
+ */
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_MMU_UNMAP_APPLET_WRITE_FAILURE;
+
+ // bail out
+ break;
+ }
+ }
+
+ //1c. set SRAM applet region to writable for copying image and calculating checksum
+
+ l_ssxrc = ppc405_mmu_map(
+ l_apltSramAddress, //
+ l_apltSramAddress, //
+ l_applet_section_size, // set whole applet including writable section
+ 0, //
+ TLBLO_WR,
+ &l_info->mmuMapWritePermission
+ );
+ if(l_ssxrc != SSX_OK)
+ {
+ TRAC_ERR("Error mapping SRAM with execute permissions rc=[%08X]",l_ssxrc);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_MMU_MAP_APPLET_OVERWRITE_FAILURE
+ * @devdesc Failure mapping applet memory region permissions
+ */
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_MMU_MAP_APPLET_OVERWRITE_FAILURE;
+ break;
+ }
+
+ // 2. read applet header info
+ // 3. copy applet image to SRAM using DMA
+
+ BceRequest pba_copy;
+ l_ssxrc = bce_request_create(&pba_copy, // block copy object
+ &G_pba_bcde_queue, // mainstore to sram copy engine
+ G_ApltAddressTable[l_info->appId].iv_aplt_address, // mainstore applet address
+ l_apltSramAddress, // sram applet starting address
+ G_ApltAddressTable[l_info->appId].iv_size, // size of applet
+ SSX_WAIT_FOREVER, // no timeout
+ 0, // no call back
+ 0, // no call back arguments
+ ASYNC_REQUEST_BLOCKING); // blocking request
+
+ if(l_ssxrc != SSX_OK)
+ {
+ TRAC_ERR("PBA request create failure rc=[%08X]",l_ssxrc);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_BCE_REQUEST_CREATE_FAILURE
+ * @devdesc SSX BCE related failure
+ */
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_BCE_REQUEST_CREATE_FAILURE;
+ break;
+ }
+
+ // actual copying
+ l_ssxrc = bce_request_schedule(&pba_copy);
+
+ if(l_ssxrc != SSX_OK)
+ {
+ TRAC_ERR("PBA request schedule failure rc=[%08X]",l_ssxrc);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_BCE_REQUEST_SCHEDULE_FAILURE
+ * @devdesc Failure to copy applet image using DMA
+ */
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_BCE_REQUEST_SCHEDULE_FAILURE;
+ break;
+ }
+
+ // --------------------------------------------------
+ // Verify the applet version matches the main version
+ // --------------------------------------------------
+ if(l_mainAppHeader->version != l_apltHeader->version)
+ {
+ TRAC_ERR("Applet not loaded b/c of version mismatch Main[%08x]:Applet[%08x]",
+ l_mainAppHeader->version, l_apltHeader->version);
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode INTERNAL_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_APLT_START_VERSION_MISMATCH
+ * @devdesc Internal failure in energy management
+ */
+ l_reasonCode = INTERNAL_FAILURE;
+ l_extReasonCode = ERC_APLT_START_VERSION_MISMATCH;
+ break;
+
+ }
+
+ // 3b. invalidate the data cache
+ // ie: clean up data cache in case stuff is left
+ // from previous applet
+ dcache_invalidate((void *) l_apltHeader, l_applet_section_size);
+
+ // 4. Verify checksum of applet
+ uint32_t l_counter = 0;
+ uint8_t * l_srcPtr = (uint8_t *) (l_apltHeader);
+ uint32_t l_checksum = 0;
+ uint32_t l_headerChecksum = l_apltHeader->checksum;
+
+ while (l_counter < l_apltHeader->image_size )
+ {
+ l_checksum += (*(l_srcPtr + l_counter));
+ l_counter = l_counter + 1;
+ if( l_counter == (uint32_t)(offsetof(imageHdr_t,checksum)))
+ {
+ l_counter = ((uint32_t)(offsetof(imageHdr_t,checksum)) +
+ sizeof(l_apltHeader->checksum));
+ }
+ }//end while loop
+
+ if ( l_checksum != l_headerChecksum )
+ {
+ //error
+ TRAC_ERR("Checksum verification failure header chksum=[%08X] calculated chksum =[%08X] ",
+ l_headerChecksum, l_checksum);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode INTERNAL_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_APLT_START_CHECKSUM_MISMATCH
+ * @devdesc Internal failure in energy management
+ */
+ l_reasonCode = INTERNAL_FAILURE;
+ l_extReasonCode = ERC_APLT_START_CHECKSUM_MISMATCH;
+ break;
+ }
+
+ // 5. flush complete I cache
+ // ie: ensure execution of current applet is clean
+ icache_invalidate_all();
+
+
+ // 5a. flush part of data cache
+ // ie: clean up data cache in case stuff is left
+ // from previous applet
+ // TODO: need to ensure this will work correctly on HW
+ // may require tweaking, based on results
+ dcache_invalidate((void *)l_apltHeader->zero_data_addr,
+ l_apltHeader->zero_data_size );
+
+ // size of readonly section is located in applet memory section
+ // get it for next step to protect text and data section
+ l_applet_readonly_size = l_apltHeader->readonly_size;
+
+ // 5b. unmap (remove permissions) on SRAM applet after copying applet image.
+ // permissions should be set correctly in SRAM rodata/rwdata section in next step.
+ if ( l_info->mmuMapWritePermission != 0 )
+ {
+ l_ssxrc = ppc405_mmu_unmap(&(l_info->mmuMapWritePermission));
+
+ if(l_ssxrc)
+ {
+ TRAC_ERR("Error unmapping/changing permissions on SRAM applet section rc=[%08X]", -l_ssxrc);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_MMU_UNMAP_APPLET_OVERWRITE_FAILURE
+ * @devdesc Failure unmapping applet memory region permissions
+ */
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_MMU_UNMAP_APPLET_OVERWRITE_FAILURE;
+
+ // bail out
+ break;
+ }
+ }
+
+ // 6 mapping mmu tlb permission (read-only section and writable section)
+ // 6a. protect applet text in SRAM (tlbie)
+ l_ssxrc = ppc405_mmu_map(
+ l_apltSramAddress,
+ l_apltSramAddress,
+ l_applet_readonly_size, // protect the text and data section
+ 0,
+ TLBLO_EX,
+ &(l_info->mmuMapReadPermission)
+ );
+ if(l_ssxrc != SSX_OK)
+ {
+ TRAC_ERR("Error mapping SRAM with execute permissions rc=[%08X]",l_ssxrc);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_MMU_MAP_APPLET_READ_FAILURE
+ * @devdesc Failure mapping applet read-only/executable permissions
+ */
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_MMU_MAP_APPLET_READ_FAILURE;
+ break;
+ }
+
+ // 6b. map applet rwdata section in SRAM as writable (tlbie)
+ if(0 != l_apltHeader->boot_writeable_size)
+ {
+ l_ssxrc = ppc405_mmu_map(
+ l_apltHeader->boot_writeable_addr,
+ l_apltHeader->boot_writeable_addr,
+ l_apltHeader->boot_writeable_size,
+ 0,
+ TLBLO_WR, // set rwdata section to write permission
+ &(l_info->mmuMapWritePermission)
+ );
+ if(l_ssxrc != SSX_OK)
+ {
+ TRAC_ERR("Error mapping SRAM with execute permissions rc=[%08X]",l_ssxrc);
+
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Applet start status
+ * @userdata4 ERC_MMU_MAP_APPLET_WRITE_FAILURE
+ * @devdesc Failure mapping applet rwdata section permissions
+ */
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_MMU_MAP_APPLET_WRITE_FAILURE;
+ break;
+ }
+ }
+
+ // save off current applet being run (already copied) into previous
+ // ie: cache applet id
+ // NOTE: This is done here, to ensure the full set up is always completed
+ // before saving off the current applet id into previous applet id var
+ l_info->previousAppId = l_info->appId;
+
+ }//end if
+
+ // 7. Copy entry point address from applet header
+ // and start executing from that address
+ errlHndl_t (*execute_app)(void *) =(void *) l_apltHeader->ep_addr;
+ errlHndl_t l_applog = (*execute_app)(l_info->param);
+ // check if applet return an error log
+ if ( l_applog )
+ {
+ TRAC_ERR("Error found from applet function see error @%p",l_applog);
+
+ if ( l_info->isBlocking )
+ {
+ // if applet caller wanted us to block
+ // save off the error and status
+ l_info->errorHandle = l_applog;
+ l_info->status = OCC_APLT_EXECUTE_FAILURE;
+ }
+ else
+ {
+ // non blocker, so commit the error
+ commitErrl(&l_applog);
+ }
+ }
+
+ }while(0); // end of do while loop
+
+ // All the error at this point setting reason code is before executing
+ // applet so set the status to pre start failure.
+ if( l_reasonCode != 0)
+ {
+ l_status = OCC_APLT_PRE_START_FAILURE;
+ // TODO use correct trace
+ tracDesc_t l_trace = NULL;
+
+ l_rc = createErrl(APLT_MID_START_APPLET, //modId
+ l_reasonCode, //reasoncode
+ l_extReasonCode, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ l_trace, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ l_status, //userdata1
+ 0); //userdata2
+
+ // Callout to firmware
+ addCalloutToErrl(l_rc,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_FIRMWARE,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+
+ if ((l_info->isBlocking ) && (l_info->errorHandle == NULL))
+ {
+ // Return error to caller for blocking call and
+ // there is no error executing applet
+ l_info->errorHandle = l_rc;
+ l_rc = NULL;
+ }
+ else
+ {
+ // commit log for the non-blocking call OR there is
+ // error executing applet
+ commitErrl(&l_rc);
+ }
+ }
+
+ if( (l_info->isBlocking) && (l_info->status == OCC_APLT_SUCCESS))
+ {
+ // Get status only if call is blocking AND no error executing applet
+ l_info->status = l_status;
+ }
+ // Moved posting of semaphores outside of while loop so that
+ // in the error paths semaphores gets posted and not blocked forever.
+ // 8. post on Finished Semaphore if caller wanted us to block them
+ if ( l_info->isBlocking )
+ {
+ l_ssxrc = ssx_semaphore_post( &l_sem->Finished );
+
+ if ( l_ssxrc != SSX_OK )
+ {
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata4 ERC_FINISHED_SEM_POSTING_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ TRAC_ERR("Error posting the Applet finished semaphore rc=[%08X]",l_ssxrc);
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_FINISHED_SEM_POSTING_FAILURE;
+ }
+ }
+ // If caller passed in semaphore post it as caller might be blocked on
+ // this semaphore.
+ else if( l_info->callerSem != NULL)
+ {
+ l_ssxrc = ssx_semaphore_post( l_info->callerSem);
+
+ if ( l_ssxrc != SSX_OK )
+ {
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata4 ERC_CALLER_SEM_POSTING_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ TRAC_ERR("Error posting the Applet complete semaphore rc=[%08X]",l_ssxrc);
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_CALLER_SEM_POSTING_FAILURE;
+ }
+ }
+
+ // 8a. post on Running Semaphore
+ l_ssxrc = ssx_semaphore_post( &l_sem->Running );
+ if ( l_ssxrc != SSX_OK )
+ {
+ /*
+ * @errortype
+ * @moduleid APLT_MID_START_APPLET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata4 ERC_RUNNING_SEM_POSTING_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ TRAC_ERR("Error posting the Applet running semaphore rc=[%08X]",l_ssxrc);
+ l_reasonCode = SSX_GENERIC_FAILURE;
+ l_extReasonCode = ERC_RUNNING_SEM_POSTING_FAILURE;
+ }
+
+ if( l_reasonCode != 0)
+ {
+ // TODO use correct trace
+ tracDesc_t l_trace = NULL;
+
+ l_rc = createErrl(APLT_MID_START_APPLET, //modId
+ l_reasonCode, //reasoncode
+ l_extReasonCode, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ l_trace, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ 0, //userdata1
+ 0); //userdata2
+
+ // Callout to firmware
+ addCalloutToErrl(l_rc,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_FIRMWARE,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+
+ // Error posting semaphores so commit it.
+ commitErrl(&l_rc);
+ }
+}
+
+
+// Function Specification
+//
+// Name: App_thread_routine
+//
+// Description: Applet Thread
+//
+// End Function Specification
+void App_thread_routine(void *i_arg)
+{
+ // This happens too often, we cannot trace it
+ //TRAC_INFO("Started ...");
+
+ errlHndl_t l_errl = NULL;
+ OCC_APLT_TYPE l_type = APLT_TYPE_INVALID;
+ // TODO use correct trace
+ tracDesc_t l_trace = NULL;
+
+ if( i_arg == NULL)
+ {
+ TRAC_ERR("Invalid parameter");
+ /*
+ * @errortype
+ * @moduleid APLT_MNGR_THREAD
+ * @reasoncode INTERNAL_FAILURE
+ * @userdata1 APLT_TYPE_INVALID
+ * @userdata4 ERC_INVALID_INPUT_DATA
+ * @devdesc Internal failure in energy management
+ */
+ l_errl = createErrl(APLT_MNGR_THREAD, //modId
+ INTERNAL_FAILURE, //reasoncode
+ ERC_INVALID_INPUT_DATA, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ l_trace, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ l_type, //userdata1
+ 0); //userdata2
+
+ // Callout to firmware
+ addCalloutToErrl(l_errl,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_FIRMWARE,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+ // commit log
+ commitErrl( &l_errl );
+ //TODO: should we reset OCC?
+ }
+ else
+ {
+ l_type = *((OCC_APLT_TYPE*)i_arg);
+
+ while( 1 )
+ {
+ // This happens too often, we cannot trace it
+ //TRAC_INFO("ApltType: [0x%x] Waiting ...", l_type);
+
+ int l_ssxrc = SSX_OK;
+
+ if( APLT_TYPE_PRODUCT == l_type)
+ {
+ l_ssxrc = ssx_semaphore_pend(&G_ApltSemaphore.Wakeup,
+ SSX_WAIT_FOREVER);
+ }
+ else
+ {
+ l_ssxrc = ssx_semaphore_pend(&G_TestApltSemaphore.Wakeup,
+ SSX_WAIT_FOREVER);
+
+ }
+
+ if ( l_ssxrc != SSX_OK )
+ {
+ TRAC_ERR("WakeUp Semaphore Failure SsxRc[0x%08X]", -l_ssxrc );
+
+ /*
+ * @errortype
+ * @moduleid APLT_MNGR_THREAD
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 Semaphore pend return code
+ * @userdata2 Applet type input from caller
+ * @userdata4 ERC_WAKEUP_SEM_PENDING_FAILURE
+ * @devdesc SSX semaphore related failure
+ */
+ l_errl = createErrl(APLT_MNGR_THREAD, //modId
+ SSX_GENERIC_FAILURE, //reasoncode
+ ERC_WAKEUP_SEM_PENDING_FAILURE, //Extended reason code
+ ERRL_SEV_UNRECOVERABLE, //Severity
+ l_trace, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ -l_ssxrc, //userdata1
+ l_type); //userdata2
+
+ // commit log
+ REQUEST_RESET(l_errl);
+ break;
+ }
+
+ startApplet(l_type);
+
+ } // end while loop
+ }
+
+ TRAC_IMP("Applet Thread Routine [%d] Ended Unexpectedly.", l_type);
+}
OpenPOWER on IntegriCloud