VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use