This is the beginning of a tool that transforms the i9x5 code to user mode code. Consider this a very early stage although it does produce two programs. Requires spatch 1.0 or greater. To try it out, assuming you have an up-to-date spatch, sh transform make make broken Please don't fall to the temptation to auto-magicize this process. It's primitive for a reason. That said, suggestions welcome of course. Change-Id: I0188e36637b198b06c17f6d3c714d990e88bd57d Signed-off-by: Ronald G. Minnich <rminnich@chromium.org> Reviewed-on: http://review.coreboot.org/1003 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
		
			
				
	
	
		
			256 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			256 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * This file is part of i915tool
 | |
|  *
 | |
|  * Copyright (C) 2012 The ChromiumOS Authors.  All rights reserved.
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License as published by
 | |
|  * the Free Software Foundation; version 2 of the License.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU General Public License
 | |
|  * along with this program; if not, write to the Free Software
 | |
|  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 | |
|  */
 | |
| 
 | |
| #include "video.h"
 | |
| 
 | |
| int verbose = 1;
 | |
| static unsigned short addrport, dataport;
 | |
| struct drm_device *i915;
 | |
| unsigned short vendor=0x8086, device=0x0116;
 | |
| struct pci_dev fake = {.vendor_id=0x8086, .device_id = 0x0116};
 | |
| int dofake = 0;
 | |
| u8 *bios_image = NULL;
 | |
| u8 *mmiobase;
 | |
| u32 mmiophys;
 | |
| int mmiosize;
 | |
| size_t bios_image_size;
 | |
| /* temporary */
 | |
| unsigned int i915_lvds_downclock = 0;
 | |
| int i915_vbt_sdvo_panel_type = -1;
 | |
| 
 | |
| /* */
 | |
| 
 | |
| /* not sure how we want to do this so let's guess */
 | |
| /* to make it easy, we start at zero and assume 250 hz. */
 | |
| unsigned long msecs(void)
 | |
| {
 | |
| 	struct timeval start, now;
 | |
| 	static int first = 0;
 | |
| 	unsigned long j;
 | |
| 	if (! first++)
 | |
| 		gettimeofday(&start, NULL);
 | |
| 	gettimeofday(&now, NULL);
 | |
| 	j = (now.tv_sec - start.tv_sec)*1000 + (now.tv_usec-start.tv_usec)/1000;
 | |
| 	return j;
 | |
| }
 | |
| 
 | |
| void
 | |
| mdelay(unsigned long ms)
 | |
| {
 | |
| 	unsigned long start;
 | |
| 	start = msecs();
 | |
| 	while (msecs() < (start + ms))
 | |
| 		;
 | |
| }
 | |
| 
 | |
| void
 | |
| hexdump(u8 *base, int size)
 | |
| {
 | |
| 	int i, j;
 | |
| 	for(i = 0; i < size/sizeof(u32); i += 8) {
 | |
| 		printf("%#x: ", i);
 | |
| 		for(j = 0; j < 8; j++)
 | |
| 			printf("%08x", base[i+j]);
 | |
| 		printf("\n");
 | |
| 	}
 | |
| }
 | |
| void udelay(int i)
 | |
| {
 | |
| 	printf("UDELAY!\n");
 | |
| }
 | |
| 
 | |
| unsigned long io_I915_READ(unsigned long addr)
 | |
| {
 | |
| 	unsigned long val;
 | |
| 	if (dofake)
 | |
| 		return 0xcafebabe;
 | |
| 	outl(addr, addrport);
 | |
| 	val = inl(dataport);
 | |
| 	if (verbose)
 | |
| 		fprintf(stderr, "%s: %x <- %x\n", __func__, val, addr);
 | |
| 	return val;
 | |
| }
 | |
| 
 | |
| void io_I915_WRITE(unsigned long addr, unsigned long val)
 | |
| {
 | |
| 	if (dofake)
 | |
| 		return;
 | |
| 	outl(addr, addrport);
 | |
| 	outl(val, dataport);
 | |
| 	if (verbose)
 | |
| 		fprintf(stderr, "%s: %x -> %x\n", __func__, val, addr);
 | |
| }
 | |
| 
 | |
| unsigned long I915_READ(unsigned long addr)
 | |
| {
 | |
| 	volatile u32 *ptr = (u32 *)(mmiobase + addr);
 | |
| 	unsigned long val;
 | |
| 	if (dofake)
 | |
| 		return 0xcafebabe;
 | |
| 	val = *ptr;
 | |
| 	if (verbose)
 | |
| 		fprintf(stderr, "%s: %x <- %x\n", __func__, val, addr);
 | |
| 	return val;
 | |
| }
 | |
| 
 | |
| void I915_WRITE(unsigned long addr, unsigned long val)
 | |
| {
 | |
| 	volatile u32 *ptr = (u32 *)(mmiobase + addr);
 | |
| 	if (dofake)
 | |
| 		return;
 | |
| 	*ptr = val;
 | |
| 	if (verbose)
 | |
| 		fprintf(stderr, "%s: %x -> %x\n", __func__, val, addr);
 | |
| }
 | |
| 
 | |
| u16 I915_READ16(unsigned long addr)
 | |
| {
 | |
| 	volatile u16 *ptr = (u16 *)(mmiobase + addr);
 | |
| 	unsigned long val;
 | |
| 	if (dofake)
 | |
| 		return 0xbabe;
 | |
| 	val = *ptr;
 | |
| 	if (verbose)
 | |
| 		fprintf(stderr, "%s: %x <- %x\n", __func__, val, addr);
 | |
| 	return val;
 | |
| }
 | |
