Newer
Older
mbed-os / targets / TARGET_RENESAS / TARGET_RZ_A2XX / TARGET_GR_MANGO / device / mmu_RZ_A2M.c
@RyoheiHagimoto RyoheiHagimoto on 17 Aug 2020 16 KB Modifed some source files for GR-MANGO.
/**************************************************************************//**
 * @file     mmu_RZ_A2M.c
 * @brief    MMU Configuration for RZ_A2M Device Series
 * @version  V1.00
 * @date     6 Sep 2018
 *
 * @note
 *
 ******************************************************************************/
/*
 * Copyright (c) 2009-2020 ARM Limited. All rights reserved.
 * Copyright (c) 2018-2020 Renesas Electronics Corporation. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Memory map description

== User's Manual:Hardware ==
                                                     Memory Type
0xffffffff |--------------------------|             ------------
           |       Peripherals        |                Device
0xffff0000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0xfd000000 |--------------------------|             ------------
           |       Peripherals        |                Device
0xfcfe0000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0xfc040000 |--------------------------|             ------------
           |       Peripherals        |                Device
0xfc000000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0xf0002000 |--------------------------|             ------------
           |  Cortex-A9 private area  |                Device
0xf0000000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0xeb000000 |--------------------------|             ------------
           |       Peripherals        |                Device
0xea000000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0xe8240000 |--------------------------|             ------------
           |       Peripherals        |                Device
0xe8200000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0xe8050000 |--------------------------|             ------------
           |       Peripherals        |                Device
0xe8000000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0x80400000 |--------------------------|             ------------
           |     On Chip RAM 4MB      |                  RW
0x80000000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0x70000000 |--------------------------|             ------------
           |      OctaRAM 256MB       |                  RW
0x60000000 |--------------------------|             ------------
           |     OctaFlash 256MB      |                  RO
0x50000000 |--------------------------|             ------------
           |      HyperRAM 256MB      |                  RW
0x40000000 |--------------------------|             ------------
           |     HyperFlash 256MB     |                  RO
0x30000000 |--------------------------|             ------------
           |   SPI multi I/O 256MB    |                  RO
0x20000000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0x1f809000 |--------------------------|             ------------
           |       Peripherals        |                Device
0x1f808000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0x1f801000 |--------------------------|             ------------
           |       Peripherals        |                Device
0x1f800000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0x1f402000 |--------------------------|             ------------
           |       Peripherals        |                Device
0x1f400000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0x1f004000 |--------------------------|             ------------
           |       Peripherals        |                Device
0x1f000000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0x1c000000 |--------------------------|             ------------
           |        Page Fault        |                Fault
0x18000000 |--------------------------|             ------------
           |         CS5 64MB         |                  RW
0x14000000 |--------------------------|             ------------
           |         CS4 64MB         |                  RW
0x10000000 |--------------------------|             ------------
           |         CS3 64MB         |                  RW
0x0c000000 |--------------------------|             ------------
           |         CS2 64MB         |                  RW
0x08000000 |--------------------------|             ------------
           |         CS1 64MB         |                  RW
0x04000000 |--------------------------|             ------------
           |         CS0 64MB         |                  RW
0x00000000 |--------------------------|             ------------


== Actual setting of MMU ==
                                                     Memory Type
0xffffffff |--------------------------|             ------------
           |       Peripherals        |                Device
0xe8000000 |--------------------------|             ------------
           |            -             |                   -
0x80400000 |--------------------------|             ------------
           |     On Chip RAM 4MB      |                  RW
0x80000000 |--------------------------|             ------------
           |            -             |                   -
0x70000000 |--------------------------|             ------------
           |      OctaRAM 256MB       |                  RW
0x60000000 |--------------------------|             ------------
           |     OctaFlash 256MB      |                  RO
0x50000000 |--------------------------|             ------------
           |      HyperRAM 256MB      |                  RW
0x40000000 |--------------------------|             ------------
           |     HyperFlash 256MB     |                  RO
0x30000000 |--------------------------|             ------------
           |   SPI multi I/O 256MB    |                  RO
0x20000000 |--------------------------|             ------------
           |       Peripherals        |                Device
0x18000000 |--------------------------|             ------------
           |            -             |                   -
0x10000000 |--------------------------|             ------------
           |      CS3 SDRAM 64MB      |                  RW
0x0c000000 |--------------------------|             ------------
           |            -             |                   -
0x00000000 |--------------------------|             ------------
*/

// L1 Cache info and restrictions about architecture of the caches (CCSIR register):
// Write-Through support *not* available
// Write-Back support available.
// Read allocation support available.
// Write allocation support available.

//Note: You should use the Shareable attribute carefully.
//For cores without coherency logic (such as SCU) marking a region as shareable forces the processor to not cache that region regardless of the inner cache settings.
//Cortex-A versions of RTX use LDREX/STREX instructions relying on Local monitors. Local monitors will be used only when the region gets cached, regions that are not cached will use the Global Monitor.
//Some Cortex-A implementations do not include Global Monitors, so wrongly setting the attribute Shareable may cause STREX to fail.

