diff --git a/include/vmem/vmem_block.h b/include/vmem/vmem_block.h index 79b068a75..fdf9539a1 100644 --- a/include/vmem/vmem_block.h +++ b/include/vmem/vmem_block.h @@ -129,7 +129,7 @@ typedef struct vmem_block_region_s { extern void vmem_block_read(vmem_t * vmem, uint64_t addr, void * dataout, uint32_t len); extern void vmem_block_write(vmem_t * vmem, uint64_t addr, const void * datain, uint32_t len); extern int vmem_block_flush(vmem_t * vmem); -extern void vmem_block_init(void); +void vmem_block_init(void) __attribute__((error("vmem_block_init() has been removed. Block devices now use lazy initialization."))); #ifdef __cplusplus } diff --git a/src/vmem/vmem_block.c b/src/vmem/vmem_block.c index 2ef50c76e..9293f5fbd 100644 --- a/src/vmem/vmem_block.c +++ b/src/vmem/vmem_block.c @@ -24,6 +24,7 @@ static int32_t cache_read(const vmem_block_driver_t *drv, vmem_block_cache_t *ca static int32_t cache_write(const vmem_block_driver_t *drv, vmem_block_cache_t *cache, uint64_t address, uintptr_t data, uint32_t *length); static void cache_flush(const vmem_block_driver_t *drv, vmem_block_cache_t *cache); static bool address_in_cache(const vmem_block_driver_t *drv, vmem_block_cache_t *cache, uint64_t address); +static int32_t _vmem_block_init(const vmem_block_device_t *dev); static bool address_in_cache(const vmem_block_driver_t *drv, vmem_block_cache_t *cache, uint64_t address) { @@ -42,6 +43,13 @@ static bool address_in_cache(const vmem_block_driver_t *drv, vmem_block_cache_t static void cache_flush(const vmem_block_driver_t *drv, vmem_block_cache_t *cache) { + if(*(drv->device->state) == VMEM_BLOCK_STATE_UNKNOWN) { + int32_t res = _vmem_block_init(drv->device); + if (res < 0) { + return; + } + } + if (cache->is_modified && cache->is_valid) { int32_t res; //printf("::cache_flush() The cache is modified, write it to device\n"); @@ -67,6 +75,15 @@ static int32_t cache_write(const vmem_block_driver_t *drv, vmem_block_cache_t *c if (data == (uintptr_t)NULL || (*length) == 0) { return 0; } + + if(*(drv->device->state) == VMEM_BLOCK_STATE_UNKNOWN) { + int32_t res = _vmem_block_init(drv->device); + if (res < 0) { + (*length) = 0; + return 0; + } + } + if (!cache) { int32_t res; uint32_t len = 0; @@ -163,6 +180,14 @@ static int32_t cache_read(const vmem_block_driver_t *drv, vmem_block_cache_t *ca return 0; } + if(*(drv->device->state) == VMEM_BLOCK_STATE_UNKNOWN) { + int32_t res = _vmem_block_init(drv->device); + if (res < 0) { + (*length) = 0; + return 0; + } + } + if (!cache) { int32_t res; uint32_t len = 0; @@ -333,22 +358,19 @@ int vmem_block_flush(vmem_t * vmem) { return res; } -void vmem_block_init(void) { - - /* Calling these methods requires that the FreeRTOS scheduler is started, since it uses usleep() */ - if ((&__start_vmem_bdevice) && (&__stop_vmem_bdevice)) { - for(vmem_block_device_t *dev = (vmem_block_device_t *)&__start_vmem_bdevice; dev < (vmem_block_device_t *)&__stop_vmem_bdevice; dev++) { - /* Print some specifics for the particular block device */ - printf("Initializing VMEM block device: '%s'\n", dev->name); - printf(" block size : %"PRIu32" bytes\n", dev->bsize); - printf(" number of blocks: %"PRIu32"\n", dev->total_nblocks); - printf(" total size : %"PRIu64" bytes\n", ((uint64_t)dev->bsize * (uint64_t)dev->total_nblocks)); - /* Then initialize it */ - if (dev->init) { - (*dev->init)(dev); - } - } +static int32_t _vmem_block_init(const vmem_block_device_t * dev) { + + /* Print some specifics for the particular block device */ + int32_t res = -1; + printf("Initializing VMEM block device: '%s'\n", dev->name); + printf(" block size : %" PRIu32 " bytes\n", dev->bsize); + printf(" number of blocks: %" PRIu32 "\n", dev->total_nblocks); + printf(" total size : %" PRIu64 " bytes\n", ((uint64_t)dev->bsize * (uint64_t)dev->total_nblocks)); + + /* Then initialize it */ + if (dev->init) { + res = (*dev->init)(dev); } + return res; } -