<commit_before>/*
 * Copyright (c) 2017-2018 Nordic Semiconductor ASA
 * Copyright (c) 2016 Linaro Limited
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>

#include <kernel.h>
#include <device.h>
#include <init.h>
#include <soc.h>
#include <drivers/flash.h>
#include <string.h>
#include <nrfx_nvmc.h>
#include <nrf_erratas.h>

#include "soc_flash_nrf.h"

#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(flash_nrf);

#if DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf51_flash_controller), okay)
#define DT_DRV_COMPAT nordic_nrf51_flash_controller
#elif DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf52_flash_controller), okay)
#define DT_DRV_COMPAT nordic_nrf52_flash_controller
#elif DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf53_flash_controller), okay)
#define DT_DRV_COMPAT nordic_nrf53_flash_controller
#elif DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf91_flash_controller), okay)
#define DT_DRV_COMPAT nordic_nrf91_flash_controller
#else
#error No matching compatible for soc_flash_nrf.c
#endif

#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash)

#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
#define FLASH_SLOT_WRITE     7500
#if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE)
#define FLASH_SLOT_ERASE (MAX(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE_MS * 1000, \
			      7500))
#else
#define FLASH_SLOT_ERASE FLASH_PAGE_ERASE_MAX_TIME_US
#endif /* CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE */

static int write_op(void *context); /* instance of flash_op_handler_t */
static int write_synchronously(off_t addr, const void *data, size_t len);

static int erase_op(void *context); /* instance of flash_op_handler_t */
static int erase_synchronously(uint32_t addr, uint32_t size);
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */

static const struct flash_parameters flash_nrf_parameters = {
#if IS_ENABLED(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS)
	.write_block_size = 1,
#else
	.write_block_size = 4,
#endif
	.erase_value = 0xff,
};

#if defined(CONFIG_MULTITHREADING)
/* semaphore for locking flash resources (tickers) */
static struct k_sem sem_lock;
#define SYNC_INIT() k_sem_init(&sem_lock, 1, 1)
#define SYNC_LOCK() k_sem_take(&sem_lock, K_FOREVER)
#define SYNC_UNLOCK() k_sem_give(&sem_lock)
#else
#define SYNC_INIT()
#define SYNC_LOCK()
#define SYNC_UNLOCK()
#endif

#if NRF52_ERRATA_242_PRESENT
#include <hal/nrf_power.h>
static int suspend_pofwarn(void);
static void restore_pofwarn(void);

#define SUSPEND_POFWARN() suspend_pofwarn()
#define RESUME_POFWARN()  restore_pofwarn()
#else
#define SUSPEND_POFWARN() 0
#define RESUME_POFWARN()
#endif /* NRF52_ERRATA_242_PRESENT */

static int write(off_t addr, const void *data, size_t len);
static int erase(uint32_t addr, uint32_t size);

static inline bool is_aligned_32(uint32_t data)
{
	return (data & 0x3) ? false : true;
}

static inline bool is_regular_addr_valid(off_t addr, size_t len)
{
	size_t flash_size = nrfx_nvmc_flash_size_get();

	if (addr >= flash_size ||
	    addr < 0 ||
	    len > flash_size ||
	    (addr) + len > flash_size) {
		return false;
	}

	return true;
}


static inline bool is_uicr_addr_valid(off_t addr, size_t len)
{
#ifdef CONFIG_SOC_FLASH_NRF_UICR
	if (addr >= (off_t)NRF_UICR + sizeof(*NRF_UICR) ||
	    addr < (off_t)NRF_UICR ||
	    len > sizeof(*NRF_UICR) ||
	    addr + len > (off_t)NRF_UICR + sizeof(*NRF_UICR)) {
		return false;
	}

	return true;
#else
	return false;
#endif /* CONFIG_SOC_FLASH_NRF_UICR */
}

static void nvmc_wait_ready(void)
{
	while (!nrfx_nvmc_write_done_check()) {
	}
}<commit_msg>drivers: flash: Refactor boundary checking<commit_after>/*
 * Copyright (c) 2017-2018 Nordic Semiconductor ASA
 * Copyright (c) 2016 Linaro Limited
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>

#include <kernel.h>
#include <device.h>
#include <init.h>
#include <soc.h>
#include <drivers/flash.h>
#include <string.h>
#include <nrfx_nvmc.h>
#include <nrf_erratas.h>

#include "soc_flash_nrf.h"

#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(flash_nrf);

#if DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf51_flash_controller), okay)
#define DT_DRV_COMPAT nordic_nrf51_flash_controller
#elif DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf52_flash_controller), okay)
#define DT_DRV_COMPAT nordic_nrf52_flash_controller
#elif DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf53_flash_controller), okay)
#define DT_DRV_COMPAT nordic_nrf53_flash_controller
#elif DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf91_flash_controller), okay)
#define DT_DRV_COMPAT nordic_nrf91_flash_controller
#else
#error No matching compatible for soc_flash_nrf.c
#endif

#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash)

#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
#define FLASH_SLOT_WRITE     7500
#if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE)
#define FLASH_SLOT_ERASE (MAX(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE_MS * 1000, \
			      7500))
#else
#define FLASH_SLOT_ERASE FLASH_PAGE_ERASE_MAX_TIME_US
#endif /* CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE */

static int write_op(void *context); /* instance of flash_op_handler_t */
static int write_synchronously(off_t addr, const void *data, size_t len);

static int erase_op(void *context); /* instance of flash_op_handler_t */
static int erase_synchronously(uint32_t addr, uint32_t size);
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */

static const struct flash_parameters flash_nrf_parameters = {
#if IS_ENABLED(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS)
	.write_block_size = 1,
#else
	.write_block_size = 4,
#endif
	.erase_value = 0xff,
};

#if defined(CONFIG_MULTITHREADING)
/* semaphore for locking flash resources (tickers) */
static struct k_sem sem_lock;
#define SYNC_INIT() k_sem_init(&sem_lock, 1, 1)
#define SYNC_LOCK() k_sem_take(&sem_lock, K_FOREVER)
#define SYNC_UNLOCK() k_sem_give(&sem_lock)
#else
#define SYNC_INIT()
#define SYNC_LOCK()
#define SYNC_UNLOCK()
#endif

#if NRF52_ERRATA_242_PRESENT
#include <hal/nrf_power.h>
static int suspend_pofwarn(void);
static void restore_pofwarn(void);

#define SUSPEND_POFWARN() suspend_pofwarn()
#define RESUME_POFWARN()  restore_pofwarn()
#else
#define SUSPEND_POFWARN() 0
#define RESUME_POFWARN()
#endif /* NRF52_ERRATA_242_PRESENT */

static int write(off_t addr, const void *data, size_t len);
static int erase(uint32_t addr, uint32_t size);

static inline bool is_aligned_32(uint32_t data)
{
	return (data & 0x3) ? false : true;
}

static inline bool is_within_bounds(off_t addr, size_t len, off_t boundary_start,
				    size_t boundary_size)
{
	return (addr >= boundary_start &&
			(addr < (boundary_start + boundary_size)) &&
			(len <= (boundary_start + boundary_size - addr)));
}

static inline bool is_regular_addr_valid(off_t addr, size_t len)
{
	return is_within_bounds(addr, len, 0, nrfx_nvmc_flash_size_get());
}

static inline bool is_uicr_addr_valid(off_t addr, size_t len)
{
#ifdef CONFIG_SOC_FLASH_NRF_UICR
	return is_within_bounds(addr, len, (off_t)NRF_UICR, sizeof(*NRF_UICR));
#else
	return false;
#endif /* CONFIG_SOC_FLASH_NRF_UICR */
}

static void nvmc_wait_ready(void)
{
	while (!nrfx_nvmc_write_done_check()) {
	}
}
{'fraction_non_alphanumeric': 0.10127991096271564, 'fraction_numerical': 0.022815804117974403, 'mean_word_length': 6.730107526881721, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5190424', 'n_tokens_mistral': 2996, 'n_tokens_neox': 2846, 'n_words': 580}