VirtualBox

Changeset 1019 in vbox for trunk/src/VBox/Devices/Serial


Ignore:
Timestamp:
Feb 22, 2007 9:29:57 AM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
18876
Message:

Converted serial card to PCI device

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Serial/serial.c

    r61 r1019  
    6565#include "../vl_vbox.h"
    6666
     67#define VBOX_SERIAL_PCI
     68
     69#ifdef VBOX_SERIAL_PCI
     70#include <VBox/pci.h>
     71#endif /* VBOX_SERIAL_PCI */
     72
     73#define SERIAL_SAVED_STATE_VERSION 2
     74
    6775#endif /* VBOX */
    6876
    6977#ifndef VBOX
    7078#include "vl.h"
    71 #endif
     79#endif /* !VBOX */
    7280
    7381//#define DEBUG_SERIAL
     
    131139       it can be reset while reading iir */
    132140    int thr_ipending;
     141#ifndef VBOX
    133142    SetIRQFunc *set_irq;
    134143    void *irq_opaque;
     144#endif /* !VBOX */
    135145    int irq;
    136146#ifdef VBOX
     147#ifdef VBOX_SERIAL_PCI
     148    PCIDEVICE dev;
     149#endif /* VBOX_SERIAL_PCI */
    137150    /* Be careful with pointers in the structure; load just gets the whole structure from the saved state */
    138151    PPDMDEVINS pDevIns;
    139 #else
     152#if 0
     153    PDMICHAR pDevChar;
     154#endif
     155#else /* !VBOX */
    140156    CharDriverState *chr;
    141 #endif
     157#endif /* !VBOX */
    142158    int last_break_enable;
    143159    target_ulong base;
     160#ifndef VBOX
    144161    int it_shift;
     162#endif /* !VBOX */
    145163};
     164
     165#ifdef VBOX
     166#ifdef VBOX_SERIAL_PCI
     167#define PCIDEV_2_SERIALSTATE(pPciDev) ( (SerialState *)((uintptr_t)(pPciDev) - RT_OFFSETOF(SerialState, dev)) )
     168#endif /* VBOX_SERIAL_PCI */
     169#endif /* VBOX */
    146170
    147171static void serial_update_irq(SerialState *s)
     
    157181#ifdef VBOX
    158182        s->pDevIns->pDevHlp->pfnISASetIrq (s->pDevIns, s->irq, 1);
    159 #else
     183#else /* !VBOX */
    160184        s->set_irq(s->irq_opaque, s->irq, 1);
    161 #endif
     185#endif /* !VBOX */
    162186    } else {
    163187#ifdef VBOX
    164188        s->pDevIns->pDevHlp->pfnISASetIrq (s->pDevIns, s->irq, 0);
    165 #else
     189#else /* !VBOX */
    166190        s->set_irq(s->irq_opaque, s->irq, 0);
    167 #endif
     191#endif /* !VBOX */
    168192    }
    169193}
     
    196220#ifndef VBOX
    197221    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
    198 #endif
     222#endif /* !VBOX */
    199223#if 0
    200224    printf("speed=%d parity=%c data=%d stop=%d\n",
     
    223247            serial_update_irq(s);
    224248            ch = val;
    225 #ifndef VBOX
     249#ifdef VBOX
     250#if 0
     251            if (s->pDrvChar)
     252            {
     253                int rc = s->pDrvChar->pfnWrite(s->pDrvChar, &ch, 1);
     254                AssertRC(rc);
     255            }
     256#endif
     257#else /* !VBOX */
    226258            qemu_chr_write(s->chr, &ch, 1);
    227 #endif
     259#endif /* !VBOX */
    228260            s->thr_ipending = 1;
    229261            s->lsr |= UART_LSR_THRE;
     
    257289                qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
    258290                               &break_enable);
    259 #endif
     291#endif /* !VBOX */
    260292            }
    261293        }
     
    335367}
    336368
    337 #ifndef VBOX
     369#ifdef VBOX
     370/* Provide non-blocking functions to receive data from the host system. */
     371
     372#else /* !VBOX */
    338373static int serial_can_receive(SerialState *s)
    339374{
     
    525560    return s;
    526561}
    527 
    528 #else
    529 
     562#endif
     563
     564#ifdef VBOX
    530565static DECLCALLBACK(int) serial_io_write (PPDMDEVINS pDevIns,
    531566                                       void *pvUser,
     
    535570{
    536571    if (cb == 1) {
     572        Log(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, u32));
    537573        serial_ioport_write (pvUser, Port, u32);
    538574    }
     
    550586{
    551587    if (cb == 1) {
     588        Log(("%s: port %#06x\n", __FUNCTION__, Port));
    552589        *pu32 = serial_ioport_read (pvUser, Port);
     590        Log(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, *pu32));
    553591        return VINF_SUCCESS;
    554592    }
     
    558596}
    559597
    560 static DECLCALLBACK(int) SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
     598static DECLCALLBACK(int) serialSaveExec(PPDMDEVINS pDevIns,
     599                                        PSSMHANDLE pSSMHandle)
    561600{
    562601    SerialState *s = PDMINS2DATA (pDevIns, SerialState *);
    563     SSMR3PutMem(pSSMHandle, s, sizeof(*s));
     602    SSMR3PutU16(pSSMHandle, s->divider);
     603    SSMR3PutU8(pSSMHandle, s->rbr);
     604    SSMR3PutU8(pSSMHandle, s->ier);
     605    SSMR3PutU8(pSSMHandle, s->lcr);
     606    SSMR3PutU8(pSSMHandle, s->mcr);
     607    SSMR3PutU8(pSSMHandle, s->lsr);
     608    SSMR3PutU8(pSSMHandle, s->msr);
     609    SSMR3PutU8(pSSMHandle, s->scr);
     610    SSMR3PutU32(pSSMHandle, s->thr_ipending);
     611    SSMR3PutU32(pSSMHandle, s->irq);
     612    SSMR3PutU32(pSSMHandle, s->last_break_enable);
     613    SSMR3PutU32(pSSMHandle, s->base);
    564614    return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
    565615}
    566616
    567 static DECLCALLBACK(int) LoadExec (PPDMDEVINS pDevIns,
    568                                    PSSMHANDLE pSSMHandle,
    569                                    uint32_t u32Version)
     617static DECLCALLBACK(int) serialLoadExec(PPDMDEVINS pDevIns,
     618                                        PSSMHANDLE pSSMHandle,
     619                                        uint32_t u32Version)
    570620{
    571621    int rc;
     
    573623    SerialState *s = PDMINS2DATA (pDevIns, SerialState *);
    574624
    575     if (u32Version != 2) {
     625    if (u32Version != SERIAL_SAVED_STATE_VERSION) {
    576626        AssertMsgFailed(("u32Version=%d\n", u32Version));
    577627        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    578628    }
    579629
    580     rc = SSMR3GetMem(pSSMHandle, s, sizeof(*s));
    581     if (VBOX_FAILURE(rc))
    582         return rc;
     630    SSMR3GetU16(pSSMHandle, &s->divider);
     631    SSMR3GetU8(pSSMHandle, &s->rbr);
     632    SSMR3GetU8(pSSMHandle, &s->ier);
     633    SSMR3GetU8(pSSMHandle, &s->lcr);
     634    SSMR3GetU8(pSSMHandle, &s->mcr);
     635    SSMR3GetU8(pSSMHandle, &s->lsr);
     636    SSMR3GetU8(pSSMHandle, &s->msr);
     637    SSMR3GetU8(pSSMHandle, &s->scr);
     638    SSMR3GetU32(pSSMHandle, &s->thr_ipending);
     639    SSMR3GetU32(pSSMHandle, &s->irq);
     640    SSMR3GetU32(pSSMHandle, &s->last_break_enable);
     641    SSMR3GetU32(pSSMHandle, &s->base);
    583642
    584643    rc = SSMR3GetU32(pSSMHandle, &u32);
     
    590649        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    591650    }
    592     /* Be careful with pointers in the structure; load just gets the whole structure from the saved state */
     651    /* Be careful with pointers in the structure; they are not preserved
     652     * in the saved state. */
    593653    s->pDevIns = pDevIns;
    594654    return VINF_SUCCESS;
    595655}
    596656
     657#ifdef VBOX_SERIAL_PCI
     658
     659static DECLCALLBACK(int) serialIOPortRegionMap(PPCIDEVICE pPciDev, /* unsigned */ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
     660{
     661    SerialState *pData = PCIDEV_2_SERIALSTATE(pPciDev);
     662    int rc = VINF_SUCCESS;
     663
     664    Assert(enmType == PCI_ADDRESS_SPACE_IO);
     665    Assert(iRegion == 0);
     666    Assert(cb == 8);
     667    AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
     668
     669    pData->base = (RTIOPORT)GCPhysAddress;
     670
     671    /*
     672     * Register our port IO handlers.
     673     */
     674    rc = pPciDev->pDevIns->pDevHlp->pfnIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress, 8, (void *)pData,
     675                                                      serial_io_write, serial_io_read, NULL, NULL, "SERIAL");
     676    AssertRC(rc);
     677    return rc;
     678}
     679
     680#endif /* VBOX_SERIAL_PCI */
    597681
    598682/**
     
    647731    s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
    648732    s->iir = UART_IIR_NO_INT;
    649 
     733    s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
     734#ifdef VBOX_SERIAL_PCI
     735    s->base = -1;
     736    s->dev.config[0x00] = 0xee; /* Vendor: ??? */
     737    s->dev.config[0x01] = 0x80;
     738    s->dev.config[0x02] = 0x01; /* Device: ??? */
     739    s->dev.config[0x03] = 0x01;
     740    s->dev.config[0x04] = PCI_COMMAND_IOACCESS;
     741    s->dev.config[0x09] = 0x01; /* Programming interface: 16450 */
     742    s->dev.config[0x0a] = 0x00; /* Subclass: Serial controller */
     743    s->dev.config[0x0b] = 0x07; /* Class: Communication controller */
     744    s->dev.config[0x0e] = 0x00; /* Header type: standard */
     745    s->dev.config[0x3c] = irq_lvl; /* preconfigure IRQ number (0 = autoconfig)*/
     746    s->dev.config[0x3d] = 1;    /* interrupt pin 0 */
     747    rc = pDevIns->pDevHlp->pfnPCIRegister(pDevIns, &s->dev);
     748    if (VBOX_FAILURE(rc))
     749        return rc;
     750    /*
     751     * Register the PCI I/O ports.
     752     */
     753    rc = pDevIns->pDevHlp->pfnPCIIORegionRegister(pDevIns, 0, 8, PCI_ADDRESS_SPACE_IO, serialIOPortRegionMap);
     754    if (VBOX_FAILURE(rc))
     755        return rc;
     756#else /* !VBOX_SERIAL_PCI */
     757    s->base = io_base;
    650758    rc = pDevIns->pDevHlp->pfnIOPortRegister (
    651759        pDevIns,
     
    661769        return rc;
    662770    }
     771#endif /* !VBOX_SERIAL_PCI */
    663772
    664773    rc = pDevIns->pDevHlp->pfnSSMRegister (
     
    666775        pDevIns->pDevReg->szDeviceName, /* pszName */
    667776        iInstance,              /* u32Instance */
    668         2                       /* u32Version */,
     777        SERIAL_SAVED_STATE_VERSION, /* u32Version */
    669778        sizeof (*s),            /* cbGuess */
    670779        NULL,                   /* pfnSavePrep */
    671         SaveExec,               /* pfnSaveExec */
     780        serialSaveExec,         /* pfnSaveExec */
    672781        NULL,                   /* pfnSaveDone */
    673782        NULL,                   /* pfnLoadPrep */
    674         LoadExec,               /* pfnLoadExec */
     783        serialLoadExec,         /* pfnLoadExec */
    675784        NULL                    /* pfnLoadDone */
    676785        );
     
    727836    NULL
    728837};
    729 #endif
     838#endif /* VBOX */
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