summaryrefslogtreecommitdiff
path: root/middleware/multicore/open-amp/common/hil/hil.c
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/multicore/open-amp/common/hil/hil.c')
-rw-r--r--middleware/multicore/open-amp/common/hil/hil.c406
1 files changed, 406 insertions, 0 deletions
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));
+}