コード例 #1
0
/*
 * Prepare dev->bars to be used for information. we do this at startup
 * so we can do the whole array at once, dealing with 64-bit BARs correctly.
 */
void
vga_pci_bar_init(struct vga_pci_softc *dev, struct pci_attach_args *pa)
{
	pcireg_t type;
	int addr = PCI_MAPREG_START, i = 0;
	memcpy(&dev->pa, pa, sizeof(dev->pa));

	while (i < VGA_PCI_MAX_BARS) {
		dev->bars[i] = malloc(sizeof((*dev->bars[i])), M_DEVBUF,
		    M_NOWAIT | M_ZERO);
		if (dev->bars[i] == NULL) {
			return;
		}

		dev->bars[i]->addr = addr;

		type = dev->bars[i]->maptype = pci_mapreg_type(pa->pa_pc,
		    pa->pa_tag, addr);
		if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, addr,
		    dev->bars[i]->maptype, &dev->bars[i]->base,
		    &dev->bars[i]->maxsize, &dev->bars[i]->flags) != 0) {
			free(dev->bars[i], M_DEVBUF);
			dev->bars[i] = NULL;
		}

		if (type == PCI_MAPREG_MEM_TYPE_64BIT) {
			addr += 8;
			i += 2;
		} else {
			addr += 4;
			i++;
		}
	}
}
コード例 #2
0
/*
 * Init memory and i/o bus space tags.  Map device registers.
 * Use memory space mapped i/o space access for i/o registers
 * for CyberPro cards.
 */
