blob: 776b8b26af8f0cb799f0bebae2d30960d1de71f0 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#ifndef _VCM_H_
15#define _VCM_H_
16
17/* All undefined types must be defined using platform specific headers */
18
19#include <linux/vcm_types.h>
20
21/*
22 * Virtual contiguous memory (VCM) region primitives.
23 *
24 * Current memory mapping software uses a CPU centric management
25 * model. This makes sense in general, average hardware only contains an
26 * CPU MMU and possibly a graphics MMU. If every device in the system
27 * has one or more MMUs a CPU centric MM programming model breaks down.
28 *
29 * Looking at mapping from a system-wide perspective reveals a general
30 * graph problem. Each node that talks to memory, either through an MMU
31 * or directly (via physical memory) can be thought of as the device end
32 * of a mapping edge. The other edge is the physical memory that is
33 * mapped.
34 *
35 * In the direct mapped case, it is useful to give the device an
36 * MMU. This one-to-one MMU allows direct mapped devices to
37 * participate in graph management, they simply see memory through a
38 * one-to-one mapping.
39 *
40 * The CPU nodes can also be brought under the same mapping
41 * abstraction with the use of a light overlay on the existing
42 * VMM. This light overlay brings the VMM's page table abstraction for
43 * each process and the kernel into the graph management API.
44 *
45 * Taken together this system wide approach provides a capability that
46 * is greater than the sum of its parts by allowing users to reason
47 * about system wide mapping issues without getting bogged down in CPU
48 * centric device page table management issues.
49 */
50
51
52/*
53 * Creating, freeing and managing VCMs.
54 *
55 * A VCM region is a virtual space that can be reserved from and
56 * associated with one or more devices. At creation the user can
57 * specify an offset to start addresses and a length of the entire VCM
58 * region. Reservations out of a VCM region are always contiguous.
59 */
60
61/**
62 * vcm_create() - Create a VCM region
63 * @start_addr: The starting address of the VCM region.
64 * @len: The len of the VCM region. This must be at least
65 * vcm_get_min_page_size() bytes.
66 *
67 * A VCM typically abstracts a page table.
68 *
69 * All functions in this API are passed and return opaque things
70 * because the underlying implementations will vary. The goal
71 * is really graph management. vcm_create() creates the "device end"
72 * of an edge in the mapping graph.
73 *
74 * The return value is non-zero if a VCM has successfully been
75 * created. It will return zero if a VCM region cannot be created or
76 * len is invalid.
77 */
78struct vcm *vcm_create(unsigned long start_addr, size_t len);
79
80
81/**
82 * vcm_create_from_prebuilt() - Create a VCM region from an existing region
83 * @ext_vcm_id: An external opaque value that allows the
84 * implementation to reference an already built table.
85 *
86 * The ext_vcm_id will probably reference a page table that's been built
87 * by the VM.
88 *
89 * The platform specific implementation will provide this.
90 *
91 * The return value is non-zero if a VCM has successfully been created.
92 */
93struct vcm *vcm_create_from_prebuilt(size_t ext_vcm_id);
94
95
96/**
97 * vcm_clone() - Clone a VCM
98 * @vcm: A VCM to clone from.
99 *
100 * Perform a VCM "deep copy." The resulting VCM will match the original at
101 * the point of cloning. Subsequent updates to either VCM will only be
102 * seen by that VCM.
103 *
104 * The return value is non-zero if a VCM has been successfully cloned.
105 */
106struct vcm *vcm_clone(struct vcm *vcm);
107
108
109/**
110 * vcm_get_start_addr() - Get the starting address of the VCM region.
111 * @vcm: The VCM we're interested in getting the starting
112 * address of.
113 *
114 * The return value will be 1 if an error has occurred.
115 */
116size_t vcm_get_start_addr(struct vcm *vcm);
117
118
119/**
120 * vcm_get_len() - Get the length of the VCM region.
121 * @vcm: The VCM we're interested in reading the length from.
122 *
123 * The return value will be non-zero for a valid VCM. VCM regions
124 * cannot have 0 len.
125 */
126size_t vcm_get_len(struct vcm *vcm);
127
128
129/**
130 * vcm_free() - Free a VCM.
131 * @vcm: The VCM we're interested in freeing.
132 *
133 * The return value is 0 if the VCM has been freed or:
134 * -EBUSY The VCM region contains reservations or has been
135 * associated (active or not) and cannot be freed.
136 * -EINVAL The vcm argument is invalid.
137 */
138int vcm_free(struct vcm *vcm);
139
140
141/*
142 * Creating, freeing and managing reservations out of a VCM.
143 *
144 */
145
146/**
147 * vcm_reserve() - Create a reservation from a VCM region.
148 * @vcm: The VCM region to reserve from.
149 * @len: The length of the reservation. Must be at least
150 * vcm_get_min_page_size() bytes.
151 * @attr: See 'Reservation Attributes'.
152 *
153 * A reservation, res_t, is a contiguous range from a VCM region.
154 *
155 * The return value is non-zero if a reservation has been successfully
156 * created. It is 0 if any of the parameters are invalid.
157 */
158struct res *vcm_reserve(struct vcm *vcm, size_t len, u32 attr);
159
160
161/**
162 * vcm_reserve_at() - Make a reservation at a given logical location.
163 * @memtarget: A logical location to start the reservation from.
164 * @vcm: The VCM region to start the reservation from.
165 * @len: The length of the reservation.
166 * @attr: See 'Reservation Attributes'.
167 *
168 * The return value is non-zero if a reservation has been successfully
169 * created.
170 */
171struct res *vcm_reserve_at(enum memtarget_t memtarget, struct vcm *vcm,
172 size_t len, u32 attr);
173
174
175/**
176 * vcm_get_vcm_from_res() - Return the VCM region of a reservation.
177 * @res: The reservation to return the VCM region of.
178 *
179 * Te return value will be non-zero if the reservation is valid. A valid
180 * reservation is always associated with a VCM region; there is no such
181 * thing as an orphan reservation.
182 */
183struct vcm *vcm_get_vcm_from_res(struct res *res);
184
185
186/**
187 * vcm_unreserve() - Unreserve the reservation.
188 * @res: The reservation to unreserve.
189 *
190 * The return value will be 0 if the reservation was successfully
191 * unreserved and:
192 * -EBUSY The reservation is still backed,
193 * -EINVAL The vcm argument is invalid.
194 */
195int vcm_unreserve(struct res *res);
196
197
198/**
199 * vcm_set_res_attr() - Set attributes of an existing reservation.
200 * @res: An existing reservation of interest.
201 * @attr: See 'Reservation Attributes'.
202 *
203 * This function can only be used on an existing reservation; there
204 * are no orphan reservations. All attributes can be set on a existing
205 * reservation.
206 *
207 * The return value will be 0 for a success, otherwise it will be:
208 * -EINVAL res or attr are invalid.
209 */
210int vcm_set_res_attr(struct res *res, u32 attr);
211
212
213/**
214 * vcm_get_num_res() - Return the number of reservations in a VCM region.
215 * @vcm: The VCM region of interest.
216 */
217size_t vcm_get_num_res(struct vcm *vcm);
218
219
220/**
221 * vcm_get_next_res() - Read each reservation one at a time.
222 * @vcm: The VCM region of interest.
223 * @res: Contains the last reservation. Pass NULL on the
224 * first call.
225 *
226 * This function works like a foreach reservation in a VCM region.
227 *
228 * The return value will be non-zero for each reservation in a VCM. A
229 * zero indicates no further reservations.
230 */
231struct res *vcm_get_next_res(struct vcm *vcm, struct res *res);
232
233
234/**
235 * vcm_res_copy() - Copy len bytes from one reservation to another.
236 * @to: The reservation to copy to.
237 * @from: The reservation to copy from.
238 * @len: The length of bytes to copy.
239 *
240 * The return value is the number of bytes copied.
241 */
242size_t vcm_res_copy(struct res *to, size_t to_off, struct res *from, size_t
243 from_off, size_t len);
244
245
246/**
247 * vcm_get_min_page_size() - Return the minimum page size supported by
248 * the architecture.
249 */
250size_t vcm_get_min_page_size(void);
251
252
253/**
254 * vcm_back() - Physically back a reservation.
255 * @res: The reservation containing the virtual contiguous
256 * region to back.
257 * @physmem: The physical memory that will back the virtual
258 * contiguous memory region.
259 *
260 * One VCM can be associated with multiple devices. When you vcm_back()
261 * each association must be active. This is not strictly necessary. It may
262 * be changed in the future.
263 *
264 * This function returns 0 on a successful physical backing. Otherwise
265 * it returns:
266 * -EINVAL res or physmem is invalid or res's len
267 * is different from physmem's len.
268 * -EAGAIN Try again, one of the devices hasn't been activated.
269 */
270int vcm_back(struct res *res, struct physmem *physmem);
271
272
273/**
274 * vcm_unback() - Unback a reservation.
275 * @res: The reservation to unback.
276 *
277 * One VCM can be associated with multiple devices. When you vcm_unback()
278 * each association must be active.
279 *
280 * This function returns 0 on a successful unbacking. Otherwise
281 * it returns:
282 * -EINVAL res is invalid.
283 * -EAGAIN Try again, one of the devices hasn't been activated.
284 */
285int vcm_unback(struct res *res);
286
287
288/**
289 * vcm_phys_alloc() - Allocate physical memory for the VCM region.
290 * @memtype: The memory type to allocate.
291 * @len: The length of the allocation.
292 * @attr: See 'Physical Allocation Attributes'.
293 *
294 * This function will allocate chunks of memory according to the attr
295 * it is passed.
296 *
297 * The return value is non-zero if physical memory has been
298 * successfully allocated.
299 */
300struct physmem *vcm_phys_alloc(enum memtype_t memtype, size_t len, u32 attr);
301
302
303/**
304 * vcm_phys_free() - Free a physical allocation.
305 * @physmem: The physical allocation to free.
306 *
307 * The return value is 0 if the physical allocation has been freed or:
308 * -EBUSY Their are reservation mapping the physical memory.
309 * -EINVAL The physmem argument is invalid.
310 */
311int vcm_phys_free(struct physmem *physmem);
312
313
314/**
315 * vcm_get_physmem_from_res() - Return a reservation's physmem
316 * @res: An existing reservation of interest.
317 *
318 * The return value will be non-zero on success, otherwise it will be:
319 * -EINVAL res is invalid
320 * -ENOMEM res is unbacked
321 */
322struct physmem *vcm_get_physmem_from_res(struct res *res);
323
324
325/**
326 * vcm_get_memtype_of_physalloc() - Return the memtype of a reservation.
327 * @physmem: The physical allocation of interest.
328 *
329 * This function returns the memtype of a reservation or VCM_INVALID
330 * if res is invalid.
331 */
332enum memtype_t vcm_get_memtype_of_physalloc(struct physmem *physmem);
333
334
335/*
336 * Associate a VCM with a device, activate that association and remove it.
337 *
338 */
339
340/**
341 * vcm_assoc() - Associate a VCM with a device.
342 * @vcm: The VCM region of interest.
343 * @dev: The device to associate the VCM with.
344 * @attr: See 'Association Attributes'.
345 *
346 * This function returns non-zero if a association is made. It returns 0
347 * if any of its parameters are invalid or VCM_ATTR_VALID is not present.
348 */
349struct avcm *vcm_assoc(struct vcm *vcm, struct device *dev, u32 attr);
350
351
352/**
353 * vcm_deassoc() - Deassociate a VCM from a device.
354 * @avcm: The association we want to break.
355 *
356 * The function returns 0 on success or:
357 * -EBUSY The association is currently activated.
358 * -EINVAL The avcm parameter is invalid.
359 */
360int vcm_deassoc(struct avcm *avcm);
361
362
363/**
364 * vcm_set_assoc_attr() - Set an AVCM's attributes.
365 * @avcm: The AVCM of interest.
366 * @attr: The new attr. See 'Association Attributes'.
367 *
368 * Every attribute can be set at runtime if an association isn't activated.
369 *
370 * This function returns 0 on success or:
371 * -EBUSY The association is currently activated.
372 * -EINVAL The avcm parameter is invalid.
373 */
374int vcm_set_assoc_attr(struct avcm *avcm, u32 attr);
375
376
377/**
378 * vcm_get_assoc_attr() - Return an AVCM's attributes.
379 * @avcm: The AVCM of interest.
380 *
381 * This function returns 0 on error.
382 */
383u32 vcm_get_assoc_attr(struct avcm *avcm);
384
385
386/**
387 * vcm_activate() - Activate an AVCM.
388 * @avcm: The AVCM to activate.
389 *
390 * You have to deactivate, before you activate.
391 *
392 * This function returns 0 on success or:
393 * -EINVAL avcm is invalid
394 * -ENODEV no device
395 * -EBUSY device is already active
396 * -1 hardware failure
397 */
398int vcm_activate(struct avcm *avcm);
399
400
401/**
402 * vcm_deactivate() - Deactivate an association.
403 * @avcm: The AVCM to deactivate.
404 *
405 * This function returns 0 on success or:
406 * -ENOENT avcm is not activate
407 * -EINVAL avcm is invalid
408 * -1 hardware failure
409 */
410int vcm_deactivate(struct avcm *avcm);
411
412
413/**
414 * vcm_is_active() - Query if an AVCM is active.
415 * @avcm: The AVCM of interest.
416 *
417 * returns 0 for not active, 1 for active or -EINVAL for error.
418 *
419 */
420int vcm_is_active(struct avcm *avcm);
421
422
423/*
424 * Create, manage and remove a boundary in a VCM.
425 */
426
427/**
428 * vcm_create_bound() - Create a bound in a VCM.
429 * @vcm: The VCM that needs a bound.
430 * @len: The len of the bound.
431 *
432 * The allocator picks the virtual addresses of the bound.
433 *
434 * This function returns non-zero if a bound was created.
435 */
436struct bound *vcm_create_bound(struct vcm *vcm, size_t len);
437
438
439/**
440 * vcm_free_bound() - Free a bound.
441 * @bound: The bound to remove.
442 *
443 * This function returns 0 if bound has been removed or:
444 * -EBUSY The bound contains reservations and cannot be removed.
445 * -EINVAL The bound is invalid.
446 */
447int vcm_free_bound(struct bound *bound);
448
449
450/**
451 * vcm_reserve_from_bound() - Make a reservation from a bounded area.
452 * @bound: The bound to reserve from.
453 * @len: The len of the reservation.
454 * @attr: See 'Reservation Attributes'.
455 *
456 * The return value is non-zero on success. It is 0 if any parameter
457 * is invalid.
458 */
459struct res *vcm_reserve_from_bound(struct bound *bound, size_t len,
460 u32 attr);
461
462
463/**
464 * vcm_get_bound_start_addr() - Return the starting device address of the bound
465 * @bound: The bound of interest.
466 *
467 * On success this function returns the starting addres of the bound. On error
468 * it returns:
469 * 1 bound_id is invalid.
470 */
471size_t vcm_get_bound_start_addr(struct bound *bound);
472
473
474
475/*
476 * Perform low-level control over VCM regions and reservations.
477 */
478
479/**
480 * vcm_map_phys_addr() - Produce a physmem from a contiguous
481 * physical address
482 *
483 * @phys: The physical address of the contiguous range.
484 * @len: The len of the contiguous address range.
485 *
486 * Returns non-zero on success, 0 on failure.
487 */
488struct physmem *vcm_map_phys_addr(phys_addr_t phys, size_t len);
489
490
491/**
492 * vcm_get_next_phys_addr() - Get the next physical addr and len of a physmem.
493 * @physmem: The physmem of interest.
494 * @phys: The current physical address. Set this to NULL to
495 * start the iteration.
496 * @len An output: the len of the next physical segment.
497 *
498 * physmems may contain physically discontiguous sections. This
499 * function returns the next physical address and len. Pass NULL to
500 * phys to get the first physical address. The len of the physical
501 * segment is returned in *len.
502 *
503 * Returns 0 if there is no next physical address.
504 */
505size_t vcm_get_next_phys_addr(struct physmem *physmem, phys_addr_t phys,
506 size_t *len);
507
508
509/**
510 * vcm_get_dev_addr() - Return the device address of a reservation.
511 * @res: The reservation of interest.
512 *
513 *
514 * On success this function returns the device address of a reservation. On
515 * error it returns:
516 * 1 res is invalid.
517 *
518 * Note: This may return a kernel address if the reservation was
519 * created from vcm_create_from_prebuilt() and the prebuilt ext_vcm_id
520 * references a VM page table.
521 */
522phys_addr_t vcm_get_dev_addr(struct res *res);
523
524
525/**
526 * vcm_get_res() - Return the reservation from a device address and a VCM
527 * @dev_addr: The device address of interest.
528 * @vcm: The VCM that contains the reservation
529 *
530 * This function returns 0 if there is no reservation whose device
531 * address is dev_addr.
532 */
533struct res *vcm_get_res(unsigned long dev_addr, struct vcm *vcm);
534
535
536/**
537 * vcm_translate() - Translate from one device address to another.
538 * @src_dev: The source device address.
539 * @src_vcm: The source VCM region.
540 * @dst_vcm: The destination VCM region.
541 *
542 * Derive the device address from a VCM region that maps the same physical
543 * memory as a device address from another VCM region.
544 *
545 * On success this function returns the device address of a translation. On
546 * error it returns:
547 * 1 res_id is invalid.
548 */
549size_t vcm_translate(struct device *src_dev, struct vcm *src_vcm,
550 struct vcm *dst_vcm);
551
552
553/**
554 * vcm_get_phys_num_res() - Return the number of reservations mapping a
555 * physical address.
556 * @phys: The physical address to read.
557 */
558size_t vcm_get_phys_num_res(phys_addr_t phys);
559
560
561/**
562 * vcm_get_next_phys_res() - Return the next reservation mapped to a physical
563 * address.
564 * @phys: The physical address to map.
565 * @res: The starting reservation. Set this to NULL for the first
566 * reservation.
567 * @len: The virtual length of the reservation
568 *
569 * This function returns 0 for the last reservation or no reservation.
570 */
571struct res *vcm_get_next_phys_res(phys_addr_t phys, struct res *res,
572 size_t *len);
573
574
575/**
576 * vcm_get_pgtbl_pa() - Return the physcial address of a VCM's page table.
577 * @vcm: The VCM region of interest.
578 *
579 * This function returns non-zero on success.
580 */
581phys_addr_t vcm_get_pgtbl_pa(struct vcm *vcm);
582
583
584/**
585 * vcm_get_cont_memtype_pa() - Return the phys base addr of a memtype's
586 * first contiguous region.
587 * @memtype: The memtype of interest.
588 *
589 * This function returns non-zero on success. A zero return indicates that
590 * the given memtype does not have a contiguous region or that the memtype
591 * is invalid.
592 */
593phys_addr_t vcm_get_cont_memtype_pa(enum memtype_t memtype);
594
595
596/**
597 * vcm_get_cont_memtype_len() - Return the len of a memtype's
598 * first contiguous region.
599 * @memtype: The memtype of interest.
600 *
601 * This function returns non-zero on success. A zero return indicates that
602 * the given memtype does not have a contiguous region or that the memtype
603 * is invalid.
604 */
605size_t vcm_get_cont_memtype_len(enum memtype_t memtype);
606
607
608/**
609 * vcm_dev_addr_to_phys_addr() - Perform a device address page-table lookup.
610 * @vcm: VCM to use for translation.
611 * @dev_addr: The device address to map.
612 *
613 * This function returns the pa of a va from a device's page-table. It will
614 * fault if the dev_addr is not mapped.
615 */
616phys_addr_t vcm_dev_addr_to_phys_addr(struct vcm *vcm, unsigned long dev_addr);
617
618
619/*
620 * Fault Hooks
621 *
622 * vcm_hook()
623 */
624
625/**
626 * vcm_hook() - Add a fault handler.
627 * @dev: The device.
628 * @handler: The handler.
629 * @data: A private piece of data that will get passed to the
630 * handler.
631 *
632 * This function returns 0 for a successful registration or:
633 * -EINVAL The arguments are invalid.
634 */
635int vcm_hook(struct device *dev, vcm_handler handler, void *data);
636
637
638
639/*
640 * Low level, platform agnostic, HW control.
641 *
642 * vcm_hw_ver()
643 */
644
645/**
646 * vcm_hw_ver() - Return the hardware version of a device, if it has one.
647 * @dev The device.
648 */
649size_t vcm_hw_ver(size_t dev);
650
651#endif /* _VCM_H_ */
652