229 lines
10 KiB
C
229 lines
10 KiB
C
/*
|
|
* Copyright (c) 2020 AIIT XUOS Lab
|
|
* XiUOS is licensed under Mulan PSL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PSL v2 for more details.
|
|
*/
|
|
|
|
/*************************************************
|
|
File name: board.c
|
|
Description: support NXP.imx8mp-board init configure and driver/task/... init
|
|
Others:
|
|
History:
|
|
1. Date: 2025-02-26
|
|
Author: AIIT XUOS Lab
|
|
Modification:
|
|
1. support NXP.imx8mp-board InitBoardHardware
|
|
*************************************************/
|
|
|
|
#include "clock_config.h"
|
|
#include "board.h"
|
|
#include "fsl_rdc.h"
|
|
#include "pin_mux.h"
|
|
#include "fsl_clock.h"
|
|
#include <device.h>
|
|
#include "rsc_table.h"
|
|
#include "xs_base.h"
|
|
|
|
#include <connect_uart.h>
|
|
|
|
#define BOARD_IMX8MP
|
|
extern void MU1_M7_IRQHandler(int irqn, void *arg);
|
|
DECLARE_HW_IRQ(MU1_M7_IRQn, MU1_M7_IRQHandler, NONE);
|
|
|
|
extern int rpmsg_remote(void);
|
|
void BOARD_ConfigMPU(void)
|
|
{
|
|
/* __CACHE_REGION_START and __CACHE_REGION_SIZE are defined in the linker file */
|
|
extern uint32_t __CACHE_REGION_START[];
|
|
extern uint32_t __CACHE_REGION_SIZE[];
|
|
uint32_t cacheStart = (uint32_t)__CACHE_REGION_START;
|
|
uint32_t size = (uint32_t)__CACHE_REGION_SIZE;
|
|
uint32_t i = 0;
|
|
|
|
/* Disable I cache and D cache */
|
|
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
|
|
{
|
|
SCB_DisableICache();
|
|
}
|
|
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
|
|
{
|
|
SCB_DisableDCache();
|
|
}
|
|
|
|
/* Disable MPU */
|
|
ARM_MPU_Disable();
|
|
|
|
/* MPU configure:
|
|
* Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable,
|
|
* SubRegionDisable, Size)
|
|
* API in mpu_armv7.h.
|
|
* param DisableExec Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches
|
|
* disabled.
|
|
* param AccessPermission Data access permissions, allows you to configure read/write access for User and
|
|
* Privileged mode.
|
|
* Use MACROS defined in mpu_armv7.h:
|
|
* ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO
|
|
* Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes.
|
|
* TypeExtField IsShareable IsCacheable IsBufferable Memory Attribtue Shareability Cache
|
|
* 0 x 0 0 Strongly Ordered shareable
|
|
* 0 x 0 1 Device shareable
|
|
* 0 0 1 0 Normal not shareable Outer and inner write
|
|
* through no write allocate
|
|
* 0 0 1 1 Normal not shareable Outer and inner write
|
|
* back no write allocate
|
|
* 0 1 1 0 Normal shareable Outer and inner write
|
|
* through no write allocate
|
|
* 0 1 1 1 Normal shareable Outer and inner write
|
|
* back no write allocate
|
|
* 1 0 0 0 Normal not shareable outer and inner
|
|
* noncache
|
|
* 1 1 0 0 Normal shareable outer and inner
|
|
* noncache
|
|
* 1 0 1 1 Normal not shareable outer and inner write
|
|
* back write/read acllocate
|
|
* 1 1 1 1 Normal shareable outer and inner write
|
|
* back write/read acllocate
|
|
* 2 x 0 0 Device not shareable
|
|
* Above are normal use settings, if your want to see more details or want to config different inner/outter cache
|
|
* policy.
|
|
* please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide <dui0646b_cortex_m7_dgug.pdf>
|
|
* param SubRegionDisable Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled.
|
|
* param Size Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in
|
|
* mpu_armv7.h.
|
|
*/
|
|
|
|
/* Region 0 [0x0000_0000 - 0x4000_0000] : Memory with Device type, not executable, not shareable, non-cacheable. */
|
|
MPU->RBAR = ARM_MPU_RBAR(0, 0x00000000U);
|
|
MPU->RASR = ARM_MPU_RASR(1, ARM_MPU_AP_FULL, 0, 0, 0, 1, 0, ARM_MPU_REGION_SIZE_1GB);
|
|
|
|
/* Region 1 TCML[0x0000_0000 - 0x0001_FFFF]: Memory with Normal type, not shareable, non-cacheable */
|
|
MPU->RBAR = ARM_MPU_RBAR(1, 0x00000000U);
|
|
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_128KB);
|
|
|
|
/* Region 2 QSPI[0x0800_0000 - 0x0FFF_FFFF]: Memory with Normal type, not shareable, cacheable */
|
|
MPU->RBAR = ARM_MPU_RBAR(2, 0x08000000U);
|
|
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128MB);
|
|
|
|
/* Region 3 TCMU[0x2000_0000 - 0x2002_0000]: Memory with Normal type, not shareable, non-cacheable */
|
|
MPU->RBAR = ARM_MPU_RBAR(3, 0x20000000U);
|
|
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_128KB);
|
|
|
|
/* Region 4 DDR[0x4000_0000 - 0x8000_0000]: Memory with Normal type, not shareable, non-cacheable */
|
|
MPU->RBAR = ARM_MPU_RBAR(4, 0x40000000U);
|
|
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
|
|
|
|
/*
|
|
Non-cacheable area is provided in DDR memory, the DDR region [0x80000000 ~ 0x81000000](please see the
|
|
imx8mp-evk-rpmsg.dts) totally 16MB is revserved for CM7 core. You can put global or static uninitialized
|
|
variables in NonCacheable section(initialized variables in NonCacheable.init section) to make them uncacheable.
|
|
Since the base address of MPU region should be multiples of region size, to make it simple, the MPU region 5 set
|
|
the address space 0x80000000 ~ 0xBFFFFFFF to be non-cacheable. Then MPU region 6 set the text and data section to
|
|
be cacheable if the program running on DDR. The cacheable area base address should be multiples of its size in
|
|
linker file, they can be modified per your needs.
|
|
*/
|
|
/* Region 5 DDR[0x8000_0000 - 0xBFFFFFFF]: Memory with Normal type, not shareable, non-cacheable */
|
|
MPU->RBAR = ARM_MPU_RBAR(5, 0x80000000U);
|
|
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
|
|
|
|
while ((size >> i) > 0x1U)
|
|
{
|
|
i++;
|
|
}
|
|
/* If run on DDR, configure text and data section to be cacheable */
|
|
if (i != 0)
|
|
{
|
|
/* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */
|
|
assert((size & (size - 1)) == 0);
|
|
assert(!(cacheStart % size));
|
|
assert(size == (uint32_t)(1 << i));
|
|
assert(i >= 5);
|
|
|
|
/* Region 6 DDR[cacheStart]: Memory with Normal type, not shareable, cacheable */
|
|
MPU->RBAR = ARM_MPU_RBAR(6, cacheStart);
|
|
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 1, 1, 0, (i - 1));
|
|
}
|
|
|
|
/*
|
|
* Enable MPU and HFNMIENA feature
|
|
* HFNMIENA ensures that M7 core uses MPU configuration when in hard fault, NMI, and FAULTMASK handlers,
|
|
* otherwise all memory regions are accessed without MPU protection, which has high risks of cacheable,
|
|
* especially for AIPS systems.
|
|
*/
|
|
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
|
|
|
|
/* Enable I cache and D cache */
|
|
SCB_EnableICache();
|
|
SCB_EnableDCache();
|
|
}
|
|
|
|
void BOARD_RdcInit(void)
|
|
{
|
|
/* Move M7 core to specific RDC domain 1 */
|
|
rdc_domain_assignment_t assignment = {0};
|
|
|
|
assignment.domainId = BOARD_DOMAIN_ID;
|
|
RDC_SetMasterDomainAssignment(RDC, kRDC_Master_M7, &assignment);
|
|
|
|
/*
|
|
* The M7 core is running at domain 1, now enable the clock gate of the following IP/BUS/PLL in domain 1 in the CCM.
|
|
* In this way, to ensure the clock of the peripherals used by M core not be affected by A core which is running at
|
|
* domain 0.
|
|
*/
|
|
CLOCK_EnableClock(kCLOCK_Iomux);
|
|
|
|
CLOCK_EnableClock(kCLOCK_Ipmux1);
|
|
CLOCK_EnableClock(kCLOCK_Ipmux2);
|
|
CLOCK_EnableClock(kCLOCK_Ipmux3);
|
|
|
|
#if defined(FLASH_TARGET)
|
|
CLOCK_EnableClock(kCLOCK_Qspi);
|
|
#endif
|
|
|
|
CLOCK_ControlGate(kCLOCK_SysPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for SysPLL1 in Domain 1 */
|
|
CLOCK_ControlGate(kCLOCK_SysPll2Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for SysPLL2 in Domain 1 */
|
|
CLOCK_ControlGate(kCLOCK_SysPll3Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for SysPLL3 in Domain 1 */
|
|
CLOCK_ControlGate(kCLOCK_AudioPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for AudioPLL1 in Domain 1 */
|
|
CLOCK_ControlGate(kCLOCK_AudioPll2Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for AudioPLL2 in Domain 1 */
|
|
CLOCK_ControlGate(kCLOCK_VideoPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for VideoPLL1 in Domain 1 */
|
|
}
|
|
|
|
/* This is the timer interrupt service routine. */
|
|
void SysTick_Handler(int irqn, void *arg)
|
|
{
|
|
TickAndTaskTimesliceUpdate();
|
|
}
|
|
|
|
/**
|
|
* This function will initial imx8mp board.
|
|
*/
|
|
void InitBoardHardware()
|
|
{
|
|
char ch;
|
|
/* Init board hardware. */
|
|
/* M7 has its local cache and enabled by default,
|
|
* need to set smart subsystems (0x28000000 ~ 0x3FFFFFFF)
|
|
* non-cacheable before accessing this address region */
|
|
BOARD_ConfigMPU();
|
|
/* Board specific RDC settings */
|
|
BOARD_RdcInit();
|
|
|
|
BOARD_InitPins();
|
|
BOARD_BootClockRUN();
|
|
SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
|
|
InitBoardMemory((void *)HEAP_BEGIN, (void *)HEAP_END);
|
|
|
|
HwUartInit();
|
|
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
|
|
|
|
KPrintf("\nconsole init completed.\n");
|
|
copyResourceTable();
|
|
|
|
KPrintf("board init done.\n");
|
|
KPrintf("start kernel...\n");
|
|
} |