[Haiku-commits] r33290 - in haiku/trunk/src/system/kernel/arch/x86: . timers
jackburton at mail.berlios.de
jackburton at mail.berlios.de
Fri Sep 25 11:50:40 CEST 2009
Author: jackburton
Date: 2009-09-25 11:50:32 +0200 (Fri, 25 Sep 2009)
New Revision: 33290
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=33290&view=rev
Added:
haiku/trunk/src/system/kernel/arch/x86/timers/x86_hpet.cpp
Removed:
haiku/trunk/src/system/kernel/arch/x86/timers/hpet.h
haiku/trunk/src/system/kernel/arch/x86/timers/x86_hpet.c
Modified:
haiku/trunk/src/system/kernel/arch/x86/Jamfile
Log:
Renamed x86_hpet.c to x86_hpet.cpp and fixed the compile errors.
Modified: haiku/trunk/src/system/kernel/arch/x86/Jamfile
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/Jamfile 2009-09-25 09:49:02 UTC (rev 33289)
+++ haiku/trunk/src/system/kernel/arch/x86/Jamfile 2009-09-25 09:50:32 UTC (rev 33290)
@@ -39,7 +39,7 @@
x86_pit.c
x86_apic.c
- x86_hpet.c
+ x86_hpet.cpp
:
$(TARGET_KERNEL_PIC_CCFLAGS)
;
Deleted: haiku/trunk/src/system/kernel/arch/x86/timers/hpet.h
Deleted: haiku/trunk/src/system/kernel/arch/x86/timers/x86_hpet.c
Added: haiku/trunk/src/system/kernel/arch/x86/timers/x86_hpet.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/timers/x86_hpet.cpp 2009-09-25 09:49:02 UTC (rev 33289)
+++ haiku/trunk/src/system/kernel/arch/x86/timers/x86_hpet.cpp 2009-09-25 09:50:32 UTC (rev 33290)
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2008, Dustin Howett, dustin.howett at gmail.com. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include <timer.h>
+#include <arch/x86/timer.h>
+#include <arch/x86/arch_hpet.h>
+
+#include <boot/kernel_args.h>
+
+#include <arch/int.h>
+#include <arch/cpu.h>
+#include <int.h>
+
+#define TRACE_HPET
+#ifdef TRACE_HPET
+ #define TRACE(x) dprintf x
+#else
+ #define TRACE(x) ;
+#endif
+
+static struct hpet_regs *sHPETRegs;
+
+static int hpet_get_prio();
+static status_t hpet_set_hardware_timer(bigtime_t relativeTimeout);
+static status_t hpet_clear_hardware_timer();
+static status_t hpet_init(struct kernel_args *args);
+
+
+struct timer_info gHPETTimer = {
+ "HPET",
+ &hpet_get_prio,
+ &hpet_set_hardware_timer,
+ &hpet_clear_hardware_timer,
+ &hpet_init
+};
+
+
+static int
+hpet_get_prio()
+{
+ return 3;
+}
+
+
+static int32
+hpet_timer_interrupt(void *arg)
+{
+ return timer_interrupt();
+}
+
+
+static status_t
+hpet_set_hardware_timer(bigtime_t relativeTimeout)
+{
+ //dprintf("disabling interrupts\n");
+
+ cpu_status state = disable_interrupts();
+
+ //dprintf("getting value\n");
+ uint64 timerValue = relativeTimeout;
+ timerValue *= 1000000000;
+ timerValue /= sHPETRegs->period;
+ //dprintf("adding hpet counter value\n");
+ timerValue += sHPETRegs->counter;
+
+ //dprintf("setting value %d, cur is %d\n", timerValue, sHPETRegs->counter);
+ sHPETRegs->timer[2].comparator = timerValue;
+
+ // Clear the interrupt (set to 0)
+ //dprintf("clearing interrupts\n");
+ sHPETRegs->timer[2].config &= (~31 << 9);
+
+ // Non-periodic mode, edge triggered
+ //dprintf("edge mode\n");
+ sHPETRegs->timer[2].config &= ~(0x8 & 0x2);
+
+ // Enable timer
+ //dprintf("enable\n");
+ sHPETRegs->timer[2].config |= 0x4;
+
+ //dprintf("reenable interrupts\n");
+ restore_interrupts(state);
+
+ return B_OK;
+}
+
+
+static status_t
+hpet_clear_hardware_timer()
+{
+ // Disable timer
+ sHPETRegs->timer[2].config &= ~0x4;
+ return B_OK;
+}
+
+
+static status_t
+hpet_set_enabled(struct hpet_regs *regs, bool enabled)
+{
+ if (enabled)
+ regs->config |= HPET_CONF_MASK_ENABLED;
+ else
+ regs->config &= ~HPET_CONF_MASK_ENABLED;
+ return B_OK;
+}
+
+
+static status_t
+hpet_set_legacy(struct hpet_regs *regs, bool enabled)
+{
+// if (!HPET_IS_LEGACY_CAPABLE(regs))
+// return B_NOT_SUPPORTED;
+
+ if (enabled)
+ regs->config |= HPET_CONF_MASK_LEGACY;
+ else
+ regs->config &= ~HPET_CONF_MASK_LEGACY;
+
+ return B_OK;
+}
+
+
+static void
+dump_timer(volatile struct hpet_timer *timer)
+{
+ dprintf(" config: 0x%lx\n", timer->config);
+ dprintf(" interrupts: 0x%lx\n", timer->interrupts);
+ dprintf(" fsb_value: 0x%lx\n", timer->fsb_value);
+ dprintf(" fsb_addr: 0x%lx\n", timer->fsb_addr);
+}
+
+
+static status_t
+hpet_init(struct kernel_args *args)
+{
+ /* hpet_acpi_probe() through a similar "scan spots" table
+ to that of smp.cpp.
+ Seems to be the most elegant solution right now. */
+ if (args->arch_args.hpet == NULL)
+ return B_ERROR;
+
+ if (sHPETRegs == NULL) {
+ sHPETRegs = (struct hpet_regs *)args->arch_args.hpet;
+ if (map_physical_memory("hpet", (void *)args->arch_args.hpet_phys,
+ B_PAGE_SIZE, B_EXACT_ADDRESS, B_KERNEL_READ_AREA |
+ B_KERNEL_WRITE_AREA, (void **)&sHPETRegs) < B_OK) {
+ // Would it be better to panic here?
+ dprintf("hpet_init: Failed to map memory for the HPET registers.");
+ return B_ERROR;
+ }
+ }
+
+ TRACE(("hpet_init: HPET is at %p. Vendor ID: %lx. Period: %ld\n",
+ sHPETRegs, HPET_GET_VENDOR_ID(sHPETRegs), sHPETRegs->period));
+
+ /* There is no hpet legacy support, so error out on init */
+ if (!HPET_IS_LEGACY_CAPABLE(sHPETRegs)) {
+ dprintf("hpet_init: HPET doesn't support legacy mode. Skipping.\n");
+ return B_ERROR;
+ }
+
+ status_t status = hpet_set_legacy(sHPETRegs, true);
+ if (status != B_OK)
+ return status;
+
+ uint32 numTimers = HPET_GET_NUM_TIMERS(sHPETRegs) + 1;
+
+ TRACE(("hpet_init: HPET does%s support legacy mode.\n",
+ HPET_IS_LEGACY_CAPABLE(sHPETRegs) ? "" : " not"));
+ TRACE(("hpet_init: HPET supports %lu timers, and is %s bits wide.\n",
+ numTimers, HPET_IS_64BIT(sHPETRegs) ? "64" : "32"));
+
+ if (numTimers < 3) {
+ dprintf("hpet_init: HPET does not have at least 3 timers. Skipping.\n");
+ return B_ERROR;
+ }
+
+ for (uint32 c = 0; c < numTimers; c++) {
+ dprintf("hpet_init: timer %lu:\n", c);
+ dump_timer(&sHPETRegs->timer[c]);
+ }
+
+ install_io_interrupt_handler(0xfb - ARCH_INTERRUPT_BASE,
+ &hpet_timer_interrupt, NULL, B_NO_LOCK_VECTOR);
+ install_io_interrupt_handler(0, &hpet_timer_interrupt, NULL,
+ B_NO_LOCK_VECTOR);
+
+ status = hpet_set_enabled(sHPETRegs, true);
+
+ return status;
+}
+
More information about the Haiku-commits
mailing list