⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pagetab.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
    }
    /* 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 + -