1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
/** @file
Private definitions of the VirtioKeyboard driver
Copyright (C) 2024, Red Hat
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _VIRTIO_KEYBOARD_DXE_H_
#define _VIRTIO_KEYBOARD_DXE_H_
#include <Protocol/ComponentName.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/SimpleTextInEx.h>
#include <IndustryStandard/Virtio.h>
#define VIRTIO_KBD_SIG SIGNATURE_32 ('V', 'K', 'B', 'D')
#define KEYBOARD_MAX_RINGS 2
#define KEYBOARD_RX_BUFSIZE 64
// Fetch new key from VirtIO every 50ms
#define KEYBOARD_PROBE_TIME_MS 50
// Max range of recognized keyboard codes
#define MAX_KEYBOARD_CODE 255
typedef struct {
UINTN Signature;
EFI_KEY_DATA KeyData;
EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
LIST_ENTRY NotifyEntry;
} VIRTIO_KBD_IN_EX_NOTIFY;
// Data structure representing payload delivered from VirtIo
typedef struct {
UINT16 Type;
UINT16 Code;
UINT32 Value;
} VIRTIO_KBD_EVENT;
// Data structure representing ring buffer
typedef struct {
VRING Ring;
VOID *RingMap;
DESC_INDICES Indices; /* Avail Ring */
UINT16 LastUsedIdx; /* Used Ring */
UINT32 BufferSize;
UINT32 BufferCount;
UINT32 BufferPages;
UINT8 *Buffers;
VOID *BufferMap;
EFI_PHYSICAL_ADDRESS DeviceAddress;
BOOLEAN Ready;
} VIRTIO_KBD_RING;
// Declaration of data structure representing driver context
typedef struct {
// Device signature
UINT32 Signature;
// Hook for the function which shall be caled when driver is closed
// before system state changes to boot
EFI_EVENT ExitBoot;
// Hooks for functions required by UEFI keyboard API
// struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL {
// EFI_INPUT_RESET Reset;
// EFI_INPUT_READ_KEY ReadKeyStroke;
// EFI_EVENT WaitForKey;
// };
EFI_SIMPLE_TEXT_INPUT_PROTOCOL Txt;
// struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL {
// EFI_INPUT_RESET_EX Reset;
// EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx;
// EFI_EVENT WaitForKeyEx;
// EFI_SET_STATE SetState;
// EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify;
// EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify;
// }
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL TxtEx;
// Virtio device hook
VIRTIO_DEVICE_PROTOCOL *VirtIo;
// Hook for ring buffer
VIRTIO_KBD_RING Rings[KEYBOARD_MAX_RINGS];
// Timer event for checking key presses from VirtIo
EFI_EVENT KeyReadTimer;
// List for notifications
LIST_ENTRY NotifyList;
EFI_EVENT KeyNotifyTimer;
// Last pressed key
// typedef struct {
// UINT16 ScanCode;
// CHAR16 UnicodeChar;
// } EFI_INPUT_KEY;
EFI_INPUT_KEY LastKey;
// Key modifiers
BOOLEAN KeyActive[MAX_KEYBOARD_CODE];
// If key is ready
BOOLEAN KeyReady;
} VIRTIO_KBD_DEV;
// Helper functions to extract VIRTIO_KBD_DEV structure pointers
#define VIRTIO_KEYBOARD_FROM_THIS(KbrPointer) \
CR (KbrPointer, VIRTIO_KBD_DEV, Txt, VIRTIO_KBD_SIG)
#define VIRTIO_KEYBOARD_EX_FROM_THIS(KbrPointer) \
CR (KbrPointer, VIRTIO_KBD_DEV, TxtEx, VIRTIO_KBD_SIG)
// Bellow candidates to be included as Linux header
#define KEY_PRESSED 1
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_PROTOCOL API
EFI_STATUS
EFIAPI
VirtioKeyboardSimpleTextInputReset (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_PROTOCOL API
EFI_STATUS
EFIAPI
VirtioKeyboardSimpleTextInputReadKeyStroke (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
);
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_PROTOCOL API
VOID
EFIAPI
VirtioKeyboardWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
);
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL API
EFI_STATUS
EFIAPI
VirtioKeyboardResetEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL API
EFI_STATUS
EFIAPI
VirtioKeyboardReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
);
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL API
VOID
EFIAPI
VirtioKeyboardWaitForKeyEx (
IN EFI_EVENT Event,
IN VOID *Context
);
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL API
EFI_STATUS
EFIAPI
VirtioKeyboardSetState (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
);
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL API
EFI_STATUS
EFIAPI
VirtioKeyboardRegisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT VOID **NotifyHandle
);
// -----------------------------------------------------------------------------
// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL API
EFI_STATUS
EFIAPI
VirtioKeyboardUnregisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN VOID *NotificationHandle
);
#endif
|