static int
igsfb_pci_map_regs(struct igsfb_devconfig *dc,
		   bus_space_tag_t iot, bus_space_tag_t memt,
		   pci_chipset_tag_t pc, pcitag_t tag,
		   pci_product_id_t id)
{

	dc->dc_id = id;

	/*
	 * Configure memory space first since for CyberPro we use
	 * memory-mapped i/o access.  Note that we are NOT mapping any
	 * of it yet.  (XXX: search for memory BAR?)
	 */
#define IGS_MEM_MAPREG (PCI_MAPREG_START + 0)

	dc->dc_memt = memt;
	if (pci_mapreg_info(pc, tag,
		IGS_MEM_MAPREG, PCI_MAPREG_TYPE_MEM,
		&dc->dc_memaddr, &dc->dc_memsz, &dc->dc_memflags) != 0)
	{
		printf("unable to configure memory space\n");
		return 1;
	}

	/*
	 * Configure I/O space.  On CyberPro use MMIO.  IGS 168x doesn't
	 * have a BAR for its i/o space, so we have to hardcode it.
	 */
	if (id >= PCI_PRODUCT_INTEGRAPHICS_CYBERPRO2000) {
		dc->dc_iot = dc->dc_memt;
		dc->dc_iobase = dc->dc_memaddr | IGS_MEM_MMIO_SELECT;
		dc->dc_ioflags = dc->dc_memflags;
	} else {
		dc->dc_iot = iot;
		dc->dc_iobase = 0;
		dc->dc_ioflags = 0;
	}

	/*
	 * Map I/O registers.  This is done in bus glue, not in common
	 * code because on e.g. ISA bus we'd need to access registers
	 * to obtain/program linear memory location.
	 */
	if (bus_space_map(dc->dc_iot,
			  dc->dc_iobase + IGS_REG_BASE, IGS_REG_SIZE,
			  dc->dc_ioflags,
			  &dc->dc_ioh) != 0)
	{
		printf("unable to map I/O registers\n");
		return 1;
	}

	return 0;
}
コード例 #3
0
ファイル: mq200_pci.c プロジェクト: MarginC/kame
void
mq200_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct mq200_pci_softc *psc = (void *) self;
	struct mq200_softc *sc = &psc->sc_mq200;
	struct pci_attach_args *pa = aux;
	int res;

	psc->sc_pc = pa->pa_pc;
	psc->sc_pcitag = pa->pa_tag;

	/* check whether it is disabled by firmware */
	if (!(pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) &
	    PCI_COMMAND_MEM_ENABLE)) {
		printf("%s: disabled\n", sc->sc_dev.dv_xname);
		return;
	}

	/* Base Address Register 0: base address of control registers */
	res = pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_MEM,
	    0, &sc->sc_iot, &sc->sc_ioh, NULL, NULL);
	if (res != 0) {
		printf("%s: can't map registers\n", sc->sc_dev.dv_xname);
		return;
	}

	/* Base Address Register 1: base address of frame buffer */
	res = pci_mapreg_info(psc->sc_pc, psc->sc_pcitag, PCI_MAPREG_START+4,
	    PCI_MAPREG_TYPE_MEM, &sc->sc_baseaddr, NULL, NULL);
	if (res != 0) {
		printf("%s: can't map frame buffer\n", sc->sc_dev.dv_xname);
		return;
	}

	mq200_attach(sc);
}
コード例 #4
0
static void
b3_617_attach(device_t parent, device_t self, void *aux)
{
	struct b3_617_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;

	pci_intr_handle_t ih;
	const char *intrstr;
	struct vmebus_attach_args vaa;

	sc->sc_dev = self;
	sc->sc_pc = pc;
	sc->sc_dmat = pa->pa_dmat;

	pci_aprint_devinfo_fancy(pa, "VME bus adapter", "BIT3 PCI-VME 617", 1);

	/*
	 * Map CSR and mapping table spaces.
	 * Don't map VME window; parts are mapped as needed to
	 * save kernel virtual memory space
	 */
	if (pci_mapreg_map(pa, 0x14,
			   PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
			   0, &sc->csrt, &sc->csrh, NULL, NULL) &&
	    pci_mapreg_map(pa, 0x10,
			   PCI_MAPREG_TYPE_IO,
			   0, &sc->csrt, &sc->csrh, NULL, NULL)) {
		aprint_error_dev(self, "can't map CSR space\n");
		return;
	}

	if (pci_mapreg_map(pa, 0x18,
			   PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
			   0, &sc->mapt, &sc->maph, NULL, NULL)) {
		aprint_error_dev(self, "can't map map space\n");
		return;
	}

	if (pci_mapreg_info(pc, pa->pa_tag, 0x1c,
			    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
			    &sc->vmepbase, 0, 0)) {
		aprint_error_dev(self, "can't get VME range\n");
		return;
	}
	sc->sc_vmet = pa->pa_memt; /* XXX needed for VME mappings */

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	/*
	 * Use a low interrupt level (the lowest?).
	 * We will raise before calling a subdevice's handler.
	 */
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, b3_617_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);

	if (b3_617_init(sc))
		return;

	/*
	 * set up all the tags for use by VME devices
	 */
	sc->sc_vct.cookie = self;
	sc->sc_vct.vct_probe = b3_617_vme_probe;
	sc->sc_vct.vct_map = b3_617_map_vme;
	sc->sc_vct.vct_unmap = b3_617_unmap_vme;
	sc->sc_vct.vct_int_map = b3_617_map_vmeint;
	sc->sc_vct.vct_int_establish = b3_617_establish_vmeint;
	sc->sc_vct.vct_int_disestablish = b3_617_disestablish_vmeint;
	sc->sc_vct.vct_dmamap_create = b3_617_dmamap_create;
	sc->sc_vct.vct_dmamap_destroy = b3_617_dmamap_destroy;
	sc->sc_vct.vct_dmamem_alloc = b3_617_dmamem_alloc;
	sc->sc_vct.vct_dmamem_free = b3_617_dmamem_free;

	vaa.va_vct = &(sc->sc_vct);
	vaa.va_bdt = pa->pa_dmat;
	vaa.va_slaveconfig = b3_617_slaveconfig;

	sc->csrwindow.offset = -1;
	sc->dmawindow24.offset = -1;
	sc->dmawindow32.offset = -1;
	config_found(self, &vaa, 0);
}
コード例 #5
0
ファイル: puc.c プロジェクト: ajinkya93/OpenBSD
void
puc_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct puc_pci_softc *psc = (struct puc_pci_softc *)self;
	struct puc_softc *sc = &psc->sc_psc;
	struct pci_attach_args *pa = aux;
	struct puc_attach_args paa;
	pcireg_t subsys;
	int i;

	subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	sc->sc_desc = puc_find_description(PCI_VENDOR(pa->pa_id),
	    PCI_PRODUCT(pa->pa_id), PCI_VENDOR(subsys), PCI_PRODUCT(subsys));

	puc_print_ports(sc->sc_desc);

	for (i = 0; i < PUC_NBARS; i++) {
		pcireg_t type;
		int bar;

		sc->sc_bar_mappings[i].mapped = 0;
		bar = PCI_MAPREG_START + 4 * i;
		if (!pci_mapreg_probe(pa->pa_pc, pa->pa_tag, bar, &type))
			continue;

		sc->sc_bar_mappings[i].mapped = (pci_mapreg_map(pa, bar, type,
		    0, &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
		    &sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s, 0)
		      == 0);
		if (sc->sc_bar_mappings[i].mapped)
			continue;

		/*
		 * If a port on this card is used as serial console,
		 * mapping the associated BAR will fail because the
		 * bus space is already mapped.  In that case, we try
		 * to re-use the already existing mapping.
		 * Unfortunately this means that if a BAR is used to
		 * support multiple ports, only the first port will
		 * work.
		 */
		if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, bar, type,
		    &sc->sc_bar_mappings[i].a, NULL, NULL) == 0 &&
		    pa->pa_iot == comconsiot &&
		    sc->sc_bar_mappings[i].a == comconsaddr) {
			sc->sc_bar_mappings[i].t = comconsiot;
			sc->sc_bar_mappings[i].h = comconsioh;
			sc->sc_bar_mappings[i].s = COM_NPORTS;
			sc->sc_bar_mappings[i].mapped = 1;
			continue;
		}

		printf("%s: couldn't map BAR at offset 0x%lx\n",
		    sc->sc_dev.dv_xname, (long)bar);
	}

	/* Map interrupt. */
	psc->pc = pa->pa_pc;
	if (pci_intr_map(pa, &psc->ih)) {
		printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
		return;
	}

	paa.puc = sc;
	paa.intr_string = &puc_pci_intr_string;
	paa.intr_establish = &puc_pci_intr_establish;

	puc_common_attach(sc, &paa);
}
コード例 #6
0
ファイル: if_ndis_pci.c プロジェクト: yazshel/netbsd-kernel
/*static*/ 
void ndis_attach_pci(device_t parent, device_t self, void *aux)
{
	struct ndis_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
#ifdef NDIS_DBG       
	char devinfo[256];
#endif
	pci_intr_handle_t ih;
	pcireg_t type;
	bus_addr_t	base;
	bus_size_t	size;
	int		flags;
	ndis_resource_list 		*rl  = NULL;
	struct cm_partial_resource_desc	*prd = NULL;
#ifdef NDIS_DBG
	struct pci_conf_state conf_state;
	int revision, i;
#endif
	int bar;
	size_t rllen;
	
	printf("in ndis_attach_pci()\n");

	/* initalize the softc */
	//sc->ndis_hardware_type  = NDIS_PCI;
	sc->ndis_dev		= self;
	sc->ndis_iftype 	= PCIBus;
	sc->ndis_res_pc		= pa->pa_pc;
	sc->ndis_res_pctag	= pa->pa_tag;
	/* TODO: is this correct? All are just pa->pa_dmat? */	
	sc->ndis_mtag		= pa->pa_dmat;
	sc->ndis_ttag		= pa->pa_dmat;
	sc->ndis_parent_tag 	= pa->pa_dmat;
	sc->ndis_res_io		= NULL;
	sc->ndis_res_mem	= NULL;
	sc->ndis_res_altmem	= NULL;
	sc->ndis_block 		= NULL;
	sc->ndis_shlist		= NULL;
	
	ndis_in_isr		= FALSE;
	
	printf("sc->ndis_mtag = %x\n", (unsigned int)sc->ndis_mtag);

	rllen = sizeof(ndis_resource_list) +
	    sizeof(cm_partial_resource_desc) * (MAX_RESOURCES - 1);
	rl = malloc(rllen, M_DEVBUF, M_NOWAIT|M_ZERO);

	if(rl == NULL) {
		sc->error = ENOMEM;
		//printf("error: out of memory\n");
		return;
	}
	
	rl->cprl_version = 5;
	rl->cprl_version = 1;    
	rl->cprl_count = 0;
	prd = rl->cprl_partial_descs;
	
#ifdef NDIS_DBG
        pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof devinfo);
        revision = PCI_REVISION(pa->pa_class);
        printf(": %s (rev. 0x%02x)\n", devinfo, revision);
	
	pci_conf_print(sc->ndis_res_pc, sc->ndis_res_pctag, NULL);

	pci_conf_capture(sc->ndis_res_pc, sc->ndis_res_pctag, &conf_state);
	for(i=0; i<16; i++) {
		printf("conf_state.reg[%d] = %x\n", i, conf_state.reg[i]);
	}
