The Pedigree Project  0.1
Decrementer.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 "Decrementer.h"
21 #include "../core/processor/ppc32/InterruptManager.h"
22 #include "pedigree/kernel/Log.h"
23 #include "pedigree/kernel/compiler.h"
24 #include "pedigree/kernel/machine/Machine.h"
25 #include "pedigree/kernel/machine/openfirmware/Device.h"
26 #include "pedigree/kernel/machine/openfirmware/OpenFirmware.h"
27 #include "pedigree/kernel/processor/InterruptManager.h"
28 #include "pedigree/kernel/processor/Processor.h"
29 
31 
32 bool Decrementer::registerHandler(TimerHandler *handler)
33 {
34  if (UNLIKELY(handler == 0 && m_Handler != 0))
35  return false;
36 
37  m_Handler = handler;
38  return true;
39 }
40 
42 {
43  // Allocate the Interrupt.
44  if (InterruptManager::instance().registerInterruptHandler(8, this) == false)
45  return false;
46 
47  // Find the frequency of the decrementer.
48  OFDevice chosen(OpenFirmware::instance().findDevice("/chosen"));
49  OFDevice cpu(chosen.getProperty("cpu"));
50  m_Frequency =
51  reinterpret_cast<uint32_t>(cpu.getProperty("timebase-frequency"));
52  if (static_cast<int32_t>(m_Frequency) <= 0)
53  {
54  WARNING("Cpu::timebase-frequency property not available!");
55  m_Frequency = 0x100000;
56  }
57 
58  // Set up the decrementer to fire in DECREMENTER_PERIOD milliseconds.
59  uint32_t n = (DECREMENTER_PERIOD * m_Frequency) / 1000;
60  asm volatile("mtdec %0" : : "r"(n));
61 
62  return true;
63 }
65 {
66 }
67 
69 {
70 }
71 
72 uint32_t numFired = 0;
73 
74 void Decrementer::interrupt(size_t interruptNumber, InterruptState &state)
75 {
76  // Set up the decrementer to fire in DECREMENTER_PERIOD milliseconds.
77  uint32_t n = (DECREMENTER_PERIOD * m_Frequency) / 1000;
78  asm volatile("mtdec %0" : : "r"(n));
79 
80  // numFired++;
81  // if (numFired == 300)
82  // {
83  // Processor::breakpoint();
84  // }
85 
86  // TODO: Delta is wrong
87  if (LIKELY(m_Handler != 0))
88  m_Handler->timer(DECREMENTER_PERIOD, state);
89 }
uint32_t m_Frequency
Definition: Decrementer.h:71
static OpenFirmware & instance()
Definition: OpenFirmware.h:45
Decrementer() INITIALISATION_ONLY
Definition: Decrementer.cc:68
#define WARNING(text)
Definition: Log.h:78
static Decrementer m_Instance
Definition: Decrementer.h:74
virtual void timer(uint64_t delta, InterruptState &state)=0
void uninitialise()
Definition: Decrementer.cc:64
bool initialise() INITIALISATION_ONLY
Definition: Decrementer.cc:41
static InterruptManager & instance()
TimerHandler * m_Handler
Definition: Decrementer.h:68
virtual void interrupt(size_t interruptNumber, InterruptState &state)
Definition: Decrementer.cc:74