File indexing completed on 2025-05-11 08:23:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <rtems.h>
0015 #include <bsp.h>
0016 #include <rtems/pci.h>
0017
0018 #include <string.h> /* memcpy */
0019
0020
0021
0022
0023
0024 static int pcibInitialized = 0;
0025 static unsigned int pcibEntry;
0026
0027
0028
0029
0030
0031
0032
0033 static volatile unsigned int pcibExchg[5];
0034
0035 static int pcib_convert_err(int err);
0036
0037
0038
0039
0040
0041 #define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f))
0042
0043
0044
0045
0046 #define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff)
0047 #define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
0048 #define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
0049
0050
0051
0052
0053 static const pci_config_access_functions pci_bios_indirect_functions;
0054
0055
0056 const pci_config_access_functions *pci_bios_initialize(void);
0057
0058
0059
0060
0061 const pci_config_access_functions *pci_bios_initialize(void)
0062 {
0063 unsigned char *ucp;
0064 unsigned char sum;
0065 int i;
0066
0067 pcibInitialized = 0;
0068
0069
0070 for (ucp = (unsigned char *)0xE0000;
0071 ucp < (unsigned char *)0xFFFFF;
0072 ucp += 0x10) {
0073 if (memcmp(ucp, "_32_", 4) != 0) {
0074 continue;
0075 }
0076
0077
0078 if (*(ucp + 9) != 1) {
0079 continue;
0080 }
0081
0082
0083 sum = 0;
0084 for (i=0; i<16; i++) {
0085 sum += *(ucp+i);
0086 }
0087
0088 if (sum == 0) {
0089
0090 break;
0091 }
0092 }
0093
0094 if (ucp >= (unsigned char *)0xFFFFF) {
0095
0096 return NULL;
0097 }
0098
0099
0100 ucp += 4;
0101
0102 pcibExchg[0] = *(unsigned int *)ucp;
0103
0104 __asm__ (" pusha");
0105 __asm__ (" movl pcibExchg, %edi");
0106 __asm__ (" movl $0x49435024, %eax");
0107 __asm__ (" xorl %ebx, %ebx");
0108 __asm__ (" pushl %cs");
0109 __asm__ (" call *%edi");
0110 __asm__ (" movl %eax, pcibExchg");
0111 __asm__ (" movl %ebx, pcibExchg+4");
0112 __asm__ (" movl %ecx, pcibExchg+8");
0113 __asm__ (" movl %edx, pcibExchg+12");
0114 __asm__ (" popa");
0115
0116 if ((pcibExchg[0] & 0xff) != 0) {
0117
0118 return NULL;
0119 }
0120
0121
0122 pcibEntry = pcibExchg[1] + pcibExchg[3];
0123
0124
0125 pcibExchg[0] = pcibEntry;
0126
0127 __asm__ (" pusha");
0128 __asm__ (" movl pcibExchg, %edi");
0129 __asm__ (" movb $0xb1, %ah");
0130 __asm__ (" movb $0x01, %al");
0131 __asm__ (" pushl %cs");
0132 __asm__ (" call *%edi");
0133 __asm__ (" movl %eax, pcibExchg");
0134 __asm__ (" movl %ebx, pcibExchg+4");
0135 __asm__ (" movl %ecx, pcibExchg+8");
0136 __asm__ (" movl %edx, pcibExchg+12");
0137 __asm__ (" popa");
0138
0139 if ((pcibExchg[0] & 0xff00) != 0) {
0140
0141 return NULL;
0142 }
0143
0144 if (pcibExchg[3] != 0x20494350) {
0145
0146 return NULL;
0147 }
0148
0149
0150 pcibInitialized = 1;
0151
0152 return &pci_bios_indirect_functions;
0153 }
0154
0155
0156
0157
0158 static int
0159 pcib_conf_read8(int sig, int off, uint8_t *data)
0160 {
0161 if (!pcibInitialized) {
0162 return PCIB_ERR_UNINITIALIZED;
0163 }
0164
0165 pcibExchg[0] = pcibEntry;
0166 pcibExchg[1] = sig;
0167 pcibExchg[2] = off;
0168
0169 __asm__ (" pusha");
0170 __asm__ (" movl pcibExchg, %esi");
0171 __asm__ (" movb $0xb1, %ah");
0172 __asm__ (" movb $0x08, %al");
0173 __asm__ (" movl pcibExchg+4, %ebx");
0174 __asm__ (" movl pcibExchg+8, %edi");
0175 __asm__ (" pushl %cs");
0176 __asm__ (" call *%esi");
0177 __asm__ (" movl %eax, pcibExchg");
0178 __asm__ (" movl %ecx, pcibExchg+4");
0179 __asm__ (" popa");
0180
0181 if ((pcibExchg[0] & 0xff00) != 0) {
0182 return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
0183 }
0184
0185 *data = (unsigned char)pcibExchg[1] & 0xff;
0186
0187 return PCIB_ERR_SUCCESS;
0188 }
0189
0190
0191
0192
0193
0194 static int
0195 pcib_conf_read16(int sig, int off, uint16_t *data)
0196 {
0197 if (!pcibInitialized) {
0198 return PCIB_ERR_UNINITIALIZED;
0199 }
0200
0201 pcibExchg[0] = pcibEntry;
0202 pcibExchg[1] = sig;
0203 pcibExchg[2] = off;
0204
0205 __asm__ (" pusha");
0206 __asm__ (" movl pcibExchg, %esi");
0207 __asm__ (" movb $0xb1, %ah");
0208 __asm__ (" movb $0x09, %al");
0209 __asm__ (" movl pcibExchg+4, %ebx");
0210 __asm__ (" movl pcibExchg+8, %edi");
0211 __asm__ (" pushl %cs");
0212 __asm__ (" call *%esi");
0213 __asm__ (" movl %eax, pcibExchg");
0214 __asm__ (" movl %ecx, pcibExchg+4");
0215 __asm__ (" popa");
0216
0217 if ((pcibExchg[0] & 0xff00) != 0) {
0218 return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
0219 }
0220
0221 *data = (unsigned short)pcibExchg[1] & 0xffff;
0222
0223 return PCIB_ERR_SUCCESS;
0224 }
0225
0226
0227
0228
0229
0230 static int
0231 pcib_conf_read32(int sig, int off, uint32_t *data)
0232 {
0233 if (!pcibInitialized) {
0234 return PCIB_ERR_UNINITIALIZED;
0235 }
0236
0237 pcibExchg[0] = pcibEntry;
0238 pcibExchg[1] = sig;
0239 pcibExchg[2] = off;
0240
0241 __asm__ (" pusha");
0242 __asm__ (" movl pcibExchg, %esi");
0243 __asm__ (" movb $0xb1, %ah");
0244 __asm__ (" movb $0x0a, %al");
0245 __asm__ (" movl pcibExchg+4, %ebx");
0246 __asm__ (" movl pcibExchg+8, %edi");
0247 __asm__ (" pushl %cs");
0248 __asm__ (" call *%esi");
0249 __asm__ (" movl %eax, pcibExchg");
0250 __asm__ (" movl %ecx, pcibExchg+4");
0251 __asm__ (" popa");
0252
0253 if ((pcibExchg[0] & 0xff00) != 0) {
0254 return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
0255 }
0256
0257 *data = (unsigned int)pcibExchg[1];
0258
0259 return PCIB_ERR_SUCCESS;
0260 }
0261
0262
0263
0264
0265
0266 static int
0267 pcib_conf_write8(int sig, int off, uint8_t data)
0268 {
0269 if (!pcibInitialized) {
0270 return PCIB_ERR_UNINITIALIZED;
0271 }
0272
0273 pcibExchg[0] = pcibEntry;
0274 pcibExchg[1] = sig;
0275 pcibExchg[2] = off;
0276 pcibExchg[3] = data & 0xff;
0277
0278 __asm__ (" pusha");
0279 __asm__ (" movl pcibExchg, %esi");
0280 __asm__ (" movb $0xb1, %ah");
0281 __asm__ (" movb $0x0b, %al");
0282 __asm__ (" movl pcibExchg+4, %ebx");
0283 __asm__ (" movl pcibExchg+8, %edi");
0284 __asm__ (" movl pcibExchg+12, %ecx");
0285 __asm__ (" pushl %cs");
0286 __asm__ (" call *%esi");
0287 __asm__ (" movl %eax, pcibExchg");
0288 __asm__ (" popa");
0289
0290 return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
0291 }
0292
0293
0294
0295
0296 static int
0297 pcib_conf_write16(int sig, int off, uint16_t data)
0298 {
0299 if (!pcibInitialized) {
0300 return PCIB_ERR_UNINITIALIZED;
0301 }
0302
0303 pcibExchg[0] = pcibEntry;
0304 pcibExchg[1] = sig;
0305 pcibExchg[2] = off;
0306 pcibExchg[3] = data & 0xffff;
0307
0308 __asm__ (" pusha");
0309 __asm__ (" movl pcibExchg, %esi");
0310 __asm__ (" movb $0xb1, %ah");
0311 __asm__ (" movb $0x0c, %al");
0312 __asm__ (" movl pcibExchg+4, %ebx");
0313 __asm__ (" movl pcibExchg+8, %edi");
0314 __asm__ (" movl pcibExchg+12, %ecx");
0315 __asm__ (" pushl %cs");
0316 __asm__ (" call *%esi");
0317 __asm__ (" movl %eax, pcibExchg");
0318 __asm__ (" popa");
0319
0320 return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
0321 }
0322
0323
0324
0325
0326
0327
0328 static int
0329 pcib_conf_write32(int sig, int off, uint32_t data)
0330 {
0331 if (!pcibInitialized){
0332 return PCIB_ERR_UNINITIALIZED;
0333 }
0334
0335 pcibExchg[0] = pcibEntry;
0336 pcibExchg[1] = sig;
0337 pcibExchg[2] = off;
0338 pcibExchg[3] = data;
0339
0340 __asm__ (" pusha");
0341 __asm__ (" movl pcibExchg, %esi");
0342 __asm__ (" movb $0xb1, %ah");
0343 __asm__ (" movb $0x0d, %al");
0344 __asm__ (" movl pcibExchg+4, %ebx");
0345 __asm__ (" movl pcibExchg+8, %edi");
0346 __asm__ (" movl pcibExchg+12, %ecx");
0347 __asm__ (" pushl %cs");
0348 __asm__ (" call *%esi");
0349 __asm__ (" movl %eax, pcibExchg");
0350 __asm__ (" popa");
0351
0352 return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
0353 }
0354
0355
0356 static int
0357 pcib_convert_err(int err)
0358 {
0359 switch(err & 0xff){
0360 case 0:
0361 return PCIB_ERR_SUCCESS;
0362 case 0x81:
0363 return PCIB_ERR_NOFUNC;
0364 case 0x83:
0365 return PCIB_ERR_BADVENDOR;
0366 case 0x86:
0367 return PCIB_ERR_DEVNOTFOUND;
0368 case 0x87:
0369 return PCIB_ERR_BADREG;
0370 default:
0371 break;
0372 }
0373 return PCIB_ERR_NOFUNC;
0374 }
0375
0376 static int
0377 BSP_pci_read_config_byte(
0378 unsigned char bus,
0379 unsigned char slot,
0380 unsigned char fun,
0381 unsigned char offset,
0382 unsigned char *val
0383 )
0384 {
0385 int sig;
0386
0387 sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
0388 pcib_conf_read8(sig, offset, val);
0389 return PCIBIOS_SUCCESSFUL;
0390 }
0391
0392 static int
0393 BSP_pci_read_config_word(
0394 unsigned char bus,
0395 unsigned char slot,
0396 unsigned char fun,
0397 unsigned char offset,
0398 unsigned short *val
0399 )
0400 {
0401 int sig;
0402
0403 sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
0404 pcib_conf_read16(sig, offset, val);
0405 return PCIBIOS_SUCCESSFUL;
0406 }
0407
0408 static int
0409 BSP_pci_read_config_dword(
0410 unsigned char bus,
0411 unsigned char slot,
0412 unsigned char fun,
0413 unsigned char offset,
0414 uint32_t *val
0415 )
0416 {
0417 int sig;
0418
0419 sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
0420 pcib_conf_read32(sig, offset, val);
0421 return PCIBIOS_SUCCESSFUL;
0422 }
0423
0424 static int
0425 BSP_pci_write_config_byte(
0426 unsigned char bus,
0427 unsigned char slot,
0428 unsigned char fun,
0429 unsigned char offset,
0430 unsigned char val
0431 )
0432 {
0433 int sig;
0434
0435 sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
0436 pcib_conf_write8(sig, offset, val);
0437 return PCIBIOS_SUCCESSFUL;
0438 }
0439
0440 static int
0441 BSP_pci_write_config_word(
0442 unsigned char bus,
0443 unsigned char slot,
0444 unsigned char fun,
0445 unsigned char offset,
0446 unsigned short val
0447 )
0448 {
0449 int sig;
0450
0451 sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
0452 pcib_conf_write16(sig, offset, val);
0453 return PCIBIOS_SUCCESSFUL;
0454 }
0455
0456 static int
0457 BSP_pci_write_config_dword(
0458 unsigned char bus,
0459 unsigned char slot,
0460 unsigned char fun,
0461 unsigned char offset,
0462 uint32_t val
0463 )
0464 {
0465 int sig;
0466
0467 sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
0468 pcib_conf_write32(sig, offset, val);
0469 return PCIBIOS_SUCCESSFUL;
0470 }
0471
0472 static const pci_config_access_functions pci_bios_indirect_functions = {
0473 BSP_pci_read_config_byte,
0474 BSP_pci_read_config_word,
0475 BSP_pci_read_config_dword,
0476 BSP_pci_write_config_byte,
0477 BSP_pci_write_config_word,
0478 BSP_pci_write_config_dword
0479 };