// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVICES_USB_DRIVERS_XHCI_REWRITE_REGISTERS_H_
#define SRC_DEVICES_USB_DRIVERS_XHCI_REWRITE_REGISTERS_H_

#include <zircon/types.h>

#include <hw/arch_ops.h>
#include <hwreg/bitfields.h>
#include <hwreg/mmio.h>

namespace usb_xhci {

// All section references refer to xHCI specification revision 1.2
// unless stated otherwise.

// section 3.2.7
struct TRB {
  uint64_t ptr = 0;
  uint32_t status = 0;
  uint32_t control = 0;
};

// Section 6.4.2.2
struct CommandCompletionEvent : TRB {
  //  6.4.5
  enum CompletionCode {
    Invalid = 0,
    Success = 1,
    DataBufferError = 2,
    BabbleJS = 3,
    UsbTransactionError = 4,
    TRBError = 5,
    StallError = 6,
    ResourceError = 7,
    BandwidthError = 8,
    NoSlotsAvailableError = 9,
    InvalidStreamType = 10,
    SlotNotEnabledError = 11,
    EndpointNotEnabledError = 12,
    ShortPacket = 13,
    RingUnderrun = 14,
    RingOverrun = 15,
    VfEventRingFullError = 16,  // Only applicable to virtualized environments
    ParameterError = 17,
    BandwidthOverrunError = 18,
    ContextStateError = 19,
    NoPingResponseError = 20,
    EventRingFullError = 21,
    IncompatibleDeviceError = 22,
    MissedServiceError = 23,
    CommandRingStopped = 24,
    CommandAborted = 25,
    Stopped = 26,
    StoppedLengthInvalid = 27,
    StoppedShortPacket = 28,
    MaxExitLatencyTooLarge = 29,
    IsochBufferOverrun = 31,
    EventLostError = 32,
    UndefinedError = 33,
    InvalidStreamIdError = 34,
    SecondaryBandwidthError = 35,
    SplitTransactionError = 36,
  };
  DEF_SUBFIELD(status, 31, 24, CompletionCode);
  DEF_SUBFIELD(control, 31, 24, SlotID);
  DEF_SUBFIELD(status, 23, 0, Parameter);
  DEF_SUBFIELD(control, 15, 10, Type);
};

// Section 6.4.2.3
struct PortStatusChangeEvent : TRB {
  DEF_SUBFIELD(ptr, 31, 24, PortID);
};

// Section 6.4.2.1
struct TransferEvent : TRB {
  DEF_SUBFIELD(status, 31, 24, CompletionCode);
  DEF_SUBFIELD(control, 31, 24, SlotID);
  DEF_SUBFIELD(status, 23, 0, TransferLength);
  DEF_SUBFIELD(control, 20, 16, EndpointID);
};

// Control register portion of a TRB (section 4.11.1)
class Control : public hwreg::RegisterBase<Control, uint32_t> {
 public:
  DEF_FIELD(15, 10, Type);
  // Cycle bit
  DEF_BIT(0, Cycle);
  // EntTC -- Evaluate next TRB in chain
  // (used for scatter-gather chained transfers)
  // OR
  // Toggle Cycle for link TRBs
  DEF_BIT(1, EntTC);

  // Section 6.4.6
  enum Type {
    Normal = 1,
    Setup = 2,
    Data = 3,
    Status = 4,
    Isoch = 5,
    Link = 6,
    EventData = 7,
    Nop = 8,
    EnableSlot = 9,
    DisableSlot = 10,
    AddressDeviceCommand = 11,
    ConfigureEndpointCommand = 12,
    EvaluateContextCommand = 13,
    ResetEndpointCommand = 14,
    StopEndpointCommand = 15,
    SetTrDequeuePointerCommand = 16,
    ResetDeviceCommand = 17,
    ForceEventCommand = 18,  // Only supported in virtualized environments
    NegotiateBandwidthCommand = 19,
    SetLatencyToleranceCommand = 20,
    GetPortBandwidthCommand = 21,
    ForceHeaderCommand = 22,
    NopCommand = 23,
    GetExtendedPropertyCommand = 24,
    SetExtendedPropertyCommand = 25,
    TransferEvent = 32,
    CommandCompletionEvent = 33,
    PortStatusChangeEvent = 34,
    BandwidthRequestEvent = 35,
    DoorbellEvent = 36,  // Only supported in virtualized environments
    HostControllerEvent = 37,
    DeviceNotificationEvent = 38,
    MFIndexWrapEvent = 39,
  };

