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