summaryrefslogtreecommitdiff
path: root/usr/src/man/man7i/agpgart_io.7i
blob: e0470bb2f0bc836a24f4ba74d4807adda9f36640 (plain)
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
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
'\" te
.\" Copyright (c) 2008, Sun Microsystems, Inc.  All Rights Reserved
.\" 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]
.TH AGPGART_IO 7I "Sep 10, 2013"
.SH NAME
agpgart_io \- Solaris agpgart driver I/O control operations
.SH SYNOPSIS
.LP
.nf
#include <sys/agpgart.h>
.fi

.SH DESCRIPTION
.sp
.LP
The Accelerated Graphics Port (AGP) is a PCI bus technology enhancement that
improves 3D graphics performance by using low-cost system memory. AGP chipsets
use the Graphics Address Remapping Table (GART) to map discontiguous system
memory into a contiguous PCI memory range (known as the AGP Aperture), enabling
the graphics card to utilize the mapped aperture range as video memory.
.sp
.LP
The \fBagpgart\fR driver creates a pseudo device node at \fB/dev/agpgart\fR and
provides a set of ioctls for managing  allocation/deallocation of system
memory, setting mappings between system memory and aperture range, and setting
up AGP devices. The \fBagpgart\fR driver manages both pseudo and real device
nodes, but to initiate AGP-related operations you operate only on the
\fB/dev/agpgart\fR pseudo device node. To do this, open \fB/dev/agpgart\fR. The
macro defined for the pseudo device node name is:
.sp
.in +2
.nf
#define  AGP_DEVICE      "/dev/agpgart"
.fi
.in -2

.sp
.LP
The \fBagpgart_io\fR driver implementation is AGP architecture-dependent and
cannot be made generic. Currently, the \fBagpgart_io\fR driver only supports
specific AGP  systems. To determine if a system is supported, run an
\fBopen\fR(2) system  call on the AGP_DEVICE node. (Note that  \fBopen\fR(2)
fails if a system is not supported). After the AGP_DEVICE is opened, you can
use \fBkstat\fR(1M) to  read the system architecture  type.
.sp
.LP
In addition to AGP system support, the \fBagpgart\fR ioctls can also be used on
Intel integrated graphics devices (IGD). IGD devices usually have no dedicated
video memory and must  use system memory as video memory. IGD devices contain
translation tables (referred to as \fBGTT\fR tables) that are similar to the
GART translation table for address mapping purposes.
.sp
.LP
Processes must open the \fBagpgart_io\fR driver utilizing a GRAPHICS_ACCESS
privilege. Then all the ioctls  can be called  by this processes with the saved
file descriptor. With the exception of AGPIOC_INFO, the AGPIOC_ACQUIRE ioctl
must be called before any other ioctl. Once a process has acquired GART, it
cannot be acquired by another process until the former process calls
AGPIOC_RELEASE.
.sp
.LP
If the AGP_DEVICE fails to open, it may be due to one of the following reasons:
.sp
.ne 2
.na
\fBEAGAIN\fR
.ad
.sp .6
.RS 4n
GART table allocation failed.
.RE

.sp
.ne 2
.na
\fBEIO\fR
.ad
.sp .6
.RS 4n
Internal hardware initialization failed.
.RE

.sp
.ne 2
.na
\fBENXIO\fR
.ad
.sp .6
.RS 4n
Getting device soft state error. (This is unlikely to happen.)
.RE

.sp
.ne 2
.na
\fB EPERM\fR
.ad
.sp .6
.RS 4n
Without enough privilege.
.RE

.SH IOCTLS
.sp
.LP
With the exception of GPIOC_INFO, all ioctls shown in this section are
protected by GRAPHICS_ACCESS privilege. (Only processes with GRAPHICS_ACCESS
privilege in its effective set can access the privileged ioctls).
.sp
.LP
Common ioctl error codes are shown below. (Additional error codes may be
displayed by individual ioctls.)
.sp
.ne 2
.na
\fBENXIO\fR
.ad
.sp .6
.RS 4n
Ioctl command not supported or getting device soft state error.
.RE

.sp
.ne 2
.na
\fBEPERM\fR
.ad
.sp .6
.RS 4n
Process not privileged.
.RE

.sp
.ne 2
.na
\fB\fBAGPIOC_INFO\fR\fR
.ad
.sp .6
.RS 4n
Get system wide AGP or IGD hardware information. This command can be called by
any process from user or kernel context.
.sp
.in +2
.nf
The argument is a pointer to agp_info_t structure.

 typedef struct  _agp_info {
       agp_version_t agpi_version; /* OUT: AGP version supported */
       uint32_t agpi_devid;    /* OUT: bridge vendor + device */
       uint32_t agpi_mode;     /* OUT: mode of bridge */
       ulong_t  agpi_aperbase; /* OUT: base of aperture */
       size_t   agpi_apersize; /* OUT: aperture size in MB */
       uint32_t agpi_pgtotal;  /* OUT: max aperture pages avail. */
       uint32_t agpi_pgsystem; /* OUT: same as pg_total */
       uint32_t agpi_pgused; /* OUT: no. of currently used pages */
 } agp_info_t;

agpi_version  The version of AGP protocol the bridge device is
              compatible with, for example, major 3 and minor 0
              means AGP version 3.0.

              typedef struct _agp_version {
                      uint16_t   agpv_major;
                      uint16_t   agpv_minor;
              } agp_version_t;

agpi_devid    AGP bridge vendor and device ID.
agpi_mode     Current AGP mode, read from AGP status register of
              target device. The main bits are defined as below.
              /* AGP status register bits definition */

                #define AGPSTAT_RQ_MASK         0xff000000
                #define AGPSTAT_SBA             (0x1 << 9)
                #define AGPSTAT_OVER4G          (0x1 << 5)
                #define AGPSTAT_FW              (0x1 << 4)
                #define AGPSTAT_RATE_MASK       0x7
                /* AGP 3.0 only bits */
                #define AGPSTAT_ARQSZ_MASK      (0x7 << 13)
                #define AGPSTAT_CAL_MASK        (0x7 << 10)
                #define AGPSTAT_GART64B         (0x1 << 7)
                #define AGPSTAT_MODE3           (0x1 << 3)
                /* rate for 2.0 mode */
                #define AGP2_RATE_1X                    0x1
                #define AGP2_RATE_2X                    0x2
                #define AGP2_RATE_4X                    0x4
                /* rate for 3.0 mode */
                #define AGP3_RATE_4X                    0x1
                #define AGP3_RATE_8X                    0x2

agpi_aperbase   The base address of aperture in PCI memory space.
agpi_apersize   The size of the aperture in megabytes.
agpi_pgtotal    Represents the maximum memory
                pages the system can allocate
                according to aperture size and
                system memory size (which may differ
                from the maximum locked memory a process
                can have. The latter  is subject
                to the memory resource limit imposed
                by the  resource_controls(5) for each
                project(4)):

                  project.max-device-locked-memory

                This value can be modified through system
                utilities like prctl(1).

agpi_pgsystem  Same as pg_total.
agpi_pgused    System pages already allocated by the driver.

Return Values:

           EFAULT  Argument copy out error
           EINVAL  Command invalid
           0       Success
.fi
.in -2

.RE

.sp
.ne 2
.na
\fB\fBAGPIOC_ACQUIRE\fR\fR
.ad
.sp .6
.RS 4n
Acquire control of GART. With the exception of AGPIOC_INFO, a process must
acquire GART before can it call other agpgart ioctl commands. Additionally,
only processes with GRAPHICS_ACCESS privilege may access this ioctl. In the
current agpgart implementation, GART access is exclusive, meaning that only one
process can perform GART operations at a time. To release control over GART,
call AGPIOC_RELEASE. This command can be called from user or kernel context.
.sp
The argument should be NULL.
.sp
Return values:
.sp
.ne 2
.na
\fBEBUSY\fR
.ad
.RS 9n
GART has been acquired
.RE

.sp
.ne 2
.na
\fB0\fR
.ad
.RS 9n
Success.
.RE

.RE

.sp
.ne 2
.na
\fB\fBAGPIOC_RELEASE\fR\fR
.ad
.sp .6
.RS 4n
Release GART control. If a process releases GART control, it cannot perform
additional GART operations until GART is reacquired. Note that this command
does not free allocated memory or clear GART entries. (All clear jobs are done
by direct calls or by closing the device). When a process exits without making
this ioctl, the final \fBclose\fR(2) performs this automatically. This command
can be called from user or kernel context.
.sp
The argument should be NULL.
.sp
Return values:
.sp
.ne 2
.na
\fBEPERM\fR
.ad
.RS 9n
Not owner of GART.
.RE

.sp
.ne 2
.na
\fB0\fR
.ad
.RS 9n
Success.
.RE

.RE

.sp
.ne 2
.na
\fB\fBAGPIOC_SETUP\fR\fR
.ad
.sp .6
.RS 4n
Setup AGPCMD register. An AGPCMD register resides in both  the  AGP master and
target devices. The AGPCMD register controls the working mode of the AGP master
and target devices. Each device must be  configured  using the same mode. This
command can be called from user or kernel context.
.sp
.in +2
.nf
The argument is a pointer to agp_setup_t structure:

     typedef struct _agp_setup {
           uint32_t agps_mode; /* IN: value to be set for AGPCMD */
     } agp_setup_t;

agps_mode  Specifying the mode to be set. Each bit of the value may have
           a specific meaning, please refer to AGP 2.0/3.0 specification
           or hardware datasheets for details.

               /* AGP command register bits definition */
               #define     AGPCMD_RQ_MASK          0xff000000
               #define     AGPCMD_SBAEN            (0x1 << 9)
               #define     AGPCMD_AGPEN            (0x1 << 8)
               #define     AGPCMD_OVER4GEN         (0x1 << 5)
               #define     AGPCMD_FWEN             (0x1 << 4)
               #define     AGPCMD_RATE_MASK        0x7
               /* AGP 3.0 only bits */
               #define     AGP3_CMD_ARQSZ_MASK     (0x7 << 13)
               #define     AGP3_CMD_CAL_MASK       (0x7 << 10)
               #define     AGP3_CMD_GART64BEN      (0x1 << 7)
.fi
.in -2

The final values set to the AGPCMD register of the master/target devices are
decided by the agps_mode value and AGPSTAT of the master and target devices.
.sp
Return Values:
.sp
.ne 2
.na
\fBEPERM\fR
.ad
.RS 10n
Not owner of GART.
.RE

.sp
.ne 2
.na
\fBEFAULT\fR
.ad
.RS 10n
Argument copy in error.
.RE

.sp
.ne 2
.na
\fBEINVAL\fR
.ad
.RS 10n
Command invalid for non-AGP system.
.RE

.sp
.ne 2
.na
\fBEIO\fR
.ad
.RS 10n
Hardware setup error.
.RE

.sp
.ne 2
.na
\fB0\fR
.ad
.RS 10n
Success.
.RE

.RE

.sp
.ne 2
.na
\fB\fBAGPIOC_ALLOCATE\fR\fR
.ad
.sp .6
.RS 4n
Allocate system memory for graphics device. This command returns a unique ID
which can be used in subsequent operations to represent the allocated memory.
The memory is made up of discontiguous physical pages. In rare cases, special
memory types may be required. The allocated memory must be bound to the GART
table before it can be used by graphics device. Graphics applications can also
\fBmmap\fR(2) the memory to userland for data storing. Memory should be freed
when it is no longer used by calling AGPIOC_DEALLOCATE or simply by closing the
device. This command can be called from user or kernel context.
.sp
.in +2
.nf
The argument is a pointer to agp_allocate_t structure.

     typedef struct _agp_allocate {
           int32_t  agpa_key;     /* OUT:ID of allocated memory */
           uint32_t agpa_pgcount;/* IN: no. of pages to be allocated */
           uint32_t agpa_type;/* IN: type of memory to be allocated */
           uint32_t agpa_physical; /* OUT: reserved */
     } agp_allocate_t;
.fi
.in -2

.sp
.ne 2
.na
\fBagpa_key\fR
.ad
.RS 21n
Unique ID of the allocated memory.
.RE

.sp
.ne 2
.na
\fBagpa_pgcount\fR
.ad
.RS 21n
Number of pages to be allocated. The driver currently supports only 4K pages.
The value cannot exceed the agpi_pgtotal value returned by AGPIOC_INFO ioct and
is subject to the limit of project.max-device-locked-memory. If the memory
needed is larger than the resource limit but not larger than agpi_pgtotal, use
\fBprctl\fR(1) or other system utilities to change the default value of memory
resource limit beforehand.
.RE

.sp
.ne 2
.na
\fBagpa_type\fR
.ad
.RS 21n
Type of memory to be allocated. The valid value of agpa_type should be
AGP_NORMAL. It is defined as:
.sp
.in +2
.nf
         #define AGP_NORMAL      0
.fi
.in -2

Above, AGP_NORMAL represents the discontiguous non-cachable physical memory
which doesn't consume kernel virtual space but can be mapped to user space by
\fBmmap\fR(2). This command may support more type values in the future.
.RE

.sp
.ne 2
.na
\fBagpa_physical\fR
.ad
.RS 21n
Reserved for special uses. In normal operations, the value is undefined.
.sp
Return Values:
.sp
.ne 2
.na
\fBEPERM\fR
.ad
.RS 10n
Not owner of GART.
.RE

.sp
.ne 2
.na
\fBEINVAL\fR
.ad
.RS 10n
Argument not valid.
.RE

.sp
.ne 2
.na
\fBEFAULT\fR
.ad
.RS 10n
Argument copy in/out error.
.RE

.sp
.ne 2
.na
\fBENOMEM\fR
.ad
.RS 10n
Memory allocation error.
.RE

.sp
.ne 2
.na
\fB0\fR
.ad
.RS 10n
Success.
.RE

.RE

.sp
.ne 2
.na
\fBAGPIOC_DEALLOCATE\fR
.ad
.RS 21n
Deallocate the memory identified by a key assigned in a previous allocation. If
the memory isn't unbound from GART, this command unbinds it automatically. The
memory should no longer be used and those still in mapping to userland cannot
be deallocated. Always call AGPIOC_DEALLOCATE explicitly (instead of
deallocating  implicitly by closing the device), as the system won't carry out
the job until the last reference to the device file is dropped. This command
from user or kernel context.
.sp
The input argument is a key of type int32_t, no output argument.
.sp
Return Values:
.sp
.ne 2
.na
\fBEPERM\fR
.ad
.RS 10n
Not owner of GART.
.RE

.sp
.ne 2
.na
\fBEINVAL\fR
.ad
.RS 10n
Key not valid or memory in use.
.RE

.sp
.ne 2
.na
\fB0\fR
.ad
.RS 10n
Success.
.RE

.RE

.sp
.ne 2
.na
\fBAGPIOC_BIND\fR
.ad
.RS 21n
Bind allocated memory.  This  command binds the allocated   memory  identified
by a key to  a specific offset of the GART table, which enables GART   to
translate the aperture  range at the offset to system memory. Each GART entry
represents one physical page. If the GART range is previously bound to other
system memory, it returns an error. Once the memory is bound, it cannot be
bound to other offsets unless it is unbound. To unbind the memory, call
AGPIOC_UNBIND or deallocate the memory. This command can be called from user or
kernel context.
.sp
.in +2
.nf
The argument is a pointer to agp_bind_t structure:

     typedef struct _agp_bind {
           int32_t  agpb_key;      /* IN: ID of memory to be bound */
           uint32_t agpb_pgstart;  /* IN: offset in aperture */
     } agp_bind_t;
.fi
.in -2

.sp
.ne 2
.na
\fBagpb_key\fR
.ad
.RS 20n
The unique ID of the memory to be bound, which is previously allocated by
calling AGPIOC_ALLOCATE.
.RE

.sp
.ne 2
.na
\fBagpb_pgstart\fR
.ad
.RS 20n
The starting page offset to be bound in aperture space.
.RE

Return Values:
.sp
.ne 2
.na
\fBEPERM\fR
.ad
.RS 20n
Not owner of GART.
.RE

.sp
.ne 2
.na
\fBEFAULT\fR
.ad
.RS 20n
Argument copy in error.
.RE

.sp
.ne 2
.na
\fBEINVAL\fR
.ad
.RS 20n
Argument not valid.
.RE

.sp
.ne 2
.na
\fBEIO\fR
.ad
.RS 20n
Binding to the GTT table of IGD devices failed.
.RE

.sp
.ne 2
.na
\fB0\fR
.ad
.RS 20n
Success.
.RE

.RE

.sp
.ne 2
.na
\fBAGPIOC_UNBIND\fR
.ad
.RS 21n
Unbind memory identified by a key from the GART. This command clears the
corresponding entries in the GART table. Only the memory not in mapping to
userland is allowed to be unbound.
.sp
This ioctl command can be called from user or kernel context.
.sp
.in +2
.nf
The argument is a pointer to agp_unbind_t structure.

     typedef struct _agp_unbind {
           int32_t  agpu_key; /* IN: key of memory to be unbound*/
           uint32_t agpu_pri; /* Not used: for compat. with Xorg */
     } agp_unbind_t;
.fi
.in -2

.sp
.ne 2
.na
\fBagpu_key\fR
.ad
.RS 20n
Unique ID of the memory to be unbound which was previously bound by calling
AGPIOC_BIND.
.RE

.sp
.ne 2
.na
\fBagpu_pri\fR
.ad
.RS 20n
Reserved for compatibility with X.org/XFree86, not used.
.RE

Return Values:
.sp
.ne 2
.na
\fBEPERM\fR
.ad
.RS 20n
Not owner of GART.
.RE

.sp
.ne 2
.na
\fBEFAULT\fR
.ad
.RS 20n
Argument copy in error.
.RE

.sp
.ne 2
.na
\fBEINVAL\fR
.ad
.RS 20n
Argument not valid or memory in use.
.RE

.sp
.ne 2
.na
\fBEIO\fR
.ad
.RS 20n
Unbinding from the GTT table of IGD devices failed.
.RE

.sp
.ne 2
.na
\fB0\fR
.ad
.RS 20n
Success
.RE

.RE

.RE

.SH EXAMPLE
.sp
.LP
Below is an sample program showing how agpgart ioctls can be used:
.sp
.in +2
.nf
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h
#include <sys/ioccom.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/agpgart.h>

#define AGP_PAGE_SIZE   4096

int main(int argc, char *argv[])
{
        int fd, ret;
        agp_allocate_t alloc;
        agp_bind_t bindinfo;
        agp_info_t agpinfo;
        agp_setup_t modesetup;
        int *p = NULL;
        off_t mapoff;
        size_t maplen;

        if((fd = open(AGP_DEVICE, O_RDWR))== -1) {
                printf("open AGP_DEVICE error with %d\en", errno);\e
                exit(-1);
        }
        printf("device opened\en");

        ret = ioctl(fd, AGPIOC_INFO, &agpinfo);
        if(ret == -1) {
                printf("Get info error %d\en", errno);
                exit(-1);
        }
        printf("AGPSTAT is %x\en", agpinfo.agpi_mode);
        printf("APBASE is %x\en", agpinfo.agpi_aperbase);
        printf("APSIZE is %dMB\en", agpinfo.agpi_apersize);
        printf("pg_total is %d\en", agpinfo.agpi_pgtotal);

        ret = ioctl(fd, AGPIOC_ACQUIRE);
        if(ret == -1) {
                printf(" Acquire GART error %d\en", errno);
                exit(-1);
        }

        modesetup.agps_mode = agpinfo.agpi_mode;
        ret = ioctl(fd, AGPIOC_SETUP, &modesetup);
        if(ret == -1) {
                printf("set up AGP mode error\en", errno);
                exit(-1);
        }

        printf("Please input the number of pages you want to allocate\en");
        scanf("%d", &alloc.agpa_pgcount);
        alloc.agpa_type = AGP_NORMAL;
        ret = ioctl(fd, AGPIOC_ALLOCATE, &alloc);
        if(ret == -1) {
                printf("Allocate memory error %d\en", errno);
                exit(-1);
        }

        printf("Please input the aperture page offset to bind\en");
        scanf("%d", &bindinfo.agpb_pgstart);
        bindinfo.agpb_key = alloc.agpa_key;
        ret = ioctl(fd, AGPIOC_BIND, &bindinfo);
        if(ret == -1) {
                printf("Bind error %d\en", errno);
                exit(-1);
        }
        printf("Bind successful\en");

        /*
         * Now gart aperture space from (bindinfo.agpb_pgstart) to
         * (bindinfo.agpb_pgstart + alloc.agpa_pgcount) can be used for
         * AGP graphics transactions
         */
        ...

        /*
         * mmap can allow user processes to store graphics data
         * to the aperture space
         */
        maplen = alloc.agpa_pgcount * AGP_PAGE_SIZE;
        mapoff = bindinfo.agpb_pgstart * AGP_PAGE_SIZE;
        p = (int *)mmap((caddr_t)0, maplen, (PROT_READ | PROT_WRITE),
                        MAP_SHARED, fd, mapoff);
        if (p == MAP_FAILED) {
                printf("Mmap error %d\en", errno);
                exit(-1);
        }
        printf("Mmap successful\en");
        ...

        /*
         * When user processes finish access to the aperture space,
         * unmap the memory range
         */
        munmap((void *)p, maplen);
        ...

        /*
         * After finishing AGP transactions, the resources can be freed
         * step by step or simply by close device.
         */
        ret = ioctl(fd, AGPIOC_DEALLOCATE, alloc.agpa_key);
        if(ret == -1) {
                printf(" Deallocate memory error %d\en", errno);
                exit(-1);
        }

        ret = ioctl(fd, AGPIOC_RELEASE);
        if(ret == -1) {
                printf(" Release GART error %d\en", errno);
                exit(-1);
        }

        close(fd);
}
.fi
.in -2

.SH FILES
.sp
.ne 2
.na
\fB\fB/dev/agpgart\fR\fR
.ad
.sp .6
.RS 4n
Symbolic link to the pseudo agpgart device.
.RE

.sp
.ne 2
.na
\fB\fB/platform/i86pc/kernel/drv/agpgart\fR\fR
.ad
.sp .6
.RS 4n
agpgart pseudo driver.
.RE

.sp
.ne 2
.na
\fB\fB/platform/i86pc/kernel/drv/agpgart.conf\fR\fR
.ad
.sp .6
.RS 4n
Driver configuration file.
.RE

.SH ATTRIBUTES
.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp

.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE	ATTRIBUTE VALUE
_
Architecture	X86
_
Stability level	Unstable
.TE

.SH SEE ALSO
.sp
.LP
\fBprctl\fR(1), \fBkstat\fR(1M), \fBclose\fR(2), \fBioctl\fR(2), \fBopen\fR(2),
\fBmmap\fR(2), \fBproject\fR(4), \fBprivileges\fR(5), \fBattributes\fR(5),
\fBresource_controls\fR(5)