diff options
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | cirrus.c | 142 | ||||
-rw-r--r-- | cirrus.h | 51 | ||||
-rw-r--r-- | cve-2017-2615.c | 243 | ||||
-rw-r--r-- | pci.c | 75 | ||||
-rw-r--r-- | pci.h | 9 |
6 files changed, 289 insertions, 242 deletions
@@ -3,14 +3,17 @@ CC ?= gcc CFLAGS ?= -Os -g CFLAGS += -Wall -SOURCES := $(wildcard *.c) -TARGETS := $(patsubst %.c,%,$(SOURCES)) +CVETEST := cve-2016-3712 +PCITEST := cve-2017-2615 +TARGETS := $(CVETEST) $(PCITEST) -cve-2017-2615 : CFLAGS += $(shell pkg-config --cflags libpci) -cve-2017-2615 : LDLIBS += $(shell pkg-config --libs libpci) +$(PCITEST) : CFLAGS += $(shell pkg-config --cflags libpci) +$(PCITEST) : LDLIBS += $(shell pkg-config --libs libpci) all: $(TARGETS) clean: rm -f $(TARGETS) rm -f *~ *.o + +cve-2017-2615: cve-2017-2615.o pci.o cirrus.o diff --git a/cirrus.c b/cirrus.c new file mode 100644 index 0000000..7e4015c --- /dev/null +++ b/cirrus.c @@ -0,0 +1,142 @@ +/* + +mode setting sequence done by cirrus drm driver + +--- set mode ( 1024 x 768 @ 24 bpp ) --- +vga_cirrus_write_io addr 0x3d4, val 0x11 +vga_cirrus_write_io addr 0x3d5, val 0x20 +vga_cirrus_write_io addr 0x3d4, val 0x0 +vga_cirrus_write_io addr 0x3d5, val 0xa3 +vga_cirrus_write_io addr 0x3d4, val 0x1 +vga_cirrus_write_io addr 0x3d5, val 0x7f +vga_cirrus_write_io addr 0x3d4, val 0x4 +vga_cirrus_write_io addr 0x3d5, val 0x84 +vga_cirrus_write_io addr 0x3d4, val 0x5 +vga_cirrus_write_io addr 0x3d5, val 0x95 +vga_cirrus_write_io addr 0x3d4, val 0x6 +vga_cirrus_write_io addr 0x3d5, val 0x24 +vga_cirrus_write_io addr 0x3d4, val 0x12 +vga_cirrus_write_io addr 0x3d5, val 0xff +vga_cirrus_write_io addr 0x3d4, val 0x9 +vga_cirrus_write_io addr 0x3d5, val 0x60 +vga_cirrus_write_io addr 0x3d4, val 0x7 +vga_cirrus_write_io addr 0x3d5, val 0x79 +vga_cirrus_write_io addr 0x3d4, val 0x1a +vga_cirrus_write_io addr 0x3d5, val 0xe0 +vga_cirrus_write_io addr 0x3d4, val 0x17 +vga_cirrus_write_io addr 0x3d5, val 0x3 + +vga_cirrus_write_io addr 0x3c4, val 0x7 +vga_cirrus_read_io addr 0x3c5, val 0x0 +vga_cirrus_write_io addr 0x3c4, val 0x7 +vga_cirrus_write_io addr 0x3c5, val 0x15 + +vga_cirrus_write_io addr 0x3d4, val 0x13 +vga_cirrus_write_io addr 0x3d5, val 0x80 +vga_cirrus_write_io addr 0x3d4, val 0x1b +vga_cirrus_write_io addr 0x3d5, val 0x32 +vga_cirrus_write_io addr 0x3ce, val 0x5 +vga_cirrus_write_io addr 0x3cf, val 0x40 +vga_cirrus_write_io addr 0x3ce, val 0x6 +vga_cirrus_write_io addr 0x3cf, val 0x1 + +vga_cirrus_read_io addr 0x3c6, val 0xff +vga_cirrus_read_io addr 0x3c6, val 0xff +vga_cirrus_read_io addr 0x3c6, val 0xff +vga_cirrus_read_io addr 0x3c6, val 0xff +vga_cirrus_write_io addr 0x3c6, val 0xc5 + +--- set base address ( 0 ) --- +vga_cirrus_write_io addr 0x3d4, val 0xc +vga_cirrus_write_io addr 0x3d5, val 0x0 +vga_cirrus_write_io addr 0x3d4, val 0xd +vga_cirrus_write_io addr 0x3d5, val 0x0 + +vga_cirrus_write_io addr 0x3d4, val 0x1b +vga_cirrus_read_io addr 0x3d5, val 0x32 +vga_cirrus_write_io addr 0x3d4, val 0x1b +vga_cirrus_write_io addr 0x3d5, val 0x32 + +vga_cirrus_write_io addr 0x3d4, val 0x1d +vga_cirrus_read_io addr 0x3d5, val 0x0 +vga_cirrus_write_io addr 0x3d4, val 0x1d +vga_cirrus_write_io addr 0x3d5, val 0x0 + +-- unblank -- +vga_cirrus_write_io addr 0x3c0, val 0x20 + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#include "cirrus.h" + +void cirrus_setmode(volatile uint8_t *mmio) +{ + fprintf(stderr, "setting mode (1024x768 @ 24bpp)\n"); + /* mode */ + mmio[0x3d4 + VGA_OFFSET] = 0x11; + mmio[0x3d5 + VGA_OFFSET] = 0x20; + mmio[0x3d4 + VGA_OFFSET] = 0x0; + mmio[0x3d5 + VGA_OFFSET] = 0xa3; + mmio[0x3d4 + VGA_OFFSET] = 0x1; + mmio[0x3d5 + VGA_OFFSET] = 0x7f; + mmio[0x3d4 + VGA_OFFSET] = 0x4; + mmio[0x3d5 + VGA_OFFSET] = 0x84; + mmio[0x3d4 + VGA_OFFSET] = 0x5; + mmio[0x3d5 + VGA_OFFSET] = 0x95; + mmio[0x3d4 + VGA_OFFSET] = 0x6; + mmio[0x3d5 + VGA_OFFSET] = 0x24; + mmio[0x3d4 + VGA_OFFSET] = 0x12; + mmio[0x3d5 + VGA_OFFSET] = 0xff; + mmio[0x3d4 + VGA_OFFSET] = 0x9; + mmio[0x3d5 + VGA_OFFSET] = 0x60; + mmio[0x3d4 + VGA_OFFSET] = 0x7; + mmio[0x3d5 + VGA_OFFSET] = 0x79; + mmio[0x3d4 + VGA_OFFSET] = 0x1a; + mmio[0x3d5 + VGA_OFFSET] = 0xe0; + mmio[0x3d4 + VGA_OFFSET] = 0x17; + mmio[0x3d5 + VGA_OFFSET] = 0x3; + mmio[0x3c4 + VGA_OFFSET] = 0x7; + mmio[0x3c5 + VGA_OFFSET] = 0x15; + mmio[0x3d4 + VGA_OFFSET] = 0x13; + mmio[0x3d5 + VGA_OFFSET] = 0x80; + mmio[0x3d4 + VGA_OFFSET] = 0x1b; + mmio[0x3d5 + VGA_OFFSET] = 0x32; + mmio[0x3ce + VGA_OFFSET] = 0x5; + mmio[0x3cf + VGA_OFFSET] = 0x40; + mmio[0x3ce + VGA_OFFSET] = 0x6; + mmio[0x3cf + VGA_OFFSET] = 0x1; +#if 0 + mmio[0x3c6 + VGA_OFFSET]; + mmio[0x3c6 + VGA_OFFSET]; + mmio[0x3c6 + VGA_OFFSET]; + mmio[0x3c6 + VGA_OFFSET]; + mmio[0x3c6 + VGA_OFFSET] = 0xc5; +#endif + + /* base */ + mmio[0x3d4 + VGA_OFFSET] = 0xc; + mmio[0x3d5 + VGA_OFFSET] = 0x0; + mmio[0x3d4 + VGA_OFFSET] = 0xd; + mmio[0x3d5 + VGA_OFFSET] = 0x0; + mmio[0x3d4 + VGA_OFFSET] = 0x1b; + mmio[0x3d5 + VGA_OFFSET] = 0x32; + mmio[0x3d4 + VGA_OFFSET] = 0x1d; + mmio[0x3d5 + VGA_OFFSET] = 0x0; + + /* dpms */ + mmio[0x3d4 + VGA_OFFSET] = 0x1; + mmio[0x3d5 + VGA_OFFSET] = 0x0; + mmio[0x3ce + VGA_OFFSET] = 0xe; + mmio[0x3cf + VGA_OFFSET] = 0x1; + + /* unblank */ + mmio[0x3c0 + VGA_OFFSET] = 0x20; + + fprintf(stderr, "mode done\n"); + sleep(1); +} diff --git a/cirrus.h b/cirrus.h new file mode 100644 index 0000000..bda4dc4 --- /dev/null +++ b/cirrus.h @@ -0,0 +1,51 @@ +#define VGA_OFFSET (-0x3c0) +#define BLT_OFFSET (0x100) + +#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword +#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword +#define CIRRUS_MMIO_BLTWIDTH 0x08 // word +#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word +#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word +#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word +#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword +#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword +#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte +#define CIRRUS_MMIO_BLTMODE 0x18 // byte +#define CIRRUS_MMIO_BLTROP 0x1a // byte +#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte +#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte + +#define CIRRUS_BLT_BUSY 0x01 +#define CIRRUS_BLT_START 0x02 +#define CIRRUS_BLT_RESET 0x04 + +#define CIRRUS_BLTMODE_BACKWARDS 0x01 +#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 +#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 +#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 +#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 +#define CIRRUS_BLTMODE_COLOREXPAND 0x80 +#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 +#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 +#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 +#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 +#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 + +#define CIRRUS_ROP_0 0x00 +#define CIRRUS_ROP_SRC_AND_DST 0x05 +#define CIRRUS_ROP_NOP 0x06 +#define CIRRUS_ROP_SRC_AND_NOTDST 0x09 +#define CIRRUS_ROP_NOTDST 0x0b +#define CIRRUS_ROP_SRC 0x0d +#define CIRRUS_ROP_1 0x0e +#define CIRRUS_ROP_NOTSRC_AND_DST 0x50 +#define CIRRUS_ROP_SRC_XOR_DST 0x59 +#define CIRRUS_ROP_SRC_OR_DST 0x6d +#define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90 +#define CIRRUS_ROP_SRC_NOTXOR_DST 0x95 +#define CIRRUS_ROP_SRC_OR_NOTDST 0xad +#define CIRRUS_ROP_NOTSRC 0xd0 +#define CIRRUS_ROP_NOTSRC_OR_DST 0xd6 +#define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda + +void cirrus_setmode(volatile uint8_t *mmio); diff --git a/cve-2017-2615.c b/cve-2017-2615.c index b953634..2b66f6b 100644 --- a/cve-2017-2615.c +++ b/cve-2017-2615.c @@ -1,72 +1,3 @@ -/* - -mode setting sequence done by cirrus drm driver - ---- set mode ( 1024 x 768 @ 24 bpp ) --- -vga_cirrus_write_io addr 0x3d4, val 0x11 -vga_cirrus_write_io addr 0x3d5, val 0x20 -vga_cirrus_write_io addr 0x3d4, val 0x0 -vga_cirrus_write_io addr 0x3d5, val 0xa3 -vga_cirrus_write_io addr 0x3d4, val 0x1 -vga_cirrus_write_io addr 0x3d5, val 0x7f -vga_cirrus_write_io addr 0x3d4, val 0x4 -vga_cirrus_write_io addr 0x3d5, val 0x84 -vga_cirrus_write_io addr 0x3d4, val 0x5 -vga_cirrus_write_io addr 0x3d5, val 0x95 -vga_cirrus_write_io addr 0x3d4, val 0x6 -vga_cirrus_write_io addr 0x3d5, val 0x24 -vga_cirrus_write_io addr 0x3d4, val 0x12 -vga_cirrus_write_io addr 0x3d5, val 0xff -vga_cirrus_write_io addr 0x3d4, val 0x9 -vga_cirrus_write_io addr 0x3d5, val 0x60 -vga_cirrus_write_io addr 0x3d4, val 0x7 -vga_cirrus_write_io addr 0x3d5, val 0x79 -vga_cirrus_write_io addr 0x3d4, val 0x1a -vga_cirrus_write_io addr 0x3d5, val 0xe0 -vga_cirrus_write_io addr 0x3d4, val 0x17 -vga_cirrus_write_io addr 0x3d5, val 0x3 - -vga_cirrus_write_io addr 0x3c4, val 0x7 -vga_cirrus_read_io addr 0x3c5, val 0x0 -vga_cirrus_write_io addr 0x3c4, val 0x7 -vga_cirrus_write_io addr 0x3c5, val 0x15 - -vga_cirrus_write_io addr 0x3d4, val 0x13 -vga_cirrus_write_io addr 0x3d5, val 0x80 -vga_cirrus_write_io addr 0x3d4, val 0x1b -vga_cirrus_write_io addr 0x3d5, val 0x32 -vga_cirrus_write_io addr 0x3ce, val 0x5 -vga_cirrus_write_io addr 0x3cf, val 0x40 -vga_cirrus_write_io addr 0x3ce, val 0x6 -vga_cirrus_write_io addr 0x3cf, val 0x1 - -vga_cirrus_read_io addr 0x3c6, val 0xff -vga_cirrus_read_io addr 0x3c6, val 0xff -vga_cirrus_read_io addr 0x3c6, val 0xff -vga_cirrus_read_io addr 0x3c6, val 0xff -vga_cirrus_write_io addr 0x3c6, val 0xc5 - ---- set base address ( 0 ) --- -vga_cirrus_write_io addr 0x3d4, val 0xc -vga_cirrus_write_io addr 0x3d5, val 0x0 -vga_cirrus_write_io addr 0x3d4, val 0xd -vga_cirrus_write_io addr 0x3d5, val 0x0 - -vga_cirrus_write_io addr 0x3d4, val 0x1b -vga_cirrus_read_io addr 0x3d5, val 0x32 -vga_cirrus_write_io addr 0x3d4, val 0x1b -vga_cirrus_write_io addr 0x3d5, val 0x32 - -vga_cirrus_write_io addr 0x3d4, val 0x1d -vga_cirrus_read_io addr 0x3d5, val 0x0 -vga_cirrus_write_io addr 0x3d4, val 0x1d -vga_cirrus_write_io addr 0x3d5, val 0x0 - --- unblank -- -vga_cirrus_write_io addr 0x3c0, val 0x20 - -*/ - #include <stdio.h> #include <stdlib.h> #include <stdint.h> @@ -77,183 +8,19 @@ vga_cirrus_write_io addr 0x3c0, val 0x20 #include <sys/io.h> #include <sys/mman.h> -#include <pci/pci.h> - -struct pci_access *pci; -struct pci_dev *dev; - -static void find_device(unsigned int vendor, - unsigned int device) -{ - struct pci_filter filter; - struct pci_dev *d; - - pci_scan_bus(pci); - pci_filter_init(pci, &filter); - filter.vendor = vendor; - filter.device = device; - - for (d = pci->devices; d != NULL; d = d->next) { - if (!pci_filter_match(&filter, d)) - continue; - dev = d; - return; - } - return; -} - -#define VGA_OFFSET (-0x3c0) -#define BLT_OFFSET (0x100) - -#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword -#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword -#define CIRRUS_MMIO_BLTWIDTH 0x08 // word -#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word -#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word -#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word -#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword -#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword -#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte -#define CIRRUS_MMIO_BLTMODE 0x18 // byte -#define CIRRUS_MMIO_BLTROP 0x1a // byte -#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte -#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte - -#define CIRRUS_BLT_BUSY 0x01 -#define CIRRUS_BLT_START 0x02 -#define CIRRUS_BLT_RESET 0x04 - -#define CIRRUS_BLTMODE_BACKWARDS 0x01 -#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 -#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 -#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 -#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 -#define CIRRUS_BLTMODE_COLOREXPAND 0x80 -#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 -#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 -#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 -#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 -#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 - -#define CIRRUS_ROP_0 0x00 -#define CIRRUS_ROP_SRC_AND_DST 0x05 -#define CIRRUS_ROP_NOP 0x06 -#define CIRRUS_ROP_SRC_AND_NOTDST 0x09 -#define CIRRUS_ROP_NOTDST 0x0b -#define CIRRUS_ROP_SRC 0x0d -#define CIRRUS_ROP_1 0x0e -#define CIRRUS_ROP_NOTSRC_AND_DST 0x50 -#define CIRRUS_ROP_SRC_XOR_DST 0x59 -#define CIRRUS_ROP_SRC_OR_DST 0x6d -#define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90 -#define CIRRUS_ROP_SRC_NOTXOR_DST 0x95 -#define CIRRUS_ROP_SRC_OR_NOTDST 0xad -#define CIRRUS_ROP_NOTSRC 0xd0 -#define CIRRUS_ROP_NOTSRC_OR_DST 0xd6 -#define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda +#include "pci.h" +#include "cirrus.h" int main(int argc, char *argv[]) { - char mmiofile[128]; - int mmiofd; volatile uint8_t *mmio; - pci = pci_alloc(); - if (!pci) { - fprintf(stderr, "libpci alloc failed\n"); - exit(1); - } - pci_init(pci); - - find_device(0x1013, 0x00b8); - if (!dev) { - fprintf(stderr, "cirrus not found\n"); - exit(1); - } - fprintf(stderr, "cirrus found at %02x:%02x.%x, mmio @ 0x%08x\n", - dev->bus, dev->dev, dev->func, - (uint32_t) dev->base_addr[1]); - - snprintf(mmiofile, sizeof(mmiofile), - "/sys/bus/pci/devices/%04x:%02x:%02x.%x/resource1", - dev->domain, dev->bus, dev->dev, dev->func); - mmiofd = open(mmiofile, O_RDWR); - if (mmiofd < 0) { - fprintf(stderr, "open %s: %s\n", mmiofile, strerror(errno)); - exit(1); - } - mmio = mmap(NULL, 4096, PROT_WRITE | PROT_READ, MAP_SHARED, mmiofd, 0); - if (mmio == MAP_FAILED) { - fprintf(stderr, "mmap %s: %s\n", mmiofile, strerror(errno)); - exit(1); - } - + find_device("cirrus", 0x1013, 0x00b8); + mmio = mmap_bar(1); fprintf(stderr, "init ok\n"); sleep(1); - fprintf(stderr, "setting mode (1024x768 @ 24bpp)\n"); - /* mode */ - mmio[0x3d4 + VGA_OFFSET] = 0x11; - mmio[0x3d5 + VGA_OFFSET] = 0x20; - mmio[0x3d4 + VGA_OFFSET] = 0x0; - mmio[0x3d5 + VGA_OFFSET] = 0xa3; - mmio[0x3d4 + VGA_OFFSET] = 0x1; - mmio[0x3d5 + VGA_OFFSET] = 0x7f; - mmio[0x3d4 + VGA_OFFSET] = 0x4; - mmio[0x3d5 + VGA_OFFSET] = 0x84; - mmio[0x3d4 + VGA_OFFSET] = 0x5; - mmio[0x3d5 + VGA_OFFSET] = 0x95; - mmio[0x3d4 + VGA_OFFSET] = 0x6; - mmio[0x3d5 + VGA_OFFSET] = 0x24; - mmio[0x3d4 + VGA_OFFSET] = 0x12; - mmio[0x3d5 + VGA_OFFSET] = 0xff; - mmio[0x3d4 + VGA_OFFSET] = 0x9; - mmio[0x3d5 + VGA_OFFSET] = 0x60; - mmio[0x3d4 + VGA_OFFSET] = 0x7; - mmio[0x3d5 + VGA_OFFSET] = 0x79; - mmio[0x3d4 + VGA_OFFSET] = 0x1a; - mmio[0x3d5 + VGA_OFFSET] = 0xe0; - mmio[0x3d4 + VGA_OFFSET] = 0x17; - mmio[0x3d5 + VGA_OFFSET] = 0x3; - mmio[0x3c4 + VGA_OFFSET] = 0x7; - mmio[0x3c5 + VGA_OFFSET] = 0x15; - mmio[0x3d4 + VGA_OFFSET] = 0x13; - mmio[0x3d5 + VGA_OFFSET] = 0x80; - mmio[0x3d4 + VGA_OFFSET] = 0x1b; - mmio[0x3d5 + VGA_OFFSET] = 0x32; - mmio[0x3ce + VGA_OFFSET] = 0x5; - mmio[0x3cf + VGA_OFFSET] = 0x40; - mmio[0x3ce + VGA_OFFSET] = 0x6; - mmio[0x3cf + VGA_OFFSET] = 0x1; -#if 0 - mmio[0x3c6 + VGA_OFFSET]; - mmio[0x3c6 + VGA_OFFSET]; - mmio[0x3c6 + VGA_OFFSET]; - mmio[0x3c6 + VGA_OFFSET]; - mmio[0x3c6 + VGA_OFFSET] = 0xc5; -#endif - - /* base */ - mmio[0x3d4 + VGA_OFFSET] = 0xc; - mmio[0x3d5 + VGA_OFFSET] = 0x0; - mmio[0x3d4 + VGA_OFFSET] = 0xd; - mmio[0x3d5 + VGA_OFFSET] = 0x0; - mmio[0x3d4 + VGA_OFFSET] = 0x1b; - mmio[0x3d5 + VGA_OFFSET] = 0x32; - mmio[0x3d4 + VGA_OFFSET] = 0x1d; - mmio[0x3d5 + VGA_OFFSET] = 0x0; - - /* dpms */ - mmio[0x3d4 + VGA_OFFSET] = 0x1; - mmio[0x3d5 + VGA_OFFSET] = 0x0; - mmio[0x3ce + VGA_OFFSET] = 0xe; - mmio[0x3cf + VGA_OFFSET] = 0x1; - - /* unblank */ - mmio[0x3c0 + VGA_OFFSET] = 0x20; - - fprintf(stderr, "mode done\n"); - sleep(1); + cirrus_setmode(mmio); fprintf(stderr, "trying invalid backwards blit\n"); mmio[BLT_OFFSET + CIRRUS_MMIO_BLTSTATUS] = CIRRUS_BLT_RESET; @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/mman.h> + +#include "pci.h" + +struct pci_access *pci; +struct pci_dev *dev; + +void find_device(char *name, + unsigned int vendor, + unsigned int device) +{ + struct pci_filter filter; + struct pci_dev *d; + + if (!pci) { + pci = pci_alloc(); + if (!pci) { + fprintf(stderr, "libpci alloc failed\n"); + exit(1); + } + pci_init(pci); + pci_scan_bus(pci); + } + + pci_filter_init(pci, &filter); + filter.vendor = vendor; + filter.device = device; + + for (d = pci->devices; d != NULL; d = d->next) { + if (!pci_filter_match(&filter, d)) + continue; + dev = d; + fprintf(stderr, "%s found at %02x:%02x.%x\n", + name, dev->bus, dev->dev, dev->func); + return; + } + fprintf(stderr, "%s not found\n", name); + exit(1); +} + +void *mmap_bar(int nr) +{ + char filename[128]; + size_t size; + int fd; + void *bar; + + snprintf(filename, sizeof(filename), + "/sys/bus/pci/devices/%04x:%02x:%02x.%x/resource%d", + dev->domain, dev->bus, dev->dev, dev->func, nr); + size = dev->size[nr]; + fd = open(filename, O_RDWR); + if (fd < 0) { + fprintf(stderr, "open %s: %s\n", filename, strerror(errno)); + exit(1); + } + bar = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); + if (bar == MAP_FAILED) { + fprintf(stderr, "mmap %s: %s\n", filename, strerror(errno)); + exit(1); + } + if (size >= (1 << 20)) { + fprintf(stderr, "bar %d mapped (%zd MB)\n", nr, size >> 20); + } else { + fprintf(stderr, "bar %d mapped (%zd bytes)\n", nr, size); + } + return bar; +} @@ -0,0 +1,9 @@ +#include <pci/pci.h> + +extern struct pci_access *pci; +extern struct pci_dev *dev; + +void find_device(char *name, + unsigned int vendor, + unsigned int device); +void *mmap_bar(int nr); |