| 761 | } |
| 762 | |
| 763 | static void |
| 764 | native_lapic_setup(int boot) |
| 765 | { |
| 766 | struct lapic *la; |
| 767 | uint32_t version; |
| 768 | uint32_t maxlvt; |
| 769 | register_t saveintr; |
| 770 | int elvt_count; |
| 771 | int i; |
| 772 | |
| 773 | saveintr = intr_disable(); |
| 774 | |
| 775 | la = &lapics[lapic_id()]; |
| 776 | KASSERT(la->la_present, ("missing APIC structure")); |
| 777 | version = lapic_read32(LAPIC_VERSION); |
| 778 | maxlvt = (version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; |
| 779 | |
| 780 | /* Initialize the TPR to allow all interrupts. */ |
| 781 | lapic_set_tpr(0); |
| 782 | |
| 783 | /* Setup spurious vector and enable the local APIC. */ |
| 784 | lapic_enable(); |
| 785 | |
| 786 | /* Program LINT[01] LVT entries. */ |
| 787 | lapic_write32(LAPIC_LVT_LINT0, lvt_mode(la, APIC_LVT_LINT0, |
| 788 | lapic_read32(LAPIC_LVT_LINT0))); |
| 789 | lapic_write32(LAPIC_LVT_LINT1, lvt_mode(la, APIC_LVT_LINT1, |
| 790 | lapic_read32(LAPIC_LVT_LINT1))); |
| 791 | |
| 792 | /* Program the PMC LVT entry if present. */ |
| 793 | if (maxlvt >= APIC_LVT_PMC) { |
| 794 | lapic_write32(LAPIC_LVT_PCINT, lvt_mode(la, APIC_LVT_PMC, |
| 795 | LAPIC_LVT_PCINT)); |
| 796 | } |
| 797 | |
| 798 | /* Program timer LVT. */ |
| 799 | la->lvt_timer_base = lvt_mode(la, APIC_LVT_TIMER, |
| 800 | lapic_read32(LAPIC_LVT_TIMER)); |
| 801 | la->lvt_timer_last = la->lvt_timer_base; |
| 802 | lapic_write32(LAPIC_LVT_TIMER, la->lvt_timer_base); |
| 803 | |
| 804 | /* Calibrate the timer parameters using BSP. */ |
| 805 | if (boot && IS_BSP()) { |
| 806 | lapic_calibrate_initcount(la); |
| 807 | if (lapic_timer_tsc_deadline) |
| 808 | lapic_calibrate_deadline(la); |
| 809 | } |
| 810 | |
| 811 | /* Setup the timer if configured. */ |
| 812 | if (la->la_timer_mode != LAT_MODE_UNDEF) { |
| 813 | KASSERT(la->la_timer_period != 0, ("lapic%u: zero divisor", |
| 814 | lapic_id())); |
| 815 | switch (la->la_timer_mode) { |
| 816 | case LAT_MODE_PERIODIC: |
| 817 | lapic_timer_set_divisor(lapic_timer_divisor); |
| 818 | lapic_timer_periodic(la); |
| 819 | break; |
| 820 | case LAT_MODE_ONESHOT: |
nothing calls this directly
no test coverage detected