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"
49 /* Configurable parameters */
50 #define HIL_MAX_CORES 2
51 #define HIL_MAX_NUM_VRINGS 2
52 #define HIL_MAX_NUM_CHANNELS 1
53 /* Reserved CPU id */
54 #define HIL_RSVD_CPU_ID 0xffffffff
56 /**
57 * struct proc_info_hdr
58 *
59 * This structure is maintained by hardware interface layer
60 * for user to pass hardware information to remote processor.
61 */
62 struct proc_info_hdr {
63 /* CPU ID as defined by the platform */
64 unsigned long cpu_id;
65 /* HIL platform ops table */
66 struct hil_platform_ops *ops;
67 };
69 /**
70 * struct proc_shm
71 *
72 * This structure is maintained by hardware interface layer for
73 * shared memory information. The shared memory provides buffers
74 * for use by the vring to exchange messages between the cores.
75 *
76 */
77 struct proc_shm {
78 /* Start address of shared memory used for buffers. */
79 void *start_addr;
80 /* Size of shared memory. */
81 unsigned long size;
82 /* Attributes for shared memory - cached or uncached. */
83 unsigned long flags;
84 };
86 /**
87 * struct proc_intr
88 *
89 * This structure is maintained by hardware interface layer for
90 * notification(interrupts) mechanism. The most common notification mechanism
91 * is Inter-Processor Interrupt(IPI). There can be other mechanism depending
92 * on SoC architecture.
93 *
94 */
95 struct proc_intr {
96 /* Interrupt number for vring - use for IPI */
97 unsigned int vect_id;
98 /* Interrupt priority */
99 unsigned int priority;
100 /* Interrupt trigger type */
101 unsigned int trigger_type;
102 /* Private data */
103 void *data;
104 };
106 /**
107 * struct proc_vring
108 *
109 * This structure is maintained by hardware interface layer to keep
110 * vring physical memory and notification info.
111 *
112 */
113 struct proc_vring {
114 /* Pointer to virtqueue encapsulating the vring */
115 struct virtqueue *vq;
116 /* Vring logical address */
117 void *vaddr;
118 /* Number of vring descriptors */
119 unsigned short num_descs;
120 /* Vring alignment */
121 unsigned long align;
122 /* Vring interrupt control block */
123 struct proc_intr intr_info;
124 };
126 /**
127 * struct proc_vdev
128 *
129 * This structure represents a virtio HW device for remote processor.
130 * Currently only one virtio device per processor is supported.
131 *
132 */
133 struct proc_vdev {
134 /* Number of vrings */
135 unsigned int num_vrings;
136 /* Virtio device features */
137 unsigned int dfeatures;
138 /* Virtio gen features */
139 unsigned int gfeatures;
140 /* Vring info control blocks */
141 struct proc_vring vring_info[HIL_MAX_NUM_VRINGS];
142 };
144 /**
145 * struct proc_chnl
146 *
147 * This structure represents channel IDs that would be used by
148 * the remote in the name service message. This will be extended
149 * further to support static channel creation.
150 *
151 */
152 struct proc_chnl {
153 /* Channel ID */
154 char name[32];
155 };
157 /**
158 * struct hil_proc
159 *
160 * This structure represents a remote processor and encapsulates shared
161 * memory and notification info required for IPC.
162 *
163 */
164 struct hil_proc {
165 /* CPU ID as defined by the platform */
166 unsigned long cpu_id;
167 /* HIL platform ops table */
168 struct hil_platform_ops *ops;
169 /* Shared memory info */
170 struct proc_shm sh_buff;
171 /* Virtio device hardware info */
172 struct proc_vdev vdev;
173 /* Number of RPMSG channels */
174 unsigned long num_chnls;
175 /* RPMsg channels array */
176 struct proc_chnl chnls[HIL_MAX_NUM_CHANNELS];
177 /* Attrbites to represent processor role, master or remote . This field is for
178 * future use. */
179 unsigned long attr;
180 /*
181 * CPU bitmask - shared variable updated by each core
182 * after it has been initialized. This field is for future use.
183 */
184 unsigned long cpu_bitmask;
185 /* Spin lock - This field is for future use. */
186 volatile unsigned int *slock;
187 /* List node */
188 struct metal_list node;
189 };
191 /**
192 * hil_create_proc
193 *
194 * This function creates a HIL proc instance for given CPU id and populates
195 * it with platform info.
196 *
197 * @param pdata - platform data for remote processor
198 * @param cpu_id - cpu id
199 *
200 * @return - pointer to proc instance
201 *
202 */
203 struct hil_proc *hil_create_proc(void *pdata, int cpu_id);
205 /**
206 * hil_delete_proc
207 *
208 * This function deletes the given proc instance and frees the
209 * associated resources.
210 *
211 * @param proc - pointer to HIL proc instance
212 *
213 */
214 void hil_delete_proc(struct hil_proc *proc);
216 /**
217 * hil_get_proc
218 *
219 * This function finds the proc instance based on the given ID
220 * from the proc list and returns it to user.
221 *
222 * @param cpu_id - cpu id
223 *
224 * @return - pointer to proc instance
225 *
226 */
227 struct hil_proc *hil_get_proc(int cpu_id);
229 /**
230 * hil_isr()
231 *
232 * This function is called when interrupt is received for the vring.
233 * This function gets the corresponding virtqueue and generates
234 * call back for it.
235 *
236 * @param vring_hw - pointer to vring control block
237 *
238 */
239 void hil_isr(struct proc_vring *vring_hw);
241 /**
242 * hil_get_vdev_info
243 *
244 * This function return virtio device for remote core.
245 *
246 * @param proc - pointer to remote proc
247 *
248 * @return - pointer to virtio HW device.
249 *
250 */
251 struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc);
253 /**
254 * hil_get_chnl_info
255 *
256 * This function returns channels info for given proc.
257 *
258 * @param proc - pointer to proc info struct
259 * @param num_chnls - pointer to integer variable to hold
260 * number of available channels
261 *
262 * @return - pointer to channel info control block
263 *
264 */
265 struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc, int *num_chnls);
267 /**
268 * hil_get_vring_info
269 *
270 * This function returns vring_info_table. The caller will use
271 * this table to get the vring HW info which will be subsequently
272 * used to create virtqueues.
273 *
274 * @param vdev - pointer to virtio HW device
275 * @param num_vrings - pointer to hold number of vrings
276 *
277 * @return - pointer to vring hardware info table
278 */
279 struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings);
281 /**
282 * hil_get_shm_info
283 *
284 * This function returns shared memory info control block. The caller
285 * will use this information to create and manage memory buffers for
286 * vring descriptor table.
287 *
288 * @param proc - pointer to proc instance
289 *
290 * @return - pointer to shared memory region used for buffers
291 *
292 */
293 struct proc_shm *hil_get_shm_info(struct hil_proc *proc);
295 /**
296 * hil_enable_vring_notifications()
297 *
298 * This function is called after successful creation of virtqueues.
299 * This function saves queue handle in the vring_info_table which
300 * will be used during interrupt handling .This function setups
301 * interrupt handlers.
302 *
303 * @param vring_index - index to vring HW table
304 * @param vq - pointer to virtqueue to save in vring HW table
305 *
306 * @return - execution status
307 */
308 int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq);
310 /**
311 * hil_vring_notify()
312 *
313 * This function generates IPI to let the other side know that there is
314 * job available for it. The required information to achieve this, like interrupt
315 * vector, CPU id etc is be obtained from the proc_vring table.
316 *
317 * @param vq - pointer to virtqueue
318 *
319 */
320 void hil_vring_notify(struct virtqueue *vq);
322 /**
323 * hil_get_status
324 *
325 * This function is used to check if the given core is up and running.
326 * This call will return after it is confirmed that remote core has
327 * started.
328 *
329 * @param proc - pointer to proc instance
330 *
331 * @return - execution status
332 */
333 int hil_get_status(struct hil_proc *proc);
335 /**
336 * hil_set_status
337 *
338 * This function is used to update the status
339 * of the given core i.e it is ready for IPC.
340 *
341 * @param proc - pointer to remote proc
342 *
343 * @return - execution status
344 */
346 int hil_set_status(struct hil_proc *proc);
348 /**
349 * hil_boot_cpu
350 *
351 * This function starts remote processor at given address.
352 *
353 * @param proc - pointer to remote proc
354 * @param load_addr - load address of remote firmware
355 *
356 * @return - execution status
357 */
358 int hil_boot_cpu(struct hil_proc *proc, unsigned int load_addr);
360 /**
361 * hil_shutdown_cpu
362 *
363 * This function shutdowns the remote processor
364 *
365 * @param proc - pointer to remote proc
366 *
367 */
368 void hil_shutdown_cpu(struct hil_proc *proc);
370 /**
371 * hil_get_firmware
372 *
373 * This function returns address and size of given firmware name passed as
374 * parameter.
375 *
376 * @param fw_name - name of the firmware
377 * @param start_addr - pointer t hold start address of firmware
378 * @param size - pointer to hold size of firmware
379 *
380 * returns - status of function execution
381 *
382 */
383 int hil_get_firmware(char *fw_name, unsigned int *start_addr,
384 unsigned int *size);
386 /**
387 *
388 * This structure is an interface between HIL and platform porting
389 * component. It is required for the user to provide definitions of
390 * these functions when framework is ported to new hardware platform.
391 *
392 */
393 struct hil_platform_ops {
394 /**
395 * enable_interrupt()
396 *
397 * This function enables interrupt(IPI) for given vring.
398 *
399 * @param vring_hw - pointer to vring control block
400 *
401 * @return - execution status
402 */
403 int (*enable_interrupt) (struct proc_vring * vring_hw);
405 /**
406 * notify()
407 *
408 * This function generates IPI to let the other side know that there is
409 * job available for it.
410 *
411 * @param cpu_id - ID of CPU which is to be notified
412 * @param intr_info - pointer to interrupt info control block
413 */
414 void (*notify) (int cpu_id, struct proc_intr * intr_info);
416 /**
417 * get_status
418 *
419 * This function is used to check if the given core is
420 * up and running. This call will return after it is confirmed
421 * that remote core is initialized.
422 *
423 * @param cpu_id - ID of CPU for which status is requested.
424 *
425 * @return - execution status
426 */
427 int (*get_status) (int cpu_id);
429 /**
430 * set_status
431 *
432 * This function is used to update the status
433 * of the given core i.e it is ready for IPC.
434 *
435 * @param cpu_id - ID of CPU for which status is to be set
436 *
437 * @return - execution status
438 */
440 int (*set_status) (int cpu_id);
442 /**
443 * boot_cpu
444 *
445 * This function boots the remote processor.
446 *
447 * @param cpu_id - ID of CPU to boot
448 * @param start_addr - start address of remote cpu
449 *
450 * @return - execution status
451 */
452 int (*boot_cpu) (int cpu_id, unsigned int start_addr);
454 /**
455 * shutdown_cpu
456 *
457 * This function shutdowns the remote processor.
458 *
459 * @param cpu_id - ID of CPU to shutdown
460 *
461 */
462 void (*shutdown_cpu) (int cpu_id);
464 /**
465 * initialize
466 *
467 * This function initialize remote processor with platform data.
468 *
469 * @param[in] pdata - platform data
470 * @param[in] cpu_id - CPU id
471 *
472 * @return NULL on failure, hil_proc pointer otherwise
473 *
474 */
475 struct hil_proc *(*initialize) (void *pdata, int cpu_id);
477 /**
478 * release
479 *
480 * This function is to release remote processor resource
481 *
482 * @param[in] proc - pointer to the remote processor
483 *
484 */
485 void (*release) (struct hil_proc *proc);
486 };
488 /* Utility macros for register read/write */
489 #define HIL_MEM_READ8(addr) *(volatile unsigned char *)(addr)
490 #define HIL_MEM_READ16(addr) *(volatile unsigned short *)(addr)
491 #define HIL_MEM_READ32(addr) *(volatile unsigned long *)(addr)
492 #define HIL_MEM_WRITE8(addr,data) *(volatile unsigned char *)(addr) = (unsigned char)(data)
493 #define HIL_MEM_WRITE16(addr,data) *(volatile unsigned short *)(addr) = (unsigned short)(data)
494 #define HIL_MEM_WRITE32(addr,data) *(volatile unsigned long *)(addr) = (unsigned long)(data)
496 #endif /* _HIL_H_ */