blob: e69504b38ed3752e44039fa974dccffdaead7c19 [file]
/*
* Copyright (c) 2024 Renesas Electronics Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/irq.h>
#include "reg_protection.h"
#if CONFIG_HAS_RENESAS_RX_RDP
#include "r_bsp_cpu.h"
#endif
#define PRCR_KEY (0xA500)
#define SYSTEM_PRCR (*(volatile uint16_t *)0x000803FE)
#ifndef CONFIG_HAS_RENESAS_RX_RDP
static volatile uint16_t protect_counters[RENESAS_RX_REG_PROTECT_TOTAL_ITEMS];
static const uint16_t prcr_masks[RENESAS_RX_REG_PROTECT_TOTAL_ITEMS] = {
0x0001, /* PRC0. */
0x0002, /* PRC1. */
0x0004, /* PRC2. */
0x0008, /* PRC3. */
};
void renesas_rx_register_protect_open(void)
{
int i;
for (i = 0; i < RENESAS_RX_REG_PROTECT_TOTAL_ITEMS; i++) {
protect_counters[i] = 0;
}
}
#endif
void renesas_rx_register_protect_enable(renesas_rx_reg_protect_t regs_to_protect)
{
#if CONFIG_HAS_RENESAS_RX_RDP
R_BSP_RegisterProtectEnable(regs_to_protect);
#else
int key;
/*
* Set IPL to the maximum value to disable all interrupts,
* so the scheduler can not be scheduled in critical region.
* Note: Please set this macro more than IPR for other FIT module interrupts.
*/
key = irq_lock();
/* Is it safe to disable write access? */
if (0 != protect_counters[regs_to_protect]) {
/* Decrement the protect counter */
protect_counters[regs_to_protect]--;
}
/* Is it safe to disable write access? */
if (0 == protect_counters[regs_to_protect]) {
/*
* Enable protection using PRCR register.
* When writing to the PRCR register the upper 8-bits must be the correct key. Set
* lower bits to 0 to disable writes. b15:b8 PRKEY - Write 0xA5 to upper byte to
* enable writing to lower byte b7:b4 Reserved (set to 0) b3 PRC3 - Please
* check the user's manual. b2 PRC2 - Please check the user's manual. b1 PRC1
* - Please check the user's manual. b0 PRC0 - Please check the user's manual.
*/
SYSTEM_PRCR = (uint16_t)((SYSTEM_PRCR | PRCR_KEY) & (~prcr_masks[regs_to_protect]));
}
/* Restore the IPL. */
irq_unlock(key);
#endif
}
void renesas_rx_register_protect_disable(renesas_rx_reg_protect_t regs_to_unprotect)
{
#if CONFIG_HAS_RENESAS_RX_RDP
R_BSP_RegisterProtectDisable(regs_to_unprotect);
#else
int key;
/*
* Set IPL to the maximum value to disable all interrupts,
* so the scheduler cannot be scheduled in the critical region.
* Note: Please set this macro more than IPR for other FIT module interrupts.
*/
key = irq_lock();
/* Is it safe to enable write access? */
if (0 == protect_counters[regs_to_unprotect]) {
/* Disable protection using PRCR register */
SYSTEM_PRCR = (uint16_t)((SYSTEM_PRCR | PRCR_KEY) | prcr_masks[regs_to_unprotect]);
}
/* Increment the protect counter */
protect_counters[regs_to_unprotect]++;
/* Restore the IPL */
irq_unlock(key);
#endif
} /* End of function renesas_register_protect_disable() */