mbed-os/targets/TARGET_Cypress/TARGET_PSOC6/common/reserved-region-bd/CyReservedRegionBlockDevice...

122 lines
3.8 KiB
C++

/***************************************************************************//**
* \file CyReservedRegionBlockDevice.cpp
*
* \brief
* Block device for working via an underlying block device without altering
* a reserved region.
*
********************************************************************************
* \copyright
* Copyright 2020 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
#include "CyReservedRegionBlockDevice.h"
CyReservedRegionBlockDevice::CyReservedRegionBlockDevice(BlockDevice *underlying_bd, mbed::bd_size_t reserved_region_size)
{
_underlying_bd = underlying_bd;
_reserved_region_size = reserved_region_size;
_reserved_region_end = 0;
}
int CyReservedRegionBlockDevice::init()
{
int status = _underlying_bd->init();
if (status == BD_ERROR_OK) {
// Round up to start usable region on an erase boundary
// May need to wait until after init() to determine erase size (e.g. QSPI)
if (_reserved_region_size % get_erase_size() != 0) {
_reserved_region_end = _reserved_region_size + get_erase_size() - (_reserved_region_size % get_erase_size());
} else {
_reserved_region_end = _reserved_region_size;
}
}
return status;
}
int CyReservedRegionBlockDevice::deinit()
{
int status = _underlying_bd->deinit();
if (status == BD_ERROR_OK) {
_reserved_region_end = 0;
}
return status;
}
int CyReservedRegionBlockDevice::read(void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size)
{
return _underlying_bd->read(buffer, addr + _reserved_region_end, size);
}
int CyReservedRegionBlockDevice::program(const void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size)
{
return _underlying_bd->program(buffer, addr + _reserved_region_end, size);
}
int CyReservedRegionBlockDevice::erase(mbed::bd_addr_t addr, mbed::bd_size_t size)
{
return _underlying_bd->erase(addr + _reserved_region_end, size);
}
mbed::bd_size_t CyReservedRegionBlockDevice::get_read_size() const
{
return _underlying_bd->get_read_size();
}
mbed::bd_size_t CyReservedRegionBlockDevice::get_program_size() const
{
return _underlying_bd->get_program_size();
}
mbed::bd_size_t CyReservedRegionBlockDevice::get_erase_size() const
{
return _underlying_bd->get_erase_size();
}
mbed::bd_size_t CyReservedRegionBlockDevice::get_erase_size(mbed::bd_addr_t addr) const
{
return _underlying_bd->get_erase_size(addr + _reserved_region_end);
}
int CyReservedRegionBlockDevice::get_erase_value() const
{
return _underlying_bd->get_erase_value();
}
mbed::bd_size_t CyReservedRegionBlockDevice::size() const
{
return _underlying_bd->size() - _reserved_region_end;
}
const char *CyReservedRegionBlockDevice::get_type() const
{
return _underlying_bd->get_type();
}
int CyReservedRegionBlockDevice::reserved_read(void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size)
{
if (addr + size > _reserved_region_end || addr % get_read_size() != 0 || size % get_read_size() != 0) {
return BD_ERROR_DEVICE_ERROR;
}
return _underlying_bd->read(buffer, addr, size);
}
mbed::bd_addr_t CyReservedRegionBlockDevice::reserved_region_end() const
{
return _reserved_region_end;
}