VirtualBox

Changeset 39959 in vbox for trunk


Ignore:
Timestamp:
Feb 2, 2012 5:11:50 PM (13 years ago)
Author:
vboxsync
Message:

New and improved PS/2 keyboard emulation.

Location:
trunk/src/VBox/Devices
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Input/DevPS2.cpp

    r39091 r39959  
    5252
    5353#include "VBoxDD.h"
    54 
    55 #define PCKBD_SAVED_STATE_VERSION 5
     54#include "PS2Dev.h"
     55
     56#define PCKBD_SAVED_STATE_VERSION 6
    5657
    5758
     
    205206    int32_t translate;
    206207    int32_t scancode_set;   /* 1=XT, 2=AT, 3=PS/2 */
     208    xlat_state_t    xlat_state;
    207209    /* mouse state */
    208210    int32_t mouse_write_cmd;
     
    227229    /** Pointer to the device instance. */
    228230    PPDMDEVINSR0                pDevInsR0;
     231
     232#if HC_ARCH_BITS == 32
     233    uint32_t                    Alignment0;
     234#endif
     235    /** Keyboard state (implemented in separate PS2K module). */
     236    PS2K                        Kbd;
    229237    /** Critical section protecting the state. */
    230238    PDMCRITSECT                 CritSect;
     239
     240#ifdef HC_ARCH_BITS //OLD_KBD
    231241    /**
    232242     * Keyboard port - LUN#0.
     
    247257        R3PTRTYPE(PPDMIKEYBOARDCONNECTOR)   pDrv;
    248258    } Keyboard;
     259#endif
    249260
    250261    /**
     
    301312    MouseEventQueue *meq = &s->mouse_event_queue;
    302313    int irq12_level, irq1_level;
     314    uint8_t val;
    303315
    304316    irq1_level = 0;
     
    312324        s->status &= ~KBD_STAT_MOUSE_OBF;
    313325        /* Keyboard data has priority if both kbd and aux data is available. */
     326#ifdef OLD_KBD
    314327        if (q->count && !(s->mode & KBD_MODE_DISABLE_KBD))
    315328        {
     
    320333            q->count--;
    321334        }
    322         else if ((mcq->count || meq->count) /*&& !(s->mode & KBD_MODE_DISABLE_MOUSE)*/)
     335#else
     336        if (!(s->mode & KBD_MODE_DISABLE_KBD) && PS2KByteFromKbd(&s->Kbd, &val) == VINF_SUCCESS)
     337        {
     338            bool    fHaveData = true;
     339
     340            /* If scancode translation is on (it usually is), there's more work to do. */
     341            if (s->translate)
     342            {
     343                uint8_t     xlated_val;
     344
     345                s->xlat_state = XlateAT2PC(s->xlat_state, val, &xlated_val);
     346                val = xlated_val;
     347
     348                /* If the translation state is XS_BREAK, there's nothing to report
     349                 * and we keep going until the state changes or there's no more data.
     350                 */
     351                while (s->xlat_state == XS_BREAK && PS2KByteFromKbd(&s->Kbd, &val) == VINF_SUCCESS)
     352                {
     353                    s->xlat_state = XlateAT2PC(s->xlat_state, val, &xlated_val);
     354                    val = xlated_val;
     355                }
     356                /* This can happen if the last byte in the queue is F0... */
     357                if (s->xlat_state == XS_BREAK)
     358                    fHaveData = false;
     359            }
     360            if (fHaveData)
     361            {
     362                s->dbbout = val;
     363                s->status |= KBD_STAT_OBF;
     364            }
     365        }
     366#endif
     367        else if ((mcq->count || meq->count) && !(s->mode & KBD_MODE_DISABLE_MOUSE))
    323368        {
    324369            s->status |= KBD_STAT_OBF | KBD_STAT_MOUSE_OBF;
     
    356401}
    357402
     403void KBCUpdateInterrupts(void *pKbc)
     404{
     405    KBDState    *s = (KBDState *)pKbc;
     406    kbd_update_irq(s);
     407}
     408
    358409static void kbd_queue(KBDState *s, int b, int aux)
    359410{
     
    596647}
    597648
     649#ifdef OLD_KBD
     650
    598651static void kbd_reset_keyboard(KBDState *s)
    599652{
     
    604657    s->queue.rptr = 0;
    605658    s->queue.wptr = 0;
     659}
     660
     661/* The keyboard BAT is specified to take several hundred milliseconds. We need
     662 * to delay sending the result to the host for at least a tiny little while.
     663 */
     664static DECLCALLBACK(void) kbd_timer_cb(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     665{
     666    KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
     667    int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
     668    AssertReleaseRC(rc);
     669
     670    kbd_queue(pThis, KBD_REPLY_POR, 0);
     671
     672    PDMCritSectLeave(&pThis->CritSect);
    606673}
    607674
     
    701768    return VINF_SUCCESS;
    702769}
     770
     771#else
     772PS2K *GetPS2KFromDevIns(PPDMDEVINS pDevIns)
     773{
     774    KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
     775    return &pThis->Kbd;
     776}
     777#endif
    703778
    704779static void kbd_mouse_set_reported_buttons(KBDState *s, unsigned fButtons, unsigned fButtonMask)
     
    10731148        /* Automatically enables keyboard interface. */
    10741149        s->mode &= ~KBD_MODE_DISABLE_KBD;
     1150#ifdef OLD_KBD
    10751151        rc = kbd_write_keyboard(s, val);
     1152#else
     1153        rc = PS2KByteToKbd(&s->Kbd, val);
     1154        if (rc == VINF_SUCCESS)
     1155            kbd_update_irq(s);
     1156#endif
    10761157        break;
    10771158    case KBD_CCMD_WRITE_MODE:
     
    11041185        break;
    11051186    case KBD_CCMD_WRITE_MOUSE:
     1187        /* Automatically enables aux interface. */
     1188        s->mode &= ~KBD_MODE_DISABLE_MOUSE;
    11061189        rc = kbd_write_mouse(s, val);
    11071190        break;
     
    11721255    qemu_put_8s(f, &s->status);
    11731256    qemu_put_8s(f, &s->mode);
    1174     qemu_put_be32s(f, &s->kbd_write_cmd);
    1175     qemu_put_be32s(f, &s->scan_enabled);
     1257    qemu_put_8s(f, &s->dbbout);
    11761258    qemu_put_be32s(f, &s->mouse_write_cmd);
    11771259    qemu_put_8s(f, &s->mouse_status);
     
    11891271    qemu_put_8s(f, &s->mouse_buttons_reported);
    11901272
     1273#ifdef OLD_KBD
    11911274    /* XXX: s->scancode_set isn't being saved, but we only really support set 2,
    11921275     * so no real harm done.
     
    12011284        SSMR3PutU8(f, s->queue.data[i]);
    12021285    Log(("kbd_save: %d keyboard queue items stored\n", s->queue.count));
     1286#endif
    12031287
    12041288    cItems = s->mouse_command_queue.count;
     
    12371321    qemu_get_8s(f, &s->status);
    12381322    qemu_get_8s(f, &s->mode);
    1239     qemu_get_be32s(f, (uint32_t *)&s->kbd_write_cmd);
    1240     qemu_get_be32s(f, (uint32_t *)&s->scan_enabled);
     1323    if (version_id <= 5)
     1324    {
     1325        qemu_get_be32s(f, (uint32_t *)&s->kbd_write_cmd);
     1326        qemu_get_be32s(f, (uint32_t *)&s->scan_enabled);
     1327    }
     1328    else
     1329    {
     1330        qemu_get_8s(f, &s->dbbout);
     1331    }
    12411332    qemu_get_be32s(f, (uint32_t *)&s->mouse_write_cmd);
    12421333    qemu_get_8s(f, &s->mouse_status);
     
    12811372     * Load the queues
    12821373     */
    1283     rc = SSMR3GetU32(f, &u32);
    1284     if (RT_FAILURE(rc))
    1285         return rc;
    1286     if (u32 > RT_ELEMENTS(s->queue.data))
    1287     {
    1288         AssertMsgFailed(("u32=%#x\n", u32));
    1289         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    1290     }
    1291     for (i = 0; i < u32; i++)
    1292     {
    1293         rc = SSMR3GetU8(f, &s->queue.data[i]);
     1374    if (version_id <= 5)
     1375    {
     1376        rc = SSMR3GetU32(f, &u32);
    12941377        if (RT_FAILURE(rc))
    12951378            return rc;
    1296     }
    1297     s->queue.wptr = u32 % RT_ELEMENTS(s->queue.data);
    1298     s->queue.count = u32;
    1299     Log(("kbd_load: %d keyboard queue items loaded\n", u32));
     1379        if (u32 > RT_ELEMENTS(s->queue.data))
     1380        {
     1381            AssertMsgFailed(("u32=%#x\n", u32));
     1382            return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     1383        }
     1384        for (i = 0; i < u32; i++)
     1385        {
     1386            rc = SSMR3GetU8(f, &s->queue.data[i]);
     1387            if (RT_FAILURE(rc))
     1388                return rc;
     1389        }
     1390        s->queue.wptr = u32 % RT_ELEMENTS(s->queue.data);
     1391        s->queue.count = u32;
     1392        Log(("kbd_load: %d keyboard queue items loaded\n", u32));
     1393    }
    13001394
    13011395    rc = SSMR3GetU32(f, &u32);
     
    14881582static DECLCALLBACK(int) kbdSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
    14891583{
    1490     kbd_save(pSSMHandle, PDMINS_2_DATA(pDevIns, KBDState *));
     1584    KBDState    *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
     1585    kbd_save(pSSMHandle, pThis);
     1586    PS2KSaveState(pSSMHandle, &pThis->Kbd);
    14911587    return VINF_SUCCESS;
    14921588}
     
    15041600static DECLCALLBACK(int) kbdLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
    15051601{
     1602    KBDState    *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
     1603    int rc;
     1604
    15061605    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
    1507     return kbd_load(pSSMHandle, PDMINS_2_DATA(pDevIns, KBDState *), uVersion);
     1606    rc = kbd_load(pSSMHandle, pThis, uVersion);
     1607    if (uVersion >= 6)
     1608        rc = PS2KLoadState(pSSMHandle, &pThis->Kbd, uVersion);
     1609    return rc;
    15081610}
    15091611
     
    15191621
    15201622    kbd_reset(pThis);
     1623#ifdef OLD_KBD
    15211624    /* Activate the PS/2 keyboard by default. */
    15221625    if (pThis->Keyboard.pDrv)
    15231626        pThis->Keyboard.pDrv->pfnSetActive(pThis->Keyboard.pDrv, true);
    1524 }
    1525 
     1627#else
     1628    PS2KReset(&pThis->Kbd);
     1629#endif
     1630}
     1631
     1632#ifdef OLD_KBD
    15261633
    15271634/* -=-=-=-=-=- Keyboard: IBase  -=-=-=-=-=- */
     
    15591666    return VINF_SUCCESS;
    15601667}
     1668#endif
    15611669
    15621670
     
    16351743        /* LUN #0: keyboard */
    16361744        case 0:
     1745#ifdef OLD_KBD
    16371746            rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pThis->Keyboard.IBase, &pThis->Keyboard.pDrvBase, "Keyboard Port");
    16381747            if (RT_SUCCESS(rc))
     
    16521761            else
    16531762                AssertLogRelMsgFailed(("Failed to attach LUN #0! rc=%Rrc\n", rc));
     1763#else
     1764            rc = PS2KAttach(pDevIns, &pThis->Kbd, iLUN, fFlags);
     1765            if (RT_FAILURE(rc))
     1766                return rc;
     1767
     1768#endif
    16541769            break;
    16551770
     
    17371852    KBDState   *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
    17381853    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    1739     NOREF(offDelta);
     1854    PS2KRelocate(&pThis->Kbd, offDelta);
    17401855}
    17411856
     
    17911906    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
    17921907    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     1908
     1909#if OLD_KBD
    17931910    pThis->Keyboard.IBase.pfnQueryInterface = kbdKeyboardQueryInterface;
    17941911    pThis->Keyboard.IPort.pfnPutEvent       = kbdKeyboardPutEvent;
     1912#else
     1913    rc = PS2KConstruct(pDevIns, &pThis->Kbd, pThis, iInstance);
     1914    if (RT_FAILURE(rc))
     1915        return rc;
     1916#endif
    17951917
    17961918    pThis->Mouse.IBase.pfnQueryInterface    = kbdMouseQueryInterface;
  • trunk/src/VBox/Devices/Makefile.kmk

    r39955 r39959  
    282282 DevicesR3_SOURCES       = \
    283283        Input/DevPS2.cpp \
     284        Input/PS2K.cpp \
    284285        Input/UsbKbd.cpp \
    285286        Input/UsbMouse.cpp \
     
    560561        Graphics/DevVGA.cpp \
    561562        Input/DevPS2.cpp \
     563        Input/PS2K.cpp \
    562564        PC/DevACPI.cpp \
    563565        PC/DevPit-i8254.cpp \
     
    663665        Graphics/DevVGA.cpp \
    664666        Input/DevPS2.cpp \
     667        Input/PS2K.cpp \
    665668        PC/DevACPI.cpp \
    666669        PC/DevPit-i8254.cpp \
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette