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