// SPDX-FileCopyrightText: CHERIoT contributors
// SPDX-License-Identifier: Apache-2.0

#pragma once
#include <cdefs.h>
#include <stdint.h>
#include <utils.hh>

/**
 * A driver for OpenTitan USB Device, which is used in the Sonata system.
 *
 * This peripheral's source and documentation can be found at:
 * https://github.com/lowRISC/opentitan/tree/ab878b5d3578939a04db72d4ed966a56a869b2ed/hw/ip/usbdev
 *
 * With rendered register documentation served at:
 * https://opentitan.org/book/hw/ip/usbdev/doc/registers.html
 *
 * An incredibly brief overview of how the USB device and it's buffers:
 * Data packet ingress and egress goes via a pool of 64 byte buffers living
 * in a 2kB SRAM packet buffer, which is accessable as a large MMIO region.
 * The software manages these buffers using buffer IDs as references.
 * IDs are pushed or popped into different FIFOs by either the software or
 * device depending on whether they contain a packet to be sent, are available
 * for a packet to be received into them, or contain a packet that has been
 * received.
 *
 * See https://opentitan.org/book/hw/ip/usbdev/doc/programmers_guide.html for
 * more information.
 */
class OpenTitanUsbdev : private utils::NoCopyNoMove
{
	public:
	/// Supported sizes for the USB Device.
	static constexpr uint8_t MaxPacketLength = 64u;
	static constexpr uint8_t BufferCount     = 32u;
	static constexpr uint8_t MaxEndpoints    = 12u;

	/**
	 * The offset from the start of the USB Device MMIO region at which
	 * packet buffer memory begins.
	 */
	static constexpr uint32_t BufferStartAddress = 0x800u;

	/// Device Registers
	uint32_t interruptState;
	uint32_t interruptEnable;
	uint32_t interruptTest;
	uint32_t alertTest;
	uint32_t usbControl;
	uint32_t endpointOutEnable;
	uint32_t endpointInEnable;
	uint32_t usbStatus;
	uint32_t availableOutBuffer;
	uint32_t availableSetupBuffer;
	uint32_t receiveBuffer;
	/// Register to enable receive SETUP transactions
	uint32_t receiveEnableSetup;
	/// Register to enable receive OUT transactions
	uint32_t receiveEnableOut;
	/// Register to set NAK (Not/Negated Acknowledge) after OUT transactions
	uint32_t setNotAcknowledgeOut;
	/// Register showing ACK receival to indicate a successful IN send
	uint32_t inSent;
	/// Registers for controlling the stalling of OUT and IN endpoints
	uint32_t outStall;
	uint32_t inStall;
	/**
	 * IN transaction configuration registers. There is one register per
	 * endpoint for the USB device.
	 */
	uint32_t configIn[MaxEndpoints];
	/**
	 * Registers for configuring which endpoints should be treated as
	 * isochronous endpoints. This means that if the corresponding bit is set,
	 * then that no handshake packet will be sent for an OUT/IN transaction on
	 * that endpoint.
	 */
	uint32_t outIsochronous;
	uint32_t inIsochronous;
	/// Registers for configuring if endpoints data toggle on transactions
	uint32_t outDataToggle;
	uint32_t inDataToggle;

	private:
	/**
	 * Registers to sense/drive the USB PHY pins. That is, these registers can
	 * be used to respectively read out the state of the USB device inputs and
	 * outputs, or to control the inputs and outputs from software. These
	 * registers are kept private as they are intended to be used for debugging
	 * purposes or during chip testing, and not in actual software.
	 */
	[[maybe_unused]] uint32_t phyPinsSense;
	[[maybe_unused]] uint32_t phyPinsDrive;

	public:
	/// Config register for the USB PHY pins.
	uint32_t phyConfig;

