cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

hcd-ehci.h (11707B)


      1/*
      2 * QEMU USB EHCI Emulation
      3 *
      4 * This library is free software; you can redistribute it and/or
      5 * modify it under the terms of the GNU Lesser General Public
      6 * License as published by the Free Software Foundation; either
      7 * version 2.1 of the License, or (at your option) any later version.
      8 *
      9 * This library is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 * Lesser General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU Lesser General Public License
     15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#ifndef HW_USB_HCD_EHCI_H
     19#define HW_USB_HCD_EHCI_H
     20
     21#include "qemu/timer.h"
     22#include "hw/usb.h"
     23#include "sysemu/dma.h"
     24#include "hw/pci/pci.h"
     25#include "hw/sysbus.h"
     26#include "qom/object.h"
     27
     28#ifndef EHCI_DEBUG
     29#define EHCI_DEBUG   0
     30#endif
     31
     32#if EHCI_DEBUG
     33#define DPRINTF printf
     34#else
     35#define DPRINTF(...)
     36#endif
     37
     38#define MMIO_SIZE        0x1000
     39#define CAPA_SIZE        0x10
     40
     41#define NB_PORTS         6        /* Max. Number of downstream ports */
     42
     43typedef struct EHCIPacket EHCIPacket;
     44typedef struct EHCIQueue EHCIQueue;
     45typedef struct EHCIState EHCIState;
     46
     47/*  EHCI spec version 1.0 Section 3.3
     48 */
     49typedef struct EHCIitd {
     50    uint32_t next;
     51
     52    uint32_t transact[8];
     53#define ITD_XACT_ACTIVE          (1 << 31)
     54#define ITD_XACT_DBERROR         (1 << 30)
     55#define ITD_XACT_BABBLE          (1 << 29)
     56#define ITD_XACT_XACTERR         (1 << 28)
     57#define ITD_XACT_LENGTH_MASK     0x0fff0000
     58#define ITD_XACT_LENGTH_SH       16
     59#define ITD_XACT_IOC             (1 << 15)
     60#define ITD_XACT_PGSEL_MASK      0x00007000
     61#define ITD_XACT_PGSEL_SH        12
     62#define ITD_XACT_OFFSET_MASK     0x00000fff
     63
     64    uint32_t bufptr[7];
     65#define ITD_BUFPTR_MASK          0xfffff000
     66#define ITD_BUFPTR_SH            12
     67#define ITD_BUFPTR_EP_MASK       0x00000f00
     68#define ITD_BUFPTR_EP_SH         8
     69#define ITD_BUFPTR_DEVADDR_MASK  0x0000007f
     70#define ITD_BUFPTR_DEVADDR_SH    0
     71#define ITD_BUFPTR_DIRECTION     (1 << 11)
     72#define ITD_BUFPTR_MAXPKT_MASK   0x000007ff
     73#define ITD_BUFPTR_MAXPKT_SH     0
     74#define ITD_BUFPTR_MULT_MASK     0x00000003
     75#define ITD_BUFPTR_MULT_SH       0
     76} EHCIitd;
     77
     78/*  EHCI spec version 1.0 Section 3.4
     79 */
     80typedef struct EHCIsitd {
     81    uint32_t next;                  /* Standard next link pointer */
     82    uint32_t epchar;
     83#define SITD_EPCHAR_IO              (1 << 31)
     84#define SITD_EPCHAR_PORTNUM_MASK    0x7f000000
     85#define SITD_EPCHAR_PORTNUM_SH      24
     86#define SITD_EPCHAR_HUBADD_MASK     0x007f0000
     87#define SITD_EPCHAR_HUBADDR_SH      16
     88#define SITD_EPCHAR_EPNUM_MASK      0x00000f00
     89#define SITD_EPCHAR_EPNUM_SH        8
     90#define SITD_EPCHAR_DEVADDR_MASK    0x0000007f
     91
     92    uint32_t uframe;
     93#define SITD_UFRAME_CMASK_MASK      0x0000ff00
     94#define SITD_UFRAME_CMASK_SH        8
     95#define SITD_UFRAME_SMASK_MASK      0x000000ff
     96
     97    uint32_t results;
     98#define SITD_RESULTS_IOC              (1 << 31)
     99#define SITD_RESULTS_PGSEL            (1 << 30)
    100#define SITD_RESULTS_TBYTES_MASK      0x03ff0000
    101#define SITD_RESULTS_TYBYTES_SH       16
    102#define SITD_RESULTS_CPROGMASK_MASK   0x0000ff00
    103#define SITD_RESULTS_CPROGMASK_SH     8
    104#define SITD_RESULTS_ACTIVE           (1 << 7)
    105#define SITD_RESULTS_ERR              (1 << 6)
    106#define SITD_RESULTS_DBERR            (1 << 5)
    107#define SITD_RESULTS_BABBLE           (1 << 4)
    108#define SITD_RESULTS_XACTERR          (1 << 3)
    109#define SITD_RESULTS_MISSEDUF         (1 << 2)
    110#define SITD_RESULTS_SPLITXSTATE      (1 << 1)
    111
    112    uint32_t bufptr[2];
    113#define SITD_BUFPTR_MASK              0xfffff000
    114#define SITD_BUFPTR_CURROFF_MASK      0x00000fff
    115#define SITD_BUFPTR_TPOS_MASK         0x00000018
    116#define SITD_BUFPTR_TPOS_SH           3
    117#define SITD_BUFPTR_TCNT_MASK         0x00000007
    118
    119    uint32_t backptr;                 /* Standard next link pointer */
    120} EHCIsitd;
    121
    122/*  EHCI spec version 1.0 Section 3.5
    123 */
    124typedef struct EHCIqtd {
    125    uint32_t next;                    /* Standard next link pointer */
    126    uint32_t altnext;                 /* Standard next link pointer */
    127    uint32_t token;
    128#define QTD_TOKEN_DTOGGLE             (1 << 31)
    129#define QTD_TOKEN_TBYTES_MASK         0x7fff0000
    130#define QTD_TOKEN_TBYTES_SH           16
    131#define QTD_TOKEN_IOC                 (1 << 15)
    132#define QTD_TOKEN_CPAGE_MASK          0x00007000
    133#define QTD_TOKEN_CPAGE_SH            12
    134#define QTD_TOKEN_CERR_MASK           0x00000c00
    135#define QTD_TOKEN_CERR_SH             10
    136#define QTD_TOKEN_PID_MASK            0x00000300
    137#define QTD_TOKEN_PID_SH              8
    138#define QTD_TOKEN_ACTIVE              (1 << 7)
    139#define QTD_TOKEN_HALT                (1 << 6)
    140#define QTD_TOKEN_DBERR               (1 << 5)
    141#define QTD_TOKEN_BABBLE              (1 << 4)
    142#define QTD_TOKEN_XACTERR             (1 << 3)
    143#define QTD_TOKEN_MISSEDUF            (1 << 2)
    144#define QTD_TOKEN_SPLITXSTATE         (1 << 1)
    145#define QTD_TOKEN_PING                (1 << 0)
    146
    147    uint32_t bufptr[5];               /* Standard buffer pointer */
    148#define QTD_BUFPTR_MASK               0xfffff000
    149#define QTD_BUFPTR_SH                 12
    150} EHCIqtd;
    151
    152/*  EHCI spec version 1.0 Section 3.6
    153 */
    154typedef struct EHCIqh {
    155    uint32_t next;                    /* Standard next link pointer */
    156
    157    /* endpoint characteristics */
    158    uint32_t epchar;
    159#define QH_EPCHAR_RL_MASK             0xf0000000
    160#define QH_EPCHAR_RL_SH               28
    161#define QH_EPCHAR_C                   (1 << 27)
    162#define QH_EPCHAR_MPLEN_MASK          0x07FF0000
    163#define QH_EPCHAR_MPLEN_SH            16
    164#define QH_EPCHAR_H                   (1 << 15)
    165#define QH_EPCHAR_DTC                 (1 << 14)
    166#define QH_EPCHAR_EPS_MASK            0x00003000
    167#define QH_EPCHAR_EPS_SH              12
    168#define EHCI_QH_EPS_FULL              0
    169#define EHCI_QH_EPS_LOW               1
    170#define EHCI_QH_EPS_HIGH              2
    171#define EHCI_QH_EPS_RESERVED          3
    172
    173#define QH_EPCHAR_EP_MASK             0x00000f00
    174#define QH_EPCHAR_EP_SH               8
    175#define QH_EPCHAR_I                   (1 << 7)
    176#define QH_EPCHAR_DEVADDR_MASK        0x0000007f
    177#define QH_EPCHAR_DEVADDR_SH          0
    178
    179    /* endpoint capabilities */
    180    uint32_t epcap;
    181#define QH_EPCAP_MULT_MASK            0xc0000000
    182#define QH_EPCAP_MULT_SH              30
    183#define QH_EPCAP_PORTNUM_MASK         0x3f800000
    184#define QH_EPCAP_PORTNUM_SH           23
    185#define QH_EPCAP_HUBADDR_MASK         0x007f0000
    186#define QH_EPCAP_HUBADDR_SH           16
    187#define QH_EPCAP_CMASK_MASK           0x0000ff00
    188#define QH_EPCAP_CMASK_SH             8
    189#define QH_EPCAP_SMASK_MASK           0x000000ff
    190#define QH_EPCAP_SMASK_SH             0
    191
    192    uint32_t current_qtd;             /* Standard next link pointer */
    193    uint32_t next_qtd;                /* Standard next link pointer */
    194    uint32_t altnext_qtd;
    195#define QH_ALTNEXT_NAKCNT_MASK        0x0000001e
    196#define QH_ALTNEXT_NAKCNT_SH          1
    197
    198    uint32_t token;                   /* Same as QTD token */
    199    uint32_t bufptr[5];               /* Standard buffer pointer */
    200#define BUFPTR_CPROGMASK_MASK         0x000000ff
    201#define BUFPTR_FRAMETAG_MASK          0x0000001f
    202#define BUFPTR_SBYTES_MASK            0x00000fe0
    203#define BUFPTR_SBYTES_SH              5
    204} EHCIqh;
    205
    206/*  EHCI spec version 1.0 Section 3.7
    207 */
    208typedef struct EHCIfstn {
    209    uint32_t next;                    /* Standard next link pointer */
    210    uint32_t backptr;                 /* Standard next link pointer */
    211} EHCIfstn;
    212
    213enum async_state {
    214    EHCI_ASYNC_NONE = 0,
    215    EHCI_ASYNC_INITIALIZED,
    216    EHCI_ASYNC_INFLIGHT,
    217    EHCI_ASYNC_FINISHED,
    218};
    219
    220struct EHCIPacket {
    221    EHCIQueue *queue;
    222    QTAILQ_ENTRY(EHCIPacket) next;
    223
    224    EHCIqtd qtd;           /* copy of current QTD (being worked on) */
    225    uint32_t qtdaddr;      /* address QTD read from                 */
    226
    227    USBPacket packet;
    228    QEMUSGList sgl;
    229    int pid;
    230    enum async_state async;
    231};
    232
    233struct EHCIQueue {
    234    EHCIState *ehci;
    235    QTAILQ_ENTRY(EHCIQueue) next;
    236    uint32_t seen;
    237    uint64_t ts;
    238    int async;
    239    int transact_ctr;
    240
    241    /* cached data from guest - needs to be flushed
    242     * when guest removes an entry (doorbell, handshake sequence)
    243     */
    244    EHCIqh qh;             /* copy of current QH (being worked on) */
    245    uint32_t qhaddr;       /* address QH read from                 */
    246    uint32_t qtdaddr;      /* address QTD read from                */
    247    int last_pid;          /* pid of last packet executed          */
    248    USBDevice *dev;
    249    QTAILQ_HEAD(, EHCIPacket) packets;
    250};
    251
    252typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead;
    253
    254struct EHCIState {
    255    USBBus bus;
    256    DeviceState *device;
    257    qemu_irq irq;
    258    MemoryRegion mem;
    259    AddressSpace *as;
    260    MemoryRegion mem_caps;
    261    MemoryRegion mem_opreg;
    262    MemoryRegion mem_ports;
    263    int companion_count;
    264    bool companion_enable;
    265    uint16_t capsbase;
    266    uint16_t opregbase;
    267    uint16_t portscbase;
    268    uint16_t portnr;
    269
    270    /* properties */
    271    uint32_t maxframes;
    272
    273    /*
    274     *  EHCI spec version 1.0 Section 2.3
    275     *  Host Controller Operational Registers
    276     */
    277    uint8_t caps[CAPA_SIZE];
    278    union {
    279        uint32_t opreg[0x44/sizeof(uint32_t)];
    280        struct {
    281            uint32_t usbcmd;
    282            uint32_t usbsts;
    283            uint32_t usbintr;
    284            uint32_t frindex;
    285            uint32_t ctrldssegment;
    286            uint32_t periodiclistbase;
    287            uint32_t asynclistaddr;
    288            uint32_t notused[9];
    289            uint32_t configflag;
    290        };
    291    };
    292    uint32_t portsc[NB_PORTS];
    293
    294    /*
    295     *  Internal states, shadow registers, etc
    296     */
    297    QEMUTimer *frame_timer;
    298    QEMUBH *async_bh;
    299    bool working;
    300    uint32_t astate;         /* Current state in asynchronous schedule */
    301    uint32_t pstate;         /* Current state in periodic schedule     */
    302    USBPort ports[NB_PORTS];
    303    USBPort *companion_ports[NB_PORTS];
    304    uint32_t usbsts_pending;
    305    uint32_t usbsts_frindex;
    306    EHCIQueueHead aqueues;
    307    EHCIQueueHead pqueues;
    308
    309    /* which address to look at next */
    310    uint32_t a_fetch_addr;
    311    uint32_t p_fetch_addr;
    312
    313    USBPacket ipacket;
    314    QEMUSGList isgl;
    315
    316    uint64_t last_run_ns;
    317    uint32_t async_stepdown;
    318    uint32_t periodic_sched_active;
    319    bool int_req_by_async;
    320    VMChangeStateEntry *vmstate;
    321};
    322
    323extern const VMStateDescription vmstate_ehci;
    324
    325void usb_ehci_init(EHCIState *s, DeviceState *dev);
    326void usb_ehci_finalize(EHCIState *s);
    327void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp);
    328void usb_ehci_unrealize(EHCIState *s, DeviceState *dev);
    329void ehci_reset(void *opaque);
    330
    331#define TYPE_PCI_EHCI "pci-ehci-usb"
    332OBJECT_DECLARE_SIMPLE_TYPE(EHCIPCIState, PCI_EHCI)
    333
    334struct EHCIPCIState {
    335    /*< private >*/
    336    PCIDevice pcidev;
    337    /*< public >*/
    338
    339    EHCIState ehci;
    340};
    341
    342
    343#define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb"
    344#define TYPE_PLATFORM_EHCI "platform-ehci-usb"
    345#define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb"
    346#define TYPE_AW_H3_EHCI "aw-h3-ehci-usb"
    347#define TYPE_NPCM7XX_EHCI "npcm7xx-ehci-usb"
    348#define TYPE_TEGRA2_EHCI "tegra2-ehci-usb"
    349#define TYPE_PPC4xx_EHCI "ppc4xx-ehci-usb"
    350#define TYPE_FUSBH200_EHCI "fusbh200-ehci-usb"
    351
    352OBJECT_DECLARE_TYPE(EHCISysBusState, SysBusEHCIClass, SYS_BUS_EHCI)
    353
    354struct EHCISysBusState {
    355    /*< private >*/
    356    SysBusDevice parent_obj;
    357    /*< public >*/
    358
    359    EHCIState ehci;
    360};
    361
    362struct SysBusEHCIClass {
    363    /*< private >*/
    364    SysBusDeviceClass parent_class;
    365    /*< public >*/
    366
    367    uint16_t capsbase;
    368    uint16_t opregbase;
    369    uint16_t portscbase;
    370    uint16_t portnr;
    371};
    372
    373OBJECT_DECLARE_SIMPLE_TYPE(FUSBH200EHCIState, FUSBH200_EHCI)
    374
    375struct FUSBH200EHCIState {
    376    /*< private >*/
    377    EHCISysBusState parent_obj;
    378    /*< public >*/
    379
    380    MemoryRegion mem_vendor;
    381};
    382
    383#endif