pci.c revision 6767
1/************************************************************************** 2** 3** $Id: pci.c,v 1.16 1995/02/25 17:26:22 se Exp $ 4** 5** General subroutines for the PCI bus on 80*86 systems. 6** pci_configure () 7** 8** 386bsd / FreeBSD 9** 10**------------------------------------------------------------------------- 11** 12** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved. 13** 14** Redistribution and use in source and binary forms, with or without 15** modification, are permitted provided that the following conditions 16** are met: 17** 1. Redistributions of source code must retain the above copyright 18** notice, this list of conditions and the following disclaimer. 19** 2. Redistributions in binary form must reproduce the above copyright 20** notice, this list of conditions and the following disclaimer in the 21** documentation and/or other materials provided with the distribution. 22** 3. The name of the author may not be used to endorse or promote products 23** derived from this software without specific prior written permission. 24** 25** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35** 36*************************************************************************** 37*/ 38 39#define PCI_PATCHLEVEL "pl5 95/02/27" 40 41#include <pci.h> 42#if NPCI > 0 43 44#ifndef __FreeBSD2__ 45#if __FreeBSD__ >= 2 46#define __FreeBSD2__ 47#endif 48#endif 49 50/*======================================================== 51** 52** #includes and declarations 53** 54**======================================================== 55*/ 56 57#include <sys/param.h> 58#include <sys/systm.h> 59#include <sys/malloc.h> 60#include <sys/errno.h> 61#include <sys/kernel.h> 62 63#include <vm/vm.h> 64#include <vm/vm_param.h> 65 66#include <pci/pcivar.h> 67#include <pci/pcireg.h> 68#include <pci/pcibus.h> 69 70#include <machine/pmap.h> 71#ifdef __FreeBSD2__ 72#include <sys/devconf.h> 73 74struct pci_devconf { 75 struct kern_devconf pdc_kdc; 76 struct pci_info pdc_pi; 77}; 78 79static int 80pci_externalize (struct proc *, struct kern_devconf *, void *, size_t); 81 82static int 83pci_internalize (struct proc *, struct kern_devconf *, void *, size_t); 84#else /* __FreeBSD2__ */ 85 86/* 87** Function prototypes missing in system headers 88*/ 89 90extern pmap_t pmap_kernel(void); 91static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize); 92#endif /* __FreeBSD2__ */ 93 94 95/*======================================================== 96** 97** Autoconfiguration of pci devices. 98** 99** This is reverse to the isa configuration. 100** (1) find a pci device. 101** (2) look for a driver. 102** 103**======================================================== 104*/ 105 106/*-------------------------------------------------------- 107** 108** Limit for pci bus numbers. 109** 110**-------------------------------------------------------- 111*/ 112 113#ifndef PCI_MAX_BUS 114#define PCI_MAX_BUS (256) 115#endif 116 117static u_long pci_bus_max = 1; 118 119/*-------------------------------------------------------- 120** 121** The pci devices can be mapped to any address. 122** This is a list of possible starting addresses. 123** It can be prepended by a config option. 124** 125**-------------------------------------------------------- 126*/ 127 128static u_long pci_stable[] = { 129#ifdef PCI_PMEM_START 130 (PCI_PMEM_START), 131#endif 132 0xf1000000, 133 0x53900000, 134 0xc0000000, 135 0x81000000, 136 0x0f000000, 137}; 138 139static vm_offset_t pci_paddr = 0; 140static vm_offset_t pci_pold = 0; 141static vm_offset_t pci_pidx = 0; 142 143 144/*-------------------------------------------------------- 145** 146** The pci ports can be mapped to any address. 147** As default we start at 0x400 148** 149**-------------------------------------------------------- 150*/ 151 152#ifndef PCI_PORT_START 153#define PCI_PORT_START 0xbc00 154#endif 155 156static u_short pci_ioaddr = PCI_PORT_START; 157 158/*-------------------------------------------------------- 159** 160** The pci device interrupt lines should have been 161** assigned by the bios. But if the bios failed to 162** to it, we set it. 163** 164**-------------------------------------------------------- 165*/ 166 167#ifndef PCI_IRQ 168#define PCI_IRQ 0 169#endif 170 171static u_long pci_irq = PCI_IRQ; 172 173/*--------------------------------------------------------- 174** 175** pci_configure () 176** 177** Probe all devices on pci bus and attach them. 178** 179** May be called more than once. 180** Any device is attached only once. 181** (Attached devices are remembered in pci_seen.) 182** Has to take care of mirrored devices, which are 183** entailed by incomplete decoding of pci address lines. 184** 185**--------------------------------------------------------- 186*/ 187 188static void not_supported (pcici_t tag, u_long type); 189 190static unsigned long pci_seen[PCI_MAX_BUS]; 191 192static int pci_conf_count; 193static int pci_info_done; 194 195void pci_configure() 196{ 197 u_char device,max_device; 198 u_short bus; 199 pcici_t tag; 200 pcidi_t type, type8, type16; 201 u_long data; 202 int unit; 203 int pci_mechanism; 204 int pciint; 205 int irq; 206 char* name=0; 207 u_short old_ioaddr=pci_ioaddr; 208 209 int dvi; 210 struct pci_device *dvp=0; 211 212#ifdef __FreeBSD2__ 213 struct pci_devconf *pdcp; 214#endif 215 216 /* 217 ** first check pci bus driver available 218 */ 219 220 if (pcibus_set.ls_length <= 0) 221 return; 222 223#define pcibus (*((struct pcibus*) pcibus_set.ls_items[0])) 224 /* 225 ** check pci bus present 226 */ 227 228 pci_mechanism = pcibus.pb_mode (); 229 if (!pci_mechanism) return; 230 max_device = pci_mechanism==1 ? 32 : 16; 231 232 /* 233 ** hello world .. 234 */ 235 236 pci_pold=pci_paddr; 237 for (bus=0; bus<pci_bus_max; bus++) { 238#ifndef PCI_QUIET 239 printf ("Probing for devices on the %s%d bus:\n", 240 pcibus.pb_name, bus); 241 if (!pci_info_done) { 242 pci_info_done=1; 243 printf ("\tconfiguration mode %d allows %d devices.\n", 244 pci_mechanism, max_device); 245 }; 246#endif 247 for (device=0; device<max_device; device ++) { 248 249 if (pci_seen[bus] & (1ul << device)) 250 continue; 251 252 tag = pcibus.pb_tag (bus, device, 0); 253 type = pcibus.pb_read (tag, PCI_ID_REG); 254 255 if ((!type) || (type==0xfffffffful)) continue; 256 257 /* 258 ** lookup device in ioconfiguration: 259 */ 260 261 for (dvi=0; dvi<pcidevice_set.ls_length; dvi++) { 262 dvp = (struct pci_device*) pcidevice_set.ls_items[dvi]; 263 if ((name=(*dvp->pd_probe)(tag, type))) 264 break; 265 dvp = NULL; 266 }; 267 268 /* 269 ** check for mirrored devices. 270 */ 271 if (device & 0x08) { 272 pcici_t mtag; 273 mtag = pcibus.pb_tag (bus, device & ~0x08, 0); 274 type8 = pcibus.pb_read (mtag, PCI_ID_REG); 275 } else type8 = 0; 276 if (device & 0x10) { 277 pcici_t mtag; 278 mtag = pcibus.pb_tag (bus, device & ~0x10, 0); 279 type16 = pcibus.pb_read (mtag, PCI_ID_REG); 280 } else type16 = 0; 281 if ((type==type8) || (type==type16)) { 282#ifndef PCI_QUIET 283 if (dvp==NULL) continue; 284 printf ("%s? <%s> mirrored on pci%d:%d\n", 285 dvp->pd_name, name, bus, device); 286#endif 287 continue; 288 }; 289 290 if (dvp==NULL) { 291#ifndef PCI_QUIET 292 if (pci_conf_count) 293 continue; 294 printf("%s%d:%d: ", pcibus.pb_name, bus, device); 295 not_supported (tag, type); 296#endif 297 continue; 298 }; 299 300 pci_seen[bus] |= (1ul << device); 301 /* 302 ** Get and increment the unit. 303 */ 304 305 unit = (*dvp->pd_count)++; 306 307 /* 308 ** ignore device ? 309 */ 310 311 if (!*name) continue; 312 313 /* 314 ** Announce this device 315 */ 316 317 printf ("%s%d <%s>", dvp->pd_name, unit, name); 318 319 /* 320 ** Get the int pin number (pci interrupt number a-d) 321 ** from the pci configuration space. 322 */ 323 324 data = pcibus.pb_read (tag, PCI_INTERRUPT_REG); 325 pciint = PCI_INTERRUPT_PIN_EXTRACT(data); 326 327 if (pciint) { 328 329 printf (" int %c", 0x60+pciint); 330 331 /* 332 ** If the interrupt line register is not set, 333 ** set it now from PCI_IRQ. 334 */ 335 336 if (!(PCI_INTERRUPT_LINE_EXTRACT(data))) { 337 338 irq = pci_irq & 0x0f; 339 pci_irq >>= 4; 340 341 data = PCI_INTERRUPT_LINE_INSERT(data, irq); 342 printf (" (config)"); 343 pcibus.pb_write (tag, PCI_INTERRUPT_REG, data); 344 }; 345 346 irq = PCI_INTERRUPT_LINE_EXTRACT(data); 347 348 /* 349 ** If it's zero, the isa irq number is unknown, 350 ** and we cannot bind the pci interrupt to isa. 351 */ 352 353 if (irq) 354 printf (" irq %d", irq); 355 else 356 printf (" not bound"); 357 }; 358 359 /* 360 ** enable memory access 361 */ 362 363 data = (pcibus.pb_read (tag, PCI_COMMAND_STATUS_REG) 364 & 0xffff) | PCI_COMMAND_MEM_ENABLE; 365 366 pcibus.pb_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); 367 368 /* 369 ** show pci slot. 370 */ 371 372 printf (" on pci%d:%d\n", bus, device); 373 374#ifdef __FreeBSD2__ 375 376 /* 377 ** Allocate a devconf structure 378 */ 379 380 pdcp = (struct pci_devconf *) 381 malloc (sizeof (struct pci_devconf),M_DEVBUF,M_WAITOK); 382 383 /* 384 ** Fill in. 385 ** 386 ** Sorry, this is not yet complete. 387 ** We should, and eventually will, set the 388 ** parent pointer to a pci bus devconf structure, 389 ** and arrange to set the state field dynamically. 390 ** 391 ** But I'll go to vacation today, and after all, 392 ** wasn't there a new feature freeze on Oct 1.? 393 */ 394 395 pdcp -> pdc_pi.pi_bus = bus; 396 pdcp -> pdc_pi.pi_device = device; 397 398 pdcp -> pdc_kdc.kdc_name = dvp->pd_name; 399 pdcp -> pdc_kdc.kdc_unit = unit; 400 401 pdcp -> pdc_kdc.kdc_md.mddc_devtype = MDDT_PCI; 402 403 pdcp -> pdc_kdc.kdc_externalize = pci_externalize; 404 pdcp -> pdc_kdc.kdc_internalize = pci_internalize; 405 406 pdcp -> pdc_kdc.kdc_datalen = PCI_EXTERNAL_LEN; 407 pdcp -> pdc_kdc.kdc_parentdata = &pdcp->pdc_pi; 408 pdcp -> pdc_kdc.kdc_state = DC_UNKNOWN; 409 pdcp -> pdc_kdc.kdc_description = name; 410 411 /* 412 ** And register this device 413 */ 414 415 dev_attach (&pdcp->pdc_kdc); 416 417#endif /* __FreeBSD2__ */ 418 419 420 /* 421 ** attach device 422 ** may produce additional log messages, 423 ** i.e. when installing subdevices. 424 */ 425 426 (*dvp->pd_attach) (tag, unit); 427 }; 428 }; 429 430#ifndef PCI_QUIET 431 if (pci_paddr != pci_pold) 432 printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", 433 (u_long)pci_pold, (u_long)pci_paddr); 434 if (pci_ioaddr != old_ioaddr) 435 printf ("pci devices use ioports from 0x%x to 0x%x\n", 436 (unsigned)PCI_PORT_START, (unsigned)pci_ioaddr); 437#endif 438 pci_conf_count++; 439} 440 441/*----------------------------------------------------------------- 442** 443** The following functions are provided for the device driver 444** to read/write the configuration space. 445** 446** pci_conf_read(): 447** Read a long word from the pci configuration space. 448** Requires a tag (from pcitag) and the register 449** number (should be a long word alligned one). 450** 451** pci_conf_write(): 452** Writes a long word to the pci configuration space. 453** Requires a tag (from pcitag), the register number 454** (should be a long word alligned one), and a value. 455** 456**----------------------------------------------------------------- 457*/ 458 459u_long 460pci_conf_read (pcici_t tag, u_long reg) 461{ 462 return (pcibus.pb_read (tag, reg)); 463} 464 465void 466pci_conf_write (pcici_t tag, u_long reg, u_long data) 467{ 468 pcibus.pb_write (tag, reg, data); 469} 470 471/*----------------------------------------------------------------------- 472** 473** Map device into port space. 474** 475** PCI-Specification: 6.2.5.1: address maps 476** 477**----------------------------------------------------------------------- 478*/ 479 480int pci_map_port (pcici_t tag, u_long reg, u_short* pa) 481{ 482 u_long data,oldmap; 483 u_short size, ioaddr; 484 485 /* 486 ** sanity check 487 */ 488 489 if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) { 490 printf ("pci_map_port failed: bad register=0x%x\n", 491 (unsigned)reg); 492 return (0); 493 }; 494 495 /* 496 ** get size and type of port 497 ** 498 ** type is in the lowest two bits. 499 ** If device requires 2^n bytes, the next 500 ** n-2 bits are hardwired as 0. 501 */ 502 503#ifdef PCI_REMAP 504 oldmap = 0; 505#else 506 oldmap = pcibus.pb_read (tag, reg) & 0xfffffffc; 507 if (oldmap==0xfffffffc) oldmap=0; 508#endif 509 pcibus.pb_write (tag, reg, 0xfffffffful); 510 data = pcibus.pb_read (tag, reg); 511 512 switch (data & 0x03) { 513 514 case PCI_MAP_IO: 515 break; 516 517 default: /* unknown */ 518 printf ("pci_map_port failed: bad port type=0x%x\n", 519 (unsigned) data); 520 return (0); 521 }; 522 523 /* 524 ** get the size 525 */ 526 527 size = -(data & PCI_MAP_IO_ADDRESS_MASK); 528 529 if (!size) return (0); 530 531 /* 532 ** align physical address to virtual size, 533 ** set ioaddr, 534 ** and don't forget to increment pci_ioaddr 535 */ 536 537 if (oldmap) { 538 ioaddr = oldmap; 539 } else { 540 if ((data = pci_ioaddr % size)) 541 pci_ioaddr += size - data; 542 ioaddr = pci_ioaddr; 543 pci_ioaddr += size; 544 }; 545 546#ifndef PCI_QUIET 547 /* 548 ** display values. 549 */ 550 551 printf ("\treg%d: ioaddr=0x%x size=0x%x\n", 552 (unsigned) reg, (unsigned) ioaddr, (unsigned) size); 553#endif 554 555 /* 556 ** set device address 557 */ 558 559 pcibus.pb_write (tag, reg, (u_long) ioaddr); 560 561 /* 562 ** return them to the driver 563 */ 564 565 *pa = pci_ioaddr; 566 567 return (1); 568} 569 570/*----------------------------------------------------------------------- 571** 572** Map device into virtual and physical space 573** 574** PCI-Specification: 6.2.5.1: address maps 575** 576**----------------------------------------------------------------------- 577*/ 578 579int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) 580{ 581 u_long data,oldmap,paddr; 582 vm_size_t vsize; 583 vm_offset_t vaddr; 584 int i; 585 586 /* 587 ** sanity check 588 */ 589 590 if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) { 591 printf ("pci_map_mem failed: bad register=0x%x\n", 592 (unsigned)reg); 593 return (0); 594 }; 595 596 /* 597 ** save old mapping, get size and type of memory 598 ** 599 ** type is in the lowest four bits. 600 ** If device requires 2^n bytes, the next 601 ** n-4 bits are read as 0. 602 */ 603 604#ifdef PCI_REMAP 605 oldmap = 0; 606#else 607 oldmap = pcibus.pb_read (tag, reg) & 0xfffffff0; 608 if (oldmap==0xfffffff0) oldmap = 0; 609#endif 610 pcibus.pb_write (tag, reg, 0xfffffffful); 611 data = pcibus.pb_read (tag, reg); 612 613 switch (data & 0x0f) { 614 615 case PCI_MAP_MEMORY_TYPE_32BIT: /* 32 bit non cachable */ 616 break; 617 618 default: /* unknown */ 619 printf ("pci_map_mem failed: bad memory type=0x%x\n", 620 (unsigned) data); 621 return (0); 622 }; 623 624 /* 625 ** mask out the type, 626 ** and round up to a page size 627 */ 628 629 vsize = round_page (-(data & PCI_MAP_MEMORY_ADDRESS_MASK)); 630 631 if (!vsize) return (0); 632 633 if (oldmap) { 634 paddr = oldmap; 635 goto domap; 636 }; 637 638next_try: 639 if (!pci_paddr) { 640 /* 641 ** Get a starting address. 642 */ 643 if (pci_pidx >= sizeof(pci_stable)/sizeof(u_long)) { 644 printf ("pci_map_mem: out of start addresses.\n"); 645 return (0); 646 }; 647 648 pci_paddr = pci_stable[pci_pidx++]; 649 pci_pold = 0; 650 651 if (pci_pidx>1) 652 printf ("\t(retry at 0x%x)\n", 653 (unsigned) pci_paddr); 654 }; 655 /* 656 ** align physical address to virtual size 657 */ 658 659 if ((data = pci_paddr % vsize)) 660 pci_paddr += vsize - data; 661 662 if (!pci_pold) 663 pci_pold = pci_paddr; 664 665 /* 666 ** set physical mapping address, 667 ** and reserve physical address range 668 */ 669 670 paddr = pci_paddr; 671 pci_paddr += vsize; 672 673domap: 674 vaddr = (vm_offset_t) pmap_mapdev (paddr, vsize); 675 676 if (!vaddr) return (0); 677 678#ifndef PCI_QUIET 679 /* 680 ** display values. 681 */ 682 683 printf ("\treg%d: virtual=0x%lx physical=0x%lx\n", 684 (unsigned) reg, (u_long)vaddr, (u_long)paddr); 685#endif 686 687 /* 688 ** probe for already mapped device. 689 */ 690 691 if (!oldmap) for (i=0; i<vsize; i+=4) { 692 u_long* addr = (u_long*) (vaddr+i); 693 data = *addr; 694 if (data != 0xffffffff) { 695 printf ("\t(possible address conflict: " 696 "at 0x%x read: 0x%x)\n", 697 (unsigned) paddr+i, (unsigned) data); 698 pci_paddr = 0; 699 goto next_try; 700 }; 701 }; 702 703 /* 704 ** Set device address 705 */ 706 707 pcibus.pb_write (tag, reg, paddr); 708 709 /* 710 ** Check if correctly mapped. 711 ** 712 ** W A R N I N G 713 ** 714 ** This code assumes that the device will NOT return 715 ** only ones (0xffffffff) from all offsets. 716 */ 717 718 for (i=0; i<vsize; i+=4) { 719 u_long* addr = (u_long*) (vaddr+i); 720 data = *addr; 721 if (data != 0xffffffff) 722 break; 723 }; 724 725 if ((data==0xffffffff) && !oldmap) { 726 printf ("\t(possible mapping problem: " 727 "at 0x%x read 0xffffffff)\n", 728 (unsigned) paddr); 729 pci_paddr = 0; 730 goto next_try; 731 }; 732 733 /* 734 ** Return addresses to the driver 735 */ 736 737 *va = vaddr; 738 *pa = paddr; 739 740 return (1); 741} 742 743/*----------------------------------------------------------------------- 744** 745** Map new pci bus. (XXX under construction) 746** 747** PCI-Specification: ____________? 748** 749**----------------------------------------------------------------------- 750*/ 751 752int pci_map_bus (pcici_t tag, u_long bus) 753{ 754 if (bus >= PCI_MAX_BUS) { 755 printf ("pci_map_bus failed: bus number %d too big.\n", 756 (int) bus); 757 return (0); 758 }; 759 760 if (bus >= pci_bus_max) 761 pci_bus_max = bus + 1; 762 763#ifndef PCI_QUIET 764 /* 765 ** display values. 766 */ 767 768 printf ("\tmapped pci bus %d.\n", 769 (int) bus); 770#endif 771 772 return (1); 773} 774 775/*------------------------------------------------------------ 776** 777** Interface functions for the devconf module. 778** 779**------------------------------------------------------------ 780*/ 781 782static int 783pci_externalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t l) 784{ 785 struct pci_externalize_buffer buffer; 786 struct pci_info * pip = kdcp->kdc_parentdata; 787 pcici_t tag; 788 int i; 789 790 if (l < sizeof buffer) { 791 return ENOMEM; 792 }; 793 794 tag = pcibus.pb_tag (pip->pi_bus, pip->pi_device, 0); 795 796 buffer.peb_pci_info = *pip; 797 798 for (i=0; i<PCI_EXT_CONF_LEN; i++) { 799 buffer.peb_config[i] = pcibus.pb_read (tag, i*4); 800 }; 801 802 return copyout(&buffer, u, sizeof buffer); 803} 804 805 806static int 807pci_internalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t s) 808{ 809 return EOPNOTSUPP; 810} 811 812/*----------------------------------------------------------------------- 813** 814** Map pci interrupts to isa interrupts. 815** 816**----------------------------------------------------------------------- 817*/ 818 819int pci_map_int (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr) 820{ 821 int irq, result; 822 823 irq = PCI_INTERRUPT_LINE_EXTRACT( 824 pcibus.pb_read (tag, PCI_INTERRUPT_REG)); 825 826 if (irq >= 16 || irq <= 0) { 827 printf ("pci_map_int failed: no int line set.\n"); 828 return (0); 829 } 830 831 result = pcibus.pb_regint (tag, func, arg, maskptr); 832 833 if (!result) { 834 printf ("pci_map_int failed.\n"); 835 return (0); 836 }; 837 838 return (1); 839} 840 841/*----------------------------------------------------------- 842** 843** Display of unknown devices. 844** 845**----------------------------------------------------------- 846*/ 847struct vt { 848 u_short ident; 849 char* name; 850}; 851 852static struct vt VendorTable[] = { 853 {0x1002, "ATI TECHNOLOGIES INC"}, 854 {0x1011, "DIGITAL EQUIPMENT CORPORATION"}, 855 {0x101A, "NCR"}, 856 {0x102B, "MATROX"}, 857 {0x1045, "OPTI"}, 858 {0x5333, "S3 INC."}, 859 {0x8086, "INTEL CORPORATION"}, 860 {0,0} 861}; 862 863static const char *const majclasses[] = { 864 "old", "storage", "network", "display", 865 "multimedia", "memory", "bridge" 866}; 867 868void not_supported (pcici_t tag, u_long type) 869{ 870 u_char reg; 871 u_long data; 872 struct vt * vp; 873 874 /* 875 ** lookup the names. 876 */ 877 878 for (vp=VendorTable; vp->ident; vp++) 879 if (vp->ident == (type & 0xffff)) 880 break; 881 882 /* 883 ** and display them. 884 */ 885 886 if (vp->ident) printf (vp->name); 887 else printf ("vendor=0x%lx", type & 0xffff); 888 889 printf (", device=0x%lx", type >> 16); 890 891 data = (pcibus.pb_read(tag, PCI_CLASS_REG) >> 24) & 0xff; 892 if (data < sizeof(majclasses) / sizeof(majclasses[0])) 893 printf(", class=%s", majclasses[data]); 894 895 printf (" [not supported]\n"); 896 897 for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) { 898 data = pcibus.pb_read (tag, reg); 899 if (!data) continue; 900 switch (data&7) { 901 902 case 1: 903 case 5: 904 printf (" map(%x): io(%lx)\n", 905 reg, data & ~3); 906 break; 907 case 0: 908 printf (" map(%x): mem32(%lx)\n", 909 reg, data & ~7); 910 break; 911 case 2: 912 printf (" map(%x): mem20(%lx)\n", 913 reg, data & ~7); 914 break; 915 case 4: 916 printf (" map(%x): mem64(%lx)\n", 917 reg, data & ~7); 918 break; 919 } 920 } 921} 922 923#ifndef __FreeBSD2__ 924/*----------------------------------------------------------- 925** 926** Mapping of physical to virtual memory 927** 928**----------------------------------------------------------- 929*/ 930 931extern vm_map_t kernel_map; 932 933static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) 934{ 935 vm_offset_t vaddr,value; 936 u_long result; 937 938 vaddr = vm_map_min (kernel_map); 939 940 result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, 941 &vaddr, vsize, TRUE); 942 943 if (result != KERN_SUCCESS) { 944 printf (" vm_map_find failed(%d)\n", result); 945 return (0); 946 }; 947 948 /* 949 ** map physical 950 */ 951 952 value = vaddr; 953 while (vsize >= NBPG) { 954 pmap_enter (pmap_kernel(), vaddr, paddr, 955 VM_PROT_READ|VM_PROT_WRITE, TRUE); 956 vaddr += NBPG; 957 paddr += NBPG; 958 vsize -= NBPG; 959 }; 960 return (value); 961} 962 963/*------------------------------------------------------------ 964** 965** Emulate the register_intr() function of FreeBSD 2.0 966** 967** requires a patch: 968** FreeBSD 2.0: "/sys/i386/isa/vector.s" 969** 386bsd0.1: "/sys/i386/isa/icu.s" 970** 386bsd1.0: Please ask Jesus Monroy Jr. 971** 972**------------------------------------------------------------ 973*/ 974 975#include <machine/segments.h> 976 977int pci_int_unit [16]; 978inthand2_t* (pci_int_hdlr [16]); 979unsigned int * pci_int_mptr [16]; 980unsigned int pci_int_count[16]; 981 982extern void 983 Vpci3(), Vpci4(), Vpci5(), Vpci6(), Vpci7(), Vpci8(), Vpci9(), 984 Vpci10(), Vpci11(), Vpci12(), Vpci13(), Vpci14(), Vpci15(); 985 986static inthand_t* pci_int_glue[16] = { 987 0, 0, 0, Vpci3, Vpci4, Vpci5, Vpci6, Vpci7, Vpci8, 988 Vpci9, Vpci10, Vpci11, Vpci12, Vpci13, Vpci14, Vpci15 }; 989 990static int 991register_intr __P((int intr, int device_id, unsigned int flags, 992 inthand2_t *handler, unsigned int* mptr, int unit)) 993{ 994 if (intr >= 16 || intr <= 2) 995 return (EINVAL); 996 if (pci_int_hdlr [intr]) 997 return (EBUSY); 998 999 pci_int_hdlr [intr] = handler; 1000 pci_int_unit [intr] = unit; 1001 pci_int_mptr [intr] = mptr; 1002 1003 setidt(NRSVIDT + intr, pci_int_glue[intr], SDT_SYS386IGT, SEL_KPL); 1004 return (0); 1005} 1006#endif /* __FreeBSD2__ */ 1007#endif /* NPCI */ 1008