[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