summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-08-27 17:11:02 +0200
committerRichard Braun <rbraun@sceen.net>2017-08-27 17:11:02 +0200
commit0917f35f0e22f28d9dd78ff340df9e114e2ba45d (patch)
treeac247476fedeb3d4a9c507b2827142d4aeaff7e3
parent20aa997e8347d5b37e1b3e39f79ac0b2309b506e (diff)
x86/pit: make the PIT a potential clock source
-rw-r--r--arch/x86/machine/acpi.c4
-rw-r--r--arch/x86/machine/pit.c43
2 files changed, 40 insertions, 7 deletions
diff --git a/arch/x86/machine/acpi.c b/arch/x86/machine/acpi.c
index 77202267..4ef52e3d 100644
--- a/arch/x86/machine/acpi.c
+++ b/arch/x86/machine/acpi.c
@@ -36,6 +36,7 @@
#include <machine/ioapic.h>
#include <machine/lapic.h>
#include <machine/pic.h>
+#include <machine/pit.h>
#include <machine/types.h>
#include <vm/vm_kmem.h>
@@ -693,9 +694,10 @@ error:
* For the sake of simplicity, it has been decided to ignore legacy
* specifications such as the multiprocessor specification, and use
* ACPI only. If ACPI is unavailable, consider the APIC system to
- * be missing and fall back to using the legacy XT-PIC.
+ * be missing and fall back to using the legacy XT-PIC and PIT.
*/
pic_setup();
+ pit_setup();
return 0;
}
diff --git a/arch/x86/machine/pit.c b/arch/x86/machine/pit.c
index c31c7e0b..86513306 100644
--- a/arch/x86/machine/pit.c
+++ b/arch/x86/machine/pit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012 Richard Braun.
+ * Copyright (c) 2011-2017 Richard Braun.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,7 +17,11 @@
#include <assert.h>
+#include <kern/clock.h>
#include <kern/init.h>
+#include <kern/intr.h>
+#include <kern/log.h>
+#include <kern/macros.h>
#include <machine/io.h>
#include <machine/pit.h>
@@ -45,19 +49,46 @@
*/
#define PIT_MAX_COUNT 0xffff
-void __init
-pit_setup_free_running(void)
+/*
+ * Timer interrupt.
+ */
+#define PIT_INTR 0
+
+static int
+pit_intr(void *arg)
+{
+ (void)arg;
+
+ clock_tick_intr();
+ return 0;
+}
+
+static void __init
+pit_setup_common(uint16_t count)
{
io_write_byte(PIT_PORT_MODE, PIT_MODE_RATE_GEN | PIT_MODE_RW_LSB
| PIT_MODE_RW_MSB);
- io_write_byte(PIT_PORT_COUNTER0, PIT_MAX_COUNT & 0xff);
- io_write_byte(PIT_PORT_COUNTER0, PIT_MAX_COUNT >> 8);
+ io_write_byte(PIT_PORT_COUNTER0, count & 0xff);
+ io_write_byte(PIT_PORT_COUNTER0, count >> 8);
+}
+
+void __init
+pit_setup_free_running(void)
+{
+ pit_setup_common(PIT_MAX_COUNT);
}
void __init
pit_setup(void)
{
- /* TODO Implement */
+ int error;
+
+ pit_setup_common(DIV_CEIL(PIT_FREQ, CLOCK_FREQ));
+ error = intr_register(PIT_INTR, pit_intr, NULL);
+
+ if (error) {
+ log_err("pit: unable to register interrupt handler");
+ }
}
static unsigned int