	/// Interrupt definitions for OpenTitan's USB Device.
	enum class UsbdevInterrupt : uint32_t
	{
		/// Interrupt asserted whilst the receive FIFO (buffer) is not empty.
		PacketReceived = 1u << 0,
		/**
		 * Interrupt asserted when a packet was sent as part of an IN
		 * transaction, but not cleared from the `inSent` register.
		 */
		PacketSent = 1u << 1,
		/**
		 * Interrupt raised when VBUS (power supply) is lost, i.e. the link to
		 * the USB host controller has been disconnected.
		 */
		Disconnected = 1u << 2,
		/**
		 * Interrupt raised when the link is active, but a Start of Frame (SOF)
		 * packet has not been received within a given timeout threshold, which
		 * is set to 4.096 milliseconds.
		 */
		HostLost = 1u << 3,
		/**
		 * Interrupt raised when a Bus Reset condition is indicated on the link
		 * by the link being held in an SE0 state (Single Ended Zero, both lines
		 * being pulled low) for longer than 3 microseconds.
		 */
		LinkReset = 1u << 4,
		/**
		 * Interrupt raised when the link has entered the suspend state, due to
		 * being idle for more than 3 milliseconds.
		 */
		LinkSuspend = 1u << 5,
		///  Interrupt raised on link transition from suspended to non-idle.
		LinkResume = 1u << 6,
		/// Interrupt asserted whilst the Available OUT buffer is empty.
		AvailableOutEmpty = 1u << 7,
		///  Interrupt asserted whilst the Receive buffer is full.
		ReceiveFull = 1u << 8,
		/**
		 * Interrupt raised when the Available OUT buffer or the Available SETUP
		 * buffer overflows.
		 */
		AvailableBufferOverflow = 1u << 9,
		///  Interrupt raised when an error occurs during an IN transaction.
		LinkInError = 1u << 10,
		/**
		 * Interrupt raised when a CRC (cyclic redundancy check) error occurs on
		 * a received packet; i.e. there was an error in transmission.
		 */
		RedundancyCheckError = 1u << 11,
		///  Interrupt raised when an invalid Packet Identifier is received.
		PacketIdentifierError = 1u << 12,
		///  Interrupt raised when a bit stuffing violation is detected.
		BitstuffingError = 1u << 13,
		/**
		 * Interrupt raised when the USB frame number is updated with a valid
		 * SOF (Start of Frame) packet.
		 */
		FrameUpdated = 1u << 14,
		///  Interrupt raised when VBUS (power supply) is detected.
		Powered = 1u << 15,
		///  Interrupt raised when an error occurs during an OUT transaction.
		LinkOutError = 1u << 16,
		///  Interrupt asserted whilst the Available SETUP buffer is empty.
		AvailableSetupEmpty = 1u << 17,
	};

	/**
	 * Definitions of fields (and their locations) for the USB Control register
	 * (offset 0x10).
	 *
	 * https://opentitan.org/book/hw/ip/usbdev/doc/registers.html#usbctrl
	 */
	enum class UsbControlField : uint32_t
	{
		Enable           = 1u << 0,
		ResumeLinkActive = 1u << 1,
		DeviceAddress    = 0x7Fu << 16,
	};

	/**
	 * Definitions of fields (and their locations) for the USB Status register
	 * (offset 0x1c).
	 *
	 * https://opentitan.org/book/hw/ip/usbdev/doc/registers.html#usbstat
	 */
	enum class UsbStatusField : uint32_t
	{
		Frame               = 0x7FFu << 0,
		HostLost            = 1u << 11,
		LinkState           = 0x7u << 12,
		Sense               = 1u << 15,
		AvailableOutDepth   = 0xFu << 16,
		AvailableSetupDepth = 0x7u << 20,
		AvailableOutFull    = 1u << 23,
		ReceiveDepth        = 0xFu << 24,
		AvailableSetupFull  = 1u << 30,
		ReceiveEmpty        = 1u << 31,
	};

	/**
	 * Definitions of fields (and their locations) for the Receive FIFO
	 * buffer register (offset 0x28).
	 *
	 * https://opentitan.org/book/hw/ip/usbdev/doc/registers.html#rxfifo
	 */
	enum class ReceiveBufferField : uint32_t
	{
		BufferId   = 0x1Fu << 0,
		Size       = 0x7Fu << 8,
		Setup      = 1u << 19,
		EndpointId = 0xFu << 20,
	};

