[SeaBIOS] I2C console16/32 segment problems

Dave Frodin dave.frodin at se-eng.com
Tue Oct 16 16:33:27 CEST 2012


All, 

I've added code to output.c to implement a I2C console interface. 
Everything was working great on my AMD/Persimmon until I added additional code 
to determine what south bridge I was on. I'm evidently not correctly handling 
the 16/32 bit code segments correctly. It's evident when I run the debugger 
and watch the disassembly. Not only is the disassembly wrong but it isn't 
even consistent between runs. 

The new code is below, along with the modified putc_debug(). 

Any suggestions would be appreciated. 

Thanks, 
Dave 


#if MODE16 
#define FIXUP_CODE_SEG_LOCATION VAR16 
#elif MODESEGMENT 
#define FIXUP_CODE_SEG_LOCATION VAR32SEG 
#else 
#define FIXUP_CODE_SEG_LOCATION 
#endif 

struct amd_i2c_list{ 
u16 sb_ven; 
u16 sb_dev; 
u8 sb_ver; 
u8 base_access; 
}; 

/* send a debug character to the i2c port */ 
static void debug_i2c(char data) 
{ 
static int FIXUP_CODE_SEG_LOCATION i2c_amd_iobase = 0; 
static int FIXUP_CODE_SEG_LOCATION i2c_inited = 0; 

static const FIXUP_CODE_SEG_LOCATION struct amd_i2c_list amd_smbus_table[] = { 
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, 0x39, 2 }, /* ATI/AMD SB700 base in pci space */ 
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, 0x42, 1 }, /* ATI/AMD SB800 base in pmreg */ 
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SB900_SM, 0x14, 1 }, /* ATI/AMD SB900 base in pmreg */ 
}; 

volatile u16 rd_vendor, rd_device; 
volatile u8 rd_ver, base_access; 
int i; 
u32 x; 

if (!CONFIG_DEBUG_I2C) 
return; 

/* check to see if we already tried init and it failed */ 
if (i2c_inited && !i2c_amd_iobase) 
return; 

/* check to see if the base address has been initialized */ 
if (!i2c_inited) { 
i2c_inited=1; 
/* check for the AMD/ATI southbridges */ 
rd_vendor = pci_config_readw(0xA0, 0x00); 
rd_device = pci_config_readw(0xA0, 0x02); 
rd_ver = pci_config_readb(0xA0, 0x08); 
base_access=0; 
for (i=0;i < sizeof(amd_smbus_table)/sizeof(amd_smbus_table[0]);++i) { 
if ((amd_smbus_table[i].sb_ven==rd_vendor) 
&& (amd_smbus_table[i].sb_dev==rd_device) 
&& (amd_smbus_table[i].sb_ver==rd_ver)) { 
base_access = amd_smbus_table[i].base_access; 
break; 
} 
} 

switch (base_access) { 
case 1: 
/* check the PM regs for the SM bus base address */ 
outb (0x2D, 0xCD6); 
i2c_amd_iobase = inb(0xCD7)<<8; 
outb (0x2C, 0xCD6); 
i2c_amd_iobase |= inb(0xCD7); 
if ((i2c_amd_iobase!=0) && ((i2c_amd_iobase&0x01)==0x01)) { 
/* Found a SBx00 base address in PM reg space */ 
i2c_amd_iobase &= 0xffe0; 
} 
else { 
/* can not find a valid base address */ 
i2c_amd_iobase = 0; 
} 
break; 
case 2: 
/* check PCI config space for SM bus base address */ 
x = pci_config_readl(0xA0, 0x90); 
if ((x!=0) && ((x&0x01)==0x01)) { 
/* Found a SBx00 base address in PCI cfg space */ 
i2c_amd_iobase = (int)(x & 0xffe0); 
} 
else { 
/* can not find a valid base address */ 
i2c_amd_iobase = 0; 
} 
break; 
default: 
i2c_amd_iobase = 0; 
break; 
} 
/* add checks for other vendors SMBUS controllers here */ 
} 

if (i2c_amd_iobase) { 
/* this sequence will send out addr/data on the AMD SBx00 smbus */ 
int timeout=DEBUG_TIMEOUT; 
/* check to see if the h/w is idle */ 
do { 
if (!timeout--) 
return; // Ran out of time. 
} 
while ((inb(i2c_amd_iobase) & 0x01)!=0x00); 
outb (0xFF, i2c_amd_iobase + 0); // clear error status 
outb (0x1F, i2c_amd_iobase + 1); // clear error status 
outb (data, i2c_amd_iobase + 3); // tx index 
outb (CONFIG_DEBUG_I2C_DEVICE_ADDR, i2c_amd_iobase + 4); // slave address and write bit 
outb (0x44, i2c_amd_iobase + 2); // command it to go 
/* check to see if the h/w is done */ 
do { 
if (!timeout--) 
return; // Ran out of time. 
} 
while ((inb(i2c_amd_iobase) & 0x01)!=0x00); 
} 
} 

// Write a character to debug port(s). 
static void 
putc_debug(struct putcinfo *action, char c) 
{ 
if (! CONFIG_DEBUG_LEVEL) 
return; 
if (CONFIG_DEBUG_IO) 
// Send character to debug port. 
outb(c, GET_GLOBAL(DebugOutputPort)); 
if (CONFIG_DEBUG_I2C) 
debug_i2c(c); 
if (c == '\n') 
debug_serial('\r'); 
debug_serial(c); 
} 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.seabios.org/pipermail/seabios/attachments/20121016/17d97ccd/attachment-0001.html>


More information about the SeaBIOS mailing list