static void BSP_START_SECTION
    lpc32xx_setup_translation_table_and_enable_mmu(uint32_t ctrl)
  {
    uint32_t const dac =
      ARM_CP15_DAC_DOMAIN(LPC32XX_MMU_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT);
    uint32_t *const ttb = (uint32_t *) bsp_section_work_end;
    size_t const config_entry_count =
      sizeof(lpc32xx_mmu_config_table) / sizeof(lpc32xx_mmu_config_table [0]);
    size_t i = 0;

    arm_cp15_set_domain_access_control(dac);
    arm_cp15_set_translation_table_base(ttb);

    /* Initialize translation table with invalid entries */
    for (i = 0; i < ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT; ++i) {
      ttb [i] = 0;
    }

    for (i = 0; i < config_entry_count; ++i) {
      lpc32xx_mmu_set_entries(ttb, &lpc32xx_mmu_config_table [i]);
    }

    /* Enable MMU and cache */
    ctrl |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M;
    arm_cp15_set_control(ctrl);
  }
Exemple #2
0
void rpi_start_rtems_on_secondary_processor(void)
{
  uint32_t ctrl;

  ctrl = arm_cp15_start_setup_mmu_and_cache(
    0,
    ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
  );

  rpi_ipi_initialize();

  arm_cp15_set_domain_access_control(
    ARM_CP15_DAC_DOMAIN(ARM_MMU_DEFAULT_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT)
  );

  /* FIXME: Sharing the translation table between processors is brittle */
  arm_cp15_set_translation_table_base(
    (uint32_t *) bsp_translation_table_base
  );

  arm_cp15_tlb_invalidate();

  ctrl |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M;
  ctrl &= ~ARM_CP15_CTRL_V;
  arm_cp15_set_control(ctrl);

  _SMP_Start_multitasking_on_secondary_processor();
}
Exemple #3
0
void mmu_init(mmu_sect_map_t *map)
{
    mmu_lvl1_t *lvl1_base;
    int i;

    /* flush the cache and TLB */
    arm_cp15_cache_invalidate();
    arm_cp15_tlb_invalidate();

    /* set manage mode access for all domains */
    arm_cp15_set_domain_access_control(0xffffffff);

    lvl1_base = (mmu_lvl1_t *)&_ttbl_base;

    /* set up the trans table */
    mmu_set_map_inval(lvl1_base);
    arm_cp15_set_translation_table_base(lvl1_base);

    /* create a 1:1 mapping of the entire address space */
    i = 0;
    while(map[i].size != 0) {
        int c = 0;  /* to avoid uninitialized warnings */
        int b = 0;  /* to avoid uninitialized warnings */
        int pbase;
        int vbase;
        int sects;

        switch (map[i].cache_flags) {
        case MMU_CACHE_NONE:
            c = 0;
            b = 0;
            break;
        case MMU_CACHE_BUFFERED:
            c = 0;
            b = 1;
            break;
        case MMU_CACHE_WTHROUGH:
            c = 1;
            b = 0;
            break;
        case MMU_CACHE_WBACK:
            c = 1;
            b = 1;
            break;
        }

        pbase = (map[i].paddr & 0xfff00000) >> 20;
        vbase = (map[i].vaddr & 0xfff00000) >> 20;
        sects = map[i].size;

        while (sects > 0) {
            lvl1_base[vbase] = MMU_SET_LVL1_SECT(pbase << 20,
                                                 MMU_SECT_AP_ALL,
                                                 0,
                                                 c,
                                                 b);
            pbase++;
            vbase++;
            sects--;
        }
        i++;
    }

    /* flush the cache and TLB */
    arm_cp15_cache_invalidate();
    arm_cp15_tlb_invalidate();

    /*  I & D caches turned on */
    arm_cp15_set_control(MMU_CTRL_DEFAULT |
                         MMU_CTRL_D_CACHE_EN |
                         MMU_CTRL_I_CACHE_EN |
                         MMU_CTRL_ALIGN_FAULT_EN |
                         MMU_CTRL_LITTLE_ENDIAN |
                         MMU_CTRL_MMU_EN);

    return;
}