github.com/jspc/eggos@v0.5.1-0.20221028160421-556c75c878a5/drivers/pci/pci.go (about) 1 package pci 2 3 import ( 4 "github.com/jspc/eggos/drivers/pic" 5 "github.com/jspc/eggos/kernel/trap" 6 "github.com/jspc/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 }