#endif
	
	/* just do the conversion work in attach instead of calling ndis_convert_res() */
	for(bar = 0x10; bar <= 0x24; bar += 0x04) {
		type = pci_mapreg_type(sc->ndis_res_pc, sc->ndis_res_pctag, bar);
		if(pci_mapreg_info(sc->ndis_res_pc, sc->ndis_res_pctag, bar, type, &base,
			&size, &flags)) {
			printf("pci_mapreg_info() failed on BAR 0x%x!\n", bar);
		} else {			
			switch(type) {
			case PCI_MAPREG_TYPE_IO:
				prd->cprd_type 				= CmResourceTypePort;
				prd->cprd_flags 			= CM_RESOURCE_PORT_IO;
				prd->u.cprd_port.cprd_start.np_quad 	= (uint64_t)base;
				prd->u.cprd_port.cprd_len  	  	= (uint32_t)size;
				if((sc->ndis_res_io = 
					malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
					//printf("error: out of memory\n");
					sc->error = ENOMEM;
					goto out;
				}
				sc->ndis_res_io->res_base = base;
				sc->ndis_res_io->res_size = size;
				sc->ndis_res_io->res_tag  = x86_bus_space_io;
				bus_space_map(sc->ndis_res_io->res_tag,
					 sc->ndis_res_io->res_base,
					 sc->ndis_res_io->res_size,
					 flags,
					&sc->ndis_res_io->res_handle);
				break;
			case PCI_MAPREG_TYPE_MEM:
				prd->cprd_type 				= CmResourceTypeMemory;
				prd->cprd_flags 			= CM_RESOURCE_MEMORY_READ_WRITE;
				prd->u.cprd_mem.cprd_start.np_quad 	= (uint64_t)base;
				prd->u.cprd_mem.cprd_len		= (uint32_t)size;
				
				if(sc->ndis_res_mem != NULL && 
					sc->ndis_res_altmem != NULL) {
					printf("too many resources\n");
					sc->error = ENXIO;
					goto out;
				}
				if(sc->ndis_res_mem) {
					if((sc->ndis_res_altmem = 
						malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
						sc->error = ENOMEM;
						return;
					}
					sc->ndis_res_altmem->res_base = base;
					sc->ndis_res_altmem->res_size = size;
					sc->ndis_res_altmem->res_tag  = x86_bus_space_mem;
					
					
					if(bus_space_map(sc->ndis_res_altmem->res_tag,
						sc->ndis_res_altmem->res_base,
						sc->ndis_res_altmem->res_size,
						flags|BUS_SPACE_MAP_LINEAR,
						&sc->ndis_res_altmem->res_handle)) {
							printf("bus_space_map failed\n");
					}
				} else {
					if((sc->ndis_res_mem = 
						malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
						sc->error = ENOMEM;
						goto out;
					}
					sc->ndis_res_mem->res_base = base;
					sc->ndis_res_mem->res_size = size;
					sc->ndis_res_mem->res_tag  = x86_bus_space_mem;
					
					if(bus_space_map(sc->ndis_res_mem->res_tag,
						sc->ndis_res_mem->res_base,
						sc->ndis_res_mem->res_size,
						flags|BUS_SPACE_MAP_LINEAR,
						&sc->ndis_res_mem->res_handle)) {
							printf("bus_space_map failed\n");
					}
				}
				break;
											   
			default:
				printf("unknown type\n");
			}
			prd->cprd_sharedisp = CmResourceShareDeviceExclusive;

			rl->cprl_count++;								
			prd++;
		}
	}
	
	/* add the interrupt to the list */
	prd->cprd_type 	= CmResourceTypeInterrupt;
	prd->cprd_flags = 0;
	/* TODO: is this all we need to save for the interrupt? */
	prd->u.cprd_intr.cprd_level = pa->pa_intrline;
	prd->u.cprd_intr.cprd_vector = pa->pa_intrline;
	prd->u.cprd_intr.cprd_affinity = 0;
	rl->cprl_count++;
	
	pci_intr_map(pa, &ih);
	sc->ndis_intrhand = pci_intr_establish(pa->pa_pc, ih, IPL_NET /*| PCATCH*/, ndis_intr, sc);
	sc->ndis_irq = (void *)sc->ndis_intrhand;
	
	printf("pci interrupt: %s\n", pci_intr_string(pa->pa_pc, ih));
	
	/* save resource list in the softc */
	sc->ndis_rl = rl;
	sc->ndis_rescnt = rl->cprl_count;
	
	kthread_create(PRI_NONE, 0, NULL, ndis_attach, (void *)sc,
	    NULL, "ndis_attach");
	return;
out:
	free(rl, M_DEVBUF); 
	return;
}
コード例 #7
0
ファイル: pci.c プロジェクト: yazshel/netbsd-kernel
int
pci_probe_device(struct pci_softc *sc, pcitag_t tag,
    int (*match)(const struct pci_attach_args *),
    struct pci_attach_args *pap)
{
	pci_chipset_tag_t pc = sc->sc_pc;
	struct pci_attach_args pa;
	pcireg_t id, /* csr, */ pciclass, intr, bhlcr, bar, endbar;
#ifdef __HAVE_PCI_MSI_MSIX
	pcireg_t cap;
	int off;
#endif
	int ret, pin, bus, device, function, i, width;
	int locs[PCICF_NLOCS];

	pci_decompose_tag(pc, tag, &bus, &device, &function);

	/* a driver already attached? */
	if (sc->PCI_SC_DEVICESC(device, function).c_dev != NULL && !match)
		return 0;

	bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
	if (PCI_HDRTYPE_TYPE(bhlcr) > 2)
		return 0;

	id = pci_conf_read(pc, tag, PCI_ID_REG);
	/* csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); */
	pciclass = pci_conf_read(pc, tag, PCI_CLASS_REG);

	/* Invalid vendor ID value? */
	if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
		return 0;
	/* XXX Not invalid, but we've done this ~forever. */
	if (PCI_VENDOR(id) == 0)
		return 0;

	/* Collect memory range info */
	memset(sc->PCI_SC_DEVICESC(device, function).c_range, 0,
	    sizeof(sc->PCI_SC_DEVICESC(device, function).c_range));
	i = 0;
	switch (PCI_HDRTYPE_TYPE(bhlcr)) {
	case PCI_HDRTYPE_PPB:
		endbar = PCI_MAPREG_PPB_END;
		break;
	case PCI_HDRTYPE_PCB:
		endbar = PCI_MAPREG_PCB_END;
		break;
	default:
		endbar = PCI_MAPREG_END;
		break;
	}
	for (bar = PCI_MAPREG_START; bar < endbar; bar += width) {
		struct pci_range *r;
		pcireg_t type;

		width = 4;
		if (pci_mapreg_probe(pc, tag, bar, &type) == 0)
			continue;

		if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_MEM) {
			if (PCI_MAPREG_MEM_TYPE(type) ==
			    PCI_MAPREG_MEM_TYPE_64BIT)
				width = 8;

			r = &sc->PCI_SC_DEVICESC(device, function).c_range[i++];
			if (pci_mapreg_info(pc, tag, bar, type,
			    &r->r_offset, &r->r_size, &r->r_flags) != 0)
				break;
			if ((PCI_VENDOR(id) == PCI_VENDOR_ATI) && (bar == 0x10)
			    && (r->r_size == 0x1000000)) {
				struct pci_range *nr;
				/*
				 * this has to be a mach64
				 * split things up so each half-aperture can
				 * be mapped PREFETCHABLE except the last page
				 * which may contain registers
				 */
				r->r_size = 0x7ff000;
				r->r_flags = BUS_SPACE_MAP_LINEAR |
					     BUS_SPACE_MAP_PREFETCHABLE;
				nr = &sc->PCI_SC_DEVICESC(device,
				    function).c_range[i++];
				nr->r_offset = r->r_offset + 0x800000;
				nr->r_size = 0x7ff000;
				nr->r_flags = BUS_SPACE_MAP_LINEAR |
					      BUS_SPACE_MAP_PREFETCHABLE;
			}
			
		}
	}

	pa.pa_iot = sc->sc_iot;
	pa.pa_memt = sc->sc_memt;
	pa.pa_dmat = sc->sc_dmat;
	pa.pa_dmat64 = sc->sc_dmat64;
	pa.pa_pc = pc;
	pa.pa_bus = bus;
	pa.pa_device = device;
	pa.pa_function = function;
	pa.pa_tag = tag;
	pa.pa_id = id;
	pa.pa_class = pciclass;

	/*
	 * Set up memory, I/O enable, and PCI command flags
	 * as appropriate.
	 */
	pa.pa_flags = sc->sc_flags;

	/*
	 * If the cache line size is not configured, then
	 * clear the MRL/MRM/MWI command-ok flags.
	 */
	if (PCI_CACHELINE(bhlcr) == 0) {
		pa.pa_flags &= ~(PCI_FLAGS_MRL_OKAY|
		    PCI_FLAGS_MRM_OKAY|PCI_FLAGS_MWI_OKAY);
	}

	if (sc->sc_bridgetag == NULL) {
		pa.pa_intrswiz = 0;
		pa.pa_intrtag = tag;
	} else {
		pa.pa_intrswiz = sc->sc_intrswiz + device;
		pa.pa_intrtag = sc->sc_intrtag;
	}

	intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);

	pin = PCI_INTERRUPT_PIN(intr);
	pa.pa_rawintrpin = pin;
	if (pin == PCI_INTERRUPT_PIN_NONE) {
		/* no interrupt */
		pa.pa_intrpin = 0;
	} else {
		/*
		 * swizzle it based on the number of busses we're
		 * behind and our device number.
		 */
		pa.pa_intrpin = 	/* XXX */
		    ((pin + pa.pa_intrswiz - 1) % 4) + 1;
	}
	pa.pa_intrline = PCI_INTERRUPT_LINE(intr);

#ifdef __HAVE_PCI_MSI_MSIX
	if (pci_get_ht_capability(pc, tag, PCI_HT_CAP_MSIMAP, &off, &cap)) {
		/*
		 * XXX Should we enable MSI mapping ourselves on
		 * systems that have it disabled?
		 */
		if (cap & PCI_HT_MSI_ENABLED) {
			uint64_t addr;
			if ((cap & PCI_HT_MSI_FIXED) == 0) {
				addr = pci_conf_read(pc, tag,
				    off + PCI_HT_MSI_ADDR_LO);
				addr |= (uint64_t)pci_conf_read(pc, tag,
				    off + PCI_HT_MSI_ADDR_HI) << 32;
			} else
				addr = PCI_HT_MSI_FIXED_ADDR;

			/*
			 * XXX This will fail to enable MSI on systems
			 * that don't use the canonical address.
			 */
			if (addr == PCI_HT_MSI_FIXED_ADDR) {
				pa.pa_flags |= PCI_FLAGS_MSI_OKAY;
				pa.pa_flags |= PCI_FLAGS_MSIX_OKAY;
			}
		}
	}
#endif

	if (match != NULL) {
		ret = (*match)(&pa);
		if (ret != 0 && pap != NULL)
			*pap = pa;
	} else {
		struct pci_child *c;
		locs[PCICF_DEV] = device;
		locs[PCICF_FUNCTION] = function;

		c = &sc->PCI_SC_DEVICESC(device, function);
		pci_conf_capture(pc, tag, &c->c_conf);
		if (pci_get_powerstate(pc, tag, &c->c_powerstate) == 0)
			c->c_psok = true;
		else
			c->c_psok = false;

		c->c_dev = config_found_sm_loc(sc->sc_dev, "pci", locs, &pa,
					     pciprint, config_stdsubmatch);

		ret = (c->c_dev != NULL);
	}

	return ret;
}
コード例 #8
0
ファイル: sbbc.c プロジェクト: ajinkya93/OpenBSD
void
sbbc_attach(struct device *parent, struct device *self, void *aux)
{
	struct sbbc_softc *sc = (void *)self;
	struct pci_attach_args *pa = aux;
	struct sbbc_sram_toc *toc;
	bus_addr_t base;
	bus_size_t size;
	pci_intr_handle_t ih;
	int chosen, iosram;
	int i;

	/* XXX Don't byteswap. */
	sc->sc_bbt = *pa->pa_memt;
	sc->sc_bbt.sasi = ASI_PRIMARY;
	sc->sc_iot = &sc->sc_bbt;

	if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, SBBC_PCI_BAR,
	    PCI_MAPREG_TYPE_MEM, &base, &size, NULL)) {
		printf(": can't find register space\n");
		return;
	}

	if (bus_space_map(sc->sc_iot, base + SBBC_REGS_OFFSET,
	    SBBC_REGS_SIZE, 0, &sc->sc_regs_ioh)) {
		printf(": can't map register space\n");
		return;
	}

	if (bus_space_map(sc->sc_iot, base + SBBC_EPLD_OFFSET,
	    SBBC_EPLD_SIZE, 0, &sc->sc_epld_ioh)) {
		printf(": can't map EPLD registers\n");
		goto unmap_regs;
	}

	if (bus_space_map(sc->sc_iot, base + SBBC_SRAM_OFFSET,
	    SBBC_SRAM_SIZE, 0, &sc->sc_sram_ioh)) {
		printf(": can't map SRAM\n");
		goto unmap_epld;
	}

	if (pci_intr_map(pa, &ih)) {
		printf(": unable to map interrupt\n");
		goto unmap_sram;
	}
	printf(": %s\n", pci_intr_string(pa->pa_pc, ih));

	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY,
	    sbbc_intr, sc, sc->sc_dv.dv_xname);
	if (sc->sc_ih == NULL) {
		printf("%s: unable to establish interrupt\n", sc->sc_dv.dv_xname);
		goto unmap_sram;
	}

	bus_space_write_4(sc->sc_iot, sc->sc_regs_ioh,
	    SBBC_PCI_INT_ENABLE, SBBC_PCI_ENABLE_INT_A);

	/* Check if we are the chosen one. */
	chosen = OF_finddevice("/chosen");
	if (OF_getprop(chosen, "iosram", &iosram, sizeof(iosram)) <= 0 ||
	    PCITAG_NODE(pa->pa_tag) != iosram)
		return;

	/* SRAM TOC offset defaults to 0. */
	if (OF_getprop(chosen, "iosram-toc", &sc->sc_sram_toc,
	    sizeof(sc->sc_sram_toc)) <= 0)
		sc->sc_sram_toc = 0;

	sc->sc_sram = bus_space_vaddr(sc->sc_iot, sc->sc_sram_ioh);
	toc = (struct sbbc_sram_toc *)(sc->sc_sram + sc->sc_sram_toc);

	for (i = 0; i < toc->toc_ntags; i++) {
		if (strcmp(toc->toc_tag[i].tag_key, "SOLSCIE") == 0)
			sc->sc_sram_solscie = (uint32_t *)
			    (sc->sc_sram + toc->toc_tag[i].tag_offset);
		if (strcmp(toc->toc_tag[i].tag_key, "SOLSCIR") == 0)
			sc->sc_sram_solscir = (uint32_t *)
			    (sc->sc_sram + toc->toc_tag[i].tag_offset);
		if (strcmp(toc->toc_tag[i].tag_key, "SCSOLIE") == 0)
			sc->sc_sram_scsolie = (uint32_t *)
			    (sc->sc_sram + toc->toc_tag[i].tag_offset);
		if (strcmp(toc->toc_tag[i].tag_key, "SCSOLIR") == 0)
			sc->sc_sram_scsolir = (uint32_t *)
			    (sc->sc_sram + toc->toc_tag[i].tag_offset);
	}

	for (i = 0; i < toc->toc_ntags; i++) {
		if (strcmp(toc->toc_tag[i].tag_key, "TODDATA") == 0)
			sbbc_attach_tod(sc, toc->toc_tag[i].tag_offset);
		if (strcmp(toc->toc_tag[i].tag_key, "SOLCONS") == 0)
			sbbc_attach_cons(sc, toc->toc_tag[i].tag_offset);
	}

	return;

 unmap_sram:
	bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_SRAM_SIZE);
 unmap_epld:
	bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_EPLD_SIZE);
 unmap_regs:
	bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_REGS_SIZE);
}
コード例 #9
0
/**
 * radeon_driver_load_kms - Main load function for KMS.
 *
 * @dev: drm dev pointer
 * @flags: device flags
 *
 * This is the main load function for KMS (all asics).
 * It calls radeon_device_init() to set up the non-display
 * parts of the chip (asic init, CP, writeback, etc.), and
 * radeon_modeset_init() to set up the display parts
 * (crtcs, encoders, hotplug detect, etc.).
 * Returns 0 on success, error on failure.
 */
