summaryrefslogtreecommitdiff
path: root/middleware/multicore/open-amp/porting/imx7d_m4
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/multicore/open-amp/porting/imx7d_m4')
-rw-r--r--middleware/multicore/open-amp/porting/imx7d_m4/platform.c273
-rw-r--r--middleware/multicore/open-amp/porting/imx7d_m4/platform.h45
-rw-r--r--middleware/multicore/open-amp/porting/imx7d_m4/platform_info.c50
-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_ */