diff --git a/lib/remoteproc/CMakeLists.txt b/lib/remoteproc/CMakeLists.txt index ad7141e..158df1d 100644 --- a/lib/remoteproc/CMakeLists.txt +++ b/lib/remoteproc/CMakeLists.txt @@ -2,4 +2,3 @@ collect (PROJECT_LIB_SOURCES elf_loader.c) collect (PROJECT_LIB_SOURCES remoteproc.c) collect (PROJECT_LIB_SOURCES remoteproc_virtio.c) collect (PROJECT_LIB_SOURCES rsc_table_parser.c) -#add_subdirectory (drivers) diff --git a/lib/remoteproc/drivers/CMakeLists.txt b/lib/remoteproc/drivers/CMakeLists.txt deleted file mode 100644 index 15028ee..0000000 --- a/lib/remoteproc/drivers/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -if ("${MACHINE}" STREQUAL "zynqmp_r5") - collect (PROJECT_LIB_SOURCES zynqmp_remoteproc_a53.c) -endif ("${MACHINE}" STREQUAL "zynqmp_r5") - -if ("${MACHINE}" STREQUAL "zynq7") - collect (PROJECT_LIB_SOURCES zynq_remoteproc_a9.c) - collect (PROJECT_LIB_SOURCES zynq_a9_trampoline.S) -endif ("${MACHINE}" STREQUAL "zynq7") - -if ("${MACHINE}" STREQUAL "zynqmp") - collect (PROJECT_LIB_SOURCES zynqmp_remoteproc_r5.c) -endif ("${MACHINE}" STREQUAL "zynqmp") - -if ("${PROJECT_SYSTEM}" STREQUAL "linux") - collect (PROJECT_LIB_SOURCES linux_remoteproc.c) -endif ("${PROJECT_SYSTEM}" STREQUAL "linux") diff --git a/lib/remoteproc/drivers/linux_remoteproc.c b/lib/remoteproc/drivers/linux_remoteproc.c deleted file mode 100644 index 68bf05c..0000000 --- a/lib/remoteproc/drivers/linux_remoteproc.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2014, Mentor Graphics Corporation - * All rights reserved. - * Copyright (c) 2016 Xilinx, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/************************************************************************** - * FILE NAME - * - * zynqmp_remoteproc_r5.c - * - * DESCRIPTION - * - * This file is the Implementation of IPC hardware layer interface - * for Xilinx Zynq UltraScale+ MPSoC system. - * - **************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_VRING_MEM_SIZE 0x20000 -#define _rproc_wait() metal_cpu_yield() - -#define UNIX_PREFIX "unix:" -#define UNIXS_PREFIX "unixs:" - -struct vring_ipi_info { - /* Socket file path */ - char *path; - int fd; - struct metal_io_region *vring_io; - atomic_int sync; -}; - -/*--------------------------- Declare Functions ------------------------ */ -static int _ipi_handler(int vect_id, void *data); -static int _enable_interrupt(struct proc_intr *intr); -static void _notify(struct hil_proc *proc, struct proc_intr *intr_info); -static int _boot_cpu(struct hil_proc *proc, unsigned int load_addr); -static void _shutdown_cpu(struct hil_proc *proc); -static int _poll(struct hil_proc *proc, int nonblock); -static int _initialize(struct hil_proc *proc); -static void _release(struct hil_proc *proc); -static struct metal_io_region* _alloc_shm(struct hil_proc *proc, - metal_phys_addr_t pa, - size_t size, - struct metal_device **dev); -static void _release_shm(struct hil_proc *proc, - struct metal_device *dev, - struct metal_io_region *io); - - -/*--------------------------- Globals ---------------------------------- */ -struct hil_platform_ops linux_proc_ops = { - .enable_interrupt = _enable_interrupt, - .notify = _notify, - .boot_cpu = _boot_cpu, - .shutdown_cpu = _shutdown_cpu, - .poll = _poll, - .alloc_shm = _alloc_shm, - .release_shm = _release_shm, - .initialize = _initialize, - .release = _release, -}; - -static int sk_unix_client(const char *descr) -{ - struct sockaddr_un addr; - int fd; - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - - memset(&addr, 0, sizeof addr); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, descr + strlen(UNIX_PREFIX), - sizeof addr.sun_path); - if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) >= 0) { - printf("connected to %s\n", descr + strlen(UNIX_PREFIX)); - return fd; - } - - close(fd); - return -1; -} - -static int sk_unix_server(const char *descr) -{ - struct sockaddr_un addr; - int fd, nfd; - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, descr + strlen(UNIXS_PREFIX), - sizeof addr.sun_path); - unlink(addr.sun_path); - if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - goto fail; - } - - listen(fd, 5); - printf("Waiting for connection on %s\n", addr.sun_path); - nfd = accept(fd, NULL, NULL); - close(fd); - return nfd; -fail: - close(fd); - return -1; -} - -static int event_open(const char *descr) -{ - int fd = -1; - int i; - - if (descr == NULL) { - return fd; - } - - if (memcmp(UNIX_PREFIX, descr, strlen(UNIX_PREFIX)) == 0) { - /* UNIX. Retry to connect a few times to give the peer a - * chance to setup. */ - for (i = 0; i < 100 && fd == -1; i++) { - fd = sk_unix_client(descr); - if (fd == -1) - usleep(i * 10 * 1000); - } - } - if (memcmp(UNIXS_PREFIX, descr, strlen(UNIXS_PREFIX)) == 0) { - /* UNIX. */ - fd = sk_unix_server(descr); - } - printf("Open IPI: %s\n", descr); - return fd; -} - -static int _ipi_handler(int vect_id, void *data) -{ - char dummy_buf[32]; - struct proc_intr *intr = data; - struct vring_ipi_info *ipi = intr->data; - - (void) vect_id; - - read(vect_id, dummy_buf, sizeof(dummy_buf)); - atomic_flag_clear(&ipi->sync); - return 0; -} - -static int _enable_interrupt(struct proc_intr *intr) -{ - struct vring_ipi_info *ipi = intr->data; - - ipi->fd = event_open(ipi->path); - if (ipi->fd < 0) { - fprintf(stderr, "ERROR: Failed to open sock %s for IPI.\n", - ipi->path); - return -1; - } - - intr->vect_id = ipi->fd; - - /* Register ISR */ - metal_irq_register(ipi->fd, _ipi_handler, - NULL, intr); - return 0; -} - -static void _notify(struct hil_proc *proc, struct proc_intr *intr_info) -{ - - (void)proc; - struct vring_ipi_info *ipi = (struct vring_ipi_info *)(intr_info->data); - if (ipi == NULL) - return; - - char dummy = 1; - send(ipi->fd, &dummy, 1, MSG_NOSIGNAL); -} - -static int _boot_cpu(struct hil_proc *proc, unsigned int load_addr) -{ - (void)proc; - (void)load_addr; - return -1; -} - -static void _shutdown_cpu(struct hil_proc *proc) -{ - (void)proc; - return; -} - -static struct metal_io_region* _alloc_shm(struct hil_proc *proc, - metal_phys_addr_t pa, - size_t size, - struct metal_device **dev) -{ - (void)proc; - (void)pa; - (void)size; - - *dev = NULL; - return NULL; - -} - -static void _release_shm(struct hil_proc *proc, - struct metal_device *dev, - struct metal_io_region *io) -{ - (void)proc; - (void)io; - hil_close_generic_mem_dev(dev); -} - -static int _poll(struct hil_proc *proc, int nonblock) -{ - (void) nonblock; - struct proc_vring *vring; - struct vring_ipi_info *ipi; - unsigned int flags; - - int num_vrings = proc->vdev.num_vrings; - int ret = 0; - int notified; - int i; - - metal_assert(proc); - - notified = 0; - while (1) { - for (i = 0; i < num_vrings; i++) { - vring = &proc->vdev.vring_info[i]; - ipi = (struct vring_ipi_info *)(vring->intr_info.data); - flags = metal_irq_save_disable(); - if (!(atomic_flag_test_and_set(&ipi->sync))) { - metal_irq_restore_enable(flags); - virtqueue_notification(vring->vq); - notified = 1; - } else { - metal_irq_restore_enable(flags); - } - } - if (notified) - return 0; - if (nonblock) - return -EAGAIN; - _rproc_wait(); - } - return ret; -} - -/** - * @brief _adjust_vring_io - Adjust the vring I/O region to map to the - * specified start device address. - * @param[in] io - vring I/O region - * @param[in] start_phy - start device address of the vring, this is - * not the actual physical address. - * @return adjusted I/O region - */ -static struct metal_io_region *_create_vring_io(struct metal_io_region *in_io, - int start_phy) -{ - struct metal_io_region *io = 0; - metal_phys_addr_t *phys; - io = metal_allocate_memory(sizeof(struct metal_io_region)); - if (!io) { - fprintf(stderr, "ERROR: Failed to allocation I/O for vring.\n"); - return NULL; - } - phys = metal_allocate_memory(sizeof(metal_phys_addr_t)); - if (!phys) { - fprintf(stderr, "ERROR: Failed to allocation phys for vring.\n"); - metal_free_memory(io); - return NULL; - } - *phys = (metal_phys_addr_t)start_phy; - metal_io_init(io, in_io->virt, phys, in_io->size, - sizeof(metal_phys_addr_t)*8 - 1, 0, NULL); - return io; -} - -static int _initialize(struct hil_proc *proc) -{ - struct proc_vring *vring; - struct vring_ipi_info *ipi; - struct metal_io_region *io; - int i; - if (proc) { - for (i = 0; i < 2; i++) { - vring = &proc->vdev.vring_info[i]; - ipi = (struct vring_ipi_info *)vring->intr_info.data; - if (ipi && !ipi->vring_io && vring->io) { - io = _create_vring_io(vring->io, 0); - if (!io) - return -1; - ipi->vring_io = vring->io; - vring->io = io; - atomic_store(&ipi->sync, 1); - } - } - } - return 0; -} - -static void _release(struct hil_proc *proc) -{ - struct proc_vring *vring; - struct vring_ipi_info *ipi; - int i; - if (proc) { - for (i = 0; i < 2; i++) { - vring = &proc->vdev.vring_info[i]; - ipi = (struct vring_ipi_info *)vring->intr_info.data; - if (ipi) { - if (ipi->fd >= 0) { - metal_irq_unregister(ipi->fd, 0, NULL, - vring); - close(ipi->fd); - } - if (ipi->vring_io) { - metal_free_memory(vring->io->physmap); - metal_free_memory(vring->io); - vring->io = NULL; - if (ipi->vring_io->ops.close) - ipi->vring_io->ops.close(ipi->vring_io); - ipi->vring_io = NULL; - } - } - } - } -} - diff --git a/lib/remoteproc/drivers/zynq_a9_trampoline.S b/lib/remoteproc/drivers/zynq_a9_trampoline.S deleted file mode 100644 index 404fba3..0000000 --- a/lib/remoteproc/drivers/zynq_a9_trampoline.S +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2014, Mentor Graphics Corporation - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -.global zynq_trampoline -zynq_trampoline: - ldr r0, [pc] - bx r0 -.global zynq_trampoline_jump -zynq_trampoline_jump: - .word -.global zynq_trampoline_end -zynq_trampoline_end: diff --git a/lib/remoteproc/drivers/zynq_remoteproc_a9.c b/lib/remoteproc/drivers/zynq_remoteproc_a9.c deleted file mode 100644 index 9f7620f..0000000 --- a/lib/remoteproc/drivers/zynq_remoteproc_a9.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2014, Mentor Graphics Corporation - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/************************************************************************** - * FILE NAME - * - * platform.c - * - * DESCRIPTION - * - * This file is the Implementation of IPC hardware layer interface - * for Xilinx Zynq ZC702EVK platform. - * - **************************************************************************/ - -#include -#include -#include -#include -#include -#include - -/* ------------------------- Macros --------------------------*/ -#define SCUGIC_PERIPH_BASE 0xF8F00000 -#define SCUGIC_DIST_BASE (SCUGIC_PERIPH_BASE + 0x00001000) -#define ESAL_DP_SLCR_BASE 0xF8000000 -#define GIC_DIST_SOFTINT 0xF00 -#define GIC_SFI_TRIG_CPU_MASK 0x00FF0000 -#define GIC_SFI_TRIG_SATT_MASK 0x00008000 -#define GIC_SFI_TRIG_INTID_MASK 0x0000000F -#define GIC_CPU_ID_BASE (1 << 4) -#define A9_CPU_SLCR_RESET_CTRL 0x244 -#define A9_CPU_SLCR_CLK_STOP (1 << 4) -#define A9_CPU_SLCR_RST (1 << 0) - -#define unlock_slcr() HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + 0x08, 0xDF0DDF0D) -#define lock_slcr() HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + 0x04, 0x767B767B) - -/* L2Cpl310 L2 cache controller base address. */ -#define HIL_PL130_BASE 0xF8F02000 - -/********************/ -/* Register offsets */ -/********************/ - -#define HIL_PL130_INVALLINE 0x770 -#define HIL_PL130_CLEANINVLINE 0x7F0 - - -#define HIL_PA_SBZ_MASK ~(HIL_CACHE_LINE_SIZE - 1UL) -#define HIL_CACHE_LINE_SIZE 32 -#define HIL_CACHE_INV_ALL_WAYS 0xFF -#define HIL_CACHE_UNLOCK_ALL_WAYS 0xFFFF0000 -#define HIL_CACHE_CLEAR_INT 0x1FF - -/* Memory attributes */ -#define NORM_NONCACHE 0x11DE2 /* Normal Non-cacheable */ -#define STRONG_ORDERED 0xC02 /* Strongly ordered */ -#define DEVICE_MEMORY 0xC06 /* Device memory */ -#define RESERVED 0x0 /* reserved memory */ - -#define HIL_DEV_NAME_PREFIX "hil-dev." - -#define _rproc_wait() asm volatile("wfi") - -/*--------------------------- Declare Functions ------------------------ */ -static int _enable_interrupt(struct proc_intr *intr); -static void _notify(struct hil_proc *proc, struct proc_intr *intr_info); -static int _boot_cpu(struct hil_proc *proc, unsigned int load_addr); -static void _shutdown_cpu(struct hil_proc *proc); -static int _poll(struct hil_proc *proc, int nonblock); -static int _initialize(struct hil_proc *proc); -static void _release(struct hil_proc *proc); -static int _ipi_handler(int vect_id, void *data); -static struct metal_io_region* _alloc_shm(struct hil_proc *proc, - metal_phys_addr_t pa, - size_t size, - struct metal_device **dev); -static void _release_shm(struct hil_proc *proc, - struct metal_device *dev, - struct metal_io_region *io); - -/*--------------------------- Globals ---------------------------------- */ -struct hil_platform_ops zynq_a9_proc_ops = { - .enable_interrupt = _enable_interrupt, - .notify = _notify, - .boot_cpu = _boot_cpu, - .shutdown_cpu = _shutdown_cpu, - .poll = _poll, - .alloc_shm = _alloc_shm, - .release_shm = _release_shm, - .initialize = _initialize, - .release = _release, -}; - -struct hil_mem_device { - struct metal_device device; - char name[64]; - metal_phys_addr_t pa; -}; - -static metal_phys_addr_t git_dist_base_addr = SCUGIC_DIST_BASE; -static struct metal_io_region gic_dist_io = { - (void *)SCUGIC_DIST_BASE, - &git_dist_base_addr, - 0x1000, - (sizeof(metal_phys_addr_t) << 3), - (metal_phys_addr_t)(-1), - 0, - {NULL}, -}; - -//volatile unsigned int ipi_counter = 0; -//volatile unsigned int enableirq_counter = 0; - -int _ipi_handler(int vect_id, void *data) -{ - struct proc_intr *intr_info = data; - - (void) vect_id; - - atomic_flag_clear((atomic_uint *)&(intr_info->data)); - - //ipi_counter++; - return 0; -} - -static int _enable_interrupt(struct proc_intr *intr) -{ - //enableirq_counter++; - /* Register ISR */ - metal_irq_register(intr->vect_id, _ipi_handler, - intr->dev, intr); - - /* Enable the interrupts */ - metal_irq_enable(intr->vect_id); - - /* FIXME: This is a workaround for Zynq. As Linux is possible - * to have already generate the soft IRQ - */ - atomic_flag_clear((atomic_uint *)&(intr->data)); - return 0; -} - -static void _notify(struct hil_proc *proc, struct proc_intr *intr_info) -{ - unsigned long mask = 0; - - mask = ((1 << (GIC_CPU_ID_BASE + proc->cpu_id)) | (intr_info->vect_id)) - & (GIC_SFI_TRIG_CPU_MASK | GIC_SFI_TRIG_INTID_MASK); - - /* Trigger IPI */ - metal_io_write32(&gic_dist_io, GIC_DIST_SOFTINT, mask); -} - -static int _poll(struct hil_proc *proc, int nonblock) -{ - struct proc_vring *vring; - unsigned int flags; - struct proc_intr *intr_info; - int i = 0; - int kicked = 0; - - while(1) { - vring = &proc->vdev.vring_info[i]; - intr_info = &(vring->intr_info); - flags = metal_irq_save_disable(); - if (!(atomic_flag_test_and_set( - (atomic_uint *)&(intr_info->data)))) { - metal_irq_restore_enable(flags); - virtqueue_notification(vring->vq); - kicked = 1; - if (i) - return 0; - i++; - } else if (!i) { - metal_irq_restore_enable(flags); - i++; - } else { - if (kicked) { - metal_irq_restore_enable(flags); - return 0; - } else if (nonblock) { - metal_irq_restore_enable(flags); - return -EAGAIN; - } else { - _rproc_wait(); - metal_irq_restore_enable(flags); - i--; - continue; - } - } - } -} - -extern char zynq_trampoline; -extern char zynq_trampoline_jump; -extern char zynq_trampoline_end; - -static int _boot_cpu(struct hil_proc *proc, unsigned int load_addr) -{ - /* FIXME: Will need to add the boot_cpu implementation back */ -#if 0 - unsigned int reg; - unsigned int tramp_size; - unsigned int tramp_addr = 0; - - if (load_addr) { - tramp_size = zynq_trampoline_end - zynq_trampoline; - if ((load_addr < tramp_size) || (load_addr & 0x3)) { - return -1; - } - - tramp_size = &zynq_trampoline_jump - &zynq_trampoline; - - /* - * Trampoline code is copied to address 0 from where remote core is expected to - * fetch first instruction after reset.If master is using the address 0 then - * this mem copy will screwed the system. It is user responsibility to not - * copy trampoline code in such cases. - * - */ - memcpy((char *)tramp_addr, &zynq_trampoline, tramp_size); - /* Write image address at the word reserved at the trampoline end */ - HIL_MEM_WRITE32((char *)(tramp_addr + tramp_size), load_addr); - } - - unlock_slcr(); - - reg = HIL_MEM_READ32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL); - reg &= ~(A9_CPU_SLCR_CLK_STOP << cpu_id); - HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg); - /* De-assert reset signal and start clock to start the core */ - reg &= ~(A9_CPU_SLCR_RST << cpu_id); - HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg); - - lock_slcr(); - -#else - (void)proc; - (void)load_addr; -#endif - return 0; -} - -static void _shutdown_cpu(struct hil_proc *proc) -{ - /* FIXME: Will need to add the shutdown CPU implementation back */ -#if 0 - unsigned int reg; - - unlock_slcr(); - - reg = HIL_MEM_READ32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL); - /* Assert reset signal and stop clock to halt the core */ - reg |= (A9_CPU_SLCR_CLK_STOP | A9_CPU_SLCR_RST) << cpu_id; - HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg); - - lock_slcr(); -#else - (void)proc; -#endif -} - -static struct metal_io_region* _alloc_shm(struct hil_proc *proc, - metal_phys_addr_t pa, - size_t size, - struct metal_device **dev) -{ - (void)proc; - - *dev = hil_create_generic_mem_dev(pa, size, - NORM_NONCACHE | STRONG_ORDERED); - if ((*dev)) - return &((*dev)->regions[0]); - - return NULL; - -} - -static void _release_shm(struct hil_proc *proc, - struct metal_device *dev, - struct metal_io_region *io) -{ - (void)proc; - (void)io; - hil_close_generic_mem_dev(dev); -} - -static int _initialize(struct hil_proc *proc) -{ - int i; - struct proc_intr *intr_info; - - for (i = 0; i < 2; i++) { - intr_info = &(proc->vdev.vring_info[i].intr_info); - atomic_store((atomic_uint *)&(intr_info->data), 1); - } - - return 0; -} - -static void _release(struct hil_proc *proc) -{ - (void)proc; - return; -} - diff --git a/lib/remoteproc/drivers/zynqmp_remoteproc_a53.c b/lib/remoteproc/drivers/zynqmp_remoteproc_a53.c deleted file mode 100644 index cb2bd82..0000000 --- a/lib/remoteproc/drivers/zynqmp_remoteproc_a53.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2014, Mentor Graphics Corporation - * All rights reserved. - * Copyright (c) 2015 Xilinx, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/************************************************************************** - * FILE NAME - * - * platform.c - * - * DESCRIPTION - * - * This file is the Implementation of IPC hardware layer interface - * for Xilinx Zynq ZC702EVK platform. - * - **************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* IPI REGs OFFSET */ -#define IPI_TRIG_OFFSET 0x00000000 /* IPI trigger register offset */ -#define IPI_OBS_OFFSET 0x00000004 /* IPI observation register offset */ -#define IPI_ISR_OFFSET 0x00000010 /* IPI interrupt status register offset */ -#define IPI_IMR_OFFSET 0x00000014 /* IPI interrupt mask register offset */ -#define IPI_IER_OFFSET 0x00000018 /* IPI interrupt enable register offset */ -#define IPI_IDR_OFFSET 0x0000001C /* IPI interrupt disable register offset */ - -/* memory attributes */ -#define DEVICE_SHARED 0x00000001U /*device, shareable*/ -#define DEVICE_NONSHARED 0x00000010U /*device, non shareable*/ -#define NORM_NSHARED_NCACHE 0x00000008U /* Non cacheable non shareable */ -#define NORM_SHARED_NCACHE 0x0000000CU /* Non cacheable shareable */ -#define PRIV_RW_USER_RW (0x00000003U<<8U) /*Full Access*/ - -#define _rproc_wait() asm volatile("wfi") - -/* -- FIX ME: ipi info is to be defined -- */ -struct ipi_info { - const char *name; - const char *bus_name; - struct metal_device *dev; - struct metal_io_region *io; - metal_phys_addr_t paddr; - uint32_t ipi_chn_mask; - int registered; - atomic_int sync; -}; - -/*--------------------------- Declare Functions ------------------------ */ -static int _enable_interrupt(struct proc_intr *intr); -static void _notify(struct hil_proc *proc, struct proc_intr *intr_info); -static int _boot_cpu(struct hil_proc *proc, unsigned int load_addr); -static void _shutdown_cpu(struct hil_proc *proc); -static int _poll(struct hil_proc *proc, int nonblock); -static int _initialize(struct hil_proc *proc); -static void _release(struct hil_proc *proc); - -static int _ipi_handler(int vect_id, void *data); -static struct metal_io_region* _alloc_shm(struct hil_proc *proc, - metal_phys_addr_t pa, - size_t size, - struct metal_device **dev); -static void _release_shm(struct hil_proc *proc, - struct metal_device *dev, - struct metal_io_region *io); - -/*--------------------------- Globals ---------------------------------- */ -struct hil_platform_ops zynqmp_r5_a53_proc_ops = { - .enable_interrupt = _enable_interrupt, - .notify = _notify, - .boot_cpu = _boot_cpu, - .shutdown_cpu = _shutdown_cpu, - .poll = _poll, - .alloc_shm = _alloc_shm, - .release_shm = _release_shm, - .initialize = _initialize, - .release = _release, -}; - -int _ipi_handler(int vect_id, void *data) -{ - struct proc_intr *intr = data; - struct ipi_info *ipi = intr->data; - struct metal_io_region *io = ipi->io; - unsigned int ipi_intr_status = - (unsigned int)metal_io_read32(io, IPI_ISR_OFFSET); - - (void) vect_id; - - if (ipi_intr_status & ipi->ipi_chn_mask) { - atomic_flag_clear(&ipi->sync); - metal_io_write32(io, IPI_ISR_OFFSET, - ipi->ipi_chn_mask); - return 0; - } - return -1; -} - -static int _enable_interrupt(struct proc_intr *intr) -{ - struct ipi_info *ipi = - (struct ipi_info *)(intr->data); - struct metal_io_region *io = ipi->io; - - if (ipi->registered) { - return 0; - } - - /* Register ISR */ - metal_irq_register(intr->vect_id, _ipi_handler, - intr->dev, intr); - /* Enable IPI interrupt */ - metal_irq_enable(intr->vect_id); - metal_io_write32(io, IPI_IER_OFFSET, ipi->ipi_chn_mask); - ipi->registered = 1; - - return 0; -} - -static void _notify(struct hil_proc *proc, struct proc_intr *intr_info) -{ - - (void)proc; - struct ipi_info *ipi = (struct ipi_info *)(intr_info->data); - if (ipi == NULL) - return; - - /* Trigger IPI */ - metal_io_write32(ipi->io, IPI_TRIG_OFFSET, ipi->ipi_chn_mask); -} - -static int _boot_cpu(struct hil_proc *proc, unsigned int load_addr) -{ - (void)proc; - (void)load_addr; - return -1; -} - -static void _shutdown_cpu(struct hil_proc *proc) -{ - (void)proc; - return; -} - -static int _poll(struct hil_proc *proc, int nonblock) -{ - struct proc_vdev *vdev; - struct ipi_info *ipi; - unsigned int flags; - - vdev = &proc->vdev; - ipi = (struct ipi_info *)(vdev->intr_info.data); - while(1) { - flags = metal_irq_save_disable(); - if (!(atomic_flag_test_and_set(&ipi->sync))) { - metal_irq_restore_enable(flags); - hil_notified(proc, (uint32_t)(-1)); - return 0; - } - if (nonblock) { - metal_irq_restore_enable(flags); - return -EAGAIN; - } - _rproc_wait(); - metal_irq_restore_enable(flags); - } -} - -static struct metal_io_region* _alloc_shm(struct hil_proc *proc, - metal_phys_addr_t pa, - size_t size, - struct metal_device **dev) -{ - (void)proc; - - *dev = hil_create_generic_mem_dev(pa, size, - NORM_SHARED_NCACHE | PRIV_RW_USER_RW); - if ((*dev)) - return &((*dev)->regions[0]); - - return NULL; - -} - -static void _release_shm(struct hil_proc *proc, - struct metal_device *dev, - struct metal_io_region *io) -{ - (void)proc; - (void)io; - hil_close_generic_mem_dev(dev); -} - -static int _initialize(struct hil_proc *proc) -{ - int ret; - struct proc_intr *intr_info; - struct ipi_info *ipi; - - if (!proc) - return -1; - - intr_info = &(proc->vdev.intr_info); - ipi = intr_info->data; - - if (ipi && ipi->name && ipi->bus_name) { - ret = metal_device_open(ipi->bus_name, ipi->name, - &ipi->dev); - if (ret) - return -ENODEV; - ipi->io = metal_device_io_region(ipi->dev, 0); - } else if (ipi->paddr) { - ipi->io = metal_allocate_memory( - sizeof(struct metal_io_region)); - if (!ipi->io) - goto error; - metal_io_init(ipi->io, (void *)ipi->paddr, - &ipi->paddr, 0x1000, - sizeof(metal_phys_addr_t) << 3, - 0, - NULL); - } - - if (ipi->io) { - metal_io_write32(ipi->io, IPI_IDR_OFFSET, - ipi->ipi_chn_mask); - atomic_store(&ipi->sync, 1); - } - ipi->registered = 0; - return 0; - -error: - _release(proc); - return -1; -} - -static void _release(struct hil_proc *proc) -{ - struct proc_intr *intr_info; - struct ipi_info *ipi; - - if (!proc) - return; - intr_info = &(proc->vdev.intr_info); - ipi = (struct ipi_info *)(intr_info->data); - if (ipi) { - if (ipi->io) { - metal_io_write32(ipi->io, IPI_IDR_OFFSET, - ipi->ipi_chn_mask); - if (ipi->dev) { - metal_device_close(ipi->dev); - ipi->dev = NULL; - } else { - metal_free_memory(ipi->io); - } - ipi->io = NULL; - } - } - -} - diff --git a/lib/remoteproc/drivers/zynqmp_remoteproc_r5.c b/lib/remoteproc/drivers/zynqmp_remoteproc_r5.c deleted file mode 100644 index b432688..0000000 --- a/lib/remoteproc/drivers/zynqmp_remoteproc_r5.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2014, Mentor Graphics Corporation - * All rights reserved. - * Copyright (c) 2015 Xilinx, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/************************************************************************** - * FILE NAME - * - * zynqmp_remoteproc_r5.c - * - * DESCRIPTION - * - * This file is the Implementation of IPC hardware layer interface - * for Xilinx Zynq UltraScale+ MPSoC system. - * - **************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* IPI REGs OFFSET */ -#define IPI_TRIG_OFFSET 0x00000000 /** IPI trigger register offset */ -#define IPI_OBS_OFFSET 0x00000004 /** IPI observation register offset */ -#define IPI_ISR_OFFSET 0x00000010 /* IPI interrupt status register offset */ -#define IPI_IMR_OFFSET 0x00000014 /* IPI interrupt mask register offset */ -#define IPI_IER_OFFSET 0x00000018 /* IPI interrupt enable register offset */ -#define IPI_IDR_OFFSET 0x0000001C /* IPI interrupt disable register offset */ - -#define _rproc_wait() metal_cpu_yield() - -/* -- FIX ME: ipi info is to be defined -- */ -struct ipi_info { - const char *name; - const char *bus_name; - struct metal_device *dev; - struct metal_io_region *io; - metal_phys_addr_t paddr; - uint32_t ipi_chn_mask; - atomic_int sync; -}; - -/*--------------------------- Declare Functions ------------------------ */ -static int _enable_interrupt(struct proc_intr *intr); -static void _notify(struct hil_proc *proc, struct proc_intr *intr_info); -static int _boot_cpu(struct hil_proc *proc, unsigned int load_addr); -static void _shutdown_cpu(struct hil_proc *proc); -static int _poll(struct hil_proc *proc, int nonblock); -static int _initialize(struct hil_proc *proc); -static void _release(struct hil_proc *proc); -static struct metal_io_region* _alloc_shm(struct hil_proc *proc, - metal_phys_addr_t pa, - size_t size, - struct metal_device **dev); -static void _release_shm(struct hil_proc *proc, - struct metal_device *dev, - struct metal_io_region *io); - -/*--------------------------- Globals ---------------------------------- */ -struct hil_platform_ops zynqmp_a53_r5_proc_ops = { - .enable_interrupt = _enable_interrupt, - .notify = _notify, - .boot_cpu = _boot_cpu, - .shutdown_cpu = _shutdown_cpu, - .poll = _poll, - .alloc_shm = _alloc_shm, - .release_shm = _release_shm, - .initialize = _initialize, - .release = _release, -}; - -static int _enable_interrupt(struct proc_intr *intr) -{ - (void)intr; - return 0; -} - -static void _notify(struct hil_proc *proc, struct proc_intr *intr_info) -{ - - (void)proc; - struct ipi_info *ipi = (struct ipi_info *)(intr_info->data); - if (ipi == NULL) - return; - - /* Trigger IPI */ - metal_io_write32(ipi->io, IPI_TRIG_OFFSET, ipi->ipi_chn_mask); -} - -static int _boot_cpu(struct hil_proc *proc, unsigned int load_addr) -{ - (void)proc; - (void)load_addr; - return -1; -} - -static void _shutdown_cpu(struct hil_proc *proc) -{ - (void)proc; - return; -} - -static int _poll(struct hil_proc *proc, int nonblock) -{ - struct proc_vdev *vdev; - struct ipi_info *ipi; - struct metal_io_region *io; - - vdev = &proc->vdev; - ipi = (struct ipi_info *)(vdev->intr_info.data); - io = ipi->io; - while(1) { - unsigned int ipi_intr_status = - (unsigned int)metal_io_read32(io, IPI_ISR_OFFSET); - if (ipi_intr_status & ipi->ipi_chn_mask) { - metal_io_write32(io, IPI_ISR_OFFSET, - ipi->ipi_chn_mask); - hil_notified(proc, (uint32_t)(-1)); - return 0; - } else if (nonblock) { - return -EAGAIN; - } - _rproc_wait(); - } -} - -static struct metal_io_region* _alloc_shm(struct hil_proc *proc, - metal_phys_addr_t pa, - size_t size, - struct metal_device **dev) -{ - (void)proc; - (void)pa; - (void)size; - - *dev = NULL; - return NULL; - -} - -static void _release_shm(struct hil_proc *proc, - struct metal_device *dev, - struct metal_io_region *io) -{ - (void)proc; - (void)io; - hil_close_generic_mem_dev(dev); -} - -static int _initialize(struct hil_proc *proc) -{ - int ret; - struct proc_intr *intr_info; - struct ipi_info *ipi; - unsigned int ipi_intr_status; - - if (!proc) - return -1; - - intr_info = &(proc->vdev.intr_info); - ipi = intr_info->data; - - if (ipi && ipi->name && ipi->bus_name) { - ret = metal_device_open(ipi->bus_name, ipi->name, - &ipi->dev); - if (ret) - return -ENODEV; - ipi->io = metal_device_io_region(ipi->dev, 0); - intr_info->vect_id = (uintptr_t)ipi->dev->irq_info; - } else if (ipi->paddr) { - ipi->io = metal_allocate_memory( - sizeof(struct metal_io_region)); - if (!ipi->io) - goto error; - metal_io_init(ipi->io, (void *)ipi->paddr, - &ipi->paddr, 0x1000, - (unsigned)(-1), - 0, - NULL); - } - - if (ipi->io) { - ipi_intr_status = (unsigned int)metal_io_read32( - ipi->io, IPI_ISR_OFFSET); - if (ipi_intr_status & ipi->ipi_chn_mask) - metal_io_write32(ipi->io, IPI_ISR_OFFSET, - ipi->ipi_chn_mask); - metal_io_write32(ipi->io, IPI_IDR_OFFSET, - ipi->ipi_chn_mask); - atomic_store(&ipi->sync, 1); - } - - return 0; - -error: - _release(proc); - return -1; -} - -static void _release(struct hil_proc *proc) -{ - struct proc_intr *intr_info; - struct ipi_info *ipi; - - if (!proc) - return; - intr_info = &(proc->vdev.intr_info); - ipi = (struct ipi_info *)(intr_info->data); - if (ipi) { - if (ipi->io) { - metal_io_write32(ipi->io, IPI_IDR_OFFSET, - ipi->ipi_chn_mask); - if (ipi->dev) { - metal_device_close(ipi->dev); - ipi->dev = NULL; - } else { - metal_free_memory(ipi->io); - } - ipi->io = NULL; - } - - } -} - -