void
radeondrm_attach_kms(struct device *parent, struct device *self, void *aux)
{
	struct radeon_device	*rdev = (struct radeon_device *)self;
	struct drm_device	*dev;
	struct pci_attach_args	*pa = aux;
	const struct drm_pcidev *id_entry;
	int			 is_agp;
	pcireg_t		 type;
	uint8_t			 iobar;

#if defined(__sparc64__) || defined(__macppc__)
	extern int fbnode;
#endif

	id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
	    PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist);
	rdev->flags = id_entry->driver_data;
	rdev->pc = pa->pa_pc;
	rdev->pa_tag = pa->pa_tag;
	rdev->iot = pa->pa_iot;
	rdev->memt = pa->pa_memt;
	rdev->dmat = pa->pa_dmat;

#if defined(__sparc64__) || defined(__macppc__)
	if (fbnode == PCITAG_NODE(rdev->pa_tag))
		rdev->console = 1;
#else
	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA &&
	    (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG)
	    & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE))
	    == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) {
		rdev->console = 1;
#if NVGA > 0
		vga_console_attached = 1;
#endif
	}
#endif

#define RADEON_PCI_MEM		0x10
#define RADEON_PCI_IO		0x14
#define RADEON_PCI_MMIO		0x18
#define RADEON_PCI_IO2		0x20

	type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM);
	if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
	    pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM,
	    type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) {
		printf(": can't get frambuffer info\n");
		return;
	}

	if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT)
		iobar = RADEON_PCI_IO;
	else
		iobar = RADEON_PCI_IO2;
	
	if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0,
	    NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) {
		printf(": can't map IO space\n");
		return;
	}

	type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO);
	if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
	    pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL,
	    &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) {
		printf(": can't map mmio space\n");
		return;
	}

	if (pci_intr_map(pa, &rdev->intrh) != 0) {
		printf(": couldn't map interrupt\n");
		return;
	}
	printf(": %s\n", pci_intr_string(pa->pa_pc, rdev->intrh));