//Recall: When the Shareable attribute is applied to a memory region that is not Write-Back, Normal memory, data held in this region is treated as Non-cacheable.
//When SMP bit = 0, Inner WB/WA Cacheable Shareable attributes are treated as Non-cacheable.
//When SMP bit = 1, Inner WB/WA Cacheable Shareable attributes are treated as Cacheable.


//Following MMU configuration is expected
//SCTLR.AFE == 1 (Simplified access permissions model - AP[2:1] define access permissions, AP[0] is an access flag)
//SCTLR.TRE == 0 (TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor)
//Domain 0 is always the Client domain
//Descriptors should place all memory in domain 0
//There are no restrictions by privilege level (PL0 can access all memory)


#include "RZ_A2M.h"

//Import symbols from linker
#if defined ( __ICCARM__ )
__no_init uint32_t Image$$TTB$$ZI$$Base @ "TTB";
__no_init uint32_t Image$$TTB_L2$$ZI$$Base @ "TTB_L2";
#else
extern uint32_t Image$$TTB$$ZI$$Base;
extern uint32_t Image$$TTB_L2$$ZI$$Base;
extern uint32_t Image$$RW_DATA_NC$$Base;
extern uint32_t Image$$ZI_DATA_NC$$Limit;
#endif

#define page4k_normal(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_4k; \
                                   region.domain = 0x0; \
                                   region.e_t = ECC_DISABLED; \
                                   region.g_t = GLOBAL; \
                                   region.inner_norm_t = WB_WA; \
                                   region.outer_norm_t = WB_WA; \
                                   region.mem_t = NORMAL; \
                                   region.sec_t = SECURE; \
                                   region.xn_t = EXECUTE; \
                                   region.priv_t = RW; \
                                   region.user_t = RW; \
                                   region.sh_t = NON_SHARED; \
                                   MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region);

#define page4k_normal_nc(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_4k; \
                                   region.domain = 0x0; \
                                   region.e_t = ECC_DISABLED; \
                                   region.g_t = GLOBAL; \
                                   region.inner_norm_t = NON_CACHEABLE; \
                                   region.outer_norm_t = NON_CACHEABLE; \
                                   region.mem_t = NORMAL; \
                                   region.sec_t = SECURE; \
                                   region.xn_t = EXECUTE; \
                                   region.priv_t = RW; \
                                   region.user_t = RW; \
                                   region.sh_t = NON_SHARED; \
                                   MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region);

__STATIC_INLINE void MMU_TTSection_Va(uint32_t *ttb, uint32_t vaddress, uint32_t paddress, uint32_t count, uint32_t descriptor_l1)
{
    uint32_t offset;
    uint32_t entry;
    uint32_t i;

    offset = vaddress >> 20;
    entry  = (paddress & 0xFFF00000) | descriptor_l1;

    //4 bytes aligned
    ttb = ttb + offset;

    for (i = 0; i < count; i++) {
        //4 bytes aligned
        *ttb++ = entry;
        entry += OFFSET_1M;
    }
}

static void MMU_TTPage4k_local(uint32_t *ttb, uint32_t start_address, uint32_t size, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2)
{
    uint32_t base_address  = start_address & 0xFF000000;
    uint32_t section_count = (start_address & 0x00F00000) >> 20;
    uint32_t rest_count    = (size + OFFSET_4K - 1) / OFFSET_4K;
    uint32_t count;
    uint32_t count_adjust;

    if (rest_count == 0) {
        return;
    }

    if ((start_address & 0x000FFFFF) != 0) {
        /* When "start_address" is not the beginning of the section. */
        count_adjust = 0x100 - ((start_address & 0x000FFFFF) / OFFSET_4K);

        count = rest_count;
        if (count > count_adjust) {
            count = count_adjust;
        }
        MMU_TTPage4k(ttb, start_address, count, descriptor_l1,
                     (uint32_t *)((uint32_t)ttb_l2 + (0x400 * section_count)), descriptor_l2);
        rest_count -= count;
        section_count++;
    }

    while (rest_count > 0) {
        count = rest_count;
        if (count > 0x100) {
            count = 0x100;
        }
        MMU_TTPage4k(ttb, base_address + (OFFSET_1M * section_count), count, descriptor_l1,
                     (uint32_t *)((uint32_t)ttb_l2 + (0x400 * section_count)), descriptor_l2);
        rest_count -= count;
        section_count++;
    }
}

