1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2022 ARM Limited 4 * (C) Copyright 2022 Linaro 5 * Rui Miguel Silva <rui.silva@linaro.org> 6 */ 7 8#include <blk.h> 9#include <common.h> 10#include <cpu_func.h> 11#include <dm.h> 12#include <env.h> 13#include <fwu.h> 14#include <netdev.h> 15#include <nvmxip.h> 16#include <part.h> 17#include <dm/platform_data/serial_pl01x.h> 18#include <asm/armv8/mmu.h> 19#include <asm/global_data.h> 20 21#define CORSTONE1000_KERNEL_PARTS 2 22#define CORSTONE1000_KERNEL_PRIMARY "kernel_primary" 23#define CORSTONE1000_KERNEL_SECONDARY "kernel_secondary" 24 25static int corstone1000_boot_idx; 26 27static struct mm_region corstone1000_mem_map[] = { 28 { 29 /* CVM */ 30 .virt = 0x02000000UL, 31 .phys = 0x02000000UL, 32 .size = 0x02000000UL, 33 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | 34 PTE_BLOCK_INNER_SHARE 35 }, { 36 /* QSPI */ 37 .virt = 0x08000000UL, 38 .phys = 0x08000000UL, 39 .size = 0x08000000UL, 40 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | 41 PTE_BLOCK_INNER_SHARE 42 }, { 43 /* Host Peripherals */ 44 .virt = 0x1A000000UL, 45 .phys = 0x1A000000UL, 46 .size = 0x26000000UL, 47 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 48 PTE_BLOCK_NON_SHARE | 49 PTE_BLOCK_PXN | PTE_BLOCK_UXN 50 }, { 51 /* USB */ 52 .virt = 0x40200000UL, 53 .phys = 0x40200000UL, 54 .size = 0x00100000UL, 55 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 56 PTE_BLOCK_NON_SHARE | 57 PTE_BLOCK_PXN | PTE_BLOCK_UXN 58 }, { 59 /* ethernet */ 60 .virt = 0x40100000UL, 61 .phys = 0x40100000UL, 62 .size = 0x00100000UL, 63 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 64 PTE_BLOCK_NON_SHARE | 65 PTE_BLOCK_PXN | PTE_BLOCK_UXN 66 }, { 67 /* OCVM */ 68 .virt = 0x80000000UL, 69 .phys = 0x80000000UL, 70 .size = 0x80000000UL, 71 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | 72 PTE_BLOCK_INNER_SHARE 73 }, { 74 /* List terminator */ 75 0, 76 } 77}; 78 79struct mm_region *mem_map = corstone1000_mem_map; 80 81int board_init(void) 82{ 83 return 0; 84} 85 86int dram_init(void) 87{ 88 gd->ram_size = PHYS_SDRAM_1_SIZE; 89 90 return 0; 91} 92 93int dram_init_banksize(void) 94{ 95 gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 96 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; 97 98 return 0; 99} 100 101void fwu_plat_get_bootidx(uint *boot_idx) 102{ 103 int ret; 104 105 /* 106 * in our platform, the Secure Enclave is the one who controls 107 * all the boot tries and status, so, every time we get here 108 * we know that the we are booting from the active index 109 */ 110 ret = fwu_get_active_index(boot_idx); 111 if (ret < 0) { 112 *boot_idx = CONFIG_FWU_NUM_BANKS; 113 log_err("corstone1000: failed to read active index\n"); 114 } 115} 116 117int board_late_init(void) 118{ 119 struct disk_partition part_info; 120 struct udevice *dev, *bdev; 121 struct nvmxip_plat *plat; 122 struct blk_desc *desc; 123 int ret; 124 125 ret = uclass_first_device_err(UCLASS_NVMXIP, &dev); 126 if (ret < 0) { 127 log_err("Cannot find kernel device\n"); 128 return ret; 129 } 130 131 plat = dev_get_plat(dev); 132 device_find_first_child(dev, &bdev); 133 desc = dev_get_uclass_plat(bdev); 134 ret = fwu_get_active_index(&corstone1000_boot_idx); 135 if (ret < 0) { 136 log_err("corstone1000: failed to read boot index\n"); 137 return ret; 138 } 139 140 if (!corstone1000_boot_idx) 141 ret = part_get_info_by_name(desc, CORSTONE1000_KERNEL_PRIMARY, 142 &part_info); 143 else 144 ret = part_get_info_by_name(desc, CORSTONE1000_KERNEL_SECONDARY, 145 &part_info); 146 147 if (ret < 0) { 148 log_err("failed to fetch kernel partition index: %d\n", 149 corstone1000_boot_idx); 150 return ret; 151 } 152 153 ret = 0; 154 155 ret |= env_set_hex("kernel_addr", plat->phys_base + 156 (part_info.start * part_info.blksz)); 157 ret |= env_set_hex("kernel_size", part_info.size * part_info.blksz); 158 159 if (ret < 0) 160 log_err("failed to setup kernel addr and size\n"); 161 162 return ret; 163} 164