1 #define HAVE_CONSTANT_PROPOGATION 1
3 void outb(unsigned char value, unsigned short port)
5 __builtin_outb(value, port);
8 void outw(unsigned short value, unsigned short port)
10 __builtin_outw(value, port);
13 void outl(unsigned int value, unsigned short port)
15 __builtin_outl(value, port);
18 unsigned char inb(unsigned short port)
20 return __builtin_inb(port);
23 unsigned char inw(unsigned short port)
25 return __builtin_inw(port);
28 unsigned char inl(unsigned short port)
30 return __builtin_inl(port);
33 static unsigned int config_cmd(unsigned char bus, unsigned devfn, unsigned where)
35 return 0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3);
38 static unsigned char pcibios_read_config_byte(
39 unsigned char bus, unsigned devfn, unsigned where)
41 outl(config_cmd(bus, devfn, where), 0xCF8);
42 return inb(0xCFC + (where & 3));
45 static unsigned short pcibios_read_config_word(
46 unsigned char bus, unsigned devfn, unsigned where)
48 outl(config_cmd(bus, devfn, where), 0xCF8);
49 return inw(0xCFC + (where & 2));
52 static unsigned int pcibios_read_config_dword(
53 unsigned char bus, unsigned devfn, unsigned where)
55 outl(config_cmd(bus, devfn, where), 0xCF8);
60 static void pcibios_write_config_byte(
61 unsigned char bus, unsigned devfn, unsigned where, unsigned char value)
63 outl(config_cmd(bus, devfn, where), 0xCF8);
64 outb(value, 0xCFC + (where & 3));
67 static void pcibios_write_config_word(
68 unsigned char bus, unsigned devfn, unsigned where, unsigned short value)
70 outl(config_cmd(bus, devfn, where), 0xCF8);
71 outw(value, 0xCFC + (where & 2));
74 static void pcibios_write_config_dword(
75 unsigned char bus, unsigned devfn, unsigned where, unsigned int value)
77 outl(config_cmd(bus, devfn, where), 0xCF8);
83 /* __builtin_bsr is a exactly equivalent to the x86 machine
84 * instruction with the exception that it returns -1
85 * when the value presented to it is zero.
86 * Otherwise __builtin_bsr returns the zero based index of
87 * the highest bit set.
89 return __builtin_bsr(value);
92 #define PIIX4_DEVFN 0x90
93 #define SMBUS_MEM_DEVICE_START 0x50
94 #define SMBUS_MEM_DEVICE_END 0x53
95 #define SMBUS_MEM_DEVICE_INC 1
99 #define PM_DEVFN (PIIX4_DEVFN+3)
101 #if HAVE_CONSTANT_PROPOGATION
102 #define SMBUS_IO_BASE 0x1000
111 static void smbus_wait_until_ready(void)
113 while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
118 static void smbus_wait_until_done(void)
122 byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
123 }while((byte &1) == 1);
124 while( (byte & ~1) == 0) {
125 byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
129 int smbus_read_byte(unsigned device, unsigned address)
131 unsigned char host_status_register;
135 smbus_wait_until_ready();
137 /* setup transaction */
138 /* disable interrupts */
139 outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
140 /* set the device I'm talking too */
141 outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
142 /* set the command/address... */
143 outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
144 /* set up for a byte data read */
145 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
147 /* clear any lingering errors, so the transaction will run */
148 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
150 /* clear the data byte...*/
151 outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
153 /* start the command */
154 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
156 /* poll for transaction completion */
157 smbus_wait_until_done();
159 host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
161 /* read results of transaction */
162 byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
165 if (host_status_register != 0x02) {
171 #else /* !HAVE_CONSTANT_PROPOGATION */
173 #define SMBUS_IO_HSTSTAT 0x1000
174 #define SMBUS_IO_HSTCTL 0x1002
175 #define SMBUS_IO_HSTCMD 0x1003
176 #define SMBUS_IO_HSTADD 0x1004
177 #define SMBUS_IO_HSTDAT0 0x1005
178 #define SMBUS_IO_HSTDAT1 0x1006
179 #define SMBUS_IO_HSTBLKDAT 0x1007
182 static void smbus_wait_until_ready(void)
184 while((inb(SMBUS_IO_HSTSTAT) & '\1') == '\1') {
189 static void smbus_wait_until_done(void)
193 byte = inb(SMBUS_IO_HSTSTAT);
194 }while((byte &1) == 1);
195 while( (byte & ~1) == 0) {
196 byte = inb(SMBUS_IO_HSTSTAT);
200 short smbus_read_byte(unsigned char device, unsigned char address)
202 unsigned char host_status_register;
205 smbus_wait_until_ready(); /* 2 */
207 /* setup transaction */
208 /* disable interrupts */
209 outb(inb(SMBUS_IO_HSTCTL) & (~1), SMBUS_IO_HSTCTL); /* 3 */
210 /* set the device I'm talking too */
211 outb(((device & 0x7f) << 1) | 1, SMBUS_IO_HSTADD); /* 1 + 3 */
212 /* set the command/address... */
213 outb(address & 0xFF, SMBUS_IO_HSTCMD); /* 1 + 3 */
214 /* set up for a byte data read */
215 outb((inb(SMBUS_IO_HSTCTL) & 0xE3) | 8, SMBUS_IO_HSTCTL); /* 3 */
217 /* clear any lingering errors, so the transaction will run */
218 outb(inb(SMBUS_IO_HSTSTAT), SMBUS_IO_HSTSTAT); /* 3 */
220 /* clear the data byte...*/
221 outb(0, SMBUS_IO_HSTDAT0); /* 3 */
223 /* start the command */
224 outb((inb(SMBUS_IO_HSTCTL) | 0x40), SMBUS_IO_HSTCTL);
226 /* poll for transaction completion */
227 smbus_wait_until_done();
229 host_status_register = inb(SMBUS_IO_HSTSTAT);
231 /* read results of transaction */
232 result = inb(SMBUS_IO_HSTDAT0);
234 if (host_status_register != 0x02) {
239 #endif /* HAVE_CONSTANT_PROPOGATION */
242 static void test(void)
246 unsigned char i, j, k, l, m, n, o;
254 device = inb(SMBUS_MEM_DEVICE_START);
255 byte = smbus_read_byte(device, 3);