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
107 *
108 * This structure is maintained by hardware interface layer to keep
109 * vring physical memory and notification info.
110 *
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
166 *
167 * This structure represents a remote processor and encapsulates shared
168 * memory and notification info required for IPC.
169 *
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_ */