	/**
	 * Definitions of fields (and their locations) for a Config In register
	 * (where there is one such register for each endpoint). These are
	 * the registers with offsets 0x44 up to (and not including) 0x74.
	 *
	 * https://opentitan.org/book/hw/ip/usbdev/doc/registers.html#configin
	 */
	enum class ConfigInField : uint32_t
	{
		BufferId = 0x1Fu << 0,
		Size     = 0x7Fu << 8,
		Sending  = 1u << 29,
		Pending  = 1u << 30,
		Ready    = 1u << 31,
	};

	/**
	 * Definitions of fields (and their locations) for the PHY Config
	 * Register (offset 0x8c).
	 *
	 * https://opentitan.org/book/hw/ip/usbdev/doc/registers.html#phy_config
	 */
	enum class PhyConfigField : uint32_t
	{
		UseDifferentialReceiver = 1u << 0,
		//  Other PHY Configuration fields are omitted.
	};

	/**
	 * Ensure that the Available OUT and Available SETUP buffers are kept
	 * supplied with buffers for packet reception.
	 *
	 * @param bufferBitmap A bitmap of the buffers that are not currently
	 * committed (where 1 corresponds to not in use).
	 * @returns The updated bitmap after supplying buffers.
	 */
	[[nodiscard]] uint64_t supply_buffers(uint64_t bufferBitmap) volatile
	{
		constexpr uint32_t SetupFullBit =
		  uint32_t(UsbStatusField::AvailableSetupFull);
		constexpr uint32_t OutFullBit =
		  uint32_t(UsbStatusField::AvailableOutFull);

		for (uint8_t index = 0; index < BufferCount; index++)
		{
			const uint32_t Buffer = (1u << index);
			if (!(bufferBitmap & Buffer))
			{
				continue; // Skip buffers that are not available
			}

			// If a buffer is available, and either Available SETUP or OUT are
			// not yet full, then commit that buffer and mark it as in use.
			if (usbStatus & SetupFullBit)
			{
				if (usbStatus & OutFullBit)
				{
					break; // Both are full - stop trying to supply buffers.
				}
				availableOutBuffer = index;
			}
			else
			{
				availableSetupBuffer = index;
			}
			bufferBitmap &= ~Buffer;
		}
		return bufferBitmap;
	}

	/**
	 * Enable a specified interrupt / interrupts.
	 */
	void interrupt_enable(UsbdevInterrupt interrupt) volatile
	{
		interruptEnable = interruptEnable | uint32_t(interrupt);
	}

	/**
	 * Disable a specified interrupt / interrupts.
	 */
	void interrupt_disable(UsbdevInterrupt interrupt) volatile
	{
		interruptEnable = interruptEnable & ~uint32_t(interrupt);
	}

	/**
	 * Initialise the USB device, ensuring that packet buffers are available for
	 * reception and that the PHY has been appropriately configured. Note that
	 * at this stage, endpoints have not been configured and the device has not
	 * been connected to the USB.
	 *
	 * @param bufferBitmap An out-parameter, to initialise a bitmap of the
	 * buffers that are not currently commited (1 corresponds to not in use).
	 *
	 * @returns 0 if initialisation is sucessful, and non-zero otherwise.
	 */
	[[nodiscard]] int init(uint64_t &bufferBitmap) volatile
	{
		bufferBitmap = supply_buffers((uint64_t(1u) << BufferCount) - 1u);
		phyConfig    = uint32_t(PhyConfigField::UseDifferentialReceiver);
		return 0;
	}

