Files
xiuos/Ubiquitous/XiZi_IIoT/board/imx8mp/board.c
T
2025-02-26 19:42:02 +08:00

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");
}