Exemple #1
0
void enable_layerscape_ns_access(void)
{
#ifdef CONFIG_ARM64
	if (current_el() == 3)
#endif
		enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
}
Exemple #2
0
int board_init(void)
{
	struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
					CONFIG_SYS_CCI400_OFFSET);

	/*
	 * Set CCI-400 control override register to enable barrier
	 * transaction
	 */
	if (current_el() == 3)
		out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);

#ifdef CONFIG_ENV_IS_NOWHERE
	gd->env_addr = (ulong)&default_environment[0];
#endif

#ifdef CONFIG_FSL_CAAM
	sec_init();
#endif

#ifdef CONFIG_FSL_LS_PPA
	ppa_init();
#endif
	return 0;
}
/*
 * sec_firmware_init - Initialize the SEC Firmware
 * @sec_firmware_img:	the SEC Firmware image address
 * @eret_hold_l:	the address to hold exception return address low
 * @eret_hold_h:	the address to hold exception return address high
 */
int sec_firmware_init(const void *sec_firmware_img,
			u32 *eret_hold_l,
			u32 *eret_hold_h)
{
	int ret;

	if (!sec_firmware_is_valid(sec_firmware_img))
		return -EINVAL;

	ret = sec_firmware_load_image(sec_firmware_img);
	if (ret) {
		printf("SEC Firmware: Failed to load image\n");
		return ret;
	} else if (sec_firmware_addr & SEC_FIRMWARE_LOADED) {
		ret = sec_firmware_entry(eret_hold_l, eret_hold_h);
		if (ret) {
			printf("SEC Firmware: Failed to initialize\n");
			return ret;
		}
	}

	debug("SEC Firmware: Return from SEC Firmware: current_el = %d\n",
	      current_el());

	/*
	 * The PE will be turned into target EL when returned from
	 * SEC Firmware.
	 */
	if (current_el() != SEC_FIRMWARE_TARGET_EL)
		return -EACCES;

	sec_firmware_addr |= SEC_FIRMWARE_RUNNING;

	/* Set exception table and enable caches if it isn't EL3 */
	if (current_el() != 3) {
		c_runtime_cpu_setup();
		enable_caches();
	}

	return 0;
}
Exemple #4
0
int board_init(void)
{
	printf("EL Level:\tEL%d\n", current_el());

#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
	fpga_init();
	/* FIXME FPGA size/id will be handled via SMCs */
	fpga_add(fpga_xilinx, &zynqmppl);
#endif

	return 0;
}
Exemple #5
0
int zynqmp_mmio_write(const u32 address,
		      const u32 mask,
		      const u32 value)
{
	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3)
		return zynqmp_mmio_rawwrite(address, mask, value);
	else
		return invoke_smc(ZYNQMP_MMIO_WRITE, address, mask,
				  value, 0, NULL);

	return -EINVAL;
}
Exemple #6
0
static int imx8mq_init_syscnt_frequency(void)
{
	if (current_el() == 3) {
		void __iomem *syscnt = IOMEM(MX8MQ_SYSCNT_CTRL_BASE_ADDR);
		/*
		 * Update with accurate clock frequency
		 */
		set_cntfrq(syscnt_get_cntfrq(syscnt));
		syscnt_enable(syscnt);
	}

	return 0;
}
Exemple #7
0
int zynqmp_mmio_read(const u32 address, u32 *value)
{
	u32 ret_payload[PAYLOAD_ARG_CNT];
	u32 ret;

	if (!value)
		return -EINVAL;

	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
		ret = zynqmp_mmio_rawread(address, value);
	} else {
		ret = invoke_smc(ZYNQMP_MMIO_READ, address, 0, 0,
				 0, ret_payload);
		*value = ret_payload[1];
	}

	return ret;
}
Exemple #8
0
unsigned int zynqmp_get_silicon_version(void)
{
	if (current_el() == 3)
		return zynqmp_get_silicon_version_secure();

	gd->cpu_clk = get_tbclk();

	switch (gd->cpu_clk) {
	case 0 ... 1000000:
		return ZYNQMP_CSU_VERSION_VELOCE;
	case 50000000:
		return ZYNQMP_CSU_VERSION_QEMU;
	case 4000000:
		return ZYNQMP_CSU_VERSION_EP108;
	}

	return ZYNQMP_CSU_VERSION_SILICON;
}
Exemple #9
0
int chip_id(unsigned char id)
{
	struct pt_regs regs;
	int val = -EINVAL;

	if (current_el() != 3) {
		regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
		regs.regs[1] = 0;
		regs.regs[2] = 0;
		regs.regs[3] = 0;

		smc_call(&regs);

		/*
		 * SMC returns:
		 * regs[0][31:0]  = status of the operation
		 * regs[0][63:32] = CSU.IDCODE register
		 * regs[1][31:0]  = CSU.version register
		 * regs[1][63:32] = CSU.IDCODE2 register
		 */
		switch (id) {
		case IDCODE:
			regs.regs[0] = upper_32_bits(regs.regs[0]);
			regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
					ZYNQMP_CSU_IDCODE_SVD_MASK;
			regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
			val = regs.regs[0];
			break;
		case VERSION:
			regs.regs[1] = lower_32_bits(regs.regs[1]);
			regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
			val = regs.regs[1];
			break;
		case IDCODE2:
			regs.regs[1] = lower_32_bits(regs.regs[1]);
			regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
			val = regs.regs[1];
			break;
		default:
			printf("%s, Invalid Req:0x%x\n", __func__, id);
		}
	} else {
void mmu_early_enable(unsigned long membase, unsigned long memsize,
		      unsigned long ttb)
{
	int el;

	/*
	 * For the early code we only create level 1 pagetables which only
	 * allow for a 1GiB granularity. If our membase is not aligned to that
	 * bail out without enabling the MMU.
	 */
	if (membase & ((1ULL << level2shift(1)) - 1))
		return;

	memset((void *)ttb, 0, GRANULE_SIZE);

	el = current_el();
	set_ttbr_tcr_mair(el, ttb, calc_tcr(el), MEMORY_ATTRIBUTES);
	create_sections((void *)ttb, 0, 0, 1UL << (BITS_PER_VA - 1), UNCACHED_MEM);
	create_sections((void *)ttb, membase, membase, memsize, CACHED_MEM);
	tlb_invalidate();
	isb();
	set_cr(get_cr() | CR_M);
}
Exemple #11
0
int board_early_init_r(void)
{
	u32 val;

	if (current_el() == 3) {
		val = readl(&crlapb_base->timestamp_ref_ctrl);
		val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
		writel(val, &crlapb_base->timestamp_ref_ctrl);

		/* Program freq register in System counter */
		writel(zynqmp_get_system_timer_freq(),
		       &iou_scntr_secure->base_frequency_id_register);
		/* And enable system counter */
		writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
		       &iou_scntr_secure->counter_control_register);
	}
	/* Program freq register in System counter and enable system counter */
	writel(gd->cpu_clk, &iou_scntr->base_frequency_id_register);
	writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_HDBG |
	       ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
	       &iou_scntr->counter_control_register);

	return 0;
}
Exemple #12
0
int board_init(void)
{
	printf("EL Level:\tEL%d\n", current_el());

	return 0;
}
/*
 * This mmu table looks as below
 * Level 0 table contains two entries to 512GB sizes. One is Level1 Table 0
 * and other Level1 Table1.
 * Level1 Table0 contains entries for each 1GB from 0 to 511GB.
 * Level1 Table1 contains entries for each 1GB from 512GB to 1TB.
 * Level2 Table0, Level2 Table1, Level2 Table2 and Level2 Table3 contains
 * entries for each 2MB starting from 0GB, 1GB, 2GB and 3GB respectively.
 */
