RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

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