Changeset f701b236 in mainline for arch/ia32/src/smp/apic.c
- Timestamp:
- 2005-11-24T00:46:43Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9149135
- Parents:
- 8418c7d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/ia32/src/smp/apic.c
r8418c7d rf701b236 63 63 __u32 apic_id_mask = 0; 64 64 65 int apic_poll_errors(void); 65 static int apic_poll_errors(void); 66 67 static char *delmod_str[] = { 68 "Fixed", 69 "Lowest Priority", 70 "SMI", 71 "Reserved", 72 "NMI", 73 "INIT", 74 "STARTUP", 75 "ExtInt" 76 }; 77 78 static char *destmod_str[] = { 79 "Physical", 80 "Logical" 81 }; 82 83 static char *trigmod_str[] = { 84 "Edge", 85 "Level" 86 }; 87 88 static char *mask_str[] = { 89 "Unmasked", 90 "Masked" 91 }; 92 93 static char *delivs_str[] = { 94 "Idle", 95 "Send Pending" 96 }; 97 98 static char *tm_mode_str[] = { 99 "One-shot", 100 "Periodic" 101 }; 102 103 static char *intpol_str[] = { 104 "Polarity High", 105 "Polarity Low" 106 }; 66 107 67 108 /** Initialize APIC on BSP. */ … … 115 156 } 116 157 158 /** APIC spurious interrupt handler. 159 * 160 * @param n Interrupt vector. 161 * @param stack Interrupted stack. 162 */ 117 163 void apic_spurious(__u8 n, __native stack[]) 118 164 { … … 120 166 } 121 167 168 /** Poll for APIC errors. 169 * 170 * Examine Error Status Register and report all errors found. 171 * 172 * @return 0 on error, 1 on success. 173 */ 122 174 int apic_poll_errors(void) 123 175 { 124 __u32esr;125 126 esr = l_apic[ESR] & ~ESRClear;127 128 if ( (esr>>0) & 1)176 esr_t esr; 177 178 esr.value = l_apic[ESR]; 179 180 if (esr.send_checksum_error) 129 181 printf("Send CS Error\n"); 130 if ( (esr>>1) & 1)182 if (esr.receive_checksum_error) 131 183 printf("Receive CS Error\n"); 132 if ( (esr>>2) & 1)184 if (esr.send_accept_error) 133 185 printf("Send Accept Error\n"); 134 if ( (esr>>3) & 1)186 if (esr.receive_accept_error) 135 187 printf("Receive Accept Error\n"); 136 if ( (esr>>5) & 1)188 if (esr.send_illegal_vector) 137 189 printf("Send Illegal Vector\n"); 138 if ( (esr>>6) & 1)190 if (esr.received_illegal_vector) 139 191 printf("Received Illegal Vector\n"); 140 if ( (esr>>7) & 1)192 if (esr.illegal_register_address) 141 193 printf("Illegal Register Address\n"); 142 194 143 return !esr; 144 } 145 146 /* 147 * Send all CPUs excluding CPU IPI vector. 195 return !esr.err_bitmap; 196 } 197 198 /** Send all CPUs excluding CPU IPI vector. 199 * 200 * @param vector Interrupt vector to be sent. 201 * 202 * @return 0 on failure, 1 on success. 148 203 */ 149 204 int l_apic_broadcast_custom_ipi(__u8 vector) … … 168 223 } 169 224 170 /* 171 * Universal Start-up Algorithm for bringing up the AP processors. 225 /** Universal Start-up Algorithm for bringing up the AP processors. 226 * 227 * @param apicid APIC ID of the processor to be brought up. 228 * 229 * @return 0 on failure, 1 on success. 172 230 */ 173 231 int l_apic_send_init_ipi(__u8 apicid) … … 239 297 } 240 298 299 /** Initialize Local APIC. */ 241 300 void l_apic_init(void) 242 301 { … … 244 303 lvt_lint_t lint; 245 304 svr_t svr; 305 icr_t icr; 306 tdcr_t tdcr; 246 307 lvt_tm_t tm; 247 icr_t icr;248 308 __u32 t1, t2; 249 309 … … 283 343 l_apic[ICRlo] = icr.lo; 284 344 285 /* 286 * Program the timer for periodic mode and respective vector. 287 */ 288 289 l_apic[TDCR] &= TDCRClear; 290 l_apic[TDCR] |= 0xb; 291 345 /* Timer Divide Configuration Register initialization. */ 346 tdcr.value = l_apic[TDCR]; 347 tdcr.div_value = DIVIDE_1; 348 l_apic[TDCR] = tdcr.value; 349 350 /* Program local timer. */ 292 351 tm.value = l_apic[LVT_Tm]; 293 352 tm.vector = VECTOR_CLK; … … 296 355 l_apic[LVT_Tm] = tm.value; 297 356 357 /* Measure and configure the timer to generate timer interrupt each ms. */ 298 358 t1 = l_apic[CCRT]; 299 359 l_apic[ICRT] = 0xffffffff; … … 310 370 } 311 371 372 /** Local APIC End of Interrupt. */ 312 373 void l_apic_eoi(void) 313 374 { … … 315 376 } 316 377 378 /** Dump content of Local APIC registers. */ 317 379 void l_apic_debug(void) 318 380 { 319 381 #ifdef LAPIC_VERBOSE 320 int i, lint; 321 382 lvt_tm_t tm; 383 lvt_lint_t lint; 384 lvt_error_t error; 385 322 386 printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id()); 323 387 324 printf("LVT_Tm: "); 325 if (l_apic[LVT_Tm] & (1<<17)) printf("periodic"); else printf("one-shot"); putchar(','); 326 if (l_apic[LVT_Tm] & (1<<16)) printf("masked"); else printf("not masked"); putchar(','); 327 if (l_apic[LVT_Tm] & (1<<12)) printf("send pending"); else printf("idle"); putchar(','); 328 printf("%B\n", l_apic[LVT_Tm] & 0xff); 329 330 for (i=0; i<2; i++) { 331 lint = i ? LVT_LINT1 : LVT_LINT0; 332 printf("LVT_LINT%d: ", i); 333 if (l_apic[lint] & (1<<16)) printf("masked"); else printf("not masked"); putchar(','); 334 if (l_apic[lint] & (1<<15)) printf("level"); else printf("edge"); putchar(','); 335 printf("%d", l_apic[lint] & (1<<14)); putchar(','); 336 printf("%d", l_apic[lint] & (1<<13)); putchar(','); 337 if (l_apic[lint] & (1<<12)) printf("send pending"); else printf("idle"); putchar(','); 338 339 switch ((l_apic[lint]>>8)&7) { 340 case 0: printf("fixed"); break; 341 case 4: printf("NMI"); break; 342 case 7: printf("ExtINT"); break; 343 } 344 putchar(','); 345 printf("%B\n", l_apic[lint] & 0xff); 346 } 347 348 printf("LVT_Err: "); 349 if (l_apic[LVT_Err] & (1<<16)) printf("masked"); else printf("not masked"); putchar(','); 350 if (l_apic[LVT_Err] & (1<<12)) printf("send pending"); else printf("idle"); putchar(','); 351 printf("%B\n", l_apic[LVT_Err] & 0xff); 352 353 /* 354 * This register is supported only on P6 and higher. 355 */ 356 if (CPU->arch.family > 5) { 357 printf("LVT_PCINT: "); 358 if (l_apic[LVT_PCINT] & (1<<16)) printf("masked"); else printf("not masked"); putchar(','); 359 if (l_apic[LVT_PCINT] & (1<<12)) printf("send pending"); else printf("idle"); putchar(','); 360 switch ((l_apic[LVT_PCINT] >> 8)&7) { 361 case 0: printf("fixed"); break; 362 case 4: printf("NMI"); break; 363 case 7: printf("ExtINT"); break; 364 } 365 putchar(','); 366 printf("%B\n", l_apic[LVT_PCINT] & 0xff); 367 } 388 tm.value = l_apic[LVT_Tm]; 389 printf("LVT Tm: vector=%B, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]); 390 lint.value = l_apic[LVT_LINT0]; 391 printf("LVT LINT0: vector=%B, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); 392 lint.value = l_apic[LVT_LINT1]; 393 printf("LVT LINT1: vector=%B, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); 394 error.value = l_apic[LVT_Err]; 395 printf("LVT Err: vector=%B, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]); 368 396 #endif 369 397 } 370 398 399 /** Local APIC Timer Interrupt. 400 * 401 * @param n Interrupt vector number. 402 * @param stack Interrupted stack. 403 */ 371 404 void l_apic_timer_interrupt(__u8 n, __native stack[]) 372 405 { … … 375 408 } 376 409 410 /** Get Local APIC ID. 411 * 412 * @return Local APIC ID. 413 */ 377 414 __u8 l_apic_id(void) 378 415 { 379 return (l_apic[L_APIC_ID] >> L_APIC_IDShift)&L_APIC_IDMask; 380 } 381 416 lapic_id_t lapic_id; 417 418 lapic_id.value = l_apic[L_APIC_ID]; 419 return lapic_id.apic_id; 420 } 421 422 /** Read from IO APIC register. 423 * 424 * @param address IO APIC register address. 425 * 426 * @return Content of the addressed IO APIC register. 427 */ 382 428 __u32 io_apic_read(__u8 address) 383 429 { 384 __u32 tmp; 385 386 tmp = io_apic[IOREGSEL] & ~0xf; 387 io_apic[IOREGSEL] = tmp | address; 430 io_regsel_t regsel; 431 432 regsel.value = io_apic[IOREGSEL]; 433 regsel.reg_addr = address; 434 io_apic[IOREGSEL] = regsel.value; 388 435 return io_apic[IOWIN]; 389 436 } 390 437 438 /** Write to IO APIC register. 439 * 440 * @param address IO APIC register address. 441 * @param Content to be written to the addressed IO APIC register. 442 */ 391 443 void io_apic_write(__u8 address, __u32 x) 392 444 { 393 __u32 tmp; 394 395 tmp = io_apic[IOREGSEL] & ~0xf; 396 io_apic[IOREGSEL] = tmp | address; 445 io_regsel_t regsel; 446 447 regsel.value = io_apic[IOREGSEL]; 448 regsel.reg_addr = address; 449 io_apic[IOREGSEL] = regsel.value; 397 450 io_apic[IOWIN] = x; 398 451 } 399 452 400 void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags) 453 /** Change some attributes of one item in I/O Redirection Table. 454 * 455 * @param pin IO APIC pin number. 456 * @param dest Interrupt destination address. 457 * @param v Interrupt vector to trigger. 458 * @param flags Flags. 459 */ 460 void io_apic_change_ioredtbl(int pin, int dest, __u8 v, int flags) 401 461 { 402 462 io_redirection_reg_t reg; 403 int dlvr = 0;463 int dlvr = DELMOD_FIXED; 404 464 405 465 if (flags & LOPRI) … … 407 467 408 468 409 reg.lo = io_apic_read(IOREDTBL + signal*2);410 reg.hi = io_apic_read(IOREDTBL + signal*2 + 1);469 reg.lo = io_apic_read(IOREDTBL + pin*2); 470 reg.hi = io_apic_read(IOREDTBL + pin*2 + 1); 411 471 412 472 reg.dest = dest; … … 417 477 reg.intvec = v; 418 478 419 io_apic_write(IOREDTBL + signal*2, reg.lo); 420 io_apic_write(IOREDTBL + signal*2 + 1, reg.hi); 421 } 422 479 io_apic_write(IOREDTBL + pin*2, reg.lo); 480 io_apic_write(IOREDTBL + pin*2 + 1, reg.hi); 481 } 482 483 /** Mask IRQs in IO APIC. 484 * 485 * @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask). 486 */ 423 487 void io_apic_disable_irqs(__u16 irqmask) 424 488 { … … 443 507 } 444 508 509 /** Unmask IRQs in IO APIC. 510 * 511 * @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask). 512 */ 445 513 void io_apic_enable_irqs(__u16 irqmask) 446 514 {
Note:
See TracChangeset
for help on using the changeset viewer.