#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" // // SMBus support for the PIIX4 // enum { IntelVendID= 0x8086, Piix4PMID= 0x7113, /* PIIX4 power management function */ // SMBus configuration registers (function 3) SMBbase= 0x90, // 4 byte base address (bit 0 == 1, bit 3:1 == 0) SMBconfig= 0xd2, SMBintrselect= (7<<1), SMIenable= (0<<1), // interrupts sent to SMI# IRQ9enable= (4<<1), // intettupts sent to IRQ9 SMBenable= (1<<0), // 1 enables // SMBus IO space registers Hoststatus= 0x0, Failed= (1<<4), // transaction terminated by KILL (reset by writing 1) Bus_error= (1<<3), // transactio collision (reset by writing 1) Dev_error= (1<<2), // device error interrupt (reset by writing 1) Host_complete= (1<<2), // host command completion interrupt (reset by writing 1) Host_busy= (1<<0), // Slavestatus= 0x1, Alert_sts= (1<<5), // someone asserted SMBALERT# (reset by writing 1) Shdw2_sts= (1<<4), // slave accessed shadow 2 port (reset by writing 1) Shdw1_sts= (1<<3), // slave accessed shadow 1 port (reset by writing 1) Slv_sts= (1<<2), // slave accessed shadow 1 port (reset by writing 1) Slv_bsy= (1<<0), Hostcontrol= 0x2, Start= (1<<6), // start execution Cmd_prot= (7<<2), // command protocol mask Quick= (0<<2), // address only Byte= (1<<2), // address + cmd ByteData= (2<<2), // address + cmd + data WordData= (3<<2), // address + cmd + data + data Kill= (1<<1), // abort in progress command Ienable= (1<<0), // enable completion interrupts Hostcommand= 0x3, Hostaddress= 0x4, AddressMask= (0x7f<<1), // target address RW= (1<<0), // 1 == read, 0 == write Hostdata0= 0x5, Hostdata1= 0x6, Blockdata= 0x7, Slavecontrol= 0x8, Alert_en= (1<<3), // enable interrupt on SMBALERT# Shdw2_en= (1<<2), // enable interrupt on external shadow 2 access Shdw1_en= (1<<1), // enable interrupt on external shadow 1 access Slv_en= (1<<0), // enable interrupt on access of host controller slave port Shadowcommand= 0x9, Slaveevent= 0xa, Slavedata= 0xc, }; static int quickcommand(SMBus *s, int addr) { } static int send(SMBus *s, int addr, int data) { } static int recv(SMBus *s, int addr. int *data) { } static int bytewrite(SMBus *s, int addr, int cmd, int data) { } static int byteread(SMBus *s, int addr, int cmd. int *data) { } static int wordwrite(SMBus *s, int addr, int cmd, int data) { } static int wordread(SMBus *s, int addr, int cmd. int *data) { } static SMBus proto = { .quick = quick, .send = send, .recv = recv, .bytewrite = bytewrite, .byteread = byteread, .wordwrite = wordwrite, .wordread = wordread, }; // // return 0 if this is a piix4 with an smbus interface // SMBus* piix4smbus(void) { int pcs; Pcidev *p; static SMBus *s; if(s != nil) return s; p = pcimatch(p, IntelVendID, Piix4PMID)); if(p == nil) return nil; s = smalloc(sizeof(*s)); memmove(s, &proto, sizeof(*s)); s->arg = p; pcicfgw8(p->tbdf, SMBconfig, IRQ9enable|0); // disable the smbus pcicfgw8(p->tbdf, SMBbase, 0x50); // default address pcicfgw8(p->tbdf, SMBconfig, IRQ9enable|SMBenable); // enable the smbus return s; }