void mmu_setup(void)
{
	int el;
	u64 i, section_l1t0, section_l1t1;
	u64 section_l2t0, section_l2t1, section_l2t2, section_l2t3;
	u64 *level0_table = (u64 *)gd->arch.tlb_addr;
	u64 *level1_table_0 = (u64 *)(gd->arch.tlb_addr + TLB_TABLE_SIZE);
	u64 *level1_table_1 = (u64 *)(gd->arch.tlb_addr + (2 * TLB_TABLE_SIZE));
	u64 *level2_table_0 = (u64 *)(gd->arch.tlb_addr + (3 * TLB_TABLE_SIZE));
	u64 *level2_table_1 = (u64 *)(gd->arch.tlb_addr + (4 * TLB_TABLE_SIZE));
	u64 *level2_table_2 = (u64 *)(gd->arch.tlb_addr + (5 * TLB_TABLE_SIZE));
	u64 *level2_table_3 = (u64 *)(gd->arch.tlb_addr + (6 * TLB_TABLE_SIZE));

	/* Invalidate all table entries */
	memset(level0_table, 0, PGTABLE_SIZE);

	level0_table[0] =
		(u64)level1_table_0 | PMD_TYPE_TABLE;
	level0_table[1] =
		(u64)level1_table_1 | PMD_TYPE_TABLE;

	/*
	 * set level 1 table 0, covering 0 to 512GB
	 * set level 1 table 1, covering 512GB to 1TB
	 */
	section_l1t0 = 0;
	section_l1t1 = BLOCK_SIZE_L0;

	for (i = 0; i < 512; i++) {
		level1_table_0[i] = section_l1t0;
		if (i >= 4)
			level1_table_0[i] |= MEMORY_ATTR;
		level1_table_1[i] = section_l1t1;
		level1_table_1[i] |= MEMORY_ATTR;
		section_l1t0 += BLOCK_SIZE_L1;
		section_l1t1 += BLOCK_SIZE_L1;
	}

	level1_table_0[0] =
		(u64)level2_table_0 | PMD_TYPE_TABLE;
	level1_table_0[1] =
		(u64)level2_table_1 | PMD_TYPE_TABLE;
	level1_table_0[2] =
		(u64)level2_table_2 | PMD_TYPE_TABLE;
	level1_table_0[3] =
		(u64)level2_table_3 | PMD_TYPE_TABLE;

	section_l2t0 = 0;
	section_l2t1 = section_l2t0 + BLOCK_SIZE_L1; /* 1GB */
	section_l2t2 = section_l2t1 + BLOCK_SIZE_L1; /* 2GB */
	section_l2t3 = section_l2t2 + BLOCK_SIZE_L1; /* 3GB */

	for (i = 0; i < 512; i++) {
		level2_table_0[i] = section_l2t0 | DEVICE_ATTR;
		level2_table_1[i] = section_l2t1 | DEVICE_ATTR;
		level2_table_2[i] = section_l2t2 | MEMORY_ATTR;
		level2_table_3[i] = section_l2t3 | MEMORY_ATTR;
		section_l2t0 += BLOCK_SIZE_L2;
		section_l2t1 += BLOCK_SIZE_L2;
		section_l2t2 += BLOCK_SIZE_L2;
		section_l2t3 += BLOCK_SIZE_L2;
	}

	/* flush new MMU table */
	flush_dcache_range(gd->arch.tlb_addr,
			   gd->arch.tlb_addr + gd->arch.tlb_size);

	/* point TTBR to the new table */
	el = current_el();
	set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
			  TEGRA_TCR, MEMORY_ATTRIBUTES);

	set_sctlr(get_sctlr() | CR_M);
}
/*
 * This function will parse the SEC Firmware image, and then load it
 * to secure memory.
 */
