* Configure and start event timers (BSP part). */
| 590 | * Configure and start event timers (BSP part). |
| 591 | */ |
| 592 | void |
| 593 | cpu_initclocks_bsp(void) |
| 594 | { |
| 595 | struct pcpu_state *state; |
| 596 | int base, div, cpu; |
| 597 | |
| 598 | mtx_init(&et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN); |
| 599 | CPU_FOREACH(cpu) { |
| 600 | state = DPCPU_ID_PTR(cpu, timerstate); |
| 601 | mtx_init(&state->et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN); |
| 602 | state->nextcall = SBT_MAX; |
| 603 | state->nextcallopt = SBT_MAX; |
| 604 | } |
| 605 | periodic = want_periodic; |
| 606 | /* Grab requested timer or the best of present. */ |
| 607 | if (timername[0]) |
| 608 | timer = et_find(timername, 0, 0); |
| 609 | if (timer == NULL && periodic) { |
| 610 | timer = et_find(NULL, |
| 611 | ET_FLAGS_PERIODIC, ET_FLAGS_PERIODIC); |
| 612 | } |
| 613 | if (timer == NULL) { |
| 614 | timer = et_find(NULL, |
| 615 | ET_FLAGS_ONESHOT, ET_FLAGS_ONESHOT); |
| 616 | } |
| 617 | if (timer == NULL && !periodic) { |
| 618 | timer = et_find(NULL, |
| 619 | ET_FLAGS_PERIODIC, ET_FLAGS_PERIODIC); |
| 620 | } |
| 621 | if (timer == NULL) |
| 622 | panic("No usable event timer found!"); |
| 623 | et_init(timer, timercb, NULL, NULL); |
| 624 | |
| 625 | /* Adapt to timer capabilities. */ |
| 626 | if (periodic && (timer->et_flags & ET_FLAGS_PERIODIC) == 0) |
| 627 | periodic = 0; |
| 628 | else if (!periodic && (timer->et_flags & ET_FLAGS_ONESHOT) == 0) |
| 629 | periodic = 1; |
| 630 | if (timer->et_flags & ET_FLAGS_C3STOP) |
| 631 | cpu_disable_c3_sleep++; |
| 632 | |
| 633 | /* |
| 634 | * We honor the requested 'hz' value. |
| 635 | * We want to run stathz in the neighborhood of 128hz. |
| 636 | * We would like profhz to run as often as possible. |
| 637 | */ |
| 638 | if (singlemul <= 0 || singlemul > 20) { |
| 639 | if (hz >= 1500 || (hz % 128) == 0) |
| 640 | singlemul = 1; |
| 641 | else if (hz >= 750) |
| 642 | singlemul = 2; |
| 643 | else |
| 644 | singlemul = 4; |
| 645 | } |
| 646 | if (periodic) { |
| 647 | base = round_freq(timer, hz * singlemul); |
| 648 | singlemul = max((base + hz / 2) / hz, 1); |
| 649 | hz = (base + singlemul / 2) / singlemul; |
no test coverage detected