#ifdef notyet
	mtx_init(&rdev->swi_lock, IPL_TTY);
#endif

	/* update BUS flag */
	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) {
		rdev->flags |= RADEON_IS_AGP;
	} else if (pci_get_capability(pa->pa_pc, pa->pa_tag,
	    PCI_CAP_PCIEXPRESS, NULL, NULL)) {
		rdev->flags |= RADEON_IS_PCIE;
	} else {
		rdev->flags |= RADEON_IS_PCI;
	}

	DRM_DEBUG("%s card detected\n",
		 ((rdev->flags & RADEON_IS_AGP) ? "AGP" :
		 (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));

	is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
	    NULL, NULL);

	dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp, self);
	rdev->ddev = dev;

	rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY,
	    radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname);
	if (rdev->irqh == NULL) {
		printf("%s: couldn't establish interrupt\n",
		    rdev->dev.dv_xname);
		return;
	}

#ifdef __sparc64__
{
	struct rasops_info *ri;
	int node, console;

	node = PCITAG_NODE(pa->pa_tag);
	console = (fbnode == node);

	fb_setsize(&rdev->sf, 8, 1152, 900, node, 0);

	/*
	 * The firmware sets up the framebuffer such that at starts at
	 * an offset from the start of video memory.
	 */
	rdev->fb_offset =
	    bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET);
	if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset,
	    rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) {
		printf("%s: can't map video memory\n", rdev->dev.dv_xname);
		return;
	}

	ri = &rdev->sf.sf_ro;
	ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh);
	ri->ri_hw = rdev;
	ri->ri_updatecursor = NULL;

	fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console);
	if (console)
		fbwscons_console_init(&rdev->sf, -1);
}
#endif

	rdev->shutdown = true;
	if (rootvp == NULL)
		mountroothook_establish(radeondrm_attachhook, rdev);
	else
		radeondrm_attachhook(rdev);
}
コード例 #10
0
ファイル: radeon_kms.c プロジェクト: ajinkya93/OpenBSD
/**
 * radeon_driver_load_kms - Main load function for KMS.
 *
 * @dev: drm dev pointer
 * @flags: device flags
 *
 * This is the main load function for KMS (all asics).
 * It calls radeon_device_init() to set up the non-display
 * parts of the chip (asic init, CP, writeback, etc.), and
 * radeon_modeset_init() to set up the display parts
 * (crtcs, encoders, hotplug detect, etc.).
 * Returns 0 on success, error on failure.
 */
