565629bc897856e1721ba177ca0c2a843a5a7fc9
[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_info_hdr
60  *
61  * This structure is maintained by hardware interface layer
62  * for user to pass hardware information to remote processor.
63  */
64 struct proc_info_hdr {
65         /* CPU ID as defined by the platform */
66         unsigned long cpu_id;
67         /* HIL platform ops table */
68         struct hil_platform_ops *ops;
69 };
71 /**
72  * struct proc_shm
73  *
74  * This structure is maintained by hardware interface layer for
75  * shared memory information. The shared memory provides buffers
76  * for use by the vring to exchange messages between the cores.
77  *
78  */
79 struct proc_shm {
80         /* Start address of shared memory used for buffers. */
81         void *start_addr;
82         /* sharmed memory I/O region */
83         struct metal_io_region *io;
84         /* Size of shared memory. */
85         unsigned long size;
86         /* Attributes for shared memory - cached or uncached. */
87         unsigned long flags;
88 };
90 /**
91 * struct proc_intr
92 *
93 * This structure is maintained by hardware interface layer for
94 * notification(interrupts) mechanism. The most common notification mechanism
95 * is Inter-Processor Interrupt(IPI). There can be other mechanism depending
96 * on SoC architecture.
97 *
98 */
99 struct proc_intr {
100         /* Interrupt number for vring - use for IPI */
101         unsigned int vect_id;
102         /* Interrupt priority */
103         unsigned int priority;
104         /* Interrupt trigger type */
105         unsigned int trigger_type;
106         /* IPI metal device */
107         struct metal_device *dev;
108         /* IPI device I/O */
109         struct metal_io_region *io;
110         /* Private data */
111         void *data;
112 };
114 /**
115 * struct proc_vring
117 * This structure is maintained by hardware interface layer to keep
118 * vring physical memory and notification info.
120 */
121 struct proc_vring {
122         /* Pointer to virtqueue encapsulating the vring */
123         struct virtqueue *vq;
124         /* Vring logical address */
125         void *vaddr;
126         /* Vring metal device */
127         struct metal_device *dev;
128         /* Vring I/O region */
129         struct metal_io_region *io;
130         /* Number of vring descriptors */
131         unsigned short num_descs;
132         /* Vring alignment */
133         unsigned long align;
134         /* Vring interrupt control block */
135         struct proc_intr intr_info;
136 };
138 /**
139  * struct proc_vdev
140  *
141  * This structure represents a virtio HW device for remote processor.
142  * Currently only one virtio device per processor is supported.
143  *
144  */
145 struct proc_vdev {
146         /* Number of vrings */
147         unsigned int num_vrings;
148         /* Virtio device features */
149         unsigned int dfeatures;
150         /* Virtio gen features */
151         unsigned int gfeatures;
152         /* Vring info control blocks */
153         struct proc_vring vring_info[HIL_MAX_NUM_VRINGS];
154 };
156 /**
157  * struct proc_chnl
158  *
159  * This structure represents channel IDs that would be used by
160  * the remote in the name service message. This will be extended
161  * further to support static channel creation.
162  *
163  */
164 struct proc_chnl {
165         /* Channel ID */
166         char name[32];
167 };
169 /**
170 * struct hil_proc
172 * This structure represents a remote processor and encapsulates shared
173 * memory and notification info required for IPC.
175 */
176 struct hil_proc {
177         /* CPU ID as defined by the platform */
178         unsigned long cpu_id;
179         /* HIL platform ops table */
180         struct hil_platform_ops *ops;
181         /* Shared memory info */
182         struct proc_shm sh_buff;
183         /* Virtio device hardware info */
184         struct proc_vdev vdev;
185         /* Number of RPMSG channels */
186         unsigned long num_chnls;
187         /* RPMsg channels array */
188         struct proc_chnl chnls[HIL_MAX_NUM_CHANNELS];
189         /* Attrbites to represent processor role, master or remote . This field is for
190          * future use. */
191         unsigned long attr;
192         /*
193          * CPU bitmask - shared variable updated by each core
194          * after it has been initialized. This field is for future use.
195          */
196         unsigned long cpu_bitmask;
197         /* Spin lock - This field is for future use. */
198         volatile unsigned int *slock;
199         /* List node */
200         struct metal_list node;
201 };
203 /**
204  * hil_create_proc
205  *
206  * This function creates a HIL proc instance for given CPU id and populates
207  * it with platform info.
208  *
209  * @param pdata  - platform data for remote processor
210  * @param cpu_id - cpu id
211  *
212  * @return - pointer to proc instance
213  *
214  */
215 struct hil_proc *hil_create_proc(void *pdata, int cpu_id);
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_get_proc
230  *
231  * This function finds the proc instance based on the given ID
232  * from the proc list and returns it to user.
233  *
234  * @param cpu_id - cpu id
235  *
236  * @return - pointer to proc instance
237  *
238  */
239 struct hil_proc *hil_get_proc(int cpu_id);
241 /**
242  * hil_isr()
243  *
244  * This function is called when interrupt is received for the vring.
245  * This function gets the corresponding virtqueue and generates
246  * call back for it.
247  *
248  * @param vring_hw   - pointer to vring control block
249  *
250  */
251 void hil_isr(struct proc_vring *vring_hw);
253 /**
254  * hil_get_vdev_info
255  *
256  * This function return virtio device for remote core.
257  *
258  * @param proc - pointer to remote proc
259  *
260  * @return - pointer to virtio HW device.
261  *
262  */
263 struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc);
265 /**
266  * hil_get_chnl_info
267  *
268  * This function returns channels info for given proc.
269  *
270  * @param proc - pointer to proc info struct
271  * @param num_chnls - pointer to integer variable to hold
272  *                    number of available channels
273  *
274  * @return - pointer to channel info control block
275  *
276  */
277 struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc, int *num_chnls);
279 /**
280  * hil_get_vring_info
281  *
282  * This function returns vring_info_table. The caller will use
283  * this table to get the vring HW info which will be subsequently
284  * used to create virtqueues.
285  *
286  * @param vdev - pointer to virtio HW device
287  * @param num_vrings - pointer to hold number of vrings
288  *
289  * @return - pointer to vring hardware info table
290  */
291 struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings);
293 /**
294  * hil_get_shm_info
295  *
296  * This function returns shared memory info control block. The caller
297  * will use this information to create and manage memory buffers for
298  * vring descriptor table.
299  *
300  * @param proc - pointer to proc instance
301  *
302  * @return - pointer to shared memory region used for buffers
303  *
304  */
305 struct proc_shm *hil_get_shm_info(struct hil_proc *proc);
307 /**
308  * hil_enable_vring_notifications()
309  *
310  * This function is called after successful creation of virtqueues.
311  * This function saves queue handle in the vring_info_table which
312  * will be used during interrupt handling .This function setups
313  * interrupt handlers.
314  *
315  * @param vring_index - index to vring HW table
316  * @param vq          - pointer to virtqueue to save in vring HW table
317  *
318  * @return            - execution status
319  */
320 int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq);
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);
413 /**
414  *
415  * This structure is an interface between HIL and platform porting
416  * component. It is required for the user to provide definitions of
417  * these functions when framework is ported to new hardware platform.
418  *
419  */
420 struct hil_platform_ops {
421     /**
422      * enable_interrupt()
423      *
424      * This function enables interrupt(IPI) for given vring.
425      *
426      * @param vring_hw - pointer to vring control block
427      *
428      * @return  - execution status
429      */
430         int (*enable_interrupt) (struct proc_vring * vring_hw);
432     /**
433      * notify()
434      *
435      * This function generates IPI to let the other side know that there is
436      * job available for it.
437      *
438      * @param cpu_id - ID of CPU which is to be notified
439      * @param intr_info - pointer to interrupt info control block
440      */
441         void (*notify) (int cpu_id, struct proc_intr * intr_info);
443     /**
444      * get_status
445      *
446      * This function is used to check if the given core is
447      * up and running. This call will return after it is confirmed
448      * that remote core is initialized.
449      *
450      * @param cpu_id - ID of CPU for which status is requested.
451      *
452      * @return - execution status
453      */
454         int (*get_status) (int cpu_id);
456     /**
457      * set_status
458      *
459      * This function is used to update the status
460      * of the given core i.e it is ready for IPC.
461      *
462      * @param cpu_id - ID of CPU for which status is to be set
463      *
464      * @return - execution status
465      */
467         int (*set_status) (int cpu_id);
469     /**
470      * boot_cpu
471      *
472      * This function boots the remote processor.
473      *
474      * @param cpu_id     - ID of CPU to boot
475      * @param start_addr - start address of remote cpu
476      *
477      * @return - execution status
478      */
479         int (*boot_cpu) (int cpu_id, unsigned int start_addr);
481     /**
482      * shutdown_cpu
483      *
484      *  This function shutdowns the remote processor.
485      *
486      * @param cpu_id    - ID of CPU to shutdown
487      *
488      */
489         void (*shutdown_cpu) (int cpu_id);
491     /**
492      * poll
493      *
494      * This function polls the remote processor.
495      *
496      * @param proc     - hil_proc to poll
497      * @param nonblock - 0 for blocking, non-0 for non-blocking.
498      *
499      * @return - 0 for no errors, non-0 for errors.
500      */
501         int (*poll) (struct hil_proc *proc, int nonblock);
503     /**
504      * initialize
505      *
506      *  This function initialize remote processor with platform data.
507      *
508      * @param[in] pdata - platform data
509      * @param[in] cpu_id - CPU id
510      *
511      * @return NULL on failure, hil_proc pointer otherwise
512      *
513      */
514         struct hil_proc *(*initialize) (void *pdata, int cpu_id);
516     /**
517      * release
518      *
519      *  This function is to release remote processor resource
520      *
521      * @param[in] proc - pointer to the remote processor
522      *
523      */
524         void (*release) (struct hil_proc *proc);
525 };
527 /* Utility macros for register read/write */
528 #define         HIL_MEM_READ8(addr)         *(volatile unsigned char *)(addr)
529 #define         HIL_MEM_READ16(addr)        *(volatile unsigned short *)(addr)
530 #define         HIL_MEM_READ32(addr)        *(volatile unsigned long *)(addr)
531 #define         HIL_MEM_WRITE8(addr,data)   *(volatile unsigned char *)(addr) = (unsigned char)(data)
532 #define         HIL_MEM_WRITE16(addr,data)  *(volatile unsigned short *)(addr) = (unsigned short)(data)
533 #define         HIL_MEM_WRITE32(addr,data)  *(volatile unsigned long *)(addr) = (unsigned long)(data)
535 #endif                          /* _HIL_H_ */