[haiku-commits] haiku: hrev45991 - src/system/kernel/arch/x86 headers/private/kernel/arch/x86 src/system/kernel/arch/x86/timers src/system/boot/platform/bios_ia32

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 26 Aug 2013 21:13:30 +0200 (CEST)

hrev45991 adds 1 changeset to branch 'master'
old head: e9eb899aa4c8baace0ed8f4eb2e2899c585bc2b5
new head: 787773400ce9ee4ce71d9255e1be8fac66584615
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=7877734+%5Ee9eb899

----------------------------------------------------------------------------

7877734: Added x2APIC support.
  
  * Mostly useful for virtualization at the moment. Works in QEmu.
  * Can be enabled by safemode settings/menu.
  * Please note that x2APIC normally requires use of VT-d interrupt remapping 
feature
  on real hardware, which we don't support yet.

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev45991
Commit:      787773400ce9ee4ce71d9255e1be8fac66584615
URL:         http://cgit.haiku-os.org/haiku/commit/?id=7877734
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Mon Aug 26 17:17:28 2013 UTC

----------------------------------------------------------------------------

7 files changed, 312 insertions(+), 35 deletions(-)
headers/private/kernel/arch/x86/apic.h         |  19 ++
headers/private/kernel/arch/x86/arch_cpu.h     |  27 +++
headers/private/system/safemode_defs.h         |   1 +
src/system/boot/platform/bios_ia32/smp.cpp     |  16 ++
src/system/kernel/arch/x86/apic.cpp            | 242 +++++++++++++++++++--
src/system/kernel/arch/x86/arch_smp.cpp        |  14 +-
src/system/kernel/arch/x86/timers/x86_apic.cpp |  28 +--

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/arch/x86/apic.h 
b/headers/private/kernel/arch/x86/apic.h
index e0e18f7..9c3d922 100644
--- a/headers/private/kernel/arch/x86/apic.h
+++ b/headers/private/kernel/arch/x86/apic.h
@@ -113,10 +113,29 @@ bool              apic_available();
 uint32         apic_read(uint32 offset);
 void           apic_write(uint32 offset, uint32 data);
 uint32         apic_local_id();
+uint32         apic_local_version();
+uint32         apic_task_priority();
+void           apic_set_task_priority(uint32 config);
 void           apic_end_of_interrupt();
 
 void           apic_disable_local_ints();
 
+uint32         apic_spurious_intr_vector();
+void           apic_set_spurious_intr_vector(uint32 config);
+uint32         apic_intr_command_1();
+void           apic_set_intr_command_1(uint32 config);
+uint32         apic_intr_command_2();
+void           apic_set_intr_command_2(uint32 config);
+
+uint32         apic_lvt_timer();
+void           apic_set_lvt_timer(uint32 config);
+uint32         apic_lvt_error();
+void           apic_set_lvt_error(uint32 config);
+uint32         apic_lvt_initial_timer_count();
+void           apic_set_lvt_initial_timer_count(uint32 config);
+uint32         apic_lvt_timer_divide_config();
+void           apic_set_lvt_timer_divide_config(uint32 config);
+
 status_t       apic_init(kernel_args *args);
 status_t       apic_per_cpu_init(kernel_args *args, int32 cpu);
 
diff --git a/headers/private/kernel/arch/x86/arch_cpu.h 
b/headers/private/kernel/arch/x86/arch_cpu.h
index bc9f4c8..4809528 100644
--- a/headers/private/kernel/arch/x86/arch_cpu.h
+++ b/headers/private/kernel/arch/x86/arch_cpu.h
@@ -39,11 +39,38 @@
 
 #define IA32_MSR_EFER                                  0xc0000080
 
+
+// MSR APIC BASE bits
+#define IA32_MSR_APIC_BASE_BSP                 0x00000100
+#define IA32_MSR_APIC_BASE_X2APIC              0x00000400
+#define IA32_MSR_APIC_BASE_ENABLED             0x00000800
+#define IA32_MSR_APIC_BASE_ADDRESS             0xfffff000
+
 // MSR EFER bits
 // reference
 #define IA32_MSR_EFER_SYSCALL                  (1 << 0)
 #define IA32_MSR_EFER_NX                               (1 << 11)
 