  static auto Get() { return hwreg::RegisterAddr<Control>(0x0); }

  void ToTrb(TRB* trb) {
    hwreg::RegisterMmio io(&trb->control);
    WriteTo(&io);
    hw_mb();
  }

  static auto FromTRB(TRB* trb) {
    hwreg::RegisterMmio io(&trb->control);
    return Control::Get().ReadFrom(&io);
  }
};

// Section 6.4.3.4
struct AddressDeviceStruct : TRB {
  DEF_SUBFIELD(control, 31, 24, SlotID);
  // See section 4.6.5. This should normally be set to 0.
  DEF_SUBBIT(control, 9, BSR);
  AddressDeviceStruct() {
    Control::FromTRB(this).set_Type(Control::Type::AddressDeviceCommand).ToTrb(this);
  }
};

// Section 6.4.3.3
struct DisableSlot : TRB {
  DEF_SUBFIELD(control, 31, 24, slot);
  DisableSlot() { Control::Get().FromValue(0).set_Type(Control::DisableSlot).ToTrb(this); }
};

// Section 6.4.3.7
struct ResetEndpoint : TRB {
  // Transfer State Previous
  DEF_SUBFIELD(control, 31, 24, SLOT);
  DEF_SUBFIELD(control, 20, 16, ENDPOINT);
  DEF_SUBBIT(control, 9, TSP);
  ResetEndpoint() { Control::Get().FromValue(0).set_Type(Control::ResetDeviceCommand).ToTrb(this); }
};

// Section 6.4.3.8
struct StopEndpoint : TRB {
  DEF_SUBFIELD(control, 31, 24, SLOT);
  DEF_SUBFIELD(control, 20, 16, ENDPOINT);
  StopEndpoint() { Control::Get().FromValue(0).set_Type(Control::StopEndpointCommand).ToTrb(this); }
};

// Section 6.4.3.9
struct SetTRDequeuePointer : TRB {
  DEF_SUBFIELD(control, 31, 24, SLOT);
  DEF_SUBFIELD(control, 20, 16, ENDPOINT);
  SetTRDequeuePointer() {
    Control::Get().FromValue(0).set_Type(Control::SetTrDequeuePointerCommand).ToTrb(this);
  }
};

// Isochronous TRB (Section 6.4.1.3)
struct Isoch : TRB {
  DEF_SUBFIELD(status, 31, 22, INTERRUPTER);
  // This bit should always be set to 0. Only set to 1 for testing purposes.
  DEF_SUBBIT(control, 31, SIA);
  DEF_SUBFIELD(control, 30, 20, FrameID);
  // Number of packets remaining in this TD
  // See section 4.10.2.4
  DEF_SUBFIELD(status, 21, 17, SIZE);
  // Transfer Last Burst Packet count (number of packets in the last burst)
  // Refer to section 4.11.2.3 for more information
  DEF_SUBFIELD(control, 19, 16, TLBPC);
  DEF_SUBFIELD(status, 16, 0, LENGTH);
  // Block event interrupt -- inserts an event into the event ring
  // but does not assert the interrupt line.
  DEF_SUBBIT(control, 9, BEI);
  // Number of bursts - 1 that are required to move this TD.
  DEF_SUBFIELD(control, 8, 7, TBC);
  // Immediate data instead of ptr
  DEF_SUBBIT(control, 6, IDT);
  // Generate interrupt on completion
  DEF_SUBBIT(control, 5, IOC);
  // Set to 1 on everything except the last transfer
  DEF_SUBBIT(control, 4, CHAIN);
  // Don't snoop the bus -- go directly to memory.
  // Valid for PCIe only.
  DEF_SUBBIT(control, 3, NO_SNOOP);
  // Interrupt on Short Packet
  DEF_SUBBIT(control, 2, ISP);
  Isoch() { Control::Get().FromValue(0).set_Type(Control::Isoch).ToTrb(this); }
};

// Normal TRB (Section 6.4.1.1)
struct Normal : TRB {
  DEF_SUBFIELD(status, 31, 22, INTERRUPTER);
  // Number of packets remaining in this TD
  // See section 4.10.2.4
  DEF_SUBFIELD(status, 21, 17, SIZE);
  DEF_SUBFIELD(status, 16, 0, LENGTH);
  // Block event interrupt -- inserts an event into the event ring
  // but does not assert the interrupt line.
  DEF_SUBBIT(control, 9, BEI);
  // Immediate data instead of ptr
  DEF_SUBBIT(control, 6, IDT);
  // Generate interrupt on completion
  DEF_SUBBIT(control, 5, IOC);
  // Set to 1 on everything except the last transfer
  DEF_SUBBIT(control, 4, CHAIN);
  // Don't snoop the bus -- go directly to memory.
  // Valid for PCIe only.
  DEF_SUBBIT(control, 3, NO_SNOOP);
  // Interrupt on Short Packet
  DEF_SUBBIT(control, 2, ISP);
  Normal() { Control::Get().FromValue(0).set_Type(Control::Normal).ToTrb(this); }
};

// Setup TRB (Section 6.4.1.2.1)
struct Setup : TRB {
  enum TransferType {
    NoDataStage = 0,
    OUT = 2,
    IN = 3,
  };
  DEF_SUBFIELD(status, 31, 22, INTERRUPTER);
  DEF_SUBFIELD(status, 16, 0, length);
  // Transfer type
  DEF_SUBFIELD(control, 17, 16, TRT);
  // Immediate data instead of ptr
  DEF_SUBBIT(control, 6, IDT);
  // Interrupt on Short Packet
  // Generate interrupt on completion
  DEF_SUBBIT(control, 5, IOC);
  Setup() {
    Control::Get().FromValue(0).set_Type(Control::Setup).ToTrb(this);
    set_IDT(1);
  }
};

// Data stage TRB for control endpoint (6.4.1.2.2)
struct ControlData : TRB {
  DEF_SUBFIELD(status, 31, 22, INTERRUPTER);
  // Number of packets remaining in this TD
  // See section 4.10.2.4
  DEF_SUBFIELD(status, 21, 17, SIZE);
  DEF_SUBFIELD(status, 16, 0, LENGTH);
  // 0 == OUT, 1 == IN
  DEF_SUBBIT(control, 16, DIRECTION);
  // Immediate data instead of ptr
  DEF_SUBBIT(control, 6, IDT);
  // Generate interrupt on completion
  DEF_SUBBIT(control, 5, IOC);
  // Set to 1 on everything except the last transfer
  DEF_SUBBIT(control, 4, CHAIN);
  // Don't snoop the bus -- go directly to memory.
  // Valid for PCIe only.
  DEF_SUBBIT(control, 3, NO_SNOOP);
  // Interrupt on Short Packet
  DEF_SUBBIT(control, 2, ISP);
  ControlData() { Control::Get().FromValue(0).set_Type(Control::Data).ToTrb(this); }
};

// 6.4.1.2.3
struct Status : TRB {
  DEF_SUBFIELD(status, 31, 22, INTERRUPTER);
  // 0 == OUT, 1 == IN
  DEF_SUBBIT(control, 16, DIRECTION);
  // Generate interrupt on completion
  DEF_SUBBIT(control, 5, IOC);
  // Set to 1 on everything except the last transfer
  DEF_SUBBIT(control, 4, CHAIN);
  Status() { Control::Get().FromValue(0).set_Type(Control::Status).ToTrb(this); }
};

// Section 6.2.5.1
// TODO (bbosak): Implement USB 3.1 support
class InputContextControlField : public hwreg::RegisterBase<InputContextControlField, uint32_t> {
 public:
  DEF_FIELD(23, 16, bAlternateSetting);
  DEF_FIELD(15, 8, bInterfaceNumber);
  DEF_FIELD(7, 0, bConfigurationValue);
  static auto Get() { return hwreg::RegisterAddr<InputContextControlField>(0x0); }
};

// Register definitions -- XHCI section 5.3
class CapLength : public hwreg::RegisterBase<CapLength, uint8_t> {
 public:
  DEF_FIELD(7, 0, Length);
  static auto Get() { return hwreg::RegisterAddr<CapLength>(0x0); }
};

class HciVersion : public hwreg::RegisterBase<HciVersion, uint16_t> {
 public:
  DEF_FIELD(15, 8, Minor);
  DEF_FIELD(7, 0, Major);
  static auto Get() { return hwreg::RegisterAddr<HciVersion>(0x2); }
};

class HCSPARAMS1 : public hwreg::RegisterBase<HCSPARAMS1, uint32_t> {
 public:
  DEF_FIELD(31, 24, MaxPorts);
  DEF_FIELD(18, 8, MaxIntrs);
  DEF_FIELD(7, 0, MaxSlots);
  static auto Get() { return hwreg::RegisterAddr<HCSPARAMS1>(0x4); }
};

class HCSPARAMS2 : public hwreg::RegisterBase<HCSPARAMS2, uint32_t> {
 public:
  // Max number of ERST entries == 2^ERST_MAX
  DEF_FIELD(31, 27, MAX_SCRATCHPAD_BUFFERS_LOW);
  DEF_FIELD(25, 21, MAX_SCRATCHPAD_BUFFERS_HIGH);
  DEF_FIELD(7, 4, ERST_MAX);
  static auto Get() { return hwreg::RegisterAddr<HCSPARAMS2>(0x8); }
};

class HCCPARAMS1 : public hwreg::RegisterBase<HCCPARAMS1, uint32_t> {
 public:
  // Extended Capabilities Pointer (offset from Base MMIO address)
  DEF_FIELD(31, 16, xECP);
  DEF_BIT(2, CSZ);
  // 64-bit addressing capability
  DEF_BIT(0, AC64);
  static auto Get() { return hwreg::RegisterAddr<HCCPARAMS1>(0x10); }
};

class XECP : public hwreg::RegisterBase<XECP, uint32_t> {
 public:
  hwreg::RegisterAddr<XECP> Next() { return hwreg::RegisterAddr<XECP>(reg_addr() + (NEXT() * 4)); }
  enum Type {
    Reserved = 0,
    UsbLegacySupport = 1,
    SupportedProtocol = 2,
    ExtendedPowerManagement = 3,
    IOVirtualization = 4,
  };
  DEF_FIELD(31, 16, CAP_INFO);
  DEF_FIELD(15, 8, NEXT);
  DEF_ENUM_FIELD(Type, 7, 0, ID);
  static auto Get(HCCPARAMS1 params) { return hwreg::RegisterAddr<XECP>(params.xECP() * 4); }
};

class DoorbellOffset : public hwreg::RegisterBase<DoorbellOffset, uint32_t> {
 public:
  DEF_FIELD(31, 0, DBOFF);
  static auto Get() { return hwreg::RegisterAddr<DoorbellOffset>(0x14); }
};

// Section 5.3.8
class RuntimeRegisterOffset : public hwreg::RegisterBase<RuntimeRegisterOffset, uint32_t> {
 public:
  DEF_FIELD(31, 0, RO);
  static auto Get() { return hwreg::RegisterAddr<RuntimeRegisterOffset>(0x18); }
};

// Section 5.4.1
class USBCMD : public hwreg::RegisterBase<USBCMD, uint32_t> {
 public:
  // Enable Wrap event
  DEF_BIT(10, EWE);
  // Host system error enable
  DEF_BIT(3, HSEE);
  // Interrupt enable
  DEF_BIT(2, INTE);
  // Writing a 1 will reset the xHCI. This bit will be set to 0
  // when reset is complete. Software is responsible for re-initializing the xHCI
  // after the reset is performed.
  DEF_BIT(1, RESET);
  // Run/stop register to enable or disable the xHCI.
  // If set to 1, commands will be processed.
  // If set to 0, the xHCI will halt within 16ms.
  // Refer to USBSTS to determine the current operational status of the xHCI.
  DEF_BIT(0, ENABLE);
  static auto Get(uint8_t cap_length) { return hwreg::RegisterAddr<USBCMD>(cap_length + 0x0); }
};

class USBSTS : public hwreg::RegisterBase<USBSTS, uint32_t> {
 public:
  // Host controller (non-fatal) error.
  // When this bit is set, it indicates that an internal error within the host controller
  // has occurred. Software should respond by resetting the HCI whenever this happens.
  DEF_BIT(12, HCE);
  // Controller not ready -- software should wait until this bit is cleared
  // before performing I/O.
  DEF_BIT(11, CNR);
  // Set to 1 when an interrupt is pending.
  // This MUST be cleared before clearing any IP flags.
  DEF_BIT(3, EINT);
  // Host system (potentially fatal) error occurred. If this happens, the driver
  // should probably unbind. It is indicative of instability
  // in the connection between xHCI and the host.
  DEF_BIT(2, HSE);
  DEF_BIT(0, HCHalted);