	/**
	 * Set up the configuration of an OUT endpoint for the USB device.
	 *
	 * @param endpointId The ID of the OUT endpoint to configure.
	 * @param enabled Whether the OUT endpoint should be enabled or not.
	 * @param setup Whether SETUP transactions should be enabled for the
	 * endpoint.
	 * @param isochronous Whether the endpoint should operate isochronously or
	 * non-isochronously.
	 *
	 * @returns 0 if configuration is successful, and non-zero otherwise.
	 */
	[[nodiscard]] int out_endpoint_configure(uint8_t endpointId,
	                                         bool    enabled,
	                                         bool    setup,
	                                         bool    isochronous) volatile
	{
		if (endpointId >= MaxEndpoints)
		{
			return -1;
		}
		const uint32_t Mask = 1u << endpointId;
		endpointOutEnable = (endpointOutEnable & ~Mask) | (enabled ? Mask : 0u);
		outIsochronous = (outIsochronous & ~Mask) | (isochronous ? Mask : 0u);
		receiveEnableSetup = (receiveEnableSetup & ~Mask) | (setup ? Mask : 0u);
		receiveEnableOut   = (receiveEnableOut & ~Mask) | (enabled ? Mask : 0u);
		return 0;
	}

	/**
	 * Set up the configuration of an IN endpoint for the USB device.
	 *
	 * @param endpointId The ID of the IN endpoint to configure
	 * @param enabled Whether the IN endpoint should be enabled or not.
	 * @param isochronous Whether the endpoint should operate isochronously or
	 * non-isochronously.
	 *
	 * @returns 0 if configuration is successful, and non-zero otherwise.
	 */
	[[nodiscard]] int in_endpoint_configure(uint8_t endpointId,
	                                        bool    enabled,
	                                        bool    isochronous) volatile
	{
		if (endpointId >= MaxEndpoints)
		{
			return -1;
		}
		const uint32_t Mask = 1u << endpointId;
		endpointInEnable = (endpointInEnable & ~Mask) | (enabled ? Mask : 0u);
		inIsochronous    = (inIsochronous & ~Mask) | (isochronous ? Mask : 0u);
		return 0;
	}

	/**
	 * Set the STALL state of a specified endpoint pair (both IN and OUT).
	 *
	 * @param endpointId The ID of the endpoint pair to modify.
	 * @param stalling Whether the endpoints are stalling or not.
	 *
	 * @returns 0 if successful, and non-zero otherwise.
	 */
	[[nodiscard]] int endpoint_stalling_set(uint8_t endpointId,
	                                        bool    stalling) volatile
	{
		if (endpointId >= MaxEndpoints)
		{
			return -1;
		}
		const uint32_t Mask = 1u << endpointId;
		outStall            = (outStall & ~Mask) | (stalling ? Mask : 0u);
		inStall             = (inStall & ~Mask) | (stalling ? Mask : 0u);
		return 0;
	}

	/**
	 * Connect the device to the USB, indicating its presence to the USB host
	 * controller. Endpoints must already have been configured at this point
	 * because traffic may be received imminently.
	 *
	 * @returns 0 if successful, and non-zero otherwise.
	 * @returns -1 if endpoint 0 isn't enabled,
	 *             suggesting the endpoints haven't been configured.
	 */
	[[nodiscard]] int connect() volatile
	{
		if (!(endpointInEnable & endpointOutEnable & 0b1))
		{
			return -1;
		}
		usbControl = usbControl | uint32_t(UsbControlField::Enable);
		return 0;
	}

	/**
	 * Disconnect the device from the USB.
	 *
	 * @returns 0 if successful, and non-zero otherwise.
	 */
	void disconnect() volatile
	{
		usbControl = usbControl & ~uint32_t(UsbControlField::Enable);
	}

	/**
	 * Check whether the USB device is connected (i.e. pullup enabled).
	 *
	 * @returns True to indicate it is connected, and false otherwise.
	 */
	[[nodiscard]] bool connected() volatile
	{
		return (usbControl & uint32_t(UsbControlField::Enable));
	}

