1 /* 2 * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <string.h> 8 9 #include <common/debug.h> 10 #include <drivers/io/io_driver.h> 11 #include <drivers/io/io_storage.h> 12 13 #include "emmc_config.h" 14 #include "emmc_def.h" 15 #include "emmc_hal.h" 16 #include "emmc_std.h" 17 #include "io_common.h" 18 #include "io_emmcdrv.h" 19 #include "io_private.h" 20 21 static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)), 22 io_dev_info_t **dev_info); 23 static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info); 24 25 typedef struct { 26 uint32_t in_use; 27 uintptr_t base; 28 signed long long file_pos; 29 EMMC_PARTITION_ID partition; 30 } file_state_t; 31 32 static file_state_t current_file = { 0 }; 33 34 static EMMC_PARTITION_ID emmcdrv_bootpartition = PARTITION_ID_USER; 35 36 static io_type_t device_type_emmcdrv(void) 37 { 38 return IO_TYPE_MEMMAP; 39 } 40 41 static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode, 42 signed long long offset) 43 { 44 if (mode != IO_SEEK_SET) { 45 return IO_FAIL; 46 } 47 48 ((file_state_t *) entity->info)->file_pos = offset; 49 50 return IO_SUCCESS; 51 } 52 53 static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer, 54 size_t length, size_t *length_read) 55 { 56 file_state_t *fp = (file_state_t *) entity->info; 57 uint32_t sector_add, sector_num, emmc_dma = 0; 58 int32_t result = IO_SUCCESS; 59 60 sector_add = current_file.file_pos >> EMMC_SECTOR_SIZE_SHIFT; 61 sector_num = (length + EMMC_SECTOR_SIZE - 1U) >> EMMC_SECTOR_SIZE_SHIFT; 62 63 NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%llx(%d) len=0x%lx(%d)\n", 64 buffer, 65 current_file.partition, current_file.file_pos, 66 sector_add, length, sector_num); 67 68 if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) { 69 emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE; 70 } 71 72 if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num, 73 emmc_dma) != EMMC_SUCCESS) { 74 result = IO_FAIL; 75 } 76 77 *length_read = length; 78 fp->file_pos += (signed long long)length; 79 80 return result; 81 } 82 83 static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, 84 const uintptr_t spec, io_entity_t *entity) 85 { 86 const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec; 87 88 if (current_file.in_use != 0U) { 89 WARN("mmc_block: Only one open spec at a time\n"); 90 return IO_RESOURCES_EXHAUSTED; 91 } 92 93 current_file.file_pos = 0; 94 current_file.in_use = 1; 95 96 if (emmcdrv_bootpartition == PARTITION_ID_USER) { 97 emmcdrv_bootpartition = mmc_drv_obj.boot_partition_en; 98 if ((emmcdrv_bootpartition == PARTITION_ID_BOOT_1) || 99 (emmcdrv_bootpartition == PARTITION_ID_BOOT_2)) { 100 current_file.partition = emmcdrv_bootpartition; 101 102 NOTICE("BL2: eMMC boot from partition %d\n", 103 emmcdrv_bootpartition); 104 goto done; 105 } 106 return IO_FAIL; 107 } 108 109 if ((block_spec->partition == PARTITION_ID_USER) || 110 (block_spec->partition == PARTITION_ID_BOOT_1) || 111 (block_spec->partition == PARTITION_ID_BOOT_2)) { 112 current_file.partition = block_spec->partition; 113 } else { 114 current_file.partition = emmcdrv_bootpartition; 115 } 116 117 done: 118 if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) { 119 return IO_FAIL; 120 } 121 122 entity->info = (uintptr_t) ¤t_file; 123 124 return IO_SUCCESS; 125 } 126 127 static int32_t emmcdrv_block_close(io_entity_t *entity) 128 { 129 memset((void *)¤t_file, 0, sizeof(current_file)); 130 entity->info = 0U; 131 132 return IO_SUCCESS; 133 } 134 135 static const io_dev_funcs_t emmcdrv_dev_funcs = { 136 .type = &device_type_emmcdrv, 137 .open = &emmcdrv_block_open, 138 .seek = &emmcdrv_block_seek, 139 .size = NULL, 140 .read = &emmcdrv_block_read, 141 .write = NULL, 142 .close = &emmcdrv_block_close, 143 .dev_init = NULL, 144 .dev_close = &emmcdrv_dev_close 145 }; 146 147 static const io_dev_info_t emmcdrv_dev_info = { 148 .funcs = &emmcdrv_dev_funcs, 149 .info = (uintptr_t) 0 150 }; 151 152 static const io_dev_connector_t emmcdrv_dev_connector = { 153 &emmcdrv_dev_open, 154 }; 155 156 static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)), 157 io_dev_info_t **dev_info) 158 { 159 *dev_info = (io_dev_info_t *) &emmcdrv_dev_info; 160 161 return IO_SUCCESS; 162 } 163 164 static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info) 165 { 166 return IO_SUCCESS; 167 } 168 169 int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **dev_con) 170 { 171 int32_t rc; 172 173 rc = io_register_device(&emmcdrv_dev_info); 174 if (rc == IO_SUCCESS) { 175 *dev_con = &emmcdrv_dev_connector; 176 } 177 178 return rc; 179 } 180