// 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_REGISTERS_H_
#define SRC_DEVICES_USB_DRIVERS_XHCI_REGISTERS_H_

#include <lib/ddk/hw/arch_ops.h>
#include <zircon/types.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.

constexpr static uint16_t kPrimaryInterrupter = 0;
constexpr static uint32_t k64KiB = (1u << 16);
constexpr static uint32_t kOSOwned = (1u << 24);
constexpr static uint32_t kBiosOwned = (1u << 16);

// 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::ResetEndpointCommand).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); }
};

// 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); }
};

// Section 6.4.3.9
struct SetTRDequeuePointer : TRB {
  DEF_SUBBIT(ptr, 0, DCS);
  DEF_SUBFIELD(ptr, 3, 1, SCT);
  DEF_SUBFIELD(control, 31, 24, SLOT);
  DEF_SUBFIELD(control, 20, 16, ENDPOINT);
  void SetPtr(CRCR cr) {
    ptr = cr.PTR();
    set_DCS(cr.RCS());
  }
  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);
  // SIZE can at max be 31 and anything above it must be set to 31.
  // See section 4.11.2.4
  constexpr auto& set_SIZE(size_t size) {
    ZX_ASSERT_MSG(size <= UINT32_MAX, "size: %lu", size);
    uint32_t size_u32 = static_cast<uint32_t>(size);
    set_SIZE(size_u32 > 31 ? 31u : size_u32);
    return *this;
  }
  // 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);
  constexpr auto& set_LENGTH(size_t len) {
    ZX_ASSERT_MSG(len <= k64KiB, "len: %lu", len);
    set_LENGTH(static_cast<uint32_t>(len));
    return *this;
  }
  // 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);
  // SIZE can at max be 31 and anything above it must be set to 31.
  // See section 4.11.2.4
  constexpr auto& set_SIZE(size_t size) {
    ZX_ASSERT_MSG(size <= UINT32_MAX, "size: %lu", size);
    uint32_t size_u32 = static_cast<uint32_t>(size);
    set_SIZE(size_u32 > 31 ? 31u : size_u32);
    return *this;
  }
  DEF_SUBFIELD(status, 16, 0, LENGTH);
  constexpr auto& set_LENGTH(size_t len) {
    ZX_ASSERT_MSG(len <= k64KiB, "len: %lu", len);
    set_LENGTH(static_cast<uint32_t>(len));
    return *this;
  }
  // 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);
  // SIZE can at max be 31 and anything above it must be set to 31.
  // See section 4.11.2.4
  constexpr auto& set_SIZE(size_t size) {
    ZX_ASSERT_MSG(size <= UINT32_MAX, "size: %lu", size);
    uint32_t size_u32 = static_cast<uint32_t>(size);
    set_SIZE(size_u32 > 31 ? 31u : size_u32);
    return *this;
  }
  DEF_SUBFIELD(status, 16, 0, LENGTH);
  constexpr auto& set_LENGTH(size_t len) {
    ZX_ASSERT_MSG(len <= k64KiB, "len: %lu", len);
    set_LENGTH(static_cast<uint32_t>(len));
    return *this;
  }
  // 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);
  DEF_FIELD(3, 0, IST);  // Isochronous Scheduling Threshold
  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 CapabilityRegWord0 : public hwreg::RegisterBase<CapabilityRegWord0, uint32_t> {
 public:
  DEF_FIELD(31, 24, MAJOR_REVISION);
  DEF_FIELD(23, 16, MINOR_REVISION);
  static auto Get(XECP xecp) { return hwreg::RegisterAddr<CapabilityRegWord0>(xecp.reg_addr()); }
};

class CapabilityRegWord2 : public hwreg::RegisterBase<CapabilityRegWord2, uint32_t> {
 public:
  DEF_FIELD(31, 28, PSIC);
  DEF_FIELD(27, 16, Reserved);
  DEF_FIELD(15, 8, PortCount);
  DEF_FIELD(7, 0, PortOffset);
  static auto Get(XECP xecp) {
    return hwreg::RegisterAddr<CapabilityRegWord2>(xecp.reg_addr() + (2 * sizeof(uint32_t)));
  }
};

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);
  }
};

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());
  }
};

// Interrupter registers

// Section 5.5.2.3.1
// Event Ring Segment Table Size
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
// Event Ring Segment Table Base Address
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
// Event Ring Dequeue Pointer
// 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
// Interrupter management
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
// Interrupter Moderation
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);
  DEF_SUBFIELD(c, 31, 22, INTERRUPTER_TARGET);
};

// 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);
  // According to Section 4.8.2, CErr shall always be set to 3 or 0 for Isochronous endpoints.
  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((type == EndpointType::IsochIn || type == EndpointType::IsochOut) ? 0 : 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_REGISTERS_H_
