diff options
Diffstat (limited to 'plat/common/tftf_nvm_accessors.c')
-rw-r--r-- | plat/common/tftf_nvm_accessors.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/plat/common/tftf_nvm_accessors.c b/plat/common/tftf_nvm_accessors.c new file mode 100644 index 000000000..f6d003133 --- /dev/null +++ b/plat/common/tftf_nvm_accessors.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <io_storage.h> +#include <platform.h> +#include <platform_def.h> +#include <spinlock.h> +#include <status.h> +#include <string.h> +#include <tftf_lib.h> + +#if USE_NVM +/* Used to serialize write operations from different CPU's */ +static spinlock_t flash_access_lock; +#endif + +STATUS tftf_nvm_write(unsigned long long offset, const void *buffer, size_t size) +{ +#if USE_NVM + int ret; + uintptr_t nvm_handle; + size_t length_written; +#endif + + if (offset + size > TFTF_NVM_SIZE) + return STATUS_OUT_OF_RESOURCES; + +#if USE_NVM + /* Obtain a handle to the NVM by querying the platfom layer */ + plat_get_nvm_handle(&nvm_handle); + + spin_lock(&flash_access_lock); + + ret = io_seek(nvm_handle, IO_SEEK_SET, + offset + TFTF_NVM_OFFSET); + if (ret != IO_SUCCESS) + goto fail; + + ret = io_write(nvm_handle, (const uintptr_t)buffer, size, + &length_written); + if (ret != IO_SUCCESS) + goto fail; + + assert(length_written == size); +fail: + spin_unlock(&flash_access_lock); + + if (ret != IO_SUCCESS) + return STATUS_FAIL; + +#else + uintptr_t addr = DRAM_BASE + TFTF_NVM_OFFSET + offset; + memcpy((void *)addr, buffer, size); +#endif + + return STATUS_SUCCESS; +} + +STATUS tftf_nvm_read(unsigned long long offset, void *buffer, size_t size) +{ +#if USE_NVM + int ret; + uintptr_t nvm_handle; + size_t length_read; +#endif + + if (offset + size > TFTF_NVM_SIZE) + return STATUS_OUT_OF_RESOURCES; + +#if USE_NVM + /* Obtain a handle to the NVM by querying the platfom layer */ + plat_get_nvm_handle(&nvm_handle); + + spin_lock(&flash_access_lock); + + ret = io_seek(nvm_handle, IO_SEEK_SET, TFTF_NVM_OFFSET + offset); + if (ret != IO_SUCCESS) + goto fail; + + ret = io_read(nvm_handle, (uintptr_t)buffer, size, &length_read); + if (ret != IO_SUCCESS) + goto fail; + + assert(length_read == size); +fail: + spin_unlock(&flash_access_lock); + + if (ret != IO_SUCCESS) + return STATUS_FAIL; +#else + uintptr_t addr = DRAM_BASE + TFTF_NVM_OFFSET + offset; + memcpy(buffer, (void *)addr, size); +#endif + + return STATUS_SUCCESS; +} + |