+// X2APIC MSRs.
+#define IA32_MSR_APIC_ID                                       0x00000802
+#define IA32_MSR_APIC_VERSION                          0x00000803
+#define IA32_MSR_APIC_TASK_PRIORITY                    0x00000808
+#define IA32_MSR_APIC_PROCESSOR_PRIORITY       0x0000080a
+#define IA32_MSR_APIC_EOI                                      0x0000080b
+#define IA32_MSR_APIC_LOGICAL_DEST                     0x0000080d
+#define IA32_MSR_APIC_SPURIOUS_INTR_VECTOR     0x0000080f
+#define IA32_MSR_APIC_ERROR_STATUS                     0x00000828
+#define IA32_MSR_APIC_INTR_COMMAND                     0x00000830
+#define IA32_MSR_APIC_LVT_TIMER                                0x00000832
+#define IA32_MSR_APIC_LVT_THERMAL_SENSOR       0x00000833
+#define IA32_MSR_APIC_LVT_PERFMON_COUNTERS     0x00000834
+#define IA32_MSR_APIC_LVT_LINT0                                0x00000835
+#define IA32_MSR_APIC_LVT_LINT1                                0x00000836
+#define IA32_MSR_APIC_LVT_ERROR                                0x00000837
+#define IA32_MSR_APIC_INITIAL_TIMER_COUNT      0x00000838
+#define IA32_MSR_APIC_CURRENT_TIMER_COUNT      0x00000839
+#define IA32_MSR_APIC_TIMER_DIVIDE_CONFIG      0x0000083e
+
 // x86_64 MSRs.
 #define IA32_MSR_STAR                                  0xc0000081
 #define IA32_MSR_LSTAR                                 0xc0000082
diff --git a/headers/private/system/safemode_defs.h 
b/headers/private/system/safemode_defs.h
index 33f1dd0..ecbeeb0 100644
--- a/headers/private/system/safemode_defs.h
+++ b/headers/private/system/safemode_defs.h
@@ -11,6 +11,7 @@
 #define B_SAFEMODE_DISABLE_IOAPIC                      "disable_ioapic"
 #define B_SAFEMODE_DISABLE_ACPI                                "disable_acpi"
 #define B_SAFEMODE_DISABLE_APIC                                "disable_apic"
+#define B_SAFEMODE_ENABLE_X2APIC                       "enable_x2apic"
 #define B_SAFEMODE_DISABLE_APM                         "disable_apm"
 #define B_SAFEMODE_DISABLE_SMP                         "disable_smp"
 #define B_SAFEMODE_DISABLE_HYPER_THREADING     "disable_hyperthreading"