void MMU_CreateTranslationTable(void)
{
    mmu_region_attributes_Type region;

    uint32_t Sect_Normal_Cod; //outer & inner wb/wa, non-shareable, executable, ro, domain 0, base addr 0
    uint32_t Sect_Normal_RW;  //as Sect_Normal_Cod, but writeable and not executable
    uint32_t Sect_Device_RW;  //as Sect_Device_RO, but writeable
    uint32_t Sect_Normal_NC;  //non-shareable, non-executable, rw, domain 0, base addr 0

    uint32_t Page_L1_4k  = 0x0;  //generic
    uint32_t Page_4k_Normal_RW;
    uint32_t Page_4k_Normal_NC;

    uint32_t sram_non_cache_base;
    uint32_t sram_non_cache_size;

#if defined ( __ICCARM__ )
#pragma section="NC_RAM"
    sram_non_cache_base = (uint32_t)__section_begin("NC_RAM");
    sram_non_cache_size = (uint32_t)__section_end("NC_RAM") - (uint32_t)__section_begin("NC_RAM");
#else
    sram_non_cache_base = (uint32_t)&Image$$RW_DATA_NC$$Base;
    sram_non_cache_size = (uint32_t)&Image$$ZI_DATA_NC$$Limit - (uint32_t)&Image$$RW_DATA_NC$$Base;
#endif

    /*
     * Generate descriptors. Refer to core_ca.h to get information about attributes
     *
     */
    //Create descriptors for Vectors, RO, RW, ZI sections
    section_normal_cod(Sect_Normal_Cod, region);
    section_normal(Sect_Normal_RW, region);
    section_normal_nc(Sect_Normal_NC, region);

    //Create descriptors for peripherals
    section_device_rw(Sect_Device_RW, region);
    //Create descriptors for 4k pages
    page4k_normal(Page_L1_4k, Page_4k_Normal_RW, region);
    page4k_normal_nc(Page_L1_4k, Page_4k_Normal_NC, region);

    /*
     *  Define MMU flat-map regions and attributes
     *
     */
    //Create 4GB of faulting entries
    MMU_TTSection(&Image$$TTB$$ZI$$Base, 0, 4096, DESCRIPTOR_FAULT);

    // memory map.
    MMU_TTSection(&Image$$TTB$$ZI$$Base, RZ_A2_SDRAM, 64, Sect_Normal_RW);
    MMU_TTSection(&Image$$TTB$$ZI$$Base, RZ_A2_SPI_IO, 256, Sect_Normal_Cod);
    MMU_TTSection(&Image$$TTB$$ZI$$Base, RZ_A2_HYPER_FLASH, 256, Sect_Normal_Cod);
    MMU_TTSection(&Image$$TTB$$ZI$$Base, RZ_A2_HYPER_RAM, 256, Sect_Normal_RW);
    MMU_TTSection(&Image$$TTB$$ZI$$Base, RZ_A2_OCTA_FLASH, 256, Sect_Normal_Cod);
    MMU_TTSection(&Image$$TTB$$ZI$$Base, RZ_A2_OCTA_RAM, 256, Sect_Normal_RW);
    MMU_TTSection(&Image$$TTB$$ZI$$Base, RZ_A2_PERIPH_BASE0, 384, Sect_Device_RW);
    MMU_TTSection(&Image$$TTB$$ZI$$Base, RZ_A2_PERIPH_BASE1, 128, Sect_Device_RW);

    // SRAM
    // Register all memory as cache.
    MMU_TTPage4k_local(&Image$$TTB$$ZI$$Base, RZ_A2_ONCHIP_SRAM_BASE, 0x400000, Page_L1_4k,
                       (uint32_t *)&Image$$TTB_L2$$ZI$$Base, Page_4k_Normal_RW);

    // Overwrite non-cache if necessary.
    MMU_TTPage4k_local(&Image$$TTB$$ZI$$Base, sram_non_cache_base, sram_non_cache_size, Page_L1_4k,
                       (uint32_t *)&Image$$TTB_L2$$ZI$$Base, Page_4k_Normal_NC);

    // Virtual address
    MMU_TTSection_Va(&Image$$TTB$$ZI$$Base, RZ_A2_HYPER_FLASH_IO, RZ_A2_HYPER_FLASH, 256, Sect_Device_RW);
    MMU_TTSection_Va(&Image$$TTB$$ZI$$Base, RZ_A2_OCTA_FLASH_NC, RZ_A2_OCTA_FLASH, 256, Sect_Normal_NC);

    /* Set location of level 1 page table
    ; 31:14 - Translation table base addr (31:14-TTBCR.N, TTBCR.N is 0 out of reset)
    ; 13:7  - 0x0
    ; 6     - IRGN[0] 0x0 (Inner WB WA)
    ; 5     - NOS     0x0 (Non-shared)
    ; 4:3   - RGN     0x1 (Outer WB WA)
    ; 2     - IMP     0x0 (Implementation Defined)
    ; 1     - S       0x0 (Non-shared)
    ; 0     - IRGN[1] 0x1 (Inner WB WA) */
    __set_TTBR0(((uint32_t)&Image$$TTB$$ZI$$Base) | 0x48);
    __ISB();

    /* Set up domain access control register
    ; We set domain 0 to Client and all other domains to No Access.
    ; All translation table entries specify domain 0 */
    __set_DACR(1);
    __ISB();
}