Notes for Lab 10 On implementing ‘show’ and ‘hide’ for the SiS 315 hardware cursor The GPU resources • The SiS 315 graphics processing units in our workstations are each equipped with 32-megabytes of video display memory (designated as PCI resource 0) • These graphics adapters also implement a set of memory-mapped registers known as the 2D graphics engine (and designated as PCI resource 1) ‘pci_resource_start()’ • Device-drivers can use this Linux kernel function to discover the physical address where resource 0, or resource 1, resides struct pci_dev *devp = NULL: devp = pci_find_device( VEN, DEV, devp ); vram = pci_resource_start( devp, 0 ); mmio = pci_resource_start( devp, 1 ); SiS 315 information • Programming manual for the SiS 315 GPU is not usually made available to the public • But some information can be derived from reading Linux device-driver source-code • Examples are: – The ‘/usr/src/linux/drivers/video/sis’ directory – Also download the ‘svgalib-1.9.17’ package Graphics Cursor 31 30 0x8500 0 cursor-image source-offset cursor visibility control bit: 0=hide, 1=show cursor starting command bit: 0=no, 1=yes 0x850C cursor-image horizontal coordinate 0x8510 cursor-image vertical coordinate Algorithm to hide cursor • Map physical page containing the registers to a virtual address (with ‘ioremap()’) • Read current values of these registers • Clear bit #30 (to make cursor invisible) • Set bit #31 (to initiate a new command) • Write these adjusted register values • Undo the mapping (with ‘iounmap()’) Algorithm to show cursor • Map physical page containing the registers to a virtual address (with ‘ioremap()’) • Read current values of these registers • Set bit #30 (to make cursor visible) • Set bit #31 (to initiate a new command) • Write these adjusted register values • Undo the mapping (with ‘iounmap()’) The ‘ioctl.c’ module • These techniques are demonstrated in this device-driver module’s ‘ioctl()’ function • Two IOCTL commands are implemented – #define CURSOR_HIDE – #define CURSOR_SHOW 0 1 • Applications can open the device-file, then use an ioctl-command; for example: int fd = open( “/dev/vram”, O_RDWR ); ioctl( fd, CURSOR_HIDE); In-class exercise: • Try adding new IOCTL commands to the ‘ioctl.c’ driver which lets applications find or move the cursor’s screen-position; #define CURSOR_FIND 2 #define CURSOR_MOVE 3 struct { long x, y; } location; ioctl( fd, CURSOR_FIND, &location ); location.x += 40; location.y += 40; ioctl( fd, CURSOR_MOVE, &location );