~ubuntu-branches/ubuntu/trusty/virtualbox/trusty-proposed

« back to all changes in this revision

Viewing changes to src/VBox/Devices/Input/DevPS2.cpp

  • Committer: Package Import Robot
  • Author(s): Felix Geyer
  • Date: 2013-03-07 16:38:36 UTC
  • mfrom: (1.1.13) (3.1.20 experimental)
  • Revision ID: package-import@ubuntu.com-20130307163836-p93jpbgx39tp3gb4
Tags: 4.2.8-dfsg-0ubuntu1
* New upstream release. (Closes: #691148)
  - Fixes compatibility with kernel 3.8. (Closes: #700823; LP: #1101867)
* Switch to my @debian.org email address.
* Move package to contrib as virtualbox 4.2 needs a non-free compiler to
  build the BIOS.
* Build-depend on libdevmapper-dev.
* Refresh patches.
  - Drop 36-fix-ftbfs-xserver-112.patch, cve-2012-3221.patch,
    CVE-2013-0420.patch 37-kcompat-3.6.patch and 38-kcompat-3.7.patch.
* Drop all virtualbox-ose transitional packages.
* Drop the virtualbox-fuse package as vdfuse fails to build with
  virtualbox 4.2.
* Update install files and VBox.sh.
* Bump required kbuild version to 0.1.9998svn2577.
* Fix path to VBoxCreateUSBNode.sh in virtualbox.postinst. (Closes: #700479)
* Add an init script to virtuabox-guest-x11 which loads the vboxvideo
  kernel module. The X Server 1.13 doesn't load it anymore. (Closes: #686994)
* Update man pages. (Closes: #680053)
* Add 36-python-multiarch.patch from Rico Tzschichholz to fix detection of
  python in multiarch paths using pkg-config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 */
5
5
 
6
6
/*
7
 
 * Copyright (C) 2006-2010 Oracle Corporation
 
7
 * Copyright (C) 2006-2012 Oracle Corporation
8
8
 *
9
9
 * This file is part of VirtualBox Open Source Edition (OSE), as
10
10
 * available from http://www.virtualbox.org. This file is free software;
51
51
#include <iprt/uuid.h>
52
52
 
53
53
#include "VBoxDD.h"
 
54
#include "PS2Dev.h"
54
55
 
55
 
#define PCKBD_SAVED_STATE_VERSION 5
 
56
#define PCKBD_SAVED_STATE_VERSION 6
56
57
 
57
58
 
58
59
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
96
97
#define KBD_CCMD_READ_TSTINP    0xE0    /* Read test inputs T0, T1 */
97
98
#define KBD_CCMD_RESET          0xFE
98
99
 
99
 
/* Keyboard Commands */
100
 
#define KBD_CMD_SET_LEDS        0xED    /* Set keyboard leds */
101
 
#define KBD_CMD_ECHO            0xEE
102
 
#define KBD_CMD_SCANCODE        0xF0    /* Get/set scancode set */
103
 
#define KBD_CMD_GET_ID          0xF2    /* get keyboard ID */
104
 
#define KBD_CMD_SET_RATE        0xF3    /* Set typematic rate */
105
 
#define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
106
 
#define KBD_CMD_RESET_DISABLE   0xF5    /* reset and disable scanning */
107
 
#define KBD_CMD_RESET_ENABLE    0xF6    /* reset and enable scanning */
108
 
#define KBD_CMD_RESET           0xFF    /* Reset */
109
 
 
110
 
/* Keyboard Replies */
111
 
#define KBD_REPLY_POR           0xAA    /* Power on reset */
112
 
#define KBD_REPLY_ACK           0xFA    /* Command ACK */
113
 
#define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
114
 
 
115
100
/* Status Register Bits */
116
101
#define KBD_STAT_OBF            0x01    /* Keyboard output buffer full */
117
102
#define KBD_STAT_IBF            0x02    /* Keyboard input buffer full */
155
140
#define MOUSE_STATUS_ENABLED    0x20
156
141
#define MOUSE_STATUS_SCALE21    0x10
157
142
 
158
 
#define KBD_QUEUE_SIZE 256
159
 
 
160
143
/** Supported mouse protocols */
161
144
enum
162
145
{
171
154
# define MOUSE_REPORT_HORIZONTAL  0x01
172
155
/** @} */
173
156
 
174
 
typedef struct {
175
 
    uint8_t data[KBD_QUEUE_SIZE];
176
 
    int rptr, wptr, count;
177
 
} KBDQueue;
178
 
 
179
157
#define MOUSE_CMD_QUEUE_SIZE 8
180
158
 
181
159
typedef struct {
192
170
} MouseEventQueue;
193
171
 
194
172
typedef struct KBDState {
195
 
    KBDQueue queue;
196
173
    MouseCmdQueue mouse_command_queue;
197
174
    MouseEventQueue mouse_event_queue;
198
175
    uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
200
177
    uint8_t mode;
201
178
    uint8_t dbbout;    /* data buffer byte */
202
179
    /* keyboard state */
203
 
    int32_t kbd_write_cmd;
204
 
    int32_t scan_enabled;
205
180
    int32_t translate;
206
 
    int32_t scancode_set;   /* 1=XT, 2=AT, 3=PS/2 */
 
181
    int32_t xlat_state;
207
182
    /* mouse state */
208
183
    int32_t mouse_write_cmd;
209
184
    uint8_t mouse_status;
220
195
    uint8_t mouse_buttons;
221
196
    uint8_t mouse_buttons_reported;
222
197
 
 
198
    uint32_t    Alignment0;
 
199
 
223
200
    /** Pointer to the device instance - RC. */
224
201
    PPDMDEVINSRC                pDevInsRC;
225
202
    /** Pointer to the device instance - R3 . */
226
203
    PPDMDEVINSR3                pDevInsR3;
227
204
    /** Pointer to the device instance. */
228
205
    PPDMDEVINSR0                pDevInsR0;
 
206
 
229
207
    /** Critical section protecting the state. */
230
208
    PDMCRITSECT                 CritSect;
231
 
    /**
232
 
     * Keyboard port - LUN#0.
233
 
     *
234
 
     * @implements  PDMIBASE
235
 
     * @implements  PDMIKEYBOARDPORT
236
 
     */
237
 
    struct
238
 
    {
239
 
        /** The base interface for the keyboard port. */
240
 
        PDMIBASE                            IBase;
241
 
        /** The keyboard port base interface. */
242
 
        PDMIKEYBOARDPORT                    IPort;
243
209
 
244
 
        /** The base interface of the attached keyboard driver. */
245
 
        R3PTRTYPE(PPDMIBASE)                pDrvBase;
246
 
        /** The keyboard interface of the attached keyboard driver. */
247
 
        R3PTRTYPE(PPDMIKEYBOARDCONNECTOR)   pDrv;
248
 
    } Keyboard;
 
210
    /** Keyboard state (implemented in separate PS2K module). */
 
211
#ifdef VBOX_DEVICE_STRUCT_TESTCASE
 
212
    uint8_t                     KbdFiller[PS2K_STRUCT_FILLER];
 
213
#else
 
214
    PS2K                        Kbd;
 
215
#endif
249
216
 
250
217
    /**
251
218
     * Mouse port - LUN#1.
267
234
    } Mouse;
268
235
} KBDState;
269
236
 
270
 
/* Table to convert from PC scancodes to scan code set 2. */
271
 
static const unsigned char ps2_raw_keycode_set2[128] = {
272
 
      0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
273
 
     21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
274
 
     35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
275
 
     50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
276
 
     11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
277
 
    114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
278
 
     71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
279
 
     19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
280
 
};
281
 
 
282
 
/* Table to convert from PC scancodes to scan code set 3. */
283
 
static const unsigned char ps2_raw_keycode_set3[128] = {
284
 
      0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
285
 
     21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27,
286
 
     35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42,
287
 
     50, 49, 58, 65, 73, 74, 89,124, 25, 41, 20,  5,  6,  4, 12,  3,
288
 
     11,  2, 10,  1,  9,118,126,108,117,125,123,107,115,116,121,105,
289
 
    114,122,112,113,127, 96, 19,120,  7, 15, 23, 31, 39, 47, 55, 63,
290
 
     71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
291
 
     19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
292
 
};
293
 
 
294
237
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
295
238
 
296
239
/* update irq and KBD_STAT_[MOUSE_]OBF */
297
240
static void kbd_update_irq(KBDState *s)
298
241
{
299
 
    KBDQueue *q = &s->queue;
300
242
    MouseCmdQueue *mcq = &s->mouse_command_queue;
301
243
    MouseEventQueue *meq = &s->mouse_event_queue;
302
244
    int irq12_level, irq1_level;
 
245
    uint8_t val;
303
246
 
304
247
    irq1_level = 0;
305
248
    irq12_level = 0;
311
254
    if (!(s->status & KBD_STAT_OBF)) {
312
255
        s->status &= ~KBD_STAT_MOUSE_OBF;
313
256
        /* Keyboard data has priority if both kbd and aux data is available. */
314
 
        if (q->count && !(s->mode & KBD_MODE_DISABLE_KBD))
 
257
        if (!(s->mode & KBD_MODE_DISABLE_KBD) && PS2KByteFromKbd(&s->Kbd, &val) == VINF_SUCCESS)
315
258
        {
316
 
            s->status |= KBD_STAT_OBF;
317
 
            s->dbbout = q->data[q->rptr];
318
 
            if (++q->rptr == KBD_QUEUE_SIZE)
319
 
                q->rptr = 0;
320
 
            q->count--;
 
259
            bool    fHaveData = true;
 
260
 
 
261
            /* If scancode translation is on (it usually is), there's more work to do. */
 
262
            if (s->translate)
 
263
            {
 
264
                uint8_t     xlated_val;
 
265
 
 
266
                s->xlat_state = XlateAT2PC(s->xlat_state, val, &xlated_val);
 
267
                val = xlated_val;
 
268
 
 
269
                /* If the translation state is XS_BREAK, there's nothing to report
 
270
                 * and we keep going until the state changes or there's no more data.
 
271
                 */
 
272
                while (s->xlat_state == XS_BREAK && PS2KByteFromKbd(&s->Kbd, &val) == VINF_SUCCESS)
 
273
                {
 
274
                    s->xlat_state = XlateAT2PC(s->xlat_state, val, &xlated_val);
 
275
                    val = xlated_val;
 
276
                }
 
277
                /* This can happen if the last byte in the queue is F0... */
 
278
                if (s->xlat_state == XS_BREAK)
 
279
                    fHaveData = false;
 
280
            }
 
281
            if (fHaveData)
 
282
            {
 
283
                s->dbbout = val;
 
284
                s->status |= KBD_STAT_OBF;
 
285
            }
321
286
        }
322
 
        else if ((mcq->count || meq->count) /*&& !(s->mode & KBD_MODE_DISABLE_MOUSE)*/)
 
287
        else if ((mcq->count || meq->count) && !(s->mode & KBD_MODE_DISABLE_MOUSE))
323
288
        {
324
289
            s->status |= KBD_STAT_OBF | KBD_STAT_MOUSE_OBF;
325
290
            if (mcq->count)
355
320
    PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), 12, irq12_level);
356
321
}
357
322
 
 
323
void KBCUpdateInterrupts(void *pKbc)
 
324
{
 
325
    KBDState    *s = (KBDState *)pKbc;
 
326
    kbd_update_irq(s);
 
327
}
 
328
 
358
329
static void kbd_queue(KBDState *s, int b, int aux)
359
330
{
360
 
    KBDQueue *q = &s->queue;
361
331
    MouseCmdQueue *mcq = &s->mouse_command_queue;
362
332
    MouseEventQueue *meq = &s->mouse_event_queue;
363
333
 
374
344
    switch (aux)
375
345
    {
376
346
        case 0: /* keyboard */
377
 
            if (q->count >= KBD_QUEUE_SIZE)
378
 
                return;
379
 
            q->data[q->wptr] = b;
380
 
            if (++q->wptr == KBD_QUEUE_SIZE)
381
 
                q->wptr = 0;
382
 
            q->count++;
 
347
            AssertMsgFailed(("kbd_queue() no longer supported for keyboard!\n"));
383
348
            break;
384
349
        case 1: /* mouse command response */
385
350
            if (mcq->count >= MOUSE_CMD_QUEUE_SIZE)
403
368
    kbd_update_irq(s);
404
369
}
405
370
 
406
 
#ifdef IN_RING3
407
 
static void pc_kbd_put_keycode(void *opaque, int keycode)
408
 
{
409
 
    KBDState *s = (KBDState*)opaque;
410
 
 
411
 
    /* XXX: add support for scancode sets 1 and 3 */
412
 
    if (!s->translate && keycode < 0xe0 && s->scancode_set >= 2)
413
 
    {
414
 
        if (keycode & 0x80)
415
 
           kbd_queue(s, 0xf0, 0);
416
 
        if (s->scancode_set == 2)
417
 
            keycode = ps2_raw_keycode_set2[keycode & 0x7f];
418
 
        else if (s->scancode_set == 3)
419
 
            keycode = ps2_raw_keycode_set3[keycode & 0x7f];
420
 
    }
421
 
    kbd_queue(s, keycode, 0);
422
 
}
423
 
#endif /* IN_RING3 */
424
 
 
425
371
static void kbc_dbb_out(void *opaque, uint8_t val)
426
372
{
427
373
    KBDState *s = (KBDState*)opaque;
436
382
static uint32_t kbd_read_status(void *opaque, uint32_t addr)
437
383
{
438
384
    KBDState *s = (KBDState*)opaque;
439
 
    int val;
440
 
    val = s->status;
 
385
    int val = s->status;
 
386
    NOREF(addr);
 
387
 
441
388
#if defined(DEBUG_KBD)
442
389
    Log(("kbd: read status=0x%02x\n", val));
443
390
#endif
448
395
{
449
396
    int rc = VINF_SUCCESS;
450
397
    KBDState *s = (KBDState*)opaque;
 
398
    NOREF(addr);
451
399
 
452
400
#ifdef DEBUG_KBD
453
401
    Log(("kbd: write cmd=0x%02x\n", val));
479
427
# ifndef IN_RING3
480
428
        if (!PDMDevHlpA20IsEnabled(s->CTX_SUFF(pDevIns)))
481
429
        {
482
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
430
            rc = VINF_IOM_R3_IOPORT_WRITE;
483
431
            break;
484
432
        }
485
433
# else /* IN_RING3 */
520
468
    case KBD_CCMD_ENABLE_A20:
521
469
# ifndef IN_RING3
522
470
        if (!PDMDevHlpA20IsEnabled(s->CTX_SUFF(pDevIns)))
523
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
471
            rc = VINF_IOM_R3_IOPORT_WRITE;
524
472
# else /* IN_RING3 */
525
473
        PDMDevHlpA20Set(s->CTX_SUFF(pDevIns), true);
526
474
# endif /* IN_RING3 */
528
476
    case KBD_CCMD_DISABLE_A20:
529
477
# ifndef IN_RING3
530
478
        if (PDMDevHlpA20IsEnabled(s->CTX_SUFF(pDevIns)))
531
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
479
            rc = VINF_IOM_R3_IOPORT_WRITE;
532
480
# else /* IN_RING3 */
533
481
        PDMDevHlpA20Set(s->CTX_SUFF(pDevIns), false);
534
482
# endif /* !IN_RING3 */
541
489
        break;
542
490
    case KBD_CCMD_RESET:
543
491
#ifndef IN_RING3
544
 
        rc = VINF_IOM_HC_IOPORT_WRITE;
 
492
        rc = VINF_IOM_R3_IOPORT_WRITE;
545
493
#else /* IN_RING3 */
546
494
        LogRel(("Reset initiated by keyboard controller\n"));
547
495
        rc = PDMDevHlpVMReset(s->CTX_SUFF(pDevIns));
573
521
{
574
522
    KBDState *s = (KBDState*)opaque;
575
523
    uint32_t val;
 
524
    NOREF(addr);
576
525
 
577
526
    /* Return the current DBB contents. */
578
527
    val = s->dbbout;
593
542
    return val;
594
543
}
595
544
 
596
 
static void kbd_reset_keyboard(KBDState *s)
597
 
{
598
 
    s->scan_enabled = 1;
599
 
    s->scancode_set = 2;
600
 
    /* Flush the keyboard queue. */
601
 
    s->queue.count = 0;
602
 
    s->queue.rptr = 0;
603
 
    s->queue.wptr = 0;
604
 
}
605
 
 
606
 
static int  kbd_write_keyboard(KBDState *s, int val)
607
 
{
608
 
    switch(s->kbd_write_cmd) {
609
 
    default:
610
 
    case -1:
611
 
        switch(val) {
612
 
        case 0x00:
613
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
614
 
            break;
615
 
        case 0x05:
616
 
            kbd_queue(s, KBD_REPLY_RESEND, 0);
617
 
            break;
618
 
        case KBD_CMD_GET_ID:
619
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
620
 
            kbd_queue(s, 0xab, 0);
621
 
            kbd_queue(s, 0x83, 0);
622
 
            break;
623
 
        case KBD_CMD_ECHO:
624
 
            kbd_queue(s, KBD_CMD_ECHO, 0);
625
 
            break;
626
 
        case KBD_CMD_ENABLE:
627
 
            s->scan_enabled = 1;
628
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
629
 
            break;
630
 
        case KBD_CMD_SCANCODE:
631
 
        case KBD_CMD_SET_LEDS:
632
 
        case KBD_CMD_SET_RATE:
633
 
            s->kbd_write_cmd = val;
634
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
635
 
            break;
636
 
        case KBD_CMD_RESET_DISABLE:
637
 
            kbd_reset_keyboard(s);
638
 
            s->scan_enabled = 0;
639
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
640
 
            break;
641
 
        case KBD_CMD_RESET_ENABLE:
642
 
            kbd_reset_keyboard(s);
643
 
            s->scan_enabled = 1;
644
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
645
 
            break;
646
 
        case KBD_CMD_RESET:
647
 
            kbd_reset_keyboard(s);
648
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
649
 
            kbd_queue(s, KBD_REPLY_POR, 0);
650
 
            break;
651
 
        default:
652
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
653
 
            break;
654
 
        }
655
 
        break;
656
 
    case KBD_CMD_SCANCODE:
657
 
#ifdef IN_RING3
658
 
        if (val == 0) {
659
 
            if (s->scancode_set == 1)
660
 
                pc_kbd_put_keycode(s, 0x43);
661
 
            else if (s->scancode_set == 2)
662
 
                pc_kbd_put_keycode(s, 0x41);
663
 
            else if (s->scancode_set == 3)
664
 
                pc_kbd_put_keycode(s, 0x3f);
665
 
        } else {
666
 
            if (val >= 1 && val <= 3) {
667
 
                LogRel(("kbd: scan code set %d selected\n", val));
668
 
                s->scancode_set = val;
669
 
            }
670
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
671
 
        }
672
 
#else
673
 
        return VINF_IOM_HC_IOPORT_WRITE;
674
 
#endif
675
 
    case KBD_CMD_SET_LEDS:
676
 
        {
677
 
#ifdef IN_RING3
678
 
            PDMKEYBLEDS enmLeds = PDMKEYBLEDS_NONE;
679
 
            if (val & 0x01)
680
 
                enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_SCROLLLOCK);
681
 
            if (val & 0x02)
682
 
                enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_NUMLOCK);
683
 
            if (val & 0x04)
684
 
                enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_CAPSLOCK);
685
 
            s->Keyboard.pDrv->pfnLedStatusChange(s->Keyboard.pDrv, enmLeds);
686
 
#else
687
 
            return VINF_IOM_HC_IOPORT_WRITE;
688
 
#endif
689
 
            kbd_queue(s, KBD_REPLY_ACK, 0);
690
 
            s->kbd_write_cmd = -1;
691
 
        }
692
 
        break;
693
 
    case KBD_CMD_SET_RATE:
694
 
        kbd_queue(s, KBD_REPLY_ACK, 0);
695
 
        s->kbd_write_cmd = -1;
696
 
        break;
697
 
    }
698
 
 
699
 
    return VINF_SUCCESS;
 
545
PS2K *GetPS2KFromDevIns(PPDMDEVINS pDevIns)
 
546
{
 
547
    KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
 
548
    return &pThis->Kbd;
700
549
}
701
550
 
702
551
static void kbd_mouse_set_reported_buttons(KBDState *s, unsigned fButtons, unsigned fButtonMask)
799
648
        kbd_mouse_send_imex_byte4(s, fToCmdQueue);
800
649
}
801
650
 
 
651
#ifdef IN_RING3
 
652
 
802
653
static bool kbd_mouse_unreported(KBDState *s)
803
654
{
804
 
   return    s->mouse_dx
805
 
          || s->mouse_dy
806
 
          || s->mouse_dz
807
 
          || s->mouse_dw
808
 
          || s->mouse_buttons != s->mouse_buttons_reported;
 
655
    return s->mouse_dx
 
656
        || s->mouse_dy
 
657
        || s->mouse_dz
 
658
        || s->mouse_dw
 
659
        || s->mouse_buttons != s->mouse_buttons_reported;
809
660
}
810
661
 
811
 
#ifdef IN_RING3
812
662
static size_t kbd_mouse_event_queue_free(KBDState *s)
813
663
{
814
664
    AssertReturn(s->mouse_event_queue.count <= MOUSE_EVENT_QUEUE_SIZE, 0);
850
700
    bool fEnabled = !!(pThis->mouse_status & MOUSE_STATUS_ENABLED);
851
701
    pDrv->pfnReportModes(pDrv, fEnabled, false);
852
702
}
 
703
 
853
704
#endif /* IN_RING3 */
854
705
 
855
706
static int kbd_write_mouse(KBDState *s, int val)
924
775
            kbd_mouse_update_downstream_status(s);
925
776
#else
926
777
            LogRelFlowFunc(("Enabling mouse device, R0 stub\n"));
927
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
778
            rc = VINF_IOM_R3_IOPORT_WRITE;
928
779
#endif
929
780
            break;
930
781
        case AUX_DISABLE_DEV:
937
788
            s->mouse_event_queue.wptr = 0;
938
789
            kbd_mouse_update_downstream_status(s);
939
790
#else
940
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
791
            rc = VINF_IOM_R3_IOPORT_WRITE;
941
792
#endif
942
793
            break;
943
794
        case AUX_SET_DEFAULT:
948
799
            kbd_queue(s, AUX_ACK, 1);
949
800
            kbd_mouse_update_downstream_status(s);
950
801
#else
951
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
802
            rc = VINF_IOM_R3_IOPORT_WRITE;
952
803
#endif
953
804
            break;
954
805
        case AUX_RESET:
966
817
            s->mouse_event_queue.wptr = 0;
967
818
            kbd_mouse_update_downstream_status(s);
968
819
#else
969
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
820
            rc = VINF_IOM_R3_IOPORT_WRITE;
970
821
#endif
971
822
            break;
972
823
        default:
1058
909
{
1059
910
    int rc = VINF_SUCCESS;
1060
911
    KBDState *s = (KBDState*)opaque;
 
912
    NOREF(addr);
1061
913
 
1062
914
#ifdef DEBUG_KBD
1063
915
    Log(("kbd: write data=0x%02x\n", val));
1067
919
    case 0:
1068
920
        /* Automatically enables keyboard interface. */
1069
921
        s->mode &= ~KBD_MODE_DISABLE_KBD;
1070
 
        rc = kbd_write_keyboard(s, val);
 
922
        rc = PS2KByteToKbd(&s->Kbd, val);
 
923
        if (rc == VINF_SUCCESS)
 
924
            kbd_update_irq(s);
1071
925
        break;
1072
926
    case KBD_CCMD_WRITE_MODE:
1073
927
        s->mode = val;
1084
938
#ifdef TARGET_I386
1085
939
#  ifndef IN_RING3
1086
940
        if (PDMDevHlpA20IsEnabled(s->CTX_SUFF(pDevIns)) != !!(val & 2))
1087
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
941
            rc = VINF_IOM_R3_IOPORT_WRITE;
1088
942
#  else /* IN_RING3 */
1089
943
        PDMDevHlpA20Set(s->CTX_SUFF(pDevIns), !!(val & 2));
1090
944
#  endif /* !IN_RING3 */
1091
945
#endif
1092
946
        if (!(val & 1)) {
1093
947
# ifndef IN_RING3
1094
 
            rc = VINF_IOM_HC_IOPORT_WRITE;
 
948
            rc = VINF_IOM_R3_IOPORT_WRITE;
1095
949
# else
1096
950
            rc = PDMDevHlpVMReset(s->CTX_SUFF(pDevIns));
1097
951
# endif
1098
952
        }
1099
953
        break;
1100
954
    case KBD_CCMD_WRITE_MOUSE:
 
955
        /* Automatically enables aux interface. */
 
956
        s->mode &= ~KBD_MODE_DISABLE_MOUSE;
1101
957
        rc = kbd_write_mouse(s, val);
1102
958
        break;
1103
959
    default:
1104
960
        break;
1105
961
    }
1106
 
    if (rc != VINF_IOM_HC_IOPORT_WRITE)
 
962
    if (rc != VINF_IOM_R3_IOPORT_WRITE)
1107
963
        s->write_cmd = 0;
1108
964
    return rc;
1109
965
}
1113
969
static void kbd_reset(void *opaque)
1114
970
{
1115
971
    KBDState *s = (KBDState*)opaque;
1116
 
    KBDQueue *q;
1117
972
    MouseCmdQueue *mcq;
1118
973
    MouseEventQueue *meq;
1119
974
 
1120
 
    s->kbd_write_cmd = -1;
1121
975
    s->mouse_write_cmd = -1;
1122
976
    s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
1123
977
    s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
1124
978
    /* Resetting everything, keyword was not working right on NT4 reboot. */
1125
979
    s->write_cmd = 0;
1126
 
    s->scan_enabled = 0;
1127
980
    s->translate = 0;
1128
 
    s->scancode_set = 2;
1129
981
    if (s->mouse_status)
1130
982
    {
1131
983
        s->mouse_status = 0;
1143
995
    s->mouse_flags = 0;
1144
996
    s->mouse_buttons = 0;
1145
997
    s->mouse_buttons_reported = 0;
1146
 
    q = &s->queue;
1147
 
    q->rptr = 0;
1148
 
    q->wptr = 0;
1149
 
    q->count = 0;
1150
998
    mcq = &s->mouse_command_queue;
1151
999
    mcq->rptr = 0;
1152
1000
    mcq->wptr = 0;
1166
1014
    qemu_put_8s(f, &s->write_cmd);
1167
1015
    qemu_put_8s(f, &s->status);
1168
1016
    qemu_put_8s(f, &s->mode);
1169
 
    qemu_put_be32s(f, &s->kbd_write_cmd);
1170
 
    qemu_put_be32s(f, &s->scan_enabled);
 
1017
    qemu_put_8s(f, &s->dbbout);
1171
1018
    qemu_put_be32s(f, &s->mouse_write_cmd);
1172
1019
    qemu_put_8s(f, &s->mouse_status);
1173
1020
    qemu_put_8s(f, &s->mouse_resolution);
1183
1030
    qemu_put_8s(f, &s->mouse_buttons);
1184
1031
    qemu_put_8s(f, &s->mouse_buttons_reported);
1185
1032
 
1186
 
    /* XXX: s->scancode_set isn't being saved, but we only really support set 2,
1187
 
     * so no real harm done.
1188
 
     */
1189
 
 
1190
 
    /*
1191
 
     * We have to save the queues too.
1192
 
     */
1193
 
    cItems = s->queue.count;
1194
 
    SSMR3PutU32(f, cItems);
1195
 
    for (i = s->queue.rptr; cItems-- > 0; i = (i + 1) % RT_ELEMENTS(s->queue.data))
1196
 
        SSMR3PutU8(f, s->queue.data[i]);
1197
 
    Log(("kbd_save: %d keyboard queue items stored\n", s->queue.count));
1198
 
 
1199
1033
    cItems = s->mouse_command_queue.count;
1200
1034
    SSMR3PutU32(f, cItems);
1201
1035
    for (i = s->mouse_command_queue.rptr; cItems-- > 0; i = (i + 1) % RT_ELEMENTS(s->mouse_command_queue.data))
1231
1065
    qemu_get_8s(f, &s->write_cmd);
1232
1066
    qemu_get_8s(f, &s->status);
1233
1067
    qemu_get_8s(f, &s->mode);
1234
 
    qemu_get_be32s(f, (uint32_t *)&s->kbd_write_cmd);
1235
 
    qemu_get_be32s(f, (uint32_t *)&s->scan_enabled);
 
1068
    if (version_id <= 5)
 
1069
    {
 
1070
        qemu_get_be32s(f, (uint32_t *)&u32Dummy);
 
1071
        qemu_get_be32s(f, (uint32_t *)&u32Dummy);
 
1072
    }
 
1073
    else
 
1074
    {
 
1075
        qemu_get_8s(f, &s->dbbout);
 
1076
    }
1236
1077
    qemu_get_be32s(f, (uint32_t *)&s->mouse_write_cmd);
1237
1078
    qemu_get_8s(f, &s->mouse_status);
1238
1079
    qemu_get_8s(f, &s->mouse_resolution);
1258
1099
        SSMR3GetU8(f, &s->mouse_buttons_reported);
1259
1100
    if (version_id == 4)
1260
1101
        SSMR3GetU8(f, &u8Dummy);
1261
 
    s->queue.count = 0;
1262
 
    s->queue.rptr = 0;
1263
 
    s->queue.wptr = 0;
1264
1102
    s->mouse_command_queue.count = 0;
1265
1103
    s->mouse_command_queue.rptr = 0;
1266
1104
    s->mouse_command_queue.wptr = 0;
1270
1108
 
1271
1109
    /* Determine the translation state. */
1272
1110
    s->translate = (s->mode & KBD_MODE_KCC) == KBD_MODE_KCC;
1273
 
    s->scancode_set = 2;    /* XXX: See comment in kbd_save(). */
1274
1111
 
1275
1112
    /*
1276
1113
     * Load the queues
1277
1114
     */
1278
 
    rc = SSMR3GetU32(f, &u32);
1279
 
    if (RT_FAILURE(rc))
1280
 
        return rc;
1281
 
    if (u32 > RT_ELEMENTS(s->queue.data))
1282
 
    {
1283
 
        AssertMsgFailed(("u32=%#x\n", u32));
1284
 
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
1285
 
    }
1286
 
    for (i = 0; i < u32; i++)
1287
 
    {
1288
 
        rc = SSMR3GetU8(f, &s->queue.data[i]);
 
1115
    if (version_id <= 5)
 
1116
    {
 
1117
        rc = SSMR3GetU32(f, &u32);
1289
1118
        if (RT_FAILURE(rc))
1290
1119
            return rc;
 
1120
        for (i = 0; i < u32; i++)
 
1121
        {
 
1122
            rc = SSMR3GetU8(f, &u8Dummy);
 
1123
            if (RT_FAILURE(rc))
 
1124
                return rc;
 
1125
        }
 
1126
        Log(("kbd_load: %d keyboard queue items discarded from old saved state\n", u32));
1291
1127
    }
1292
 
    s->queue.wptr = u32 % RT_ELEMENTS(s->queue.data);
1293
 
    s->queue.count = u32;
1294
 
    Log(("kbd_load: %d keyboard queue items loaded\n", u32));
1295
1128
 
1296
1129
    rc = SSMR3GetU32(f, &u32);
1297
1130
    if (RT_FAILURE(rc))
1366
1199
    if (cb == 1)
1367
1200
    {
1368
1201
        KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
1369
 
        int rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_READ);
 
1202
        int rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_R3_IOPORT_READ);
1370
1203
        if (RT_LIKELY(rc == VINF_SUCCESS))
1371
1204
        {
1372
1205
            *pu32 = kbd_read_data(pThis, Port);
1397
1230
    if (cb == 1)
1398
1231
    {
1399
1232
        KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
1400
 
        rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_WRITE);
 
1233
        rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_R3_IOPORT_WRITE);
1401
1234
        if (RT_LIKELY(rc == VINF_SUCCESS))
1402
1235
        {
1403
1236
            rc = kbd_write_data(pThis, Port, u32);
1427
1260
    if (cb == 1)
1428
1261
    {
1429
1262
        KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
1430
 
        int rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_READ);
 
1263
        int rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_R3_IOPORT_READ);
1431
1264
        if (RT_LIKELY(rc == VINF_SUCCESS))
1432
1265
        {
1433
1266
            *pu32 = kbd_read_status(pThis, Port);
1458
1291
    if (cb == 1)
1459
1292
    {
1460
1293
        KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
1461
 
        rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_WRITE);
 
1294
        rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_R3_IOPORT_WRITE);
1462
1295
        if (RT_LIKELY(rc == VINF_SUCCESS))
1463
1296
        {
1464
1297
            rc = kbd_write_command(pThis, Port, u32);
1482
1315
 */
1483
1316
static DECLCALLBACK(int) kbdSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
1484
1317
{
1485
 
    kbd_save(pSSMHandle, PDMINS_2_DATA(pDevIns, KBDState *));
 
1318
    KBDState    *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
 
1319
    kbd_save(pSSMHandle, pThis);
 
1320
    PS2KSaveState(pSSMHandle, &pThis->Kbd);
1486
1321
    return VINF_SUCCESS;
1487
1322
}
1488
1323
 
1498
1333
 */
1499
1334
static DECLCALLBACK(int) kbdLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
1500
1335
{
 
1336
    KBDState    *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
 
1337
    int rc;
 
1338
 
1501
1339
    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
1502
 
    return kbd_load(pSSMHandle, PDMINS_2_DATA(pDevIns, KBDState *), uVersion);
 
1340
    rc = kbd_load(pSSMHandle, pThis, uVersion);
 
1341
    if (uVersion >= 6)
 
1342
        rc = PS2KLoadState(pSSMHandle, &pThis->Kbd, uVersion);
 
1343
    return rc;
1503
1344
}
1504
1345
 
1505
1346
/**
1513
1354
    KBDState   *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
1514
1355
 
1515
1356
    kbd_reset(pThis);
1516
 
    /* Activate the PS/2 keyboard by default. */
1517
 
    if (pThis->Keyboard.pDrv)
1518
 
        pThis->Keyboard.pDrv->pfnSetActive(pThis->Keyboard.pDrv, true);
1519
 
}
1520
 
 
1521
 
 
1522
 
/* -=-=-=-=-=- Keyboard: IBase  -=-=-=-=-=- */
1523
 
 
1524
 
/**
1525
 
 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
1526
 
 */
1527
 
static DECLCALLBACK(void *)  kbdKeyboardQueryInterface(PPDMIBASE pInterface, const char *pszIID)
1528
 
{
1529
 
    KBDState *pThis = RT_FROM_MEMBER(pInterface, KBDState, Keyboard.IBase);
1530
 
    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->Keyboard.IBase);
1531
 
    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIKEYBOARDPORT, &pThis->Keyboard.IPort);
1532
 
    return NULL;
1533
 
}
1534
 
 
1535
 
 
1536
 
/* -=-=-=-=-=- Keyboard: IKeyboardPort  -=-=-=-=-=- */
1537
 
 
1538
 
/**
1539
 
 * Keyboard event handler.
1540
 
 *
1541
 
 * @returns VBox status code.
1542
 
 * @param   pInterface      Pointer to the keyboard port interface (KBDState::Keyboard.IPort).
1543
 
 * @param   u8KeyCode       The keycode.
1544
 
 */
1545
 
static DECLCALLBACK(int) kbdKeyboardPutEvent(PPDMIKEYBOARDPORT pInterface, uint8_t u8KeyCode)
1546
 
{
1547
 
    KBDState *pThis = RT_FROM_MEMBER(pInterface, KBDState, Keyboard.IPort);
1548
 
    int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
1549
 
    AssertReleaseRC(rc);
1550
 
 
1551
 
    pc_kbd_put_keycode(pThis, u8KeyCode);
1552
 
 
1553
 
    PDMCritSectLeave(&pThis->CritSect);
1554
 
    return VINF_SUCCESS;
 
1357
    PS2KReset(&pThis->Kbd);
1555
1358
}
1556
1359
 
1557
1360
 
1593
1396
static DECLCALLBACK(int) kbdMousePutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t uX, uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtons)
1594
1397
{
1595
1398
    AssertFailedReturn(VERR_NOT_SUPPORTED);
 
1399
    NOREF(pInterface); NOREF(uX); NOREF(uY); NOREF(iDeltaZ); NOREF(iDeltaW); NOREF(fButtons);
1596
1400
}
1597
1401
 
1598
1402
 
1628
1432
    {
1629
1433
        /* LUN #0: keyboard */
1630
1434
        case 0:
1631
 
            rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pThis->Keyboard.IBase, &pThis->Keyboard.pDrvBase, "Keyboard Port");
1632
 
            if (RT_SUCCESS(rc))
1633
 
            {
1634
 
                pThis->Keyboard.pDrv = PDMIBASE_QUERY_INTERFACE(pThis->Keyboard.pDrvBase, PDMIKEYBOARDCONNECTOR);
1635
 
                if (!pThis->Keyboard.pDrv)
1636
 
                {
1637
 
                    AssertLogRelMsgFailed(("LUN #0 doesn't have a keyboard interface! rc=%Rrc\n", rc));
1638
 
                    rc = VERR_PDM_MISSING_INTERFACE;
1639
 
                }
1640
 
            }
1641
 
            else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
1642
 
            {
1643
 
                Log(("%s/%d: warning: no driver attached to LUN #0!\n", pDevIns->pReg->szName, pDevIns->iInstance));
1644
 
                rc = VINF_SUCCESS;
1645
 
            }
1646
 
            else
1647
 
                AssertLogRelMsgFailed(("Failed to attach LUN #0! rc=%Rrc\n", rc));
 
1435
            rc = PS2KAttach(pDevIns, &pThis->Kbd, iLUN, fFlags);
 
1436
            if (RT_FAILURE(rc))
 
1437
                return rc;
1648
1438
            break;
1649
1439
 
1650
1440
        /* LUN #1: aux/mouse */
1717
1507
            AssertMsgFailed(("Invalid LUN #%d\n", iLUN));
1718
1508
            break;
1719
1509
    }
 
1510
#else
 
1511
    NOREF(pDevIns); NOREF(iLUN); NOREF(fFlags);
1720
1512
#endif
1721
1513
}
1722
1514
 
1728
1520
{
1729
1521
    KBDState   *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
1730
1522
    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
 
1523
    PS2KRelocate(&pThis->Kbd, offDelta);
1731
1524
}
1732
1525
 
1733
1526
 
1781
1574
    pThis->pDevInsR3 = pDevIns;
1782
1575
    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
1783
1576
    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
1784
 
    pThis->Keyboard.IBase.pfnQueryInterface = kbdKeyboardQueryInterface;
1785
 
    pThis->Keyboard.IPort.pfnPutEvent       = kbdKeyboardPutEvent;
 
1577
 
 
1578
    rc = PS2KConstruct(pDevIns, &pThis->Kbd, pThis, iInstance);
 
1579
    if (RT_FAILURE(rc))
 
1580
        return rc;
1786
1581
 
1787
1582
    pThis->Mouse.IBase.pfnQueryInterface    = kbdMouseQueryInterface;
1788
1583
    pThis->Mouse.IPort.pfnPutEvent          = kbdMousePutEvent;