1/* 2 * from: vector.s, 386BSD 0.1 unknown origin 3 * $FreeBSD: src/sys/i386/isa/apic_vector.s,v 1.47.2.5 2001/09/01 22:33:38 tegge Exp $ 4 */ 5 6#if 0 7#include "opt_auto_eoi.h" 8#endif 9 10#include <machine/asmacros.h> 11#include <machine/lock.h> 12#include <machine/psl.h> 13#include <machine/trap.h> 14#include <machine/segments.h> 15 16#include <machine_base/icu/icu.h> 17#include <bus/isa/isa.h> 18 19#include "assym.s" 20 21#include "apicreg.h" 22#include <machine_base/apic/ioapic_ipl.h> 23#include <machine/intr_machdep.h> 24 25#ifdef foo 26/* convert an absolute IRQ# into bitmask */ 27#define IRQ_LBIT(irq_num) (1UL << (irq_num & 0x3f)) 28#endif 29 30#define IRQ_SBITS(irq_num) ((irq_num) & 0x3f) 31 32/* convert an absolute IRQ# into gd_ipending index */ 33#define IRQ_LIDX(irq_num) ((irq_num) >> 6) 34 35#define MPLOCKED lock ; 36 37#define APIC_PUSH_FRAME_TFRIP \ 38 PUSH_FRAME_TFRIP ; /* 15 regs + space for 5 extras */ \ 39 movq $0,TF_XFLAGS(%rsp) ; \ 40 movq $0,TF_TRAPNO(%rsp) ; \ 41 movq $0,TF_ADDR(%rsp) ; \ 42 movq $0,TF_FLAGS(%rsp) ; \ 43 movq $0,TF_ERR(%rsp) ; \ 44 cld ; \ 45 46/* 47 * JG stale? Warning: POP_FRAME can only be used if there is no chance of a 48 * segment register being changed (e.g. by procfs), which is why syscalls 49 * have to use doreti. 50 */ 51#define APIC_POP_FRAME(lastinsn) \ 52 POP_FRAME(lastinsn) \ 53 54#define IOAPICADDR(irq_num) \ 55 CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_ADDR 56#define REDIRIDX(irq_num) \ 57 CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_IDX 58#define IOAPICFLAGS(irq_num) \ 59 CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_FLAGS 60 61#define MASK_IRQ(irq_num) \ 62 testl $IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ 63 jne 7f ; /* masked, don't mask */ \ 64 orl $IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ 65 /* set the mask bit */ \ 66 movq IOAPICADDR(irq_num), %rcx ; /* ioapic addr */ \ 67 movl REDIRIDX(irq_num), %eax ; /* get the index */ \ 68 movl %eax, (%rcx) ; /* write the index */ \ 69 orl $IOART_INTMASK,IOAPIC_WINDOW(%rcx) ;/* set the mask */ \ 707: ; /* already masked */ \ 71 72/* 73 * Test to see whether we are handling an edge or level triggered INT. 74 * Level-triggered INTs must still be masked as we don't clear the source, 75 * and the EOI cycle would cause redundant INTs to occur. 76 */ 77#define MASK_LEVEL_IRQ(irq_num) \ 78 testl $IOAPIC_IRQI_FLAG_LEVEL, IOAPICFLAGS(irq_num) ; \ 79 jz 9f ; /* edge, don't mask */ \ 80 MASK_IRQ(irq_num) ; \ 819: ; \ 82 83/* 84 * Test to see if the source is currntly masked, clear if so. 85 */ 86#define UNMASK_IRQ(irq_num) \ 87 cmpl $0,%eax ; \ 88 jnz 8f ; \ 89 IOAPIC_IMASK_LOCK ; \ 90 testl $IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ 91 je 7f ; /* bit clear, not masked */ \ 92 andl $~IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ 93 /* clear mask bit */ \ 94 movq IOAPICADDR(irq_num),%rcx ; /* ioapic addr */ \ 95 movl REDIRIDX(irq_num), %eax ; /* get the index */ \ 96 movl %eax,(%rcx) ; /* write the index */ \ 97 andl $~IOART_INTMASK,IOAPIC_WINDOW(%rcx) ;/* clear the mask */ \ 987: ; \ 99 IOAPIC_IMASK_UNLOCK ; \ 1008: ; \ 101 102/* 103 * Interrupt call handlers run in the following sequence: 104 * 105 * - Push the trap frame required by doreti 106 * - Mask the interrupt and reenable its source 107 * - If we cannot take the interrupt set its ipending bit and 108 * doreti. 109 * - If we can take the interrupt clear its ipending bit, 110 * call the handler, then unmask and doreti. 111 * 112 * YYY can cache gd base opitner instead of using hidden %fs prefixes. 113 */ 114 115#define INTR_HANDLER(irq_num) \ 116 .text ; \ 117 SUPERALIGN_TEXT ; \ 118IDTVEC(ioapic_intr##irq_num) ; \ 119 APIC_PUSH_FRAME_TFRIP ; \ 120 FAKE_MCOUNT(TF_RIP(%rsp)) ; \ 121 IOAPIC_IMASK_LOCK ; \ 122 MASK_LEVEL_IRQ(irq_num) ; \ 123 movq lapic_eoi, %rax ; \ 124 IOAPIC_IMASK_UNLOCK ; \ 125 callq *%rax ; \ 126 movq PCPU(curthread),%rbx ; \ 127 testl $-1,TD_NEST_COUNT(%rbx) ; \ 128 jne 1f ; \ 129 testl $-1,TD_CRITCOUNT(%rbx) ; \ 130 je 2f ; \ 1311: ; \ 132 /* in critical section, make interrupt pending */ \ 133 /* set the pending bit and return, leave interrupt masked */ \ 134 movq $1,%rcx ; \ 135 shlq $IRQ_SBITS(irq_num),%rcx ; \ 136 movq $IRQ_LIDX(irq_num),%rdx ; \ 137 orq %rcx,PCPU_E8(ipending,%rdx) ; \ 138 orl $RQF_INTPEND,PCPU(reqflags) ; \ 139 jmp 5f ; \ 1402: ; \ 141 /* clear pending bit, run handler */ \ 142 movq $1,%rcx ; \ 143 shlq $IRQ_SBITS(irq_num),%rcx ; \ 144 notq %rcx ; \ 145 movq $IRQ_LIDX(irq_num),%rdx ; \ 146 andq %rcx,PCPU_E8(ipending,%rdx) ; \ 147 pushq $irq_num ; /* trapframe -> intrframe */ \ 148 movq %rsp, %rdi ; /* pass frame by reference */ \ 149 incl TD_CRITCOUNT(%rbx) ; \ 150 sti ; \ 151 call ithread_fast_handler ; /* returns 0 to unmask */ \ 152 cli ; /* interlock avoid stacking */ \ 153 decl TD_CRITCOUNT(%rbx) ; \ 154 addq $8, %rsp ; /* intrframe -> trapframe */ \ 155 UNMASK_IRQ(irq_num) ; \ 1565: ; \ 157 MEXITCOUNT ; \ 158 jmp doreti ; \ 159 160/* 161 * Handle "spurious INTerrupts". 162 * 163 * NOTE: This is different than the "spurious INTerrupt" generated by an 164 * 8259 PIC for missing INTs. See the APIC documentation for details. 165 * This routine should NOT do an 'EOI' cycle. 166 * 167 * NOTE: Even though we don't do anything here we must still swapgs if 168 * coming from a user frame in case the iretq faults... just use 169 * the nominal APIC_PUSH_FRAME sequence to get it done. 170 */ 171 .text 172 SUPERALIGN_TEXT 173 .globl Xspuriousint 174Xspuriousint: 175 APIC_PUSH_FRAME_TFRIP 176 /* No EOI cycle used here */ 177 FAKE_MCOUNT(TF_RIP(%rsp)) 178 MEXITCOUNT 179 APIC_POP_FRAME(jmp doreti_iret) 180 181/* 182 * Handle TLB shootdowns. 183 * 184 * NOTE: interrupts are left disabled. 185 */ 186 .text 187 SUPERALIGN_TEXT 188 .globl Xinvltlb 189Xinvltlb: 190 APIC_PUSH_FRAME_TFRIP 191 movq lapic_eoi, %rax 192 callq *%rax /* End Of Interrupt to APIC */ 193 FAKE_MCOUNT(TF_RIP(%rsp)) 194 incl PCPU(cnt) + V_IPI 195 movq PCPU(curthread),%rbx 196 incl PCPU(intr_nesting_level) 197 incl TD_CRITCOUNT(%rbx) 198 subq $8,%rsp /* make same as interrupt frame */ 199 movq %rsp,%rdi /* pass frame by reference */ 200 orl $RQF_XINVLTLB,PCPU(reqflags) /* HVM interlock */ 201 call smp_inval_intr /* called w/interrupts disabled */ 202 addq $8,%rsp /* turn into trapframe */ 203 decl TD_CRITCOUNT(%rbx) 204 decl PCPU(intr_nesting_level) 205 MEXITCOUNT 206 /*APIC_POP_FRAME*/ 207 jmp doreti /* doreti b/c intrs enabled */ 208 209/* 210 * Handle sniffs - sniff %rip and %rsp. 211 */ 212 .text 213 SUPERALIGN_TEXT 214 .globl Xsniff 215Xsniff: 216 APIC_PUSH_FRAME_TFRIP 217 movq lapic_eoi, %rax 218 callq *%rax /* End Of Interrupt to APIC */ 219 FAKE_MCOUNT(TF_RIP(%rsp)) 220 incl PCPU(cnt) + V_IPI 221 movq %rsp,%rdi 222 call CNAME(hard_sniff) /* systat -pv and flame sniff */ 223 MEXITCOUNT 224 APIC_POP_FRAME(jmp doreti_iret) 225 226/* 227 * Executed by a CPU when it receives an Xcpustop IPI from another CPU, 228 * 229 * - We cannot call doreti 230 * - Signals its receipt. 231 * - Waits for permission to restart. 232 * - Processing pending IPIQ events while waiting. 233 * - Signals its restart. 234 */ 235 236 .text 237 SUPERALIGN_TEXT 238 .globl Xcpustop 239Xcpustop: 240 APIC_PUSH_FRAME_TFRIP 241 movq lapic_eoi, %rax 242 callq *%rax /* End Of Interrupt to APIC */ 243 244 movl PCPU(cpuid), %eax 245 imull $PCB_SIZE, %eax 246 leaq CNAME(stoppcbs), %rdi 247 addq %rax, %rdi 248 call CNAME(savectx) /* Save process context */ 249 250 /* 251 * Indicate that we have stopped and loop waiting for permission 252 * to start again. We must still process IPI events while in a 253 * stopped state. 254 * 255 * Interrupts must remain enabled for non-IPI'd per-cpu interrupts 256 * (e.g. Xtimer, Xinvltlb). 257 */ 258#if CPUMASK_ELEMENTS != 4 259#error "assembly incompatible with cpumask_t" 260#endif 261 movq PCPU(cpumask)+0,%rax /* stopped_cpus |= 1 << cpuid */ 262 MPLOCKED orq %rax, stopped_cpus+0 263 movq PCPU(cpumask)+8,%rax 264 MPLOCKED orq %rax, stopped_cpus+8 265 movq PCPU(cpumask)+16,%rax 266 MPLOCKED orq %rax, stopped_cpus+16 267 movq PCPU(cpumask)+24,%rax 268 MPLOCKED orq %rax, stopped_cpus+24 269 270 movq PCPU(curthread),%rbx 271 incl PCPU(intr_nesting_level) 272 incl TD_CRITCOUNT(%rbx) 273 sti 2741: 275 andl $~RQF_IPIQ,PCPU(reqflags) 276 call lwkt_smp_stopped 277 pause 278 279 subq %rdi,%rdi 280 movq started_cpus+0,%rax /* while (!(started_cpus & (1<<id))) */ 281 andq PCPU(cpumask)+0,%rax 282 orq %rax,%rdi 283 movq started_cpus+8,%rax 284 andq PCPU(cpumask)+8,%rax 285 orq %rax,%rdi 286 movq started_cpus+16,%rax 287 andq PCPU(cpumask)+16,%rax 288 orq %rax,%rdi 289 movq started_cpus+24,%rax 290 andq PCPU(cpumask)+24,%rax 291 orq %rax,%rdi 292 testq %rdi,%rdi 293 jz 1b 294 295 movq PCPU(other_cpus)+0,%rax /* started_cpus &= ~(1 << cpuid) */ 296 MPLOCKED andq %rax, started_cpus+0 297 movq PCPU(other_cpus)+8,%rax 298 MPLOCKED andq %rax, started_cpus+8 299 movq PCPU(other_cpus)+16,%rax 300 MPLOCKED andq %rax, started_cpus+16 301 movq PCPU(other_cpus)+24,%rax 302 MPLOCKED andq %rax, started_cpus+24 303 304 movq PCPU(other_cpus)+0,%rax /* stopped_cpus &= ~(1 << cpuid) */ 305 MPLOCKED andq %rax, stopped_cpus+0 306 movq PCPU(other_cpus)+8,%rax 307 MPLOCKED andq %rax, stopped_cpus+8 308 movq PCPU(other_cpus)+16,%rax 309 MPLOCKED andq %rax, stopped_cpus+16 310 movq PCPU(other_cpus)+24,%rax 311 MPLOCKED andq %rax, stopped_cpus+24 312 313 cmpl $0,PCPU(cpuid) 314 jnz 2f 315 316 movq CNAME(cpustop_restartfunc), %rax 317 testq %rax, %rax 318 jz 2f 319 movq $0, CNAME(cpustop_restartfunc) /* One-shot */ 320 321 call *%rax 3222: 323 decl TD_CRITCOUNT(%rbx) 324 decl PCPU(intr_nesting_level) 325 MEXITCOUNT 326 /*APIC_POP_FRAME*/ 327 jmp doreti 328 329 /* 330 * For now just have one ipiq IPI, but what we really want is 331 * to have one for each source cpu to the APICs don't get stalled 332 * backlogging the requests. 333 */ 334 .text 335 SUPERALIGN_TEXT 336 .globl Xipiq 337Xipiq: 338 APIC_PUSH_FRAME_TFRIP 339 movq lapic_eoi, %rax 340 callq *%rax /* End Of Interrupt to APIC */ 341 FAKE_MCOUNT(TF_RIP(%rsp)) 342 343 incl PCPU(cnt) + V_IPI 344 movq PCPU(curthread),%rbx 345 testl $-1,TD_CRITCOUNT(%rbx) 346 jne 1f 347 subq $8,%rsp /* make same as interrupt frame */ 348 movq %rsp,%rdi /* pass frame by reference */ 349 incl PCPU(intr_nesting_level) 350 incl TD_CRITCOUNT(%rbx) 351 subq %rax,%rax 352 sti 353 xchgl %eax,PCPU(npoll) /* (atomic op) allow another Xipi */ 354 call lwkt_process_ipiq_frame 355 cli /* interlock avoid stacking */ 356 decl TD_CRITCOUNT(%rbx) 357 decl PCPU(intr_nesting_level) 358 addq $8,%rsp /* turn into trapframe */ 359 MEXITCOUNT 360 jmp doreti 3611: 362 orl $RQF_IPIQ,PCPU(reqflags) 363 MEXITCOUNT 364 APIC_POP_FRAME(jmp doreti_iret) 365 366 .text 367 SUPERALIGN_TEXT 368 .globl Xtimer 369Xtimer: 370 APIC_PUSH_FRAME_TFRIP 371 movq lapic_eoi, %rax 372 callq *%rax /* End Of Interrupt to APIC */ 373 FAKE_MCOUNT(TF_RIP(%rsp)) 374 375 subq $8,%rsp /* make same as interrupt frame */ 376 movq %rsp,%rdi /* pass frame by reference */ 377 call pcpu_timer_always 378 addq $8,%rsp /* turn into trapframe */ 379 380 incl PCPU(cnt) + V_TIMER 381 movq TF_RIP(%rsp),%rbx /* sample addr before checking crit */ 382 movq %rbx,PCPU(sample_pc) 383 movq PCPU(curthread),%rbx 384 testl $-1,TD_CRITCOUNT(%rbx) 385 jne 1f 386 testl $-1,TD_NEST_COUNT(%rbx) 387 jne 1f 388 subq $8,%rsp /* make same as interrupt frame */ 389 movq %rsp,%rdi /* pass frame by reference */ 390 incl PCPU(intr_nesting_level) 391 incl TD_CRITCOUNT(%rbx) 392 sti 393 call pcpu_timer_process_frame 394 cli /* interlock avoid stacking */ 395 decl TD_CRITCOUNT(%rbx) 396 decl PCPU(intr_nesting_level) 397 addq $8,%rsp /* turn into trapframe */ 398 MEXITCOUNT 399 jmp doreti 4001: 401 orl $RQF_TIMER,PCPU(reqflags) 402 MEXITCOUNT 403 APIC_POP_FRAME(jmp doreti_iret) 404 405MCOUNT_LABEL(bintr) 406 INTR_HANDLER(0) 407 INTR_HANDLER(1) 408 INTR_HANDLER(2) 409 INTR_HANDLER(3) 410 INTR_HANDLER(4) 411 INTR_HANDLER(5) 412 INTR_HANDLER(6) 413 INTR_HANDLER(7) 414 INTR_HANDLER(8) 415 INTR_HANDLER(9) 416 INTR_HANDLER(10) 417 INTR_HANDLER(11) 418 INTR_HANDLER(12) 419 INTR_HANDLER(13) 420 INTR_HANDLER(14) 421 INTR_HANDLER(15) 422 INTR_HANDLER(16) 423 INTR_HANDLER(17) 424 INTR_HANDLER(18) 425 INTR_HANDLER(19) 426 INTR_HANDLER(20) 427 INTR_HANDLER(21) 428 INTR_HANDLER(22) 429 INTR_HANDLER(23) 430 INTR_HANDLER(24) 431 INTR_HANDLER(25) 432 INTR_HANDLER(26) 433 INTR_HANDLER(27) 434 INTR_HANDLER(28) 435 INTR_HANDLER(29) 436 INTR_HANDLER(30) 437 INTR_HANDLER(31) 438 INTR_HANDLER(32) 439 INTR_HANDLER(33) 440 INTR_HANDLER(34) 441 INTR_HANDLER(35) 442 INTR_HANDLER(36) 443 INTR_HANDLER(37) 444 INTR_HANDLER(38) 445 INTR_HANDLER(39) 446 INTR_HANDLER(40) 447 INTR_HANDLER(41) 448 INTR_HANDLER(42) 449 INTR_HANDLER(43) 450 INTR_HANDLER(44) 451 INTR_HANDLER(45) 452 INTR_HANDLER(46) 453 INTR_HANDLER(47) 454 INTR_HANDLER(48) 455 INTR_HANDLER(49) 456 INTR_HANDLER(50) 457 INTR_HANDLER(51) 458 INTR_HANDLER(52) 459 INTR_HANDLER(53) 460 INTR_HANDLER(54) 461 INTR_HANDLER(55) 462 INTR_HANDLER(56) 463 INTR_HANDLER(57) 464 INTR_HANDLER(58) 465 INTR_HANDLER(59) 466 INTR_HANDLER(60) 467 INTR_HANDLER(61) 468 INTR_HANDLER(62) 469 INTR_HANDLER(63) 470 INTR_HANDLER(64) 471 INTR_HANDLER(65) 472 INTR_HANDLER(66) 473 INTR_HANDLER(67) 474 INTR_HANDLER(68) 475 INTR_HANDLER(69) 476 INTR_HANDLER(70) 477 INTR_HANDLER(71) 478 INTR_HANDLER(72) 479 INTR_HANDLER(73) 480 INTR_HANDLER(74) 481 INTR_HANDLER(75) 482 INTR_HANDLER(76) 483 INTR_HANDLER(77) 484 INTR_HANDLER(78) 485 INTR_HANDLER(79) 486 INTR_HANDLER(80) 487 INTR_HANDLER(81) 488 INTR_HANDLER(82) 489 INTR_HANDLER(83) 490 INTR_HANDLER(84) 491 INTR_HANDLER(85) 492 INTR_HANDLER(86) 493 INTR_HANDLER(87) 494 INTR_HANDLER(88) 495 INTR_HANDLER(89) 496 INTR_HANDLER(90) 497 INTR_HANDLER(91) 498 INTR_HANDLER(92) 499 INTR_HANDLER(93) 500 INTR_HANDLER(94) 501 INTR_HANDLER(95) 502 INTR_HANDLER(96) 503 INTR_HANDLER(97) 504 INTR_HANDLER(98) 505 INTR_HANDLER(99) 506 INTR_HANDLER(100) 507 INTR_HANDLER(101) 508 INTR_HANDLER(102) 509 INTR_HANDLER(103) 510 INTR_HANDLER(104) 511 INTR_HANDLER(105) 512 INTR_HANDLER(106) 513 INTR_HANDLER(107) 514 INTR_HANDLER(108) 515 INTR_HANDLER(109) 516 INTR_HANDLER(110) 517 INTR_HANDLER(111) 518 INTR_HANDLER(112) 519 INTR_HANDLER(113) 520 INTR_HANDLER(114) 521 INTR_HANDLER(115) 522 INTR_HANDLER(116) 523 INTR_HANDLER(117) 524 INTR_HANDLER(118) 525 INTR_HANDLER(119) 526 INTR_HANDLER(120) 527 INTR_HANDLER(121) 528 INTR_HANDLER(122) 529 INTR_HANDLER(123) 530 INTR_HANDLER(124) 531 INTR_HANDLER(125) 532 INTR_HANDLER(126) 533 INTR_HANDLER(127) 534 INTR_HANDLER(128) 535 INTR_HANDLER(129) 536 INTR_HANDLER(130) 537 INTR_HANDLER(131) 538 INTR_HANDLER(132) 539 INTR_HANDLER(133) 540 INTR_HANDLER(134) 541 INTR_HANDLER(135) 542 INTR_HANDLER(136) 543 INTR_HANDLER(137) 544 INTR_HANDLER(138) 545 INTR_HANDLER(139) 546 INTR_HANDLER(140) 547 INTR_HANDLER(141) 548 INTR_HANDLER(142) 549 INTR_HANDLER(143) 550 INTR_HANDLER(144) 551 INTR_HANDLER(145) 552 INTR_HANDLER(146) 553 INTR_HANDLER(147) 554 INTR_HANDLER(148) 555 INTR_HANDLER(149) 556 INTR_HANDLER(150) 557 INTR_HANDLER(151) 558 INTR_HANDLER(152) 559 INTR_HANDLER(153) 560 INTR_HANDLER(154) 561 INTR_HANDLER(155) 562 INTR_HANDLER(156) 563 INTR_HANDLER(157) 564 INTR_HANDLER(158) 565 INTR_HANDLER(159) 566 INTR_HANDLER(160) 567 INTR_HANDLER(161) 568 INTR_HANDLER(162) 569 INTR_HANDLER(163) 570 INTR_HANDLER(164) 571 INTR_HANDLER(165) 572 INTR_HANDLER(166) 573 INTR_HANDLER(167) 574 INTR_HANDLER(168) 575 INTR_HANDLER(169) 576 INTR_HANDLER(170) 577 INTR_HANDLER(171) 578 INTR_HANDLER(172) 579 INTR_HANDLER(173) 580 INTR_HANDLER(174) 581 INTR_HANDLER(175) 582 INTR_HANDLER(176) 583 INTR_HANDLER(177) 584 INTR_HANDLER(178) 585 INTR_HANDLER(179) 586 INTR_HANDLER(180) 587 INTR_HANDLER(181) 588 INTR_HANDLER(182) 589 INTR_HANDLER(183) 590 INTR_HANDLER(184) 591 INTR_HANDLER(185) 592 INTR_HANDLER(186) 593 INTR_HANDLER(187) 594 INTR_HANDLER(188) 595 INTR_HANDLER(189) 596 INTR_HANDLER(190) 597 INTR_HANDLER(191) 598MCOUNT_LABEL(eintr) 599 600 .data 601 602#if CPUMASK_ELEMENTS != 4 603#error "assembly incompatible with cpumask_t" 604#endif 605/* variables used by stop_cpus()/restart_cpus()/Xcpustop */ 606 .globl stopped_cpus, started_cpus 607stopped_cpus: 608 .quad 0 609 .quad 0 610 .quad 0 611 .quad 0 612started_cpus: 613 .quad 0 614 .quad 0 615 .quad 0 616 .quad 0 617 618 .globl CNAME(cpustop_restartfunc) 619CNAME(cpustop_restartfunc): 620 .quad 0 621 622 .text 623 624