8dca8aa0638fb12a791916b7f55469bfba841bad
[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"
51 /* Configurable parameters */
52 #define HIL_MAX_CORES                   2
53 #define HIL_MAX_NUM_VRINGS              2
54 #define HIL_MAX_NUM_CHANNELS            1
55 /* Reserved CPU id */
56 #define HIL_RSVD_CPU_ID                 0xffffffff
58 /**
59  * struct proc_shm
60  *
61  * This structure is maintained by hardware interface layer for
62  * shared memory information. The shared memory provides buffers
63  * for use by the vring to exchange messages between the cores.
64  *
65  */
66 struct proc_shm {
67         /* Start address of shared memory used for buffers. */
68         void *start_addr;
69         /* Start physical address of shared memory used for buffers. */
70         metal_phys_addr_t start_paddr;
71         /* sharmed memory I/O region */
72         struct metal_io_region *io;
73         /* sharmed memory metal device */
74         struct metal_device *dev;
75         /* Size of shared memory. */
76         unsigned long size;
77         /* Attributes for shared memory - cached or uncached. */
78         unsigned long flags;
79 };
81 /**
82 * struct proc_intr
83 *
84 * This structure is maintained by hardware interface layer for
85 * notification(interrupts) mechanism. The most common notification mechanism
86 * is Inter-Processor Interrupt(IPI). There can be other mechanism depending
87 * on SoC architecture.
88 *
89 */
90 struct proc_intr {
91         /* Interrupt number for vring - use for IPI */
92         unsigned int vect_id;
93         /* Interrupt priority */
94         unsigned int priority;
95         /* Interrupt trigger type */
96         unsigned int trigger_type;
97         /* IPI metal device */
98         struct metal_device *dev;
99         /* IPI device I/O */
100         struct metal_io_region *io;
101         /* Private data */
102         void *data;
103 };
105 /**
106 * struct proc_vring
108 * This structure is maintained by hardware interface layer to keep
109 * vring physical memory and notification info.
111 */
112 struct proc_vring {
113         /* Pointer to virtqueue encapsulating the vring */
114         struct virtqueue *vq;
115         /* Vring logical address */
116         void *vaddr;
117         /* Vring metal device */
118         struct metal_device *dev;
119         /* Vring I/O region */
120         struct metal_io_region *io;
121         /* Number of vring descriptors */
122         unsigned short num_descs;
123         /* Vring alignment */
124         unsigned long align;
125         /* Vring interrupt control block */
126         struct proc_intr intr_info;
127 };
129 /**
130  * struct proc_vdev
131  *
132  * This structure represents a virtio HW device for remote processor.
133  * Currently only one virtio device per processor is supported.
134  *
135  */
136 struct proc_vdev {
137         /* Address for the vdev info */
138         void *vdev_info;
139         /* Vdev interrupt control block */
140         struct proc_intr intr_info;
141         /* Number of vrings */
142         unsigned int num_vrings;
143         /* Virtio device features */
144         unsigned int dfeatures;
145         /* Virtio gen features */
146         unsigned int gfeatures;
147         /* Vring info control blocks */
148         struct proc_vring vring_info[HIL_MAX_NUM_VRINGS];
149 };
151 /**
152  * struct proc_chnl
153  *
154  * This structure represents channel IDs that would be used by
155  * the remote in the name service message. This will be extended
156  * further to support static channel creation.
157  *
158  */
159 struct proc_chnl {
160         /* Channel ID */
161         char name[32];
162 };
164 /**
165 * struct hil_proc
167 * This structure represents a remote processor and encapsulates shared
168 * memory and notification info required for IPC.
170 */
171 struct hil_proc {
172         /* HIL CPU ID */
173         unsigned long cpu_id;
174         /* HIL platform ops table */
175         struct hil_platform_ops *ops;
176         /* Shared memory info */
177         struct proc_shm sh_buff;
178         /* Virtio device hardware info */
179         struct proc_vdev vdev;
180         /* Number of RPMSG channels */
181         unsigned long num_chnls;
182         /* RPMsg channels array */
183         struct proc_chnl chnls[HIL_MAX_NUM_CHANNELS];
184         /* Initialized status */
185         int is_initialized;
186         /* private data */
187         void *pdata;
188         /* List node */
189         struct metal_list node;
190 };
192 /**
193  * hil_create_proc
194  *
195  * This function creates a HIL proc instance
196  *
197  * @param ops - hil proc platform operations
198  * @param cpu_id - remote CPU ID.
199  *                 E.g. the CPU ID of the remote processor in its
200  *                 cluster.
201  * @param pdata  - private data
202  * @return - pointer to proc instance
203  *
204  */
205 struct hil_proc *hil_create_proc(struct hil_platform_ops *ops,
206                                 unsigned long cpu_id, void *pdata);
208 /**
209  * hil_delete_proc
210  *
211  * This function deletes the given proc instance and frees the
212  * associated resources.
213  *
214  * @param proc - pointer to HIL proc instance
215  *
216  */
217 void hil_delete_proc(struct hil_proc *proc);
219 /**
220  * hil_init_proc
221  *
222  * This function initialize a HIL proc instance with the given platform data
223  * @param proc  - pointer to the hil_proc to initialize
224  *
225  * @return - 0 succeeded, non-0 for failure
226  *
227  */
228 int hil_init_proc(struct hil_proc *proc);
230 /**
231  * hil_isr()
232  *
233  * This function is called when interrupt is received for the vring.
234  * This function gets the corresponding virtqueue and generates
235  * call back for it.
236  *
237  * @param vring_hw   - pointer to vring control block
238  *
239  */
240 void hil_isr(struct proc_vring *vring_hw);
242 /**
243  * hil_get_vdev_info
244  *
245  * This function return virtio device for remote core.
246  *
247  * @param proc - pointer to remote proc
248  *
249  * @return - pointer to virtio HW device.
250  *
251  */
252 struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc);
254 /**
255  * hil_get_chnl_info
256  *
257  * This function returns channels info for given proc.
258  *
259  * @param proc - pointer to proc info struct
260  * @param num_chnls - pointer to integer variable to hold
261  *                    number of available channels
262  *
263  * @return - pointer to channel info control block
264  *
265  */
266 struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc, int *num_chnls);
268 /**
269  * hil_get_vring_info
270  *
271  * This function returns vring_info_table. The caller will use
272  * this table to get the vring HW info which will be subsequently
273  * used to create virtqueues.
274  *
275  * @param vdev - pointer to virtio HW device
276  * @param num_vrings - pointer to hold number of vrings
277  *
278  * @return - pointer to vring hardware info table
279  */
280 struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings);
282 /**
283  * hil_get_shm_info
284  *
285  * This function returns shared memory info control block. The caller
286  * will use this information to create and manage memory buffers for
287  * vring descriptor table.
288  *
289  * @param proc - pointer to proc instance
290  *
291  * @return - pointer to shared memory region used for buffers
292  *
293  */
294 struct proc_shm *hil_get_shm_info(struct hil_proc *proc);
296 /**
297  * hil_enable_vring_notifications()
298  *
299  * This function is called after successful creation of virtqueues.
300  * This function saves queue handle in the vring_info_table which
301  * will be used during interrupt handling .This function setups
302  * interrupt handlers.
303  *
304  * @param vring_index - index to vring HW table
305  * @param vq          - pointer to virtqueue to save in vring HW table
306  *
307  * @return            - execution status
308  */
309 int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq);
311 /**
312  * hil_vdev_notify()
313  *
314  * This function generates IPI to let the other side know that there is
315  * change to virtio device configs.
316  *
317  * @param vdev - pointer to virtio device
318  *
319  */
320 void hil_vdev_notify(struct virtio_device *vdev);
322 /**
323  * hil_vring_notify()
324  *
325  * This function generates IPI to let the other side know that there is
326  * job available for it. The required information to achieve this, like interrupt
327  * vector, CPU id etc is be obtained from the proc_vring table.
328  *
329  * @param vq - pointer to virtqueue
330  *
331  */
332 void hil_vring_notify(struct virtqueue *vq);
334 /**
335  * hil_get_status
336  *
337  * This function is used to check if the given core is up and running.
338  * This call will return after it is confirmed that remote core has
339  * started.
340  *
341  * @param proc - pointer to proc instance
342  *
343  * @return - execution status
344  */
345 int hil_get_status(struct hil_proc *proc);
347 /**
348  * hil_set_status
349  *
350  * This function is used to update the status
351  * of the given core i.e it is ready for IPC.
352  *
353  * @param proc - pointer to remote proc
354  *
355  * @return - execution status
356  */
358 int hil_set_status(struct hil_proc *proc);
360 /**
361  * hil_boot_cpu
362  *
363  * This function starts remote processor at given address.
364  *
365  * @param proc      - pointer to remote proc
366  * @param load_addr - load address of remote firmware
367  *
368  * @return - execution status
369  */
370 int hil_boot_cpu(struct hil_proc *proc, unsigned int load_addr);
372 /**
373  * hil_shutdown_cpu
374  *
375  *  This function shutdowns the remote processor
376  *
377  * @param proc - pointer to remote proc
378  *
379  */
380 void hil_shutdown_cpu(struct hil_proc *proc);
382 /**
383  * hil_get_firmware
384  *
385  * This function returns address and size of given firmware name passed as
386  * parameter.
387  *
388  * @param fw_name    - name of the firmware
389  * @param start_addr - pointer t hold start address of firmware
390  * @param size       - pointer to hold size of firmware
391  *
392  * returns -  status of function execution
393  *
394  */
395 int hil_get_firmware(char *fw_name, uintptr_t *start_addr,
396                      unsigned int *size);
398 /**
399  * hil_poll
400  *
401  * This function polls the remote processor.
402  * If it is blocking mode, it will not return until the remoteproc
403  * is signaled. If it is non-blocking mode, it will return 0
404  * if the remoteproc has pending signals, it will return non 0
405  * otherwise.
406  *
407  * @param proc     - hil_proc to poll
408  * @param nonblock - 0 for blocking, non-0 for non-blocking.
409  *
410  * @return - 0 for no errors, non-0 for errors.
411  */
412 int hil_poll (struct hil_proc *proc, int nonblock);
414 /**
415  * hil_set_shm
416  *
417  * This function set HIL proc shared memory
418  *
419  * @param proc     - hil_proc to set
420  * @param bus_name - bus name of the shared memory device
421  * @param name     - name of the shared memory, or platform device
422  *                   mandatory for Linux system.
423  * @param paddr    - physical address of the memory for baremetal/RTOS only
424  * @param size     - size of the shared memory
425  *
426  * If name argument exists, it will open the specified libmetal
427  * shared memory or the specified libmetal device if bus_name
428  * is specified to get the I/O region of the shared memory. Otherwise, it
429  * will use a generic normal I/O region for the shared memory.
430  * paddr argument is for baremetal/RTOS system only. Linux system
431  * will not take this paddr, for Linux system, you have to specify
432  * the name, otherwise, you will get segfault later.
433  *
434  * @return - 0 for no errors, non-0 for errors.
435  */
436 int hil_set_shm (struct hil_proc *proc,
437                  const char *bus_name, const char *name,
438                  metal_phys_addr_t paddr, size_t size);
440 /**
441  * hil_set_vring
442  *
443  * This function set HIL proc vring
444  *
445  * @param proc     - hil_proc to set
446  * @param index    - vring index
447  * @param bus_name - bus name of the vring device
448  * @param name     - name of the shared memory, or platform device
449  *                   mandatory for Linux system.
450  *
451  * If name argument exists, it will open the specified libmetal
452  * shared memory or the specified device if bus name is specified
453  * to get the I/O region of the vring.
454  *
455  * @return - 0 for no errors, non-0 for errors.
456  */
457 int hil_set_vring (struct hil_proc *proc, int index,
458                    const char *bus_name, const char *name);
460 /**
461  * hil_set_ipi
462  *
463  * This function set HIL proc IPI
464  *
465  * @param proc     - hil_proc to set
466  * @param index    - vring index for the IPI
467  * @param irq      - IPI irq vector ID
468  * @param data     - IPI data
469  *
470  * @return - 0 for no errors, non-0 for errors.
471  */
472 int hil_set_ipi (struct hil_proc *proc, int index,
473                  unsigned int irq, void *data);
475 /**
476  * hil_set_rpmsg_channel
477  *
478  * This function set HIL proc rpmsg_channel
479  *
480  * @param proc     - hil_proc to set
481  * @param index    - vring index for the rpmsg_channel
482  * @param name     - RPMsg channel name
483  *
484  * @return - 0 for no errors, non-0 for errors.
485  */
486 int hil_set_rpmsg_channel (struct hil_proc *proc, int index,
487                 char *name);
489 /**
490  *
491  * This structure is an interface between HIL and platform porting
492  * component. It is required for the user to provide definitions of
493  * these functions when framework is ported to new hardware platform.
494  *
495  */
496 struct hil_platform_ops {
497     /**
498      * enable_interrupt()
499      *
500      * This function enables interrupt(IPI) for given vring.
501      *
502      * @param vring_hw - pointer to vring control block
503      *
504      * @return  - execution status
505      */
506         int (*enable_interrupt) (struct proc_vring * vring_hw);
508     /**
509      * notify()
510      *
511      * This function generates IPI to let the other side know that there is
512      * job available for it.
513      *
514      * @param proc - pointer to the hil_proc
515      * @param intr_info - pointer to interrupt info control block
516      */
517         void (*notify) (struct hil_proc *proc, struct proc_intr * intr_info);
519     /**
520      * boot_cpu
521      *
522      * This unction boots the remote processor.
523      *
524      * @param proc - pointer to the hil_proc
525      * @param start_addr - start address of remote cpu
526      *
527      * @return - execution status
528      */
529         int (*boot_cpu) (struct hil_proc *proc, unsigned int start_addr);
531     /**
532      * shutdown_cpu
533      *
534      *  This function shutdowns the remote processor.
535      *
536      * @param proc - pointer to the hil_proc
537      *
538      */
539         void (*shutdown_cpu) (struct hil_proc *proc);
541     /**
542      * poll
543      *
544      * This function polls the remote processor.
545      *
546      * @param proc     - hil_proc to poll
547      * @param nonblock - 0 for blocking, non-0 for non-blocking.
548      *
549      * @return - 0 for no errors, non-0 for errors.
550      */
551         int (*poll) (struct hil_proc *proc, int nonblock);
553     /**
554      * initialize
555      *
556      *  This function initialize remote processor with platform data.
557      *
558      * @param proc     - hil_proc to poll
559      *
560      * @return NULL on failure, hil_proc pointer otherwise
561      *
562      */
563         int (*initialize) (struct hil_proc *proc);
565     /**
566      * release
567      *
568      *  This function is to release remote processor resource
569      *
570      * @param[in] proc - pointer to the remote processor
571      *
572      */
573         void (*release) (struct hil_proc *proc);
574 };
576 /* Utility macros for register read/write */
577 #define         HIL_MEM_READ8(addr)         *(volatile unsigned char *)(addr)
578 #define         HIL_MEM_READ16(addr)        *(volatile unsigned short *)(addr)
579 #define         HIL_MEM_READ32(addr)        *(volatile unsigned long *)(addr)
580 #define         HIL_MEM_WRITE8(addr,data)   *(volatile unsigned char *)(addr) = (unsigned char)(data)
581 #define         HIL_MEM_WRITE16(addr,data)  *(volatile unsigned short *)(addr) = (unsigned short)(data)
582 #define         HIL_MEM_WRITE32(addr,data)  *(volatile unsigned long *)(addr) = (unsigned long)(data)
584 #endif                          /* _HIL_H_ */