github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/drivers/pci/pci.go (about)

     1  package pci
     2  
     3  import (
     4  	"github.com/icexin/eggos/drivers/pic"
     5  	"github.com/icexin/eggos/kernel/trap"
     6  	"github.com/icexin/eggos/log"
     7  )
     8  
     9  type Identity struct {
    10  	Vendor uint16
    11  	Device uint16
    12  }
    13  
    14  type Device struct {
    15  	Ident Identity
    16  	Addr  Address
    17  
    18  	Class, SubClass uint8
    19  
    20  	IRQLine uint8
    21  	IRQNO   uint8
    22  }
    23  
    24  var devices []*Device
    25  
    26  func Scan() []*Device {
    27  	var devices []*Device
    28  	for bus := int(0); bus < 256; bus++ {
    29  		for dev := uint8(0); dev < 32; dev++ {
    30  			for f := uint8(0); f < 8; f++ {
    31  				addr := Address{
    32  					Bus:    uint8(bus),
    33  					Device: dev,
    34  					Func:   f,
    35  				}
    36  				vendor := addr.ReadVendorID()
    37  				if vendor == 0xffff {
    38  					continue
    39  				}
    40  				devid := addr.ReadDeviceID()
    41  				class := addr.ReadPCIClass()
    42  				irqline := addr.ReadIRQLine()
    43  				device := &Device{
    44  					Ident: Identity{
    45  						Vendor: vendor,
    46  						Device: devid,
    47  					},
    48  					Addr:     addr,
    49  					Class:    uint8((class >> 8) & 0xff),
    50  					SubClass: uint8(class & 0xff),
    51  					IRQLine:  irqline,
    52  					IRQNO:    pic.IRQ_BASE + irqline,
    53  				}
    54  				devices = append(devices, device)
    55  			}
    56  		}
    57  	}
    58  	return devices
    59  }
    60  
    61  func findDev(idents []Identity) *Device {
    62  	for _, ident := range idents {
    63  		for _, dev := range devices {
    64  			if dev.Ident == ident {
    65  				return dev
    66  			}
    67  		}
    68  	}
    69  	return nil
    70  }
    71  
    72  func Init() {
    73  	devices = Scan()
    74  	for _, driver := range drivers {
    75  		dev := findDev(driver.Idents())
    76  		if dev == nil {
    77  			log.Infof("[pci] no pci device found for %v\n", driver.Name())
    78  			continue
    79  		}
    80  		log.Infof("[pci] found %x:%x for %s, irq:%d\n", dev.Ident.Vendor, dev.Ident.Device, driver.Name(), dev.IRQNO)
    81  		driver.Init(dev)
    82  		pic.EnableIRQ(uint16(dev.IRQLine))
    83  		trap.Register(int(dev.IRQNO), driver.Intr)
    84  	}
    85  }