void
radeondrm_attach_kms(struct device *parent, struct device *self, void *aux)
{
	struct radeon_device	*rdev = (struct radeon_device *)self;
	struct drm_device	*dev;
	struct pci_attach_args	*pa = aux;
	const struct drm_pcidev *id_entry;
	int			 is_agp;
	pcireg_t		 type;
	uint8_t			 iobar;
#if !defined(__sparc64__)
	pcireg_t		 addr, mask;
	int			 s;
#endif

#if defined(__sparc64__) || defined(__macppc__)
	extern int fbnode;
#endif

	id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
	    PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist);
	rdev->flags = id_entry->driver_data;
	rdev->pc = pa->pa_pc;
	rdev->pa_tag = pa->pa_tag;
	rdev->iot = pa->pa_iot;
	rdev->memt = pa->pa_memt;
	rdev->dmat = pa->pa_dmat;

#if defined(__sparc64__) || defined(__macppc__)
	if (fbnode == PCITAG_NODE(rdev->pa_tag))
		rdev->console = 1;
#else
	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA &&
	    (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG)
	    & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE))
	    == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) {
		rdev->console = 1;
#if NVGA > 0
		vga_console_attached = 1;
#endif
	}
#if NEFIFB > 0
	if (efifb_is_console(pa)) {
		rdev->console = 1;
		efifb_cndetach();
	}
