1 2 /* 3 * Macro: PCI_WRITE_CONFIG_BYTE 4 * Arguments: %eax address to write to (includes bus, device, function, &offset) 5 * %dl byte to write 6 * 7 * Results: none 8 * 9 * Trashed: %eax, %edx 10 * Effects: writes a single byte to pci config space 11 * 12 * Notes: This routine is optimized for minimal register usage. 13 * And the tricks it does cannot scale beyond writing a single byte. 14 * 15 * What it does is almost simple. 16 * It preserves %eax (baring special bits) until it is written 17 * out to the appropriate port. And hides the data byte 18 * in the high half of edx. 19 * 20 * In %edx[3] it stores the byte to write. 21 * In %edx[2] it stores the lower three bits of the address. 22 */ 23 24 25#define PCI_WRITE_CONFIG_BYTE \ 26 shll $8, %edx ; \ 27 movb %al, %dl ; \ 28 andb $0x3, %dl ; \ 29 shll $16, %edx ; \ 30 \ 31 orl $0x80000000, %eax ; \ 32 andl $0xfffffffc, %eax ; \ 33 movw $0xcf8, %dx ; \ 34 outl %eax, %dx ; \ 35 \ 36 shrl $16, %edx ; \ 37 movb %dh, %al ; \ 38 movb $0, %dh ; \ 39 addl $0xcfc, %edx ; \ 40 outb %al, %dx 41 42 43 /* 44 * Macro: PCI_WRITE_CONFIG_WORD 45 * Arguments: %eax address to write to (includes bus, device, function, &offset) 46 * %ecx word to write 47 * 48 * Results: none 49 * 50 * Trashed: %eax, %edx 51 * Preserved: %ecx 52 * Effects: writes a single byte to pci config space 53 * 54 * Notes: This routine is optimized for minimal register usage. 55 * 56 * What it does is almost simple. 57 * It preserves %eax (baring special bits) until it is written 58 * out to the appropriate port. And hides the least significant 59 * bits of the address in the high half of edx. 60 * 61 * In %edx[2] it stores the lower three bits of the address. 62 */ 63 64 65#define PCI_WRITE_CONFIG_WORD \ 66 movb %al, %dl ; \ 67 andl $0x3, %edx ; \ 68 shll $16, %edx ; \ 69 \ 70 orl $0x80000000, %eax ; \ 71 andl $0xfffffffc, %eax ; \ 72 movw $0xcf8, %dx ; \ 73 outl %eax, %dx ; \ 74 \ 75 shrl $16, %edx ; \ 76 movl %ecx, %eax ; \ 77 addl $0xcfc, %edx ; \ 78 outw %ax, %dx 79 80 81 82 /* 83 * Macro: PCI_WRITE_CONFIG_DWORD 84 * Arguments: %eax address to write to (includes bus, device, function, &offset) 85 * %ecx dword to write 86 * 87 * Results: none 88 * 89 * Trashed: %eax, %edx 90 * Preserved: %ecx 91 * Effects: writes a single byte to pci config space 92 * 93 * Notes: This routine is optimized for minimal register usage. 94 * 95 * What it does is almost simple. 96 * It preserves %eax (baring special bits) until it is written 97 * out to the appropriate port. And hides the least significant 98 * bits of the address in the high half of edx. 99 * 100 * In %edx[2] it stores the lower three bits of the address. 101 */ 102 103 104#define PCI_WRITE_CONFIG_DWORD \ 105 movb %al, %dl ; \ 106 andl $0x3, %edx ; \ 107 shll $16, %edx ; \ 108 \ 109 orl $0x80000000, %eax ; \ 110 andl $0xfffffffc, %eax ; \ 111 movw $0xcf8, %dx ; \ 112 outl %eax, %dx ; \ 113 \ 114 shrl $16, %edx ; \ 115 movl %ecx, %eax ; \ 116 addl $0xcfc, %edx ; \ 117 outl %eax, %dx 118 119 120 121 122 /* 123 * Macro: PCI_READ_CONFIG_BYTE 124 * Arguments: %eax address to read from (includes bus, device, function, &offset) 125 * 126 * Results: %al Byte read 127 * 128 * Trashed: %eax, %edx 129 * Effects: reads a single byte from pci config space 130 * 131 * Notes: This routine is optimized for minimal register usage. 132 * 133 * What it does is almost simple. 134 * It preserves %eax (baring special bits) until it is written 135 * out to the appropriate port. And hides the least significant 136 * bits of the address in the high half of edx. 137 * 138 * In %edx[2] it stores the lower three bits of the address. 139 */ 140 141 142#define PCI_READ_CONFIG_BYTE \ 143 movb %al, %dl ; \ 144 andl $0x3, %edx ; \ 145 shll $16, %edx ; \ 146 \ 147 orl $0x80000000, %eax ; \ 148 andl $0xfffffffc, %eax ; \ 149 movw $0xcf8, %dx ; \ 150 outl %eax, %dx ; \ 151 \ 152 shrl $16, %edx ; \ 153 addl $0xcfc, %edx ; \ 154 inb %dx, %al 155 156 157 158 /* 159 * Macro: PCI_READ_CONFIG_WORD 160 * Arguments: %eax address to read from (includes bus, device, function, &offset) 161 * 162 * Results: %ax word read 163 * 164 * Trashed: %eax, %edx 165 * Effects: reads a 2 bytes from pci config space 166 * 167 * Notes: This routine is optimized for minimal register usage. 168 * 169 * What it does is almost simple. 170 * It preserves %eax (baring special bits) until it is written 171 * out to the appropriate port. And hides the least significant 172 * bits of the address in the high half of edx. 173 * 174 * In %edx[2] it stores the lower three bits of the address. 175 */ 176 177 178#define PCI_READ_CONFIG_WORD \ 179 movb %al, %dl ; \ 180 andl $0x3, %edx ; \ 181 shll $16, %edx ; \ 182 \ 183 orl $0x80000000, %eax ; \ 184 andl $0xfffffffc, %eax ; \ 185 movw $0xcf8, %dx ; \ 186 outl %eax, %dx ; \ 187 \ 188 shrl $16, %edx ; \ 189 addl $0xcfc, %edx ; \ 190 inw %dx, %ax 191 192 193 194 /* 195 * Macro: PCI_READ_CONFIG_DWORD 196 * Arguments: %eax address to read from (includes bus, device, function, &offset) 197 * 198 * Results: %eax 199 * 200 * Trashed: %edx 201 * Effects: reads 4 bytes from pci config space 202 * 203 * Notes: This routine is optimized for minimal register usage. 204 * 205 * What it does is almost simple. 206 * It preserves %eax (baring special bits) until it is written 207 * out to the appropriate port. And hides the least significant 208 * bits of the address in the high half of edx. 209 * 210 * In %edx[2] it stores the lower three bits of the address. 211 */ 212 213 214#define PCI_READ_CONFIG_DWORD \ 215 movb %al, %dl ; \ 216 andl $0x3, %edx ; \ 217 shll $16, %edx ; \ 218 \ 219 orl $0x80000000, %eax ; \ 220 andl $0xfffffffc, %eax ; \ 221 movw $0xcf8, %dx ; \ 222 outl %eax, %dx ; \ 223 \ 224 shrl $16, %edx ; \ 225 addl $0xcfc, %edx ; \ 226 inl %dx, %eax 227 228 229 230