	/**
	 * Set the device address on the USB; this address will have been supplied
	 * by the USB host controller in the standard `SET_ADDRESS` Control
	 * Transfer.
	 *
	 * @param address The device address to set on the USB.
	 *
	 * @returns 0 if successful, and non-zero otherwise.
	 */
	[[nodiscard]] int device_address_set(uint8_t address) volatile
	{
		if (address >= 0x80)
		{
			return -1; // Device addresses are only 7 bits long.
		}
		constexpr uint32_t Mask = uint32_t(UsbControlField::DeviceAddress);
		usbControl              = (usbControl & ~Mask) | (address << 16);
		return 0;
	}

	/**
	 * Check and retrieve the endpoint and buffer numbers of a
	 * recently-collected IN data packet. The caller is responsible for reusing
	 * or releasing the buffer.
	 *
	 * @param endpointId An out-parameter, to which the ID of the endpoint for
	 * a recently-collected IN data packet will be written.
	 * @param bufferId An out-parameter, to which the ID of the buffer for a
	 * recently-collected IN data packet will be written.
	 *
	 * @returns 0 if successful, and non-zero otherwise.
	 */
	[[nodiscard]] int retrieve_collected_packet(uint8_t &endpointId,
	                                            uint8_t &bufferId) volatile
	{
		constexpr uint32_t BufferIdMask = uint32_t(ConfigInField::BufferId);
		uint32_t           sent         = inSent;

		// Clear the first encountered packet sent indication.
		for (endpointId = 0; endpointId < MaxEndpoints; endpointId++)
		{
			const uint32_t EndpointBit = 1u << endpointId;
			if (sent & EndpointBit)
			{
				// Clear the `in_sent` bit for this specific endpoint, and
				// indicate which buffer has been released.
				inSent   = EndpointBit;
				bufferId = (configIn[endpointId] & BufferIdMask);
				return 0;
			}
		}

		// If no packet sent indications were found, then fail.
		return -1;
	}

	/**
	 * Present a packet on the specified IN endpoint for collection by the USB
	 * host controller.
	 *
	 * @param bufferId The buffer to use to store the packet.
	 * @param endpointId The IN endpoint used to send the packet.
	 * @param data The packet to be transmitted.
	 * @param size The size of the packet.
	 */
	void packet_send(uint8_t         bufferId,
	                 uint8_t         endpointId,
	                 const uint32_t *data,
	                 uint8_t         size) volatile
	{
		// Transmission of zero length packets is common over USB
		if (size > 0)
		{
			usbdev_transfer(buffer(bufferId), data, size, true);
		}

		constexpr uint32_t ReadyBit = uint32_t(ConfigInField::Ready);
		configIn[endpointId]        = bufferId | (size << 8);
		configIn[endpointId]        = configIn[endpointId] | ReadyBit;
	}

	/**
	 * Test for and collect the next received packet.
	 *
	 * @param bufferId An out-parameter storing the buffer ID used
	 * @param endpointId An out-parameter storing the endpoint received on.
	 * @param size An out-parameter storing the size of the received packet.
	 * @param isSetup A boolean out-parameter. True means the received packet
	 * was a SETUP packet, false means it was not.
	 * @param destination A destination buffer to read the packet's data into.
	 *
	 * @returns 0 if successful, or non-zero if not successful.
	 */
	[[nodiscard]] int packet_receive(uint8_t  &bufferId,
	                                 uint8_t  &endpointId,
	                                 uint16_t &size,
	                                 bool     &isSetup,
	                                 uint32_t *destination) volatile
	{
		if (!(usbStatus & uint32_t(UsbStatusField::ReceiveDepth)))
		{
			return -1; // No packets received
		}

		uint32_t received = receiveBuffer;

		typedef ReceiveBufferField Reg;
		endpointId = (received & uint32_t(Reg::EndpointId)) >> 20;
		size       = (received & uint32_t(Reg::Size)) >> 8;
		isSetup    = (received & uint32_t(Reg::Setup)) != 0;
		bufferId   = (received & uint32_t(Reg::BufferId)) >> 0;

		// Reception of Zero Length Packets occurs in the Status Stage of IN
		// Control Transfers.
		if (size > 0)
		{
			usbdev_transfer(destination, buffer(bufferId), size, false);
		}
		return 0;
	}

