VirtualBox

source: vbox/trunk/src/VBox/Devices/Input/DevPS2.h@ 88037

Last change on this file since 88037 was 83443, checked in by vboxsync, 5 years ago

DevPS2: Improved logging, gave queues human-readable names.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.8 KB
Line 
1/* $Id: DevPS2.h 83443 2020-03-26 16:49:44Z vboxsync $ */
2/** @file
3 * PS/2 devices - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2007-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_INCLUDED_SRC_Input_DevPS2_h
19#define VBOX_INCLUDED_SRC_Input_DevPS2_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24/** @defgroup grp_devps2 PS/2 Device
25 * @{
26 */
27
28/** Pointer to the shared keyboard (PS/2) controller / device state. */
29typedef struct KBDSTATE *PKBDSTATE;
30
31
32/** @name PS/2 Input Queue Primitive
33 * @{ */
34typedef struct PS2QHDR
35{
36 uint32_t volatile rpos;
37 uint32_t volatile wpos;
38 uint32_t volatile cUsed;
39 uint32_t uPadding;
40 const char *pszDesc;
41} PS2QHDR;
42/** Pointer to a queue header. */
43typedef PS2QHDR *PPS2QHDR;
44
45/** Define a simple PS/2 input device queue. */
46#define DEF_PS2Q_TYPE(name, size) \
47 typedef struct { \
48 PS2QHDR Hdr; \
49 uint8_t abQueue[size]; \
50 } name
51
52void PS2CmnClearQueue(PPS2QHDR pQHdr, size_t cElements);
53void PS2CmnInsertQueue(PPS2QHDR pQHdr, size_t cElements, uint8_t *pbElements, uint8_t bValue);
54int PS2CmnRemoveQueue(PPS2QHDR pQHdr, size_t cElements, uint8_t const *pbElements, uint8_t *pbValue);
55void PS2CmnR3SaveQueue(PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM, PPS2QHDR pQHdr, size_t cElements, uint8_t const *pbElements);
56int PS2CmnR3LoadQueue(PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM, PPS2QHDR pQHdr, size_t cElements, uint8_t *pbElements);
57
58#define PS2Q_CLEAR(a_pQueue) \
59 PS2CmnClearQueue(&(a_pQueue)->Hdr, RT_ELEMENTS((a_pQueue)->abQueue))
60#define PS2Q_INSERT(a_pQueue, a_bValue) \
61 PS2CmnInsertQueue(&(a_pQueue)->Hdr, RT_ELEMENTS((a_pQueue)->abQueue), (a_pQueue)->abQueue, (a_bValue))
62#define PS2Q_REMOVE(a_pQueue, a_pbValue) \
63 PS2CmnRemoveQueue(&(a_pQueue)->Hdr, RT_ELEMENTS((a_pQueue)->abQueue), (a_pQueue)->abQueue, (a_pbValue))
64#define PS2Q_SAVE(a_pHlp, a_pSSM, a_pQueue) \
65 PS2CmnR3SaveQueue((a_pHlp), (a_pSSM), &(a_pQueue)->Hdr, RT_ELEMENTS((a_pQueue)->abQueue), (a_pQueue)->abQueue)
66#define PS2Q_LOAD(a_pHlp, a_pSSM, a_pQueue) \
67 PS2CmnR3LoadQueue((a_pHlp), (a_pSSM), &(a_pQueue)->Hdr, RT_ELEMENTS((a_pQueue)->abQueue), (a_pQueue)->abQueue)
68#define PS2Q_SIZE(a_pQueue) RT_ELEMENTS((a_pQueue)->abQueue)
69#define PS2Q_COUNT(a_pQueue) ((a_pQueue)->Hdr.cUsed)
70#define PS2Q_RD_POS(a_pQueue) ((a_pQueue)->Hdr.rpos)
71#define PS2Q_WR_POS(a_pQueue) ((a_pQueue)->Hdr.wpos)
72/** @} */
73
74
75/** @defgroup grp_devps2k DevPS2K - Keyboard
76 * @{
77 */
78
79/** @name HID modifier range.
80 * @{ */
81#define HID_MODIFIER_FIRST 0xE0
82#define HID_MODIFIER_LAST 0xE8
83/** @} */
84
85/** @name USB HID additional constants
86 * @{ */
87/** The highest USB usage code reported by VirtualBox. */
88#define VBOX_USB_MAX_USAGE_CODE 0xE7
89/** The size of an array needed to store all USB usage codes */
90#define VBOX_USB_USAGE_ARRAY_SIZE (VBOX_USB_MAX_USAGE_CODE + 1)
91/** USB HID Keyboard Usage Page. */
92#define USB_HID_KB_PAGE 7
93/** USB HID Consumer Control Usage Page. */
94#define USB_HID_CC_PAGE 12
95/** @} */
96
97/* Internal keyboard queue sizes. The input queue doesn't need to be
98 * extra huge and the command queue only needs to handle a few bytes.
99 */
100#define KBD_KEY_QUEUE_SIZE 64
101#define KBD_CMD_QUEUE_SIZE 4
102
103DEF_PS2Q_TYPE(KbdKeyQ, KBD_KEY_QUEUE_SIZE);
104DEF_PS2Q_TYPE(KbdCmdQ, KBD_CMD_QUEUE_SIZE);
105
106/** Typematic state. */
107typedef enum {
108 KBD_TMS_IDLE = 0, /* No typematic key active. */
109 KBD_TMS_DELAY = 1, /* In the initial delay period. */
110 KBD_TMS_REPEAT = 2, /* Key repeating at set rate. */
111 KBD_TMS_32BIT_HACK = 0x7fffffff
112} tmatic_state_t;
113
114
115/**
116 * The shared PS/2 keyboard instance data.
117 */
118typedef struct PS2K
119{
120 /** Set if keyboard is enabled ('scans' for input). */
121 bool fScanning;
122 /** Set NumLock is on. */
123 bool fNumLockOn;
124 /** Selected scan set. */
125 uint8_t u8ScanSet;
126 /** Modifier key state. */
127 uint8_t u8Modifiers;
128 /** Currently processed command (if any). */
129 uint8_t u8CurrCmd;
130 /** Status indicator (LED) state. */
131 uint8_t u8LEDs;
132 /** Selected typematic delay/rate. */
133 uint8_t u8TypematicCfg;
134 uint8_t bAlignment1;
135 /** Usage code of current typematic key, if any. */
136 uint32_t u32TypematicKey;
137 /** Current typematic repeat state. */
138 tmatic_state_t enmTypematicState;
139 /** Buffer holding scan codes to be sent to the host. */
140 KbdKeyQ keyQ;
141 /** Command response queue (priority). */
142 KbdCmdQ cmdQ;
143 /** Currently depressed keys. */
144 uint8_t abDepressedKeys[VBOX_USB_USAGE_ARRAY_SIZE];
145 /** Typematic delay in milliseconds. */
146 uint32_t uTypematicDelay;
147 /** Typematic repeat period in milliseconds. */
148 uint32_t uTypematicRepeat;
149 /** Set if the throttle delay is currently active. */
150 bool fThrottleActive;
151 /** Set if the input rate should be throttled. */
152 bool fThrottleEnabled;
153 /** Set if the serial line is disabled on the KBC. */
154 bool fLineDisabled;
155 uint8_t abAlignment2[1];
156
157 /** Command delay timer. */
158 TMTIMERHANDLE hKbdDelayTimer;
159 /** Typematic timer. */
160 TMTIMERHANDLE hKbdTypematicTimer;
161 /** Input throttle timer. */
162 TMTIMERHANDLE hThrottleTimer;
163} PS2K;
164/** Pointer to the shared PS/2 keyboard instance data. */
165typedef PS2K *PPS2K;
166
167
168/**
169 * The PS/2 keyboard instance data for ring-3.
170 */
171typedef struct PS2KR3
172{
173 /** The device instance.
174 * @note Only for getting our bearings in interface methods. */
175 PPDMDEVINSR3 pDevIns;
176
177 /**
178 * Keyboard port - LUN#0.
179 *
180 * @implements PDMIBASE
181 * @implements PDMIKEYBOARDPORT
182 */
183 struct
184 {
185 /** The base interface for the keyboard port. */
186 PDMIBASE IBase;
187 /** The keyboard port base interface. */
188 PDMIKEYBOARDPORT IPort;
189
190 /** The base interface of the attached keyboard driver. */
191 R3PTRTYPE(PPDMIBASE) pDrvBase;
192 /** The keyboard interface of the attached keyboard driver. */
193 R3PTRTYPE(PPDMIKEYBOARDCONNECTOR) pDrv;
194 } Keyboard;
195} PS2KR3;
196/** Pointer to the PS/2 keyboard instance data for ring-3. */
197typedef PS2KR3 *PPS2KR3;
198
199
200int PS2KByteToKbd(PPDMDEVINS pDevIns, PPS2K pThis, uint8_t cmd);
201int PS2KByteFromKbd(PPDMDEVINS pDevIns, PPS2K pThis, uint8_t *pVal);
202
203void PS2KLineDisable(PPS2K pThis);
204void PS2KLineEnable(PPS2K pThis);
205
206int PS2KR3Construct(PPDMDEVINS pDevIns, PPS2K pThis, PPS2KR3 pThisCC, PCFGMNODE pCfg);
207int PS2KR3Attach(PPDMDEVINS pDevIns, PPS2KR3 pThisCC, unsigned iLUN, uint32_t fFlags);
208void PS2KR3Reset(PPDMDEVINS pDevIns, PPS2K pThis, PPS2KR3 pThisCC);
209void PS2KR3SaveState(PPDMDEVINS pDevIns, PPS2K pThis, PSSMHANDLE pSSM);
210int PS2KR3LoadState(PPDMDEVINS pDevIns, PPS2K pThis, PSSMHANDLE pSSM, uint32_t uVersion);
211int PS2KR3LoadDone(PPDMDEVINS pDevIns, PPS2K pThis, PPS2KR3 pThisCC);
212/** @} */
213
214
215/** @defgroup grp_devps2m DevPS2M - Auxiliary Device (Mouse)
216 * @{
217 */
218
219/* Internal mouse queue sizes. The input queue is relatively large,
220 * but the command queue only needs to handle a few bytes.
221 */
222#define AUX_EVT_QUEUE_SIZE 256
223#define AUX_CMD_QUEUE_SIZE 8
224
225DEF_PS2Q_TYPE(AuxEvtQ, AUX_EVT_QUEUE_SIZE);
226DEF_PS2Q_TYPE(AuxCmdQ, AUX_CMD_QUEUE_SIZE);
227
228/** Auxiliary device special modes of operation. */
229typedef enum {
230 AUX_MODE_STD, /* Standard operation. */
231 AUX_MODE_RESET, /* Currently in reset. */
232 AUX_MODE_WRAP /* Wrap mode (echoing input). */
233} PS2M_MODE;
234
235/** Auxiliary device operational state. */
236typedef enum {
237 AUX_STATE_RATE_ERR = RT_BIT(0), /* Invalid rate received. */
238 AUX_STATE_RES_ERR = RT_BIT(1), /* Invalid resolution received. */
239 AUX_STATE_SCALING = RT_BIT(4), /* 2:1 scaling in effect. */
240 AUX_STATE_ENABLED = RT_BIT(5), /* Reporting enabled in stream mode. */
241 AUX_STATE_REMOTE = RT_BIT(6) /* Remote mode (reports on request). */
242} PS2M_STATE;
243
244/** Externally visible state bits. */
245#define AUX_STATE_EXTERNAL (AUX_STATE_SCALING | AUX_STATE_ENABLED | AUX_STATE_REMOTE)
246
247/** Protocols supported by the PS/2 mouse. */
248typedef enum {
249 PS2M_PROTO_PS2STD = 0, /* Standard PS/2 mouse protocol. */
250 PS2M_PROTO_IMPS2 = 3, /* IntelliMouse PS/2 protocol. */
251 PS2M_PROTO_IMEX = 4, /* IntelliMouse Explorer protocol. */
252 PS2M_PROTO_IMEX_HORZ = 5 /* IntelliMouse Explorer with horizontal reports. */
253} PS2M_PROTO;
254
255/** Protocol selection 'knock' states. */
256typedef enum {
257 PS2M_KNOCK_INITIAL,
258 PS2M_KNOCK_1ST,
259 PS2M_KNOCK_IMPS2_2ND,
260 PS2M_KNOCK_IMEX_2ND,
261 PS2M_KNOCK_IMEX_HORZ_2ND
262} PS2M_KNOCK_STATE;
263
264/**
265 * The shared PS/2 auxiliary device instance data.
266 */
267typedef struct PS2M
268{
269 /** Operational state. */
270 uint8_t u8State;
271 /** Configured sampling rate. */
272 uint8_t u8SampleRate;
273 /** Configured resolution. */
274 uint8_t u8Resolution;
275 /** Currently processed command (if any). */
276 uint8_t u8CurrCmd;
277 /** Set if the serial line is disabled on the KBC. */
278 bool fLineDisabled;
279 /** Set if the throttle delay is active. */
280 bool fThrottleActive;
281 /** Set if the throttle delay is active. */
282 bool fDelayReset;
283 /** Operational mode. */
284 PS2M_MODE enmMode;
285 /** Currently used protocol. */
286 PS2M_PROTO enmProtocol;
287 /** Currently used protocol. */
288 PS2M_KNOCK_STATE enmKnockState;
289 /** Buffer holding mouse events to be sent to the host. */
290 AuxEvtQ evtQ;
291 /** Command response queue (priority). */
292 AuxCmdQ cmdQ;
293 /** Accumulated horizontal movement. */
294 int32_t iAccumX;
295 /** Accumulated vertical movement. */
296 int32_t iAccumY;
297 /** Accumulated Z axis (vertical scroll) movement. */
298 int32_t iAccumZ;
299 /** Accumulated W axis (horizontal scroll) movement. */
300 int32_t iAccumW;
301 /** Accumulated button presses. */
302 uint32_t fAccumB;
303 /** Instantaneous button data. */
304 uint32_t fCurrB;
305 /** Button state last sent to the guest. */
306 uint32_t fReportedB;
307 /** Throttling delay in milliseconds. */
308 uint32_t uThrottleDelay;
309
310 /** Command delay timer. */
311 TMTIMERHANDLE hDelayTimer;
312 /** Interrupt throttling timer. */
313 TMTIMERHANDLE hThrottleTimer;
314} PS2M;
315/** Pointer to the shared PS/2 auxiliary device instance data. */
316typedef PS2M *PPS2M;
317
318/**
319 * The PS/2 auxiliary device instance data for ring-3.
320 */
321typedef struct PS2MR3
322{
323 /** The device instance.
324 * @note Only for getting our bearings in interface methods. */
325 PPDMDEVINSR3 pDevIns;
326
327 /**
328 * Mouse port - LUN#1.
329 *
330 * @implements PDMIBASE
331 * @implements PDMIMOUSEPORT
332 */
333 struct
334 {
335 /** The base interface for the mouse port. */
336 PDMIBASE IBase;
337 /** The keyboard port base interface. */
338 PDMIMOUSEPORT IPort;
339
340 /** The base interface of the attached mouse driver. */
341 R3PTRTYPE(PPDMIBASE) pDrvBase;
342 /** The keyboard interface of the attached mouse driver. */
343 R3PTRTYPE(PPDMIMOUSECONNECTOR) pDrv;
344 } Mouse;
345} PS2MR3;
346/** Pointer to the PS/2 auxiliary device instance data for ring-3. */
347typedef PS2MR3 *PPS2MR3;
348
349int PS2MByteToAux(PPDMDEVINS pDevIns, PPS2M pThis, uint8_t cmd);
350int PS2MByteFromAux(PPS2M pThis, uint8_t *pVal);
351
352void PS2MLineDisable(PPS2M pThis);
353void PS2MLineEnable(PPS2M pThis);
354
355int PS2MR3Construct(PPDMDEVINS pDevIns, PPS2M pThis, PPS2MR3 pThisCC);
356int PS2MR3Attach(PPDMDEVINS pDevIns, PPS2MR3 pThisCC, unsigned iLUN, uint32_t fFlags);
357void PS2MR3Reset(PPS2M pThis);
358void PS2MR3SaveState(PPDMDEVINS pDevIns, PPS2M pThis, PSSMHANDLE pSSM);
359int PS2MR3LoadState(PPDMDEVINS pDevIns, PPS2M pThis, PPS2MR3 pThisCC, PSSMHANDLE pSSM, uint32_t uVersion);
360void PS2MR3FixupState(PPS2M pThis, PPS2MR3 pThisCC, uint8_t u8State, uint8_t u8Rate, uint8_t u8Proto);
361/** @} */
362
363
364/**
365 * The shared keyboard controller/device state.
366 *
367 * @note We use the default critical section for serialize data access.
368 */
369typedef struct KBDSTATE
370{
371 uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
372 uint8_t status;
373 uint8_t mode;
374 uint8_t dbbout; /* data buffer byte */
375 /* keyboard state */
376 int32_t translate;
377 int32_t xlat_state;
378
379 /** I/O port 60h. */
380 IOMIOPORTHANDLE hIoPortData;
381 /** I/O port 64h. */
382 IOMIOPORTHANDLE hIoPortCmdStatus;
383
384 /** Shared keyboard state (implemented in separate PS2K module). */
385 PS2K Kbd;
386 /** Shared mouse state (implemented in separate PS2M module). */
387 PS2M Aux;
388} KBDSTATE;
389
390
391/**
392 * The ring-3 keyboard controller/device state.
393 */
394typedef struct KBDSTATER3
395{
396 /** Keyboard state for ring-3 (implemented in separate PS2K module). */
397 PS2KR3 Kbd;
398 /** Mouse state for ring-3 (implemented in separate PS2M module). */
399 PS2MR3 Aux;
400} KBDSTATER3;
401/** Pointer to the keyboard (PS/2) controller / device state for ring-3. */
402typedef KBDSTATER3 *PKBDSTATER3;
403
404
405/* Shared keyboard/aux internal interface. */
406void KBCUpdateInterrupts(PPDMDEVINS pDevIns);
407
408/** @} */
409
410#endif /* !VBOX_INCLUDED_SRC_Input_DevPS2_h */
411
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette