From a57cc2c988482010061b9e68344fdf1969889763 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 12 Jan 2016 14:06:54 -0800 Subject: initial commit, FreeRTOS_BSP_1.0.0_iMX7D --- middleware/multicore/open-amp/common/hil/hil.c | 406 +++++++++++++++++ middleware/multicore/open-amp/common/hil/hil.h | 494 +++++++++++++++++++++ middleware/multicore/open-amp/common/llist/llist.c | 100 +++++ middleware/multicore/open-amp/common/llist/llist.h | 59 +++ middleware/multicore/open-amp/common/shm/sh_mem.c | 230 ++++++++++ middleware/multicore/open-amp/common/shm/sh_mem.h | 89 ++++ 6 files changed, 1378 insertions(+) create mode 100644 middleware/multicore/open-amp/common/hil/hil.c create mode 100644 middleware/multicore/open-amp/common/hil/hil.h create mode 100644 middleware/multicore/open-amp/common/llist/llist.c create mode 100644 middleware/multicore/open-amp/common/llist/llist.h create mode 100644 middleware/multicore/open-amp/common/shm/sh_mem.c create mode 100644 middleware/multicore/open-amp/common/shm/sh_mem.h (limited to 'middleware/multicore/open-amp/common') diff --git a/middleware/multicore/open-amp/common/hil/hil.c b/middleware/multicore/open-amp/common/hil/hil.c new file mode 100644 index 0000000..e4b0bf3 --- /dev/null +++ b/middleware/multicore/open-amp/common/hil/hil.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 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 + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/************************************************************************** + * FILE NAME + * + * hil.c + * + * COMPONENT + * + * OpenAMP Stack. + * + * DESCRIPTION + * + * This file is implementation of generic part of HIL. + * + * + * + **************************************************************************/ + +#include "hil.h" + +/*--------------------------- Globals ---------------------------------- */ +struct hil_proc_list procs; + +#if defined (OPENAMP_BENCHMARK_ENABLE) + +unsigned long long boot_time_stamp; +unsigned long long shutdown_time_stamp; + +#endif + +extern int platform_get_processor_info(struct hil_proc *proc, int cpu_id); +extern int platform_get_processor_for_fw(char *fw_name); + +/** + * hil_create_proc + * + * This function creates a HIL proc instance for given CPU id and populates + * it with platform info. + * + * @param cpu_id - cpu id + * + * @return - pointer to proc instance + * + */ +struct hil_proc *hil_create_proc(int cpu_id) { + struct hil_proc *proc = NULL; + struct llist *node = NULL; + struct llist *proc_hd = procs.proc_list; + int status; + + /* If proc already exists then return it */ + while (proc_hd != NULL) { + proc = (struct hil_proc *) proc_hd->data; + if (proc->cpu_id == cpu_id) { + return proc; + } + proc_hd = proc_hd->next; + } + + /* Allocate memory for proc instance */ + proc = env_allocate_memory(sizeof(struct hil_proc)); + if (!proc) { + return NULL; + } + + /* Get HW specfic info */ + status = platform_get_processor_info(proc, cpu_id); + if (status) { + env_free_memory(proc); + return NULL; + } + + /* Enable mapping for the shared memory region */ + env_map_memory((unsigned int) proc->sh_buff.start_addr, + (unsigned int) proc->sh_buff.start_addr, proc->sh_buff.size, + (SHARED_MEM | UNCACHED)); + + /* Put the new proc in the procs list */ + node = env_allocate_memory(sizeof(struct llist)); + + if (!node) { + env_free_memory(proc); + return NULL; + } + + node->data = proc; + add_to_list(&procs.proc_list, node); + + return proc; +} + +/** + * hil_get_cpuforfw + * + * This function provides the CPU ID for the given firmware. + * + * @param fw_name - name of firmware + * + * @return - cpu id + * + */ +int hil_get_cpuforfw(char *fw_name) { + return (platform_get_processor_for_fw(fw_name)); +} + +/** + * hil_delete_proc + * + * This function deletes the given proc instance and frees the + * associated resources. + * + * @param proc - pointer to hil remote_proc instance + * + */ +void hil_delete_proc(struct hil_proc *proc) { + struct llist *proc_hd = NULL; + + if (!proc) + return; + + proc_hd = procs.proc_list; + + while (proc_hd != NULL) { + if (proc_hd->data == proc) { + remove_from_list(&procs.proc_list, proc_hd); + env_free_memory(proc_hd); + break; + } + proc_hd = proc_hd->next; + } + + env_free_memory(proc); +} + + +/** + * hil_isr() + * + * This function is called when interrupt is received for the vring. + * This function gets the corresponding virtqueue and generates + * call back for it. + * + * @param vring_hw - pointer to vring control block + * + */ +void hil_isr(struct proc_vring *vring_hw){ + virtqueue_notification(vring_hw->vq); +} + +/** + * hil_get_proc + * + * This function finds the proc instance based on the given ID + * from the proc list and returns it to user. + * + * @param cpu_id - cpu id + * + * @return - pointer to hil proc instance + * + */ +struct hil_proc *hil_get_proc(int cpu_id) { + struct llist *proc_hd = procs.proc_list; + + if (!proc_hd) + return NULL; + + while (proc_hd != NULL) { + struct hil_proc *proc = (struct hil_proc *) proc_hd->data; + if (proc->cpu_id == cpu_id) { + return proc; + } + proc_hd = proc_hd->next; + } + + return NULL; +} + +/** + * hil_get_chnl_info + * + * This function returns channels info for given proc. + * + * @param proc - pointer to proc info struct + * @param num_chnls - pointer to integer variable to hold + * number of available channels + * + * @return - pointer to channel info control block + * + */ +struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc, int *num_chnls) { + *num_chnls = proc->num_chnls; + return (proc->chnls); +} + +/** + * hil_get_vdev_info + * + * This function return virtio device for remote core. + * + * @param proc - pointer to remote proc + * + * @return - pointer to virtio HW device. + * + */ + +struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc) { + return (&proc->vdev); + +} + +/** + * hil_get_vring_info + * + * This function returns vring_info_table. The caller will use + * this table to get the vring HW info which will be subsequently + * used to create virtqueues. + * + * @param vdev - pointer to virtio HW device + * @param num_vrings - pointer to hold number of vrings + * + * @return - pointer to vring hardware info table + */ +struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings) { + + *num_vrings = vdev->num_vrings; + return (vdev->vring_info); + +} + +/** + * hil_get_shm_info + * + * This function returns shared memory info control block. The caller + * will use this information to create and manage memory buffers for + * vring descriptor table. + * + * @param proc - pointer to proc instance + * + * @return - pointer to shared memory region used for buffers + * + */ +struct proc_shm *hil_get_shm_info(struct hil_proc *proc) { + return (&proc->sh_buff); +} + +/** + * hil_enable_vring_notifications() + * + * This function is called after successful creation of virtqueues. + * This function saves queue handle in the vring_info_table which + * will be used during interrupt handling .This function setups + * interrupt handlers. + * + * @param vring_index - index to vring HW table + * @param vq - pointer to virtqueue to save in vring HW table + * + * @return - execution status + */ +int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq) { + struct hil_proc *proc_hw = (struct hil_proc *) vq->vq_dev->device; + struct proc_vring *vring_hw = &proc_hw->vdev.vring_info[vring_index]; + /* Save virtqueue pointer for later reference */ + vring_hw->vq = vq; + + if (proc_hw->ops->enable_interrupt) { + proc_hw->ops->enable_interrupt(vring_hw); /*_enable_interrupt*/ + } + + return 0; +} + +/** + * hil_vring_notify() + * + * This function generates IPI to let the other side know that there is + * job available for it. The required information to achieve this, like interrupt + * vector, CPU id etc is be obtained from the proc_vring table. + * + * @param vq - pointer to virtqueue + * + */ +void hil_vring_notify(struct virtqueue *vq) { + struct hil_proc *proc_hw = (struct hil_proc *) vq->vq_dev->device; + struct proc_vring *vring_hw = &proc_hw->vdev.vring_info[vq->vq_queue_index]; + + if (proc_hw->ops->notify) { + proc_hw->ops->notify(proc_hw->cpu_id, &vring_hw->intr_info); /*_notify*/ + } +} + +/** + * hil_get_status + * + * This function is used to check if the given core is up and running. + * This call will return after it is confirmed that remote core has + * started. + * + * @param proc - pointer to proc instance + * + * @return - execution status + */ +int hil_get_status(struct hil_proc *proc) { + /* For future use only.*/ + return 0; +} + +/** + * hil_set_status + * + * This function is used to update the status + * of the given core i.e it is ready for IPC. + * + * @param proc - pointer to remote proc + * + * @return - execution status + */ +int hil_set_status(struct hil_proc *proc) { + /* For future use only.*/ + return 0; +} + +/** + * hil_boot_cpu + * + * This function boots the remote processor. + * + * @param proc - pointer to remote proc + * @param start_addr - start address of remote cpu + * + * @return - execution status + */ +int hil_boot_cpu(struct hil_proc *proc, unsigned int start_addr) { + + if (proc->ops->boot_cpu) { + proc->ops->boot_cpu(proc->cpu_id, start_addr); + } + +#if defined (OPENAMP_BENCHMARK_ENABLE) + boot_time_stamp = env_get_timestamp(); +#endif + + return 0; +} + +/** + * hil_shutdown_cpu + * + * This function shutdowns the remote processor + * + * @param proc - pointer to remote proc + * + */ +void hil_shutdown_cpu(struct hil_proc *proc) { + if (proc->ops->shutdown_cpu) { + proc->ops->shutdown_cpu(proc->cpu_id); + } + +#if defined (OPENAMP_BENCHMARK_ENABLE) + shutdown_time_stamp = env_get_timestamp(); +#endif +} + +/** + * hil_get_firmware + * + * This function returns address and size of given firmware name passed as + * parameter. + * + * @param fw_name - name of the firmware + * @param start_addr - pointer t hold start address of firmware + * @param size - pointer to hold size of firmware + * + * returns - status of function execution + * + */ +int hil_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size){ + return (config_get_firmware(fw_name , start_addr, size)); +} diff --git a/middleware/multicore/open-amp/common/hil/hil.h b/middleware/multicore/open-amp/common/hil/hil.h new file mode 100644 index 0000000..0f5ce2d --- /dev/null +++ b/middleware/multicore/open-amp/common/hil/hil.h @@ -0,0 +1,494 @@ +#ifndef _HIL_H_ +#define _HIL_H_ + +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 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 the nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/************************************************************************** + * FILE NAME + * + * hil.h + * + * DESCRIPTION + * + * This file defines interface layer to access hardware features. This + * interface is used by both RPMSG and remoteproc components. + * + ***************************************************************************/ + +#include "../../virtio/virtio.h" +#include "../../porting/config/config.h" + +/* Configurable parameters */ +#define HIL_MAX_CORES 2 +#define HIL_MAX_NUM_VRINGS 2 +#define HIL_MAX_NUM_CHANNELS 1 +/* Reserved CPU id */ +#define HIL_RSVD_CPU_ID 0xffffffff + +/** + * struct proc_shm + * + * This structure is maintained by hardware interface layer for + * shared memory information. The shared memory provides buffers + * for use by the vring to exchange messages between the cores. + * + */ +struct proc_shm +{ + /* Start address of shared memory used for buffers. */ + void *start_addr; + /* Size of shared memory. */ + unsigned long size; + /* Attributes for shared memory - cached or uncached. */ + unsigned long flags; +}; + +/** +* struct proc_intr +* +* This structure is maintained by hardware interface layer for +* notification(interrupts) mechanism. The most common notification mechanism +* is Inter-Processor Interrupt(IPI). There can be other mechanism depending +* on SoC architecture. +* +*/ +struct proc_intr +{ + /* Interrupt number for vring - use for IPI */ + unsigned int vect_id; + /* Interrupt priority */ + unsigned int priority; + /* Interrupt trigger type */ + unsigned int trigger_type; + /* Private data */ + void *data; +}; + +/** +* struct proc_vring +* +* This structure is maintained by hardware interface layer to keep +* vring physical memory and notification info. +* +*/ +struct proc_vring +{ + /* Pointer to virtqueue encapsulating the vring */ + struct virtqueue *vq; + /* Vring physical address */ + void *phy_addr; + /* Number of vring descriptors */ + unsigned short num_descs; + /* Vring alignment*/ + unsigned long align; + /* Vring interrupt control block */ + struct proc_intr intr_info; +}; + +/** + * struct proc_vdev + * + * This structure represents a virtio HW device for remote processor. + * Currently only one virtio device per processor is supported. + * + */ +struct proc_vdev +{ + /* Number of vrings*/ + unsigned int num_vrings; + /* Virtio device features */ + unsigned int dfeatures; + /* Virtio gen features */ + unsigned int gfeatures; + /* Vring info control blocks */ + struct proc_vring vring_info[HIL_MAX_NUM_VRINGS]; +}; + +/** + * struct proc_chnl + * + * This structure represents channel IDs that would be used by + * the remote in the name service message. This will be extended + * further to support static channel creation. + * + */ +struct proc_chnl +{ + /* Channel ID */ + char name[32]; +}; + +/** +* struct hil_proc +* +* This structure represents a remote processor and encapsulates shared +* memory and notification info required for IPC. +* +*/ +struct hil_proc +{ + /* CPU ID as defined by the platform */ + unsigned long cpu_id; + /* Shared memory info */ + struct proc_shm sh_buff; + /* Virtio device hardware info */ + struct proc_vdev vdev; + /* Number of RPMSG channels */ + unsigned long num_chnls; + /* RPMsg channels array */ + struct proc_chnl chnls[HIL_MAX_NUM_CHANNELS]; + /* HIL platform ops table */ + struct hil_platform_ops *ops; + /* Attrbites to represent processor role, master or remote . This field is for + * future use. */ + unsigned long attr; + /* + * CPU bitmask - shared variable updated by each core + * after it has been initialized. This field is for future use. + */ + unsigned long cpu_bitmask; + /* Spin lock - This field is for future use. */ + volatile unsigned int *slock; +}; + +/** + * struct hil_proc_list + * + * This structure serves as lists for cores present in the system. + * It provides entry point to access remote core parameters. + * + */ +struct hil_proc_list { + struct llist *proc_list; +}; + +/** + * hil_create_proc + * + * This function creates a HIL proc instance for given CPU id and populates + * it with platform info. + * + * @param cpu_id - cpu id + * + * @return - pointer to proc instance + * + */ +struct hil_proc *hil_create_proc(int cpu_id); + +/** + * hil_delete_proc + * + * This function deletes the given proc instance and frees the + * associated resources. + * + * @param proc - pointer to HIL proc instance + * + */ +void hil_delete_proc(struct hil_proc *proc); + +/** + * hil_get_proc + * + * This function finds the proc instance based on the given ID + * from the proc list and returns it to user. + * + * @param cpu_id - cpu id + * + * @return - pointer to proc instance + * + */ +struct hil_proc *hil_get_proc(int cpu_id); + +/** + * hil_isr() + * + * This function is called when interrupt is received for the vring. + * This function gets the corresponding virtqueue and generates + * call back for it. + * + * @param vring_hw - pointer to vring control block + * + */ +void hil_isr(struct proc_vring *vring_hw); + +/** + * hil_get_cpuforfw + * + * This function provides the CPU ID for the given firmware. + * + * @param fw_name - name of firmware + * + * @return - cpu id + * + */ +int hil_get_cpuforfw(char *fw_name); + +/** + * hil_get_vdev_info + * + * This function return virtio device for remote core. + * + * @param proc - pointer to remote proc + * + * @return - pointer to virtio HW device. + * + */ +struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc); + +/** + * hil_get_chnl_info + * + * This function returns channels info for given proc. + * + * @param proc - pointer to proc info struct + * @param num_chnls - pointer to integer variable to hold + * number of available channels + * + * @return - pointer to channel info control block + * + */ +struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc , int *num_chnls); + +/** + * hil_get_vring_info + * + * This function returns vring_info_table. The caller will use + * this table to get the vring HW info which will be subsequently + * used to create virtqueues. + * + * @param vdev - pointer to virtio HW device + * @param num_vrings - pointer to hold number of vrings + * + * @return - pointer to vring hardware info table + */ +struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings); + +/** + * hil_get_shm_info + * + * This function returns shared memory info control block. The caller + * will use this information to create and manage memory buffers for + * vring descriptor table. + * + * @param proc - pointer to proc instance + * + * @return - pointer to shared memory region used for buffers + * + */ +struct proc_shm *hil_get_shm_info(struct hil_proc *proc); + +/** + * hil_enable_vring_notifications() + * + * This function is called after successful creation of virtqueues. + * This function saves queue handle in the vring_info_table which + * will be used during interrupt handling .This function setups + * interrupt handlers. + * + * @param vring_index - index to vring HW table + * @param vq - pointer to virtqueue to save in vring HW table + * + * @return - execution status + */ +int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq); + +/** + * hil_vring_notify() + * + * This function generates IPI to let the other side know that there is + * job available for it. The required information to achieve this, like interrupt + * vector, CPU id etc is be obtained from the proc_vring table. + * + * @param vq - pointer to virtqueue + * + */ +void hil_vring_notify(struct virtqueue *vq); + +/** + * hil_get_status + * + * This function is used to check if the given core is up and running. + * This call will return after it is confirmed that remote core has + * started. + * + * @param proc - pointer to proc instance + * + * @return - execution status + */ +int hil_get_status(struct hil_proc *proc); + +/** + * hil_set_status + * + * This function is used to update the status + * of the given core i.e it is ready for IPC. + * + * @param proc - pointer to remote proc + * + * @return - execution status + */ + +int hil_set_status(struct hil_proc *proc); + +/** + * hil_boot_cpu + * + * This function starts remote processor at given address. + * + * @param proc - pointer to remote proc + * @param load_addr - load address of remote firmware + * + * @return - execution status + */ +int hil_boot_cpu(struct hil_proc *proc , unsigned int load_addr); + +/** + * hil_shutdown_cpu + * + * This function shutdowns the remote processor + * + * @param proc - pointer to remote proc + * + */ +void hil_shutdown_cpu(struct hil_proc *proc); + +/** + * hil_get_firmware + * + * This function returns address and size of given firmware name passed as + * parameter. + * + * @param fw_name - name of the firmware + * @param start_addr - pointer t hold start address of firmware + * @param size - pointer to hold size of firmware + * + * returns - status of function execution + * + */ +int hil_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size); + +/** + * + * This structure is an interface between HIL and platform porting + * component. It is required for the user to provide definitions of + * these functions when framework is ported to new hardware platform. + * + */ +struct hil_platform_ops +{ + /** + * enable_interrupt() + * + * This function enables interrupt(IPI) for given vring. + * + * @param vring_hw - pointer to vring control block + * + * @return - execution status + */ + int (*enable_interrupt)(struct proc_vring *vring_hw); + + /** + * reg_ipi_after_deinit() + * This function register interrupt(IPI) after openamp resource . + * + * @param vring_hw - pointer to vring control block + */ + void (*reg_ipi_after_deinit)(struct proc_vring *vring_hw); + + /** + * notify() + * + * This function generates IPI to let the other side know that there is + * job available for it. + * + * @param cpu_id - ID of CPU which is to be notified + * @param intr_info - pointer to interrupt info control block + */ + void (*notify)(int cpu_id , struct proc_intr *intr_info); + + /** + * get_status + * + * This function is used to check if the given core is + * up and running. This call will return after it is confirmed + * that remote core is initialized. + * + * @param cpu_id - ID of CPU for which status is requested. + * + * @return - execution status + */ + int (*get_status)(int cpu_id); + + /** + * set_status + * + * This function is used to update the status + * of the given core i.e it is ready for IPC. + * + * @param cpu_id - ID of CPU for which status is to be set + * + * @return - execution status + */ + + int (*set_status)(int cpu_id); + + /** + * boot_cpu + * + * This function boots the remote processor. + * + * @param cpu_id - ID of CPU to boot + * @param start_addr - start address of remote cpu + * + * @return - execution status + */ + int (*boot_cpu)(int cpu_id , unsigned int start_addr); + + /** + * shutdown_cpu + * + * This function shutdowns the remote processor. + * + * @param cpu_id - ID of CPU to shutdown + * + */ + void (*shutdown_cpu)(int cpu_id); + +}; + +/* Utility macros for register read/write */ +#define HIL_MEM_READ8(addr) *(volatile unsigned char *)(addr) +#define HIL_MEM_READ16(addr) *(volatile unsigned short *)(addr) +#define HIL_MEM_READ32(addr) *(volatile unsigned long *)(addr) +#define HIL_MEM_WRITE8(addr,data) *(volatile unsigned char *)(addr) = (unsigned char)(data) +#define HIL_MEM_WRITE16(addr,data) *(volatile unsigned short *)(addr) = (unsigned short)(data) +#define HIL_MEM_WRITE32(addr,data) *(volatile unsigned long *)(addr) = (unsigned long)(data) + +#endif /* _HIL_H_ */ diff --git a/middleware/multicore/open-amp/common/llist/llist.c b/middleware/multicore/open-amp/common/llist/llist.c new file mode 100644 index 0000000..37e888c --- /dev/null +++ b/middleware/multicore/open-amp/common/llist/llist.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 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 + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/************************************************************************** + * FILE NAME + * + * llist.c + * + * COMPONENT + * + * OpenAMP stack. + * + * DESCRIPTION + * + * Source file for basic linked list service. + * + **************************************************************************/ +#include "llist.h" + +#define LIST_NULL ((void *)0) +/** + * add_to_list + * + * Places new element at the start of the list. + * + * @param head - list head + * @param node - new element to add + * + */ +void add_to_list(struct llist **head, struct llist *node) { + + if (!node) + return; + + if (*head) { + /* Place the new element at the start of list. */ + node->next = *head; + node->prev = LIST_NULL; + (*head)->prev = node; + *head = node; + } else { + /* List is empty - assign new element to list head. */ + *head = node; + (*head)->next = LIST_NULL; + (*head)->prev = LIST_NULL; + } +} + +/** + * remove_from_list + * + * Removes the given element from the list. + * + * @param head - list head + * @param element - element to remove from list + * + */ +void remove_from_list(struct llist **head, struct llist *node) { + + if (!(*head) || !(node)) + return; + + if (node == *head) { + /* First element has to be removed. */ + *head = (*head)->next; + } else if (node->next == LIST_NULL) { + /* Last element has to be removed. */ + node->prev->next = node->next; + } else { + /* Intermediate element has to be removed. */ + node->prev->next = node->next; + node->next->prev = node->prev; + } +} diff --git a/middleware/multicore/open-amp/common/llist/llist.h b/middleware/multicore/open-amp/common/llist/llist.h new file mode 100644 index 0000000..004f4e0 --- /dev/null +++ b/middleware/multicore/open-amp/common/llist/llist.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 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 + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +/************************************************************************** + * FILE NAME + * + * llist.h + * + * COMPONENT + * + * OpenAMP stack. + * + * DESCRIPTION + * + * Header file for linked list service. + * + **************************************************************************/ + +#ifndef LLIST_H_ +#define LLIST_H_ + +struct llist { + void *data; + unsigned int attr; + struct llist *next; + struct llist *prev; +}; + +void add_to_list(struct llist **head, struct llist *node); +void remove_from_list(struct llist **head, struct llist *node); + +#endif /* LLIST_H_ */ diff --git a/middleware/multicore/open-amp/common/shm/sh_mem.c b/middleware/multicore/open-amp/common/shm/sh_mem.c new file mode 100644 index 0000000..6a290a4 --- /dev/null +++ b/middleware/multicore/open-amp/common/shm/sh_mem.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 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 + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/************************************************************************** + * FILE NAME + * + * sh_mem.c + * + * COMPONENT + * + * OpenAMP stack. + * + * DESCRIPTION + * + * Source file for fixed buffer size memory management service. Currently + * it is only being used to manage shared memory. + * + **************************************************************************/ +#include "sh_mem.h" + +/** + * sh_mem_create_pool + * + * Creates new memory pool with the given parameters. + * + * @param start_addr - start address of the memory region + * @param size - size of the memory + * @param buff_size - fixed buffer size + * + * @return - pointer to memory pool + * + */ +struct sh_mem_pool * sh_mem_create_pool(void *start_addr, unsigned int size, + unsigned int buff_size) { + struct sh_mem_pool *mem_pool; + int status, pool_size; + int num_buffs, bmp_size; + + if (!start_addr || !size || !buff_size) + return NULL; + + /* Word align the buffer size */ + buff_size = WORD_ALIGN(buff_size); + + /* Get number of buffers. */ + num_buffs = (size / buff_size) + ((size % buff_size) == 0 ? 0 : 1); + + /* + * Size of the bitmap required to maintain buffers info. One word(32 bit) can + * keep track of 32 buffers. + */ + bmp_size = (num_buffs / BITMAP_WORD_SIZE) + + ((num_buffs % BITMAP_WORD_SIZE) == 0 ? 0 : 1); + + /* Total size required for pool control block. */ + pool_size = sizeof(struct sh_mem_pool) + WORD_SIZE * bmp_size; + + /* Create pool control block. */ + mem_pool = env_allocate_memory(pool_size); + + if (mem_pool) { + /* Initialize pool parameters */ + env_memset(mem_pool, 0x00, pool_size); + status = env_create_mutex(&mem_pool->lock , 1); + if (status){ + env_free_memory(mem_pool); + return NULL; + } + mem_pool->start_addr = start_addr; + mem_pool->buff_size = buff_size; + mem_pool->bmp_size = bmp_size; + mem_pool->total_buffs = num_buffs; + } + + return mem_pool; +} + +/** + * sh_mem_get_buffer + * + * Allocates fixed size buffer from the given memory pool. + * + * @param pool - pointer to memory pool + * + * @return - pointer to allocated buffer + * + */ +void * sh_mem_get_buffer(struct sh_mem_pool *pool) { + void *buff = NULL; + int idx, bit_idx; + + if (!pool) + return NULL; + + env_lock_mutex(pool->lock); + + if (pool->used_buffs >= pool->total_buffs) { + env_unlock_mutex(pool->lock); + return NULL; + } + + for (idx = 0; idx < pool->bmp_size; idx++) { + /* + * Find the first 0 bit in the buffers bitmap. The 0th bit + * represents a free buffer. + */ + bit_idx = get_first_zero_bit(pool->bitmap[idx]); + if (bit_idx < 32) { + /* Set bit to mark it as consumed. */ + pool->bitmap[idx] |= (1 << bit_idx); + buff = (char *) pool->start_addr + + pool->buff_size * (idx * BITMAP_WORD_SIZE + bit_idx); + pool->used_buffs++; + break; + } + } + + env_unlock_mutex(pool->lock); + + return buff; +} + +/** + * sh_mem_free_buffer + * + * Frees the given buffer. + * + * @param pool - pointer to memory pool + * @param buff - pointer to buffer + * + * @return - none + */ +void sh_mem_free_buffer(void *buff, struct sh_mem_pool *pool) { + unsigned long *bitmask; + int bmp_idx, bit_idx, buff_idx; + + if (!pool || !buff) + return; + + /* Acquire the pool lock */ + env_lock_mutex(pool->lock); + + /* Map the buffer address to its index. */ + buff_idx = ((char *) buff - (char*) pool->start_addr) / pool->buff_size; + + /* Translate the buffer index to bitmap index. */ + bmp_idx = buff_idx / BITMAP_WORD_SIZE; + bit_idx = buff_idx % BITMAP_WORD_SIZE; + bitmask = &pool->bitmap[bmp_idx]; + + /* Mark the buffer as free */ + *bitmask ^= (1 << bit_idx); + + pool->used_buffs--; + + /* Release the pool lock. */ + env_unlock_mutex(pool->lock); + +} + +/** + * sh_mem_delete_pool + * + * Deletes the given memory pool. + * + * @param pool - pointer to memory pool + * + * @return - none + */ +void sh_mem_delete_pool(struct sh_mem_pool *pool) { + + if (pool) { + env_delete_mutex(pool->lock); + env_free_memory(pool); + } +} + +/** + * get_first_zero_bit + * + * Provides position of first 0 bit in a 32 bit value + * + * @param value - given value + * + * @return - 0th bit position + */ +unsigned int get_first_zero_bit(unsigned long value) { + unsigned int idx; + unsigned int tmp32; + + /* Invert value */ + value = ~value; + + /* (~value) & (2's complement of value) */ + value = (value & (-value)) - 1; + + /* log2(value) */ + + tmp32 = value - ((value >> 1) & 033333333333) + - ((value >> 2) & 011111111111); + + idx = ((tmp32 + (tmp32 >> 3)) & 030707070707) % 63; + + return idx; +} diff --git a/middleware/multicore/open-amp/common/shm/sh_mem.h b/middleware/multicore/open-amp/common/shm/sh_mem.h new file mode 100644 index 0000000..4ba830b --- /dev/null +++ b/middleware/multicore/open-amp/common/shm/sh_mem.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 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 + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/************************************************************************** + * FILE NAME + * + * sh_mem.c + * + * COMPONENT + * + * IPC Stack for uAMP systems. + * + * DESCRIPTION + * + * Header file for fixed buffer size memory management service. Currently + * it is being used to manage shared memory. + * + **************************************************************************/ +#ifndef SH_MEM_H_ +#define SH_MEM_H_ + +#include "../../porting/env/env.h" + + +/* Macros */ +#define BITMAP_WORD_SIZE 32 +#define WORD_SIZE sizeof(unsigned long) +#define WORD_ALIGN(a) (((a) & (WORD_SIZE-1)) != 0)? \ + (((a) & (~(WORD_SIZE-1))) + 4):(a) +/* + * This structure represents a shared memory pool. + * + * @start_addr - start address of shared memory region + * @lock - lock to ensure exclusive access + * @size - size of shared memory* + * @buff_size - size of each buffer + * @total_buffs - total number of buffers in shared memory region + * @used_buffs - number of used buffers + * @bmp_size - size of bitmap array + * @bitmap - array to keep record of free and used blocks + * + */ + +struct sh_mem_pool { + void *start_addr; + LOCK *lock; + int size; + int buff_size; + int total_buffs; + int used_buffs; + int bmp_size; + unsigned long bitmap[0]; +}; + +/* APIs */ +struct sh_mem_pool *sh_mem_create_pool(void *start_addr, unsigned int size, + unsigned int buff_size); +void sh_mem_delete_pool(struct sh_mem_pool *pool); +void *sh_mem_get_buffer(struct sh_mem_pool *pool); +void sh_mem_free_buffer(void *ptr, struct sh_mem_pool *pool); +unsigned int get_first_zero_bit(unsigned long value); + +#endif /* SH_MEM_H_ */ -- cgit v1.2.3