コード例 #1
0
ファイル: driver.c プロジェクト: looncraz/haiku
static status_t et6000MapDevice(ET6000DeviceInfo *di) {
char buffer[B_OS_NAME_LENGTH];
ET6000SharedInfo *si = di->si;
uint32  tmpUlong;
pci_info *pcii = &(di->pcii);

    /* Enable memory space access and I/O space access */
    tmpUlong = get_pci(PCI_command, 4);
    tmpUlong |= 0x00000003;
    set_pci(PCI_command, 4, tmpUlong);

    /* Enable ROM decoding */
    tmpUlong = get_pci(PCI_rom_base, 4);
    tmpUlong |= 0x00000001;
    set_pci(PCI_rom_base, 4, tmpUlong);

    /* PCI header base address in I/O space */
    si->pciConfigSpace = (uint16)di->pcii.u.h0.base_registers[1];

    sprintf(buffer, "%04X_%04X_%02X%02X%02X videomemory",
        di->pcii.vendor_id, di->pcii.device_id,
        di->pcii.bus, di->pcii.device, di->pcii.function);

   /*
    * We map the whole graphics card memory area (which consist of RAM memory
    * and memory mapped registers) at once. Memory mapped registers must not
    * be cacheble, so the whole area is mapped with B_MTR_UC (unable caching).
    * We certainly could map separately the RAM memory with write combining
    * (B_MTR_WC) and the memory mapped registers with B_MTR_UC.
    */
    si->memoryArea = map_physical_memory(buffer,
        di->pcii.u.h0.base_registers[0],
        di->pcii.u.h0.base_register_sizes[0],
        B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_UC,
        B_READ_AREA + B_WRITE_AREA,
        &(si->memory));

    si->framebuffer = si->memory;
    si->mmRegs = (void *)((uint32)si->memory + 0x003fff00);
    si->emRegs = (void *)((uint32)si->memory + 0x003fe000);

    /* remember the physical addresses */
    si->physMemory = si->physFramebuffer =
        (void *) di->pcii.u.h0.base_registers_pci[0];

    si->memSize = et6000GetOnboardMemorySize(si->pciConfigSpace, si->memory);

    /* in any case, return the result */
    return si->memoryArea;
}
コード例 #2
0
ファイル: driver.c プロジェクト: DonCN/haiku
static void unmap_device(device_info *di) {
	shared_info *si = di->si;
	uint32	tmpUlong;
	pci_info *pcii = &(di->pcii);

	/* disable memory mapped IO */
	tmpUlong = get_pci(PCI_command, 4);
	tmpUlong &= 0xfffffffc;
	set_pci(PCI_command, 4, tmpUlong);
	/* delete the areas */
	if (si->regs_area >= 0) delete_area(si->regs_area);
	if (si->fb_area >= 0) delete_area(si->fb_area);
	si->regs_area = si->fb_area = -1;
	si->framebuffer = NULL;
	di->regs = NULL;
}
コード例 #3
0
ファイル: device.c プロジェクト: DonCN/haiku
static void
UnmapDevice()
{
	SharedInfo *si = gPd->si;
	pci_info *pcii = &gPd->pcii;
	uint32 tmpUlong;

	/* Disable memory mapped IO */
	tmpUlong = get_pci(PCI_command, 2);
	tmpUlong &= ~PCI_command_memory;
	set_pci(PCI_command, 2, tmpUlong);

	/* Delete the areas */
	if (si->fifoArea >= 0)
		delete_area(si->fifoArea);
	if (si->fbArea >= 0)
		delete_area(si->fbArea);
	si->fifoArea = si->fbArea = -1;
	si->fb = si->fifo = NULL;
}
コード例 #4
0
ファイル: device.c プロジェクト: DonCN/haiku
static status_t
OpenHook(const char *name, uint32 flags, void **cookie)
{
	status_t ret = B_OK;
	pci_info *pcii = &gPd->pcii;
	uint32 tmpUlong;

	TRACE("OpenHook (%s, %ld)\n", name, flags);
	ACQUIRE_BEN(gPd->kernel);

	if (gPd->isOpen)
		goto markAsOpen;

	/* Enable memory mapped IO and VGA I/O */
	tmpUlong = get_pci(PCI_command, 2);
	tmpUlong |= PCI_command_memory;
	tmpUlong |= PCI_command_io;
	set_pci(PCI_command, 2, tmpUlong);

	if ((ret = CreateShared()) != B_OK)
		goto done;
	if ((ret = CheckCapabilities()) != B_OK)
		goto freeShared;
	if ((ret = MapDevice()) != B_OK)
		goto freeShared;

markAsOpen:
	gPd->isOpen++;
	*cookie = gPd;
	goto done;

freeShared:
	FreeShared();

done:
	RELEASE_BEN(gPd->kernel);
	TRACE("OpenHook: %ld\n", ret);
	return ret;
}
コード例 #5
0
ファイル: driver.c プロジェクト: DonCN/haiku
/* -----------
	control_hook - where the real work is done
----------- */
static status_t
control_hook (void* dev, uint32 msg, void *buf, size_t len) {
	device_info *di = (device_info *)dev;
	status_t result = B_DEV_INVALID_IOCTL;
	uint32 tmpUlong;

	switch (msg) {
		/* the only PUBLIC ioctl */
		case B_GET_ACCELERANT_SIGNATURE: {
			char *sig = (char *)buf;
			strcpy(sig, current_settings.accelerant);
			result = B_OK;
		} break;

		/* PRIVATE ioctl from here on */
		case ENG_GET_PRIVATE_DATA: {
			eng_get_private_data *gpd = (eng_get_private_data *)buf;
			if (gpd->magic == VIA_PRIVATE_DATA_MAGIC) {
				gpd->shared_info_area = di->shared_area;
				result = B_OK;
			}
		} break;
		case ENG_GET_PCI: {
			eng_get_set_pci *gsp = (eng_get_set_pci *)buf;
			if (gsp->magic == VIA_PRIVATE_DATA_MAGIC) {
				pci_info *pcii = &(di->pcii);
				gsp->value = get_pci(gsp->offset, gsp->size);
				result = B_OK;
			}
		} break;
		case ENG_SET_PCI: {
			eng_get_set_pci *gsp = (eng_get_set_pci *)buf;
			if (gsp->magic == VIA_PRIVATE_DATA_MAGIC) {
				pci_info *pcii = &(di->pcii);
				set_pci(gsp->offset, gsp->size, gsp->value);
				result = B_OK;
			}
		} break;
		case ENG_DEVICE_NAME: { // apsed
			eng_device_name *dn = (eng_device_name *)buf;
			if (dn->magic == VIA_PRIVATE_DATA_MAGIC) {
				strcpy(dn->name, di->name);
				result = B_OK;
			}
		} break;
		case ENG_RUN_INTERRUPTS: {
			eng_set_bool_state *ri = (eng_set_bool_state *)buf;
			if (ri->magic == VIA_PRIVATE_DATA_MAGIC) {
				vuint32 *regs = di->regs;
				if (ri->do_it) {
					enable_vbi(regs);
				} else {
					disable_vbi(regs);
				}
				result = B_OK;
			}
		} break;
		case ENG_GET_NTH_AGP_INFO: {
			eng_nth_agp_info *nai = (eng_nth_agp_info *)buf;
			if (nai->magic == VIA_PRIVATE_DATA_MAGIC) {
				nai->exist = false;
				nai->agp_bus = false;
				if (agp_bus) {
					nai->agp_bus = true;
					if ((*agp_bus->get_nth_agp_info)(nai->index, &(nai->agpi)) == B_NO_ERROR) {
						nai->exist = true;
					}
				}
				result = B_OK;
			}
		} break;
		case ENG_ENABLE_AGP: {
			eng_cmd_agp *nca = (eng_cmd_agp *)buf;
			if (nca->magic == VIA_PRIVATE_DATA_MAGIC) {
				if (agp_bus) {
					nca->agp_bus = true;
					nca->cmd = agp_bus->set_agp_mode(nca->cmd);
				} else {
					nca->agp_bus = false;
					nca->cmd = 0;
				}
				result = B_OK;
			}
		} break;
		case ENG_ISA_OUT: {
			eng_in_out_isa *io_isa = (eng_in_out_isa *)buf;
			if (io_isa->magic == VIA_PRIVATE_DATA_MAGIC) {
				pci_info *pcii = &(di->pcii);

				/* lock the driver:
				 * no other graphics card may have ISA I/O enabled when we enter */
				AQUIRE_BEN(pd->kernel);

				/* enable ISA I/O access */
				tmpUlong = get_pci(PCI_command, 2);
				tmpUlong |= PCI_command_io;
				set_pci(PCI_command, 2, tmpUlong);

				if (io_isa->size == 1)
  					isa_bus->write_io_8(io_isa->adress, (uint8)io_isa->data);
   				else
   					isa_bus->write_io_16(io_isa->adress, io_isa->data);
  				result = B_OK;

				/* disable ISA I/O access */
				tmpUlong = get_pci(PCI_command, 2);
				tmpUlong &= ~PCI_command_io;
				set_pci(PCI_command, 2, tmpUlong);

				/* end of critical section */
				RELEASE_BEN(pd->kernel);
   			}
		} break;
		case ENG_ISA_IN: {
			eng_in_out_isa *io_isa = (eng_in_out_isa *)buf;
			if (io_isa->magic == VIA_PRIVATE_DATA_MAGIC) {
				pci_info *pcii = &(di->pcii);

				/* lock the driver:
				 * no other graphics card may have ISA I/O enabled when we enter */
				AQUIRE_BEN(pd->kernel);

				/* enable ISA I/O access */
				tmpUlong = get_pci(PCI_command, 2);
				tmpUlong |= PCI_command_io;
				set_pci(PCI_command, 2, tmpUlong);

				if (io_isa->size == 1)
	   				io_isa->data = isa_bus->read_io_8(io_isa->adress);
	   			else
	   				io_isa->data = isa_bus->read_io_16(io_isa->adress);
   				result = B_OK;

				/* disable ISA I/O access */
				tmpUlong = get_pci(PCI_command, 2);
				tmpUlong &= ~PCI_command_io;
				set_pci(PCI_command, 2, tmpUlong);

				/* end of critical section */
				RELEASE_BEN(pd->kernel);
   			}
		} break;
	}
	return result;
}
コード例 #6
0
ファイル: driver.c プロジェクト: DonCN/haiku
static status_t map_device(device_info *di)
{
	char buffer[B_OS_NAME_LENGTH]; /*memory for device name*/
	shared_info *si = di->si;
	uint32	tmpUlong;
	pci_info *pcii = &(di->pcii);
	system_info sysinfo;

	/*storage for the physical to virtual table (used for dma buffer)*/
//	physical_entry physical_memory[2];
//	#define G400_DMA_BUFFER_SIZE 1024*1024

	/* variables for making copy of ROM */
	uint8* rom_temp;
	area_id rom_area;

	/* Nvidia cards have registers in [0] and framebuffer in [1] */
	int registers = 1;
	int frame_buffer = 0;
//	int pseudo_dma = 2;

	/* enable memory mapped IO, disable VGA I/O - this is defined in the PCI standard */
	tmpUlong = get_pci(PCI_command, 2);
	/* enable PCI access */
	tmpUlong |= PCI_command_memory;
	/* enable busmastering */
	tmpUlong |= PCI_command_master;
	/* disable ISA I/O access */
	tmpUlong &= ~PCI_command_io;
	set_pci(PCI_command, 2, tmpUlong);

 	/*work out which version of BeOS is running*/
 	get_system_info(&sysinfo);
 	if (0)//sysinfo.kernel_build_date[0]=='J')/*FIXME - better ID version*/
 	{
 		si->use_clone_bugfix = 1;
 	}
 	else
 	{
 		si->use_clone_bugfix = 0;
 	}

	/* work out a name for the register mapping */
	sprintf(buffer, DEVICE_FORMAT " regs",
		di->pcii.vendor_id, di->pcii.device_id,
		di->pcii.bus, di->pcii.device, di->pcii.function);

	/* get a virtual memory address for the registers*/
	si->regs_area = map_physical_memory(
		buffer,
		/* WARNING: Nvidia needs to map regs as viewed from PCI space! */
		di->pcii.u.h0.base_registers_pci[registers],
		di->pcii.u.h0.base_register_sizes[registers],
		B_ANY_KERNEL_ADDRESS,
 		(si->use_clone_bugfix ? B_READ_AREA|B_WRITE_AREA : 0),
		(void **)&(di->regs));
 	si->clone_bugfix_regs = (uint32 *) di->regs;

	/* if mapping registers to vmem failed then pass on error */
	if (si->regs_area < 0) return si->regs_area;

	/* work out a name for the ROM mapping*/
	sprintf(buffer, DEVICE_FORMAT " rom",
		di->pcii.vendor_id, di->pcii.device_id,
		di->pcii.bus, di->pcii.device, di->pcii.function);

	/* disable ROM shadowing, we want the guaranteed exact contents of the chip */
	/* warning:
	 * don't touch: (confirmed) NV04, NV05, NV05-M64, NV11 all shutoff otherwise.
	 * NV18, NV28 and NV34 keep working.
	 * confirmed NV28 and NV34 to use upper part of shadowed ROM for scratch purposes,
	 * however the actual ROM content (so the used part) is intact (confirmed). */
	//set_pci(ENCFG_ROMSHADOW, 4, 0);

	/* get ROM memory mapped base adress - this is defined in the PCI standard */
	tmpUlong = get_pci(PCI_rom_base, 4);
	if (tmpUlong)
	{
		/* ROM was assigned an adress, so enable ROM decoding - see PCI standard */
		tmpUlong |= 0x00000001;
		set_pci(PCI_rom_base, 4, tmpUlong);

		rom_area = map_physical_memory(
			buffer,
			(void *)di->pcii.u.h0.rom_base_pci,
			di->pcii.u.h0.rom_size,
			B_ANY_KERNEL_ADDRESS,
			B_READ_AREA,
			(void **)&(rom_temp)
		);

		/* check if we got the BIOS signature (might fail on laptops..) */
		if (rom_temp[0]!=0x55 || rom_temp[1]!=0xaa)
		{
			/* apparantly no ROM is mapped here */
			delete_area(rom_area);
			rom_area = -1;
			/* force using ISA legacy map as fall-back */
			tmpUlong = 0x00000000;
		}
	}

	if (!tmpUlong)
	{
		/* ROM was not assigned an adress, fetch it from ISA legacy memory map! */
		rom_area = map_physical_memory(
			buffer,
			(void *)0x000c0000,
			65536,
			B_ANY_KERNEL_ADDRESS,
			B_READ_AREA,
			(void **)&(rom_temp)
		);
	}

	/* if mapping ROM to vmem failed then clean up and pass on error */
	if (rom_area < 0) {
		delete_area(si->regs_area);
		si->regs_area = -1;
		return rom_area;
	}

	/* dump ROM to file if selected in skel.settings
	 * (ROM always fits in 64Kb: checked TNT1 - FX5950) */
	if (current_settings.dumprom) dumprom (rom_temp, 65536);
	/* make a copy of ROM for future reference */
	memcpy (si->rom_mirror, rom_temp, 65536);

	/* disable ROM decoding - this is defined in the PCI standard, and delete the area */
	tmpUlong = get_pci(PCI_rom_base, 4);
	tmpUlong &= 0xfffffffe;
	set_pci(PCI_rom_base, 4, tmpUlong);
	delete_area(rom_area);

	/* work out a name for the framebuffer mapping*/
	sprintf(buffer, DEVICE_FORMAT " framebuffer",
		di->pcii.vendor_id, di->pcii.device_id,
		di->pcii.bus, di->pcii.device, di->pcii.function);

	/* map the framebuffer into vmem, using Write Combining*/
	si->fb_area = map_physical_memory(
		buffer,
		/* WARNING: Nvidia needs to map framebuffer as viewed from PCI space! */
		(void *) di->pcii.u.h0.base_registers_pci[frame_buffer],
		di->pcii.u.h0.base_register_sizes[frame_buffer],
		B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC,
		B_READ_AREA + B_WRITE_AREA,
		&(si->framebuffer));

	/*if failed with write combining try again without*/
	if (si->fb_area < 0) {
		si->fb_area = map_physical_memory(
			buffer,
			/* WARNING: Nvidia needs to map framebuffer as viewed from PCI space! */
			(void *) di->pcii.u.h0.base_registers_pci[frame_buffer],
			di->pcii.u.h0.base_register_sizes[frame_buffer],
			B_ANY_KERNEL_BLOCK_ADDRESS,
			B_READ_AREA + B_WRITE_AREA,
			&(si->framebuffer));
	}

	/* if there was an error, delete our other areas and pass on error*/
	if (si->fb_area < 0)
	{
		delete_area(si->regs_area);
		si->regs_area = -1;
		return si->fb_area;
	}
//fixme: retest for card coldstart and PCI/virt_mem mapping!!
	/* remember the DMA address of the frame buffer for BDirectWindow?? purposes */
	si->framebuffer_pci = (void *) di->pcii.u.h0.base_registers_pci[frame_buffer];

	// remember settings for use here and in accelerant
	si->settings = current_settings;

	/* in any case, return the result */
	return si->fb_area;
}
コード例 #7
0
ファイル: driver.c プロジェクト: luciang/haiku
static status_t
control_hook(void* dev, uint32 msg, void *buf, size_t len)
{
	device_info *di = (device_info *)dev;
	status_t result = B_DEV_INVALID_IOCTL;
	uint32 tmpUlong;

	switch (msg) {
		/* the only PUBLIC ioctl */
		case B_GET_ACCELERANT_SIGNATURE:
		{
			strcpy((char* )buf, sSettings.accelerant);
			result = B_OK;
			break;
		}

		/* PRIVATE ioctl from here on */
		case NV_GET_PRIVATE_DATA:
		{
			nv_get_private_data *gpd = (nv_get_private_data *)buf;
			if (gpd->magic == NV_PRIVATE_DATA_MAGIC) {
				gpd->shared_info_area = di->shared_area;
				result = B_OK;
			}
			break;
		}

		case NV_GET_PCI:
		{
			nv_get_set_pci *gsp = (nv_get_set_pci *)buf;
			if (gsp->magic == NV_PRIVATE_DATA_MAGIC) {
				pci_info *pcii = &(di->pcii);
				gsp->value = get_pci(gsp->offset, gsp->size);
				result = B_OK;
			}
			break;
		}

		case NV_SET_PCI:
		{
			nv_get_set_pci *gsp = (nv_get_set_pci *)buf;
			if (gsp->magic == NV_PRIVATE_DATA_MAGIC) {
				pci_info *pcii = &(di->pcii);
				set_pci(gsp->offset, gsp->size, gsp->value);
				result = B_OK;
			}
			break;
		}

		case NV_DEVICE_NAME:
		{
			nv_device_name *dn = (nv_device_name *)buf;
			if (dn->magic == NV_PRIVATE_DATA_MAGIC) {
				strcpy(dn->name, di->name);
				result = B_OK;
			}
			break;
		}

		case NV_RUN_INTERRUPTS:
		{
			nv_set_vblank_int *vi = (nv_set_vblank_int *)buf;
			if (vi->magic == NV_PRIVATE_DATA_MAGIC) {
				vuint32 *regs = di->regs;
				if (!(vi->crtc)) {
					if (vi->do_it) {
						enable_vbi_crtc1(regs);
					} else {
						disable_vbi_crtc1(regs);
					}
				} else {
					if (vi->do_it) {
						enable_vbi_crtc2(regs);
					} else {
						disable_vbi_crtc2(regs);
					}
				}
				result = B_OK;
			}
			break;
		}

		case NV_ISA_OUT:
		{
			nv_in_out_isa *io_isa = (nv_in_out_isa *)buf;
			if (io_isa->magic == NV_PRIVATE_DATA_MAGIC) {
				pci_info *pcii = &(di->pcii);

				/* lock the driver:
				 * no other graphics card may have ISA I/O enabled when we enter */
				AQUIRE_BEN(pd->kernel);

				/* enable ISA I/O access */
				tmpUlong = get_pci(PCI_command, 2);
				tmpUlong |= PCI_command_io;
				set_pci(PCI_command, 2, tmpUlong);

				if (io_isa->size == 1)
  					isa_bus->write_io_8(io_isa->adress, (uint8)io_isa->data);
   				else
   					isa_bus->write_io_16(io_isa->adress, io_isa->data);
  				result = B_OK;

				/* disable ISA I/O access */
				tmpUlong = get_pci(PCI_command, 2);
				tmpUlong &= ~PCI_command_io;
				set_pci(PCI_command, 2, tmpUlong);

				/* end of critical section */
				RELEASE_BEN(pd->kernel);
   			}
			break;
		}

		case NV_ISA_IN:
		{
			nv_in_out_isa *io_isa = (nv_in_out_isa *)buf;
			if (io_isa->magic == NV_PRIVATE_DATA_MAGIC) {
				pci_info *pcii = &(di->pcii);

				/* lock the driver:
				 * no other graphics card may have ISA I/O enabled when we enter */
				AQUIRE_BEN(pd->kernel);

				/* enable ISA I/O access */
				tmpUlong = get_pci(PCI_command, 2);
				tmpUlong |= PCI_command_io;
				set_pci(PCI_command, 2, tmpUlong);

				if (io_isa->size == 1)
	   				io_isa->data = isa_bus->read_io_8(io_isa->adress);
	   			else
	   				io_isa->data = isa_bus->read_io_16(io_isa->adress);
   				result = B_OK;

				/* disable ISA I/O access */
				tmpUlong = get_pci(PCI_command, 2);
				tmpUlong &= ~PCI_command_io;
				set_pci(PCI_command, 2, tmpUlong);

				/* end of critical section */
				RELEASE_BEN(pd->kernel);
   			}
			break;
		}
	}

	return result;
}
コード例 #8
0
ファイル: driver.c プロジェクト: looncraz/haiku
/*
 * et6000ControlHook - where the real work is done
 */
