Files
banban/ql-kernel/threadx/quec_minsys/EE_Postmortem.c

978 lines
29 KiB
C

/*------------------------------------------------------------
(C) Copyright [2006-2008] Marvell International Ltd.
All Rights Reserved
------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------------
INTEL CONFIDENTIAL
Copyright 2006 Intel Corporation All Rights Reserved.
The source code contained or described herein and all documents related to the source code ("Material") are owned
by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or
its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of
Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and
treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted,
transmitted, distributed, or disclosed in any way without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual property right is granted to or
conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement,
estoppel or otherwise. Any license under such intellectual property rights must be express and approved by
Intel in writing.
-------------------------------------------------------------------------------------------------------------------*/
/*******************************************************************************
* MODULE HEADER FILE
********************************************************************************
*
* Filename: EE_Postmortem.c
*
* The BOERNE could access the whole HARBELL's DDR for postmortem debugging
* Let's use this possibility for the fetching HARBELL-DDR dump into BIN-file.
* This is especially usable in case of exceptions.
*
* There are next utilities:
* - SaveComMIPSbuf keep the MIPS-RAM buffer. The Address of buffer is FIXED-PreDefined
* - SaveComEEbuf keep the EE-handler buffer. The Address of buffer is FIXED-PreDefined
* - SaveCom_Addr_Len make dump of any COMM-DDR area started from with a given address and length.
* The address may be given even in the COMM-addressing format (0xD0Xxxxxx)
*
*******************************************************************************/
//#if !defined(_TAVOR_BOERNE_) && !defined(_TAVOR_HARBELL_) && !defined(SILICON_PV2)
#if !defined(_TAVOR_BOERNE_) && !defined(SILICON_PV2)
#include "global_types.h"
BOOL EE_PostmortemRegistration(char* name, UINT8* bufAddr, UINT32 bufLen) {return(TRUE);}
#else
#include <string.h> // for memcpy() & strcpy()
#include <stdio.h>
#include "EEHandler.h"
#include "EEHandler_int.h"
#include "diag.h"
#include "asserts.h"
#include "EE_Postmortem.h"
#include "EE_PostmortemApi.h"
#include "loadTable.h"
#include "crossplatformsw.h"
#include "diag_comm_SD.h"
#include "diag_comm_EXTif.h"
#include "UART.h"
#define ENTRY_NOT_FOUND ((EE_PostmortemDesc_Entry*)0xDEADDEAD)
//The EE_PostmortemDesc may be printed when ICAT postmortem command sent
//#define PRINT_POSTMORTEM_DESC
extern BOOL useYmodem(void);
extern int ymodem_trans(unsigned char *buf, char *name, unsigned int sizeFile);
#if defined (OSA_WINCE)
#define CacheCleanMemory(X,Y) /* */
#else
extern void CacheCleanMemory( void *pMem ,UINT32 size);
#endif
//#if defined (_TAVOR_HARBELL_) || defined(SILICON_PV2)
#if defined(SILICON_PV2)
#include "mipsram_def.h"
extern EE_LogBuffer __CurrentExceptionLog;
EE_PostmortemDesc_Entry EE_PostmortemDesc[POSTMORTEM_NUMOF_ENTRIES] =
{
/* Buf-Name[8] UINT8* pBuf UINT32 len */
POSTMORTEM_BUF_NAME_EEBUF , (UINT8*)&__CurrentExceptionLog.log,
sizeof(__CurrentExceptionLog.log)/*sizeof(EE_Entry_t)*/
+sizeof(__CurrentExceptionLog.DBversionID),
#if defined(MIPS_TEST_RAM)
#if 0
POSTMORTEM_BUF_NAME_MIPSRAM , (UINT8*)mipsRamBuffer , sizeof(mipsRamBuffer) ,
#endif
#endif
0,0,0,
0,0,0 /*end must be zeroed*/
};
// PUB_ADDR_OF_PTR2POSTMORTEM_DESC <- &EE_PostmortemDesc[0]
#else // _TAVOR_HARBELL_
UINT32 EE_AssistingMaster_ASSERT_found = 0;
#endif // _TAVOR_HARBELL_
BOOL EE_PostmortemRegistration(char* name, UINT8* bufAddr, UINT32 bufLen)
{
#if !defined (PHS_SW_DEMO_TTC) || !defined (SILICON_PV2) // _TAVOR_HARBELL_
return TRUE;
#else
char nameBuf[POSTMORTEM_BUF_NAME_SIZE];
int i;
UINT32 cpsrReg;
//Check neme length and cut if needed
//[klockwork][issue id: 851]
strncpy(nameBuf, name, POSTMORTEM_BUF_NAME_SIZE-1);
nameBuf[POSTMORTEM_BUF_NAME_SIZE-1] = 0;
//Check the name is already registered
for(i=0; i < (POSTMORTEM_NUMOF_ENTRIES-1); i++)
if(strcmp(EE_PostmortemDesc[i].name, nameBuf) == 0)
{//Already exists => update pBuf and size
EE_PostmortemDesc[i].bufAddr = bufAddr;
EE_PostmortemDesc[i].bufLen = bufLen;
CacheCleanMemory(&EE_PostmortemDesc[i], sizeof(EE_PostmortemDesc_Entry));
return TRUE;
}
//Look for a free entry (Don't forget, the last should be zero)
for(i=0; i < (POSTMORTEM_NUMOF_ENTRIES-1); i++)
{
cpsrReg = disableInterrupts(); //Protect from task-switch
if(EE_PostmortemDesc[i].name[0] == 0)
{
//Add to Table with disableInterrupts
memcpy(EE_PostmortemDesc[i].name, nameBuf, POSTMORTEM_BUF_NAME_SIZE);
EE_PostmortemDesc[i].bufAddr = bufAddr;
EE_PostmortemDesc[i].bufLen = bufLen;
CacheCleanMemory(&EE_PostmortemDesc[i], sizeof(EE_PostmortemDesc_Entry));
restoreInterrupts(cpsrReg);
return (TRUE);
}
restoreInterrupts(cpsrReg);
}
return(FALSE);
#endif // _TAVOR_HARBELL_
}
#ifdef PHS_SW_DEMO_TTC
#include "mmap_phy.h"
static EE_PostmortemDesc_Entry* getEntryNext(int getFirst)
{
void * addr = &EE_PostmortemDesc;
void * whellKnownAddr = (void*)& addr; //PUB_ADDR_OF_PTR2POSTMORTEM_DESC;
static EE_PostmortemDesc_Entry * pCurr;
static int idx;
if(getFirst)
{
pCurr = (EE_PostmortemDesc_Entry*) ADDR_CONVERT(*(UINT32*) ADDR_CONVERT(whellKnownAddr));
idx = 0;
}
else
{
pCurr++;
idx++;
if((pCurr->name[0] == 0) || (idx >= POSTMORTEM_NUMOF_ENTRIES))
return(ENTRY_NOT_FOUND);
}
return( (EE_PostmortemDesc_Entry*) ADDR_CONVERT(pCurr) );
}
static EE_PostmortemDesc_Entry* getEntryByName(char* name)
{
int i;
void * whellKnownAddr = (void*)PUB_ADDR_OF_PTR2POSTMORTEM_DESC;
EE_PostmortemDesc_Entry * p = (EE_PostmortemDesc_Entry*) ADDR_CONVERT(*(UINT32*) ADDR_CONVERT(whellKnownAddr));
EE_PostmortemDesc_Entry * retAddr = ENTRY_NOT_FOUND;
for(i=0; i < POSTMORTEM_NUMOF_ENTRIES; i++)
{
if(p->name[0] == 0)
break;//Last END-entry. Just exit
else
{
if(strcmp(p->name, name) == 0)
{
retAddr = p;
break;// found
}
p++;
}
}
return( (EE_PostmortemDesc_Entry*) ADDR_CONVERT(retAddr) );
}
#if 0
static void SaveToFileEx(char* fileName, UINT8* pBuf, UINT32 len)
{
FILE_ID fdiID;
UINT32 count;
char fNameBuf[POSTMORTEM_BUF_NAME_SIZE + 4/*com_*/ + 4/*.bin*/ +4/*spare*/];
UINT32 nameLen;
//cut given name if too long
nameLen = strlen(fileName);
if(nameLen >= POSTMORTEM_BUF_NAME_SIZE)
fileName[POSTMORTEM_BUF_NAME_SIZE-1] = 0;
sprintf(fNameBuf,"com_%s.bin",fileName);
//The FDI does NOT update the FILE-time-date attributes. So delete and create with new date
//if(FStatusIsExist(fNameBuf))
// FDI_remove((char *)fNameBuf);
if(len==0)
{
DIAG_FILTER(SW_PLAT,PERFORMANCE,SAVE2FILE0, DIAG_INFORMATION)
diagPrintf("COMM MEM-DUMP File %s: nothing to save", fNameBuf);
}
else
{
pBuf = ADDR_CONVERT(pBuf);
if((fdiID = FDI_fopen(fNameBuf,"wb"))!=0)
{
count=FDI_fwrite(pBuf,sizeof(char),len, fdiID);
FDI_fclose(fdiID);
DIAG_FILTER(SW_PLAT,PERFORMANCE,SAVE2FILE, DIAG_INFORMATION)
diagPrintf("COMM MEM-DUMP File %s: %ld bytes saved", fNameBuf, count);
}
}
}
#else
typedef enum
{
EEH_OPEN_OK = 1,
EEH_OPEN_FAIL,
EEH_RD_OK,
EEH_RD_FAIL,
EEH_WRITE_OK,
EEH_WRITE_FAIL,
EEH_CLOSE_OK,
EEH_CLOSE_FAIL
}EehHalOpStatus;
extern BspCustomType customtype;
extern EehHalOpStatus EELOG_fopen_(const char* filename, const char* modeStr);
extern EehHalOpStatus EELOG_fwrite_(const void *buf, UINT32 chunkSize, UINT32 numChunks, UINT32 handle);
extern EehHalOpStatus EELOG_fclose_(void);
void SaveToFileEx(char* fileName, UINT8* pBuf, UINT32 len)
{
EehHalOpStatus fdiID, stat;
UINT32 count;
char fNameBuf[POSTMORTEM_BUF_NAME_SIZE + 4/*com_*/ + 4/*.bin*/ +4/*spare*/];
char temp[POSTMORTEM_BUF_NAME_SIZE + 4/*com_*/ + 4/*.bin*/ +4/*spare*/+5];
UINT32 nameLen;
#ifndef CRANE_SD_NOT_SUPPORT
unsigned int file_handle;
diag_comm_sd_log_info *info = diag_comm_sd_get_info();
#endif
//cut given name if too long
nameLen = strlen(fileName);
if(nameLen >= POSTMORTEM_BUF_NAME_SIZE)
{
fileName[POSTMORTEM_BUF_NAME_SIZE-1] = 0;
}
sprintf(fNameBuf,"com_%s.bin",fileName);
ErrorLogPrintf("EE LOG: Start to save %s, Len: %d", fNameBuf, len);
//The FDI does NOT update the FILE-time-date attributes. So delete and create with new date
//if(FStatusIsExist(fNameBuf))
// FDI_remove((char *)fNameBuf);
if(len == 0)
{
DIAG_FILTER(SW_PLAT,PERFORMANCE,SAVE2FILE0, DIAG_INFORMATION)
diagPrintf("COMM MEM-DUMP File %s: nothing to save", fNameBuf);
}
else
{
pBuf = ADDR_CONVERT(pBuf);
if(!DumpFileToSDEnable())
{
#ifdef YMODEM_EEH_DUMP
if (useYmodem())
{
ymodem_trans(pBuf, fNameBuf, len);
}
#endif
return;
}
#ifndef CRANE_SD_NOT_SUPPORT
sprintf(temp, "%s\\%s%d\\%s", DUMP_VOL, DIAG_SD_DIR_NAME, info->dindex, fNameBuf);
if((file_handle = (FAT_fopen(temp,"wbc"))) != 0)
{
count = FAT_fwrite(pBuf, sizeof(char), len, file_handle);
FAT_fclose(file_handle);
DIAG_FILTER(SW_PLAT,PERFORMANCE,SAVE2FILE, DIAG_INFORMATION)
diagPrintf("COMM MEM-DUMP File %s: %ld bytes saved", temp, count);
ErrorLogPrintf("COMM MEM-DUMP File %s: %ld bytes saved", temp, count);
}
else
{
//DIAG_FILTER(SW_PLAT,PERFORMANCE,SAVE2FILE, DIAG_INFORMATION)
//diagPrintf("Fat_open err\n);
ErrorLogPrintf("Fat_open err\n");
}
#endif
}
diagCommTransmitInSysException();
}
#endif
//ICAT EXPORTED FUNCTION - Diag,comMem,SaveComPostmortemEx
void SaveComPostmortemEx(void)
{
/*Fixed coverity[returned_pointer]*/
#if 0
EE_PostmortemDesc_Entry* p = getEntryByName( POSTMORTEM_BUF_NAME_EEBUF );
#else
EE_PostmortemDesc_Entry* p = NULL;
#endif
p = getEntryNext(1/*getFirst*/);
while (p != ENTRY_NOT_FOUND)
{
SaveToFileEx( p->name, ADDR_CONVERT(p->bufAddr), p->bufLen);
p = getEntryNext(0/*getFirst*/);
}
}
#ifdef QUEC_DUMP_NVM_SUPPORT
typedef struct
{
char name[16];
UINT16 fsize;
} EE_DUMP_BIN_Entry; //=16 bytes
EE_DUMP_BIN_Entry Dump_Bin_To_Flash[]={
{"com_EE_Hbuf.bin", 800},
{"com_rti_tsk.bin", 2148},
{"com_wdtKICK.bin", 128},
{0,0}
};
UINT8 Save_dump_flash_enable = 0;
void Quec_FlashSave_Dump_Enable(UINT8 EnableFlag)
{
if(EnableFlag == 1)
{
Save_dump_flash_enable = 1;
}
else
{
Save_dump_flash_enable = 0;
}
}
void Quec_EEcnt(void)
{
unsigned int EEcnt = 1;
FILE_ID fd;
size_t write_num = 0;
int ret = 0;
fd=FDI_fopen("EEcnt.bin","rb");
if (fd == 0)
{
RTI_LOG("FDI_fopen failedr ret=%d\r\n",ret);
}
else
{
FDI_fread((void *)(&EEcnt), 1, sizeof(EEcnt), fd);
FDI_fclose(fd);
EEcnt++;
}
fd=FDI_fopen("EEcnt.bin","wb");
if (fd == 0)
{
ret=-1;
RTI_LOG("FDI_fopen failedr ret=%d\r\n",ret);
return;
}
write_num = FDI_fwrite((void *)(&EEcnt), 1, sizeof(EEcnt), fd);
if (write_num != sizeof(EEcnt))
{
ret=-2;
RTI_LOG("FDI_write failedr ret=%d\r\n",ret);
}
FDI_fclose(fd);
}
int Quec_get_dump_cnt(void)
{
unsigned int EEcnt = 0;
FILE_ID fd;
int ret = 0;
fd=FDI_fopen("EEcnt.bin","rb");
if (fd == 0)
{
ret=-1;
RTI_LOG("FDI_fopen failedr ret=%d\r\n",ret);
goto err;
}
FDI_fread((void *)(&EEcnt), 1, sizeof(EEcnt), fd);
FDI_fclose(fd);
err:
return EEcnt;
}
int Quec_clean_dump_cnt(void)
{
int ret=0;
FILE_ID fd;
size_t write_num = 0;
unsigned int EEcnt = 0;
fd=FDI_fopen("EEcnt.bin","wb");
if (fd == 0)
{
ret=-1;
RTI_LOG("FDI_fopen failedr ret=%d\r\n",ret);
goto err;
}
write_num = FDI_fwrite((void *)(&EEcnt), 1, sizeof(EEcnt), fd);
if (write_num != sizeof(EEcnt))
{
ret=-2;
RTI_LOG("FDI_write failedr ret=%d\r\n",ret);
}
FDI_fclose(fd);
err:
return ret;
}
void Quec_SaveComPostmortem_FS(void)
{
EE_PostmortemDesc_Entry* p = NULL;
char fNameBuf[POSTMORTEM_BUF_NAME_SIZE + 4/*com_*/ + 4/*.bin*/ +4/*spare*/];
UINT32 nameLen;
UINT8 index;
int ret = 0;
FILE_ID fd;
UINT8 cnt=sizeof(Dump_Bin_To_Flash)/sizeof(EE_DUMP_BIN_Entry);
size_t write_num = 0;
RTI_LOG("%s, start\r\n",__func__);
p = getEntryNext(1/*getFirst*/);
while (p != ENTRY_NOT_FOUND)
{
//fatal_printf("%s, name=%s, len=%d\r\n",__func__,p->name,p->bufLen);
//cut given name if too long
nameLen = strlen(p->name);
if(nameLen >= POSTMORTEM_BUF_NAME_SIZE)
(p->name)[POSTMORTEM_BUF_NAME_SIZE-1] = 0;
sprintf(fNameBuf,"com_%s.bin",p->name);
for(index=0;index<cnt;index++)
{
if(!strncmp(Dump_Bin_To_Flash[index].name,fNameBuf,10))
break;
}
if(index < cnt)
{
fd=FDI_fopen(Dump_Bin_To_Flash[index].name,"wb");
if (fd == 0)
{
ret=-1;
RTI_LOG("FDI_fopen failedr ret=%d\r\n",ret);
continue;
}
write_num = FDI_fwrite((void *)(p->bufAddr), 1, p->bufLen, fd);
if (write_num != p->bufLen)
{
ret=-2;
RTI_LOG("FDI_write failedr ret=%d\r\n",ret);
}
FDI_fclose(fd);
RTI_LOG("save dump %d, index=%d,name=%s\r\n", ret, index, Dump_Bin_To_Flash[index].name);
}
p = getEntryNext(0/*getFirst*/);
}
Quec_EEcnt();
RTI_LOG("%s, end\r\n",__func__);
}
int Quec_Get_Dump_file(QUEC_DUMP_BIN_FILE* EEbuf,unsigned int EEbufnum)
{
UINT8 index;
UINT8 cnt=sizeof(Dump_Bin_To_Flash)/sizeof(EE_DUMP_BIN_Entry);
FILE_ID fd;
UINT8 errcnt=0;
int ret = 0;
int num=0;
RTI_LOG("%s, start\r\n",__func__);
cnt= (EEbufnum>cnt) ? cnt : EEbufnum;
do
{
if(EEbuf==NULL || EEbufnum == 0)
{
ret = -2;
RTI_LOG("%s,EEbuf is not init\r\n",__FUNCTION__);
break;
}
for(index=0;index<cnt;index++)
{
if(!strncmp(Dump_Bin_To_Flash[index].name,EEbuf[num].fname,10))
{
ret=0;
break;
}
}
if(index<cnt)
{
fd=FDI_fopen(Dump_Bin_To_Flash[index].name,"rb");
if (fd == 0)
{
errcnt++;
RTI_LOG("FDI_fopen failedr ret=%d\r\n",ret);
}
else
{
FDI_fread((void *)(EEbuf[num].EEbuf), 1, EEbuf[num].buflen, fd);
RTI_LOG("buflen=%d\r\n",EEbuf[num].buflen);
FDI_fclose(fd);
RTI_LOG("read dump %d, index=%d,name=%s\r\n", ret, index, Dump_Bin_To_Flash[index].name);
}
}
else
{
break;
}
if(num<EEbufnum)//�޶�,��ֹ��������Խ��
{
num++;
}
else
{
break;
}
}while(1);
if(errcnt==0)
{
ret=0;
RTI_LOG("FDI_remove succeed\r\n");
}
else
{
ret=-1;
RTI_LOG("FDI_remove filed errcnt=%d\r\n",errcnt);
}
RTI_LOG("%s, end\r\n",__func__);
return ret;
}
int Quec_Clear_Dump_file(void)
{
UINT8 index;
UINT8 errcnt=0;
int ret=0;
UINT8 cnt=sizeof(Dump_Bin_To_Flash)/sizeof(EE_DUMP_BIN_Entry);
for(index=0;index<cnt;index++)
{
ret=FDI_remove(Dump_Bin_To_Flash[index].name);
if(ret!=0)
{
errcnt++;
}
}
if(errcnt==0)
{
ret=0;
RTI_LOG("FDI_remove succeed\r\n");
}
else
{
ret=-1;
RTI_LOG("FDI_remove filed errcnt=%d\r\n",errcnt);
}
return ret;
}
#endif /*#ifdef QUEC_DUMP_NVM_SUPPORT*/
//-----------------------------------------------------------------------------
void EE_SaveComDDR_RWEx(void)
{
extern UINT32 Image$$DDR_RW_DATA$$Base;
extern UINT32 Image$$PS_NONCACHE_DATA$$Base;
extern UINT32 Image$$PS_NONCACHE_DATA_ENDMARK$$Base;
extern UINT32 Image$$DDR_PRIVATE_RW_AREA_ENDMARK$$Base;
extern UINT32 Image$$DDR_DSP_RO_ENDMARK$$Base;
extern UINT32 Image$$DDR_RO_EXEC$$Limit;
#if defined(CRANE_MCU_DONGLE)// && !defined(LTEONLY_8M8M) && !defined(CRANEL_4MRAM)
extern UINT32 Image$$PSRAM_END$$Base;
#endif
volatile UINT32 start_addr, end_addr;
UINT32 len;
volatile UINT8* pBuf;
start_addr=(UINT32)(&Image$$DDR_DSP_RO_ENDMARK$$Base);
#if defined(CRANE_MCU_DONGLE)// && !defined(LTEONLY_8M8M) && !defined(CRANEL_4MRAM)
end_addr=(UINT32)(&Image$$PSRAM_END$$Base);
#else
end_addr=(UINT32)(&Image$$DDR_PRIVATE_RW_AREA_ENDMARK$$Base);
#endif
len=end_addr-start_addr;
pBuf = (UINT8*)start_addr;
SaveToFileEx( "DDR_RW", (UINT8*)pBuf, len);
start_addr=(UINT32)(&Image$$PS_NONCACHE_DATA$$Base);
end_addr=(UINT32)(&Image$$PS_NONCACHE_DATA_ENDMARK$$Base);
len=end_addr-start_addr;
pBuf = (UINT8*)start_addr;
SaveToFileEx( "PS_DAT", (UINT8*)pBuf, len);
}
void EE_SaveCom_DSP_PSRAM(void)
{
extern UINT32 Image$$DDR_DSP_RO$$Base;
extern UINT32 Image$$DDR_DSP_RO_ENDMARK$$Base;
volatile UINT32 start_addr, end_addr;
UINT32 len;
volatile UINT8* pBuf;
start_addr =(UINT32)(&Image$$DDR_DSP_RO$$Base);
end_addr =(UINT32)(&Image$$DDR_DSP_RO_ENDMARK$$Base);
len=end_addr-start_addr + 0x4;
uart_printf("EE_SaveCom_DSP_PSRAM 0x%x 0x%x\r\n", start_addr, len);
pBuf = (UINT8*)start_addr;
SaveToFileEx( "DSP_DDR", (UINT8*)pBuf, len);
}
void EE_SaveCom_DSP_DTCM(void)
{
volatile UINT32 start_addr;
UINT32 len;
volatile UINT8* pBuf;
volatile UINT32* MSA_RESET_REG = (volatile UINT32*)0xD4050020;
if ((*(MSA_RESET_REG) & (0x1<<2)) != 0)
{
uart_printf("DSP is in reset, abort dumping DSP DTCM.\r\n");
return; //DSP in reset, not able to dump this.
}
start_addr =(UINT32)0xF0000000;
len =(UINT32)((CHIP_IS_CRANELR || CHIP_IS_CRANELG || CHIP_IS_CRANELRH)?0x00020000:0x00040000);//256K
uart_printf("EE_SaveCom_DSP_DTCM 0x%x 0x%x\r\n", start_addr, len);
pBuf = (UINT8*)start_addr;
SaveToFileEx( "DSPdtcm", (UINT8*)pBuf, len);
}
void EE_SaveCom_SQU(void)
{
volatile UINT32 start_addr;
UINT32 len;
volatile UINT8* pBuf;
start_addr =(UINT32)0xD1000000;
if(IsChipCraneL()||IsChipCraneLS()||IsChipCraneLR()||IsChipCraneLG()||IsChipCraneLRH()){
len =(UINT32)0x00008000;//32K
}else{
len =(UINT32)0x00010000;//64K
}
uart_printf("EE_SaveCom_SQU 0x%x 0x%x\r\n", start_addr, len);
pBuf = (UINT8*)start_addr;
SaveToFileEx( "SQU", (UINT8*)pBuf, len);
}
void EE_SaveCom_DSP_L2SRAM(void)
{
volatile UINT32 start_addr;
UINT32 len = 0x20000;
volatile UINT8* pBuf;
if (CHIP_IS_CRANEL_Z1)//this only for craneL Z1, craneL A0 same as craneM
{
start_addr =(UINT32)0xD1F40000;
len = 0x40000;//256K for CraneL
}
else
{
start_addr =(UINT32)0xD1F00000;
if ((CHIP_IS_CRANEG))
len = 0x60000; //384K for CraneG
else if (CHIP_IS_CRANELR || CHIP_IS_CRANELG || CHIP_IS_CRANELRH)
len = 0x10000; //64K for CraneLR
else
len = 0x20000; //128K for Crane and CraneM
}
uart_printf("EE_SaveCom_DSP_L2SRAM 0x%x 0x%x\r\n", start_addr, len);
pBuf = (UINT8*)start_addr;
SaveToFileEx( "L2_sram", (UINT8*)pBuf, len);
}
void EE_SaveCom_GNSS_SRAM(void)
{
volatile UINT32 start_addr;
UINT32 len = 0x20000;
volatile UINT8* pBuf;
if (CHIP_IS_CRANELS)
{
/* GNSS is Ready. */
if((*(volatile unsigned int *)0xD42828FC) & 0x10000)
{
start_addr =(UINT32)0xD60A8000;
len = 96 * 1024;
uart_printf("EE_SaveCom_GNSS_SRAM 0x%x 0x%x\r\n", start_addr, len);
pBuf = (UINT8*)start_addr;
SaveToFileEx( "GNSS_sram", (UINT8*)pBuf, len);
}
}
else if(CHIP_IS_CRANELG)
{
/* GNSS is Ready. */
if((*(volatile unsigned int *)0xD42828FC) & 0x10000)
{
start_addr =(UINT32)0xD6054000;
len = 64 * 1024;
uart_printf("EE_SaveCom_GNSS_SRAM 0x%x 0x%x\r\n", start_addr, len);
pBuf = (UINT8*)start_addr;
SaveToFileEx( "GNSS_sram", (UINT8*)pBuf, len);
}
}
}
#endif
#if defined(INTEL_FDI) && defined (_TAVOR_BOERNE_)
static void SaveToFile(char* fileName, UINT8* pBuf, UINT32 len)
{
FILE_ID fdiID;
UINT32 count;
char fNameBuf[POSTMORTEM_BUF_NAME_SIZE + 4/*com_*/ + 4/*.bin*/ +4/*spare*/];
UINT32 nameLen;
//cut given name if too long
nameLen = strlen(fileName);
if(nameLen >= POSTMORTEM_BUF_NAME_SIZE)
fileName[POSTMORTEM_BUF_NAME_SIZE-1] = 0;
sprintf(fNameBuf,"com_%s.bin",fileName);
//The FDI does NOT update the FILE-time-date attributes. So delete and create with new date
//if(FStatusIsExist(fNameBuf))
FDI_remove((char *)fNameBuf);
if(len==0)
{
DIAG_FILTER(SW_PLAT,PERFORMANCE,SAVE2FILE0, DIAG_INFORMATION)
diagPrintf("COMM MEM-DUMP File %s: nothing to save", fNameBuf);
}
else
{
pBuf = ADDR_CONVERT(pBuf);
if((fdiID = FDI_fopen(fNameBuf,"wb"))!=0)
{
count=FDI_fwrite(pBuf,sizeof(char),len, fdiID);
FDI_fclose(fdiID);
DIAG_FILTER(SW_PLAT,PERFORMANCE,SAVE2FILE, DIAG_INFORMATION)
diagPrintf("COMM MEM-DUMP File %s: %ld bytes saved", fNameBuf, count);
}
}
}
static EE_PostmortemDesc_Entry* getEntryNext(int getFirst)
{
void * addr = &EE_PostmortemDesc;
void * whellKnownAddr = (void*)& addr; //PUB_ADDR_OF_PTR2POSTMORTEM_DESC;
static EE_PostmortemDesc_Entry * pCurr;
static int idx;
if(getFirst)
{
pCurr = (EE_PostmortemDesc_Entry*) ADDR_CONVERT(*(UINT32*) ADDR_CONVERT(whellKnownAddr));
idx = 0;
}
else
{
pCurr++;
idx++;
if((pCurr->name[0] == 0) || (idx >= POSTMORTEM_NUMOF_ENTRIES))
return(ENTRY_NOT_FOUND);
}
return( (EE_PostmortemDesc_Entry*) ADDR_CONVERT(pCurr) );
}
static EE_PostmortemDesc_Entry* getEntryByName(char* name)
{
int i;
void * whellKnownAddr = (void*)PUB_ADDR_OF_PTR2POSTMORTEM_DESC;
EE_PostmortemDesc_Entry * p = (EE_PostmortemDesc_Entry*) ADDR_CONVERT(*(UINT32*) ADDR_CONVERT(whellKnownAddr));
EE_PostmortemDesc_Entry * retAddr = ENTRY_NOT_FOUND;
for(i=0; i < POSTMORTEM_NUMOF_ENTRIES; i++)
{
if(p->name[0] == 0)
break;//Last END-entry. Just exit
else
{
if(strcmp(p->name, name) == 0)
{
retAddr = p;
break;// found
}
p++;
}
}
return( (EE_PostmortemDesc_Entry*) ADDR_CONVERT(retAddr) );
}
static void printEEinfo(UINT8* pBuf)
{
// The pBuf points onto __CurrentExceptionLog.log
// Keep it in the pEElog after Comm/App address convertion.
// Since we need also the buffer CheckSum and Signature
// let's find also the buffer beginning pEE.
EE_Entry_t * pEElog = ((EE_Entry_t*)ADDR_CONVERT(pBuf));
EE_LogBuffer* pEE;
UINT32 logOffset;
logOffset = (UINT32) &( ((EE_LogBuffer*)pEElog)->log );
logOffset -= (UINT32)pEElog;
pEE = (EE_LogBuffer*) ( (UINT32)pEElog - logOffset );
EE_AssistingMaster_ASSERT_found = (pEE->logSignature == EE_RAM_BUFFER_SIGNATURE);
if(EE_AssistingMaster_ASSERT_found)
{
DIAG_FILTER(Diag,comMem,EE_LOG_TXT, DIAG_INFORMATION)
diagPrintf("COMM EE LOG: %s", pEElog->desc);
DIAG_FILTER(Diag,comMem,EE_LOG, DIAG_INFORMATION)
diagStructPrintf("COMM EE LOG: %S{EE_Entry_t}",(UINT16 *)pEElog,sizeof(EE_Entry_t));
}
else
{
DIAG_FILTER(Diag,comMem,EE_LOG_NOERR, DIAG_INFORMATION)
diagPrintf("COMM WDT expired (NOT caused by ASSERT)" );
}
}
//-----------------------------------------------------------------------------
//ICAT EXPORTED FUNCTION - Diag,comMem,SaveComPostmortem
void SaveComPostmortem(void)
{
EE_PostmortemDesc_Entry* p = getEntryByName( POSTMORTEM_BUF_NAME_EEBUF );
p = getEntryNext(1/*getFirst*/);
while (p != ENTRY_NOT_FOUND)
{
#ifdef PRINT_POSTMORTEM_DESC
DIAG_FILTER(Diag,comMem,DESC, DIAG_INFORMATION)
diagStructPrintf("%S{EE_PostmortemDesc_Entry}",(VOID*)p, sizeof(EE_PostmortemDesc_Entry));
#endif
if(strcmp(p->name, POSTMORTEM_BUF_NAME_EEBUF) == 0)
printEEinfo(p->bufAddr);
SaveToFile( p->name, ADDR_CONVERT(p->bufAddr), p->bufLen);
p = getEntryNext(0/*getFirst*/);
}
}
//ICAT EXPORTED FUNCTION - Diag,comMem,SaveCom_Addr_Len
void SaveCom_Addr_Len(void* p)
{
UINT32* pVal = (UINT32*)p;
UINT8* pBuf = (UINT8*) pVal[0];
UINT32 len = pVal[1];
SaveToFile( POSTMORTEM_BUF_NAME_GENDUMP, pBuf, len);
}
//-----------------------------------------------------------------------------
void EE_SaveComDDR_RW(UINT32 sizeLimitBytes)
{
LoadTableType *p = pLoadTable;
UINT8* pBuf;
UINT32 len;
if(p != (LoadTableType*)INVALID_ADDRESS)
{
pBuf = (UINT8*)(p->ramRWbegin);
if(sizeLimitBytes == 0) //do noting
return;
if(sizeLimitBytes <= 1024) //do NOT limit but use default - full dump
len = p->ramRWend - p->ramRWbegin;
else
{ //len = MIN(A,B)
len = ((p->ramRWend - p->ramRWbegin) < sizeLimitBytes) ?
(p->ramRWend - p->ramRWbegin) : sizeLimitBytes ;
}
DIAG_FILTER(Diag,comMem,DDR_RW, DIAG_INFORMATION)
diagPrintf("WAIT 1MIN! Be patient! Dumping 0x%lx bytes of DDR_RW", len);
SaveToFile( "DDR_RW", pBuf, len); //"com_DDR_RW.bin"
}
}
#if defined (EE_POSTMORTEM_EXTEND_ICAT_EXPORT)
//-----------------------------------------------------------------------------
//ICAT EXPORTED FUNCTION - Diag,comMem,SaveComDDR_RW
void EE_SaveComDDR_RW_ACAT(UINT32 *pSizeLimitBytes)
{
UINT32 sizeLimitBytes = *pSizeLimitBytes;
EE_SaveComDDR_RW(sizeLimitBytes);
}
//ICAT EXPORTED FUNCTION - Diag,comMem,SaveComMIPSbuf
void SaveComMIPSbuf(void)
{
EE_PostmortemDesc_Entry* p = getEntryByName( POSTMORTEM_BUF_NAME_MIPSRAM );
if(p != ENTRY_NOT_FOUND)
{
DIAG_FILTER(Diag,comMem,MIPS, DIAG_INFORMATION)
diagStructPrintf("%S{EE_PostmortemDesc_Entry}",(VOID*)p, sizeof(EE_PostmortemDesc_Entry));
SaveToFile( p->name, ADDR_CONVERT(p->bufAddr), p->bufLen);
}
}
//ICAT EXPORTED FUNCTION - Diag,comMem,SaveComEEbuf
void SaveComEEbuf(void)
{
EE_PostmortemDesc_Entry* p = getEntryByName( POSTMORTEM_BUF_NAME_EEBUF );
if(p != ENTRY_NOT_FOUND)
{
printEEinfo(p->bufAddr);
DIAG_FILTER(Diag,comMem,EE, DIAG_INFORMATION)
diagStructPrintf("%S{EE_PostmortemDesc_Entry}",(VOID*)p, sizeof(EE_PostmortemDesc_Entry));
SaveToFile( p->name, ADDR_CONVERT(p->bufAddr), p->bufLen);
}
}
#endif //EE_POSTMORTEM_EXTEND_ICAT_EXPORT
#endif//INTEL_FDI && _TAVOR_BOERNE_
#endif//_TAVOR_BOERNE_ _TAVOR_HARBELL_