Handout
This commit is contained in:
61
kernel/arch/cmos.cc
Normal file
61
kernel/arch/cmos.cc
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "cmos.h"
|
||||
|
||||
#include "core_interrupt.h"
|
||||
#include "ioport.h"
|
||||
|
||||
namespace CMOS {
|
||||
static constexpr IOPort address(0x70);
|
||||
static constexpr IOPort data(0x71);
|
||||
|
||||
namespace NMI {
|
||||
static constexpr uint8_t mask = 0x80;
|
||||
// Cache NMI to speed things up
|
||||
static bool disabled = false;
|
||||
|
||||
void enable() {
|
||||
bool status = Core::Interrupt::disable();
|
||||
uint8_t value = address.inb();
|
||||
value &= ~mask;
|
||||
address.outb(value);
|
||||
Core::Interrupt::restore(status);
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
void disable() {
|
||||
bool status = Core::Interrupt::disable();
|
||||
uint8_t value = address.inb();
|
||||
value |= mask;
|
||||
address.outb(value);
|
||||
Core::Interrupt::restore(status);
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
bool isEnabled() {
|
||||
disabled = (address.inb() & mask) != 0;
|
||||
return !disabled;
|
||||
}
|
||||
} // namespace NMI
|
||||
|
||||
static void setAddress(enum Register reg) {
|
||||
uint8_t value = static_cast<uint8_t>(reg);
|
||||
// The highest bit controls the Non Maskable Interrupt
|
||||
// so we don't want to accidentally change it.
|
||||
if (NMI::disabled) {
|
||||
value |= NMI::mask;
|
||||
} else {
|
||||
value &= ~NMI::mask;
|
||||
}
|
||||
address.outb(value);
|
||||
}
|
||||
|
||||
uint8_t read(enum Register reg) {
|
||||
setAddress(reg);
|
||||
return data.inb();
|
||||
}
|
||||
|
||||
void write(enum Register reg, uint8_t value) {
|
||||
setAddress(reg);
|
||||
data.outb(value);
|
||||
}
|
||||
|
||||
} // namespace CMOS
|
||||
Reference in New Issue
Block a user