#endif
#endif

#define RADEON_PCI_MEM		0x10
#define RADEON_PCI_IO		0x14
#define RADEON_PCI_MMIO		0x18
#define RADEON_PCI_IO2		0x20

	type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM);
	if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
	    pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM,
	    type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) {
		printf(": can't get frambuffer info\n");
		return;
	}

	if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT)
		iobar = RADEON_PCI_IO;
	else
		iobar = RADEON_PCI_IO2;
	
	if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0,
	    NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) {
		printf(": can't map IO space\n");
		return;
	}

	type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO);
	if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
	    pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL,
	    &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) {
		printf(": can't map mmio space\n");
		return;
	}

#if !defined(__sparc64__)
	/*
	 * Make sure we have a base address for the ROM such that we
	 * can map it later.
	 */
	s = splhigh();
	addr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE);
	mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, addr);
	splx(s);

	if (addr == 0 && PCI_ROM_SIZE(mask) != 0 && pa->pa_memex) {
		bus_size_t size, start, end;
		bus_addr_t base;

		size = PCI_ROM_SIZE(mask);
		start = max(PCI_MEM_START, pa->pa_memex->ex_start);
		end = min(PCI_MEM_END, pa->pa_memex->ex_end);
		if (extent_alloc_subregion(pa->pa_memex, start, end, size,
		    size, 0, 0, 0, &base) == 0)
			pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, base);
	}
#endif

#ifdef notyet
	mtx_init(&rdev->swi_lock, IPL_TTY);
#endif

	/* update BUS flag */
	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) {
		rdev->flags |= RADEON_IS_AGP;
	} else if (pci_get_capability(pa->pa_pc, pa->pa_tag,
	    PCI_CAP_PCIEXPRESS, NULL, NULL)) {
		rdev->flags |= RADEON_IS_PCIE;
	} else {
		rdev->flags |= RADEON_IS_PCI;
	}

	DRM_DEBUG("%s card detected\n",
		 ((rdev->flags & RADEON_IS_AGP) ? "AGP" :
		 (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));

	is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
	    NULL, NULL);

	printf("\n");

	kms_driver.num_ioctls = radeon_max_kms_ioctl;

	dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp,
	    rdev->console, self);
	rdev->ddev = dev;
	rdev->pdev = dev->pdev;

	rdev->family = rdev->flags & RADEON_FAMILY_MASK;
	if (!radeon_msi_ok(rdev))
		pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED;

	rdev->msi_enabled = 0;
	if (pci_intr_map_msi(pa, &rdev->intrh) == 0)
		rdev->msi_enabled = 1;
	else if (pci_intr_map(pa, &rdev->intrh) != 0) {
		printf(": couldn't map interrupt\n");
		return;
	}
	printf("%s: %s\n", rdev->dev.dv_xname,
	    pci_intr_string(pa->pa_pc, rdev->intrh));

	rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY,
	    radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname);
	if (rdev->irqh == NULL) {
		printf("%s: couldn't establish interrupt\n",
		    rdev->dev.dv_xname);
		return;
	}

