diff options
author | Richard Braun <rbraun@sceen.net> | 2017-08-27 17:11:02 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-08-27 17:11:02 +0200 |
commit | 0917f35f0e22f28d9dd78ff340df9e114e2ba45d (patch) | |
tree | ac247476fedeb3d4a9c507b2827142d4aeaff7e3 | |
parent | 20aa997e8347d5b37e1b3e39f79ac0b2309b506e (diff) |
x86/pit: make the PIT a potential clock source
-rw-r--r-- | arch/x86/machine/acpi.c | 4 | ||||
-rw-r--r-- | arch/x86/machine/pit.c | 43 |
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 |