hil: add API to enable vdev IPI
[processor-sdk/open-amp.git] / lib / include / openamp / hil.h
1 #ifndef _HIL_H_
2 #define _HIL_H_
4 /*
5  * Copyright (c) 2014, Mentor Graphics Corporation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
33 /**************************************************************************
34  * FILE NAME
35  *
36  *       hil.h
37  *
38  * DESCRIPTION
39  *
40  *       This file defines interface layer to access hardware features. This
41  *       interface is used by both RPMSG and remoteproc components.
42  *
43  ***************************************************************************/
45 #include "openamp/virtio.h"
46 #include "openamp/firmware.h"
47 #include "metal/list.h"
48 #include "metal/io.h"
49 #include "metal/device.h"
50 #include "metal/mutex.h"
52 /* Configurable parameters */
53 #define HIL_MAX_CORES                   2
54 #define HIL_MAX_NUM_VRINGS              2
55 #define HIL_MAX_NUM_CHANNELS            1
56 /* Reserved CPU id */
57 #define HIL_RSVD_CPU_ID                 0xffffffff
59 struct hil_proc;
61 typedef void (*hil_proc_vdev_rst_cb_t)(struct hil_proc *proc, int id);
63 /**
64  * struct proc_shm
65  *
66  * This structure is maintained by hardware interface layer for
67  * shared memory information. The shared memory provides buffers
68  * for use by the vring to exchange messages between the cores.
69  *
70  */
71 struct proc_shm {
72         /* Start address of shared memory used for buffers. */
73         void *start_addr;
74         /* Start physical address of shared memory used for buffers. */
75         metal_phys_addr_t start_paddr;
76         /* sharmed memory I/O region */
77         struct metal_io_region *io;
78         /* sharmed memory metal device */
79         struct metal_device *dev;
80         /* Size of shared memory. */
81         unsigned long size;
82         /* Attributes for shared memory - cached or uncached. */
83         unsigned long flags;
84 };
86 /**
87 * struct proc_intr
88 *
89 * This structure is maintained by hardware interface layer for
90 * notification(interrupts) mechanism. The most common notification mechanism
91 * is Inter-Processor Interrupt(IPI). There can be other mechanism depending
92 * on SoC architecture.
93 *
94 */
95 struct proc_intr {
96         /* Interrupt number for vring - use for IPI */
97         unsigned int vect_id;
98         /* Interrupt priority */
99         unsigned int priority;
100         /* Interrupt trigger type */
101         unsigned int trigger_type;
102         /* IPI metal device */
103         struct metal_device *dev;
104         /* IPI device I/O */
105         struct metal_io_region *io;
106         /* Private data */
107         void *data;
108 };
110 /**
111 * struct proc_vring
113 * This structure is maintained by hardware interface layer to keep
114 * vring physical memory and notification info.
116 */
117 struct proc_vring {
118         /* Pointer to virtqueue encapsulating the vring */
119         struct virtqueue *vq;
120         /* Vring logical address */
121         void *vaddr;
122         /* Vring metal device */
123         struct metal_device *dev;
124         /* Vring I/O region */
125         struct metal_io_region *io;
126         /* Number of vring descriptors */
127         unsigned short num_descs;
128         /* Vring alignment */
129         unsigned long align;
130         /* Vring interrupt control block */
131         struct proc_intr intr_info;
132 };
134 /**
135  * struct proc_vdev
136  *
137  * This structure represents a virtio HW device for remote processor.
138  * Currently only one virtio device per processor is supported.
139  *
140  */
141 struct proc_vdev {
142         /* Address for the vdev info */
143         void *vdev_info;
144         /* Vdev interrupt control block */
145         struct proc_intr intr_info;
146         /* Vdev reset callback */
147         hil_proc_vdev_rst_cb_t rst_cb;
148         /* Number of vrings */
149         unsigned int num_vrings;
150         /* Virtio device features */
151         unsigned int dfeatures;
152         /* Virtio gen features */
153         unsigned int gfeatures;
154         /* Vring info control blocks */
155         struct proc_vring vring_info[HIL_MAX_NUM_VRINGS];
156 };
158 /**
159  * struct proc_chnl
160  *
161  * This structure represents channel IDs that would be used by
162  * the remote in the name service message. This will be extended
163  * further to support static channel creation.
164  *
165  */
166 struct proc_chnl {
167         /* Channel ID */
168         char name[32];
169 };
171 /**
172 * struct hil_proc
174 * This structure represents a remote processor and encapsulates shared
175 * memory and notification info required for IPC.
177 */
178 struct hil_proc {
179         /* HIL CPU ID */
180         unsigned long cpu_id;
181         /* HIL platform ops table */
182         struct hil_platform_ops *ops;
183         /* Shared memory info */
184         struct proc_shm sh_buff;
185         /* Virtio device hardware info */
186         struct proc_vdev vdev;
187         /* Number of RPMSG channels */
188         unsigned long num_chnls;
189         /* RPMsg channels array */
190         struct proc_chnl chnls[HIL_MAX_NUM_CHANNELS];
191         /* Initialized status */
192         int is_initialized;
193         /* hil_proc lock */
194         metal_mutex_t lock;
195         /* private data */
196         void *pdata;
197         /* List node */
198         struct metal_list node;
199 };
201 /**
202  * hil_create_proc
203  *
204  * This function creates a HIL proc instance
205  *
206  * @param ops - hil proc platform operations
207  * @param cpu_id - remote CPU ID.
208  *                 E.g. the CPU ID of the remote processor in its
209  *                 cluster.
210  * @param pdata  - private data
211  * @return - pointer to proc instance
212  *
213  */
214 struct hil_proc *hil_create_proc(struct hil_platform_ops *ops,
215                                 unsigned long cpu_id, void *pdata);
217 /**
218  * hil_delete_proc
219  *
220  * This function deletes the given proc instance and frees the
221  * associated resources.
222  *
223  * @param proc - pointer to HIL proc instance
224  *
225  */
226 void hil_delete_proc(struct hil_proc *proc);
228 /**
229  * hil_init_proc
230  *
231  * This function initialize a HIL proc instance with the given platform data
232  * @param proc  - pointer to the hil_proc to initialize
233  *
234  * @return - 0 succeeded, non-0 for failure
235  *
236  */
237 int hil_init_proc(struct hil_proc *proc);
239 /**
240  * hil_notified()
241  *
242  * This function is called when notification is received.
243  * This function gets the corresponding virtqueue and generates
244  * call back for it.
245  *
246  * @param proc   - pointer to hil_proc
247  * @param notifyid - notifyid
248  *
249  */
250 void hil_notified(struct hil_proc *proc, uint32_t notifyid);
252 /**
253  * hil_get_vdev_info
254  *
255  * This function return virtio device for remote core.
256  *
257  * @param proc - pointer to remote proc
258  *
259  * @return - pointer to virtio HW device.
260  *
261  */
262 struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc);
264 /**
265  * hil_get_chnl_info
266  *
267  * This function returns channels info for given proc.
268  *
269  * @param proc - pointer to proc info struct
270  * @param num_chnls - pointer to integer variable to hold
271  *                    number of available channels
272  *
273  * @return - pointer to channel info control block
274  *
275  */
276 struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc, int *num_chnls);
278 /**
279  * hil_get_vring_info
280  *
281  * This function returns vring_info_table. The caller will use
282  * this table to get the vring HW info which will be subsequently
283  * used to create virtqueues.
284  *
285  * @param vdev - pointer to virtio HW device
286  * @param num_vrings - pointer to hold number of vrings
287  *
288  * @return - pointer to vring hardware info table
289  */
290 struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings);
292 /**
293  * hil_get_shm_info
294  *
295  * This function returns shared memory info control block. The caller
296  * will use this information to create and manage memory buffers for
297  * vring descriptor table.
298  *
299  * @param proc - pointer to proc instance
300  *
301  * @return - pointer to shared memory region used for buffers
302  *
303  */
304 struct proc_shm *hil_get_shm_info(struct hil_proc *proc);
306 /**
307  * hil_free_virtqueues
308  *
309  * This function remove virt queues of the vdev.
311  * @param vdev - pointer to the vdev which needs to remove vqs
312  */
313 void hil_free_vqs(struct virtio_device *vdev);
315 /**
316  * hil_enable_vdev_notification()
317  *
318  * This function enable handler for vdev notification.
319  *
320  * @param proc - pointer to hil_proc
321  * @param id   - vdev index
322  *
323  * @return - execution status
324  */
325 int hil_enable_vdev_notification(struct hil_proc *proc, int id);
327 /**
328  * hil_enable_vring_notifications()
329  *
330  * This function is called after successful creation of virtqueues.
331  * This function saves queue handle in the vring_info_table which
332  * will be used during interrupt handling .This function setups
333  * interrupt handlers.
334  *
335  * @param vring_index - index to vring HW table
336  * @param vq          - pointer to virtqueue to save in vring HW table
337  *
338  * @return            - execution status
339  */
340 int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq);
342 /**
343  * hil_vdev_notify()
344  *
345  * This function generates IPI to let the other side know that there is
346  * change to virtio device configs.
347  *
348  * @param vdev - pointer to virtio device
349  *
350  */
351 void hil_vdev_notify(struct virtio_device *vdev);
353 /**
354  * hil_vring_notify()
355  *
356  * This function generates IPI to let the other side know that there is
357  * job available for it. The required information to achieve this, like interrupt
358  * vector, CPU id etc is be obtained from the proc_vring table.
359  *
360  * @param vq - pointer to virtqueue
361  *
362  */
363 void hil_vring_notify(struct virtqueue *vq);
365 /**
366  * hil_get_status
367  *
368  * This function is used to check if the given core is up and running.
369  * This call will return after it is confirmed that remote core has
370  * started.
371  *
372  * @param proc - pointer to proc instance
373  *
374  * @return - execution status
375  */
376 int hil_get_status(struct hil_proc *proc);
378 /**
379  * hil_set_status
380  *
381  * This function is used to update the status
382  * of the given core i.e it is ready for IPC.
383  *
384  * @param proc - pointer to remote proc
385  *
386  * @return - execution status
387  */
389 int hil_set_status(struct hil_proc *proc);
391 /**
392  * hil_boot_cpu
393  *
394  * This function starts remote processor at given address.
395  *
396  * @param proc      - pointer to remote proc
397  * @param load_addr - load address of remote firmware
398  *
399  * @return - execution status
400  */
401 int hil_boot_cpu(struct hil_proc *proc, unsigned int load_addr);
403 /**
404  * hil_shutdown_cpu
405  *
406  *  This function shutdowns the remote processor
407  *
408  * @param proc - pointer to remote proc
409  *
410  */
411 void hil_shutdown_cpu(struct hil_proc *proc);
413 /**
414  * hil_get_firmware
415  *
416  * This function returns address and size of given firmware name passed as
417  * parameter.
418  *
419  * @param fw_name    - name of the firmware
420  * @param start_addr - pointer t hold start address of firmware
421  * @param size       - pointer to hold size of firmware
422  *
423  * returns -  status of function execution
424  *
425  */
426 int hil_get_firmware(char *fw_name, uintptr_t *start_addr,
427                      unsigned int *size);
429 /**
430  * hil_poll
431  *
432  * This function polls the remote processor.
433  * If it is blocking mode, it will not return until the remoteproc
434  * is signaled. If it is non-blocking mode, it will return 0
435  * if the remoteproc has pending signals, it will return non 0
436  * otherwise.
437  *
438  * @param proc     - hil_proc to poll
439  * @param nonblock - 0 for blocking, non-0 for non-blocking.
440  *
441  * @return - 0 for no errors, non-0 for errors.
442  */
443 int hil_poll (struct hil_proc *proc, int nonblock);
445 /**
446  * hil_set_shm
447  *
448  * This function set HIL proc shared memory
449  *
450  * @param proc     - hil_proc to set
451  * @param bus_name - bus name of the shared memory device
452  * @param name     - name of the shared memory, or platform device
453  *                   mandatory for Linux system.
454  * @param paddr    - physical address of the memory for baremetal/RTOS only
455  * @param size     - size of the shared memory
456  *
457  * If name argument exists, it will open the specified libmetal
458  * shared memory or the specified libmetal device if bus_name
459  * is specified to get the I/O region of the shared memory. Otherwise, it
460  * will use a generic normal I/O region for the shared memory.
461  * paddr argument is for baremetal/RTOS system only. Linux system
462  * will not take this paddr, for Linux system, you have to specify
463  * the name, otherwise, you will get segfault later.
464  *
465  * @return - 0 for no errors, non-0 for errors.
466  */
467 int hil_set_shm (struct hil_proc *proc,
468                  const char *bus_name, const char *name,
469                  metal_phys_addr_t paddr, size_t size);
471 /**
472  * hil_set_vring
473  *
474  * This function set HIL proc vring
475  *
476  * @param proc     - hil_proc to set
477  * @param index    - vring index
478  * @param bus_name - bus name of the vring device
479  * @param name     - name of the shared memory, or platform device
480  *                   mandatory for Linux system.
481  *
482  * If name argument exists, it will open the specified libmetal
483  * shared memory or the specified device if bus name is specified
484  * to get the I/O region of the vring.
485  *
486  * @return - 0 for no errors, non-0 for errors.
487  */
488 int hil_set_vring (struct hil_proc *proc, int index,
489                    const char *bus_name, const char *name);
491 /**
492  * hil_set_vdev_ipi
493  *
494  * This function set HIL proc vdev IPI
495  *
496  * @param proc     - hil_proc to set
497  * @param index    - vring index for the IPI
498  * @param irq      - IPI irq vector ID
499  * @param data     - IPI data
500  *
501  * @return - 0 for no errors, non-0 for errors.
502  */
503 int hil_set_vdev_ipi (struct hil_proc *proc, int index,
504                  unsigned int irq, void *data);
506 /**
507  * hil_set_vring_ipi
508  *
509  * This function set HIL proc vring IPI
510  *
511  * @param proc     - hil_proc to set
512  * @param index    - vring index for the IPI
513  * @param irq      - IPI irq vector ID
514  * @param data     - IPI data
515  *
516  * @return - 0 for no errors, non-0 for errors.
517  */
518 int hil_set_vring_ipi (struct hil_proc *proc, int index,
519                  unsigned int irq, void *data);
521 /**
522  * hil_set_rpmsg_channel
523  *
524  * This function set HIL proc rpmsg_channel
525  *
526  * @param proc     - hil_proc to set
527  * @param index    - vring index for the rpmsg_channel
528  * @param name     - RPMsg channel name
529  *
530  * @return - 0 for no errors, non-0 for errors.
531  */
532 int hil_set_rpmsg_channel (struct hil_proc *proc, int index,
533                 char *name);
535 /**
536  *
537  * This structure is an interface between HIL and platform porting
538  * component. It is required for the user to provide definitions of
539  * these functions when framework is ported to new hardware platform.
540  *
541  */
542 struct hil_platform_ops {
543         /**
544          * enable_interrupt()
545          *
546          * This function enables interrupt(IPI)
547          *
548          * @param intr - pointer to intr information
549          *
550          * @return  - execution status
551          */
552         int (*enable_interrupt) (struct proc_intr *intr);
554         /**
555          * notify()
556          *
557          * This function generates IPI to let the other side know that there is
558          * job available for it.
559          *
560          * @param proc - pointer to the hil_proc
561          * @param intr_info - pointer to interrupt info control block
562          */
563         void (*notify) (struct hil_proc *proc, struct proc_intr * intr_info);
565         /**
566          * boot_cpu
567          *
568          * This unction boots the remote processor.
569          *
570          * @param proc - pointer to the hil_proc
571          * @param start_addr - start address of remote cpu
572          *
573          * @return - execution status
574          */
575         int (*boot_cpu) (struct hil_proc *proc, unsigned int start_addr);
577         /**
578          * shutdown_cpu
579          *
580          *  This function shutdowns the remote processor.
581          *
582          * @param proc - pointer to the hil_proc
583          *
584          */
585         void (*shutdown_cpu) (struct hil_proc *proc);
587         /**
588          * poll
589          *
590          * This function polls the remote processor.
591          *
592          * @param proc   - hil_proc to poll
593          * @param nonblock - 0 for blocking, non-0 for non-blocking.
594          *
595          * @return - 0 for no errors, non-0 for errors.
596          */
597         int (*poll) (struct hil_proc *proc, int nonblock);
599         /**
600          * initialize
601          *
602          *  This function initialize remote processor with platform data.
603          *
604          * @param proc   - hil_proc to poll
605          *
606          * @return NULL on failure, hil_proc pointer otherwise
607          *
608          */
609         int (*initialize) (struct hil_proc *proc);
611         /**
612          * release
613          *
614          *  This function is to release remote processor resource
615          *
616          * @param[in] proc - pointer to the remote processor
617          *
618          */
619         void (*release) (struct hil_proc *proc);
620 };
622 /* Utility macros for register read/write */
623 #define         HIL_MEM_READ8(addr)         *(volatile unsigned char *)(addr)
624 #define         HIL_MEM_READ16(addr)        *(volatile unsigned short *)(addr)
625 #define         HIL_MEM_READ32(addr)        *(volatile unsigned long *)(addr)
626 #define         HIL_MEM_WRITE8(addr,data)   *(volatile unsigned char *)(addr) = (unsigned char)(data)
627 #define         HIL_MEM_WRITE16(addr,data)  *(volatile unsigned short *)(addr) = (unsigned short)(data)
628 #define         HIL_MEM_WRITE32(addr,data)  *(volatile unsigned long *)(addr) = (unsigned long)(data)
630 #endif                          /* _HIL_H_ */