diff options
Diffstat (limited to 'middleware/multicore/open-amp/porting/imx7d_m4')
-rw-r--r-- | middleware/multicore/open-amp/porting/imx7d_m4/platform.c | 273 | ||||
-rw-r--r-- | middleware/multicore/open-amp/porting/imx7d_m4/platform.h | 45 | ||||
-rw-r--r-- | middleware/multicore/open-amp/porting/imx7d_m4/platform_info.c | 50 | ||||
-rw-r--r-- | middleware/multicore/open-amp/porting/imx7d_m4/rpmsg_platform_porting.h (renamed from middleware/multicore/open-amp/porting/imx7d_m4/plat_porting.h) | 24 |
4 files changed, 308 insertions, 84 deletions
diff --git a/middleware/multicore/open-amp/porting/imx7d_m4/platform.c b/middleware/multicore/open-amp/porting/imx7d_m4/platform.c index 6b1fc8f..c682fc6 100644 --- a/middleware/multicore/open-amp/porting/imx7d_m4/platform.c +++ b/middleware/multicore/open-amp/porting/imx7d_m4/platform.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2015, Freescale Corporation - * All rights reserved. + * Copyright (c) 2015 Freescale Semiconductor, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -10,7 +9,7 @@ * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * 3. Neither the name of Mentor Graphics Corporation nor the names of its + * 3. Neither the name of Freescale Semiconductor nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * @@ -35,81 +34,285 @@ * DESCRIPTION * * This file is the Implementation of IPC hardware layer interface - * for Freescale i.MX7 Dual platform. + * for Freescale i.MX 7Dual platform. * **************************************************************************/ -#include "device_imx.h" +#include <assert.h> #include "platform.h" -#include "plat_porting.h" #include "mu_imx.h" +#include "common/hil/hil.h" +#include "porting/env/env.h" -extern void freertos_env_isr(int vector); +static int _enable_interrupt(struct proc_vring *vring_hw) +{ + /* Register ISR*/ + env_register_isr(vring_hw->intr_info.vect_id, vring_hw, platform_isr); + + /* Prepare the MU Hardware, enable channel 1 interrupt */ + MU_EnableRxFullInt(MUB, RPMSG_MU_CHANNEL); + + return 0; +} + +static void _notify(int cpu_id, struct proc_intr *intr_info) +{ + /* As Linux suggests, use MU->Data Channle 1 as communication channel */ + uint32_t msg = (intr_info->vect_id) << 16; + MU_SendMsg(MUB, RPMSG_MU_CHANNEL, msg); +} + +static int _boot_cpu(int cpu_id, unsigned int load_addr) +{ + /* not imlemented */ + assert(0); + return 0; +} -// uint32_t channel_id; -/*--------------------------- Globals ---------------------------------- */ +static void _shutdown_cpu(int cpu_id) +{ + /* not imlemented */ + assert(0); +} struct hil_platform_ops proc_ops = { - .enable_interrupt = _enable_interrupt, + .enable_interrupt = _enable_interrupt, .notify = _notify, .boot_cpu = _boot_cpu, .shutdown_cpu = _shutdown_cpu, }; +/** + * rpmsg_handler + * + * Called directly from ISR. Convert IRQ number to channel + * number and invoke 'env_isr'. + * + */ void rpmsg_handler(void) { uint32_t msg, channel; - if (MU_TryReceiveMsg(MU0_B, MU_RPMSG_CHANNEL, &msg) == kStatus_MU_Success) { + if (MU_TryReceiveMsg(MUB, RPMSG_MU_CHANNEL, &msg) == kStatus_MU_Success) + { channel = msg >> 16; - freertos_env_isr(channel); + env_isr(channel); } return; } -int _enable_interrupt(struct proc_vring *vring_hw) { /*enable_interrupt*/ - /* Register ISR*/ - env_register_isr(vring_hw->intr_info.vect_id, vring_hw, platform_isr); +#define PLATFORM_DISABLE_COUNTERS 2 +static int disable_counters[PLATFORM_DISABLE_COUNTERS] = {0}; +static int disable_counter_all = 0; - /* - * Prepare the MU Hardware, enable channel 1 interrupt - */ - MU_EnableRxFullInt(MU0_B, MU_RPMSG_CHANNEL); +/** + * platform_time_delay + * + * @param num_msec - delay time in ms. + * + * This is not an accurate delay, it ensures at least num_msec passed when return. + */ +void platform_time_delay(int num_msec) +{ + uint32_t loop; - return 0; + /* Recalculate the CPU frequency */ + SystemCoreClockUpdate(); + + /* Calculate the CPU loops to delay, each loop has 3 cycles */ + loop = SystemCoreClock / 3 / 1000 * num_msec; + + /* There's some difference among toolchains, 3 or 4 cycles each loop */ + while (loop) + { + __NOP(); + loop--; + } } -void _notify(int cpu_id, struct proc_intr *intr_info) +/** + * platform_isr + * + * RPMSG platform IRQ callback + * + */ +void platform_isr(int vect_id, void *data) { - /* - * As Linux suggests, use MU->Data Channle 1 as communication channel - */ - uint32_t msg = (intr_info->vect_id) << 16; - MU_SendMsg(MU0_B, MU_RPMSG_CHANNEL, msg); + hil_isr(((struct proc_vring *) data)); } +/** + * platform_in_isr + * + * Return whether CPU is processing IRQ + * + * @return - true for IRQ, false otherwise. + * + */ +int platform_in_isr(void) +{ + return ((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0); +} -int _boot_cpu(int cpu_id, unsigned int load_addr) +/** + * platform_interrupt_enable + * + * Enable peripheral-related interrupt with passed priority and type. + * + * @param vector_id - vector ID that need to be converted to IRQ number + * @param trigger_type - IRQ active level + * @param trigger_type - IRQ priority + * + * @return - vector_id. Return value is never checked.. + * + */ +int platform_interrupt_enable(unsigned int vector_id, unsigned int trigger_type, + unsigned int priority) { - return 0; + assert(vector_id < PLATFORM_DISABLE_COUNTERS); + assert(0 < disable_counters[vector_id]); + disable_counters[vector_id]--; + // channels use the same NVIC vector + // enable only if all counters are zero + for (int i = 0; i < PLATFORM_DISABLE_COUNTERS; i++) + { + if (disable_counters[i]) + return (vector_id); + } + NVIC_EnableIRQ(MU_M4_IRQn); + return (vector_id); +} + +/** + * platform_interrupt_disable + * + * Disable peripheral-related interrupt. + * + * @param vector_id - vector ID that need to be converted to IRQ number + * + * @return - vector_id. Return value is never checked. + * + */ +int platform_interrupt_disable(unsigned int vector_id) +{ + assert(vector_id < PLATFORM_DISABLE_COUNTERS); + assert(0 <= disable_counters[vector_id]); + int disabled = 0; + // channels use the same NVIC vector + // if one counter is set - the interrupts are disabled + for (int i = 0; i < PLATFORM_DISABLE_COUNTERS; i++) + { + if (disable_counters[i]) + { + disabled = 1; + break; + } + } + // if not disabled - disable interrutps + if (!disabled) + NVIC_DisableIRQ(MU_M4_IRQn); + disable_counters[vector_id]++; + return (vector_id); } -void _shutdown_cpu(int cpu_id) +/** + * platform_interrupt_enable_all + * + * Enable all platform-related interrupts. + * + */ +void platform_interrupt_enable_all(void) { + assert(0 < disable_counter_all); + disable_counter_all--; + if (0 == disable_counter_all) + platform_interrupt_enable(0, 0, 0); } -void platform_isr(int vect_id, void *data) +/** + * platform_interrupt_disable_all + * + * Enable all platform-related interrupts. + * + */ +void platform_interrupt_disable_all(void) { - hil_isr(((struct proc_vring *) data)); + assert(0 <= disable_counter_all); + if (0 == disable_counter_all) + platform_interrupt_disable(0); + disable_counter_all++; } -void platform_interrupt_enable() +/** + * platform_map_mem_region + * + * Dummy implementation + * + */ +void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, + unsigned int size, unsigned int flags) { - NVIC_EnableIRQ(MU_INT_M4_IRQn); } -void platform_interrupt_disable() +/** + * platform_cache_all_flush_invalidate + * + * Dummy implementation + * + */ +void platform_cache_all_flush_invalidate() { - NVIC_DisableIRQ(MU_INT_M4_IRQn); +} + +/** + * platform_cache_disable + * + * Dummy implementation + * + */ +void platform_cache_disable() +{ +} + +/** + * platform_vatopa + * + * Dummy implementation + * + */ +unsigned long platform_vatopa(void *addr) +{ + return ((unsigned long)addr); +} + +/** + * platform_patova + * + * Dummy implementation + * + */ +void *platform_patova(unsigned long addr) +{ + return ((void *)addr); +} + +/** + * platform_init + * + * platform/environment init + */ +int platform_init(void) +{ + return 0; +} + +/** + * platform_deinit + * + * platform/environment deinit process + */ +int platform_deinit(void) +{ + return 0; } diff --git a/middleware/multicore/open-amp/porting/imx7d_m4/platform.h b/middleware/multicore/open-amp/porting/imx7d_m4/platform.h index 14a92cc..53bed56 100644 --- a/middleware/multicore/open-amp/porting/imx7d_m4/platform.h +++ b/middleware/multicore/open-amp/porting/imx7d_m4/platform.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2014, Mentor Graphics Corporation - * All rights reserved. + * Copyright (c) 2015 Freescale Semiconductor, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -10,7 +9,7 @@ * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * 3. Neither the name of Mentor Graphics Corporation nor the names of its + * 3. Neither the name of Freescale Semiconductor nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * @@ -27,15 +26,45 @@ * POSSIBILITY OF SUCH DAMAGE. */ +/************************************************************************** + * FILE NAME + * + * platform.h + * + * COMPONENT + * + * OpenAMP + * + * DESCRIPTION + * + * This file provides function prototypes of platform.c. + * + **************************************************************************/ + #ifndef PLATFORM_H_ #define PLATFORM_H_ -#include "../../common/hil/hil.h" +/* + * 32 MSG (16 rx, 16 tx), 512 bytes each, it is only used when RPMSG driver is working in master mode, otherwise + * the share memory is managed by the other side. + * When working with Linux, SHM_ADDR and SHM_SIZE is not used + */ +#define SHM_ADDR (0) +#define SHM_SIZE (0) -int _enable_interrupt(struct proc_vring *vring_hw); -void _notify(int cpu_id, struct proc_intr *intr_info); -int _boot_cpu(int cpu_id, unsigned int load_addr); -void _shutdown_cpu(int cpu_id); +void platform_time_delay(int num_msec); +int platform_in_isr(void); +int platform_interrupt_enable(unsigned int vector_id, unsigned int trigger_type, unsigned int priority); +int platform_interrupt_disable(unsigned int vector_id); +void platform_interrupt_enable_all(void); +void platform_interrupt_disable_all(void); +void platform_map_mem_region(unsigned int va,unsigned int pa, unsigned int size, unsigned int flags); +void platform_cache_all_flush_invalidate(void); +void platform_cache_disable(void); +unsigned long platform_vatopa(void *addr); +void *platform_patova(unsigned long addr); void platform_isr(int vect_id, void *data); +int platform_init(void); +int platform_deinit(void); #endif /* PLATFORM_H_ */ diff --git a/middleware/multicore/open-amp/porting/imx7d_m4/platform_info.c b/middleware/multicore/open-amp/porting/imx7d_m4/platform_info.c index aaef04f..4aa2c4a 100644 --- a/middleware/multicore/open-amp/porting/imx7d_m4/platform_info.c +++ b/middleware/multicore/open-amp/porting/imx7d_m4/platform_info.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2015, Freescale Corporation - * All rights reserved. + * Copyright (c) 2015 Freescale Semiconductor, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -10,7 +9,7 @@ * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * 3. Neither the name of Mentor Graphics Corporation nor the names of its + * 3. Neither the name of Freescale Semiconductor nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * @@ -35,20 +34,20 @@ * DESCRIPTION * * This file implements APIs to get platform specific - * information for OpenAMP. + * information for OpenAMP. * **************************************************************************/ #include "platform.h" -#include "../../rpmsg/rpmsg.h" +#include "rpmsg/rpmsg.h" -/* Reference implementation that show cases platform_get_cpu_info and +/* Reference implementation that show cases platform_get_cpu_info and platform_get_for_firmware API implementation for Bare metal environment */ extern struct hil_platform_ops proc_ops; /* - * Linux requirems the ALIGN to 0x1000 instead of 0x80 + * Linux requires the ALIGN to 0x1000(4KB) instead of 0x80 */ #define VRING_ALIGN 0x1000 @@ -58,14 +57,6 @@ extern struct hil_platform_ops proc_ops; #define VRING0_BASE 0xBFFF0000 #define VRING1_BASE 0xBFFF8000 -/* - * 32 MSG (16 rx, 16 tx), 512 bytes each, it is only used when RPMSG driver is working in master mode, otherwise - * the share memory is managed by the other side. - * When working with Linux, SHM_ADDR and SHM_SIZE is not used - */ -#define SHM_ADDR 0 -#define SHM_SIZE 0 - /* IPI_VECT here defines VRING index in MU */ #define VRING0_IPI_VECT 0 #define VRING1_IPI_VECT 1 @@ -74,10 +65,10 @@ extern struct hil_platform_ops proc_ops; #define REMOTE_CPU_ID 1 /** - * This array provdes defnition of CPU nodes for master and remote - * context. It contains two nodes beacuse the same file is intended + * This array provides definition of CPU nodes for master and remote + * context. It contains two nodes because the same file is intended * to use with both master and remote configurations. On zynq platform - * only one node defintion is required for master/remote as there + * only one node definition is required for master/remote as there * are only two cores present in the platform. * * Only platform specific info is populated here. Rest of information @@ -90,7 +81,7 @@ extern struct hil_platform_ops proc_ops; * -Channel info. * * Although the channel info is not platform specific information - * but it is conveneient to keep it in HIL so that user can easily + * but it is convenient to keep it in HIL so that user can easily * provide it without modifying the generic part. * * It is good idea to define hil_proc structure with platform @@ -108,10 +99,10 @@ extern struct hil_platform_ops proc_ops; * * 2)Second node is required by the master and it defines remote CPU ID, * shared memory and interrupts info. In general no channel info is required by the - * Master node, however in baremetal master and linux remote case the linux + * Master node, however in bare-metal master and linux remote case the linux * rpmsg bus driver behaves as master so the rpmsg driver on linux side still needs - * channel info. This information is not required by the masters for baremetal - * remotes. + * channel info. This information is not required by the masters for bare-metal + * remotes. * */ struct hil_proc proc_table []= @@ -133,7 +124,7 @@ struct hil_proc proc_table []= /* Vring info */ /*struct proc_vring*/ { /*[0]*/ - { /* TX */ + { /* TX */ NULL, (void*)VRING0_BASE/*phy_addr*/, 256/*num_descs*/, VRING_ALIGN/*align*/, /*struct virtqueue, phys_addr, num_descs, align*/ { @@ -228,10 +219,13 @@ struct hil_proc proc_table []= * * return - status of execution */ -int platform_get_processor_info(struct hil_proc *proc , int cpu_id) { +int platform_get_processor_info(struct hil_proc *proc , int cpu_id) +{ int idx; - for(idx = 0; idx < sizeof(proc_table)/sizeof(struct hil_proc); idx++) { - if((cpu_id == HIL_RSVD_CPU_ID) || (proc_table[idx].cpu_id == cpu_id) ) { + for(idx = 0; idx < sizeof(proc_table)/sizeof(struct hil_proc); idx++) + { + if((cpu_id == HIL_RSVD_CPU_ID) || (proc_table[idx].cpu_id == cpu_id)) + { env_memcpy(proc,&proc_table[idx], sizeof(struct hil_proc)); return 0; } @@ -239,7 +233,7 @@ int platform_get_processor_info(struct hil_proc *proc , int cpu_id) { return -1; } -int platform_get_processor_for_fw(char *fw_name) { - +int platform_get_processor_for_fw(char *fw_name) +{ return 1; } diff --git a/middleware/multicore/open-amp/porting/imx7d_m4/plat_porting.h b/middleware/multicore/open-amp/porting/imx7d_m4/rpmsg_platform_porting.h index 4c25960..9bcac32 100644 --- a/middleware/multicore/open-amp/porting/imx7d_m4/plat_porting.h +++ b/middleware/multicore/open-amp/porting/imx7d_m4/rpmsg_platform_porting.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2015, Freescale Corporation - * All rights reserved. + * Copyright (c) 2015 Freescale Semiconductor, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -10,7 +9,7 @@ * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * 3. Neither the name of Mentor Graphics Corporation nor the names of its + * 3. Neither the name of Freescale Semiconductor nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * @@ -30,21 +29,20 @@ /************************************************************************** * FILE NAME * - * plat_porting.h + * rpmsg_platform_porting.h * * DESCRIPTION * - * This file contains the declaration of porting related function - * and macros + * This file contains enviroment specific settings * **************************************************************************/ -#ifndef PLAT_PORTING_H_ -#define PLAT_PORTING_H_ +#ifndef RPMSG_PLATFORM_PORTING_H_ +#define RPMSG_PLATFORM_PORTING_H_ -/* MU_RPMSG_CHANNEL is the MU channel used for master and remote to notify each other*/ -#define MU_RPMSG_CHANNEL 1 +/* RPMSG MU channel index */ +#define RPMSG_MU_CHANNEL (1) -/* platform specific rpmsg handler which is invoked when a notification is received from peer*/ -void rpmsg_handler(void); +/* RPMSG ISR handler to be called in Application */ +extern void rpmsg_handler(void); -#endif /* PLAT_PORTING_H_ */ +#endif /* RPMSG_PLATFORM_PORTING_H_ */ |