	private:
	/**
	 * Return a pointer to the given offset within the USB device register
	 * space; this is used to access the packet buffer memory.
	 *
	 * @param bufferId The buffer number to access the packet buffer memory for
	 *
	 * @returns A pointer to the buffer's memory.
	 */
	uint32_t *buffer(uint8_t bufferId) volatile
	{
		const uint32_t Offset = BufferStartAddress + bufferId * MaxPacketLength;
		const uintptr_t Address = reinterpret_cast<uintptr_t>(this) + Offset;
		return const_cast<uint32_t *>(reinterpret_cast<uint32_t *>(Address));
	}

	/**
	 * Perform a transfer to or from packet buffer memory. This function is
	 * hand-optimised to perform a faster, unrolled, word-based data transfer
	 * for efficiency.
	 *
	 * @param destination A pointer to transfer the source data to.
	 * @param source A pointer to the data to be transferred.
	 * @param size The size of the data pointed to by `source`.
	 * @param toDevice True if the transfer is to the device (e.g. when sending
	 * a packet), and False if not (e.g. when receiving a packet).
	 */
	static void usbdev_transfer(uint32_t       *destination,
	                            const uint32_t *source,
	                            uint8_t         size,
	                            bool            toDevice)
	{
		// Unroll word transfer. Each word transfer is 4 bytes, so we must round
		// to the closest multiple of (4 * words) when unrolling.
		constexpr uint8_t  UnrollFactor = 4u;
		constexpr uint32_t UnrollMask   = (UnrollFactor * 4u) - 1;

		// Round down to the previous multiple for unrolling
		const uint32_t  UnrollSize = (size & ~UnrollMask);
		const uint32_t *sourceEnd  = reinterpret_cast<uint32_t *>(
          reinterpret_cast<uintptr_t>(source) + UnrollSize);

		// This is manulally unrolled for two reasons:
		// 1. We can't do partial writes to the USB packet buffer,
		//    which memcpy will attempt and causes a BUS fault.
		// 2. In the sonata system at the time of writing,
		//    the core clock is 40MHz compared to the USB device's 48MHz.
		//    This approach was found to be significantly faster than when
		//    left to compiler to optimisation.
		//
		// Ensure the unrolling here matches `UnrollFactor`.
		while (source < sourceEnd)
		{
			destination[0] = source[0];
			destination[1] = source[1];
			destination[2] = source[2];
			destination[3] = source[3];
			destination += UnrollFactor;
			source += UnrollFactor;
		}

		// Copy the remaining whole words.
		for (size &= UnrollMask; size >= UnrollFactor; size -= UnrollFactor)
		{
			*destination++ = *source++;
		}
		if (size == 0)
		{
			return;
		}

		// Copy trailing tail bytes, as USBDEV only supports 32-bit accesses.
		if (toDevice)
		{
			// Collect final bytes into a word.
			const volatile uint8_t *trailingBytes =
			  reinterpret_cast<const volatile uint8_t *>(source);
			uint32_t partialWord = trailingBytes[0];
			if (size > 1)
			{
				partialWord |= trailingBytes[1] << 8;
			}
			if (size > 2)
			{
				partialWord |= trailingBytes[2] << 16;
			}
			// Write the final word to the device.
			*destination = partialWord;
		}
		else
		{
			volatile uint8_t *destinationBytes =
			  reinterpret_cast<volatile uint8_t *>(destination);
			// Collect the final word from the device.
			const uint32_t TrailingBytes = *source;
			// Unpack it into final bytes.
			destinationBytes[0] = static_cast<uint8_t>(TrailingBytes);
			if (size > 1)
			{
				destinationBytes[1] = static_cast<uint8_t>(TrailingBytes >> 8);
			}
			if (size > 2)
			{
				destinationBytes[2] = static_cast<uint8_t>(TrailingBytes >> 16);
			}
		}
	}
};
