MMU module

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11058 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
isiora 2017-11-22 09:59:36 +00:00
parent 520032b848
commit 28ec07319b
2 changed files with 476 additions and 0 deletions

View File

@ -0,0 +1,363 @@
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio.
This file is part of ChibiOS.
ChibiOS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file mmu.c
* @brief MMU code.
*
* @addtogroup MMU
* @{
*/
#if !defined(CH_CFG_USE_MMU) || defined(__DOXYGEN__)
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "mmu.h"
#include "armparams.h"
#include "ARMCA5.h"
#if defined(__GNUC__) || defined(__DOXYGEN__)
#include "cmsis_gcc.h"
#else
#include "cmsis_armcc.h"
#endif
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*
* Use 1MB granularity. It best fits the SAMA5D2 memory layout.
*
* The MMU table contains 4096 entries.
* Each entry in the mmu table (short descriptor, type 1MB section) is 32 bit wide (total 16kB),
* and is structured in this way (with examples):
*
* +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
* |3 2|1 |1|1 |1|1 |1 1|1 1| | | | | | | |
* |1 0|9 |8|7 |6|5 |4 2|1 0|9|8 5|4 |3|2|1|0 |
* +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
* | section |NS|0|nG|S|AP[2]|TEX[2:0]|AP[1:0]| |domain|XN|C|B|1|PXN|
* +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
* | |0 |0|0 |1|0 |111 |11 |0|1111 |0 |1|1|1|0 | == normal, cacheable
* | |0 |0|0 |1|0 |100 |11 |0|1111 |0 |0|0|1|0 | == normal, no-cacheable
* | |0 |0|0 |1|0 |000 |11 |0|1111 |0 |0|1|1|0 | == device
* | |0 |0|0 |1|0 |000 |11 |0|1111 |0 |0|0|1|0 | == strongly-ordered
* | |0 |0|0 |0|0 |000 |00 |0|0000 |0 |0|0|0|0 | == undefined
*
* Domains are 'manager'. Accesses are not checked against the permission bits in tlb.
*/
static uint32_t mmuTable[4096] __attribute__ ((aligned (16384)));
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
/**
* @brief MMU Module initialization.
* @note This function is implicitly invoked on system initialization,
* there is no need to explicitly initialize the module.
*
* @notapi
*/
void __mmu_init(void) {
uint32_t pm;
/*
* Default, undefined regions
*/
for (pm = 0; pm < 4096; ++pm)
mmuTable[pm] = TTE_SECT_UNDEF;
/*
* ROM region
*
* 0x00000000
*/
mmuTable[0] = TTE_SECT_SECTION(0x00000000) |
TTE_SECT_MEM_NO_CACHEABLE |
TTE_SECT_RO_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* NFC SRAM region
*
* 0x00100000
*/
mmuTable[1] = TTE_SECT_SECTION(0x00100000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* SRAM region
*
* 0x00200000
*/
mmuTable[2] = TTE_SECT_SECTION(0x00200000) |
TTE_SECT_MEM_CACHEABLE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* UDPHS RAM region
*
* 0x00300000
*/
mmuTable[3] = TTE_SECT_SECTION(0x00300000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* UHPHS region
*
* 0x00400000
*/
mmuTable[4] = TTE_SECT_SECTION(0x00400000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* UDPHS region
*
* 0x00500000
*/
mmuTable[5] = TTE_SECT_SECTION(0x00500000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* AXIMX region
*
* 0x00600000
*/
mmuTable[6] = TTE_SECT_SECTION(0x00600000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* DAP region
*
* 0x00700000
*/
mmuTable[7] = TTE_SECT_SECTION(0x00700000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* L2CC region, low
*
* 0x00a00000
*/
mmuTable[0xa] = TTE_SECT_SECTION(0x00a00000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* L2CC region, hi
*
* 0x00b00000
*/
mmuTable[0xb] = TTE_SECT_SECTION(0x00b00000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* EBI regions
*
* 0x10000000 - 0x1fffffff
*/
for (pm = 0x100; pm < 0x200; pm++)
mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
TTE_SECT_MEM_STRONGLY_ORD |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* DDR regions
*
* 0x20000000 - 0x3fffffff
*/
for (pm = 0x200; pm < 0x400; pm++)
mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
TTE_SECT_MEM_CACHEABLE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* DDR AESB regions
*
* 0x40000000 - 0x5fffffff
*/
for (pm = 0x400; pm < 0x600; pm++)
mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
TTE_SECT_MEM_CACHEABLE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* EBI 1, 2 and 3 regions
*
* 0x60000000 - 0x8fffffff
*/
for (pm = 0x600; pm < 0x900; pm++)
mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
TTE_SECT_MEM_STRONGLY_ORD |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* QSPI0/1 AESB MEM regions
*
* 0x90000000 - 0x9fffffff
*/
for (pm = 0x900; pm < 0xa00; pm++)
mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
TTE_SECT_MEM_STRONGLY_ORD |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* SDMMC0/1 regions
*
* 0xa0000000 - 0xbfffffff
*/
for (pm = 0xa00; pm < 0xc00; pm++)
mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
TTE_SECT_MEM_STRONGLY_ORD |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* NFC regions
*
* 0xc0000000 - 0xcfffffff
*/
for (pm = 0xc00; pm < 0xd00; pm++)
mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
TTE_SECT_MEM_STRONGLY_ORD |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* QSPI0/1 MEM regions
*
* 0xd0000000 - 0xdfffffff
*/
for (pm = 0xd00; pm < 0xe00; pm++)
mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
TTE_SECT_MEM_STRONGLY_ORD |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* Internal peripherals regions
*
* 0xf0000000
* 0xf8000000
* 0xfc000000
*/
mmuTable[0xf00] = TTE_SECT_SECTION(0xf0000000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
mmuTable[0xf80] = TTE_SECT_SECTION(0xf8000000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
mmuTable[0xfc0] = TTE_SECT_SECTION(0xfc000000) |
TTE_SECT_DEVICE |
TTE_SECT_RW_ACCESS |
TTE_SECT_DOM(0x0F) |
TTE_SECT_EXE_NEVER |
TTE_SECT_S | TTE_TYPE_SECT;
/*
* Invalidate I/D cache
* Enable caches and MMU
*/
__set_TTBR0((uint32_t)mmuTable|0x5B);
__set_DACR(0xC0000000);
__DSB();
__ISB();
/*
* I cache invalidate and enable
*/
pm = __get_SCTLR();
if ((pm & SCTLR_I_Msk) == 0) {
__set_ICIALLU(0);
__set_SCTLR(pm | SCTLR_I_Msk);
}
/*
* MMU enable
*/
pm = __get_SCTLR();
if ((pm & SCTLR_M_Msk) == 0)
__set_SCTLR(pm | SCTLR_M_Msk);
/*
* D cache clean, invalidate and enable
*/
pm = __get_SCTLR();
if ((pm & SCTLR_C_Msk) == 0) {
__L1C_CleanInvalidateCache(DCISW_CLEAN_AND_INV);
__set_SCTLR(pm | SCTLR_C_Msk);
}
}
#endif /* CH_CFG_USE_MMU */
/** @} */

View File

@ -0,0 +1,113 @@
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio.
This file is part of ChibiOS.
ChibiOS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file mmu.h
* @brief MMU macros and structures.
*
* @addtogroup MMU
* @{
*/
#ifndef MMU_H
#define MMU_H
#if !defined(CH_CFG_USE_MMU) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
#define DCISW_INVALIDATE 0
#define DCISW_CLEAN 1
#define DCISW_CLEAN_AND_INV 2
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/*
* Translation Table Entry descriptor macros
*
* Type Section layout:
* +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
* |3 2|1 |1|1 |1|1 |1 1|1 1| | | | | | | |
* |1 0|9 |8|7 |6|5 |4 2|1 0|9|8 5|4 |3|2|1|0 |
* +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
* | section |NS|0|nG|S|AP[2]|TEX[2:0]|AP[1:0]| |domain|XN|C|B|1|PXN|
* +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
*
*/
#define TTE_TYPE_SECT (0x01 << 1)
#define TTE_SECT_B (0x01 << 2)
#define TTE_SECT_C (0x01 << 3)
#define TTE_SECT_XN (0x01 << 4)
#define TTE_SECT_DOM(x) ((x) << 5)
#define TTE_SECT_AP0 (0x01 << 10)
#define TTE_SECT_AP1 (0x01 << 11)
#define TTE_SECT_TEX(x) ((x) << 12)
#define TTE_SECT_AP2 (0x01 << 15)
#define TTE_SECT_S (0x01 << 16)
#define TTE_SECT_NG (0x01 << 17)
#define TTE_SECT_NS (0x01 << 19)
#define TTE_SECT_MEM_CACHEABLE (TTE_SECT_TEX(0b111)|TTE_SECT_B|TTE_SECT_C)
#define TTE_SECT_MEM_NO_CACHEABLE (TTE_SECT_TEX(0b100))
#define TTE_SECT_MEM_STRONGLY_ORD (TTE_SECT_TEX(0b000))
#define TTE_SECT_DEVICE (TTE_SECT_B)
#define TTE_SECT_EXE_NEVER (TTE_SECT_XN)
#define TTE_SECT_RW_ACCESS (TTE_SECT_AP1|TTE_SECT_AP0)
#define TTE_SECT_RO_ACCESS (TTE_SECT_AP1)
#define TTE_SECT_UNDEF (0)
#define TTE_SECT_SECTION(addr) ((addr) & 0xFFF00000)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void __mmu_init(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
#endif /* CH_CFG_USE_MMU */
#endif /* MMU_H */
/** @} */