diff --git a/src/system/boot/platform/bios_ia32/smp.cpp 
b/src/system/boot/platform/bios_ia32/smp.cpp
index e3abb4f..138e1cd 100644
--- a/src/system/boot/platform/bios_ia32/smp.cpp
+++ b/src/system/boot/platform/bios_ia32/smp.cpp
@@ -579,6 +579,22 @@ smp_add_safemode_menus(Menu *menu)
                item->SetType(MENU_ITEM_MARKABLE);
                item->SetData(B_SAFEMODE_DISABLE_APIC);
                item->SetHelpText("Disables using the local APIC, also disables 
SMP.");
+
+               cpuid_info info;
+               if (get_current_cpuid(&info, 1) == B_OK
+                               && (info.regs.ecx & IA32_FEATURE_EXT_X2APIC) != 
0) {
+#if 0
+                       menu->AddItem(item = new(nothrow) MenuItem("Disable 
X2APIC"));
+                       item->SetType(MENU_ITEM_MARKABLE);
+                       item->SetData(B_SAFEMODE_DISABLE_X2APIC);
+                       item->SetHelpText("Disables using X2APIC.");
+#else
+                       menu->AddItem(item = new(nothrow) MenuItem("Enable 
X2APIC"));
+                       item->SetType(MENU_ITEM_MARKABLE);
+                       item->SetData(B_SAFEMODE_ENABLE_X2APIC);
+                       item->SetHelpText("Enables using X2APIC.");
+#endif
+               }
        }
 
        if (gKernelArgs.num_cpus < 2)
diff --git a/src/system/kernel/arch/x86/apic.cpp 
b/src/system/kernel/arch/x86/apic.cpp
index 70f662c..d8a653a 100644
--- a/src/system/kernel/arch/x86/apic.cpp
+++ b/src/system/kernel/arch/x86/apic.cpp
@@ -13,18 +13,20 @@
 #include <arch/x86/msi.h>
 
 #include <debug.h>
+#include <safemode.h>
 #include <vm/vm.h>
 
 #include "timers/apic_timer.h"
 
 
 static void *sLocalAPIC = NULL;
+static bool sX2APIC = false;
 
 
 bool
 apic_available()
 {
-       return sLocalAPIC != NULL;
+       return sLocalAPIC != NULL || sX2APIC;
 }
 
 
@@ -45,14 +47,50 @@ apic_write(uint32 offset, uint32 data)
 uint32
 apic_local_id()
 {
-       return (apic_read(APIC_ID) & 0xffffffff) >> 24;
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_ID);
+       else
+               return (apic_read(APIC_ID) & 0xffffffff) >> 24;
+}
+
+
+uint32
+apic_version()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_VERSION);
+       else
+               return apic_read(APIC_VERSION);
+}
+
+
+uint32
+apic_task_priority()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_TASK_PRIORITY);
+       else
+               return apic_read(APIC_TASK_PRIORITY);
+}
+
+
+void
+apic_set_task_priority(uint32 config)
+{
+       if (sX2APIC)
+               x86_write_msr(IA32_MSR_APIC_TASK_PRIORITY, config);
+       else
+               apic_write(APIC_TASK_PRIORITY, config);
 }
 
 
 void
 apic_end_of_interrupt()
 {
-       apic_write(APIC_EOI, 0);
+       if (sX2APIC)
+               x86_write_msr(IA32_MSR_APIC_EOI, 0);
+       else
+               apic_write(APIC_EOI, 0);
 }
 
 
@@ -60,8 +98,156 @@ void
 apic_disable_local_ints()
 {
        // just clear them out completely
-       apic_write(APIC_LVT_LINT0, APIC_LVT_MASKED);
-       apic_write(APIC_LVT_LINT1, APIC_LVT_MASKED);
+       if (sX2APIC) {
+               x86_write_msr(IA32_MSR_APIC_LVT_LINT0, APIC_LVT_MASKED);
+               x86_write_msr(IA32_MSR_APIC_LVT_LINT1, APIC_LVT_MASKED);
+       } else {
+               apic_write(APIC_LVT_LINT0, APIC_LVT_MASKED);
+               apic_write(APIC_LVT_LINT1, APIC_LVT_MASKED);
+       }
+}
+
+
+uint32
+apic_spurious_intr_vector()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_SPURIOUS_INTR_VECTOR);
+       else
+               return apic_read(APIC_SPURIOUS_INTR_VECTOR);
+}
+
+
+void
+apic_set_spurious_intr_vector(uint32 config)
+{
+       if (sX2APIC)
+               x86_write_msr(IA32_MSR_APIC_SPURIOUS_INTR_VECTOR, config);
+       else
+               apic_write(APIC_SPURIOUS_INTR_VECTOR, config);
+}
+
+
+uint32
+apic_intr_command_1()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_INTR_COMMAND) & 0xffffffff;
+       else
+               return apic_read(APIC_INTR_COMMAND_1);
+}
+
+
+void
+apic_set_intr_command_1(uint32 config)
+{
+       if (sX2APIC) {
+               x86_write_msr(IA32_MSR_APIC_INTR_COMMAND,
+                       (x86_read_msr(IA32_MSR_APIC_INTR_COMMAND) & 
0xffffffff00000000LL) | config);
+       } else
+               apic_write(APIC_INTR_COMMAND_1, config);
+}
+
+
+uint32
+apic_intr_command_2()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_INTR_COMMAND) >> 32;
+       else
+               return apic_read(APIC_INTR_COMMAND_2);
+}
+
+
+void
+apic_set_intr_command_2(uint32 config)
+{
+       if (sX2APIC) {
+               x86_write_msr(IA32_MSR_APIC_INTR_COMMAND,
+                       (x86_read_msr(IA32_MSR_APIC_INTR_COMMAND) & 0xffffffff)
+                               | ((uint64)config << 32));
+       } else
+               apic_write(APIC_INTR_COMMAND_2, config);
+}
+
+
+uint32
+apic_lvt_timer()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_LVT_TIMER);
+       else
+               return apic_read(APIC_LVT_TIMER);
+}
+
+
+void
+apic_set_lvt_timer(uint32 config)
+{
+       if (sX2APIC)
+               x86_write_msr(IA32_MSR_APIC_LVT_TIMER, config);
+       else
+               apic_write(APIC_LVT_TIMER, config);
+}
+
+
+uint32
+apic_lvt_error()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_LVT_ERROR);
+       else
+               return apic_read(APIC_LVT_ERROR);
+}
+
+
+void
+apic_set_lvt_error(uint32 config)
+{
+       if (sX2APIC)
+               x86_write_msr(IA32_MSR_APIC_LVT_ERROR, config);
+       else
+               apic_write(APIC_LVT_ERROR, config);
+}
+
+
+uint32
+apic_lvt_initial_timer_count()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_INITIAL_TIMER_COUNT);
+       else
+               return apic_read(APIC_INITIAL_TIMER_COUNT);
+}
+
+
+void
+apic_set_lvt_initial_timer_count(uint32 config)
+{
+       if (sX2APIC)
+               x86_write_msr(IA32_MSR_APIC_INITIAL_TIMER_COUNT, config);
+       else
+               apic_write(APIC_INITIAL_TIMER_COUNT, config);
+}
+
+
+uint32
+apic_lvt_timer_divide_config()
+{
+       if (sX2APIC)
+               return x86_read_msr(IA32_MSR_APIC_TIMER_DIVIDE_CONFIG);
+       else
+               return apic_read(APIC_TIMER_DIVIDE_CONFIG);
+}
+
+
+void
+apic_set_lvt_timer_divide_config(uint32 config)
+{
+       if (sX2APIC)
+               x86_write_msr(IA32_MSR_APIC_TIMER_DIVIDE_CONFIG, config);
+       else
+               apic_write(APIC_TIMER_DIVIDE_CONFIG, config);
 }
 
 
