1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _SYS_DDIDMAREQ_H
#define _SYS_DDIDMAREQ_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Memory Objects
*
* Definitions of structures that can describe
* an object that can be mapped for DMA.
*/
/*
* Structure describing a virtual address
*/
struct v_address {
caddr_t v_addr; /* base virtual address */
struct as *v_as; /* pointer to address space */
void *v_priv; /* priv data for shadow I/O */
};
/*
* Structure describing a page-based address
*/
struct pp_address {
/*
* A pointer to a circularly linked list of page structures.
*/
struct page *pp_pp;
uint_t pp_offset; /* offset within first page */
};
/*
* Structure to describe a physical memory address.
*/
struct phy_address {
ulong_t p_addr; /* base physical address */
ulong_t p_memtype; /* memory type */
};
/*
* Structure to describe an array DVMA addresses.
* Under normal circumstances, dv_nseg will be 1.
* dvs_start is always page aligned.
*/
struct dvma_address {
size_t dv_off;
size_t dv_nseg;
struct dvmaseg {
uint64_t dvs_start;
size_t dvs_len;
} *dv_seg;
};
/*
* A union of all of the above structures.
*
* This union describes the relationship between
* the kind of an address description and an object.
*/
typedef union {
struct v_address virt_obj; /* Some virtual address */
struct pp_address pp_obj; /* Some page-based address */
struct phy_address phys_obj; /* Some physical address */
struct dvma_address dvma_obj;
} ddi_dma_aobj_t;
/*
* DMA object types - used to select how the object
* being mapped is being addressed by the IU.
*/
typedef enum {
DMA_OTYP_VADDR = 0, /* enforce starting value of zero */
DMA_OTYP_PAGES,
DMA_OTYP_PADDR,
DMA_OTYP_BUFVADDR,
DMA_OTYP_DVADDR
} ddi_dma_atyp_t;
/*
* A compact package to describe an object that is to be mapped for DMA.
*/
typedef struct {
uint_t dmao_size; /* size, in bytes, of the object */
ddi_dma_atyp_t dmao_type; /* type of object */
ddi_dma_aobj_t dmao_obj; /* the object described */
} ddi_dma_obj_t;
/*
* DMA addressing limits.
*
* This structure describes the constraints that a particular device's
* DMA engine has to its parent so that the parent may correctly set
* things up for a DMA mapping. Each parent may in turn modify the
* constraints listed in a DMA request structure in order to describe
* to its parent any changed or additional constraints. The rules
* are that each parent may modify a constraint in order to further
* constrain things (e.g., picking a more limited address range than
* that permitted by the child), but that the parent may not ignore
* a child's constraints.
*
* A particular constraint that we do *not* address is whether or not
* a requested mapping is too large for a DMA engine's counter to
* correctly track. It is still up to each driver to explicitly handle
* transfers that are too large for its own hardware to deal with directly.
*
* The mapping routines that are cognizant of this structure will
* copy any user defined limits structure if they need to modify
* the fields (as alluded to above).
*
* A note as to how to define constraints:
*
* How you define the constraints for your device depends on how you
* define your device. For example, you may have an SBus card with a
* device on it that address only the bottom 16mb of virtual DMA space.
* However, if the card also has ancillary circuitry that pulls the high 8
* bits of address lines high, the more correct expression for your device
* is that it address [0xff000000..0xffffffff] rather than [0..0x00ffffff].
*/
#if defined(__sparc)
typedef struct ddi_dma_lim {
/*
* Low range of 32 bit addressing capability.
*/
uint_t dlim_addr_lo;
/*
* Upper inclusive bound of addressing capability. It is an
* inclusive boundary limit to allow for the addressing range
* [0..0xffffffff] to be specified in preference to [0..0].
*/
uint_t dlim_addr_hi;
/*
* Inclusive upper bound with which The DMA engine's counter acts as
* a register.
*
* This handles the case where an upper portion of a DMA address
* register is a latch instead of being a full 32 bit register
* (e.g., the upper 8 bits may remain constant while the lower
* 24 bits are the real address register).
*
* This essentially gives a hint about segment limitations
* to the mapping routines.
*/
uint_t dlim_cntr_max;
/*
* DMA burst sizes.
*
* At the time of a mapping request, this tag defines the possible
* DMA burst cycle sizes that the requestor's DMA engine can
* emit. The format of the data is binary encoding of burst sizes
* assumed to be powers of two. That is, if a DMA engine is capable
* of doing 1, 2, 4 and 16 byte transfers, the encoding would be 0x17.
*
* As the mapping request is handled by intervening nexi, the
* burstsizes value may be modified. Prior to enabling DMA for
* the specific device, the driver that owns the DMA engine should
* check (via ddi_dma_burstsizes(9F)) what the allowed burstsizes
* have become and program their DMA engine appropriately.
*/
uint_t dlim_burstsizes;
/*
* Minimum effective DMA transfer size, in units of bytes.
*
* This value specifies the minimum effective granularity of the
* DMA engine. It is distinct from dlim_burtsizes in that it
* describes the minimum amount of access a DMA transfer will
* effect. dlim_burtsizes describes in what electrical fashion
* the DMA engine might perform its accesses, while dlim_minxfer
* describes the minimum amount of memory that can be touched by
* the DMA transfer.
*
* As the mapping request is handled by intervening nexi, the
* dlim_minxfer value may be modifed contingent upon the presence
* (and use) of I/O caches and DMA write buffers in between the
* DMA engine and the object that DMA is being performed on.
*
*/
uint_t dlim_minxfer;
/*
* Expected average data rate for this DMA engine
* while transferring data.
*
* This is used as a hint for a number of operations that might
* want to know the possible optimal latency requirements of this
* device. A value of zero will be interpreted as a 'do not care'.
*/
uint_t dlim_dmaspeed;
} ddi_dma_lim_t;
#elif defined(__x86)
/*
* values for dlim_minxfer
*/
#define DMA_UNIT_8 1
#define DMA_UNIT_16 2
#define DMA_UNIT_32 4
/*
* Version number
*/
#define DMALIM_VER0 ((0x86000000) + 0)
typedef struct ddi_dma_lim {
/*
* Low range of 32 bit addressing capability.
*/
uint_t dlim_addr_lo;
/*
* Upper Inclusive bound of 32 bit addressing capability.
*
* The ISA nexus restricts this to 0x00ffffff, since this bus has
* only 24 address lines. This enforces the 16 Mb address limitation.
* The EISA nexus restricts this to 0xffffffff.
*/
uint_t dlim_addr_hi;
/*
* DMA engine counter not used; set to 0
*/
uint_t dlim_cntr_max;
/*
* DMA burst sizes not used; set to 1
*/
uint_t dlim_burstsizes;
/*
* Minimum effective DMA transfer size.
*
* This value specifies the minimum effective granularity of the
* DMA engine. It is distinct from dlim_burstsizes in that it
* describes the minimum amount of access a DMA transfer will
* effect. dlim_burstsizes describes in what electrical fashion
* the DMA engine might perform its accesses, while dlim_minxfer
* describes the minimum amount of memory that can be touched by
* the DMA transfer.
*
* This value also implies the required address alignment.
* The number of bytes transferred is assumed to be
* dlim_minxfer * (DMA engine count)
*
* It should be set to DMA_UNIT_8, DMA_UNIT_16, or DMA_UNIT_32.
*/
uint_t dlim_minxfer;
/*
* Expected average data rate for this DMA engine
* while transferring data.
*
* This is used as a hint for a number of operations that might
* want to know the possible optimal latency requirements of this
* device. A value of zero will be interpreted as a 'do not care'.
*/
uint_t dlim_dmaspeed;
/*
* Version number of this structure
*/
uint_t dlim_version; /* = 0x86 << 24 + 0 */
/*
* Inclusive upper bound with which the DMA engine's Address acts as
* a register.
* This handles the case where an upper portion of a DMA address
* register is a latch instead of being a full 32 bit register
* (e.g., the upper 16 bits remain constant while the lower 16 bits
* are incremented for each DMA transfer).
*
* The ISA nexus restricts only 3rd-party DMA requests to 0x0000ffff,
* since the ISA DMA engine has a 16-bit register for low address and
* an 8-bit latch for high address. This enforces the first 64 Kb
* limitation (address boundary).
* The EISA nexus restricts only 3rd-party DMA requests to 0xffffffff.
*/
uint_t dlim_adreg_max;
/*
* Maximum transfer count that the DMA engine can handle.
*
* The ISA nexus restricts only 3rd-party DMA requests to 0x0000ffff,
* since the ISA DMA engine has a 16-bit register for counting.
* This enforces the other 64 Kb limitation (count size).
* The EISA nexus restricts only 3rd-party DMA requests to 0x00ffffff,
* since the EISA DMA engine has a 24-bit register for counting.
*
* This transfer count limitation is a per segment limitation.
* It can also be used to restrict the size of segments.
*
* This is used as a bit mask, so it must be a power of 2, minus 1.
*/
uint_t dlim_ctreg_max;
/*
* Granularity of DMA transfer, in units of bytes.
*
* Breakup sizes must be multiples of this value.
* If no scatter/gather capabilty is specified, then the size of
* each DMA transfer must be a multiple of this value.
*
* If there is scatter/gather capability, then a single cookie cannot
* be smaller in size than the minimum xfer value, and may be less
* than the granularity value. The total transfer length of the
* scatter/gather list should be a multiple of the granularity value;
* use dlim_sgllen to specify the length of the scatter/gather list.
*
* This value should be equal to the sector size of the device.
*/
uint_t dlim_granular;
/*
* Length of scatter/gather list
*
* This value specifies the number of segments or cookies that a DMA
* engine can consume in one i/o request to the device. For 3rd-party
* DMA that uses the bus nexus this should be set to 1. Devices with
* 1st-party DMA capability should specify the number of entries in
* its scatter/gather list. The breakup routine will ensure that each
* group of dlim_sgllen cookies (within a DMA window) will have a
* total transfer length that is a multiple of dlim_granular.
*
* < 0 : tbd
* = 0 : breakup is for PIO.
* = 1 : breakup is for DMA engine with no scatter/gather
* capability.
* >= 2 : breakup is for DMA engine with scatter/gather
* capability; value is max number of entries in list.
*
* Note that this list length is not dependent on the DMA window
* size. The size of the DMA window is based on resources consumed,
* such as intermediate buffers. Several s/g lists may exist within
* a window. But the end of a window does imply the end of the s/g
* list.
*/
short dlim_sgllen;
/*
* Size of device i/o request
*
* This value indicates the maximum number of bytes the device
* can transmit/receive for one i/o command. This limitation is
* significant ony if it is less than (dlim_ctreg_max * dlim_sgllen).
*/
uint_t dlim_reqsize;
} ddi_dma_lim_t;
#else
#error "struct ddi_dma_lim not defined for this architecture"
#endif /* defined(__sparc) */
/*
* Flags definition for dma_attr_flags
*/
/*
* return physical DMA address on platforms
* which support DVMA
*/
#define DDI_DMA_FORCE_PHYSICAL 0x0100
/*
* An error will be flagged for DMA data path errors
*/
#define DDI_DMA_FLAGERR 0x200
/*
* Enable relaxed ordering
*/
#define DDI_DMA_RELAXED_ORDERING 0x400
/*
* Consolidation private x86 only flag which will cause a bounce buffer
* (paddr < dma_attr_seg) to be used if the buffer passed to the bind
* operation contains pages both above and below dma_attr_seg. If this flag
* is set, dma_attr_seg must be <= dma_attr_addr_hi.
*/
#define _DDI_DMA_BOUNCE_ON_SEG 0x8000
#define DMA_ATTR_V0 0
#define DMA_ATTR_VERSION DMA_ATTR_V0
typedef struct ddi_dma_attr {
uint_t dma_attr_version; /* version number */
uint64_t dma_attr_addr_lo; /* low DMA address range */
uint64_t dma_attr_addr_hi; /* high DMA address range */
uint64_t dma_attr_count_max; /* DMA counter register */
uint64_t dma_attr_align; /* DMA address alignment */
uint_t dma_attr_burstsizes; /* DMA burstsizes */
uint32_t dma_attr_minxfer; /* min effective DMA size */
uint64_t dma_attr_maxxfer; /* max DMA xfer size */
uint64_t dma_attr_seg; /* segment boundary */
int dma_attr_sgllen; /* s/g length */
uint32_t dma_attr_granular; /* granularity of device */
uint_t dma_attr_flags; /* Bus specific DMA flags */
} ddi_dma_attr_t;
/*
* Handy macro to set a maximum bit value (should be elsewhere)
*
* Clear off all bits lower then 'mybit' in val; if there are no
* bits higher than or equal to mybit in val then set mybit. Assumes
* mybit equals some power of 2 and is not zero.
*/
#define maxbit(val, mybit) \
((val) & ~((mybit)-1)) | ((((val) & ~((mybit)-1)) == 0) ? (mybit) : 0)
/*
* Handy macro to set a minimum bit value (should be elsewhere)
*
* Clear off all bits higher then 'mybit' in val; if there are no
* bits lower than or equal to mybit in val then set mybit. Assumes
* mybit equals some pow2 and is not zero.
*/
#define minbit(val, mybit) \
(((val)&((mybit)|((mybit)-1))) | \
((((val) & ((mybit)-1)) == 0) ? (mybit) : 0))
/*
* Structure of a request to map an object for DMA.
*/
typedef struct ddi_dma_req {
/*
* Caller's DMA engine constraints.
*
* If there are no particular constraints to the caller's DMA
* engine, this field may be set to NULL. The implementation DMA
* setup functions will then select a set of standard beginning
* constraints.
*
* In either case, as the mapping proceeds, the initial DMA
* constraints may become more restrictive as each intervening
* nexus might add further restrictions.
*/
ddi_dma_lim_t *dmar_limits;
/*
* Contains the information passed to the DMA mapping allocation
* routine(s).
*/
uint_t dmar_flags;
/*
* Callback function. A caller of the DMA mapping functions must
* specify by filling in this field whether the allocation routines
* can sleep awaiting mapping resources, must *not* sleep awaiting
* resources, or may *not* sleep awaiting any resources and must
* call the function specified by dmar_fp with the the argument
* dmar_arg when resources might have become available at a future
* time.
*/
int (*dmar_fp)();
caddr_t dmar_arg; /* Callback function argument */
/*
* Description of the object to be mapped for DMA.
* Must be last in this structure in case that the
* union ddi_dma_obj_t changes in the future.
*/
ddi_dma_obj_t dmar_object;
} ddi_dma_req_t;
/*
* Defines for the DMA mapping allocation functions
*
* If a DMA callback funtion is set to anything other than the following
* defines then it is assumed that one wishes a callback and is providing
* a function address.
*/
#define DDI_DMA_DONTWAIT ((int (*)(caddr_t))0)
#define DDI_DMA_SLEEP ((int (*)(caddr_t))1)
/*
* Return values from callback functions.
*/
#define DDI_DMA_CALLBACK_RUNOUT 0
#define DDI_DMA_CALLBACK_DONE 1
/*
* Flag definitions for the allocation functions.
*/
#define DDI_DMA_WRITE 0x0001 /* Direction memory --> IO */
#define DDI_DMA_READ 0x0002 /* Direction IO --> memory */
#define DDI_DMA_RDWR (DDI_DMA_READ | DDI_DMA_WRITE)
/*
* If possible, establish a MMU redzone after the mapping (to protect
* against cheap DMA hardware that might get out of control).
*/
#define DDI_DMA_REDZONE 0x0004
/*
* A partial allocation is allowed. That is, if the size of the object
* exceeds the mapping resources available, only map a portion of the
* object and return status indicating that this took place. The caller
* can use the functions ddi_dma_numwin(9F) and ddi_dma_getwin(9F) to
* change, at a later point, the actual mapped portion of the object.
*
* The mapped portion begins at offset 0 of the object.
*
*/
#define DDI_DMA_PARTIAL 0x0008
/*
* Map the object for byte consistent access. Note that explicit
* synchronization (via ddi_dma_sync(9F)) will still be required.
* Consider this flag to be a hint to the mapping routines as to
* the intended use of the mapping.
*
* Normal data transfers can be usually consider to use 'streaming'
* modes of operations. They start at a specific point, transfer a
* fairly large amount of data sequentially, and then stop (usually
* on a well aligned boundary).
*
* Control mode data transfers (for memory resident device control blocks,
* e.g., ethernet message descriptors) do not access memory in such
* a streaming sequential fashion. Instead, they tend to modify a few
* words or bytes, move around and maybe modify a few more.
*
* There are many machine implementations that make this difficult to
* control in a generic and seamless fashion. Therefore, explicit synch-
* ronization steps (via ddi_dma_sync(9F)) are still required (even if you
* ask for a byte-consistent mapping) in order to make the view of the
* memory object shared between a CPU and a DMA master in consistent.
* However, judicious use of this flag can give sufficient hints to
* the mapping routines to attempt to pick the most efficacious mapping
* such that the synchronization steps are as efficient as possible.
*
*/
#define DDI_DMA_CONSISTENT 0x0010
/*
* Some DMA mappings have to be 'exclusive' access.
*/
#define DDI_DMA_EXCLUSIVE 0x0020
/*
* Sequential, unidirectional, block-sized and block aligned transfers
*/
#define DDI_DMA_STREAMING 0x0040
/*
* Support for 64-bit SBus devices
*/
#define DDI_DMA_SBUS_64BIT 0x2000
/*
* Return values from the mapping allocation functions.
*/
/*
* succeeded in satisfying request
*/
#define DDI_DMA_MAPPED 0
/*
* Mapping is legitimate (for advisory calls).
*/
#define DDI_DMA_MAPOK 0
/*
* Succeeded in mapping a portion of the request.
*/
#define DDI_DMA_PARTIAL_MAP 1
/*
* indicates end of window/segment list
*/
#define DDI_DMA_DONE 2
/*
* No resources to map request.
*/
#define DDI_DMA_NORESOURCES -1
/*
* Can't establish a mapping to the specified object
* (no specific reason).
*/
#define DDI_DMA_NOMAPPING -2
/*
* The request is too big to be mapped.
*/
#define DDI_DMA_TOOBIG -3
/*
* The request is too small to be mapped.
*/
#define DDI_DMA_TOOSMALL -4
/*
* The request cannot be mapped because the object
* is locked against mapping by another DMA master.
*/
#define DDI_DMA_LOCKED -5
/*
* The request cannot be mapped because the limits
* structure has bogus values.
*/
#define DDI_DMA_BADLIMITS -6
/*
* the segment/window pointer is stale
*/
#define DDI_DMA_STALE -7
/*
* The system can't allocate DMA resources using
* the given DMA attributes
*/
#define DDI_DMA_BADATTR -8
/*
* A DMA handle is already used for a DMA
*/
#define DDI_DMA_INUSE -9
/*
* DVMA disabled or not supported. use physical DMA
*/
#define DDI_DMA_USE_PHYSICAL -10
/*
* In order for the access to a memory object to be consistent
* between a device and a CPU, the function ddi_dma_sync(9F)
* must be called upon the DMA handle. The following flags
* define whose view of the object should be made consistent.
* There are different flags here because on different machines
* there are definite performance implications of how long
* such synchronization takes.
*
* DDI_DMA_SYNC_FORDEV makes all device references to the object
* mapped by the DMA handle up to date. It should be used by a
* driver after a cpu modifies the memory object (over the range
* specified by the other arguments to the ddi_dma_sync(9F) call).
*
* DDI_DMA_SYNC_FORCPU makes all cpu references to the object
* mapped by the DMA handle up to date. It should be used
* by a driver after the receipt of data from the device to
* the memory object is done (over the range specified by
* the other arguments to the ddi_dma_sync(9F) call).
*
* If the only mapping that concerns the driver is one for the
* kernel (such as memory allocated by ddi_iopb_alloc(9F)), the
* flag DDI_DMA_SYNC_FORKERNEL can be used. This is a hint to the
* system that if it can synchronize the kernel's view faster
* that the CPU's view, it can do so, otherwise it acts the
* same as DDI_DMA_SYNC_FORCPU. DDI_DMA_SYNC_FORKERNEL might
* speed up the synchronization of kernel mappings in case of
* non IO-coherent CPU caches.
*/
#define DDI_DMA_SYNC_FORDEV 0x0
#define DDI_DMA_SYNC_FORCPU 0x1
#define DDI_DMA_SYNC_FORKERNEL 0x2
/*
* Bus nexus control functions for DMA
*/
/*
* Control operations, defined here so that devops.h can be included
* by drivers without having to include a specific SYSDDI implementation
* header file.
*/
enum ddi_dma_ctlops {
DDI_DMA_FREE, /* obsolete - do not use */
DDI_DMA_SYNC, /* obsolete - do not use */
DDI_DMA_HTOC, /* obsolete - do not use */
DDI_DMA_KVADDR, /* obsolete - do not use */
DDI_DMA_MOVWIN, /* obsolete - do not use */
DDI_DMA_REPWIN, /* obsolete - do not use */
DDI_DMA_GETERR, /* obsolete - do not use */
DDI_DMA_COFF, /* obsolete - do not use */
DDI_DMA_NEXTWIN, /* obsolete - do not use */
DDI_DMA_NEXTSEG, /* obsolete - do not use */
DDI_DMA_SEGTOC, /* obsolete - do not use */
DDI_DMA_RESERVE, /* reserve some DVMA range */
DDI_DMA_RELEASE, /* free preallocated DVMA range */
DDI_DMA_RESETH, /* obsolete - do not use */
DDI_DMA_CKSYNC, /* obsolete - do not use */
DDI_DMA_IOPB_ALLOC, /* obsolete - do not use */
DDI_DMA_IOPB_FREE, /* obsolete - do not use */
DDI_DMA_SMEM_ALLOC, /* obsolete - do not use */
DDI_DMA_SMEM_FREE, /* obsolete - do not use */
DDI_DMA_SET_SBUS64, /* 64 bit SBus support */
DDI_DMA_REMAP, /* remap DVMA buffers after relocation */
/*
* control ops for DMA engine on motherboard
*/
DDI_DMA_E_ACQUIRE, /* get channel for exclusive use */
DDI_DMA_E_FREE, /* release channel */
DDI_DMA_E_1STPTY, /* setup channel for 1st party DMA */
DDI_DMA_E_GETCB, /* get control block for DMA engine */
DDI_DMA_E_FREECB, /* free control blk for DMA engine */
DDI_DMA_E_PROG, /* program channel of DMA engine */
DDI_DMA_E_SWSETUP, /* setup channel for software control */
DDI_DMA_E_SWSTART, /* software operation of DMA channel */
DDI_DMA_E_ENABLE, /* enable channel of DMA engine */
DDI_DMA_E_STOP, /* stop a channel of DMA engine */
DDI_DMA_E_DISABLE, /* disable channel of DMA engine */
DDI_DMA_E_GETCNT, /* get remaining xfer count */
DDI_DMA_E_GETLIM, /* obsolete - do not use */
DDI_DMA_E_GETATTR /* get DMA engine attributes */
};
/*
* Cache attribute flags:
*
* IOMEM_DATA_CACHED
* The CPU can cache the data it fetches and push it to memory at a later
* time. This is the default attribute and used if no cache attributes is
* specified.
*
* IOMEM_DATA_UC_WR_COMBINE
* The CPU never caches the data but writes may occur out of order or be
* combined. It implies re-ordering.
*
* IOMEM_DATA_UNCACHED
* The CPU never caches the data and has uncacheable access to memory.
* It also implies strict ordering.
*
* The cache attributes are mutually exclusive, and any combination of the
* values leads to a failure. On the sparc architecture, only IOMEM_DATA_CACHED
* is meaningful, but others lead to a failure.
*/
#define IOMEM_DATA_CACHED 0x10000 /* data is cached */
#define IOMEM_DATA_UC_WR_COMBINE 0x20000 /* data is not cached, but */
/* writes might be combined */
#define IOMEM_DATA_UNCACHED 0x40000 /* data is not cached. */
#define IOMEM_DATA_MASK 0xF0000 /* cache attrs mask */
/*
* Check if either uncacheable or write-combining specified. (those flags are
* mutually exclusive) This macro is used to override hat attributes if either
* one is set.
*/
#define OVERRIDE_CACHE_ATTR(attr) \
(attr & (IOMEM_DATA_UNCACHED | IOMEM_DATA_UC_WR_COMBINE))
/*
* Get the cache attribute from flags. If there is no attributes,
* return IOMEM_DATA_CACHED (default attribute).
*/
#define IOMEM_CACHE_ATTR(flags) \
((flags & IOMEM_DATA_MASK) ? (flags & IOMEM_DATA_MASK) : \
IOMEM_DATA_CACHED)
#ifdef __cplusplus
}
#endif
#endif /* _SYS_DDIDMAREQ_H */
|