static int sec_firmware_load_image(const void *sec_firmware_img)
{
	const void *raw_image_addr;
	size_t raw_image_size = 0;
	int ret;

	/*
	 * The Excetpion Level must be EL3 to load and initialize
	 * the SEC Firmware.
	 */
	if (current_el() != 3) {
		ret = -EACCES;
		goto out;
	}

#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
	/*
	 * The SEC Firmware must be stored in secure memory.
	 * Append SEC Firmware to secure mmu table.
	 */
	if (!(gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED)) {
		ret = -ENXIO;
		goto out;
	}

	sec_firmware_addr = (gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK) +
			gd->arch.tlb_size;
#else
#error "The CONFIG_SYS_MEM_RESERVE_SECURE must be defined when enabled SEC Firmware support"
#endif

	/* Align SEC Firmware base address to 4K */
	sec_firmware_addr = (sec_firmware_addr + 0xfff) & ~0xfff;
	debug("SEC Firmware: Load address: 0x%llx\n",
	      sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);

	ret = sec_firmware_parse_image(sec_firmware_img, &raw_image_addr,
			&raw_image_size);
	if (ret)
		goto out;

	/* TODO:
	 * Check if the end addr of SEC Firmware has been extend the secure
	 * memory.
	 */

	/* Copy the secure firmware to secure memory */
	ret = sec_firmware_copy_image("SEC Firmware", (u64)raw_image_addr,
			raw_image_size, sec_firmware_addr &
			SEC_FIRMWARE_ADDR_MASK);
	if (ret)
		goto out;

	sec_firmware_addr |= SEC_FIRMWARE_LOADED;
	debug("SEC Firmware: Entry point: 0x%llx\n",
	      sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);

	return 0;

out:
	printf("SEC Firmware: error (%d)\n", ret);
	sec_firmware_addr = 0;

	return ret;
}
Exemple #15
0
/*
 * This mmu table looks as below
 * Level 0 table contains two entries to 512GB sizes. One is Level1 Table 0
 * and other Level1 Table1.
 * Level1 Table0 contains entries for each 1GB from 0 to 511GB.
 * Level1 Table1 contains entries for each 1GB from 512GB to 1TB.
 * Level2 Table0, Level2 Table1, Level2 Table2 and Level2 Table3 contains
 * entries for each 2MB starting from 0GB, 1GB, 2GB and 3GB respectively.
 */