#ifdef __sparc64__
{
	struct rasops_info *ri;
	int node, console;

	node = PCITAG_NODE(pa->pa_tag);
	console = (fbnode == node);

	fb_setsize(&rdev->sf, 8, 1152, 900, node, 0);

	/*
	 * The firmware sets up the framebuffer such that at starts at
	 * an offset from the start of video memory.
	 */
	rdev->fb_offset =
	    bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET);
	if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset,
	    rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) {
		printf("%s: can't map video memory\n", rdev->dev.dv_xname);
		return;
	}

	ri = &rdev->sf.sf_ro;
	ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh);
	ri->ri_hw = rdev;
	ri->ri_updatecursor = NULL;

	fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console);
	if (console)
		fbwscons_console_init(&rdev->sf, -1);
}
#endif

	rdev->shutdown = true;
	config_mountroot(self, radeondrm_attachhook);
}
コード例 #11
0
ファイル: gfxp.c プロジェクト: alenichev/openbsd-kernel
void
gfxp_attach(struct device *parent, struct device *self, void *aux)
{
	struct gfxp_softc *sc = (struct gfxp_softc *)self;
	struct pci_attach_args *pa = aux;
	struct rasops_info *ri;
	int node, console, flags;
	char *model;

	sc->sc_pcitag = pa->pa_tag;

	node = PCITAG_NODE(pa->pa_tag);
	console = gfxp_is_console(node);

	printf("\n");

	model = getpropstring(node, "model");
	printf("%s: %s", self->dv_xname, model);

	if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PM2_PCI_MEM_LE,
	    PCI_MAPREG_TYPE_MEM, &sc->sc_membase_le, &sc->sc_memsize_le, NULL))
		sc->sc_memsize_le = 0;

	if (pci_mapreg_map(pa, PM2_PCI_MEM_BE, PCI_MAPREG_TYPE_MEM,
	    BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh,
	    &sc->sc_membase_be, &sc->sc_memsize_be, 0)) {
		printf("\n%s: can't map video memory\n", self->dv_xname);
		return;
	}

	if (pci_mapreg_map(pa, PM2_PCI_MMIO, PCI_MAPREG_TYPE_MEM, 0,
	    &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmiobase,
	    &sc->sc_mmiosize, 0)) {
		bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_memsize_be);
		printf("\n%s: can't map mmio\n", self->dv_xname);
		return;
	}

	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);

	printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	ri = &sc->sc_sunfb.sf_ro;
	ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
	ri->ri_hw = sc;

	flags = RI_BSWAP;
	if (sc->sc_sunfb.sf_depth == 32) {
		ri->ri_rnum = 8;
		ri->ri_rpos = 16;
		ri->ri_gnum = 8;
		ri->ri_gpos = 8;
		ri->ri_bnum = 8;
		ri->ri_bpos = 0;
		flags &= ~RI_BSWAP;
	}

	fbwscons_init(&sc->sc_sunfb, flags, console);
	fbwscons_setcolormap(&sc->sc_sunfb, gfxp_setcolor);
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;

	gfxp_init(sc);
	ri->ri_ops.copyrows = gfxp_copyrows;
	ri->ri_ops.copycols = gfxp_copycols;
	ri->ri_ops.eraserows = gfxp_eraserows;
	ri->ri_ops.erasecols = gfxp_erasecols;

	if (console)
		fbwscons_console_init(&sc->sc_sunfb, -1);
	fbwscons_attach(&sc->sc_sunfb, &gfxp_accessops, console);
}
コード例 #12
0
int
pci_mapreg_map(struct pci_attach_args *pa, int reg, pcireg_t type, int busflags,
    bus_space_tag_t *tagp, bus_space_handle_t *handlep, bus_addr_t *basep,
    bus_size_t *sizep, bus_size_t maxsize)
{
	bus_space_tag_t tag;
	bus_space_handle_t handle;
	bus_addr_t base;
	bus_size_t size;
	pcireg_t csr;
	int flags;
	int rv;

	if ((rv = pci_mapreg_info(pa->pa_pc, pa->pa_tag, reg, type,
	    &base, &size, &flags)) != 0)
		return (rv);
	if (base == 0)
		return (EINVAL);	/* disabled because of invalid BAR */

	csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_IO)
		csr |= PCI_COMMAND_IO_ENABLE;
	else
		csr |= PCI_COMMAND_MEM_ENABLE;
	/* XXX Should this only be done for devices that do DMA?  */
	csr |= PCI_COMMAND_MASTER_ENABLE;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr);

	if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_IO) {
		if ((pa->pa_flags & PCI_FLAGS_IO_ENABLED) == 0)
			return (EINVAL);
		tag = pa->pa_iot;
	} else {
		if ((pa->pa_flags & PCI_FLAGS_MEM_ENABLED) == 0)
			return (EINVAL);
		tag = pa->pa_memt;
	}

	/* The caller can request limitation of the mapping's size. */
	if (maxsize != 0 && size > maxsize) {
#ifdef DEBUG
		printf("pci_mapreg_map: limited PCI mapping from %lx to %lx\n",
		    (u_long)size, (u_long)maxsize);
#endif
		size = maxsize;
	}

	if (bus_space_map(tag, base, size, busflags | flags, &handle))
		return (1);

	if (tagp != NULL)
		*tagp = tag;
	if (handlep != NULL)
		*handlep = handle;
	if (basep != NULL)
		*basep = base;
	if (sizep != NULL)
		*sizep = size;

	return (0);
}