?? freemaster_tsa.c
字號:
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
****************************************************************************//*!
*
* @file freemaster_tsa.c
*
* @brief FreeMaster TSA implementation
*
* @version 1.0.1.0
*
* @date Oct-12-2006
*
*******************************************************************************
*
* This file implements a new FreeMaster feature called Targer-side address
* translation.
*
*******************************************************************************/
#include "freemaster.h"
#include "freemaster_private.h"
#include "freemaster_protocol.h"
#if FMSTR_USE_TSA
/**************************************************************************//*!
*
* @brief TSA Initialization
*
******************************************************************************/
void FMSTR_InitTsa(void)
{
}
/**************************************************************************//*!
*
* @brief Handling GETTSAINFO and GETTSAINFO_EX command
*
* @param pMessageIO - original command (in) and response buffer (out)
*
* @return As all command handlers, the return value should be the buffer
* pointer where the response output finished (except checksum)
*
******************************************************************************/
FMSTR_BPTR FMSTR_GetTsaInfo(FMSTR_BPTR pMessageIO)
{
FMSTR_BPTR pResponse = pMessageIO;
const FMSTR_TSA_ENTRY* pTbl;
FMSTR_TSA_TINDEX nTblIndex;
FMSTR_TSA_TSIZE nTblSize = 0;
FMSTR_ADDR tmpAddr;
FMSTR_U16 tmp16;
// get index of table the PC is requesting
pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2);
pMessageIO = FMSTR_ValueFromBuffer16(&nTblIndex, pMessageIO);
// TSA flags
tmp16 = FMSTR_TSA_VERSION | FMSTR_TSA_FLAGS;
// sizeof TSA table entry items
if((sizeof(FMSTR_TSA_ENTRY)/4) == 4)
tmp16 |= FMSTR_TSA_INFO_32BIT; // 32bit TSA entries
// get the table (or NULL if no table on given index)
pTbl = FMSTR_TsaGetTable(nTblIndex, &nTblSize);
// success, flags
pResponse = FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK);
pResponse = FMSTR_ValueToBuffer16(pResponse, tmp16);
// table size in bytes
nTblSize *= FMSTR_CFG_BUS_WIDTH;
pResponse = FMSTR_ValueToBuffer16(pResponse, nTblSize);
// table address
FMSTR_PTR2ADDR(tmpAddr, pTbl);
return FMSTR_AddressToBuffer(pResponse, tmpAddr);
}
/**************************************************************************//*!
*
* @brief Private inline implementation of "strlen"
*
******************************************************************************/
FMSTR_U16 FMSTR_StrLen(FMSTR_ADDR nAddr)
{
const char* pStr;
FMSTR_U16 nLen = 0;
#ifdef __HCS12X__
// convert from logical to global if needed
nAddr = FMSTR_FixHcs12xAddr(nAddr);
#endif
pStr = (const char*) nAddr;
while(*pStr++)
nLen++;
return nLen;
}
/**************************************************************************//*!
*
* @brief Handling GETSTRLEN and GETSTRLEN_EX commands
*
* @param pMessageIO - original command (in) and response buffer (out)
*
* @return As all command handlers, the return value should be the buffer
* pointer where the response output finished (except checksum)
*
******************************************************************************/
FMSTR_BPTR FMSTR_GetStringLen(FMSTR_BPTR pMessageIO)
{
FMSTR_BPTR pResponse = pMessageIO;
FMSTR_ADDR nAddr;
FMSTR_U16 nLen = 0;
pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 1);
pMessageIO = FMSTR_AddressFromBuffer(&nAddr, pMessageIO);
nLen = FMSTR_StrLen(nAddr);
// return strign size in bytes (even on 16bit DSP)
nLen *= FMSTR_CFG_BUS_WIDTH ;
pResponse = FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK);
return FMSTR_ValueToBuffer16(pResponse, nLen);
}
/**************************************************************************//*!
*
* @brief Helper inline function for TSA memory region check
*
* @param nAddrUser - address of region to be checked
* @param wSizeUser - size of region to be checked
* @param nAddrSafe - address of known "safe" region
* @param wSizeSafe - size of safe region
*
* @return This function returns non-zero if given user space is safe
* (i.e. it lies in given safe space)
*
******************************************************************************/
#if defined(FMSTR_PLATFORM_56F8xxx) || defined(FMSTR_PLATFORM_56F8xx)
inline
#endif
FMSTR_BOOL FMSTR_CheckMemSpace(FMSTR_ADDR nAddrUser, FMSTR_SIZE8 wSizeUser,
FMSTR_ADDR nAddrSafe, FMSTR_SIZE wSizeSafe)
{
#ifdef __HCS12X__
// convert from logical to global if needed
nAddrUser = FMSTR_FixHcs12xAddr(nAddrUser);
nAddrSafe = FMSTR_FixHcs12xAddr(nAddrSafe);
#endif
if(nAddrUser < nAddrSafe)
return 0;
return (nAddrUser + wSizeUser) <= (nAddrSafe + wSizeSafe);
}
/**************************************************************************//*!
*
* @brief Check wether given memory region is "safe" (covered by TSA)
*
* @param dwAddr - address of the memory to be checked
* @param wSize - size of the memory to be checked
* @param bWriteAccess - write access is required
*
* @return This function returns non-zero if user space is safe
*
******************************************************************************/
FMSTR_BOOL FMSTR_CheckTsaSpace(FMSTR_ADDR dwAddr, FMSTR_SIZE8 wSize, FMSTR_BOOL bWriteAccess)
{
const FMSTR_TSA_ENTRY* pte;
FMSTR_TSA_TINDEX nTableIndex;
FMSTR_TSA_TSIZE i, cnt;
FMSTR_SIZE nInfo;
#if FMSTR_CFG_BUS_WIDTH >= 2
// TSA tables use sizeof() operator which returns size in "bus-widths"
wSize = (wSize + 1) / FMSTR_CFG_BUS_WIDTH;
#endif
// to be as fast as possible during normal opearaion,
// check variable entries in all tables first
for(nTableIndex=0; (pte=FMSTR_TsaGetTable(nTableIndex, &cnt)) != NULL; nTableIndex++)
{
// number of items in a table
cnt /= sizeof(FMSTR_TSA_ENTRY);
// all table entries
for(i=0; i<cnt; i++, pte++)
{
nInfo = (FMSTR_SIZE) pte->info.p;
// variable entry only (also check read-write flag)
if((nInfo & FMSTR_TSA_INFO_VAR_FLAG) && (!bWriteAccess || (nInfo & FMSTR_TSA_INFO_RWV_FLAG)))
{
// need to take the larger of the two in union (will be optimized by compiler anyway)
if(sizeof(pte->addr.p) < sizeof(pte->addr.n))
{
if(FMSTR_CheckMemSpace(dwAddr, wSize, (FMSTR_ADDR) pte->addr.n, nInfo >> 2))
return 1; // access granted!
}
else
{
if(FMSTR_CheckMemSpace(dwAddr, wSize, (FMSTR_ADDR) pte->addr.p, nInfo >> 2))
return 1; // access granted!
}
}
}
}
// no more writeable memory chunks available
if(bWriteAccess)
return 0;
// allow reading of recorder buffer
#if FMSTR_USE_RECORDER
if(FMSTR_IsInRecBuffer(dwAddr, wSize))
return 1;
#endif
// allow reading of any C-constant string referenced in TSA tables
for(nTableIndex=0; (pte=FMSTR_TsaGetTable(nTableIndex, &cnt)) != NULL; nTableIndex++)
{
// allow reading of the TSA table itself
if(FMSTR_CheckMemSpace(dwAddr, wSize, (FMSTR_ADDR)(FMSTR_U8*)pte, cnt))
return 1;
// number of items in a table
cnt /= sizeof(FMSTR_TSA_ENTRY);
// all table entries
for(i=0; i<cnt; i++, pte++)
{
// system strings are always accessible at C-pointers
if(pte->name.p && FMSTR_CheckMemSpace(dwAddr, wSize, (FMSTR_ADDR) pte->name.p, FMSTR_StrLen((FMSTR_ADDR) pte->name.p)))
return 1;
if(pte->type.p && FMSTR_CheckMemSpace(dwAddr, wSize, (FMSTR_ADDR) pte->type.p, FMSTR_StrLen((FMSTR_ADDR) pte->type.p)))
return 1;
}
}
// no valid TSA entry found => not-safe to access the memory
return 0;
}
#endif // FMSTR_USE_TSA
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -