agpgart_io - Solaris agpgart driver I/O control operations
#include <sys/agpgart.h>
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.
The agpgart driver creates a pseudo device node at /dev/agpgart 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 agpgart driver manages both pseudo and real device nodes, but to initiate AGP-related operations you operate only on the /dev/agpgart pseudo device node. To do this, open /dev/agpgart. The macro defined for the pseudo device node name is:
#define AGP_DEVICE "/dev/agpgart"
The agpgart_io driver implementation is AGP architecture-dependent and cannot be made generic. Currently, the agpgart_io driver only supports specific AGP systems. To determine if a system is supported, run an open(2) system call on the AGP_DEVICE node. (Note that open(2) fails if a system is not supported). After the AGP_DEVICE is opened, you can use kstat(1M) to read the system architecture type.
In addition to AGP system support, the agpgart 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 GTT tables) that are similar to the GART translation table for address mapping purposes.
Processes must open the agpgart_io 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.
If the AGP_DEVICE fails to open, it may be due to one of the following reasons:
EAGAIN
EIO
ENXIO
EPERM
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).
Common ioctl error codes are shown below. (Additional error codes may be displayed by individual ioctls.)
ENXIO
EPERM
AGPIOC_INFO
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
AGPIOC_ACQUIRE
The argument should be NULL.
Return values:
EBUSY
0
AGPIOC_RELEASE
The argument should be NULL.
Return values:
EPERM
0
AGPIOC_SETUP
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)
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.
Return Values:
EPERM
EFAULT
EINVAL
EIO
0
AGPIOC_ALLOCATE
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;
agpa_key
agpa_pgcount
agpa_type
#define AGP_NORMAL 0
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 mmap(2). This command may support more type values in the future.
agpa_physical
Return Values:
EPERM
EINVAL
EFAULT
ENOMEM
0
AGPIOC_DEALLOCATE
The input argument is a key of type int32_t, no output argument.
Return Values:
EPERM
EINVAL
0
AGPIOC_BIND
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;
agpb_key
agpb_pgstart
Return Values:
EPERM
EFAULT
EINVAL
EIO
0
AGPIOC_UNBIND
This ioctl command can be called from user or kernel context.
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;
agpu_key
agpu_pri
Return Values:
EPERM
EFAULT
EINVAL
EIO
0
Below is an sample program showing how agpgart ioctls can be used:
#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\n", errno);\ exit(-1); } printf("device opened\n"); ret = ioctl(fd, AGPIOC_INFO, &agpinfo); if(ret == -1) { printf("Get info error %d, errno); exit(-1); } printf("AGPSTAT is %x\n", agpinfo.agpi_mode); printf("APBASE is %x\n", agpinfo.agpi_aperbase); printf("APSIZE is %dMB\n", agpinfo.agpi_apersize); printf("pg_total is %d\n", agpinfo.agpi_pgtotal); ret = ioctl(fd, AGPIOC_ACQUIRE); if(ret == -1) { printf(" Acquire GART error %d\n", errno); exit(-1); } modesetup.agps_mode = agpinfo.agpi_mode; ret = ioctl(fd, AGPIOC_SETUP, &modesetup); if(ret == -1) { printf("set up AGP mode error\n", errno); exit(-1); } printf("Please input the number of pages you want to allocate\n"); scanf("%d", &alloc.agpa_pgcount); alloc.agpa_type = AGP_NORMAL; ret = ioctl(fd, AGPIOC_ALLOCATE, &alloc); if(ret == -1) { printf("Allocate memory error %d\n", errno); exit(-1); } printf("Please input the aperture page offset to bind\n"); scanf("%d", &bindinfo.agpb_pgstart); bindinfo.agpb_key = alloc.agpa_key; ret = ioctl(fd, AGPIOC_BIND, &bindinfo); if(ret == -1) { printf("Bind error %d\n", errno); exit(-1); } printf("Bind successful\n"); /* * 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\n", errno); exit(-1); } printf("Mmap successful\n"); ... /* * 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\n", errno); exit(-1); } ret = ioctl(fd, AGPIOC_RELEASE); if(ret == -1) { printf(" Release GART error %d\n", errno); exit(-1); } close(fd); }
/dev/agpgart
/platform/i86pc/kernel/drv/agpgart
/platform/i86pc/kernel/drv/agpgart.conf
See attributes(5) for descriptions of the following attributes:
|
prctl(1), kstat(1M), close(2), ioctl(2), open(2), mmap(2), project(4), privileges(5), attributes(5), resource_controls(5)
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |