mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
updated based on mbed-os5.15.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /* mbed Microcontroller Library
kenjiArai 0:5b88d5760320 2 * Copyright (c) 2017 ARM Limited
kenjiArai 0:5b88d5760320 3 *
kenjiArai 0:5b88d5760320 4 * Licensed under the Apache License, Version 2.0 (the "License");
kenjiArai 0:5b88d5760320 5 * you may not use this file except in compliance with the License.
kenjiArai 0:5b88d5760320 6 * You may obtain a copy of the License at
kenjiArai 0:5b88d5760320 7 *
kenjiArai 0:5b88d5760320 8 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 0:5b88d5760320 9 *
kenjiArai 0:5b88d5760320 10 * Unless required by applicable law or agreed to in writing, software
kenjiArai 0:5b88d5760320 11 * distributed under the License is distributed on an "AS IS" BASIS,
kenjiArai 0:5b88d5760320 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 0:5b88d5760320 13 * See the License for the specific language governing permissions and
kenjiArai 0:5b88d5760320 14 * limitations under the License.
kenjiArai 0:5b88d5760320 15 */
kenjiArai 0:5b88d5760320 16
kenjiArai 0:5b88d5760320 17 #include "MBRBlockDevice.h"
kenjiArai 0:5b88d5760320 18 #include "platform/mbed_atomic.h"
kenjiArai 0:5b88d5760320 19 #include "platform/mbed_toolchain.h"
kenjiArai 0:5b88d5760320 20 #include "platform/mbed_assert.h"
kenjiArai 0:5b88d5760320 21 #include <algorithm>
kenjiArai 0:5b88d5760320 22 #include <string.h>
kenjiArai 0:5b88d5760320 23
kenjiArai 0:5b88d5760320 24 namespace mbed {
kenjiArai 0:5b88d5760320 25
kenjiArai 0:5b88d5760320 26 // On disk structures, all entries are little endian
kenjiArai 0:5b88d5760320 27 MBED_PACKED(struct) mbr_entry {
kenjiArai 0:5b88d5760320 28 uint8_t status;
kenjiArai 0:5b88d5760320 29 uint8_t chs_start[3];
kenjiArai 0:5b88d5760320 30 uint8_t type;
kenjiArai 0:5b88d5760320 31 uint8_t chs_stop[3];
kenjiArai 0:5b88d5760320 32 uint32_t lba_offset;
kenjiArai 0:5b88d5760320 33 uint32_t lba_size;
kenjiArai 0:5b88d5760320 34 };
kenjiArai 0:5b88d5760320 35
kenjiArai 0:5b88d5760320 36 MBED_PACKED(struct) mbr_table {
kenjiArai 0:5b88d5760320 37 struct mbr_entry entries[4];
kenjiArai 0:5b88d5760320 38 uint8_t signature[2];
kenjiArai 0:5b88d5760320 39 };
kenjiArai 0:5b88d5760320 40
kenjiArai 0:5b88d5760320 41 // Little-endian conversion, should compile to noop
kenjiArai 0:5b88d5760320 42 // if system is little-endian
kenjiArai 0:5b88d5760320 43 static inline uint32_t tole32(uint32_t a)
kenjiArai 0:5b88d5760320 44 {
kenjiArai 0:5b88d5760320 45 union {
kenjiArai 0:5b88d5760320 46 uint32_t u32;
kenjiArai 0:5b88d5760320 47 uint8_t u8[4];
kenjiArai 0:5b88d5760320 48 } w;
kenjiArai 0:5b88d5760320 49
kenjiArai 0:5b88d5760320 50 w.u8[0] = a >> 0;
kenjiArai 0:5b88d5760320 51 w.u8[1] = a >> 8;
kenjiArai 0:5b88d5760320 52 w.u8[2] = a >> 16;
kenjiArai 0:5b88d5760320 53 w.u8[3] = a >> 24;
kenjiArai 0:5b88d5760320 54
kenjiArai 0:5b88d5760320 55 return w.u32;
kenjiArai 0:5b88d5760320 56 }
kenjiArai 0:5b88d5760320 57
kenjiArai 0:5b88d5760320 58 static inline uint32_t fromle32(uint32_t a)
kenjiArai 0:5b88d5760320 59 {
kenjiArai 0:5b88d5760320 60 return tole32(a);
kenjiArai 0:5b88d5760320 61 }
kenjiArai 0:5b88d5760320 62
kenjiArai 0:5b88d5760320 63 static void tochs(uint32_t lba, uint8_t chs[3])
kenjiArai 0:5b88d5760320 64 {
kenjiArai 0:5b88d5760320 65 uint32_t sector = std::min<uint32_t>(lba, 0xfffffd) + 1;
kenjiArai 0:5b88d5760320 66 chs[0] = (sector >> 6) & 0xff;
kenjiArai 0:5b88d5760320 67 chs[1] = ((sector >> 0) & 0x3f) | ((sector >> 16) & 0xc0);
kenjiArai 0:5b88d5760320 68 chs[2] = (sector >> 14) & 0xff;
kenjiArai 0:5b88d5760320 69 }
kenjiArai 0:5b88d5760320 70
kenjiArai 0:5b88d5760320 71
kenjiArai 0:5b88d5760320 72 // Partition after address are turned into absolute
kenjiArai 0:5b88d5760320 73 // addresses, assumes bd is initialized
kenjiArai 0:5b88d5760320 74 static int partition_absolute(
kenjiArai 0:5b88d5760320 75 BlockDevice *bd, int part, uint8_t type,
kenjiArai 0:5b88d5760320 76 bd_size_t offset, bd_size_t size)
kenjiArai 0:5b88d5760320 77 {
kenjiArai 0:5b88d5760320 78 // Allocate smallest buffer necessary to write MBR
kenjiArai 0:5b88d5760320 79 uint32_t buffer_size = std::max<uint32_t>(bd->get_program_size(), sizeof(struct mbr_table));
kenjiArai 0:5b88d5760320 80
kenjiArai 0:5b88d5760320 81 // Prevent alignment issues
kenjiArai 0:5b88d5760320 82 if (buffer_size % bd->get_program_size() != 0) {
kenjiArai 0:5b88d5760320 83 buffer_size += bd->get_program_size() - (buffer_size % bd->get_program_size());
kenjiArai 0:5b88d5760320 84 }
kenjiArai 0:5b88d5760320 85
kenjiArai 0:5b88d5760320 86 uint8_t *buffer = new uint8_t[buffer_size];
kenjiArai 0:5b88d5760320 87
kenjiArai 0:5b88d5760320 88 // Check for existing MBR
kenjiArai 0:5b88d5760320 89 int err = bd->read(buffer, 512 - buffer_size, buffer_size);
kenjiArai 0:5b88d5760320 90 if (err) {
kenjiArai 0:5b88d5760320 91 delete[] buffer;
kenjiArai 0:5b88d5760320 92 return err;
kenjiArai 0:5b88d5760320 93 }
kenjiArai 0:5b88d5760320 94
kenjiArai 0:5b88d5760320 95 uint32_t table_start_offset = buffer_size - sizeof(struct mbr_table);
kenjiArai 0:5b88d5760320 96 struct mbr_table *table = reinterpret_cast<struct mbr_table *>(
kenjiArai 0:5b88d5760320 97 &buffer[table_start_offset]);
kenjiArai 0:5b88d5760320 98 if (table->signature[0] != 0x55 || table->signature[1] != 0xaa) {
kenjiArai 0:5b88d5760320 99 // Setup default values for MBR
kenjiArai 0:5b88d5760320 100 table->signature[0] = 0x55;
kenjiArai 0:5b88d5760320 101 table->signature[1] = 0xaa;
kenjiArai 0:5b88d5760320 102 memset(table->entries, 0, sizeof(table->entries));
kenjiArai 0:5b88d5760320 103 }
kenjiArai 0:5b88d5760320 104
kenjiArai 0:5b88d5760320 105 // For Windows-formatted SD card, it is not partitioned (no MBR), but its PBR has the
kenjiArai 0:5b88d5760320 106 // same boot signature (0xaa55) as MBR. We would easily mis-recognize this SD card has valid
kenjiArai 0:5b88d5760320 107 // partitions if we only check partition type. We add check by only accepting 0x00 (inactive)
kenjiArai 0:5b88d5760320 108 // /0x80 (active) for valid partition status.
kenjiArai 0:5b88d5760320 109 for (int i = 1; i <= 4; i++) {
kenjiArai 0:5b88d5760320 110 if (table->entries[i - 1].status != 0x00 &&
kenjiArai 0:5b88d5760320 111 table->entries[i - 1].status != 0x80) {
kenjiArai 0:5b88d5760320 112 memset(table->entries, 0, sizeof(table->entries));
kenjiArai 0:5b88d5760320 113 break;
kenjiArai 0:5b88d5760320 114 }
kenjiArai 0:5b88d5760320 115 }
kenjiArai 0:5b88d5760320 116
kenjiArai 0:5b88d5760320 117 // Setup new partition
kenjiArai 0:5b88d5760320 118 MBED_ASSERT(part >= 1 && part <= 4);
kenjiArai 0:5b88d5760320 119 table->entries[part - 1].status = 0x00; // inactive (not bootable)
kenjiArai 0:5b88d5760320 120 table->entries[part - 1].type = type;
kenjiArai 0:5b88d5760320 121
kenjiArai 0:5b88d5760320 122 // lba dimensions
kenjiArai 0:5b88d5760320 123 MBED_ASSERT(bd->is_valid_erase(offset, size));
kenjiArai 0:5b88d5760320 124 uint32_t sector = std::max<uint32_t>(bd->get_erase_size(), 512);
kenjiArai 0:5b88d5760320 125 uint32_t lba_offset = offset / sector;
kenjiArai 0:5b88d5760320 126 uint32_t lba_size = size / sector;
kenjiArai 0:5b88d5760320 127 table->entries[part - 1].lba_offset = tole32(lba_offset);
kenjiArai 0:5b88d5760320 128 table->entries[part - 1].lba_size = tole32(lba_size);
kenjiArai 0:5b88d5760320 129
kenjiArai 0:5b88d5760320 130 // chs dimensions
kenjiArai 0:5b88d5760320 131 tochs(lba_offset, table->entries[part - 1].chs_start);
kenjiArai 0:5b88d5760320 132 tochs(lba_offset + lba_size - 1, table->entries[part - 1].chs_stop);
kenjiArai 0:5b88d5760320 133
kenjiArai 0:5b88d5760320 134 // Check that we don't overlap other entries
kenjiArai 0:5b88d5760320 135 for (int i = 1; i <= 4; i++) {
kenjiArai 0:5b88d5760320 136 if (i != part && table->entries[i - 1].type != 0x00) {
kenjiArai 0:5b88d5760320 137 uint32_t neighbor_lba_offset = fromle32(table->entries[i - 1].lba_offset);
kenjiArai 0:5b88d5760320 138 uint32_t neighbor_lba_size = fromle32(table->entries[i - 1].lba_size);
kenjiArai 0:5b88d5760320 139 MBED_ASSERT(
kenjiArai 0:5b88d5760320 140 (lba_offset >= neighbor_lba_offset + neighbor_lba_size) ||
kenjiArai 0:5b88d5760320 141 (lba_offset + lba_size <= neighbor_lba_offset));
kenjiArai 0:5b88d5760320 142 (void)neighbor_lba_offset;
kenjiArai 0:5b88d5760320 143 (void)neighbor_lba_size;
kenjiArai 0:5b88d5760320 144 }
kenjiArai 0:5b88d5760320 145 }
kenjiArai 0:5b88d5760320 146
kenjiArai 0:5b88d5760320 147 // As the erase operation may do nothing, erase remainder of the buffer, to eradicate
kenjiArai 0:5b88d5760320 148 // any remaining programmed data (such as previously programmed file systems).
kenjiArai 0:5b88d5760320 149 if (table_start_offset > 0) {
kenjiArai 0:5b88d5760320 150 memset(buffer, 0xFF, table_start_offset);
kenjiArai 0:5b88d5760320 151 }
kenjiArai 0:5b88d5760320 152 if (table_start_offset + sizeof(struct mbr_table) < buffer_size) {
kenjiArai 0:5b88d5760320 153 memset(buffer + table_start_offset + sizeof(struct mbr_table), 0xFF,
kenjiArai 0:5b88d5760320 154 buffer_size - (table_start_offset + sizeof(struct mbr_table)));
kenjiArai 0:5b88d5760320 155 }
kenjiArai 0:5b88d5760320 156
kenjiArai 0:5b88d5760320 157 // Write out MBR
kenjiArai 0:5b88d5760320 158 err = bd->erase(0, bd->get_erase_size());
kenjiArai 0:5b88d5760320 159 if (err) {
kenjiArai 0:5b88d5760320 160 delete[] buffer;
kenjiArai 0:5b88d5760320 161 return err;
kenjiArai 0:5b88d5760320 162 }
kenjiArai 0:5b88d5760320 163
kenjiArai 0:5b88d5760320 164 err = bd->program(buffer, 512 - buffer_size, buffer_size);
kenjiArai 0:5b88d5760320 165 delete[] buffer;
kenjiArai 0:5b88d5760320 166 return err;
kenjiArai 0:5b88d5760320 167 }
kenjiArai 0:5b88d5760320 168
kenjiArai 0:5b88d5760320 169 int MBRBlockDevice::partition(BlockDevice *bd, int part, uint8_t type, bd_addr_t start)
kenjiArai 0:5b88d5760320 170 {
kenjiArai 0:5b88d5760320 171 int err = bd->init();
kenjiArai 0:5b88d5760320 172 if (err) {
kenjiArai 0:5b88d5760320 173 return err;
kenjiArai 0:5b88d5760320 174 }
kenjiArai 0:5b88d5760320 175
kenjiArai 0:5b88d5760320 176 // Calculate dimensions
kenjiArai 0:5b88d5760320 177 bd_size_t offset = ((int64_t)start < 0) ? -start : start;
kenjiArai 0:5b88d5760320 178 bd_size_t size = bd->size();
kenjiArai 0:5b88d5760320 179
kenjiArai 0:5b88d5760320 180 if (offset < 512) {
kenjiArai 0:5b88d5760320 181 offset += std::max<uint32_t>(bd->get_erase_size(), 512);
kenjiArai 0:5b88d5760320 182 }
kenjiArai 0:5b88d5760320 183
kenjiArai 0:5b88d5760320 184 size -= offset;
kenjiArai 0:5b88d5760320 185
kenjiArai 0:5b88d5760320 186 err = partition_absolute(bd, part, type, offset, size);
kenjiArai 0:5b88d5760320 187 if (err) {
kenjiArai 0:5b88d5760320 188 return err;
kenjiArai 0:5b88d5760320 189 }
kenjiArai 0:5b88d5760320 190
kenjiArai 0:5b88d5760320 191 err = bd->deinit();
kenjiArai 0:5b88d5760320 192 if (err) {
kenjiArai 0:5b88d5760320 193 return err;
kenjiArai 0:5b88d5760320 194 }
kenjiArai 0:5b88d5760320 195
kenjiArai 0:5b88d5760320 196 return 0;
kenjiArai 0:5b88d5760320 197 }
kenjiArai 0:5b88d5760320 198
kenjiArai 0:5b88d5760320 199 int MBRBlockDevice::partition(BlockDevice *bd, int part, uint8_t type,
kenjiArai 0:5b88d5760320 200 bd_addr_t start, bd_addr_t stop)
kenjiArai 0:5b88d5760320 201 {
kenjiArai 0:5b88d5760320 202 int err = bd->init();
kenjiArai 0:5b88d5760320 203 if (err) {
kenjiArai 0:5b88d5760320 204 return err;
kenjiArai 0:5b88d5760320 205 }
kenjiArai 0:5b88d5760320 206
kenjiArai 0:5b88d5760320 207 // Calculate dimensions
kenjiArai 0:5b88d5760320 208 bd_size_t offset = ((int64_t)start < 0) ? -start : start;
kenjiArai 0:5b88d5760320 209 bd_size_t size = ((int64_t)stop < 0) ? -stop : stop;
kenjiArai 0:5b88d5760320 210
kenjiArai 0:5b88d5760320 211 if (offset < 512) {
kenjiArai 0:5b88d5760320 212 offset += std::max<uint32_t>(bd->get_erase_size(), 512);
kenjiArai 0:5b88d5760320 213 }
kenjiArai 0:5b88d5760320 214
kenjiArai 0:5b88d5760320 215 size -= offset;
kenjiArai 0:5b88d5760320 216
kenjiArai 0:5b88d5760320 217 err = partition_absolute(bd, part, type, offset, size);
kenjiArai 0:5b88d5760320 218 if (err) {
kenjiArai 0:5b88d5760320 219 return err;
kenjiArai 0:5b88d5760320 220 }
kenjiArai 0:5b88d5760320 221
kenjiArai 0:5b88d5760320 222 err = bd->deinit();
kenjiArai 0:5b88d5760320 223 if (err) {
kenjiArai 0:5b88d5760320 224 return err;
kenjiArai 0:5b88d5760320 225 }
kenjiArai 0:5b88d5760320 226
kenjiArai 0:5b88d5760320 227 return 0;
kenjiArai 0:5b88d5760320 228 }
kenjiArai 0:5b88d5760320 229
kenjiArai 0:5b88d5760320 230 MBRBlockDevice::MBRBlockDevice(BlockDevice *bd, int part)
kenjiArai 0:5b88d5760320 231 : _bd(bd), _offset(0), _size(0), _type(0), _part(part), _init_ref_count(0), _is_initialized(false)
kenjiArai 0:5b88d5760320 232 {
kenjiArai 0:5b88d5760320 233 MBED_ASSERT(_part >= 1 && _part <= 4);
kenjiArai 0:5b88d5760320 234 }
kenjiArai 0:5b88d5760320 235
kenjiArai 0:5b88d5760320 236 int MBRBlockDevice::init()
kenjiArai 0:5b88d5760320 237 {
kenjiArai 0:5b88d5760320 238 uint32_t buffer_size;
kenjiArai 0:5b88d5760320 239 uint8_t *buffer = 0;
kenjiArai 0:5b88d5760320 240 struct mbr_table *table;
kenjiArai 0:5b88d5760320 241 bd_size_t sector;
kenjiArai 0:5b88d5760320 242 int err;
kenjiArai 0:5b88d5760320 243
kenjiArai 0:5b88d5760320 244 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
kenjiArai 0:5b88d5760320 245
kenjiArai 0:5b88d5760320 246 if (val != 1) {
kenjiArai 0:5b88d5760320 247 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 248 }
kenjiArai 0:5b88d5760320 249
kenjiArai 0:5b88d5760320 250 err = _bd->init();
kenjiArai 0:5b88d5760320 251 if (err) {
kenjiArai 0:5b88d5760320 252 goto fail;
kenjiArai 0:5b88d5760320 253 }
kenjiArai 0:5b88d5760320 254
kenjiArai 0:5b88d5760320 255 // Allocate smallest buffer necessary to write MBR
kenjiArai 0:5b88d5760320 256 buffer_size = std::max<uint32_t>(_bd->get_read_size(), sizeof(struct mbr_table));
kenjiArai 0:5b88d5760320 257 buffer = new uint8_t[buffer_size];
kenjiArai 0:5b88d5760320 258
kenjiArai 0:5b88d5760320 259 err = _bd->read(buffer, 512 - buffer_size, buffer_size);
kenjiArai 0:5b88d5760320 260 if (err) {
kenjiArai 0:5b88d5760320 261 goto fail;
kenjiArai 0:5b88d5760320 262 }
kenjiArai 0:5b88d5760320 263
kenjiArai 0:5b88d5760320 264 // Check for valid table
kenjiArai 0:5b88d5760320 265 table = reinterpret_cast<struct mbr_table *>(&buffer[buffer_size - sizeof(struct mbr_table)]);
kenjiArai 0:5b88d5760320 266 if (table->signature[0] != 0x55 || table->signature[1] != 0xaa) {
kenjiArai 0:5b88d5760320 267 err = BD_ERROR_INVALID_MBR;
kenjiArai 0:5b88d5760320 268 goto fail;
kenjiArai 0:5b88d5760320 269 }
kenjiArai 0:5b88d5760320 270
kenjiArai 0:5b88d5760320 271 // Check for valid partition status
kenjiArai 0:5b88d5760320 272 // Same reason as in partition_absolute regarding Windows-formatted SD card
kenjiArai 0:5b88d5760320 273 if (table->entries[_part - 1].status != 0x00 &&
kenjiArai 0:5b88d5760320 274 table->entries[_part - 1].status != 0x80) {
kenjiArai 0:5b88d5760320 275 err = BD_ERROR_INVALID_PARTITION;
kenjiArai 0:5b88d5760320 276 goto fail;
kenjiArai 0:5b88d5760320 277 }
kenjiArai 0:5b88d5760320 278
kenjiArai 0:5b88d5760320 279 // Check for valid entry
kenjiArai 0:5b88d5760320 280 // 0x00 = no entry
kenjiArai 0:5b88d5760320 281 // 0x05, 0x0f = extended partitions, currently not supported
kenjiArai 0:5b88d5760320 282 if ((table->entries[_part - 1].type == 0x00 ||
kenjiArai 0:5b88d5760320 283 table->entries[_part - 1].type == 0x05 ||
kenjiArai 0:5b88d5760320 284 table->entries[_part - 1].type == 0x0f)) {
kenjiArai 0:5b88d5760320 285 err = BD_ERROR_INVALID_PARTITION;
kenjiArai 0:5b88d5760320 286 goto fail;
kenjiArai 0:5b88d5760320 287 }
kenjiArai 0:5b88d5760320 288
kenjiArai 0:5b88d5760320 289 // Get partition attributes
kenjiArai 0:5b88d5760320 290 sector = std::max<uint32_t>(_bd->get_erase_size(), 512);
kenjiArai 0:5b88d5760320 291 _type = table->entries[_part - 1].type;
kenjiArai 0:5b88d5760320 292 _offset = fromle32(table->entries[_part - 1].lba_offset) * sector;
kenjiArai 0:5b88d5760320 293 _size = fromle32(table->entries[_part - 1].lba_size) * sector;
kenjiArai 0:5b88d5760320 294
kenjiArai 0:5b88d5760320 295 // Check that block addresses are valid
kenjiArai 0:5b88d5760320 296 if (!_bd->is_valid_erase(_offset, _size)) {
kenjiArai 0:5b88d5760320 297 err = BD_ERROR_INVALID_PARTITION;
kenjiArai 0:5b88d5760320 298 goto fail;
kenjiArai 0:5b88d5760320 299 }
kenjiArai 0:5b88d5760320 300
kenjiArai 0:5b88d5760320 301 _is_initialized = true;
kenjiArai 0:5b88d5760320 302 delete[] buffer;
kenjiArai 0:5b88d5760320 303 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 304
kenjiArai 0:5b88d5760320 305 fail:
kenjiArai 0:5b88d5760320 306 delete[] buffer;
kenjiArai 0:5b88d5760320 307 _is_initialized = false;
kenjiArai 0:5b88d5760320 308 _init_ref_count = 0;
kenjiArai 0:5b88d5760320 309 return err;
kenjiArai 0:5b88d5760320 310 }
kenjiArai 0:5b88d5760320 311
kenjiArai 0:5b88d5760320 312 int MBRBlockDevice::deinit()
kenjiArai 0:5b88d5760320 313 {
kenjiArai 0:5b88d5760320 314 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 315 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 316 }
kenjiArai 0:5b88d5760320 317
kenjiArai 0:5b88d5760320 318 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
kenjiArai 0:5b88d5760320 319
kenjiArai 0:5b88d5760320 320 if (val) {
kenjiArai 0:5b88d5760320 321 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 322 }
kenjiArai 0:5b88d5760320 323
kenjiArai 0:5b88d5760320 324 _is_initialized = false;
kenjiArai 0:5b88d5760320 325 return _bd->deinit();
kenjiArai 0:5b88d5760320 326 }
kenjiArai 0:5b88d5760320 327
kenjiArai 0:5b88d5760320 328 int MBRBlockDevice::sync()
kenjiArai 0:5b88d5760320 329 {
kenjiArai 0:5b88d5760320 330 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 331 return BD_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 332 }
kenjiArai 0:5b88d5760320 333
kenjiArai 0:5b88d5760320 334 return _bd->sync();
kenjiArai 0:5b88d5760320 335 }
kenjiArai 0:5b88d5760320 336
kenjiArai 0:5b88d5760320 337 int MBRBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
kenjiArai 0:5b88d5760320 338 {
kenjiArai 0:5b88d5760320 339 MBED_ASSERT(is_valid_read(addr, size));
kenjiArai 0:5b88d5760320 340 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 341 return BD_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 342 }
kenjiArai 0:5b88d5760320 343
kenjiArai 0:5b88d5760320 344 return _bd->read(b, addr + _offset, size);
kenjiArai 0:5b88d5760320 345 }
kenjiArai 0:5b88d5760320 346
kenjiArai 0:5b88d5760320 347 int MBRBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
kenjiArai 0:5b88d5760320 348 {
kenjiArai 0:5b88d5760320 349 MBED_ASSERT(is_valid_program(addr, size));
kenjiArai 0:5b88d5760320 350 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 351 return BD_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 352 }
kenjiArai 0:5b88d5760320 353
kenjiArai 0:5b88d5760320 354 return _bd->program(b, addr + _offset, size);
kenjiArai 0:5b88d5760320 355 }
kenjiArai 0:5b88d5760320 356
kenjiArai 0:5b88d5760320 357 int MBRBlockDevice::erase(bd_addr_t addr, bd_size_t size)
kenjiArai 0:5b88d5760320 358 {
kenjiArai 0:5b88d5760320 359 MBED_ASSERT(is_valid_erase(addr, size));
kenjiArai 0:5b88d5760320 360 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 361 return BD_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 362 }
kenjiArai 0:5b88d5760320 363
kenjiArai 0:5b88d5760320 364 return _bd->erase(addr + _offset, size);
kenjiArai 0:5b88d5760320 365 }
kenjiArai 0:5b88d5760320 366
kenjiArai 0:5b88d5760320 367 bd_size_t MBRBlockDevice::get_read_size() const
kenjiArai 0:5b88d5760320 368 {
kenjiArai 0:5b88d5760320 369 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 370 return 0;
kenjiArai 0:5b88d5760320 371 }
kenjiArai 0:5b88d5760320 372
kenjiArai 0:5b88d5760320 373 return _bd->get_read_size();
kenjiArai 0:5b88d5760320 374 }
kenjiArai 0:5b88d5760320 375
kenjiArai 0:5b88d5760320 376 bd_size_t MBRBlockDevice::get_program_size() const
kenjiArai 0:5b88d5760320 377 {
kenjiArai 0:5b88d5760320 378 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 379 return 0;
kenjiArai 0:5b88d5760320 380 }
kenjiArai 0:5b88d5760320 381
kenjiArai 0:5b88d5760320 382 return _bd->get_program_size();
kenjiArai 0:5b88d5760320 383 }
kenjiArai 0:5b88d5760320 384
kenjiArai 0:5b88d5760320 385 bd_size_t MBRBlockDevice::get_erase_size() const
kenjiArai 0:5b88d5760320 386 {
kenjiArai 0:5b88d5760320 387 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 388 return 0;
kenjiArai 0:5b88d5760320 389 }
kenjiArai 0:5b88d5760320 390
kenjiArai 0:5b88d5760320 391 return _bd->get_erase_size();
kenjiArai 0:5b88d5760320 392 }
kenjiArai 0:5b88d5760320 393
kenjiArai 0:5b88d5760320 394 bd_size_t MBRBlockDevice::get_erase_size(bd_addr_t addr) const
kenjiArai 0:5b88d5760320 395 {
kenjiArai 0:5b88d5760320 396 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 397 return 0;
kenjiArai 0:5b88d5760320 398 }
kenjiArai 0:5b88d5760320 399
kenjiArai 0:5b88d5760320 400 return _bd->get_erase_size(_offset + addr);
kenjiArai 0:5b88d5760320 401 }
kenjiArai 0:5b88d5760320 402
kenjiArai 0:5b88d5760320 403 int MBRBlockDevice::get_erase_value() const
kenjiArai 0:5b88d5760320 404 {
kenjiArai 0:5b88d5760320 405 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 406 return 0;
kenjiArai 0:5b88d5760320 407 }
kenjiArai 0:5b88d5760320 408
kenjiArai 0:5b88d5760320 409 return _bd->get_erase_value();
kenjiArai 0:5b88d5760320 410 }
kenjiArai 0:5b88d5760320 411
kenjiArai 0:5b88d5760320 412 bd_size_t MBRBlockDevice::size() const
kenjiArai 0:5b88d5760320 413 {
kenjiArai 0:5b88d5760320 414 return _size;
kenjiArai 0:5b88d5760320 415 }
kenjiArai 0:5b88d5760320 416
kenjiArai 0:5b88d5760320 417 bd_size_t MBRBlockDevice::get_partition_start() const
kenjiArai 0:5b88d5760320 418 {
kenjiArai 0:5b88d5760320 419 return _offset;
kenjiArai 0:5b88d5760320 420 }
kenjiArai 0:5b88d5760320 421
kenjiArai 0:5b88d5760320 422 bd_size_t MBRBlockDevice::get_partition_stop() const
kenjiArai 0:5b88d5760320 423 {
kenjiArai 0:5b88d5760320 424 return _offset + _size;
kenjiArai 0:5b88d5760320 425 }
kenjiArai 0:5b88d5760320 426
kenjiArai 0:5b88d5760320 427 uint8_t MBRBlockDevice::get_partition_type() const
kenjiArai 0:5b88d5760320 428 {
kenjiArai 0:5b88d5760320 429 return _type;
kenjiArai 0:5b88d5760320 430 }
kenjiArai 0:5b88d5760320 431
kenjiArai 0:5b88d5760320 432 int MBRBlockDevice::get_partition_number() const
kenjiArai 0:5b88d5760320 433 {
kenjiArai 0:5b88d5760320 434 return _part;
kenjiArai 0:5b88d5760320 435 }
kenjiArai 0:5b88d5760320 436
kenjiArai 0:5b88d5760320 437 const char *MBRBlockDevice::get_type() const
kenjiArai 0:5b88d5760320 438 {
kenjiArai 0:5b88d5760320 439 if (_bd != NULL) {
kenjiArai 0:5b88d5760320 440 return _bd->get_type();
kenjiArai 0:5b88d5760320 441 }
kenjiArai 0:5b88d5760320 442
kenjiArai 0:5b88d5760320 443 return NULL;
kenjiArai 0:5b88d5760320 444 }
kenjiArai 0:5b88d5760320 445
kenjiArai 0:5b88d5760320 446 } // namespace mbed
kenjiArai 0:5b88d5760320 447