From 1a0aecb0cef0e1debbdd200bd61db191f82b4afd Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Wed, 8 Mar 2023 10:08:29 +0100 Subject: [PATCH] arch/nrf53: initial support for rptun --- arch/arm/src/nrf53/Kconfig | 4 + arch/arm/src/nrf53/Make.defs | 8 + arch/arm/src/nrf53/hardware/nrf53_ipc.h | 68 +++ arch/arm/src/nrf53/hardware/nrf53_spu.h | 86 ++-- arch/arm/src/nrf53/nrf53_ipc.c | 183 ++++++++ arch/arm/src/nrf53/nrf53_ipc.h | 47 +++ arch/arm/src/nrf53/nrf53_rptun.c | 537 ++++++++++++++++++++++++ arch/arm/src/nrf53/nrf53_rptun.h | 61 +++ 8 files changed, 958 insertions(+), 36 deletions(-) create mode 100644 arch/arm/src/nrf53/hardware/nrf53_ipc.h create mode 100644 arch/arm/src/nrf53/nrf53_ipc.c create mode 100644 arch/arm/src/nrf53/nrf53_ipc.h create mode 100644 arch/arm/src/nrf53/nrf53_rptun.c create mode 100644 arch/arm/src/nrf53/nrf53_rptun.h diff --git a/arch/arm/src/nrf53/Kconfig b/arch/arm/src/nrf53/Kconfig index 0a4c815763..d1bf7849c5 100644 --- a/arch/arm/src/nrf53/Kconfig +++ b/arch/arm/src/nrf53/Kconfig @@ -68,6 +68,10 @@ config NRF53_ENABLE_APPROTECT # Peripheral Selection +config NRF53_IPC + bool + default y if RPTUN + config NRF53_UART bool default n diff --git a/arch/arm/src/nrf53/Make.defs b/arch/arm/src/nrf53/Make.defs index 686f1c5e27..2453bba049 100644 --- a/arch/arm/src/nrf53/Make.defs +++ b/arch/arm/src/nrf53/Make.defs @@ -42,6 +42,14 @@ ifeq ($(CONFIG_NRF53_APPCORE),y) CHIP_CSRCS += nrf53_cpunet.c endif +ifeq ($(CONFIG_NRF53_IPC),y) +CHIP_CSRCS += nrf53_ipc.c +endif + +ifeq ($(CONFIG_RPTUN),y) +CHIP_CSRCS += nrf53_rptun.c +endif + ifeq ($(CONFIG_NRF53_SOFTDEVICE_CONTROLLER),y) NRFXLIB_UNPACK := sdk-nrfxlib diff --git a/arch/arm/src/nrf53/hardware/nrf53_ipc.h b/arch/arm/src/nrf53/hardware/nrf53_ipc.h new file mode 100644 index 0000000000..6985160b10 --- /dev/null +++ b/arch/arm/src/nrf53/hardware/nrf53_ipc.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * arch/arm/src/nrf53/hardware/nrf53_ipc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_IPC_H +#define __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_IPC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "nrf53_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NRF53_IPC_CHANS 16 + +/* Register offsets *********************************************************/ + +#define NRF53_IPC_TASKS_SEND_OFFSET(n) (0x000 + (0x4 * n)) /* Trigger events on IPC channel enabled in SEND_CNF[n] */ +#define NRF53_IPC_SUBSCRIBE_SEND_OFFSET(n) (0x080 + (0x4 * n)) /* Subscribe configuration for task SEND[n] */ +#define NRF53_IPC_EVENTS_RECEIVE_OFFSET(n) (0x100 + (0x4 * n)) /* Event received on one or more of the enabled IPC channels in RECEIVE_CNF[n] */ +#define NRF53_IPC_PUBLISH_RECEIVE_OFFSET(n) (0x180 + (0x4 * n)) /* Publish configuration for event RECEIVE[n] */ +#define NRF53_IPC_INTEN_OFFSET (0x300) /* Enable or disable interrupt */ +#define NRF53_IPC_INTENSET_OFFSET (0x304) /* Enable interrupt */ +#define NRF53_IPC_INTENCLR_OFFSET (0x308) /* Disable interrupt */ +#define NRF53_IPC_INTPEND_OFFSET (0x30C) /* Pending interrupts */ +#define NRF53_IPC_SEND_CNF_OFFSET(n) (0x510 + (0x4 * n)) /* Send event configuration for TASKS_SEND[n] */ +#define NRF53_IPC_RECEIVE_CNF_OFFSET(n) (0x590 + (0x4 * n)) /* Receive event configuration for EVENTS_RECEIVE[n] */ +#define NRF53_IPC_GPMEM_OFFSET(n) (0x610 + (0x4 * n)) /* General purpose memory */ + +/* Register definitions *****************************************************/ + +#define NRF53_IPC_TASKS_SEND(n) (NRF53_IPC_BASE + NRF53_IPC_TASKS_SEND_OFFSET(n)) +#define NRF53_IPC_SUBSCRIBE_SEND(n) (NRF53_IPC_BASE + NRF53_IPC_SUBSCRIBE_SEND_OFFSET(n)) +#define NRF53_IPC_EVENTS_RECEIVE(n) (NRF53_IPC_BASE + NRF53_IPC_EVENTS_RECEIVE_OFFSET(n)) +#define NRF53_IPC_INTEN (NRF53_IPC_BASE + NRF53_IPC_INTEN_OFFSET) +#define NRF53_IPC_INTENSET (NRF53_IPC_BASE + NRF53_IPC_INTENSET_OFFSET) +#define NRF53_IPC_INTENCLR (NRF53_IPC_BASE + NRF53_IPC_INTENCLR_OFFSET) +#define NRF53_IPC_INTPEND (NRF53_IPC_BASE + NRF53_IPC_INTPEND_OFFSET) +#define NRF53_IPC_SEND_CNF(n) (NRF53_IPC_BASE + NRF53_IPC_SEND_CNF_OFFSET(n)) +#define NRF53_IPC_RECEIVE_CNF(n) (NRF53_IPC_BASE + NRF53_IPC_RECEIVE_CNF_OFFSET(n)) +#define NRF53_IPC_GPMEM(n) (NRF53_IPC_BASE + NRF53_IPC_GPMEM_OFFSET(n)) + +/* Register bit definitions *************************************************/ + +#define IPC_CHAN_ID(x) (1 << x) /* Channel ID */ + +#endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_IPC_H */ diff --git a/arch/arm/src/nrf53/hardware/nrf53_spu.h b/arch/arm/src/nrf53/hardware/nrf53_spu.h index 7a675ec89a..1da0ec2600 100644 --- a/arch/arm/src/nrf53/hardware/nrf53_spu.h +++ b/arch/arm/src/nrf53/hardware/nrf53_spu.h @@ -34,29 +34,29 @@ /* Register offsets *********************************************************/ -#define NRF53_SPU_EVENTS_RAMACCERR_OFFSET 0x100 /* A security violation has been detected for the RAM memory space */ -#define NRF53_SPU_EVENTS_FLASHACCERR_OFFSET 0x104 /* A security violation has been detected for the FLASH memory space */ -#define NRF53_SPU_EVENTS_PERIPHACCERR_OFFSET 0x108 /* A security violation has been detected on one or several peripherals */ -#define NRF53_SPU_PUBLISH_RAMACCERR_OFFSET 0x180 /* Publish configuration for event RAMACCERR */ -#define NRF53_SPU_PUBLISH_FLASHACCERR_OFFSET 0x184 /* Publish configuration for event FLASHACCERR */ -#define NRF53_SPU_PUBLISH_PERIPHACCERR_OFFSET 0x188 /* Publish configuration for event PERIPHACCERR */ -#define NRF53_SPU_INTEN_OFFSET 0x300 /* Enable or disable interrupt */ -#define NRF53_SPU_INTSEL_OFFSET 0x304 /* Enable interrupt */ -#define NRF53_SPU_INTCLR_OFFSET 0x308 /* Disable interrupt */ -#define NRF53_SPU_CAP_OFFSET 0x400 /* Show implemented features for the current device */ -#define NRF53_SPU_CPULOCK_OFFSET 0x404 /* Configure bits to lock down CPU features at runtime */ -#define NRF53_SPU_EXTDOMAIN_OFFSET 0x440 /* Access for bus access generated from the external domain n */ -#define NRF53_SPU_DPPIPERM_OFFSET 0x480 /* Select between secure and non-secure attribute for the DPPI channels. */ -#define NRF53_SPU_DPPILOCK_OFFSET 0x484 /* Prevent further modification of the corresponding PERM register */ -#define NRF53_SPU_GPIOPORTPERM_OFFSET 0x4C0 /* Select between secure and non-secure attribute for pins 0 to 31 of port n. */ -#define NRF53_SPU_GPIOPORTLOCK_OFFSET 0x4C4 /* Prevent further modification of the corresponding PERM register */ -#define NRF53_SPU_FLASHNSCREGION_OFFSET 0x500 /* Define which flash region can contain the non-secure callable (NSC) region n */ -#define NRF53_SPU_FLASHNSCSIZE_OFFSET 0x504 /* Define the size of the non-secure callable (NSC) region n */ -#define NRF53_SPU_RAMNSCREGION_OFFSET 0x540 /* Define which RAM region can contain the non-secure callable (NSC) region n */ -#define NRF53_SPU_RAMNSCSIZE_OFFSET 0x544 /* Define the size of the non-secure callable (NSC) region n */ -#define NRF53_SPU_FLASHREGIONPERM_OFFSET 0x600 /* Access permissions for flash region n */ -#define NRF53_SPU_RAMREGIONPERM_OFFSET 0x700 /* Access permissions for RAM region n */ -#define NRF53_SPU_PERIPHIDPERM_OFFSET 0x800 /* List capabilities and access permissions for the peripheral with ID n */ +#define NRF53_SPU_EVENTS_RAMACCERR_OFFSET 0x100 /* A security violation has been detected for the RAM memory space */ +#define NRF53_SPU_EVENTS_FLASHACCERR_OFFSET 0x104 /* A security violation has been detected for the FLASH memory space */ +#define NRF53_SPU_EVENTS_PERIPHACCERR_OFFSET 0x108 /* A security violation has been detected on one or several peripherals */ +#define NRF53_SPU_PUBLISH_RAMACCERR_OFFSET 0x180 /* Publish configuration for event RAMACCERR */ +#define NRF53_SPU_PUBLISH_FLASHACCERR_OFFSET 0x184 /* Publish configuration for event FLASHACCERR */ +#define NRF53_SPU_PUBLISH_PERIPHACCERR_OFFSET 0x188 /* Publish configuration for event PERIPHACCERR */ +#define NRF53_SPU_INTEN_OFFSET 0x300 /* Enable or disable interrupt */ +#define NRF53_SPU_INTSEL_OFFSET 0x304 /* Enable interrupt */ +#define NRF53_SPU_INTCLR_OFFSET 0x308 /* Disable interrupt */ +#define NRF53_SPU_CAP_OFFSET 0x400 /* Show implemented features for the current device */ +#define NRF53_SPU_CPULOCK_OFFSET 0x404 /* Configure bits to lock down CPU features at runtime */ +#define NRF53_SPU_EXTDOMAIN_OFFSET(n) (0x440 + (0x4 * n)) /* Access for bus access generated from the external domain n */ +#define NRF53_SPU_DPPIPERM_OFFSET(n) (0x480 + (0x4 * n)) /* Select between secure and non-secure attribute for the DPPI channels. */ +#define NRF53_SPU_DPPILOCK_OFFSET(n) (0x484 + (0x4 * n)) /* Prevent further modification of the corresponding PERM register */ +#define NRF53_SPU_GPIOPORTPERM_OFFSET(n) (0x4C0 + (0x4 * n)) /* Select between secure and non-secure attribute for pins 0 to 31 of port n. */ +#define NRF53_SPU_GPIOPORTLOCK_OFFSET(n) (0x4C4 + (0x4 * n)) /* Prevent further modification of the corresponding PERM register */ +#define NRF53_SPU_FLASHNSCREGION_OFFSET(n) (0x500 + (0x4 * n)) /* Define which flash region can contain the non-secure callable (NSC) region n */ +#define NRF53_SPU_FLASHNSCSIZE_OFFSET(n) (0x504 + (0x4 * n)) /* Define the size of the non-secure callable (NSC) region n */ +#define NRF53_SPU_RAMNSCREGION_OFFSET(n) (0x540 + (0x4 * n)) /* Define which RAM region can contain the non-secure callable (NSC) region n */ +#define NRF53_SPU_RAMNSCSIZE_OFFSET(n) (0x544 + (0x4 * n)) /* Define the size of the non-secure callable (NSC) region n */ +#define NRF53_SPU_FLASHREGIONPERM_OFFSET(n) (0x600 + (0x4 * n)) /* Access permissions for flash region n */ +#define NRF53_SPU_RAMREGIONPERM_OFFSET(n) (0x700 + (0x4 * n)) /* Access permissions for RAM region n */ +#define NRF53_SPU_PERIPHIDPERM_OFFSET(n) (0x800 + (0x4 * n)) /* List capabilities and access permissions for the peripheral with ID n */ /* Register definitions *****************************************************/ @@ -71,21 +71,35 @@ #define NRF53_SPU_INTCLR (NRF53_SPU_BASE + NRF53_SPU_INTCLR_OFFSET) #define NRF53_SPU_CAP (NRF53_SPU_BASE + NRF53_SPU_CAP_OFFSET) #define NRF53_SPU_CPULOCK (NRF53_SPU_BASE + NRF53_SPU_CPULOCK_OFFSET) -#define NRF53_SPU_EXTDOMAIN (NRF53_SPU_BASE + NRF53_SPU_EXTDOMAIN_OFFSET) -#define NRF53_SPU_DPPIPERM (NRF53_SPU_BASE + NRF53_SPU_DPPIPERM_OFFSET) -#define NRF53_SPU_DPPILOCK (NRF53_SPU_BASE + NRF53_SPU_DPPILOCK_OFFSET) -#define NRF53_SPU_GPIOPORTPERM (NRF53_SPU_BASE + NRF53_SPU_GPIOPORTPERM_OFFSET) -#define NRF53_SPU_GPIOPORTLOCK (NRF53_SPU_BASE + NRF53_SPU_GPIOPORTLOCK_OFFSET) -#define NRF53_SPU_FLASHNSCREGION (NRF53_SPU_BASE + NRF53_SPU_FLASHNSCREGION_OFFSET) -#define NRF53_SPU_FLASHNSCSIZE (NRF53_SPU_BASE + NRF53_SPU_FLASHNSCSIZE_OFFSET) -#define NRF53_SPU_RAMNSCREGION (NRF53_SPU_BASE + NRF53_SPU_RAMNSCREGION_OFFSET) -#define NRF53_SPU_RAMNSCSIZE (NRF53_SPU_BASE + NRF53_SPU_RAMNSCSIZE_OFFSET) -#define NRF53_SPU_FLASHREGIONPERM (NRF53_SPU_BASE + NRF53_SPU_FLASHREGIONPERM_OFFSET) -#define NRF53_SPU_RAMREGIONPERM (NRF53_SPU_BASE + NRF53_SPU_RAMREGIONPERM_OFFSET) -#define NRF53_SPU_PERIPHIDPERM (NRF53_SPU_BASE + NRF53_SPU_PERIPHIDPERM_OFFSET) +#define NRF53_SPU_EXTDOMAIN(n) (NRF53_SPU_BASE + NRF53_SPU_EXTDOMAIN_OFFSET(n)) +#define NRF53_SPU_DPPIPERM(n) (NRF53_SPU_BASE + NRF53_SPU_DPPIPERM_OFFSET(n)) +#define NRF53_SPU_DPPILOCK(n) (NRF53_SPU_BASE + NRF53_SPU_DPPILOCK_OFFSET(n)) +#define NRF53_SPU_GPIOPORTPERM(n) (NRF53_SPU_BASE + NRF53_SPU_GPIOPORTPERM_OFFSET(n)) +#define NRF53_SPU_GPIOPORTLOCK(n) (NRF53_SPU_BASE + NRF53_SPU_GPIOPORTLOCK_OFFSET(n)) +#define NRF53_SPU_FLASHNSCREGION(n) (NRF53_SPU_BASE + NRF53_SPU_FLASHNSCREGION_OFFSET(n)) +#define NRF53_SPU_FLASHNSCSIZE(n) (NRF53_SPU_BASE + NRF53_SPU_FLASHNSCSIZE_OFFSET(n)) +#define NRF53_SPU_RAMNSCREGION(n) (NRF53_SPU_BASE + NRF53_SPU_RAMNSCREGION_OFFSET(n)) +#define NRF53_SPU_RAMNSCSIZE(n) (NRF53_SPU_BASE + NRF53_SPU_RAMNSCSIZE_OFFSET(n)) +#define NRF53_SPU_FLASHREGIONPERM(n) (NRF53_SPU_BASE + NRF53_SPU_FLASHREGIONPERM_OFFSET(n)) +#define NRF53_SPU_RAMREGIONPERM(n) (NRF53_SPU_BASE + NRF53_SPU_RAMREGIONPERM_OFFSET(n)) +#define NRF53_SPU_PERIPHIDPERM(n) (NRF53_SPU_BASE + NRF53_SPU_PERIPHIDPERM_OFFSET(n)) /* Register bit definitions *************************************************/ -/* TODO */ +#define SPU_RAM_REGIONS (64) + +#define SPU_EXTDOMAIN_SECUREMAPPING_SHIFT (0) +#define SPU_EXTDOMAIN_SECUREMAPPING_MASK (3 << SPU_EXTDOMAIN_SECUREMAPPING_SHIFT) +# define SPU_EXTDOMAIN_SECUREMAPPING_NONSEC (0 << SPU_EXTDOMAIN_SECUREMAPPING_SHIFT) +# define SPU_EXTDOMAIN_SECUREMAPPING_SEC (1 << SPU_EXTDOMAIN_SECUREMAPPING_SHIFT) +# define SPU_EXTDOMAIN_SECUREMAPPING_USER (2 << SPU_EXTDOMAIN_SECUREMAPPING_SHIFT) +#define SPU_EXTDOMAIN_SECUREMAPPING_SECATTR (1 << 4) +#define SPU_EXTDOMAIN_SECUREMAPPING_LOCK (1 << 8) + +#define SPU_RAMREGION_PERM_EXEC (1 << 0) +#define SPU_RAMREGION_PERM_WRITE (1 << 1) +#define SPU_RAMREGION_PERM_READ (1 << 2) +#define SPU_RAMREGION_PERM_SECATTR (1 << 4) +#define SPU_RAMREGION_PERM_LOCK (1 << 5) #endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_SPU_H */ diff --git a/arch/arm/src/nrf53/nrf53_ipc.c b/arch/arm/src/nrf53/nrf53_ipc.c new file mode 100644 index 0000000000..b20bd60355 --- /dev/null +++ b/arch/arm/src/nrf53/nrf53_ipc.c @@ -0,0 +1,183 @@ +/**************************************************************************** + * arch/arm/src/nrf53/nrf53_ipc.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "arm_internal.h" +#include "nrf53_ipc.h" +#include "hardware/nrf53_ipc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* IPC receive channel configuration */ + +struct nrf53_ipc_recv_s +{ + ipc_callback_t callback; + void *args; +}; + +/* IPC device */ + +struct nrf53_ipc_s +{ + struct nrf53_ipc_recv_s recv[NRF53_IPC_CHANS]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct nrf53_ipc_s g_nrf53_ipc; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nrf53_ipc_interrupt + ****************************************************************************/ + +static int nrf53_ipc_interrupt(int irq, void *context, void *args) +{ + struct nrf53_ipc_s *dev = args; + uint32_t regval = 0; + int i = 0; + + regval = getreg32(NRF53_IPC_INTPEND); + + _info("IPC interrupt 0x%" PRIx32 "\n", regval); + + for (i = 0; i < NRF53_IPC_CHANS; i += 1) + { + if (regval & IPC_CHAN_ID(i)) + { + if (dev->recv[i].callback) + { + dev->recv[i].callback(i, dev->recv[i].args); + } + + /* Clear EVENT */ + + putreg32(0, NRF53_IPC_EVENTS_RECEIVE(i)); + } + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nrf53_ipc_subscribe + ****************************************************************************/ + +void nrf53_ipc_subscribe(int id, ipc_callback_t callback, void *args) +{ + struct nrf53_ipc_s *dev = &g_nrf53_ipc; + + DEBUGASSERT(id < NRF53_IPC_CHANS); + + _info("IPC subscribe %d\n", id); + + /* Register callaback */ + + dev->recv[id].callback = callback; + dev->recv[id].args = args; + + if (callback) + { + /* Register as receive channel and enable interrupts */ + + putreg32(IPC_CHAN_ID(id), NRF53_IPC_RECEIVE_CNF(id)); + putreg32(IPC_CHAN_ID(id), NRF53_IPC_INTENSET); + } + else + { + /* Disable interrupts */ + + putreg32(IPC_CHAN_ID(id), NRF53_IPC_INTENCLR); + } +} + +/**************************************************************************** + * Name: nrf53_ipc_signal + ****************************************************************************/ + +void nrf53_ipc_signal(int id) +{ + DEBUGASSERT(id < NRF53_IPC_CHANS); + + _info("IPC signal %d\n", id); + + putreg32(1, NRF53_IPC_TASKS_SEND(id)); +} + +/**************************************************************************** + * Name: nrf53_ipc_send_cfg + ****************************************************************************/ + +void nrf53_ipc_send_cfg(int id) +{ + DEBUGASSERT(id < NRF53_IPC_CHANS); + + _info("IPC send cfg %d\n", id); + + /* Enable send event on a single IPC channel */ + + putreg32(IPC_CHAN_ID(id), NRF53_IPC_SEND_CNF(id)); +} + +/**************************************************************************** + * Name: nrf53_ipc_init + ****************************************************************************/ + +void nrf53_ipc_init(void) +{ + struct nrf53_ipc_s *dev = &g_nrf53_ipc; + + /* Reset device */ + + memset(dev, 0, sizeof(struct nrf53_ipc_s)); + + /* Attach and enable the IRQ */ + + irq_attach(NRF53_IRQ_IPC, nrf53_ipc_interrupt, dev); + + up_enable_irq(NRF53_IRQ_IPC); +} diff --git a/arch/arm/src/nrf53/nrf53_ipc.h b/arch/arm/src/nrf53/nrf53_ipc.h new file mode 100644 index 0000000000..c4fa6a832f --- /dev/null +++ b/arch/arm/src/nrf53/nrf53_ipc.h @@ -0,0 +1,47 @@ +/**************************************************************************** + * arch/arm/src/nrf53/nrf53_ipc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NRF53_NRF53_IPC_H +#define __ARCH_ARM_SRC_NRF53_NRF53_IPC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "hardware/nrf53_ipc.h" + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef void (*ipc_callback_t)(int id, void *arg); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void nrf53_ipc_subscribe(int id, ipc_callback_t callback, void *args); +void nrf53_ipc_send_cfg(int id); +void nrf53_ipc_signal(int id); +void nrf53_ipc_init(void); + +#endif /* __ARCH_ARM_SRC_NRF53_NRF53_IPC_H */ diff --git a/arch/arm/src/nrf53/nrf53_rptun.c b/arch/arm/src/nrf53/nrf53_rptun.c new file mode 100644 index 0000000000..1d7a8d04a6 --- /dev/null +++ b/arch/arm/src/nrf53/nrf53_rptun.c @@ -0,0 +1,537 @@ +/**************************************************************************** + * arch/arm/src/nrf53/nrf53_rptun.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include + +#include "arm_internal.h" +#include "hardware/nrf53_spu.h" + +#include "nrf53_ipc.h" + +#ifdef CONFIG_NRF53_APPCORE +# include "nrf53_cpunet.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Vring configuration parameters */ + +#define VRINGS (2) /* Number of vrings */ +#define VRING_ALIGN (8) /* Vring alignment */ +#define VRING_NR (8) /* Number of descriptors */ +#define VRING_SIZE (512) /* Size of one descriptor */ + +/* This is the RPMSG default channel used with only one RPMSG channel. + * We use the last 32kB of the App core RAM as a shared memory. + */ + +#define VRING_SHMEM (0x20078000) /* Vring shared memory start */ +#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */ +#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */ + +/* IPC configuration */ + +#define RPTUN_IPC_CHAN_MASTER_RX (0) /* RX for master is ready */ +#define RPTUN_IPC_CHAN_SLAVE_RX (1) /* RX for slave is ready */ +#define RPTUN_IPC_CHAN_SLAVE_RESET (2) +#define RPTUN_IPC_CHAN_SLAVE_PANIC (3) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* NRF53 rptun sharred memory */ + +struct nrf53_rptun_shmem_s +{ + volatile uintptr_t base; + struct rptun_rsc_s rsc; +}; + +/* NRF53 rptun device */ + +struct nrf53_rptun_dev_s +{ + struct rptun_dev_s rptun; + rptun_callback_t callback; + void *arg; + bool master; + struct nrf53_rptun_shmem_s *shmem; + char cpuname[RPMSG_NAME_SIZE + 1]; + char shmemname[RPMSG_NAME_SIZE + 1]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static const char *nrf53_rptun_get_cpuname(struct rptun_dev_s *dev); +static const char *nrf53_rptun_get_firmware(struct rptun_dev_s *dev); +static const struct rptun_addrenv_s * +nrf53_rptun_get_addrenv(struct rptun_dev_s *dev); +static struct rptun_rsc_s * +nrf53_rptun_get_resource(struct rptun_dev_s *dev); +static bool nrf53_rptun_is_autostart(struct rptun_dev_s *dev); +static bool nrf53_rptun_is_master(struct rptun_dev_s *dev); +static int nrf53_rptun_start(struct rptun_dev_s *dev); +static int nrf53_rptun_stop(struct rptun_dev_s *dev); +static int nrf53_rptun_notify(struct rptun_dev_s *dev, uint32_t vqid); +static int nrf53_rptun_register_callback(struct rptun_dev_s *dev, + rptun_callback_t callback, + void *arg); + +#ifdef CONFIG_NRF53_APPCORE +static void nrf53_rptun_reset(struct rptun_dev_s *dev, int value); +static void nrf53_rptun_panic(struct rptun_dev_s *dev); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct rptun_ops_s g_nrf53_rptun_ops = +{ + .get_cpuname = nrf53_rptun_get_cpuname, + .get_firmware = nrf53_rptun_get_firmware, + .get_addrenv = nrf53_rptun_get_addrenv, + .get_resource = nrf53_rptun_get_resource, + .is_autostart = nrf53_rptun_is_autostart, + .is_master = nrf53_rptun_is_master, + .start = nrf53_rptun_start, + .stop = nrf53_rptun_stop, + .notify = nrf53_rptun_notify, + .register_callback = nrf53_rptun_register_callback, +#ifdef CONFIG_NRF53_APPCORE + .reset = nrf53_rptun_reset, + .panic = nrf53_rptun_panic +#endif +}; + +#ifdef CONFIG_NRF53_APPCORE +/* Allocate shared memory on the App core side */ + +static struct nrf53_rptun_shmem_s g_shmem __attribute__((section(".shmem"))); +#endif + +struct nrf53_rptun_dev_s g_rptun_dev; +static sem_t g_nrf53_rx_sig = SEM_INITIALIZER(0); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nrf53_rptun_get_cpuname + ****************************************************************************/ + +static const char *nrf53_rptun_get_cpuname(struct rptun_dev_s *dev) +{ + struct nrf53_rptun_dev_s *priv = container_of(dev, + struct nrf53_rptun_dev_s, rptun); + + return priv->cpuname; +} + +/**************************************************************************** + * Name: nrf53_rptun_get_firmware + ****************************************************************************/ + +static const char *nrf53_rptun_get_firmware(struct rptun_dev_s *dev) +{ + return NULL; +} + +/**************************************************************************** + * Name: nrf53_rptun_get_addrenv + ****************************************************************************/ + +static const struct rptun_addrenv_s * +nrf53_rptun_get_addrenv(struct rptun_dev_s *dev) +{ + return NULL; +} + +/**************************************************************************** + * Name: nrf53_rptun_get_resource + ****************************************************************************/ + +static struct rptun_rsc_s * +nrf53_rptun_get_resource(struct rptun_dev_s *dev) +{ + struct nrf53_rptun_dev_s *priv = container_of(dev, + struct nrf53_rptun_dev_s, rptun); + struct rptun_rsc_s *rsc; + + if (priv->shmem != NULL) + { + return &priv->shmem->rsc; + } + +#ifdef CONFIG_NRF53_APPCORE + priv->shmem = &g_shmem; +#else + priv->shmem = (struct nrf53_rptun_shmem_s *)VRING_SHMEM; +#endif + + if (priv->master) + { + /* Perform initial setup */ + + rsc = &priv->shmem->rsc; + + priv->shmem->base = (uintptr_t)priv->shmem; + + rsc->rsc_tbl_hdr.ver = 1; + rsc->rsc_tbl_hdr.num = 1; + rsc->rsc_tbl_hdr.reserved[0] = 0; + rsc->rsc_tbl_hdr.reserved[1] = 0; + rsc->offset[0] = offsetof(struct rptun_rsc_s, + rpmsg_vdev); + + rsc->rpmsg_vdev.type = RSC_VDEV; + rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG; + rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS + | 1 << VIRTIO_RPMSG_F_ACK + | 1 << VIRTIO_RPMSG_F_BUFSZ; + rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config); + rsc->rpmsg_vdev.num_of_vrings = VRINGS; + + rsc->rpmsg_vring0.align = VRING_ALIGN; + rsc->rpmsg_vring0.num = VRING_NR; + rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID; + rsc->rpmsg_vring1.align = VRING_ALIGN; + rsc->rpmsg_vring1.num = VRING_NR; + rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID; + rsc->config.r2h_buf_size = VRING_SIZE; + rsc->config.h2r_buf_size = VRING_SIZE; + } + else + { + /* TODO: use IPC */ + + while (priv->shmem->base == 0) + { + usleep(100); + } + } + + return &priv->shmem->rsc; +} + +/**************************************************************************** + * Name: nrf53_rptun_is_autostart + ****************************************************************************/ + +static bool nrf53_rptun_is_autostart(struct rptun_dev_s *dev) +{ + return true; +} + +/**************************************************************************** + * Name: nrf53_rptun_is_master + ****************************************************************************/ + +static bool nrf53_rptun_is_master(struct rptun_dev_s *dev) +{ + struct nrf53_rptun_dev_s *priv = container_of(dev, + struct nrf53_rptun_dev_s, rptun); + return priv->master; +} + +/**************************************************************************** + * Name: nrf53_rptun_start + ****************************************************************************/ + +static int nrf53_rptun_start(struct rptun_dev_s *dev) +{ + return 0; +} + +/**************************************************************************** + * Name: nrf53_rptun_stop + ****************************************************************************/ + +static int nrf53_rptun_stop(struct rptun_dev_s *dev) +{ + return 0; +} + +/**************************************************************************** + * Name: nrf53_rptun_notify + ****************************************************************************/ + +static int nrf53_rptun_notify(struct rptun_dev_s *dev, uint32_t vqid) +{ +#ifdef CONFIG_NRF53_APPCORE + /* Notify slave that RX is ready */ + + nrf53_ipc_signal(RPTUN_IPC_CHAN_SLAVE_RX); +#else + /* Notify master that RX is ready */ + + nrf53_ipc_signal(RPTUN_IPC_CHAN_MASTER_RX); +#endif + + return 0; +} + +/**************************************************************************** + * Name: nrf53_rptun_register_callback + ****************************************************************************/ + +static int nrf53_rptun_register_callback(struct rptun_dev_s *dev, + rptun_callback_t callback, + void *arg) +{ + struct nrf53_rptun_dev_s *priv = container_of(dev, + struct nrf53_rptun_dev_s, rptun); + + priv->callback = callback; + priv->arg = arg; + + return 0; +} + +#ifdef CONFIG_NRF53_APPCORE +/**************************************************************************** + * Name: nrf53_rptun_reset + ****************************************************************************/ + +static void nrf53_rptun_reset(struct rptun_dev_s *dev, int value) +{ + if (value == 0) + { + /* Hard reset with Forceoff */ + + nrf53_cpunet_power(false); + nrf53_cpunet_power(true); + } + else + { + /* Soft reset */ + + nrf53_ipc_signal(RPTUN_IPC_CHAN_SLAVE_RESET); + } +} + +/**************************************************************************** + * Name: nrf53_rptun_panic + ****************************************************************************/ + +static void nrf53_rptun_panic(struct rptun_dev_s *dev) +{ + nrf53_ipc_signal(RPTUN_IPC_CHAN_SLAVE_PANIC); +} +#endif + +#ifdef CONFIG_NRF53_APPCORE +/**************************************************************************** + * Name: nrf53_ipc_master_callback + ****************************************************************************/ + +static void nrf53_ipc_master_callback(int id, void *arg) +{ + _info("Rptun IPC master %d\n", id); + + switch (id) + { + case RPTUN_IPC_CHAN_MASTER_RX: + { + nxsem_post(&g_nrf53_rx_sig); + break; + } + + default: + { + DEBUGASSERT(0); + } + } +} + +/**************************************************************************** + * Name: nrf53_rptun_ipc_app + ****************************************************************************/ + +static void nrf53_rptun_ipc_app(struct nrf53_rptun_dev_s *dev) +{ + DEBUGASSERT(dev); + + nrf53_ipc_subscribe(RPTUN_IPC_CHAN_MASTER_RX, + nrf53_ipc_master_callback, + dev); + nrf53_ipc_send_cfg(RPTUN_IPC_CHAN_SLAVE_RX); + nrf53_ipc_send_cfg(RPTUN_IPC_CHAN_SLAVE_RESET); + nrf53_ipc_send_cfg(RPTUN_IPC_CHAN_SLAVE_PANIC); +} +#else +/**************************************************************************** + * Name: nrf53_ipc_slave_callback + ****************************************************************************/ + +static void nrf53_ipc_slave_callback(int id, void *arg) +{ + _info("Rptun IPC slave %d\n", id); + + switch (id) + { + case RPTUN_IPC_CHAN_SLAVE_RX: + { + nxsem_post(&g_nrf53_rx_sig); + break; + } + + case RPTUN_IPC_CHAN_SLAVE_RESET: + { + /* TODO: Soft reset */ + + break; + } + + case RPTUN_IPC_CHAN_SLAVE_PANIC: + { + PANIC(); + } + + default: + { + DEBUGASSERT(0); + } + } +} + +/**************************************************************************** + * Name: nrf53_rptun_ipc_net + ****************************************************************************/ + +static void nrf53_rptun_ipc_net(struct nrf53_rptun_dev_s *dev) +{ + DEBUGASSERT(dev); + + nrf53_ipc_subscribe(RPTUN_IPC_CHAN_SLAVE_RX, + nrf53_ipc_slave_callback, + dev); + nrf53_ipc_subscribe(RPTUN_IPC_CHAN_SLAVE_RESET, + nrf53_ipc_slave_callback, + dev); + nrf53_ipc_subscribe(RPTUN_IPC_CHAN_SLAVE_PANIC, + nrf53_ipc_slave_callback, + dev); + nrf53_ipc_send_cfg(RPTUN_IPC_CHAN_MASTER_RX); +} +#endif + +/**************************************************************************** + * Name: nrf53_rptun_thread + ****************************************************************************/ + +static int nrf53_rptun_thread(int argc, char *argv[]) +{ + struct nrf53_rptun_dev_s *dev = &g_rptun_dev; + + while (1) + { + if (dev->callback != NULL) + { + dev->callback(dev->arg, RPTUN_NOTIFY_ALL); + } + + nxsem_wait(&g_nrf53_rx_sig); + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int nrf53_rptun_init(const char *shmemname, const char *cpuname) +{ + struct nrf53_rptun_dev_s *dev = &g_rptun_dev; + int ret = OK; + + /* Initialize IPC */ + + nrf53_ipc_init(); + + /* The App core always master */ + +#ifdef CONFIG_NRF53_APPCORE + memset(&g_shmem, 0, sizeof(struct nrf53_rptun_shmem_s)); + dev->master = true; +#else + dev->master = false; +#endif + +#ifdef CONFIG_NRF53_APPCORE + /* Set secure domain - this allows net core to access shared mem */ + + putreg32(SPU_EXTDOMAIN_SECUREMAPPING_SECATTR, NRF53_SPU_EXTDOMAIN(0)); +#endif + + /* Subscribe to IPC */ + +#ifdef CONFIG_NRF53_APPCORE + nrf53_rptun_ipc_app(dev); +#else + nrf53_rptun_ipc_net(dev); +#endif + + /* TODO: handle net core reset */ + + /* Configure device */ + + dev->rptun.ops = &g_nrf53_rptun_ops; + strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE); + strncpy(dev->shmemname, shmemname, RPMSG_NAME_SIZE); + + ret = rptun_initialize(&dev->rptun); + if (ret < 0) + { + _err("ERROR: rptun_initialize failed %d!\n", ret); + goto errout; + } + + /* Create rptun RX thread */ + + ret = kthread_create("nrf53-rptun", CONFIG_RPTUN_PRIORITY, + CONFIG_RPTUN_STACKSIZE, nrf53_rptun_thread, NULL); + if (ret < 0) + { + _err("ERROR: kthread_create failed %d\n", ret); + } + +errout: + return ret; +} diff --git a/arch/arm/src/nrf53/nrf53_rptun.h b/arch/arm/src/nrf53/nrf53_rptun.h new file mode 100644 index 0000000000..db5eecdb3a --- /dev/null +++ b/arch/arm/src/nrf53/nrf53_rptun.h @@ -0,0 +1,61 @@ +/**************************************************************************** + * arch/arm/src/nrf53/nrf53_rptun.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NRF53_NRF53_RPTUN_H +#define __ARCH_ARM_SRC_NRF53_NRF53_RPTUN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: nrf53_rptun_init + ****************************************************************************/ + +int nrf53_rptun_init(const char *shmemname, const char *cpuname); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_NRF53_NRF53_RPTUN_H */