static void zynqmp_mmu_setup(void)
{
	int el;
	u32 index_attr;
	u64 i, section_l1t0, section_l1t1;
	u64 section_l2t0, section_l2t1, section_l2t2, section_l2t3;
	u64 *level0_table = (u64 *)gd->arch.tlb_addr;
	u64 *level1_table_0 = (u64 *)(gd->arch.tlb_addr + TLB_TABLE_SIZE);
	u64 *level1_table_1 = (u64 *)(gd->arch.tlb_addr + (2 * TLB_TABLE_SIZE));
	u64 *level2_table_0 = (u64 *)(gd->arch.tlb_addr + (3 * TLB_TABLE_SIZE));
	u64 *level2_table_1 = (u64 *)(gd->arch.tlb_addr + (4 * TLB_TABLE_SIZE));
	u64 *level2_table_2 = (u64 *)(gd->arch.tlb_addr + (5 * TLB_TABLE_SIZE));
	u64 *level2_table_3 = (u64 *)(gd->arch.tlb_addr + (6 * TLB_TABLE_SIZE));

	level0_table[0] =
		(u64)level1_table_0 | PMD_TYPE_TABLE;
	level0_table[1] =
		(u64)level1_table_1 | PMD_TYPE_TABLE;

	/*
	 * set level 1 table 0, covering 0 to 512GB
	 * set level 1 table 1, covering 512GB to 1TB
	 */
	section_l1t0 = 0;
	section_l1t1 = BLOCK_SIZE_L0;

	index_attr = 0;
	for (i = 0; i < 512; i++) {
		level1_table_0[i] = section_l1t0;
		level1_table_0[i] |= attr_tbll1t0[index_attr].attr;
		attr_tbll1t0[index_attr].num--;
		if (attr_tbll1t0[index_attr].num == 0)
			index_attr++;
		level1_table_1[i] = section_l1t1;
		level1_table_1[i] |= DEVICE_ATTR;
		section_l1t0 += BLOCK_SIZE_L1;
		section_l1t1 += BLOCK_SIZE_L1;
	}

	level1_table_0[0] =
		(u64)level2_table_0 | PMD_TYPE_TABLE;
	level1_table_0[1] =
		(u64)level2_table_1 | PMD_TYPE_TABLE;
	level1_table_0[2] =
		(u64)level2_table_2 | PMD_TYPE_TABLE;
	level1_table_0[3] =
		(u64)level2_table_3 | PMD_TYPE_TABLE;

	section_l2t0 = 0;
	section_l2t1 = section_l2t0 + BLOCK_SIZE_L1; /* 1GB */
	section_l2t2 = section_l2t1 + BLOCK_SIZE_L1; /* 2GB */
	section_l2t3 = section_l2t2 + BLOCK_SIZE_L1; /* 3GB */

	index_attr = 0;

	for (i = 0; i < 512; i++) {
		level2_table_0[i] = section_l2t0 | MEMORY_ATTR;
		level2_table_1[i] = section_l2t1 | MEMORY_ATTR;
		level2_table_2[i] = section_l2t2 | DEVICE_ATTR;
		level2_table_3[i] = section_l2t3 |
				    attr_tbll2t3[index_attr].attr;
		attr_tbll2t3[index_attr].num--;
		if (attr_tbll2t3[index_attr].num == 0)
			index_attr++;
		section_l2t0 += BLOCK_SIZE_L2;
		section_l2t1 += BLOCK_SIZE_L2;
		section_l2t2 += BLOCK_SIZE_L2;
		section_l2t3 += BLOCK_SIZE_L2;
	}

	/* flush new MMU table */
	flush_dcache_range(gd->arch.tlb_addr,
			   gd->arch.tlb_addr + gd->arch.tlb_size);

	/* point TTBR to the new table */
	el = current_el();
	set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
			  ZYNQMP_TCR, MEMORY_ATTRIBUTES);

	set_sctlr(get_sctlr() | CR_M);
}