/* * Copyright (c) 2021 Weidmueller Interface GmbH & Co. KG * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #include "soc.h" /* System Level Control Registers (SLCR) */ #define SLCR_UNLOCK 0x0008 #define SLCR_UNLOCK_KEY 0xdf0d #define AXI_GPIO_MMU_ENTRY(id)\ MMU_REGION_FLAT_ENTRY("axigpio",\ DT_REG_ADDR(id),\ DT_REG_SIZE(id),\ MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), static const struct arm_mmu_region mmu_regions[] = { MMU_REGION_FLAT_ENTRY("vectors", 0x00000000, 0x1000, MT_STRONGLY_ORDERED | MPERM_R | MPERM_X), MMU_REGION_FLAT_ENTRY("mpcore", 0xF8F00000, 0x2000, MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), MMU_REGION_FLAT_ENTRY("ocm", DT_REG_ADDR(DT_CHOSEN(zephyr_ocm)), DT_REG_SIZE(DT_CHOSEN(zephyr_ocm)), MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), /* ARM Arch timer, GIC are covered by the MPCore mapping */ /* GEMs */ #if DT_NODE_HAS_STATUS(DT_NODELABEL(gem0), okay) MMU_REGION_FLAT_ENTRY("gem0", DT_REG_ADDR(DT_NODELABEL(gem0)), DT_REG_SIZE(DT_NODELABEL(gem0)), MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(gem1), okay) MMU_REGION_FLAT_ENTRY("gem1", DT_REG_ADDR(DT_NODELABEL(gem1)), DT_REG_SIZE(DT_NODELABEL(gem1)), MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), #endif /* GPIO controller */ #if DT_NODE_HAS_STATUS(DT_NODELABEL(psgpio), okay) MMU_REGION_FLAT_ENTRY("psgpio", DT_REG_ADDR(DT_NODELABEL(psgpio)), DT_REG_SIZE(DT_NODELABEL(psgpio)), MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), #endif DT_FOREACH_STATUS_OKAY(xlnx_xps_gpio_1_00_a, AXI_GPIO_MMU_ENTRY) }; const struct arm_mmu_config mmu_config = { .num_regions = ARRAY_SIZE(mmu_regions), .mmu_regions = mmu_regions, }; /* Platform-specific early initialization */ void soc_reset_hook(void) { /* * When coming out of u-boot rather than downloading the Zephyr binary * via JTAG, a few things modified by u-boot have to be re-set to a * suitable default value for Zephyr to run, namely: * * - u-boot places the exception vectors somewhere in RAM and then * lets the VBAR register point to them. Zephyr uses the default * vector table location at address zero (and maybe at some later * time alternatively the HIVECS position). If VBAR isn't reset * to zero, the system crashes during the first context switch when * SVC is invoked. * - u-boot sets the following bits in the SCTLR register: * - [I] ICache enable * - [C] DCache enable * - [Z] Branch prediction enable * - [A] Enforce strict alignment enable * [I] and [C] will be enabled during the MMU init -> disable them * until then. [Z] is probably not harmful. [A] will cause a crash * as early as z_mem_manage_init when an unaligned access is performed * -> clear [A]. */ uint32_t vbar = 0; __set_VBAR(vbar); uint32_t sctlr = __get_SCTLR(); sctlr &= ~SCTLR_I_Msk; sctlr &= ~SCTLR_C_Msk; sctlr &= ~SCTLR_A_Msk; __set_SCTLR(sctlr); #if DT_NODE_HAS_STATUS(DT_NODELABEL(slcr), okay) mm_reg_t addr = DT_REG_ADDR(DT_NODELABEL(slcr)); /* Unlock System Level Control Registers (SLCR) */ sys_write32(SLCR_UNLOCK_KEY, addr + SLCR_UNLOCK); #endif }