Changeset f701b236 in mainline
- 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
- Location:
- arch/ia32
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/ia32/include/smp/apic.h
r8418c7d rf701b236 71 71 #define POLARITY_HIGH 0x0 72 72 #define POLARITY_LOW 0x1 73 74 /** Divide Values. (Bit 2 is always 0) */ 75 #define DIVIDE_2 0x0 76 #define DIVIDE_4 0x1 77 #define DIVIDE_8 0x2 78 #define DIVIDE_16 0x3 79 #define DIVIDE_32 0x8 80 #define DIVIDE_64 0x9 81 #define DIVIDE_128 0xa 82 #define DIVIDE_1 0xb 83 84 /** Timer Modes. */ 85 #define TIMER_ONESHOT 0x0 86 #define TIMER_PERIODIC 0x1 73 87 74 88 #define SEND_PENDING (1<<12) … … 106 120 #define EOI (0x0b0/sizeof(__u32)) 107 121 108 /* Error Status Register*/122 /** Error Status Register. */ 109 123 #define ESR (0x280/sizeof(__u32)) 110 #define ESRClear ((0xffffff<<8)|(1<<4)) 124 union esr { 125 __u32 value; 126 __u8 err_bitmap; 127 struct { 128 unsigned send_checksum_error : 1; 129 unsigned receive_checksum_error : 1; 130 unsigned send_accept_error : 1; 131 unsigned receive_accept_error : 1; 132 unsigned : 1; 133 unsigned send_illegal_vector : 1; 134 unsigned received_illegal_vector : 1; 135 unsigned illegal_register_address : 1; 136 unsigned : 24; 137 } __attribute__ ((packed)); 138 }; 139 typedef union esr esr_t; 111 140 112 141 /* Task Priority Register */ … … 127 156 typedef union svr svr_t; 128 157 129 /* Time Divide Configuration Register*/158 /** Time Divide Configuration Register. */ 130 159 #define TDCR (0x3e0/sizeof(__u32)) 131 #define TDCRClear (~0xb) 160 union tdcr { 161 __u32 value; 162 struct { 163 unsigned div_value : 4; /**< Divide Value, bit 2 is always 0. */ 164 unsigned : 28; /**< Reserved. */ 165 } __attribute__ ((packed)); 166 }; 167 typedef union tdcr tdcr_t; 132 168 133 169 /* Initial Count Register for Timer */ … … 136 172 /* Current Count Register for Timer */ 137 173 #define CCRT (0x390/sizeof(__u32)) 138 139 /** Timer Modes. */140 #define TIMER_ONESHOT 0x0141 #define TIMER_PERIODIC 0x1142 174 143 175 /** LVT Timer register. */ … … 191 223 typedef union lvt_error lvt_error_t; 192 224 193 194 #define LVT_PCINT (0x340/sizeof(__u32)) 195 196 /* Local APIC ID Register */ 225 /** Local APIC ID Register. */ 197 226 #define L_APIC_ID (0x020/sizeof(__u32)) 198 #define L_APIC_IDClear (~(0xf<<24)) 199 #define L_APIC_IDShift 24 200 #define L_APIC_IDMask 0xf 227 union lapic_id { 228 __u32 value; 229 struct { 230 unsigned : 24; /**< Reserved. */ 231 __u8 apic_id; /**< Local APIC ID. */ 232 } __attribute__ ((packed)); 233 }; 234 typedef union lapic_id lapic_id_t; 201 235 202 236 /* Local APIC Version Register */ … … 215 249 #define IOAPICARB 0x02 216 250 #define IOREDTBL 0x10 251 252 /** I/O Register Select Register. */ 253 union io_regsel { 254 __u32 value; 255 struct { 256 __u8 reg_addr; /**< APIC Register Address. */ 257 unsigned : 24; /**< Reserved. */ 258 } __attribute__ ((packed)); 259 }; 260 typedef union io_regsel io_regsel_t; 217 261 218 262 /** I/O Redirection Register. */ … … 262 306 extern __u32 io_apic_read(__u8 address); 263 307 extern void io_apic_write(__u8 address , __u32 x); 264 extern void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags);308 extern void io_apic_change_ioredtbl(int pin, int dest, __u8 v, int flags); 265 309 extern void io_apic_disable_irqs(__u16 irqmask); 266 310 extern void io_apic_enable_irqs(__u16 irqmask); -
arch/ia32/src/drivers/i8254.c
r8418c7d rf701b236 61 61 { 62 62 outb(CLK_PORT4, 0x36); 63 trap_virtual_disable_irqs(1<<IRQ_CLK);63 pic_disable_irqs(1<<IRQ_CLK); 64 64 outb(CLK_PORT1, (CLK_CONST/HZ) & 0xf); 65 65 outb(CLK_PORT1, (CLK_CONST/HZ) >> 8); 66 trap_virtual_enable_irqs(1<<IRQ_CLK);66 pic_enable_irqs(1<<IRQ_CLK); 67 67 trap_register(VECTOR_CLK, i8254_interrupt); 68 68 } -
arch/ia32/src/ia32.c
r8418c7d rf701b236 95 95 { 96 96 i8254_calibrate_delay_loop(); 97 i8254_normal_operation(); 97 if (config.cpu_active == 1) { 98 /* 99 * This has to be done only on UP. 100 * On SMP, i8254 is not used for time keeping and its interrupt pin remains masked. 101 */ 102 i8254_normal_operation(); 103 } 98 104 } -
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.