VirtualBox

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

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

DevPS2: Critsect. bugref:9218

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
Line 
1/* $Id: DevPS2.h 82200 2019-11-25 20:55:43Z vboxsync $ */
2/** @file
3 * PS/2 devices - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2007-2019 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/** Define a simple PS/2 input device queue. */
32#define DEF_PS2Q_TYPE(name, size) \
33 typedef struct { \
34 uint32_t rpos; \
35 uint32_t wpos; \
36 uint32_t cUsed; \
37 uint32_t cSize; \
38 uint8_t abQueue[size]; \
39 } name
40
41DEF_PS2Q_TYPE(GeneriQ, 1);
42void PS2CmnClearQueue(GeneriQ *pQ);
43void PS2CmnInsertQueue(GeneriQ *pQ, uint8_t val);
44int PS2CmnRemoveQueue(GeneriQ *pQ, uint8_t *pVal);
45void PS2CmnR3SaveQueue(PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM, GeneriQ *pQ);
46int PS2CmnR3LoadQueue(PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM, GeneriQ *pQ);
47
48
49/** @defgroup grp_devps2k DevPS2K - Keyboard
50 * @{
51 */
52
53/** @name HID modifier range.
54 * @{ */
55#define HID_MODIFIER_FIRST 0xE0
56#define HID_MODIFIER_LAST 0xE8
57/** @} */
58
59/** @name USB HID additional constants
60 * @{ */
61/** The highest USB usage code reported by VirtualBox. */
62#define VBOX_USB_MAX_USAGE_CODE 0xE7
63/** The size of an array needed to store all USB usage codes */
64#define VBOX_USB_USAGE_ARRAY_SIZE (VBOX_USB_MAX_USAGE_CODE + 1)
65/** USB HID Keyboard Usage Page. */
66#define USB_HID_KB_PAGE 7
67/** USB HID Consumer Control Usage Page. */
68#define USB_HID_CC_PAGE 12
69/** @} */
70
71/* Internal keyboard queue sizes. The input queue doesn't need to be
72 * extra huge and the command queue only needs to handle a few bytes.
73 */
74#define KBD_KEY_QUEUE_SIZE 64
75#define KBD_CMD_QUEUE_SIZE 4
76
77DEF_PS2Q_TYPE(KbdKeyQ, KBD_KEY_QUEUE_SIZE);
78DEF_PS2Q_TYPE(KbdCmdQ, KBD_CMD_QUEUE_SIZE);
79
80/** Typematic state. */
81typedef enum {
82 KBD_TMS_IDLE = 0, /* No typematic key active. */
83 KBD_TMS_DELAY = 1, /* In the initial delay period. */
84 KBD_TMS_REPEAT = 2, /* Key repeating at set rate. */
85 KBD_TMS_32BIT_HACK = 0x7fffffff
86} tmatic_state_t;
87
88
89/**
90 * The shared PS/2 keyboard instance data.
91 */
92typedef struct PS2K
93{
94 /** Pointer to parent device (keyboard controller). */
95 R3PTRTYPE(PKBDSTATE) pParent;
96 /** Set if keyboard is enabled ('scans' for input). */
97 bool fScanning;
98 /** Set NumLock is on. */
99 bool fNumLockOn;
100 /** Selected scan set. */
101 uint8_t u8ScanSet;
102 /** Modifier key state. */
103 uint8_t u8Modifiers;
104 /** Currently processed command (if any). */
105 uint8_t u8CurrCmd;
106 /** Status indicator (LED) state. */
107 uint8_t u8LEDs;
108 /** Selected typematic delay/rate. */
109 uint8_t u8TypematicCfg;
110 uint8_t bAlignment1;
111 /** Usage code of current typematic key, if any. */
112 uint32_t u32TypematicKey;
113 /** Current typematic repeat state. */
114 tmatic_state_t enmTypematicState;
115 /** Buffer holding scan codes to be sent to the host. */
116 KbdKeyQ keyQ;
117 /** Command response queue (priority). */
118 KbdCmdQ cmdQ;
119 /** Currently depressed keys. */
120 uint8_t abDepressedKeys[VBOX_USB_USAGE_ARRAY_SIZE];
121 /** Typematic delay in milliseconds. */
122 uint32_t uTypematicDelay;
123 /** Typematic repeat period in milliseconds. */
124 uint32_t uTypematicRepeat;
125 /** Set if the throttle delay is currently active. */
126 bool fThrottleActive;
127 /** Set if the input rate should be throttled. */
128 bool fThrottleEnabled;
129 uint8_t abAlignment2[2];
130
131 /** Command delay timer - R3 Ptr. */
132 TMTIMERHANDLE hKbdDelayTimer;
133 /** Typematic timer - R3 Ptr. */
134 TMTIMERHANDLE hKbdTypematicTimer;
135 /** Input throttle timer. */
136 TMTIMERHANDLE hThrottleTimer;
137
138 /** The device instance.
139 * @note Only for getting our bearings in interface methods. */
140 PPDMDEVINSR3 pDevIns;
141
142 /**
143 * Keyboard port - LUN#0.
144 *
145 * @implements PDMIBASE
146 * @implements PDMIKEYBOARDPORT
147 */
148 struct
149 {
150 /** The base interface for the keyboard port. */
151 PDMIBASE IBase;
152 /** The keyboard port base interface. */
153 PDMIKEYBOARDPORT IPort;
154
155 /** The base interface of the attached keyboard driver. */
156 R3PTRTYPE(PPDMIBASE) pDrvBase;
157 /** The keyboard interface of the attached keyboard driver. */
158 R3PTRTYPE(PPDMIKEYBOARDCONNECTOR) pDrv;
159 } Keyboard;
160} PS2K;
161/** Pointer to the PS/2 keyboard instance data. */
162typedef PS2K *PPS2K;
163
164
165int PS2KByteToKbd(PPDMDEVINS pDevIns, PPS2K pThis, uint8_t cmd);
166int PS2KByteFromKbd(PPDMDEVINS pDevIns, PPS2K pThis, uint8_t *pVal);
167
168int PS2KR3Construct(PPS2K pThis, PPDMDEVINS pDevIns, PKBDSTATE pParent, unsigned iInstance, PCFGMNODE pCfg);
169int PS2KR3Attach(PPS2K pThis, PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
170void PS2KR3Reset(PPDMDEVINS pDevIns, PPS2K pThis);
171void PS2KR3SaveState(PPDMDEVINS pDevIns, PPS2K pThis, PSSMHANDLE pSSM);
172int PS2KR3LoadState(PPDMDEVINS pDevIns, PPS2K pThis, PSSMHANDLE pSSM, uint32_t uVersion);
173int PS2KR3LoadDone(PPDMDEVINS pDevIns, PPS2K pThis);
174
175PS2K *KBDGetPS2KFromDevIns(PPDMDEVINS pDevIns);
176
177/** @} */
178
179
180/** @defgroup grp_devps2m DevPS2M - Auxiliary Device (Mouse)
181 * @{
182 */
183
184/* Internal mouse queue sizes. The input queue is relatively large,
185 * but the command queue only needs to handle a few bytes.
186 */
187#define AUX_EVT_QUEUE_SIZE 256
188#define AUX_CMD_QUEUE_SIZE 8
189
190DEF_PS2Q_TYPE(AuxEvtQ, AUX_EVT_QUEUE_SIZE);
191DEF_PS2Q_TYPE(AuxCmdQ, AUX_CMD_QUEUE_SIZE);
192
193/** Auxiliary device special modes of operation. */
194typedef enum {
195 AUX_MODE_STD, /* Standard operation. */
196 AUX_MODE_RESET, /* Currently in reset. */
197 AUX_MODE_WRAP /* Wrap mode (echoing input). */
198} PS2M_MODE;
199
200/** Auxiliary device operational state. */
201typedef enum {
202 AUX_STATE_RATE_ERR = RT_BIT(0), /* Invalid rate received. */
203 AUX_STATE_RES_ERR = RT_BIT(1), /* Invalid resolution received. */
204 AUX_STATE_SCALING = RT_BIT(4), /* 2:1 scaling in effect. */
205 AUX_STATE_ENABLED = RT_BIT(5), /* Reporting enabled in stream mode. */
206 AUX_STATE_REMOTE = RT_BIT(6) /* Remote mode (reports on request). */
207} PS2M_STATE;
208
209/** Externally visible state bits. */
210#define AUX_STATE_EXTERNAL (AUX_STATE_SCALING | AUX_STATE_ENABLED | AUX_STATE_REMOTE)
211
212/** Protocols supported by the PS/2 mouse. */
213typedef enum {
214 PS2M_PROTO_PS2STD = 0, /* Standard PS/2 mouse protocol. */
215 PS2M_PROTO_IMPS2 = 3, /* IntelliMouse PS/2 protocol. */
216 PS2M_PROTO_IMEX = 4, /* IntelliMouse Explorer protocol. */
217 PS2M_PROTO_IMEX_HORZ = 5 /* IntelliMouse Explorer with horizontal reports. */
218} PS2M_PROTO;
219
220/** Protocol selection 'knock' states. */
221typedef enum {
222 PS2M_KNOCK_INITIAL,
223 PS2M_KNOCK_1ST,
224 PS2M_KNOCK_IMPS2_2ND,
225 PS2M_KNOCK_IMEX_2ND,
226 PS2M_KNOCK_IMEX_HORZ_2ND
227} PS2M_KNOCK_STATE;
228
229/**
230 * The PS/2 auxiliary device instance data.
231 */
232typedef struct PS2M
233{
234 /** Pointer to parent device (keyboard controller). */
235 R3PTRTYPE(PKBDSTATE) pParent;
236 /** Operational state. */
237 uint8_t u8State;
238 /** Configured sampling rate. */
239 uint8_t u8SampleRate;
240 /** Configured resolution. */
241 uint8_t u8Resolution;
242 /** Currently processed command (if any). */
243 uint8_t u8CurrCmd;
244 /** Set if the throttle delay is active. */
245 bool fThrottleActive;
246 /** Set if the throttle delay is active. */
247 bool fDelayReset;
248 /** Operational mode. */
249 PS2M_MODE enmMode;
250 /** Currently used protocol. */
251 PS2M_PROTO enmProtocol;
252 /** Currently used protocol. */
253 PS2M_KNOCK_STATE enmKnockState;
254 /** Buffer holding mouse events to be sent to the host. */
255 AuxEvtQ evtQ;
256 /** Command response queue (priority). */
257 AuxCmdQ cmdQ;
258 /** Accumulated horizontal movement. */
259 int32_t iAccumX;
260 /** Accumulated vertical movement. */
261 int32_t iAccumY;
262 /** Accumulated Z axis (vertical scroll) movement. */
263 int32_t iAccumZ;
264 /** Accumulated W axis (horizontal scroll) movement. */
265 int32_t iAccumW;
266 /** Accumulated button presses. */
267 uint32_t fAccumB;
268 /** Instantaneous button data. */
269 uint32_t fCurrB;
270 /** Button state last sent to the guest. */
271 uint32_t fReportedB;
272 /** Throttling delay in milliseconds. */
273 uint32_t uThrottleDelay;
274
275 /** The device instance.
276 * @note Only for getting our bearings in interface methods. */
277 PPDMDEVINSR3 pDevIns;
278
279 /** Command delay timer. */
280 TMTIMERHANDLE hDelayTimer;
281 /** Interrupt throttling timer. */
282 TMTIMERHANDLE hThrottleTimer;
283
284 /**
285 * Mouse port - LUN#1.
286 *
287 * @implements PDMIBASE
288 * @implements PDMIMOUSEPORT
289 */
290 struct
291 {
292 /** The base interface for the mouse port. */
293 PDMIBASE IBase;
294 /** The keyboard port base interface. */
295 PDMIMOUSEPORT IPort;
296
297 /** The base interface of the attached mouse driver. */
298 R3PTRTYPE(PPDMIBASE) pDrvBase;
299 /** The keyboard interface of the attached mouse driver. */
300 R3PTRTYPE(PPDMIMOUSECONNECTOR) pDrv;
301 } Mouse;
302} PS2M;
303/** Pointer to the PS/2 auxiliary device instance data. */
304typedef PS2M *PPS2M;
305
306int PS2MByteToAux(PPDMDEVINS pDevIns, PPS2M pThis, uint8_t cmd);
307int PS2MByteFromAux(PPS2M pThis, uint8_t *pVal);
308
309int PS2MR3Construct(PPS2M pThis, PPDMDEVINS pDevIns, PKBDSTATE pParent, unsigned iInstance);
310int PS2MR3Attach(PPS2M pThis, PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
311void PS2MR3Reset(PPS2M pThis);
312void PS2MR3SaveState(PPDMDEVINS pDevIns, PPS2M pThis, PSSMHANDLE pSSM);
313int PS2MR3LoadState(PPDMDEVINS pDevIns, PPS2M pThis, PSSMHANDLE pSSM, uint32_t uVersion);
314void PS2MR3FixupState(PPS2M pThis, uint8_t u8State, uint8_t u8Rate, uint8_t u8Proto);
315
316PS2M *KBDGetPS2MFromDevIns(PPDMDEVINS pDevIns);
317
318/** @} */
319
320
321/**
322 * The shared keyboard controller/device state.
323 *
324 * @note We use the default critical section for serialize data access.
325 */
326typedef struct KBDSTATE
327{
328 uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
329 uint8_t status;
330 uint8_t mode;
331 uint8_t dbbout; /* data buffer byte */
332 /* keyboard state */
333 int32_t translate;
334 int32_t xlat_state;
335
336 /** Pointer to the device instance - RC. */
337 PPDMDEVINSRC pDevInsRC;
338 /** Pointer to the device instance - R3 . */
339 PPDMDEVINSR3 pDevInsR3;
340 /** Pointer to the device instance. */
341 PPDMDEVINSR0 pDevInsR0;
342
343 /** Keyboard state (implemented in separate PS2K module). */
344 PS2K Kbd;
345
346 /** Mouse state (implemented in separate PS2M module). */
347 PS2M Aux;
348} KBDSTATE, KBDState;
349
350
351/* Shared keyboard/aux internal interface. */
352void KBCUpdateInterrupts(PPDMDEVINS pDevIns);
353
354/** @} */
355
356#endif /* !VBOX_INCLUDED_SRC_Input_DevPS2_h */
357
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