|
|
|
@ -30,35 +30,32 @@
|
|
|
|
|
#include "sdcard.h"
|
|
|
|
|
#include "sdcard_emu_mock.h"
|
|
|
|
|
|
|
|
|
|
#define SDCARD_FILE sdcard_mock.filename
|
|
|
|
|
#define SDCARD_BUFFER sdcard_mock.buffer
|
|
|
|
|
#define SDCARD_SIZE sdcard_mock.capacity_bytes
|
|
|
|
|
#define SDCARD_BLOCKS (SDCARD_SIZE / SDCARD_BLOCK_SIZE)
|
|
|
|
|
#define SDCARD_BLOCKS (sd_mock.capacity_bytes / SDCARD_BLOCK_SIZE)
|
|
|
|
|
|
|
|
|
|
static void sdcard_exit(void) {
|
|
|
|
|
if (SDCARD_BUFFER == NULL) {
|
|
|
|
|
if (sd_mock.buffer == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int r = munmap(SDCARD_BUFFER, SDCARD_SIZE);
|
|
|
|
|
int r = munmap(sd_mock.buffer, sd_mock.capacity_bytes);
|
|
|
|
|
ensure(sectrue * (r == 0), "munmap failed");
|
|
|
|
|
SDCARD_BUFFER = NULL;
|
|
|
|
|
sd_mock.buffer = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void sdcard_init(void) {
|
|
|
|
|
if (SDCARD_BUFFER != NULL) {
|
|
|
|
|
if (sd_mock.buffer != NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check whether the file exists and it has the correct size
|
|
|
|
|
struct stat sb;
|
|
|
|
|
int r = stat(SDCARD_FILE, &sb);
|
|
|
|
|
int r = stat(sd_mock.filename, &sb);
|
|
|
|
|
int should_clear = 0;
|
|
|
|
|
|
|
|
|
|
// (re)create if non existent or wrong size
|
|
|
|
|
if (r != 0 || sb.st_size != SDCARD_SIZE) {
|
|
|
|
|
int fd = open(SDCARD_FILE, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
|
|
|
|
|
if (r != 0 || sb.st_size != sd_mock.capacity_bytes) {
|
|
|
|
|
int fd = open(sd_mock.filename, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
|
|
|
|
|
ensure(sectrue * (fd >= 0), "open failed");
|
|
|
|
|
r = ftruncate(fd, SDCARD_SIZE);
|
|
|
|
|
r = ftruncate(fd, sd_mock.capacity_bytes);
|
|
|
|
|
ensure(sectrue * (r == 0), "truncate failed");
|
|
|
|
|
r = close(fd);
|
|
|
|
|
ensure(sectrue * (r == 0), "close failed");
|
|
|
|
@ -67,43 +64,44 @@ void sdcard_init(void) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// mmap file
|
|
|
|
|
int fd = open(SDCARD_FILE, O_RDWR);
|
|
|
|
|
int fd = open(sd_mock.filename, O_RDWR);
|
|
|
|
|
ensure(sectrue * (fd >= 0), "open failed");
|
|
|
|
|
|
|
|
|
|
void *map = mmap(0, SDCARD_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
|
void *map = mmap(0, sd_mock.capacity_bytes, PROT_READ | PROT_WRITE,
|
|
|
|
|
MAP_SHARED, fd, 0);
|
|
|
|
|
ensure(sectrue * (map != MAP_FAILED), "mmap failed");
|
|
|
|
|
|
|
|
|
|
SDCARD_BUFFER = (uint8_t *)map;
|
|
|
|
|
sd_mock.buffer = (uint8_t *)map;
|
|
|
|
|
|
|
|
|
|
if (should_clear) {
|
|
|
|
|
for (int i = 0; i < SDCARD_SIZE; ++i) SDCARD_BUFFER[i] = 0xFF;
|
|
|
|
|
for (int i = 0; i < sd_mock.capacity_bytes; ++i) sd_mock.buffer[i] = 0xFF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sdcard_mock.powered = secfalse;
|
|
|
|
|
sd_mock.powered = secfalse;
|
|
|
|
|
|
|
|
|
|
atexit(sdcard_exit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
secbool sdcard_is_present(void) { return sdcard_mock.inserted; }
|
|
|
|
|
secbool sdcard_is_present(void) { return sd_mock.inserted; }
|
|
|
|
|
|
|
|
|
|
secbool sdcard_power_on(void) {
|
|
|
|
|
if (sdcard_mock.inserted == secfalse) {
|
|
|
|
|
if (sd_mock.inserted == secfalse) {
|
|
|
|
|
return secfalse;
|
|
|
|
|
}
|
|
|
|
|
sdcard_init();
|
|
|
|
|
sdcard_mock.powered = sectrue;
|
|
|
|
|
sd_mock.powered = sectrue;
|
|
|
|
|
return sectrue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void sdcard_power_off(void) { sdcard_mock.powered = secfalse; }
|
|
|
|
|
void sdcard_power_off(void) { sd_mock.powered = secfalse; }
|
|
|
|
|
|
|
|
|
|
uint64_t sdcard_get_capacity_in_bytes(void) {
|
|
|
|
|
return sdcard_mock.powered == sectrue ? SDCARD_SIZE : 0;
|
|
|
|
|
return sd_mock.powered == sectrue ? sd_mock.capacity_bytes : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
secbool sdcard_read_blocks(uint32_t *dest, uint32_t block_num,
|
|
|
|
|
uint32_t num_blocks) {
|
|
|
|
|
if (sectrue != sdcard_mock.powered) {
|
|
|
|
|
if (sectrue != sd_mock.powered) {
|
|
|
|
|
return secfalse;
|
|
|
|
|
}
|
|
|
|
|
if (block_num >= SDCARD_BLOCKS) {
|
|
|
|
@ -112,14 +110,14 @@ secbool sdcard_read_blocks(uint32_t *dest, uint32_t block_num,
|
|
|
|
|
if (num_blocks > SDCARD_BLOCKS - block_num) {
|
|
|
|
|
return secfalse;
|
|
|
|
|
}
|
|
|
|
|
memcpy(dest, SDCARD_BUFFER + block_num * SDCARD_BLOCK_SIZE,
|
|
|
|
|
memcpy(dest, sd_mock.buffer + block_num * SDCARD_BLOCK_SIZE,
|
|
|
|
|
num_blocks * SDCARD_BLOCK_SIZE);
|
|
|
|
|
return sectrue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
secbool sdcard_write_blocks(const uint32_t *src, uint32_t block_num,
|
|
|
|
|
uint32_t num_blocks) {
|
|
|
|
|
if (sectrue != sdcard_mock.powered) {
|
|
|
|
|
if (sectrue != sd_mock.powered) {
|
|
|
|
|
return secfalse;
|
|
|
|
|
}
|
|
|
|
|
if (block_num >= SDCARD_BLOCKS) {
|
|
|
|
@ -128,14 +126,12 @@ secbool sdcard_write_blocks(const uint32_t *src, uint32_t block_num,
|
|
|
|
|
if (num_blocks > SDCARD_BLOCKS - block_num) {
|
|
|
|
|
return secfalse;
|
|
|
|
|
}
|
|
|
|
|
memcpy(SDCARD_BUFFER + block_num * SDCARD_BLOCK_SIZE, src,
|
|
|
|
|
memcpy(sd_mock.buffer + block_num * SDCARD_BLOCK_SIZE, src,
|
|
|
|
|
num_blocks * SDCARD_BLOCK_SIZE);
|
|
|
|
|
return sectrue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t __wur sdcard_get_manuf_id(void) {
|
|
|
|
|
return (uint64_t)sdcard_mock.manuf_ID;
|
|
|
|
|
}
|
|
|
|
|
uint64_t __wur sdcard_get_manuf_id(void) { return (uint64_t)sd_mock.manuf_ID; }
|
|
|
|
|
uint64_t __wur sdcard_get_serial_num(void) {
|
|
|
|
|
return (uint64_t)sdcard_mock.serial_number;
|
|
|
|
|
return (uint64_t)sd_mock.serial_number;
|
|
|
|
|
}
|
|
|
|
|