21 #include "pedigree/kernel/LockGuard.h" 22 #include "pedigree/kernel/Log.h" 23 #include "pedigree/kernel/compiler.h" 24 #include "pedigree/kernel/core/SlamAllocator.h" 25 #include "pedigree/kernel/machine/IrqManager.h" 26 #include "pedigree/kernel/machine/Machine.h" 27 #include "pedigree/kernel/machine/Serial.h" 28 #include "pedigree/kernel/machine/TimerHandler.h" 29 #include "pedigree/kernel/process/Process.h" 30 #include "pedigree/kernel/process/Scheduler.h" 31 #include "pedigree/kernel/process/Thread.h" 32 #include "pedigree/kernel/processor/Processor.h" 33 #include "pedigree/kernel/processor/ProcessorInformation.h" 34 #include "pedigree/kernel/time/Time.h" 35 #include "pedigree/kernel/utilities/Iterator.h" 36 #include "pedigree/kernel/utilities/StaticString.h" 37 #include "pedigree/kernel/utilities/utility.h" 45 #define INITIAL_RTC_HZ 64 47 #define INITIAL_RTC_HZ 512 49 #define BCD_TO_BIN8(x) (((((x) &0xF0) >> 4) * 10) + ((x) &0x0F)) 50 #define BIN_TO_BCD8(x) ((((x) / 10) * 16) + ((x) % 10)) 53 {4, 0x0e, {250000000ULL, 250000000ULL}},
54 {8, 0x0d, {125000000ULL, 125000000ULL}},
55 {16, 0x0c, {62500000ULL, 62500000ULL}},
56 {32, 0x0b, {31250000ULL, 31250000ULL}},
57 {64, 0x0a, {15625000ULL, 15625000ULL}},
58 {128, 0x09, {7812500ULL, 7812500ULL}},
59 {256, 0x08, {3906250ULL, 3906250ULL}},
60 {512, 0x07, {1953125ULL, 1953125ULL}},
61 {1024, 0x06, {976562ULL, 976563ULL}},
62 {2048, 0x05, {488281ULL, 488281ULL}},
63 {4096, 0x04, {244140ULL, 244141ULL}},
64 {8192, 0x03, {122070ULL, 122070ULL}},
67 static uint8_t daysPerMonth[] = {31, 28, 31, 30, 31, 30,
68 31, 31, 30, 31, 30, 31};
78 uint64_t delta = alarmSecs * Time::Multiplier::Second;
79 delta += alarmUsecs * Time::Multiplier::Microsecond;
92 if ((*it)->m_pEvent == pEvent)
114 if ((*it)->m_pEvent == pEvent)
119 size_t alarmEndTime = (*it)->m_Time;
122 if (alarmEndTime < currTime)
127 size_t diff = alarmEndTime - currTime;
128 ret = (diff / 1000) + 1;
146 for (nHandler = 0; nHandler < MAX_TIMER_HANDLERS; nHandler++)
162 for (nHandler = 0; nHandler < MAX_TIMER_HANDLERS; nHandler++)
188 static size_t monthnumbers[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
192 dayOfWeek += monthnumbers[
m_Month - 1];
193 dayOfWeek += ((
m_Year % 100) + ((
m_Year % 100) / 4)) % 7;
194 dayOfWeek -= ((
m_Year / 100) % 4 - 3) * 2;
224 asm volatile(
"rdtsc" :
"=d"(edx),
"=a"(eax)::
"memory");
227 tsc = (
static_cast<uint64_t
>(edx) << 32UL) | eax;
236 NOTICE(
"Rtc::initialise1");
272 uint8_t rateBits = 0x06;
273 for (
size_t i = 0; i < 12; i++)
282 uint8_t tmp =
read(0x0A);
283 write(0x0A, (tmp & 0xF0) | rateBits);
290 NOTICE(
"Rtc::initialise2");
293 IrqManager &irqManager = *Machine::instance().getIrqManager();
299 uint8_t statusb =
read(0x0B);
300 write(0x0B, statusb | 0x40);
311 asm volatile(
"rdtsc" :
"=d"(edx),
"=a"(eax)::
"memory");
312 tsc0 = (
static_cast<uint64_t
>(edx) << 32UL) | eax;
317 for (
size_t i = 0; i < 50; ++i)
322 asm volatile(
"rdtsc" :
"=d"(edx),
"=a"(eax)::
"memory");
323 tsc1 = (
static_cast<uint64_t
>(edx) << 32UL) | eax;
325 uint64_t diff = tsc1 - tsc0;
392 uint8_t statusb =
read(0x0B);
393 write(0x0B, statusb & ~0x40);
398 IrqManager &irqManager = *Machine::instance().getIrqManager();
413 extern size_t g_AllocedPages;
415 bool Rtc::irq(irq_id_t number, InterruptState &state)
417 static size_t index = 0;
420 index = (index == 0) ? 1 : 0;
437 bool bDispatched =
false;
460 Machine::instance().getIrqManager()->
tick();
468 #ifdef MEMORY_LOGGING_ENABLED 471 memoryLogStr +=
"Heap: ";
472 memoryLogStr += SlamAllocator::instance().heapPageCount() * 4;
473 memoryLogStr +=
"K\tPages: ";
474 memoryLogStr += (g_AllocedPages * 4096) / 1024;
475 memoryLogStr +=
"K\t Free: ";
477 memoryLogStr +=
"K\n";
479 pSerial->write(memoryLogStr);
488 ssize_t virtK = (pProcess->getVirtualPageCount() * 0x1000) / 1024;
489 ssize_t physK = (pProcess->getPhysicalPageCount() * 0x1000) / 1024;
490 ssize_t shrK = (pProcess->getSharedPageCount() * 0x1000) / 1024;
492 processListStr.append(
"\tProcess #");
493 processListStr.append(pProcess->
getId(), 10);
494 processListStr.append(
" '");
496 processListStr.append(
"' V=");
497 processListStr.append(virtK, 10);
498 processListStr.append(
"K P=");
499 processListStr.append(physK, 10);
500 processListStr.append(
"K S=");
501 processListStr.append(shrK, 10);
502 processListStr.append(
"K Heap=");
503 processListStr.append(heapK, 10);
504 processListStr.append(
"K\n");
505 pSerial->write(processListStr);
525 bool isLeap = ((
m_Year % 4) == 0) & (((
m_Year % 100) != 0) |
530 ((
m_Month != 2) || isLeap ==
false)) ||
551 for (
size_t nHandler = 0; nHandler < MAX_TIMER_HANDLERS; nHandler++)
568 if (index <= 9 || index == 50)
virtual void addAlarm(class Event *pEvent, size_t alarmSecs, size_t alarmUsecs=0)
void write(uint8_t index, uint8_t value)
uint64_t m_TscTicksPerNanosecond
virtual Serial * getSerial(size_t n)=0
void waitForUpdateCompletion(uint8_t index)
static bool getInterrupts()
ssize_t getHeapUsage() const
virtual uint8_t getHour()
virtual uint8_t getDayOfWeek()
virtual uint64_t getTickCount()
virtual void synchronise(bool tohw=false)
virtual uint8_t read8(size_t offset=0)
static ProcessorInformation & information()
void enableRtcUpdates(bool enable)
bool initialise1() INITIALISATION_ONLY
void setIndex(uint8_t index)
bool sendEvent(Event *pEvent)
static periodicIrqInfo_t periodicIrqInfo[12]
virtual uint64_t getNanosecond()
virtual uint8_t getMinute()
::Iterator< T, node_t > Iterator
virtual uint8_t getDayOfMonth()
virtual void unregisterHandler(irq_id_t Id, IrqHandler *handler)=0
static Scheduler & instance()
bool allocate(io_port_t ioPort, size_t size)
static void haltUntilInterrupt()
Process * getProcess(size_t n)
virtual void timer(uint64_t delta, InterruptState &state)=0
static void setInterrupts(bool bEnable)
size_t m_PeriodicIrqInfoIndex
virtual bool irq(irq_id_t number, InterruptState &state)
virtual uint8_t getSecond()
virtual uint8_t getMonth()
TimerHandler * m_Handlers[MAX_TIMER_HANDLERS]
virtual irq_id_t registerIsaIrqHandler(uint8_t irq, IrqHandler *handler, bool bEdge=false)=0
LargeStaticString & description()
Rtc() INITIALISATION_ONLY
bool initialise2() INITIALISATION_ONLY
virtual void removeAlarm(class Event *pEvent)
uint8_t read(uint8_t index)
virtual void write8(uint8_t value, size_t offset=0)
virtual uint64_t getTickCountNano()