The Pedigree Project 0.1
Pit.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "Pit.h"
21#include "pedigree/kernel/Log.h"
22#include "pedigree/kernel/compiler.h"
23#include "pedigree/kernel/machine/IrqManager.h"
24#include "pedigree/kernel/machine/Machine.h"
25#include "pedigree/kernel/machine/SchedulerTimerDispatchCleanup.h"
26#include "pedigree/kernel/machine/SchedulerTimerHandler.h"
27#include "pedigree/kernel/processor/Processor.h"
28#include "pedigree/kernel/processor/types.h"
29
31#ifdef BOCHS
32#define PIT_FREQUENCY 10
33#else
34#define PIT_FREQUENCY 100
35#endif
36
38
39uint64_t Pit::nominalQuantumNs() const {
40 return uint64_t(1000000000) / PIT_FREQUENCY;
41}
42
44 return m_Handler.publish(0, handler);
45}
46
50
52 // Allocate the PIT I/O range
53 if (m_IoPort.allocate(0x40, 4) == false)
54 return false;
55
56 // Allocate the IRQ
57 IrqManager& irqManager = *Machine::instance().getIrqManager();
58 m_IrqId = irqManager.registerSchedulerIrqHandler(0, this, IrqPolicy::edgeHard());
59 if (m_IrqId == 0)
60 return false;
61
62 // Set the PIT frequency
63 // The value we send to the PIT is the value to divide it's input clock
64 // (1193180 Hz) by, to get our required frequency. Important to note is
65 // that the divisor must be small enough to fit into 16-bits.
66 size_t divisor = 1193180 / PIT_FREQUENCY;
67
68 // Send the command byte.
69 m_IoPort.write8(0x36, 3);
70
71 // Divisor has to be sent byte-wise, so split here into upper/lower bytes.
72 uint8_t l = divisor & 0xFF;
73 uint8_t h = (divisor >> 8) & 0xFF;
74
75 // Send the frequency divisor.
76 m_IoPort.write8(l, 0);
77 m_IoPort.write8(h, 0);
78
79 return true;
80}
82 // TODO: Reset the PIT frequency
83
84 // Free the IRQ
85 if (m_IrqId != 0) {
86 IrqManager& irqManager = *Machine::instance().getIrqManager();
87 if (!irqManager.unregisterSchedulerIrqHandler(m_IrqId, this)) {
88 FATAL("PIT teardown could not remove its direct IRQ route");
89 }
90 m_IrqId = 0;
91 }
92
93 // Free the PIT I/O range
94 m_IoPort.free();
95
96 // Source teardown does not confer ownership of the scheduler callback.
97 // Its exact owner remains responsible for unpublishing it.
98}
99
100Pit::Pit() : m_IoPort("PIT"), m_IrqId(0), m_Handler() {}
101
102void Pit::schedulerIrq(irq_id_t number, InterruptState& state) {
104 if (LIKELY(m_Handler.beginDispatch(0, dispatch))) {
105 SchedulerTimerDispatchCleanup dispatchCleanup(dispatch);
106 ExecutionContextGuard schedulerContext(ExecutionContext::SchedulerIrq);
107 dispatch.handler()->timer(nominalQuantumNs(), state);
108 }
109
110 // Processor::information().getScheduler().checkEventState(state.getStackPointer());
111}
void free()
Definition IoPort.cc:42
bool allocate(io_port_t ioPort, size_t size)
Definition IoPort.cc:29
virtual void write8(uint8_t value, size_t offset=0)
virtual irq_id_t registerSchedulerIrqHandler(uint8_t irq, SchedulerIrqHandler *handler, const IrqPolicy &policy)
Definition IrqManager.cc:41
virtual bool unregisterSchedulerIrqHandler(irq_id_t Id, SchedulerIrqHandler *handler)
Definition IrqManager.cc:45
Definition Pit.h:38
virtual bool removeHandler(SchedulerTimerHandler *handler)
Definition Pit.cc:47
virtual bool registerHandler(SchedulerTimerHandler *handler)
Definition Pit.cc:43
bool initialise() INITIALISATION_ONLY
Definition Pit.cc:51
Pit() INITIALISATION_ONLY
Definition Pit.cc:100
SchedulerTimerHandlerSlot m_Handler
Definition Pit.h:82
void uninitialise()
Definition Pit.cc:81
irq_id_t m_IrqId
Definition Pit.h:80
static Pit m_Instance
Definition Pit.h:85
IoPort m_IoPort
Definition Pit.h:78
bool beginDispatch(size_t owner, DispatchGuard &guard)
bool publish(size_t owner, SchedulerTimerHandler *handler)
bool unpublish(size_t owner, SchedulerTimerHandler *handler)
virtual void timer(uint64_t delta, InterruptState &state)=0
static bool canRemoveHandlerInCurrentContext()