| 
 | |
| void I915_WRITE16(unsigned long addr, u16 val)
 | |
| {
 | |
| 	volatile u16 *ptr = (u16 *)(mmiobase + addr);
 | |
| 	if (dofake)
 | |
| 		return;
 | |
| 	*ptr = val;
 | |
| 	if (verbose)
 | |
| 		fprintf(stderr, "%s: %x -> %x\n", __func__, val, addr);
 | |
| }
 | |
| 
 | |
| #define GTT_RETRY 1000
 | |
| static int gtt_poll(u32 reg, u32 mask, u32 value)
 | |
| {
 | |
|         unsigned try = GTT_RETRY;
 | |
|         u32 data;
 | |
| 
 | |
|         while (try--) {
 | |
|                 data = I915_READ(reg);
 | |
|                 if ((data & mask) == value){
 | |
| 			printf("succeeds after %d tries\n", GTT_RETRY-try);
 | |
|                         return 1;
 | |
| 		}
 | |
|                 udelay(10);
 | |
|         }
 | |
| 
 | |
|         fprintf(stderr, "GT init timeout\n");
 | |
|         return 0;
 | |
| }
 | |
| void *pci_map_rom(struct pci_dev *dev, size_t *size)
 | |
| {
 | |
| 	*size = bios_image_size;
 | |
| 	return bios_image;
 | |
| }
 | |
| 
 | |
| void *pci_unmap_rom(struct pci_dev *dev, void *bios)
 | |
| {
 | |
| 	return NULL;
 | |
| }
 | |
| 
 | |
| void *dmi_check_system(unsigned long ignore)
 | |
| {
 | |
| 	return NULL;
 | |
| }
 | |
| 
 | |
| void
 | |
| mapit(void)
 | |
| {
 | |
| 	int kfd;
 | |
| 	kfd = open("/dev/mem", O_RDWR);
 | |
| 	if (kfd < 0)
 | |
| 		errx(1, "/dev/kmem");
 | |
| 	mmiobase = mmap(NULL, mmiosize, PROT_WRITE|PROT_READ, MAP_SHARED, kfd,
 | |
| 		mmiophys);
 | |
| 	if ((void *)-1 == mmiobase)
 | |
| 		errx(1, "mmap");
 | |
| }
 | |
| 
 | |
| void
 | |
| devinit()
 | |
| {
 | |
| 	u32 val;
 | |
| 	/* force wake. */
 | |
| 	I915_WRITE(0xa18c, 1);
 | |
| 	gtt_poll(0x130090, 1, 1);
 | |
| }
 | |
| int main(int argc, char *argv[])
 | |
| {
 | |
| 	struct pci_dev *pci_dev_find(struct drm_device *dev);
 | |
| 
 | |
| 	for(argc--, argv++; argc; argc--, argv++) {
 | |
| 		if (argv[0][0] != '-')
 | |
| 			break;
 | |
| 		if (!strcmp(argv[0], "-f"))
 | |
| 			dofake++;
 | |
| 	}
 | |
| 	i915 = calloc(1, sizeof(*i915));
 | |
| 	i915->dev_private = calloc(1, sizeof(*i915->dev_private));
 | |
| 	/* until we do a bit more w/ coccinelle */
 | |
| 	i915->dev_private->dev = i915;
 | |
| 
 | |
| 	if (dofake) {
 | |
| 		i915->pdev = &fake;
 | |
| 		if (! find_idlist(i915, vendor, device))
 | |
| 			errx(1, "can't find fake device in pciidlist");
 | |
| 	} else {
 | |
| 		if (! pci_dev_find(i915))
 | |
| 			errx(1, "No VGA device of any kind found\n");
 | |
| 	}
 | |
| 
 | |
| 	if (argc) {
 | |
| 		FILE *fd;
 | |
| 		int amt;
 | |
| 		/* size it later */
 | |
| 		bios_image = malloc(8*1048576);
 | |
| 		fd = fopen(argv[0], "r");
 | |
| 		amt = fread(bios_image, 65536, 128, fd);
 | |
| 		if (amt < 1) {
 | |
| 			free(bios_image);
 | |
| 		} else {
 | |
| 			i915->bios_bin = bios_image;
 | |
| 			i915->dev_private->opregion.vbt = bios_image;
 | |
| 			bios_image_size = amt * 65536;
 | |
| 			fclose(fd);
 | |
| 		}
 | |
| 	}
 | |
| 	/* get the base address for the mmio indirection registers -- BAR 2 */
 | |
| 	addrport = i915->pdev->base_addr[4] & ~3;
 | |
| 	dataport = addrport + 4;
 | |
| 	printf("Addrport is at %x, dataport at %x\n", addrport, dataport);
 | |
| 	/* get the base of the mmio space */
 | |
| 	mmiophys = i915->pdev->base_addr[0] & ~0xf;
 | |
| 	mmiosize = i915->pdev->size[0];
 | |
| 	printf("phys base is %#x, size %d\n", mmiophys, mmiosize);
 | |
| 	mapit();
 | |
| 	devinit();
 | |
| 	//hexdump(mmiobase, mmiosize);
 | |
| 	/* we should use ioperm but hey ... it's had troubles */
 | |
| 	iopl(3);
 | |
| 	intel_setup_bios(i915);
 | |
| 	if (i915->bios_bin)
 | |
| 		intel_parse_bios(i915);
 | |
| }
 |