summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/VirtioKeyboardDxe/VirtioKeyboard.h
blob: d4cbde97fd66ed37782c5b80fd0f84f986e37d36 (plain)
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