ps2.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. /*
  2. * QEMU PS/2 keyboard/mouse emulation
  3. *
  4. * Copyright (c) 2003 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "qemu/log.h"
  26. #include "hw/input/ps2.h"
  27. #include "migration/vmstate.h"
  28. #include "ui/console.h"
  29. #include "ui/input.h"
  30. #include "sysemu/reset.h"
  31. #include "sysemu/runstate.h"
  32. #include "trace.h"
  33. /* debug PC keyboard */
  34. //#define DEBUG_KBD
  35. /* debug PC keyboard : only mouse */
  36. //#define DEBUG_MOUSE
  37. /* Keyboard Commands */
  38. #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
  39. #define KBD_CMD_ECHO 0xEE
  40. #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
  41. #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
  42. #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
  43. #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
  44. #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
  45. #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
  46. #define KBD_CMD_RESET 0xFF /* Reset */
  47. /* Keyboard Replies */
  48. #define KBD_REPLY_POR 0xAA /* Power on reset */
  49. #define KBD_REPLY_ID 0xAB /* Keyboard ID */
  50. #define KBD_REPLY_ACK 0xFA /* Command ACK */
  51. #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
  52. /* Mouse Commands */
  53. #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
  54. #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
  55. #define AUX_SET_RES 0xE8 /* Set resolution */
  56. #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
  57. #define AUX_SET_STREAM 0xEA /* Set stream mode */
  58. #define AUX_POLL 0xEB /* Poll */
  59. #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
  60. #define AUX_SET_WRAP 0xEE /* Set wrap mode */
  61. #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
  62. #define AUX_GET_TYPE 0xF2 /* Get type */
  63. #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
  64. #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
  65. #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
  66. #define AUX_SET_DEFAULT 0xF6
  67. #define AUX_RESET 0xFF /* Reset aux device */
  68. #define AUX_ACK 0xFA /* Command byte ACK. */
  69. #define MOUSE_STATUS_REMOTE 0x40
  70. #define MOUSE_STATUS_ENABLED 0x20
  71. #define MOUSE_STATUS_SCALE21 0x10
  72. #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
  73. /* Bits for 'modifiers' field in PS2KbdState */
  74. #define MOD_CTRL_L (1 << 0)
  75. #define MOD_SHIFT_L (1 << 1)
  76. #define MOD_ALT_L (1 << 2)
  77. #define MOD_CTRL_R (1 << 3)
  78. #define MOD_SHIFT_R (1 << 4)
  79. #define MOD_ALT_R (1 << 5)
  80. typedef struct {
  81. /* Keep the data array 256 bytes long, which compatibility
  82. with older qemu versions. */
  83. uint8_t data[256];
  84. int rptr, wptr, count;
  85. } PS2Queue;
  86. struct PS2State {
  87. PS2Queue queue;
  88. int32_t write_cmd;
  89. void (*update_irq)(void *, int);
  90. void *update_arg;
  91. };
  92. typedef struct {
  93. PS2State common;
  94. int scan_enabled;
  95. int translate;
  96. int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
  97. int ledstate;
  98. bool need_high_bit;
  99. unsigned int modifiers; /* bitmask of MOD_* constants above */
  100. } PS2KbdState;
  101. typedef struct {
  102. PS2State common;
  103. uint8_t mouse_status;
  104. uint8_t mouse_resolution;
  105. uint8_t mouse_sample_rate;
  106. uint8_t mouse_wrap;
  107. uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
  108. uint8_t mouse_detect_state;
  109. int mouse_dx; /* current values, needed for 'poll' mode */
  110. int mouse_dy;
  111. int mouse_dz;
  112. uint8_t mouse_buttons;
  113. } PS2MouseState;
  114. static uint8_t translate_table[256] = {
  115. 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
  116. 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
  117. 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
  118. 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
  119. 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
  120. 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
  121. 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
  122. 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
  123. 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
  124. 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
  125. 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
  126. 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
  127. 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
  128. 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
  129. 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
  130. 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
  131. 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
  132. 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  133. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  134. 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
  135. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  136. 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  137. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  138. 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  139. 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  140. 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  141. 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
  142. 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  143. 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  144. 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  145. 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  146. 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
  147. };
  148. static unsigned int ps2_modifier_bit(QKeyCode key)
  149. {
  150. switch (key) {
  151. case Q_KEY_CODE_CTRL:
  152. return MOD_CTRL_L;
  153. case Q_KEY_CODE_CTRL_R:
  154. return MOD_CTRL_R;
  155. case Q_KEY_CODE_SHIFT:
  156. return MOD_SHIFT_L;
  157. case Q_KEY_CODE_SHIFT_R:
  158. return MOD_SHIFT_R;
  159. case Q_KEY_CODE_ALT:
  160. return MOD_ALT_L;
  161. case Q_KEY_CODE_ALT_R:
  162. return MOD_ALT_R;
  163. default:
  164. return 0;
  165. }
  166. }
  167. static void ps2_reset_queue(PS2State *s)
  168. {
  169. PS2Queue *q = &s->queue;
  170. q->rptr = 0;
  171. q->wptr = 0;
  172. q->count = 0;
  173. }
  174. void ps2_queue_noirq(PS2State *s, int b)
  175. {
  176. PS2Queue *q = &s->queue;
  177. if (q->count == PS2_QUEUE_SIZE) {
  178. return;
  179. }
  180. q->data[q->wptr] = b;
  181. if (++q->wptr == PS2_QUEUE_SIZE)
  182. q->wptr = 0;
  183. q->count++;
  184. }
  185. void ps2_raise_irq(PS2State *s)
  186. {
  187. s->update_irq(s->update_arg, 1);
  188. }
  189. void ps2_queue(PS2State *s, int b)
  190. {
  191. ps2_queue_noirq(s, b);
  192. s->update_irq(s->update_arg, 1);
  193. }
  194. void ps2_queue_2(PS2State *s, int b1, int b2)
  195. {
  196. if (PS2_QUEUE_SIZE - s->queue.count < 2) {
  197. return;
  198. }
  199. ps2_queue_noirq(s, b1);
  200. ps2_queue_noirq(s, b2);
  201. s->update_irq(s->update_arg, 1);
  202. }
  203. void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
  204. {
  205. if (PS2_QUEUE_SIZE - s->queue.count < 3) {
  206. return;
  207. }
  208. ps2_queue_noirq(s, b1);
  209. ps2_queue_noirq(s, b2);
  210. ps2_queue_noirq(s, b3);
  211. s->update_irq(s->update_arg, 1);
  212. }
  213. void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
  214. {
  215. if (PS2_QUEUE_SIZE - s->queue.count < 4) {
  216. return;
  217. }
  218. ps2_queue_noirq(s, b1);
  219. ps2_queue_noirq(s, b2);
  220. ps2_queue_noirq(s, b3);
  221. ps2_queue_noirq(s, b4);
  222. s->update_irq(s->update_arg, 1);
  223. }
  224. /* keycode is the untranslated scancode in the current scancode set. */
  225. static void ps2_put_keycode(void *opaque, int keycode)
  226. {
  227. PS2KbdState *s = opaque;
  228. trace_ps2_put_keycode(opaque, keycode);
  229. qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
  230. if (s->translate) {
  231. if (keycode == 0xf0) {
  232. s->need_high_bit = true;
  233. } else if (s->need_high_bit) {
  234. ps2_queue(&s->common, translate_table[keycode] | 0x80);
  235. s->need_high_bit = false;
  236. } else {
  237. ps2_queue(&s->common, translate_table[keycode]);
  238. }
  239. } else {
  240. ps2_queue(&s->common, keycode);
  241. }
  242. }
  243. static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
  244. InputEvent *evt)
  245. {
  246. PS2KbdState *s = (PS2KbdState *)dev;
  247. InputKeyEvent *key = evt->u.key.data;
  248. int qcode;
  249. uint16_t keycode = 0;
  250. int mod;
  251. /* do not process events while disabled to prevent stream corruption */
  252. if (!s->scan_enabled) {
  253. return;
  254. }
  255. qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
  256. assert(evt->type == INPUT_EVENT_KIND_KEY);
  257. qcode = qemu_input_key_value_to_qcode(key->key);
  258. mod = ps2_modifier_bit(qcode);
  259. trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers);
  260. if (key->down) {
  261. s->modifiers |= mod;
  262. } else {
  263. s->modifiers &= ~mod;
  264. }
  265. if (s->scancode_set == 1) {
  266. if (qcode == Q_KEY_CODE_PAUSE) {
  267. if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
  268. if (key->down) {
  269. ps2_put_keycode(s, 0xe0);
  270. ps2_put_keycode(s, 0x46);
  271. ps2_put_keycode(s, 0xe0);
  272. ps2_put_keycode(s, 0xc6);
  273. }
  274. } else {
  275. if (key->down) {
  276. ps2_put_keycode(s, 0xe1);
  277. ps2_put_keycode(s, 0x1d);
  278. ps2_put_keycode(s, 0x45);
  279. ps2_put_keycode(s, 0xe1);
  280. ps2_put_keycode(s, 0x9d);
  281. ps2_put_keycode(s, 0xc5);
  282. }
  283. }
  284. } else if (qcode == Q_KEY_CODE_PRINT) {
  285. if (s->modifiers & MOD_ALT_L) {
  286. if (key->down) {
  287. ps2_put_keycode(s, 0xb8);
  288. ps2_put_keycode(s, 0x38);
  289. ps2_put_keycode(s, 0x54);
  290. } else {
  291. ps2_put_keycode(s, 0xd4);
  292. ps2_put_keycode(s, 0xb8);
  293. ps2_put_keycode(s, 0x38);
  294. }
  295. } else if (s->modifiers & MOD_ALT_R) {
  296. if (key->down) {
  297. ps2_put_keycode(s, 0xe0);
  298. ps2_put_keycode(s, 0xb8);
  299. ps2_put_keycode(s, 0xe0);
  300. ps2_put_keycode(s, 0x38);
  301. ps2_put_keycode(s, 0x54);
  302. } else {
  303. ps2_put_keycode(s, 0xd4);
  304. ps2_put_keycode(s, 0xe0);
  305. ps2_put_keycode(s, 0xb8);
  306. ps2_put_keycode(s, 0xe0);
  307. ps2_put_keycode(s, 0x38);
  308. }
  309. } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
  310. MOD_SHIFT_R | MOD_CTRL_R)) {
  311. if (key->down) {
  312. ps2_put_keycode(s, 0xe0);
  313. ps2_put_keycode(s, 0x37);
  314. } else {
  315. ps2_put_keycode(s, 0xe0);
  316. ps2_put_keycode(s, 0xb7);
  317. }
  318. } else {
  319. if (key->down) {
  320. ps2_put_keycode(s, 0xe0);
  321. ps2_put_keycode(s, 0x2a);
  322. ps2_put_keycode(s, 0xe0);
  323. ps2_put_keycode(s, 0x37);
  324. } else {
  325. ps2_put_keycode(s, 0xe0);
  326. ps2_put_keycode(s, 0xb7);
  327. ps2_put_keycode(s, 0xe0);
  328. ps2_put_keycode(s, 0xaa);
  329. }
  330. }
  331. } else {
  332. if (qcode < qemu_input_map_qcode_to_atset1_len)
  333. keycode = qemu_input_map_qcode_to_atset1[qcode];
  334. if (keycode) {
  335. if (keycode & 0xff00) {
  336. ps2_put_keycode(s, keycode >> 8);
  337. }
  338. if (!key->down) {
  339. keycode |= 0x80;
  340. }
  341. ps2_put_keycode(s, keycode & 0xff);
  342. } else {
  343. qemu_log_mask(LOG_UNIMP,
  344. "ps2: ignoring key with qcode %d\n", qcode);
  345. }
  346. }
  347. } else if (s->scancode_set == 2) {
  348. if (qcode == Q_KEY_CODE_PAUSE) {
  349. if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
  350. if (key->down) {
  351. ps2_put_keycode(s, 0xe0);
  352. ps2_put_keycode(s, 0x7e);
  353. ps2_put_keycode(s, 0xe0);
  354. ps2_put_keycode(s, 0xf0);
  355. ps2_put_keycode(s, 0x7e);
  356. }
  357. } else {
  358. if (key->down) {
  359. ps2_put_keycode(s, 0xe1);
  360. ps2_put_keycode(s, 0x14);
  361. ps2_put_keycode(s, 0x77);
  362. ps2_put_keycode(s, 0xe1);
  363. ps2_put_keycode(s, 0xf0);
  364. ps2_put_keycode(s, 0x14);
  365. ps2_put_keycode(s, 0xf0);
  366. ps2_put_keycode(s, 0x77);
  367. }
  368. }
  369. } else if (qcode == Q_KEY_CODE_PRINT) {
  370. if (s->modifiers & MOD_ALT_L) {
  371. if (key->down) {
  372. ps2_put_keycode(s, 0xf0);
  373. ps2_put_keycode(s, 0x11);
  374. ps2_put_keycode(s, 0x11);
  375. ps2_put_keycode(s, 0x84);
  376. } else {
  377. ps2_put_keycode(s, 0xf0);
  378. ps2_put_keycode(s, 0x84);
  379. ps2_put_keycode(s, 0xf0);
  380. ps2_put_keycode(s, 0x11);
  381. ps2_put_keycode(s, 0x11);
  382. }
  383. } else if (s->modifiers & MOD_ALT_R) {
  384. if (key->down) {
  385. ps2_put_keycode(s, 0xe0);
  386. ps2_put_keycode(s, 0xf0);
  387. ps2_put_keycode(s, 0x11);
  388. ps2_put_keycode(s, 0xe0);
  389. ps2_put_keycode(s, 0x11);
  390. ps2_put_keycode(s, 0x84);
  391. } else {
  392. ps2_put_keycode(s, 0xf0);
  393. ps2_put_keycode(s, 0x84);
  394. ps2_put_keycode(s, 0xe0);
  395. ps2_put_keycode(s, 0xf0);
  396. ps2_put_keycode(s, 0x11);
  397. ps2_put_keycode(s, 0xe0);
  398. ps2_put_keycode(s, 0x11);
  399. }
  400. } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
  401. MOD_SHIFT_R | MOD_CTRL_R)) {
  402. if (key->down) {
  403. ps2_put_keycode(s, 0xe0);
  404. ps2_put_keycode(s, 0x7c);
  405. } else {
  406. ps2_put_keycode(s, 0xe0);
  407. ps2_put_keycode(s, 0xf0);
  408. ps2_put_keycode(s, 0x7c);
  409. }
  410. } else {
  411. if (key->down) {
  412. ps2_put_keycode(s, 0xe0);
  413. ps2_put_keycode(s, 0x12);
  414. ps2_put_keycode(s, 0xe0);
  415. ps2_put_keycode(s, 0x7c);
  416. } else {
  417. ps2_put_keycode(s, 0xe0);
  418. ps2_put_keycode(s, 0xf0);
  419. ps2_put_keycode(s, 0x7c);
  420. ps2_put_keycode(s, 0xe0);
  421. ps2_put_keycode(s, 0xf0);
  422. ps2_put_keycode(s, 0x12);
  423. }
  424. }
  425. } else {
  426. if (qcode < qemu_input_map_qcode_to_atset2_len)
  427. keycode = qemu_input_map_qcode_to_atset2[qcode];
  428. if (keycode) {
  429. if (keycode & 0xff00) {
  430. ps2_put_keycode(s, keycode >> 8);
  431. }
  432. if (!key->down) {
  433. ps2_put_keycode(s, 0xf0);
  434. }
  435. ps2_put_keycode(s, keycode & 0xff);
  436. } else {
  437. qemu_log_mask(LOG_UNIMP,
  438. "ps2: ignoring key with qcode %d\n", qcode);
  439. }
  440. }
  441. } else if (s->scancode_set == 3) {
  442. if (qcode < qemu_input_map_qcode_to_atset3_len)
  443. keycode = qemu_input_map_qcode_to_atset3[qcode];
  444. if (keycode) {
  445. /* FIXME: break code should be configured on a key by key basis */
  446. if (!key->down) {
  447. ps2_put_keycode(s, 0xf0);
  448. }
  449. ps2_put_keycode(s, keycode);
  450. } else {
  451. qemu_log_mask(LOG_UNIMP,
  452. "ps2: ignoring key with qcode %d\n", qcode);
  453. }
  454. }
  455. }
  456. uint32_t ps2_read_data(PS2State *s)
  457. {
  458. PS2Queue *q;
  459. int val, index;
  460. trace_ps2_read_data(s);
  461. q = &s->queue;
  462. if (q->count == 0) {
  463. /* NOTE: if no data left, we return the last keyboard one
  464. (needed for EMM386) */
  465. /* XXX: need a timer to do things correctly */
  466. index = q->rptr - 1;
  467. if (index < 0)
  468. index = PS2_QUEUE_SIZE - 1;
  469. val = q->data[index];
  470. } else {
  471. val = q->data[q->rptr];
  472. if (++q->rptr == PS2_QUEUE_SIZE)
  473. q->rptr = 0;
  474. q->count--;
  475. /* reading deasserts IRQ */
  476. s->update_irq(s->update_arg, 0);
  477. /* reassert IRQs if data left */
  478. s->update_irq(s->update_arg, q->count != 0);
  479. }
  480. return val;
  481. }
  482. static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
  483. {
  484. trace_ps2_set_ledstate(s, ledstate);
  485. s->ledstate = ledstate;
  486. kbd_put_ledstate(ledstate);
  487. }
  488. static void ps2_reset_keyboard(PS2KbdState *s)
  489. {
  490. trace_ps2_reset_keyboard(s);
  491. s->scan_enabled = 1;
  492. s->scancode_set = 2;
  493. ps2_reset_queue(&s->common);
  494. ps2_set_ledstate(s, 0);
  495. }
  496. void ps2_write_keyboard(void *opaque, int val)
  497. {
  498. PS2KbdState *s = (PS2KbdState *)opaque;
  499. trace_ps2_write_keyboard(opaque, val);
  500. switch(s->common.write_cmd) {
  501. default:
  502. case -1:
  503. switch(val) {
  504. case 0x00:
  505. ps2_queue(&s->common, KBD_REPLY_ACK);
  506. break;
  507. case 0x05:
  508. ps2_queue(&s->common, KBD_REPLY_RESEND);
  509. break;
  510. case KBD_CMD_GET_ID:
  511. /* We emulate a MF2 AT keyboard here */
  512. if (s->translate)
  513. ps2_queue_3(&s->common,
  514. KBD_REPLY_ACK,
  515. KBD_REPLY_ID,
  516. 0x41);
  517. else
  518. ps2_queue_3(&s->common,
  519. KBD_REPLY_ACK,
  520. KBD_REPLY_ID,
  521. 0x83);
  522. break;
  523. case KBD_CMD_ECHO:
  524. ps2_queue(&s->common, KBD_CMD_ECHO);
  525. break;
  526. case KBD_CMD_ENABLE:
  527. s->scan_enabled = 1;
  528. ps2_queue(&s->common, KBD_REPLY_ACK);
  529. break;
  530. case KBD_CMD_SCANCODE:
  531. case KBD_CMD_SET_LEDS:
  532. case KBD_CMD_SET_RATE:
  533. s->common.write_cmd = val;
  534. ps2_queue(&s->common, KBD_REPLY_ACK);
  535. break;
  536. case KBD_CMD_RESET_DISABLE:
  537. ps2_reset_keyboard(s);
  538. s->scan_enabled = 0;
  539. ps2_queue(&s->common, KBD_REPLY_ACK);
  540. break;
  541. case KBD_CMD_RESET_ENABLE:
  542. ps2_reset_keyboard(s);
  543. s->scan_enabled = 1;
  544. ps2_queue(&s->common, KBD_REPLY_ACK);
  545. break;
  546. case KBD_CMD_RESET:
  547. ps2_reset_keyboard(s);
  548. ps2_queue_2(&s->common,
  549. KBD_REPLY_ACK,
  550. KBD_REPLY_POR);
  551. break;
  552. default:
  553. ps2_queue(&s->common, KBD_REPLY_RESEND);
  554. break;
  555. }
  556. break;
  557. case KBD_CMD_SCANCODE:
  558. if (val == 0) {
  559. if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
  560. ps2_queue(&s->common, KBD_REPLY_ACK);
  561. ps2_put_keycode(s, s->scancode_set);
  562. }
  563. } else if (val >= 1 && val <= 3) {
  564. s->scancode_set = val;
  565. ps2_queue(&s->common, KBD_REPLY_ACK);
  566. } else {
  567. ps2_queue(&s->common, KBD_REPLY_RESEND);
  568. }
  569. s->common.write_cmd = -1;
  570. break;
  571. case KBD_CMD_SET_LEDS:
  572. ps2_set_ledstate(s, val);
  573. ps2_queue(&s->common, KBD_REPLY_ACK);
  574. s->common.write_cmd = -1;
  575. break;
  576. case KBD_CMD_SET_RATE:
  577. ps2_queue(&s->common, KBD_REPLY_ACK);
  578. s->common.write_cmd = -1;
  579. break;
  580. }
  581. }
  582. /* Set the scancode translation mode.
  583. 0 = raw scancodes.
  584. 1 = translated scancodes (used by qemu internally). */
  585. void ps2_keyboard_set_translation(void *opaque, int mode)
  586. {
  587. PS2KbdState *s = (PS2KbdState *)opaque;
  588. trace_ps2_keyboard_set_translation(opaque, mode);
  589. s->translate = mode;
  590. }
  591. static int ps2_mouse_send_packet(PS2MouseState *s)
  592. {
  593. const int needed = 3 + (s->mouse_type - 2);
  594. unsigned int b;
  595. int dx1, dy1, dz1;
  596. if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
  597. return 0;
  598. }
  599. dx1 = s->mouse_dx;
  600. dy1 = s->mouse_dy;
  601. dz1 = s->mouse_dz;
  602. /* XXX: increase range to 8 bits ? */
  603. if (dx1 > 127)
  604. dx1 = 127;
  605. else if (dx1 < -127)
  606. dx1 = -127;
  607. if (dy1 > 127)
  608. dy1 = 127;
  609. else if (dy1 < -127)
  610. dy1 = -127;
  611. b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
  612. ps2_queue_noirq(&s->common, b);
  613. ps2_queue_noirq(&s->common, dx1 & 0xff);
  614. ps2_queue_noirq(&s->common, dy1 & 0xff);
  615. /* extra byte for IMPS/2 or IMEX */
  616. switch(s->mouse_type) {
  617. default:
  618. break;
  619. case 3:
  620. if (dz1 > 127)
  621. dz1 = 127;
  622. else if (dz1 < -127)
  623. dz1 = -127;
  624. ps2_queue_noirq(&s->common, dz1 & 0xff);
  625. break;
  626. case 4:
  627. if (dz1 > 7)
  628. dz1 = 7;
  629. else if (dz1 < -7)
  630. dz1 = -7;
  631. b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
  632. ps2_queue_noirq(&s->common, b);
  633. break;
  634. }
  635. ps2_raise_irq(&s->common);
  636. trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
  637. /* update deltas */
  638. s->mouse_dx -= dx1;
  639. s->mouse_dy -= dy1;
  640. s->mouse_dz -= dz1;
  641. return 1;
  642. }
  643. static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
  644. InputEvent *evt)
  645. {
  646. static const int bmap[INPUT_BUTTON__MAX] = {
  647. [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT,
  648. [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
  649. [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT,
  650. [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE,
  651. [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA,
  652. };
  653. PS2MouseState *s = (PS2MouseState *)dev;
  654. InputMoveEvent *move;
  655. InputBtnEvent *btn;
  656. /* check if deltas are recorded when disabled */
  657. if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
  658. return;
  659. switch (evt->type) {
  660. case INPUT_EVENT_KIND_REL:
  661. move = evt->u.rel.data;
  662. if (move->axis == INPUT_AXIS_X) {
  663. s->mouse_dx += move->value;
  664. } else if (move->axis == INPUT_AXIS_Y) {
  665. s->mouse_dy -= move->value;
  666. }
  667. break;
  668. case INPUT_EVENT_KIND_BTN:
  669. btn = evt->u.btn.data;
  670. if (btn->down) {
  671. s->mouse_buttons |= bmap[btn->button];
  672. if (btn->button == INPUT_BUTTON_WHEEL_UP) {
  673. s->mouse_dz--;
  674. } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
  675. s->mouse_dz++;
  676. }
  677. } else {
  678. s->mouse_buttons &= ~bmap[btn->button];
  679. }
  680. break;
  681. default:
  682. /* keep gcc happy */
  683. break;
  684. }
  685. }
  686. static void ps2_mouse_sync(DeviceState *dev)
  687. {
  688. PS2MouseState *s = (PS2MouseState *)dev;
  689. /* do not sync while disabled to prevent stream corruption */
  690. if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
  691. return;
  692. }
  693. if (s->mouse_buttons) {
  694. qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
  695. }
  696. if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
  697. /* if not remote, send event. Multiple events are sent if
  698. too big deltas */
  699. while (ps2_mouse_send_packet(s)) {
  700. if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
  701. break;
  702. }
  703. }
  704. }
  705. void ps2_mouse_fake_event(void *opaque)
  706. {
  707. PS2MouseState *s = opaque;
  708. trace_ps2_mouse_fake_event(opaque);
  709. s->mouse_dx++;
  710. ps2_mouse_sync(opaque);
  711. }
  712. void ps2_write_mouse(void *opaque, int val)
  713. {
  714. PS2MouseState *s = (PS2MouseState *)opaque;
  715. trace_ps2_write_mouse(opaque, val);
  716. #ifdef DEBUG_MOUSE
  717. printf("kbd: write mouse 0x%02x\n", val);
  718. #endif
  719. switch(s->common.write_cmd) {
  720. default:
  721. case -1:
  722. /* mouse command */
  723. if (s->mouse_wrap) {
  724. if (val == AUX_RESET_WRAP) {
  725. s->mouse_wrap = 0;
  726. ps2_queue(&s->common, AUX_ACK);
  727. return;
  728. } else if (val != AUX_RESET) {
  729. ps2_queue(&s->common, val);
  730. return;
  731. }
  732. }
  733. switch(val) {
  734. case AUX_SET_SCALE11:
  735. s->mouse_status &= ~MOUSE_STATUS_SCALE21;
  736. ps2_queue(&s->common, AUX_ACK);
  737. break;
  738. case AUX_SET_SCALE21:
  739. s->mouse_status |= MOUSE_STATUS_SCALE21;
  740. ps2_queue(&s->common, AUX_ACK);
  741. break;
  742. case AUX_SET_STREAM:
  743. s->mouse_status &= ~MOUSE_STATUS_REMOTE;
  744. ps2_queue(&s->common, AUX_ACK);
  745. break;
  746. case AUX_SET_WRAP:
  747. s->mouse_wrap = 1;
  748. ps2_queue(&s->common, AUX_ACK);
  749. break;
  750. case AUX_SET_REMOTE:
  751. s->mouse_status |= MOUSE_STATUS_REMOTE;
  752. ps2_queue(&s->common, AUX_ACK);
  753. break;
  754. case AUX_GET_TYPE:
  755. ps2_queue_2(&s->common,
  756. AUX_ACK,
  757. s->mouse_type);
  758. break;
  759. case AUX_SET_RES:
  760. case AUX_SET_SAMPLE:
  761. s->common.write_cmd = val;
  762. ps2_queue(&s->common, AUX_ACK);
  763. break;
  764. case AUX_GET_SCALE:
  765. ps2_queue_4(&s->common,
  766. AUX_ACK,
  767. s->mouse_status,
  768. s->mouse_resolution,
  769. s->mouse_sample_rate);
  770. break;
  771. case AUX_POLL:
  772. ps2_queue(&s->common, AUX_ACK);
  773. ps2_mouse_send_packet(s);
  774. break;
  775. case AUX_ENABLE_DEV:
  776. s->mouse_status |= MOUSE_STATUS_ENABLED;
  777. ps2_queue(&s->common, AUX_ACK);
  778. break;
  779. case AUX_DISABLE_DEV:
  780. s->mouse_status &= ~MOUSE_STATUS_ENABLED;
  781. ps2_queue(&s->common, AUX_ACK);
  782. break;
  783. case AUX_SET_DEFAULT:
  784. s->mouse_sample_rate = 100;
  785. s->mouse_resolution = 2;
  786. s->mouse_status = 0;
  787. ps2_queue(&s->common, AUX_ACK);
  788. break;
  789. case AUX_RESET:
  790. s->mouse_sample_rate = 100;
  791. s->mouse_resolution = 2;
  792. s->mouse_status = 0;
  793. s->mouse_type = 0;
  794. ps2_reset_queue(&s->common);
  795. ps2_queue_3(&s->common,
  796. AUX_ACK,
  797. 0xaa,
  798. s->mouse_type);
  799. break;
  800. default:
  801. break;
  802. }
  803. break;
  804. case AUX_SET_SAMPLE:
  805. s->mouse_sample_rate = val;
  806. /* detect IMPS/2 or IMEX */
  807. switch(s->mouse_detect_state) {
  808. default:
  809. case 0:
  810. if (val == 200)
  811. s->mouse_detect_state = 1;
  812. break;
  813. case 1:
  814. if (val == 100)
  815. s->mouse_detect_state = 2;
  816. else if (val == 200)
  817. s->mouse_detect_state = 3;
  818. else
  819. s->mouse_detect_state = 0;
  820. break;
  821. case 2:
  822. if (val == 80)
  823. s->mouse_type = 3; /* IMPS/2 */
  824. s->mouse_detect_state = 0;
  825. break;
  826. case 3:
  827. if (val == 80)
  828. s->mouse_type = 4; /* IMEX */
  829. s->mouse_detect_state = 0;
  830. break;
  831. }
  832. ps2_queue(&s->common, AUX_ACK);
  833. s->common.write_cmd = -1;
  834. break;
  835. case AUX_SET_RES:
  836. s->mouse_resolution = val;
  837. ps2_queue(&s->common, AUX_ACK);
  838. s->common.write_cmd = -1;
  839. break;
  840. }
  841. }
  842. static void ps2_common_reset(PS2State *s)
  843. {
  844. s->write_cmd = -1;
  845. ps2_reset_queue(s);
  846. s->update_irq(s->update_arg, 0);
  847. }
  848. static void ps2_common_post_load(PS2State *s)
  849. {
  850. PS2Queue *q = &s->queue;
  851. uint8_t i, size;
  852. uint8_t tmp_data[PS2_QUEUE_SIZE];
  853. /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
  854. size = q->count;
  855. if (q->count < 0) {
  856. size = 0;
  857. } else if (q->count > PS2_QUEUE_SIZE) {
  858. size = PS2_QUEUE_SIZE;
  859. }
  860. /* move the queue elements to the start of data array */
  861. for (i = 0; i < size; i++) {
  862. if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
  863. q->rptr = 0;
  864. }
  865. tmp_data[i] = q->data[q->rptr++];
  866. }
  867. memcpy(q->data, tmp_data, size);
  868. /* reset rptr/wptr/count */
  869. q->rptr = 0;
  870. q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size;
  871. q->count = size;
  872. }
  873. static void ps2_kbd_reset(void *opaque)
  874. {
  875. PS2KbdState *s = (PS2KbdState *) opaque;
  876. trace_ps2_kbd_reset(opaque);
  877. ps2_common_reset(&s->common);
  878. s->scan_enabled = 1;
  879. s->translate = 0;
  880. s->scancode_set = 2;
  881. s->modifiers = 0;
  882. }
  883. static void ps2_mouse_reset(void *opaque)
  884. {
  885. PS2MouseState *s = (PS2MouseState *) opaque;
  886. trace_ps2_mouse_reset(opaque);
  887. ps2_common_reset(&s->common);
  888. s->mouse_status = 0;
  889. s->mouse_resolution = 0;
  890. s->mouse_sample_rate = 0;
  891. s->mouse_wrap = 0;
  892. s->mouse_type = 0;
  893. s->mouse_detect_state = 0;
  894. s->mouse_dx = 0;
  895. s->mouse_dy = 0;
  896. s->mouse_dz = 0;
  897. s->mouse_buttons = 0;
  898. }
  899. static const VMStateDescription vmstate_ps2_common = {
  900. .name = "PS2 Common State",
  901. .version_id = 3,
  902. .minimum_version_id = 2,
  903. .fields = (VMStateField[]) {
  904. VMSTATE_INT32(write_cmd, PS2State),
  905. VMSTATE_INT32(queue.rptr, PS2State),
  906. VMSTATE_INT32(queue.wptr, PS2State),
  907. VMSTATE_INT32(queue.count, PS2State),
  908. VMSTATE_BUFFER(queue.data, PS2State),
  909. VMSTATE_END_OF_LIST()
  910. }
  911. };
  912. static bool ps2_keyboard_ledstate_needed(void *opaque)
  913. {
  914. PS2KbdState *s = opaque;
  915. return s->ledstate != 0; /* 0 is default state */
  916. }
  917. static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
  918. {
  919. PS2KbdState *s = opaque;
  920. kbd_put_ledstate(s->ledstate);
  921. return 0;
  922. }
  923. static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
  924. .name = "ps2kbd/ledstate",
  925. .version_id = 3,
  926. .minimum_version_id = 2,
  927. .post_load = ps2_kbd_ledstate_post_load,
  928. .needed = ps2_keyboard_ledstate_needed,
  929. .fields = (VMStateField[]) {
  930. VMSTATE_INT32(ledstate, PS2KbdState),
  931. VMSTATE_END_OF_LIST()
  932. }
  933. };
  934. static bool ps2_keyboard_need_high_bit_needed(void *opaque)
  935. {
  936. PS2KbdState *s = opaque;
  937. return s->need_high_bit != 0; /* 0 is the usual state */
  938. }
  939. static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
  940. .name = "ps2kbd/need_high_bit",
  941. .version_id = 1,
  942. .minimum_version_id = 1,
  943. .needed = ps2_keyboard_need_high_bit_needed,
  944. .fields = (VMStateField[]) {
  945. VMSTATE_BOOL(need_high_bit, PS2KbdState),
  946. VMSTATE_END_OF_LIST()
  947. }
  948. };
  949. static int ps2_kbd_post_load(void* opaque, int version_id)
  950. {
  951. PS2KbdState *s = (PS2KbdState*)opaque;
  952. PS2State *ps2 = &s->common;
  953. if (version_id == 2)
  954. s->scancode_set=2;
  955. ps2_common_post_load(ps2);
  956. return 0;
  957. }
  958. static int ps2_kbd_pre_save(void *opaque)
  959. {
  960. PS2KbdState *s = (PS2KbdState *)opaque;
  961. PS2State *ps2 = &s->common;
  962. ps2_common_post_load(ps2);
  963. return 0;
  964. }
  965. static const VMStateDescription vmstate_ps2_keyboard = {
  966. .name = "ps2kbd",
  967. .version_id = 3,
  968. .minimum_version_id = 2,
  969. .post_load = ps2_kbd_post_load,
  970. .pre_save = ps2_kbd_pre_save,
  971. .fields = (VMStateField[]) {
  972. VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
  973. VMSTATE_INT32(scan_enabled, PS2KbdState),
  974. VMSTATE_INT32(translate, PS2KbdState),
  975. VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
  976. VMSTATE_END_OF_LIST()
  977. },
  978. .subsections = (const VMStateDescription*[]) {
  979. &vmstate_ps2_keyboard_ledstate,
  980. &vmstate_ps2_keyboard_need_high_bit,
  981. NULL
  982. }
  983. };
  984. static int ps2_mouse_post_load(void *opaque, int version_id)
  985. {
  986. PS2MouseState *s = (PS2MouseState *)opaque;
  987. PS2State *ps2 = &s->common;
  988. ps2_common_post_load(ps2);
  989. return 0;
  990. }
  991. static int ps2_mouse_pre_save(void *opaque)
  992. {
  993. PS2MouseState *s = (PS2MouseState *)opaque;
  994. PS2State *ps2 = &s->common;
  995. ps2_common_post_load(ps2);
  996. return 0;
  997. }
  998. static const VMStateDescription vmstate_ps2_mouse = {
  999. .name = "ps2mouse",
  1000. .version_id = 2,
  1001. .minimum_version_id = 2,
  1002. .post_load = ps2_mouse_post_load,
  1003. .pre_save = ps2_mouse_pre_save,
  1004. .fields = (VMStateField[]) {
  1005. VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
  1006. VMSTATE_UINT8(mouse_status, PS2MouseState),
  1007. VMSTATE_UINT8(mouse_resolution, PS2MouseState),
  1008. VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
  1009. VMSTATE_UINT8(mouse_wrap, PS2MouseState),
  1010. VMSTATE_UINT8(mouse_type, PS2MouseState),
  1011. VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
  1012. VMSTATE_INT32(mouse_dx, PS2MouseState),
  1013. VMSTATE_INT32(mouse_dy, PS2MouseState),
  1014. VMSTATE_INT32(mouse_dz, PS2MouseState),
  1015. VMSTATE_UINT8(mouse_buttons, PS2MouseState),
  1016. VMSTATE_END_OF_LIST()
  1017. }
  1018. };
  1019. static QemuInputHandler ps2_keyboard_handler = {
  1020. .name = "QEMU PS/2 Keyboard",
  1021. .mask = INPUT_EVENT_MASK_KEY,
  1022. .event = ps2_keyboard_event,
  1023. };
  1024. void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
  1025. {
  1026. PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
  1027. trace_ps2_kbd_init(s);
  1028. s->common.update_irq = update_irq;
  1029. s->common.update_arg = update_arg;
  1030. s->scancode_set = 2;
  1031. vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
  1032. qemu_input_handler_register((DeviceState *)s,
  1033. &ps2_keyboard_handler);
  1034. qemu_register_reset(ps2_kbd_reset, s);
  1035. return s;
  1036. }
  1037. static QemuInputHandler ps2_mouse_handler = {
  1038. .name = "QEMU PS/2 Mouse",
  1039. .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
  1040. .event = ps2_mouse_event,
  1041. .sync = ps2_mouse_sync,
  1042. };
  1043. void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
  1044. {
  1045. PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
  1046. trace_ps2_mouse_init(s);
  1047. s->common.update_irq = update_irq;
  1048. s->common.update_arg = update_arg;
  1049. vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
  1050. qemu_input_handler_register((DeviceState *)s,
  1051. &ps2_mouse_handler);
  1052. qemu_register_reset(ps2_mouse_reset, s);
  1053. return s;
  1054. }