21#include "pedigree/kernel/LockGuard.h"
22#include "pedigree/kernel/Log.h"
23#include "pedigree/kernel/machine/HidInputManager.h"
24#include "pedigree/kernel/machine/InputManager.h"
25#include "pedigree/kernel/machine/KeymapManager.h"
26#include "pedigree/kernel/process/Thread.h"
27#include "pedigree/kernel/processor/Processor.h"
28#include "pedigree/kernel/processor/ProcessorInformation.h"
29#include "pedigree/kernel/utilities/new"
31#include "Ps2Controller.h"
34#if TRACK_PAGE_ALLOCATIONS
35#include "pedigree/kernel/debugger/commands/AllocationCommand.h"
38#include "pedigree/kernel/core/SlamAllocator.h"
39#include "pedigree/kernel/debugger/commands/SlamCommand.h"
45extern void toggleTracingAllocations();
49 : m_pPs2Controller(controller),
53 m_LedCommandState(LedIdle),
59X86Keyboard::~X86Keyboard() {
70 NOTICE(
"X86Keyboard: 'enable stream' response: " <<
Hex << result);
79 ERROR(
"Keyboard::getChar() should not be called outside debug mode");
95 "Keyboard::getCharNonBlock should not be called outside debug "
105bool X86Keyboard::getDebugState() {
122 if (key & Keyboard::Special) {
123 char a = key & 0xFF, b = (key >> 8) & 0xFF, c = (key >> 16) & 0xFF, d = (key >> 24) & 0xFF;
125 if (a ==
'u' && b ==
'p')
128 if (a ==
'd' && b ==
'o' && c ==
'w' && d ==
'n')
131 if (a ==
'p' && b ==
'g' && c ==
'u' && d ==
'p')
134 if (a ==
'p' && b ==
'g' && c ==
'd' && d ==
'n')
138 if ((key & Keyboard::Special) || ((key & 0xFFFFFFFF) > 0x7f))
140 return static_cast<char>(key & 0x7f);
149 updateLedState(state,
false);
152void X86Keyboard::updateLedState(
char state,
bool toggle) {
155 if (m_LedCommandState == LedIdle) {
156 m_LedCommandState = LedCommandAck;
162void X86Keyboard::handleLedResponse(uint8_t response) {
166 if (m_LedCommandState == LedIdle) {
170 if (response == 0xFE) {
171 if (m_LedRetries++ == 3) {
172 m_LedCommandState = LedIdle;
173 ERROR(
"X86Keyboard: LED command retry limit reached");
181 if (m_LedCommandState == LedCommandAck) {
183 m_LedCommandState = LedDataAck;
186 m_LedCommandState = LedCommandAck;
189 m_LedCommandState = LedIdle;
193void X86Keyboard::startReaderThread() {
195 FATAL(
"X86Keyboard reader started more than once.");
199 Thread* pThread =
new Thread(pProcess, readerThreadTrampoline,
this);
200 pThread->setName(
"X86 keyboard reader");
207void X86Keyboard::stopReaderThread() {
211int X86Keyboard::readerThreadTrampoline(
void* param) {
213 instance->readerThread();
217void X86Keyboard::readerThread() {
227 if (scancode == 0xFA || scancode == 0xFE) {
228 handleLedResponse(scancode);
234#if CRIPPLINGLY_VIGILANT
235 if (scancode == 0x43)
236 SlamAllocator::instance().setVigilance(
true);
237 if (scancode == 0x44)
238 SlamAllocator::instance().setVigilance(
false);
240 if (scancode == 0x57)
243 WARNING(
"F11: Toggling allocation tracing.");
244 toggleTracingAllocations();
246#if TRACK_PAGE_ALLOCATIONS
247 NOTICE(
"F11: Triggering allocation checkpoint.");
248 g_AllocationCommand.checkpoint();
250 NOTICE(
"F11: Cleaning SLAM.");
251 g_SlamCommand.clean();
256 if (scancode == 0x58)
258 FATAL(
"User-induced breakpoint.");
263 if (scancode & 0x80) {
264 uint8_t code = scancode & ~0x80;
266 DEBUG_LOG(
"X86Keyboard: Caps Lock toggled");
268 }
else if (code == 0x45) {
269 DEBUG_LOG(
"X86Keyboard: Num Lock toggled");
271 }
else if (code == 0x46) {
272 DEBUG_LOG(
"X86Keyboard: Scroll Lock toggled");
283 ERROR(
"X86Keyboard: failed to translate scancode " <<
Hex << scancode);
@ NumLock
Number Lock LED.
@ ScrollLock
Scroll Lock LED.
static KeymapManager & instance()
Singleton design.
uint8_t convertPc102ScancodeToHidKeycode(uint8_t scancode, EscapeState &escape)
Converts a pc102 scancode into a HID keycode.
uint64_t resolveHidKeycode(uint8_t keyCode)
static ProcessorInformation & information()
uint8_t readByte()
Reads a single byte from the PS/2 controller by polling.
void writeFirstPort(uint8_t byte)
Send a byte to the first port, dropping it if the controller times out.
bool getDebugState() const
Gets the debug state.
bool readFirstPort(uint8_t &byte, bool block=true)
Reads a single byte from the first port.
EXPORTED_PUBLIC void setIrqEnable(bool firstEnabled, bool secondEnabled)
Enables/disables IRQs for the first or second ports.
void setDebugState(bool debugState)
Selects trap-safe polling without changing controller IRQ state.
@ Continue
No unwind necessary, carry on as normal.
UnwindType getUnwindState()
KeymapManager::EscapeState m_Escape
The current escape state.
char m_LedState
Current LED state.
Ps2Controller * m_pPs2Controller
Parent PS/2 controller.
virtual char getLedState()
OwnedThread m_ReaderThread
The controller buffer may block this worker until teardown wakes it.
virtual void setDebugState(bool enableDebugState)
virtual void initialise()
Initialises the device.
virtual char getCharNonBlock()
virtual void setLedState(char state)
char scancodeToAscii(uint8_t scancode)
Converts a scancode into an ASCII character (for use in debug state)