📄 pagetab.c
字号:
}
/* Now write all the values to the copro */
ARMulif_CPWrite(&tab->coredesc, 15, 2, &Cacheable_reg);
ARMulif_CPWrite(&tab->coredesc, 15, 3, &WriteBuffer_reg);
ARMulif_CPWrite(&tab->coredesc, 15, 5, &Protection_reg);
ARMulif_CPWrite(&tab->coredesc, 15, 6, Region_regs);
/* Final thing to do is set the Configuration register */
ARMulif_CPRead(&tab->coredesc, 15, 1, &Config_reg);
option = ToolConf_Lookup(config,ARMulCnf_Cache);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_C, TRUE);
option = ToolConf_Lookup(config,ARMulCnf_WriteBuffer);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_W, TRUE);
option = ToolConf_Lookup(config,ARMulCnf_ICache);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_I, TRUE);
if (tab->Set_Endian)
{
if (tab->sh_Bigend32)
Config_reg |= ARM_MMU_B;
else
Config_reg &= ~(ARM_MMU_B);
}
option = ToolConf_Lookup(config,ARMulCnf_MMU);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_M, TRUE);
option = ToolConf_Lookup(config,ARMulCnf_HighExceptionVectors);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_V, TRUE);
if (!(ToolConf_DLookupBool(config, ARMulCnf_FastBus, FALSE)))
Config_reg |= 0x40000000;
else
Config_reg &= ~0x40000000;
if(tab->hasTCRAM)
{
if ((ToolConf_DLookupBool(config, ARMulCnf_TCIRAM, FALSE)))
{
Config_reg |= (1<<18);
}
if ((ToolConf_DLookupBool(config, ARMulCnf_TCDRAM, FALSE))) {
Config_reg |= (1<<16);
}
}
#ifdef VERBOSE
printf("Pagetab.c:PU: writing %08lx to CP15 Reg1\n",
(unsigned long)Config_reg);
#endif
ARMulif_CPWrite(&tab->coredesc, 15, 1, &Config_reg);
return;
}
static void pagetab_TCRAM(PagetabState *tab)
{
toolconf config = tab->clone;
const char *option;
ARMword CP15R1[16];
/* Variables to hold the values eventually sent to copro 15.
They are all different sizes, but for simplicity's sake they
are stored as longs.
*/
unsigned long Config_reg;
/* Final thing to do is set the Configuration register */
ARMulif_CPRead(&tab->coredesc, 15, 1, &CP15R1[0]);
Config_reg = CP15R1[0];
option = ToolConf_Lookup(config,ARMulCnf_WriteBuffer);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_W, TRUE);
#ifdef OldCode
option = ToolConf_Lookup(config,ARMulCnf_BigEnd);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_B, TRUE);
#else
if (tab->Set_Endian)
{
if (tab->sh_Bigend32)
{
Config_reg |= ARM_MMU_B;
}
else
{
Config_reg &= ~(ARM_MMU_B);
}
}
#endif
option = ToolConf_Lookup(config,ARMulCnf_HighExceptionVectors);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_V, TRUE);
/* These are for the 966E-S (not the same as 946) */
if ((ToolConf_DLookupBool(config, ARMulCnf_TCIRAM, FALSE)))
Config_reg |= 0x1000;
if ((ToolConf_DLookupBool(config, ARMulCnf_TCDRAM, FALSE)))
Config_reg |= 0x4;
#ifdef VERBOSE
printf("Pagetab.c:TCRAM: writing %08lx to CP15 Reg1\n",
(unsigned long)Config_reg);
#endif
CP15R1[0]= Config_reg;
ARMulif_CPWrite(&tab->coredesc, 15, 1, &CP15R1[0]);
return;
}
static void v6pagetab_ProtectionUnit(PagetabState *tab)
{
toolconf config = tab->clone;
const char *option;
/* Variables to hold the values eventually sent to copro 15.
They are all different sizes, but for simplicity's sake they
are stored as longs.
*/
unsigned long Config_reg=0;
ARMword start;
ARMword size;
bool_int Bufferable;
bool_int Cacheable;
bool_int Shareable;
ARMWord TEXBits;
ARMWord APBits;
bool_int Execute_Never;
/* reg value */
ARMWord access_permissions;
ARMWord region_vals[7] = {0,0,0,0,0,0,0};
toolconf region;
char buffer[32];
int i,x;
disable_MMU(tab); /* Disables the MPU. */
for (i = 15; i >= 0; i--) { /* a bitmask, 'DI' */
/* For each type of region. Highest priority comes last and ovewrites */
sprintf(buffer,"MPUREGION[%d]",i);
region = ToolConf_Child(config,(tag_t)buffer);
if (region != NULL) {
start = ToolConf_DLookupUInt(region, ARMulCnf_PhysicalBase, 0);
option = ToolConf_Lookup(region, ARMulCnf_Size);
if (option != NULL) {
size = ToolConf_Power(option, TRUE);
} else {
int n = ToolConf_DLookupUInt(region, ARMulCnf_Pages, 4096);
size = n << 20;
}
/* to get the 5 bit size value from the actual size,
* we have to do a linear search, to find the most
* significant bit set.(Any other bit is ignored)
*/
for (x = 31; x >= 12; x--) {
/* Any value for size less than 0x1000 is considered 0 i.e. 4G */
if (size & (1 << x)) break;
}
size = (x < 12) ? 0x1f : x-1;
/* for the moment I am assuming if we get this far we want the region enabled */
Bufferable = ToolConf_DLookupBool(region,(tag_t)"BUFFERABLE",FALSE);
Cacheable = ToolConf_DLookupBool(region,(tag_t)"CACHEABLE",FALSE);
Shareable = ToolConf_DLookupBool(region,(tag_t)"SHAREABLE",FALSE);
Execute_Never = ToolConf_DLookupBool(region,(tag_t)"EXECUTE_NEVER"
,FALSE);
TEXBits = ToolConf_DLookupUInt(region,(tag_t)"TEX",0);
APBits = ToolConf_DLookupUInt(region,(tag_t)"ACCESSPERMISIONS",3);
access_permissions = (APBits & 7) << 8;
access_permissions |= (TEXBits & 7) << 3;
if(Bufferable)
access_permissions |= 1;
if(Cacheable)
access_permissions |= 2;
if(Shareable)
access_permissions |= 4;
if(Execute_Never)
access_permissions |= (1 << 12);
region_vals[6] = i;
region_vals[0] = start;
region_vals[2] = (size << 1) | 1;
region_vals[4] = access_permissions;
ARMulif_CPWrite(&tab->coredesc, 15, 6, region_vals);
}
}
/* Final thing to do is set the Configuration register */
ARMulif_CPRead(&tab->coredesc, 15, 1, &Config_reg);
option = ToolConf_Lookup(config,ARMulCnf_Cache);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_C, TRUE);
option = ToolConf_Lookup(config,ARMulCnf_WriteBuffer);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_W, TRUE);
option = ToolConf_Lookup(config,ARMulCnf_ICache);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_I, TRUE);
if (tab->Set_Endian)
{
if (tab->sh_Bigend32)
Config_reg |= ARM_MMU_B;
else
Config_reg &= ~(ARM_MMU_B);
}
option = ToolConf_Lookup(config,ARMulCnf_MMU);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_M, TRUE);
option = ToolConf_Lookup(config,ARMulCnf_HighExceptionVectors);
Config_reg = ToolConf_AddFlag(option, Config_reg, ARM_MMU_V, TRUE);
#ifdef VERBOSE
printf("Pagetab.c:PU: writing %08lx to CP15 Reg1\n",
(unsigned long)Config_reg);
#endif
ARMulif_CPWrite(&tab->coredesc, 15, 1, &Config_reg);
return;
}
static void pagetab_reset(PagetabState *tab)
{
if (tab->pt_verbose)
Hostif_ConsolePrint(tab->hostif, "Pagetab(%s) RESET\n",
PT_CP15TypeNames[tab->pt_CP15TYPE] );
if(tab->hasV6MPU)
{
v6pagetab_ProtectionUnit(tab);
}
else if (tab->hasPU)
{
/* protection unit */
pagetab_ProtectionUnit(tab);
}
else if (tab->hasMMU)
{
/* MMU */
pagetab_MMU(tab);
}
else if (tab->hasTCRAM)
{
pagetab_TCRAM(tab);
}
else
{
uint32 value =
ARMulif_GetConfig(&tab->coredesc,ARM_MMU_P | ARM_MMU_D);
uint32 old_value = value;
if(ToolConf_DLookupBool(tab->clone,ARMulCnf_Prog32,TRUE))
value |=ARM_MMU_P;
else
value &= ~(uint32)ARM_MMU_P;
if(ToolConf_DLookupBool(tab->clone,ARMulCnf_Data32,TRUE))
value |=ARM_MMU_D;
else
value &= ~(uint32)ARM_MMU_D;
#ifdef VERBOSE_RESET
printf("Pagetab.c:NoSysCopro: writing %08lx to Config\n",
(unsigned long)value);
#endif
ARMulif_SetConfig(&tab->coredesc, old_value ^ value, value);
}
}
static unsigned pagetab_ConfigEvents(void *handle, void *data)
{
PagetabState *tab = (PagetabState *)handle;
ARMul_Event *evt = data;
if (evt->event == ConfigEvent_Reset)
{
pagetab_reset(tab);
}
return FALSE;
}
BEGIN_EXIT(Pagetab)
{
PagetabState *tab = state;
ToolConf_Reset(tab->clone);
}
END_EXIT(Pagetab)
BEGIN_INIT(Pagetab)
{
PagetabState *tab = state;
Hostif_PrettyPrint(hostif, config, ", Pagetables" );
if (tab != NULL) tab->clone = ToolConf_Clone(config);
if (tab != NULL && tab->clone != NULL) {
ARMulif_InstallEventHandler(&tab->coredesc,
ConfigEventSel,
pagetab_ConfigEvents, tab);
/* Continue... */
}
else
{
return RDIError_OutOfStore;
}
/* This would not be in the cloned toolconf, so read it here. */
tab->pt_arch = ToolConf_DLookupUInt(config, ARMulCnf_Architecture, 0);
if (!tab->pt_arch) {
Hostif_ConsolePrint(tab->hostif,
"\n**WARNING :Pagetab cannot read processor Architecture - assuming 5.\n");
tab->pt_arch = 5;
}
tab->pt_verbose = ToolConf_DLookupBool(config,(tag_t)"VERBOSE", FALSE);
tab->hasMMU = ToolConf_DLookupBool(config,(tag_t)"HASMMU",FALSE);
tab->hasPU = ToolConf_DLookupBool(config,(tag_t)"HASPU",FALSE);
tab->hasTCRAM = ToolConf_DLookupBool(config,(tag_t)"HASTCRAM",FALSE);
tab->hasV6MPU = ToolConf_DLookupBool(config,(tag_t)"HASV6MPU",FALSE);
tab->pt_CP15TYPE = (tab->hasPU) ? PT_PU : (tab->hasMMU) ? PT_MMU :
(tab->hasTCRAM) ? PT_TCRAM : PT_OTHER;
/* Decide whether the debugger has asked us to set the bytesex,
* and which endianness if so. */
{
/* First, see if I've been configured */
char const *option = ToolConf_Lookup(config, ARMulCnf_BigEnd);
if (option && strchr("bBlLYyNn", option[0]))
{
state->sh_Bigend32 = (strchr("bBYy", option[0]) != NULL);
state->Set_Endian = TRUE;
#ifdef VERBOSE_RESET
printf("BIGEND=%u\n",state->sh_Bigend32);
#endif
}
/* Else see if I want to follow the debugger (default is yes) or
* hardware (not default). */
else if (ToolConf_DLookupBool(config,Dbg_Cnf_TargetHWEndian,FALSE))
{
state->Set_Endian = false;
}
else if ((type & RDIOpen_ByteSexMask) != RDIOpen_DontCareEndian)
{
state->sh_Bigend32 =
((type & RDIOpen_ByteSexMask) == RDIOpen_BigEndian);
state->Set_Endian = TRUE;
#ifdef VERBOSE_RESET
printf("RDIOpen, BIGEND=%u\n",state->sh_Bigend32);
#endif
}
else if ( ((option=ToolConf_Lookup(config, Dbg_Cnf_ByteSex))!=NULL) &&
strchr("bBlL", option[0]))
{
state->Set_Endian = TRUE;
state->sh_Bigend32 = (strchr("bB", option[0]) != NULL);
#ifdef VERBOSE_RESET
printf("ByteSex=%u\n",state->sh_Bigend32);
#endif
}
else
{
state->Set_Endian = false;
}
/* And if we're boing asked for BE-8 mode... */
/* Later, tweaking signals BIGENDINIT and UBITINIT is the
* virtuous way, but there is one requested setup this doesn't support-
* BE8 without Unaligned.. */
if (ToolConf_DLookupBool(state->config, ARMulCnf_HAS_BE8, FALSE) && state->Set_Endian)
{
/* Now for the unaligned bit */
state->sh_Unaligned = ToolConf_DLookupBool(state->config, ARMulCnf_UNALIGNED, FALSE);
state->Set_Unaligned = TRUE;
if (ToolConf_DLookupBool(state->config, ARMulCnf_BIGEND_IS_BE8, FALSE))
{
if (state->sh_Bigend32)
{
state->sh_Bigend32 = FALSE;
state->Set_Endian = TRUE;
state->sh_Bigend8 = TRUE;
state->Set_Endian8 = TRUE;
if (state->pt_verbose)
Hostif_PrettyPrint(hostif, config, "(BE-8)" );
}
}
else
{
/* LE or BE32 */
if (state->sh_Bigend32)
{
/* BE32 clears U and EE */
state->sh_Unaligned = FALSE;
state->sh_Bigend8 = FALSE;
state->Set_Endian8 = TRUE;
}
}
}
}
}
END_INIT(Pagetab)
/*--- <SORDI STUFF> ---*/
#define SORDI_DLL_NAME_STRING "Pagetab"
#define SORDI_DLL_DESCRIPTION_STRING "Page-table initialiser"
#define SORDI_RDI_PROCVEC Pagetab_AgentRDI
#include "perip_sordi.h"
#include "perip_rdi_agent.h"
IMPLEMENT_AGENT_PROCS_NOEXE_NOMODULE(Pagetab)
IMPLEMENT_AGENT_PROCVEC_NOEXE(Pagetab)
/*--- </> ---*/
/* EOF pagetab.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -