VirtualBox

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

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

DevPS2: Converted the generic queue stuff into some a lot more paranoid (I hope), requiring no ugly casting. bugref:9218

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