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 /* Number of vrings */
140 unsigned int num_vrings;
141 /* Virtio device features */
142 unsigned int dfeatures;
143 /* Virtio gen features */
144 unsigned int gfeatures;
145 /* Vring info control blocks */
146 struct proc_vring vring_info[HIL_MAX_NUM_VRINGS];
147 };
149 /**
150 * struct proc_chnl
151 *
152 * This structure represents channel IDs that would be used by
153 * the remote in the name service message. This will be extended
154 * further to support static channel creation.
155 *
156 */
157 struct proc_chnl {
158 /* Channel ID */
159 char name[32];
160 };
162 /**
163 * struct hil_proc
164 *
165 * This structure represents a remote processor and encapsulates shared
166 * memory and notification info required for IPC.
167 *
168 */
169 struct hil_proc {
170 /* HIL CPU ID */
171 unsigned long cpu_id;
172 /* HIL platform ops table */
173 struct hil_platform_ops *ops;
174 /* Shared memory info */
175 struct proc_shm sh_buff;
176 /* Virtio device hardware info */
177 struct proc_vdev vdev;
178 /* Number of RPMSG channels */
179 unsigned long num_chnls;
180 /* RPMsg channels array */
181 struct proc_chnl chnls[HIL_MAX_NUM_CHANNELS];
182 /* Initialized status */
183 int is_initialized;
184 /* private data */
185 void *pdata;
186 /* List node */
187 struct metal_list node;
188 };
190 /**
191 * hil_create_proc
192 *
193 * This function creates a HIL proc instance
194 *
195 * @param ops - hil proc platform operations
196 * @param cpu_id - remote CPU ID.
197 * E.g. the CPU ID of the remote processor in its
198 * cluster.
199 * @param pdata - private data
200 * @return - pointer to proc instance
201 *
202 */
203 struct hil_proc *hil_create_proc(struct hil_platform_ops *ops,
204 unsigned long cpu_id, void *pdata);
206 /**
207 * hil_delete_proc
208 *
209 * This function deletes the given proc instance and frees the
210 * associated resources.
211 *
212 * @param proc - pointer to HIL proc instance
213 *
214 */
215 void hil_delete_proc(struct hil_proc *proc);
217 /**
218 * hil_init_proc
219 *
220 * This function initialize a HIL proc instance with the given platform data
221 * @param proc - pointer to the hil_proc to initialize
222 *
223 * @return - 0 succeeded, non-0 for failure
224 *
225 */
226 int hil_init_proc(struct hil_proc *proc);
228 /**
229 * hil_isr()
230 *
231 * This function is called when interrupt is received for the vring.
232 * This function gets the corresponding virtqueue and generates
233 * call back for it.
234 *
235 * @param vring_hw - pointer to vring control block
236 *
237 */
238 void hil_isr(struct proc_vring *vring_hw);
240 /**
241 * hil_get_vdev_info
242 *
243 * This function return virtio device for remote core.
244 *
245 * @param proc - pointer to remote proc
246 *
247 * @return - pointer to virtio HW device.
248 *
249 */
250 struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc);
252 /**
253 * hil_get_chnl_info
254 *
255 * This function returns channels info for given proc.
256 *
257 * @param proc - pointer to proc info struct
258 * @param num_chnls - pointer to integer variable to hold
259 * number of available channels
260 *
261 * @return - pointer to channel info control block
262 *
263 */
264 struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc, int *num_chnls);
266 /**
267 * hil_get_vring_info
268 *
269 * This function returns vring_info_table. The caller will use
270 * this table to get the vring HW info which will be subsequently
271 * used to create virtqueues.
272 *
273 * @param vdev - pointer to virtio HW device
274 * @param num_vrings - pointer to hold number of vrings
275 *
276 * @return - pointer to vring hardware info table
277 */
278 struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings);
280 /**
281 * hil_get_shm_info
282 *
283 * This function returns shared memory info control block. The caller
284 * will use this information to create and manage memory buffers for
285 * vring descriptor table.
286 *
287 * @param proc - pointer to proc instance
288 *
289 * @return - pointer to shared memory region used for buffers
290 *
291 */
292 struct proc_shm *hil_get_shm_info(struct hil_proc *proc);
294 /**
295 * hil_enable_vring_notifications()
296 *
297 * This function is called after successful creation of virtqueues.
298 * This function saves queue handle in the vring_info_table which
299 * will be used during interrupt handling .This function setups
300 * interrupt handlers.
301 *
302 * @param vring_index - index to vring HW table
303 * @param vq - pointer to virtqueue to save in vring HW table
304 *
305 * @return - execution status
306 */
307 int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq);
309 /**
310 * hil_vring_notify()
311 *
312 * This function generates IPI to let the other side know that there is
313 * job available for it. The required information to achieve this, like interrupt
314 * vector, CPU id etc is be obtained from the proc_vring table.
315 *
316 * @param vq - pointer to virtqueue
317 *
318 */
319 void hil_vring_notify(struct virtqueue *vq);
321 /**
322 * hil_get_status
323 *
324 * This function is used to check if the given core is up and running.
325 * This call will return after it is confirmed that remote core has
326 * started.
327 *
328 * @param proc - pointer to proc instance
329 *
330 * @return - execution status
331 */
332 int hil_get_status(struct hil_proc *proc);
334 /**
335 * hil_set_status
336 *
337 * This function is used to update the status
338 * of the given core i.e it is ready for IPC.
339 *
340 * @param proc - pointer to remote proc
341 *
342 * @return - execution status
343 */
345 int hil_set_status(struct hil_proc *proc);
347 /**
348 * hil_boot_cpu
349 *
350 * This function starts remote processor at given address.
351 *
352 * @param proc - pointer to remote proc
353 * @param load_addr - load address of remote firmware
354 *
355 * @return - execution status
356 */
357 int hil_boot_cpu(struct hil_proc *proc, unsigned int load_addr);
359 /**
360 * hil_shutdown_cpu
361 *
362 * This function shutdowns the remote processor
363 *
364 * @param proc - pointer to remote proc
365 *
366 */
367 void hil_shutdown_cpu(struct hil_proc *proc);
369 /**
370 * hil_get_firmware
371 *
372 * This function returns address and size of given firmware name passed as
373 * parameter.
374 *
375 * @param fw_name - name of the firmware
376 * @param start_addr - pointer t hold start address of firmware
377 * @param size - pointer to hold size of firmware
378 *
379 * returns - status of function execution
380 *
381 */
382 int hil_get_firmware(char *fw_name, uintptr_t *start_addr,
383 unsigned int *size);
385 /**
386 * hil_poll
387 *
388 * This function polls the remote processor.
389 * If it is blocking mode, it will not return until the remoteproc
390 * is signaled. If it is non-blocking mode, it will return 0
391 * if the remoteproc has pending signals, it will return non 0
392 * otherwise.
393 *
394 * @param proc - hil_proc to poll
395 * @param nonblock - 0 for blocking, non-0 for non-blocking.
396 *
397 * @return - 0 for no errors, non-0 for errors.
398 */
399 int hil_poll (struct hil_proc *proc, int nonblock);
401 /**
402 * hil_set_shm
403 *
404 * This function set HIL proc shared memory
405 *
406 * @param proc - hil_proc to set
407 * @param bus_name - bus name of the shared memory device
408 * @param name - name of the shared memory, or platform device
409 * mandatory for Linux system.
410 * @param paddr - physical address of the memory for baremetal/RTOS only
411 * @param size - size of the shared memory
412 *
413 * If name argument exists, it will open the specified libmetal
414 * shared memory or the specified libmetal device if bus_name
415 * is specified to get the I/O region of the shared memory. Otherwise, it
416 * will use a generic normal I/O region for the shared memory.
417 * paddr argument is for baremetal/RTOS system only. Linux system
418 * will not take this paddr, for Linux system, you have to specify
419 * the name, otherwise, you will get segfault later.
420 *
421 * @return - 0 for no errors, non-0 for errors.
422 */
423 int hil_set_shm (struct hil_proc *proc,
424 const char *bus_name, const char *name,
425 metal_phys_addr_t paddr, size_t size);
427 /**
428 * hil_set_vring
429 *
430 * This function set HIL proc vring
431 *
432 * @param proc - hil_proc to set
433 * @param index - vring index
434 * @param bus_name - bus name of the vring device
435 * @param name - name of the shared memory, or platform device
436 * mandatory for Linux system.
437 *
438 * If name argument exists, it will open the specified libmetal
439 * shared memory or the specified device if bus name is specified
440 * to get the I/O region of the vring.
441 *
442 * @return - 0 for no errors, non-0 for errors.
443 */
444 int hil_set_vring (struct hil_proc *proc, int index,
445 const char *bus_name, const char *name);
447 /**
448 * hil_set_ipi
449 *
450 * This function set HIL proc IPI
451 *
452 * @param proc - hil_proc to set
453 * @param index - vring index for the IPI
454 * @param irq - IPI irq vector ID
455 * @param data - IPI data
456 *
457 * @return - 0 for no errors, non-0 for errors.
458 */
459 int hil_set_ipi (struct hil_proc *proc, int index,
460 unsigned int irq, void *data);
462 /**
463 * hil_set_rpmsg_channel
464 *
465 * This function set HIL proc rpmsg_channel
466 *
467 * @param proc - hil_proc to set
468 * @param index - vring index for the rpmsg_channel
469 * @param name - RPMsg channel name
470 *
471 * @return - 0 for no errors, non-0 for errors.
472 */
473 int hil_set_rpmsg_channel (struct hil_proc *proc, int index,
474 char *name);
476 /**
477 *
478 * This structure is an interface between HIL and platform porting
479 * component. It is required for the user to provide definitions of
480 * these functions when framework is ported to new hardware platform.
481 *
482 */
483 struct hil_platform_ops {
484 /**
485 * enable_interrupt()
486 *
487 * This function enables interrupt(IPI) for given vring.
488 *
489 * @param vring_hw - pointer to vring control block
490 *
491 * @return - execution status
492 */
493 int (*enable_interrupt) (struct proc_vring * vring_hw);
495 /**
496 * notify()
497 *
498 * This function generates IPI to let the other side know that there is
499 * job available for it.
500 *
501 * @param proc - pointer to the hil_proc
502 * @param intr_info - pointer to interrupt info control block
503 */
504 void (*notify) (struct hil_proc *proc, struct proc_intr * intr_info);
506 /**
507 * boot_cpu
508 *
509 * This unction boots the remote processor.
510 *
511 * @param proc - pointer to the hil_proc
512 * @param start_addr - start address of remote cpu
513 *
514 * @return - execution status
515 */
516 int (*boot_cpu) (struct hil_proc *proc, unsigned int start_addr);
518 /**
519 * shutdown_cpu
520 *
521 * This function shutdowns the remote processor.
522 *
523 * @param proc - pointer to the hil_proc
524 *
525 */
526 void (*shutdown_cpu) (struct hil_proc *proc);
528 /**
529 * poll
530 *
531 * This function polls the remote processor.
532 *
533 * @param proc - hil_proc to poll
534 * @param nonblock - 0 for blocking, non-0 for non-blocking.
535 *
536 * @return - 0 for no errors, non-0 for errors.
537 */
538 int (*poll) (struct hil_proc *proc, int nonblock);
540 /**
541 * initialize
542 *
543 * This function initialize remote processor with platform data.
544 *
545 * @param proc - hil_proc to poll
546 *
547 * @return NULL on failure, hil_proc pointer otherwise
548 *
549 */
550 int (*initialize) (struct hil_proc *proc);
552 /**
553 * release
554 *
555 * This function is to release remote processor resource
556 *
557 * @param[in] proc - pointer to the remote processor
558 *
559 */
560 void (*release) (struct hil_proc *proc);
561 };
563 /* Utility macros for register read/write */
564 #define HIL_MEM_READ8(addr) *(volatile unsigned char *)(addr)
565 #define HIL_MEM_READ16(addr) *(volatile unsigned short *)(addr)
566 #define HIL_MEM_READ32(addr) *(volatile unsigned long *)(addr)
567 #define HIL_MEM_WRITE8(addr,data) *(volatile unsigned char *)(addr) = (unsigned char)(data)
568 #define HIL_MEM_WRITE16(addr,data) *(volatile unsigned short *)(addr) = (unsigned short)(data)
569 #define HIL_MEM_WRITE32(addr,data) *(volatile unsigned long *)(addr) = (unsigned long)(data)
571 #endif /* _HIL_H_ */