@@ -71,6 +257,35 @@ apic_init(kernel_args *args)
        if (args->arch_args.apic == NULL)
                return B_NO_INIT;
 
+       if (x86_check_feature(IA32_FEATURE_EXT_X2APIC, FEATURE_EXT)) {
+               dprintf("found x2apic\n");
+#if 0
+               if (!get_safemode_boolean(B_SAFEMODE_DISABLE_X2APIC, false)) {
+                       uint64 apic_base = x86_read_msr(IA32_MSR_APIC_BASE);
+                       if ((apic_base & IA32_MSR_APIC_BASE_X2APIC) == 0) {
+                               x86_write_msr(IA32_MSR_APIC_BASE, apic_base
+                                       | IA32_MSR_APIC_BASE_X2APIC);
+                       }
+                       sX2APIC = true;
+                       return B_OK;
+               }
+
+               dprintf("x2apic disabled per safemode setting\n");
+#else
+               if (get_safemode_boolean(B_SAFEMODE_ENABLE_X2APIC, false)) {
+                       uint64 apic_base = x86_read_msr(IA32_MSR_APIC_BASE);
+                       if ((apic_base & IA32_MSR_APIC_BASE_X2APIC) == 0) {
+                               x86_write_msr(IA32_MSR_APIC_BASE, apic_base
+                                       | IA32_MSR_APIC_BASE_X2APIC);
+                       }
+                       sX2APIC = true;
+
+                       dprintf("x2apic enabled per safemode setting\n");
+                       return B_OK;
+               }
+#endif
+       }
+
        sLocalAPIC = args->arch_args.apic;
        dprintf("mapping local apic at %p\n", sLocalAPIC);
        if (vm_map_physical_memory(B_SYSTEM_TEAM, "local apic", &sLocalAPIC,
@@ -89,13 +304,12 @@ status_t
 apic_per_cpu_init(kernel_args *args, int32 cpu)
 {
        dprintf("setting up apic for CPU %" B_PRId32 ": apic id %" B_PRIu32 ", "
-               "version %" B_PRIu32 "\n", cpu, apic_local_id(),
-               apic_read(APIC_VERSION));
+               "version %" B_PRIu32 "\n", cpu, apic_local_id(), 
apic_version());
 
        /* set spurious interrupt vector to 0xff */
-       uint32 config = apic_read(APIC_SPURIOUS_INTR_VECTOR) & 0xffffff00;
+       uint32 config = apic_spurious_intr_vector() & 0xffffff00;
        config |= APIC_ENABLE | 0xff;
-       apic_write(APIC_SPURIOUS_INTR_VECTOR, config);
+       apic_set_spurious_intr_vector(config);
 
        // don't touch the LINT0/1 configuration in virtual wire mode
        // ToDo: implement support for other modes...
@@ -130,14 +344,14 @@ apic_per_cpu_init(kernel_args *args, int32 cpu)
        apic_timer_per_cpu_init(args, cpu);
 
        /* setup error vector to 0xfe */
-       config = (apic_read(APIC_LVT_ERROR) & 0xffffff00) | 0xfe;
-       apic_write(APIC_LVT_ERROR, config);
+       config = (apic_lvt_error() & 0xffffff00) | 0xfe;
+       apic_set_lvt_error(config);
 
        /* accept all interrupts */
-       config = apic_read(APIC_TASK_PRIORITY) & 0xffffff00;
-       apic_write(APIC_TASK_PRIORITY, config);
+       config = apic_task_priority() & 0xffffff00;
+       apic_set_task_priority(config);
 
-       config = apic_read(APIC_SPURIOUS_INTR_VECTOR);
+       config = apic_spurious_intr_vector();
        apic_end_of_interrupt();
 
        return B_OK;
diff --git a/src/system/kernel/arch/x86/arch_smp.cpp 
b/src/system/kernel/arch/x86/arch_smp.cpp
index b1aedd8..8c2bc75 100644
--- a/src/system/kernel/arch/x86/arch_smp.cpp
+++ b/src/system/kernel/arch/x86/arch_smp.cpp
@@ -121,8 +121,8 @@ arch_smp_send_broadcast_ici(void)
        uint32 config;
        cpu_status state = disable_interrupts();
 
-       config = apic_read(APIC_INTR_COMMAND_1) & APIC_INTR_COMMAND_1_MASK;
-       apic_write(APIC_INTR_COMMAND_1, config | 0xfd | APIC_DELIVERY_MODE_FIXED
+       config = apic_intr_command_1() & APIC_INTR_COMMAND_1_MASK;
+       apic_set_intr_command_1(config | 0xfd | APIC_DELIVERY_MODE_FIXED
                | APIC_INTR_COMMAND_1_ASSERT
                | APIC_INTR_COMMAND_1_DEST_MODE_PHYSICAL
                | APIC_INTR_COMMAND_1_DEST_ALL_BUT_SELF);
@@ -140,18 +140,18 @@ arch_smp_send_ici(int32 target_cpu)
 
        state = disable_interrupts();
 
-       config = apic_read(APIC_INTR_COMMAND_2) & APIC_INTR_COMMAND_2_MASK;
-       apic_write(APIC_INTR_COMMAND_2, config | sCPUAPICIds[target_cpu] << 24);
+       config = apic_intr_command_2() & APIC_INTR_COMMAND_2_MASK;
+       apic_set_intr_command_2(config | sCPUAPICIds[target_cpu] << 24);
 
-       config = apic_read(APIC_INTR_COMMAND_1) & APIC_INTR_COMMAND_1_MASK;
-       apic_write(APIC_INTR_COMMAND_1, config | 0xfd | APIC_DELIVERY_MODE_FIXED
+       config = apic_intr_command_1() & APIC_INTR_COMMAND_1_MASK;
+       apic_set_intr_command_1(config | 0xfd | APIC_DELIVERY_MODE_FIXED
                | APIC_INTR_COMMAND_1_ASSERT
                | APIC_INTR_COMMAND_1_DEST_MODE_PHYSICAL
                | APIC_INTR_COMMAND_1_DEST_FIELD);
 
        timeout = 100000000;
        // wait for message to be sent
-       while ((apic_read(APIC_INTR_COMMAND_1) & APIC_DELIVERY_STATUS) != 0 && 
--timeout != 0)
+       while ((apic_intr_command_1() & APIC_DELIVERY_STATUS) != 0 && --timeout 
!= 0)
                asm volatile ("pause;");
 
        if (timeout == 0)
diff --git a/src/system/kernel/arch/x86/timers/x86_apic.cpp 
b/src/system/kernel/arch/x86/timers/x86_apic.cpp
index 7c9b3f0..3569e75 100644
--- a/src/system/kernel/arch/x86/timers/x86_apic.cpp
+++ b/src/system/kernel/arch/x86/timers/x86_apic.cpp
@@ -63,18 +63,18 @@ apic_timer_set_hardware_timer(bigtime_t relativeTimeout)
 
        cpu_status state = disable_interrupts();
 
-       uint32 config = apic_read(APIC_LVT_TIMER) | APIC_LVT_MASKED; // mask 
the timer
-       apic_write(APIC_LVT_TIMER, config);
+       uint32 config = apic_lvt_timer() | APIC_LVT_MASKED; // mask the timer
+       apic_set_lvt_timer(config);
 
-       apic_write(APIC_INITIAL_TIMER_COUNT, 0); // zero out the timer
+       apic_set_lvt_initial_timer_count(0); // zero out the timer
 
-       config = apic_read(APIC_LVT_TIMER) & ~APIC_LVT_MASKED; // unmask the 
timer
-       apic_write(APIC_LVT_TIMER, config);
+       config = apic_lvt_timer() & ~APIC_LVT_MASKED; // unmask the timer
+       apic_set_lvt_timer(config);
 
        //TRACE_TIMER(("arch_smp_set_apic_timer: config 0x%lx, timeout %Ld, 
tics/sec %lu, tics %lu\n",
        //      config, relativeTimeout, sApicTicsPerSec, ticks));
 
-       apic_write(APIC_INITIAL_TIMER_COUNT, ticks); // start it up
+       apic_set_lvt_initial_timer_count(ticks); // start it up
 
        restore_interrupts(state);
 
@@ -87,11 +87,11 @@ apic_timer_clear_hardware_timer()
 {
        cpu_status state = disable_interrupts();
 
-       uint32 config = apic_read(APIC_LVT_TIMER) | APIC_LVT_MASKED;
+       uint32 config = apic_lvt_timer() | APIC_LVT_MASKED;
                // mask the timer
-       apic_write(APIC_LVT_TIMER, config);
+       apic_set_lvt_timer(config);
 
-       apic_write(APIC_INITIAL_TIMER_COUNT, 0); // zero out the timer
+       apic_set_lvt_initial_timer_count(0); // zero out the timer
 
        restore_interrupts(state);
        return B_OK;
@@ -118,14 +118,14 @@ status_t
 apic_timer_per_cpu_init(struct kernel_args *args, int32 cpu)
 {
        /* setup timer */
-       uint32 config = apic_read(APIC_LVT_TIMER) & APIC_LVT_TIMER_MASK;
+       uint32 config = apic_lvt_timer() & APIC_LVT_TIMER_MASK;
        config |= 0xfb | APIC_LVT_MASKED; // vector 0xfb, timer masked
-       apic_write(APIC_LVT_TIMER, config);
+       apic_set_lvt_timer(config);
 
-       apic_write(APIC_INITIAL_TIMER_COUNT, 0); // zero out the clock
+       apic_set_lvt_initial_timer_count(0); // zero out the clock
 
-       config = apic_read(APIC_TIMER_DIVIDE_CONFIG) & 0xfffffff0;
+       config = apic_lvt_timer_divide_config() & 0xfffffff0;
        config |= APIC_TIMER_DIVIDE_CONFIG_1; // clock division by 1
-       apic_write(APIC_TIMER_DIVIDE_CONFIG, config);
+       apic_set_lvt_timer_divide_config(config);
        return B_OK;
 }


Other related posts:

  • » [haiku-commits] haiku: hrev45991 - src/system/kernel/arch/x86 headers/private/kernel/arch/x86 src/system/kernel/arch/x86/timers src/system/boot/platform/bios_ia32 - korli