VirtualBox

Changeset 1476 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 14, 2007 4:36:04 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
19537
Message:

First go at a serial port device with I/O hooked to named pipe/local
socket. Doesn't support mounting/unmounting at runtime yet.

Location:
trunk/src/VBox/Devices
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Builtins.cpp

    r1458 r1476  
    204204#endif
    205205
     206    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvChar);
     207    if (VBOX_FAILURE(rc))
     208        return rc;
     209    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvNamedPipe);
     210    if (VBOX_FAILURE(rc))
     211        return rc;
     212
    206213    return VINF_SUCCESS;
    207214}
  • trunk/src/VBox/Devices/Builtins.h

    r240 r1476  
    7575extern const PDMDRVREG g_DrvACPI;
    7676extern const PDMDRVREG g_DrvVUSBRootHub;
     77extern const PDMDRVREG g_DrvChar;
     78extern const PDMDRVREG g_DrvNamedPipe;
    7779
    7880__END_DECLS
  • trunk/src/VBox/Devices/Serial/serial.c

    r1031 r1476  
    6161#include <iprt/uuid.h>
    6262#include <iprt/string.h>
     63#include <iprt/semaphore.h>
    6364
    6465#include "Builtins.h"
    6566#include "../vl_vbox.h"
    6667
    67 #define VBOX_SERIAL_PCI
     68#undef VBOX_SERIAL_PCI /* The PCI variant has lots of problems: wrong IRQ line and wrong IO base assigned. */
    6869
    6970#ifdef VBOX_SERIAL_PCI
     
    148149    PCIDEVICE dev;
    149150#endif /* VBOX_SERIAL_PCI */
    150     /* Be careful with pointers in the structure; load just gets the whole structure from the saved state */
    151151    PPDMDEVINS pDevIns;
    152 #if 0
    153     PDMICHAR pDevChar;
    154 #endif
     152    PDMIBASE IBase;
     153    PDMICHARPORT ICharPort;
     154    PPDMIBASE pDrvBase;
     155    PPDMICHAR pDrvChar;
     156
     157    RTSEMEVENT ReceiveSem;
    155158#else /* !VBOX */
    156159    CharDriverState *chr;
     
    167170#define PCIDEV_2_SERIALSTATE(pPciDev) ( (SerialState *)((uintptr_t)(pPciDev) - RT_OFFSETOF(SerialState, dev)) )
    168171#endif /* VBOX_SERIAL_PCI */
     172#define PDMIBASE_2_SERIALSTATE(pInstance) ( (SerialState *)((uintptr_t)(pInterface) - RT_OFFSETOF(SerialState, IBase)) )
     173#define PDMICHARPORT_2_SERIALSTATE(pInstance) ( (SerialState *)((uintptr_t)(pInterface) - RT_OFFSETOF(SerialState, ICharPort)) )
    169174#endif /* VBOX */
    170175
     
    180185    if (s->iir != UART_IIR_NO_INT) {
    181186#ifdef VBOX
    182         s->pDevIns->pDevHlp->pfnISASetIrq (s->pDevIns, s->irq, 1);
     187#ifdef VBOX_SERIAL_PCI
     188        PDMDevHlpPCISetIrqNoWait(s->pDevIns, 0, 1);
     189#else /* !VBOX_SERIAL_PCI */
     190        PDMDevHlpISASetIrqNoWait(s->pDevIns, s->irq, 1);
     191#endif /* !VBOX_SERIAL_PCI */
    183192#else /* !VBOX */
    184193        s->set_irq(s->irq_opaque, s->irq, 1);
     
    186195    } else {
    187196#ifdef VBOX
    188         s->pDevIns->pDevHlp->pfnISASetIrq (s->pDevIns, s->irq, 0);
     197#ifdef VBOX_SERIAL_PCI
     198        PDMDevHlpPCISetIrqNoWait(s->pDevIns, 0, 0);
     199#else /* !VBOX_SERIAL_PCI */
     200        PDMDevHlpISASetIrqNoWait(s->pDevIns, s->irq, 0);
     201#endif /* !VBOX_SERIAL_PCI */
    189202#else /* !VBOX */
    190203        s->set_irq(s->irq_opaque, s->irq, 0);
     
    248261            ch = val;
    249262#ifdef VBOX
    250 #if 0
     263            /** @todo implement backpressure for writing (don't set interrupt
     264             * bits/line until the character is actually written). This way
     265             * EMT wouldn't block for writes taking longer than normal. */
    251266            if (s->pDrvChar)
    252267            {
     
    254269                AssertRC(rc);
    255270            }
    256 #endif
    257271#else /* !VBOX */
    258272            qemu_chr_write(s->chr, &ch, 1);
     
    321335            s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
    322336            serial_update_irq(s);
     337#ifdef VBOX
     338            {
     339                int rc = RTSemEventSignal(s->ReceiveSem);
     340                AssertRC(rc);
     341            }
     342#endif /* VBOX */
    323343        }
    324344        break;
     
    368388
    369389#ifdef VBOX
    370 /* Provide non-blocking functions to receive data from the host system. */
    371 
     390static DECLCALLBACK(int) serialNotifyRead(PPDMICHARPORT pInterface, const void *pvBuf, size_t *pcbRead)
     391{
     392    SerialState *s = PDMICHARPORT_2_SERIALSTATE(pInterface);
     393    int rc;
     394
     395    Assert(*pcbRead != 0);
     396    rc = RTSemEventWait(s->ReceiveSem, 250);
     397    if (VBOX_FAILURE(rc))
     398        return rc;
     399    Assert(!(s->lsr & UART_LSR_DR));
     400    s->rbr = *(const char *)pvBuf;
     401    s->lsr |= UART_LSR_DR;
     402    serial_update_irq(s);
     403    *pcbRead = 1;
     404    return VINF_SUCCESS;
     405}
    372406#else /* !VBOX */
    373407static int serial_can_receive(SerialState *s)
     
    651685    /* Be careful with pointers in the structure; they are not preserved
    652686     * in the saved state. */
     687
     688    if (s->lsr & UART_LSR_DR)
     689    {
     690        int rc = RTSemEventSignal(s->ReceiveSem);
     691        AssertRC(rc);
     692    }
    653693    s->pDevIns = pDevIns;
    654694    return VINF_SUCCESS;
     
    668708
    669709    pData->base = (RTIOPORT)GCPhysAddress;
     710    LogRel(("Serial#%d: mapping I/O at %#06x\n", pData->pDevIns->iInstance, pData->base));
    670711
    671712    /*
    672713     * Register our port IO handlers.
    673714     */
    674     rc = pPciDev->pDevIns->pDevHlp->pfnIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress, 8, (void *)pData,
    675                                                       serial_io_write, serial_io_read, NULL, NULL, "SERIAL");
     715    rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress, 8, (void *)pData,
     716                                 serial_io_write, serial_io_read, NULL, NULL, "SERIAL");
    676717    AssertRC(rc);
    677718    return rc;
     
    679720
    680721#endif /* VBOX_SERIAL_PCI */
     722
     723
     724/** @copyfrom PIBASE::pfnqueryInterface */
     725static DECLCALLBACK(void *) serialQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
     726{
     727    SerialState *pData = PDMIBASE_2_SERIALSTATE(pInterface);
     728    switch (enmInterface)
     729    {
     730        case PDMINTERFACE_BASE:
     731            return &pData->IBase;
     732        case PDMINTERFACE_CHAR_PORT:
     733            return &pData->ICharPort;
     734        default:
     735            return NULL;
     736    }
     737}
     738
    681739
    682740/**
     
    702760    uint8_t        irq_lvl;
    703761
    704     Assert(iInstance < 2);
     762    Assert(iInstance < 4);
    705763
    706764    s->pDevIns = pDevIns;
     
    712770    }
    713771
     772    /* IBase */
     773    s->IBase.pfnQueryInterface = serialQueryInterface;
     774
     775    /* ICharPort */
     776    s->ICharPort.pfnNotifyRead = serialNotifyRead;
     777
     778    rc = RTSemEventCreate(&s->ReceiveSem);
     779    AssertRC(rc);
    714780
    715781/** @todo r=bird: Check for VERR_CFGM_VALUE_NOT_FOUND and provide sensible defaults.
     
    745811    s->dev.config[0x3c] = irq_lvl; /* preconfigure IRQ number (0 = autoconfig)*/
    746812    s->dev.config[0x3d] = 1;    /* interrupt pin 0 */
    747     rc = pDevIns->pDevHlp->pfnPCIRegister(pDevIns, &s->dev);
     813    rc = PDMDevHlpPCIRegister(pDevIns, &s->dev);
    748814    if (VBOX_FAILURE(rc))
    749815        return rc;
     
    751817     * Register the PCI I/O ports.
    752818     */
    753     rc = pDevIns->pDevHlp->pfnPCIIORegionRegister(pDevIns, 0, 8, PCI_ADDRESS_SPACE_IO, serialIOPortRegionMap);
     819    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 8, PCI_ADDRESS_SPACE_IO, serialIOPortRegionMap);
    754820    if (VBOX_FAILURE(rc))
    755821        return rc;
    756822#else /* !VBOX_SERIAL_PCI */
    757823    s->base = io_base;
    758     rc = pDevIns->pDevHlp->pfnIOPortRegister (
    759         pDevIns,
    760         io_base,
    761         8,
    762         s,
    763         serial_io_write,
    764         serial_io_read,
    765         NULL, NULL,
    766         "SERIAL"
    767         );
     824    rc = PDMDevHlpIOPortRegister(pDevIns, io_base, 8, s,
     825                                 serial_io_write, serial_io_read,
     826                                 NULL, NULL, "SERIAL");
    768827    if (VBOX_FAILURE (rc)) {
    769828        return rc;
     
    771830#endif /* !VBOX_SERIAL_PCI */
    772831
    773     rc = pDevIns->pDevHlp->pfnSSMRegister (
     832    /* Attach the char driver and get the interfaces. For now no run-time
     833     * changes are supported. */
     834    rc = PDMDevHlpDriverAttach(pDevIns, 0, &s->IBase, &s->pDrvBase, "Serial Char");
     835    if (VBOX_SUCCESS(rc))
     836    {
     837        s->pDrvChar = (PDMICHAR *)s->pDrvBase->pfnQueryInterface(s->pDrvBase, PDMINTERFACE_CHAR);
     838        if (!s->pDrvChar)
     839        {
     840            AssertMsgFailed(("Configuration error: instance %d has no char interface!\n", iInstance));
     841            return VERR_PDM_MISSING_INTERFACE;
     842        }
     843        /** @todo provide read notification interface!!!! */
     844    }
     845    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     846    {
     847        s->pDrvBase = NULL;
     848        s->pDrvChar = NULL;
     849        LogRel(("Serial%d: no unit\n", iInstance));
     850    }
     851    else
     852    {
     853        AssertMsgFailed(("Serial%d: Failed to attach to char driver. rc=%Vrc\n", iInstance, rc));
     854        return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     855                                   N_("Serial device %d cannot attach to char driver\n"), iInstance);
     856    }
     857
     858    rc = PDMDevHlpSSMRegister (
    774859        pDevIns,                /* pDevIns */
    775860        pDevIns->pDevReg->szDeviceName, /* pszName */
     
    808893    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
    809894    /* fClass */
    810     PDM_DEVREG_CLASS_SERIAL_PORT,
     895    PDM_DEVREG_CLASS_SERIAL,
    811896    /* cMaxInstances */
    812897    1,
Note: See TracChangeset for help on using the changeset viewer.

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