  static auto Get(uint8_t cap_length) { return hwreg::RegisterAddr<USBSTS>(cap_length + 0x4); }
};

class USB_PAGESIZE : public hwreg::RegisterBase<USB_PAGESIZE, uint32_t> {
 public:
  DEF_FIELD(15, 0, PageSize);
  static auto Get(uint8_t cap_length) {
    return hwreg::RegisterAddr<USB_PAGESIZE>(cap_length + 0x8);
  }
};

// Command Ring Control Register
// section 5.4.5
class CRCR : public hwreg::RegisterBase<CRCR, uint64_t> {
 public:
  DEF_UNSHIFTED_FIELD(63, 4, PTR);
  // Command ring running
  DEF_BIT(3, CRR);
  // Command abort -- Aborts the running command and generates a
  // stopped event when complete.
  DEF_BIT(2, CA);
  // Command stop -- asynchronously aborts the running command
  // and generates a stopped event when complete.
  DEF_BIT(1, CS);
  // Consumer cycle state (see 4.9.3)
  DEF_BIT(0, RCS);
  static auto Get(uint8_t cap_length) { return hwreg::RegisterAddr<CRCR>(cap_length + 0x18); }
};

class DCBAAP : public hwreg::RegisterBase<DCBAAP, uint64_t> {
 public:
  DEF_UNSHIFTED_FIELD(63, 6, PTR);
  static auto Get(uint8_t cap_length) { return hwreg::RegisterAddr<DCBAAP>(cap_length + 0x30); }
};

class CONFIG : public hwreg::RegisterBase<CONFIG, uint32_t> {
 public:
  DEF_FIELD(7, 0, MaxSlotsEn);
  static auto Get(uint8_t cap_length) { return hwreg::RegisterAddr<CONFIG>(cap_length + 0x38); }
};

// Section 5.4.8
class PORTSC : public hwreg::RegisterBase<PORTSC, uint32_t> {
 public:
  // Port link change
  DEF_BIT(22, PLC);
  // Port reset change
  DEF_BIT(21, PRC);
  // Overcurrent change
  DEF_BIT(20, OCC);
  // Warm port reset for USB 3.0 ports
  DEF_BIT(19, WRC);
  // Port enabled/disabled changed. Only applicable to USB 2.0 ports
  DEF_BIT(18, PEC);
  // Events -- each event must be ACKed by writing a 1 to it if set
  // Connect status change
  DEF_BIT(17, CSC);
  // Write a 1 to this field before writing to PLS
  DEF_BIT(16, LWS);
  // Port Indicator Control
  DEF_FIELD(15, 14, PIC);
  // Speed ID (see 7.2.1 to find actual speed this represents)
  DEF_FIELD(13, 10, PortSpeed);
  // Port Power bit
  DEF_BIT(9, PP);
  enum LinkState {
    U0 = 0,
    U1 = 1,
    U2 = 2,
    U3 = 3,
    Disabled = 4,
    RxDetect = 5,
    Inactive = 6,
    Polling = 7,
    Recovery = 8,
    HotReset = 9,
    ComplianceMode = 10,
    TestMode = 11,
    Resume = 15,
  };
  // Port Link State. Must write a 1 to LWS prior to writing this field.
  DEF_ENUM_FIELD(LinkState, 8, 5, PLS);
  // Port reset
  // For USB 2.0, write this bit to transition from POLLING to ENABLED state.
  // For USB 3.0, writing this bit will cause a hot reset.
  DEF_BIT(4, PR);
  // Overcurrent active. Not sure how to handle this?
  DEF_BIT(3, OCA);
  // Port enabled (write a 1 to disable it)
  // Reset the port to enable it again
  DEF_BIT(1, PED);
  // Current connect status (1 when a device is connected)
  DEF_BIT(0, CCS);
  static auto Get(uint8_t cap_length, uint16_t port) {
    return hwreg::RegisterAddr<PORTSC>(cap_length + (0x400 + (0x10 * (port - 1))));
  }
};

// Section 5.5.1
class MFINDEX : public hwreg::RegisterBase<MFINDEX, uint32_t> {
 public:
  // Interrupt pending
  DEF_FIELD(13, 0, INDEX);
  static auto Get(const RuntimeRegisterOffset& reg_offset) {
    return hwreg::RegisterAddr<MFINDEX>(reg_offset.RO());
  }
};

// Section 5.5.2.3.1
class ERSTSZ : public hwreg::RegisterBase<ERSTSZ, uint32_t> {
 public:
  DEF_FIELD(15, 0, TableSize);
  static auto Get(const RuntimeRegisterOffset& reg_offset, uint32_t interrupter) {
    return hwreg::RegisterAddr<ERSTSZ>(reg_offset.RO() + 0x28 + (32 * interrupter));
  }
};

// Section 5.5.2.3.2
class ERSTBA : public hwreg::RegisterBase<ERSTBA, uint64_t> {
 public:
  // Spec incorrectly had 63, 6.
  DEF_FIELD(63, 0, Pointer);
  static auto Get(const RuntimeRegisterOffset& reg_offset, uint32_t interrupter) {
    return hwreg::RegisterAddr<ERSTBA>(reg_offset.RO() + 0x30 + (32 * interrupter));
  }
};

// Section 5.5.2.3.3
// Address overlaps EHB, which isn't supported by our register library.
// This is safe due to the page-alignment requirements of the ERDP
class ERDP : public hwreg::RegisterBase<ERDP, uint64_t> {
 public:
  // Event handler busy -- must be cleared by software
  // when the dequeue pointer register is written to
  // Refer to section 4.17.2
  DEF_UNSHIFTED_FIELD(63, 4, Pointer);
  DEF_BIT(3, EHB);
  DEF_FIELD(2, 0, DESI);
  // Event Ring Dequeue Pointer overlaps EHB.
  static auto Get(const RuntimeRegisterOffset& reg_offset, uint32_t interrupter) {
    return hwreg::RegisterAddr<ERDP>(reg_offset.RO() + 0x38 + (32 * interrupter));
  }
};

// Section 5.5.2.1
class IMAN : public hwreg::RegisterBase<IMAN, uint32_t> {
 public:
  // Interrupt enable
  DEF_BIT(1, IE);
  // Interrupt pending
  DEF_BIT(0, IP);
  // Event Ring Dequeue Pointer
  static auto Get(const RuntimeRegisterOffset& reg_offset, uint32_t interrupter) {
    return hwreg::RegisterAddr<IMAN>(reg_offset.RO() + 0x20 + (32 * interrupter));
  }
};

// Section 5.5.2.2
class IMODI : public hwreg::RegisterBase<IMODI, uint32_t> {
 public:
  // Interrupt pending
  DEF_FIELD(15, 0, MODI);
  // Event Ring Dequeue Pointer
  static auto Get(const RuntimeRegisterOffset& reg_offset, uint32_t interrupter) {
    return hwreg::RegisterAddr<IMODI>(reg_offset.RO() + 0x24 + (32 * interrupter));
  }
};

// Section 5.6
class DOORBELL : public hwreg::RegisterBase<DOORBELL, uint32_t> {
 public:
  DEF_FIELD(31, 16, StreamID);
  DEF_FIELD(7, 0, Target);
  static auto Get(const DoorbellOffset& offset, uint32_t index) {
    return hwreg::RegisterAddr<DOORBELL>(offset.DBOFF() + (index * 4));
  }
};

// Section 6.2.2
struct SlotContext {
  uint32_t a;
  uint32_t b;
  uint32_t c;
  uint32_t d;
  DEF_SUBFIELD(b, 31, 24, PORT_COUNT);
  DEF_SUBFIELD(a, 31, 27, CONTEXT_ENTRIES);
  DEF_SUBBIT(a, 26, HUB);
  DEF_SUBBIT(a, 25, MULTI_TT);
  DEF_SUBFIELD(a, 23, 20, SPEED);
  // Root Hub Port Number
  DEF_SUBFIELD(b, 23, 16, PORTNO);
  DEF_SUBFIELD(a, 19, 0, ROUTE_STRING);
  // TT Think Time
  DEF_SUBFIELD(c, 17, 16, TTT);
  DEF_SUBFIELD(b, 15, 0, MAX_EXIT_LATENCY);
  DEF_SUBFIELD(c, 15, 8, PARENT_PORT_NUMBER);
  DEF_SUBFIELD(c, 7, 0, PARENT_HUB_SLOT_ID);
};

// Section 6.2.3
struct EndpointContext {
  uint32_t a;
  uint32_t b;
  uint32_t dequeue_pointer_a;
  uint32_t dequeue_pointer_b;
  uint32_t c;
  enum EndpointType {
    Invalid = 0,
    IsochOut = 1,
    BulkOut = 2,
    InterruptOut = 3,
    Control = 4,
    IsochIn = 5,
    BulkIn = 6,
    InterruptIn = 7,
  };
  DEF_SUBFIELD(c, 31, 16, MAX_ESIT_PAYLOAD_LOW);
  // Only set if LEC = 1
  DEF_SUBFIELD(a, 31, 24, MAX_ESIT_PAYLOAD_HI);
  DEF_SUBFIELD(b, 31, 16, MAX_PACKET_SIZE);
  DEF_SUBFIELD(a, 23, 16, Interval);
  DEF_SUBFIELD(b, 15, 8, MaxBurstSize);
  DEF_SUBFIELD(c, 15, 0, AVG_TRB_LENGTH);
  DEF_SUBFIELD(a, 9, 8, Mult);

  DEF_SUBFIELD(b, 5, 3, EP_TYPE);
  // CErr shall always be set to 3.
  DEF_SUBFIELD(b, 2, 1, CErr);
  DEF_SUBBIT(dequeue_pointer_a, 0, DCS);
  void Init(EndpointType type, CRCR dequeue_pointer, uint16_t max_packet_size = 8,
            uint16_t avg_trb_length = 8) {
    uint64_t ptr = dequeue_pointer.PTR();
    dequeue_pointer_a = static_cast<uint32_t>(ptr);
    dequeue_pointer_b = static_cast<uint32_t>(ptr >> 32);
    set_EP_TYPE(type);
    set_DCS(static_cast<bool>(dequeue_pointer.RCS()));
    set_MAX_PACKET_SIZE(max_packet_size);
    set_AVG_TRB_LENGTH(avg_trb_length);
    set_CErr(3);
  }
  void Deinit() {
    a = 0;
    b = 0;
    dequeue_pointer_a = 0;
    dequeue_pointer_b = 0;
    c = 0;
  }
};

}  // namespace usb_xhci

#endif  // SRC_DEVICES_USB_DRIVERS_XHCI_REWRITE_REGISTERS_H_
