/*
 * cc -lpciaccess dumpio810.c -o dumpio810
 */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <pciaccess.h>

#define A(reg) (*(unsigned volatile *)(map_base + (reg)))
#define B(reg) (*(unsigned short volatile *)(map_base + (reg)))
#define C(reg) (*(unsigned char volatile *)(map_base + (reg)))

#define HTOTAL			0x60000
#define DISP_SL                 0x70000
#define DISP_SLC                0x70004
#define DPLYSTAS                0x70024

#define I810REG_HWSTAM          0x02098
#define I810REG_INT_IDENTITY_R  0x020a4
#define I810REG_INT_MASK_R      0x020a8
#define I810REG_INT_ENABLE_R    0x020a0

#define CRTC_I                  0x3d4
#define CRTC_D                  0x3d5
#define CR00                    0x00
#define CR35                    0x35
#define CR39                    0x39

main(int argc, char **argv)
{
    void *map_base;
    struct pci_device *dev;
    struct pci_id_match match;
    struct pci_device_iterator *iter;

    if (pci_system_init()) {
	printf("pci_system_init: %s\n", strerror(errno)); exit(-1);
    }
    match.vendor_id = 0x8086;
    match.device_id = PCI_MATCH_ANY;
    match.subvendor_id = PCI_MATCH_ANY;
    match.subdevice_id = PCI_MATCH_ANY;
    match.device_class = 0;
    match.device_class_mask = 0;
    if (!(iter = pci_id_match_iterator_create(&match))) {
	printf("pci_id_match_iterator_create: %s\n", strerror(errno)); exit(-1);
    }
    while (1) {
	if (!(dev = pci_device_next(iter))) {
	    printf("device not found\n"); exit(-1);
	}
	if (dev->device_id == 0x7125
#if 0
         || dev->device_id == 0x5d44 
#endif
				     ) {
	    break;
	}
    }
    if (pci_device_probe(dev)) {
	printf("pci_device_probe: %s\n", strerror(errno)); exit(-1);
    }
    printf("phys_base: 0x%08llx phys_len: 0x%08llx\n", dev->regions[1].base_addr, dev->regions[1].size);
    if (pci_device_map_range(dev, dev->regions[1].base_addr, 
                             dev->regions[1].size, 1, &map_base)) {
        printf("pci_device_map_range: %s\n", strerror(errno)); exit(-1);
    }

    printf("\n");
    printf("I810REG_HWSTAM            ==> 0x%08x\n", B(I810REG_HWSTAM));
    printf("I810REG_INT_MASK_R        ==> 0x%08x\n", B(I810REG_INT_MASK_R));
    printf("I810REG_INT_ENABLE_R      ==> 0x%08x\n", B(I810REG_INT_ENABLE_R));
    printf("I810REG_INT_IDENTITY_R    ==> 0x%08x\n", B(I810REG_INT_IDENTITY_R));
    printf("DPLYSTAS                  ==> 0x%08x\n", A(DPLYSTAS));
    printf("DISP_SL                   ==> 0x%08x\n", A(DISP_SL));
    printf("DISP_SLC                  ==> 0x%08x\n", A(DISP_SLC));
    printf("HTOTAL                    ==> 0x%08x\n", A(HTOTAL));
    printf("CR00                      ==> 0x%08x\n", (C(CRTC_I) = CR00, C(CRTC_D)));
    printf("CR35                      ==> 0x%08x\n", (C(CRTC_I) = CR35, C(CRTC_D)));
    printf("CR39                      ==> 0x%08x\n", (C(CRTC_I) = CR39, C(CRTC_D)));
}

