blob: 3de332691914f1efbc973cbc6dabd0ed4e73726a [file] [log] [blame]
/*--------------------------------------------------------------------------------------------------------------------
(C) Copyright 2006, 2007 Marvell DSPC 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<94>) 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 Intels 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 IMPLEMENTATION FILE
****************************************************************************
*
* Filename: loadTable.c
*
* The OBM is responsible to copy image from flash to the DDR.
* It doesn't know about real image size and always copy the maximum 7MB.
* The problems:
* - long time for copying (about 2 sec),
* - all ERR/spy/debug buffers are overwriten.
*
* SOLUTION:
* Put the Image BEGIN and END address onto predefined area - offset_0x1C0 size 0x40
* Add the the text-signature to recognize are these addresses present in image or not.
* The signature is following the BEGIN/END and is next ":BEGIN:END:LOAD_TABLE_SIGNATURE"
* OBM should check signature in flash and if it is present MAY use the size=(END-BEGIN).
* If signature is invalid the default 7MB is used.
* The IMAGE_END region added into scatter file
*
******************************************************************************/
#define _LOAD_TABLE_C_
#include <string.h>
#include "loadTable.h"
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include "linux_types.h"
#include "eeh_ioctl.h"
#include "pxa_dbg.h"
#include "diag_API.h"
#include "cploader.h"
#include "pxa9xx_cp.h"
extern int sehdrv_fd;
unsigned long PRE_LOADTABLE_PHYADDR;
void printComLoadTable(void);
LoadTableType *pLoadTable = (LoadTableType*)INVALID_ADDRESS;
char* CommRWaddr = NULL;
char* CommRObaseAddr = NULL;
char* CommResetAddrRoutine = NULL;
char* CommShareMemoryAddr = NULL;
UINT32 g_CommRWArea, g_CommRWAreaSizeInBytes; //Read Write area to post mortem
UINT32 getCommImageBaseAddr(void)
{
// ASSERT((UINT32)pLoadTable != INVALID_ADDRESS);
if ((UINT32)pLoadTable == INVALID_ADDRESS)
return(INVALID_ADDRESS);
else
return(pLoadTable->imageBegin);
}
void getAppComShareMemAddr(UINT32* begin, UINT32* end)
{
if ((UINT32)pLoadTable == INVALID_ADDRESS)
{ //set the SAME address for begin and end, e.g. the size is zero
*begin = INVALID_ADDRESS;
*end = INVALID_ADDRESS;
}
else
{
*begin = pLoadTable->sharedFreeBegin;
*end = pLoadTable->sharedFreeEnd;
}
}
#define PAGE_OFFS_BITS(pgsz) ((unsigned long)(pgsz) - 1)
#define PAGE_MASK_BITS(pgsz) (~PAGE_OFFS_BITS(pgsz))
void * eeh_mmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset)
{
int pageSize = sysconf(_SC_PAGESIZE);
unsigned long addrAligned;
volatile unsigned long* pa;
void* vpa;
// Align the length so the mapped area is page-aligned and contains the requested area
addrAligned = offset & PAGE_MASK_BITS(pageSize);
if ((vpa = mmap(addr, len + (offset - addrAligned), prot, flags, fd, addrAligned)) == MAP_FAILED)
{
ERRMSG("mmap failed (%d)\n", errno);
return NULL;
}
pa = (volatile unsigned long*)
((unsigned char *)vpa + (offset & PAGE_OFFS_BITS(pageSize)));
return (void *)pa;
}
int eeh_munmap (void *addr, size_t length)
{
int pageSize = sysconf(_SC_PAGESIZE);
unsigned long addrAligned = (unsigned long)addr & PAGE_MASK_BITS(pageSize);
return munmap((void*)addrAligned, length + ((unsigned long)addr - addrAligned));
}
void commImageTableInit(void)
{
char signature[] = LOAD_TABLE_SIGNATURE_STR;
BOOL signatureFound = FALSE;
LoadTableType* p;
CommRObaseAddr = eeh_mmap(0, sizeof(LoadTableType) + LOAD_TABLE_OFFSET, PROT_READ, MAP_PRIVATE, sehdrv_fd, PRE_LOADTABLE_PHYADDR);
if (CommRObaseAddr == NULL)
{
ERRMSG("%s: CommRObaseAddr is NULL\n", __FUNCTION__);
return;
}
DBGMSG("%s: CommRObaseAddr Logic Addr: 0x%p\n", __FUNCTION__, CommRObaseAddr);
// Find loadTable
p = (LoadTableType*)(CommRObaseAddr + LOAD_TABLE_OFFSET);
signatureFound = ( memcmp(p->Signature, signature, sizeof(signature)) == 0 );
if (signatureFound)
{
pLoadTable = p;
DBGMSG("commImageTableInit: signatureFound\n");
DBGMSG("pLoadTable->imageBegin: 0x%x, pLoadTable->imageEnd: 0x%x\n", pLoadTable->imageBegin, pLoadTable->imageEnd);
DBGMSG("pLoadTable->ramRWbegin: 0x%x, pLoadTable->ramRWend: 0x%x\n", pLoadTable->ramRWbegin, pLoadTable->ramRWend);
DBGMSG("pLoadTable->sharedFreeBegin: 0x%x, pLoadTable->sharedFreeEnd: 0x%x\n", pLoadTable->sharedFreeBegin, pLoadTable->sharedFreeEnd);
//printComLoadTable();
g_CommRWArea = p->ramRWbegin;
DBGMSG("%s: g_CommRWArea: 0x%x\n", __FUNCTION__, g_CommRWArea);
//g_CommRWAreaSizeInBytes = (p->ramRWend - p->ramRWbegin + 4);
g_CommRWAreaSizeInBytes = p->imageBegin - OFFSET_IN_ARBEL_IMAGE + get_cpmem_size() - p->ramRWbegin;
CommRWaddr = eeh_mmap(0, g_CommRWAreaSizeInBytes, PROT_READ | PROT_WRITE, MAP_SHARED, sehdrv_fd, (UINT32)ADDR_CONVERT(p->ramRWbegin));
if (CommRWaddr == NULL)
{
ERRMSG("%s: CommRWaddr is NULL\n", __FUNCTION__);
return;
}
DBGMSG("%s: CommRWaddr: 0x%x\n", __FUNCTION__, CommRWaddr);
return;
}
else
{
ERRMSG("commImageTableInit: signature NOT Found\n");
return;
}
}
void commImageTableFree(void)
{
if (CommRObaseAddr != NULL)
{
eeh_munmap(CommRObaseAddr, LOAD_TABLE_OFFSET + sizeof(LoadTableType));
CommRObaseAddr = NULL;
}
if (CommRWaddr != NULL)
{
eeh_munmap(CommRWaddr, g_CommRWAreaSizeInBytes);
CommRWaddr = NULL;
}
return;
}
void* ConvertPhysicalAddrToVirtualAddr(UINT32 PhysicalAddr)
{
void* ret_Addr = NULL;
UINT32 StartAddr, OffsetInBytes;
StartAddr = PRE_LOADTABLE_PHYADDR;
OffsetInBytes = LOAD_TABLE_OFFSET + sizeof(LoadTableType);
//if((PhysicalAddr >= StartAddr)&&(PhysicalAddr <= StartAddr+OffsetInBytes)){ //Comm Space
// ret_Addr = (CommRObaseAddr+(PhysicalAddr-StartAddr));
//}
if ((PhysicalAddr >= (UINT32)ADDR_CONVERT(StartAddr)) && (PhysicalAddr <= (UINT32)ADDR_CONVERT(StartAddr + OffsetInBytes)))
{
ret_Addr = (CommRObaseAddr + (PhysicalAddr - (UINT32)ADDR_CONVERT(StartAddr)));
return ret_Addr;
}
StartAddr = g_CommRWArea;
OffsetInBytes = g_CommRWAreaSizeInBytes;
//if((PhysicalAddr >= StartAddr)&&(PhysicalAddr <= StartAddr+OffsetInBytes)){
// ret_Addr = (CommRWaddr+(PhysicalAddr-StartAddr));
//}
if ((PhysicalAddr >= (UINT32)ADDR_CONVERT(StartAddr)) && (PhysicalAddr <= (UINT32)ADDR_CONVERT(StartAddr + OffsetInBytes)))
{
ret_Addr = (CommRWaddr + (PhysicalAddr - (UINT32)ADDR_CONVERT(StartAddr)));
}
//RETAILMSG(1, (TEXT("[SHACHAR_DEBUG] ** VA Conv PhysicalAddr=%x VA=%x ADDR_CONVERT(VA)=%x ** .\r\n"),PhysicalAddr,ret_Addr,(UINT32)ADDR_CONVERT(ret_Addr)));
return(ret_Addr);
}
//#ifdef _DIAG_ENABLED_
//#include "diag.h"
//ICAT EXPORTED FUNCTION - Diag,comMem,printComLoadTable
void printComLoadTable(void)
{
if ((UINT32)pLoadTable != INVALID_ADDRESS)
{
DIAG_FILTER(Diag, comMem, image, DIAG_INFORMATION)
diagPrintf("COMM image BEGIN=0x%lx, END=0x%lx, rw-ram-Begin=0x%lx",
ADDR_CONVERT(pLoadTable->imageBegin), ADDR_CONVERT(pLoadTable->imageEnd),
ADDR_CONVERT(pLoadTable->ramRWbegin) );
}
else
{
DIAG_FILTER(Diag, comMem, imageNO, DIAG_INFORMATION)
diagPrintf("COMM loadTable not found");
}
}
//#endif