static status_t et6000ControlHook(void* dev, uint32 msg, void *buf, size_t len) {
ET6000DeviceInfo *di = (ET6000DeviceInfo *)dev;
status_t result = B_DEV_INVALID_IOCTL;

    /* ddprintf(("ioctl: %d, buf: 0x%08x, len: %d\n", msg, buf, len)); */
    switch (msg) {
        /* the only PUBLIC ioctl */
        case B_GET_ACCELERANT_SIGNATURE: {
            char *sig = (char *)buf;
            strcpy(sig, "et6000.accelerant");
            result = B_OK;
        } break;

        /* PRIVATE ioctl from here on */
        case ET6000_GET_PRIVATE_DATA: {
            ET6000GetPrivateData *gpd = (ET6000GetPrivateData *)buf;
            if (gpd->magic == ET6000_PRIVATE_DATA_MAGIC) {
                gpd->sharedInfoArea = di->sharedArea;
                result = B_OK;
            }
        } break;

        case ET6000_GET_PCI: {
            ET6000GetSetPCI *gsp = (ET6000GetSetPCI *)buf;
            if (gsp->magic == ET6000_PRIVATE_DATA_MAGIC) {
                pci_info *pcii = &(di->pcii);
                gsp->value = get_pci(gsp->offset, gsp->size);
                result = B_OK;
            }
        } break;

        case ET6000_SET_PCI: {
            ET6000GetSetPCI *gsp = (ET6000GetSetPCI *)buf;
            if (gsp->magic == ET6000_PRIVATE_DATA_MAGIC) {
                pci_info *pcii = &(di->pcii);
                set_pci(gsp->offset, gsp->size, gsp->value);
                result = B_OK;
            }
        } break;

        case ET6000_DEVICE_NAME: {   /* Needed for cloning */
            ET6000DeviceName *dn = (ET6000DeviceName *)buf;
            if(dn->magic == ET6000_PRIVATE_DATA_MAGIC) {
                strncpy(dn->name, di->name, B_OS_NAME_LENGTH);
                result = B_OK;
            }
        } break;

        case ET6000_PROPOSE_DISPLAY_MODE: {
            ET6000DisplayMode *dm = (ET6000DisplayMode *)buf;
            if(dm->magic == ET6000_PRIVATE_DATA_MAGIC) {
                result = et6000ProposeMode(&dm->mode, dm->memSize);
            }
        } break;

        case ET6000_SET_DISPLAY_MODE: {
            ET6000DisplayMode *dm = (ET6000DisplayMode *)buf;
            if(dm->magic == ET6000_PRIVATE_DATA_MAGIC) {
                result = et6000SetMode(&dm->mode, dm->pciConfigSpace);
            }
        } break;
    }
    return result;
}