// SPDX-License-Identifier: GPL-2.0

//! PCI memory-mapped I/O infrastructure.

use super::Device;
use crate::{
    bindings,
    device,
    devres::DevresLt,
    io::{
        IoBackend,
        IoBase,
        IoCapable,
        Mmio,
        MmioBackend,
        MmioRaw,
        Region, //
    },
    prelude::*,
    ptr::KnownSize,
    types::{
        CovariantForLt,
        ForLt, //
    }, //
};

/// Represents the size of a PCI configuration space.
///
/// PCI devices can have either a *normal* (legacy) configuration space of 256 bytes,
/// or an *extended* configuration space of 4096 bytes as defined in the PCI Express
/// specification.
#[repr(usize)]
#[derive(Eq, PartialEq)]
pub enum ConfigSpaceSize {
    /// 256-byte legacy PCI configuration space.
    Normal = 256,

    /// 4096-byte PCIe extended configuration space.
    Extended = 4096,
}

impl ConfigSpaceSize {
    /// Get the raw value of this enum.
    #[inline(always)]
    pub const fn into_raw(self) -> usize {
        // CAST: PCI configuration space size is at most 4096 bytes, so the value always fits
        // within `usize` without truncation or sign change.
        self as usize
    }
}

/// Alias for normal (256-byte) PCI configuration space.
pub type Normal = Region<256>;

/// Alias for extended (4096-byte) PCIe configuration space.
pub type Extended = Region<4096>;

/// A view of PCI configuration space of a device.
///
/// Provides typed read and write accessors for configuration registers
/// using the standard `pci_read_config_*` and `pci_write_config_*` helpers.
///
/// The generic parameter `T` is the type of the view. The full configuration space is also a
/// special type of view; in such cases, `T` can be [`Normal`] for 256-byte legacy configuration
/// space or [`Extended`] for 4096-byte PCIe extended configuration space (default).
///
/// # Invariants
///
/// `ptr` is aligned and range `ptr..ptr + KnownSize::size(ptr)` is within
/// `0..pdev.cfg_size().into_raw()`.
pub struct ConfigSpace<'a, T: ?Sized = Extended> {
    pub(crate) pdev: &'a Device<device::Bound>,
    ptr: *mut T,
}

impl<T: ?Sized> Copy for ConfigSpace<'_, T> {}
impl<T: ?Sized> Clone for ConfigSpace<'_, T> {
    #[inline]
    fn clone(&self) -> Self {
        *self
    }
}

// SAFETY: `ConfigSpace<'_, T>` is conceptually `&T` but in I/O memory.
unsafe impl<T: ?Sized + Sync> Send for ConfigSpace<'_, T> {}

// SAFETY: `ConfigSpace<'_, T>` is conceptually `&T` but in I/O memory.
unsafe impl<T: ?Sized + Sync> Sync for ConfigSpace<'_, T> {}

/// I/O Backend for PCI configuration space.
pub struct ConfigSpaceBackend;

impl IoBackend for ConfigSpaceBackend {
    type View<'a, T: ?Sized + KnownSize> = ConfigSpace<'a, T>;

    #[inline]
    fn as_ptr<'a, T: ?Sized + KnownSize>(view: ConfigSpace<'a, T>) -> *mut T {
        view.ptr
    }

    #[inline]
    unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
        view: Self::View<'a, T>,
        ptr: *mut U,
    ) -> Self::View<'a, U> {
        // INVARIANT: Per safety requirement.
        ConfigSpace {
            pdev: view.pdev,
            ptr,
        }
    }
}

/// Implements [`IoCapable`] on [`ConfigSpace`] for `$ty` using `$read_fn` and `$write_fn`.
macro_rules! impl_config_space_io_capable {
    ($ty:ty, $read_fn:ident, $write_fn:ident) => {
        impl IoCapable<$ty> for ConfigSpaceBackend {
            fn io_read(view: ConfigSpace<'_, $ty>) -> $ty {
                // CAST: The offset is cast to `i32` because the C functions expect a 32-bit
                // signed offset parameter. PCI configuration space size is at most 4096 bytes,
                // so the value always fits within `i32` without truncation or sign change.
                let addr = view.ptr.addr() as i32;

                let mut val: $ty = 0;

                // Return value from C function is ignored in infallible accessors.
                // SAFETY: By the type invariant `pdev` is a valid address.
                let _ = unsafe { bindings::$read_fn(view.pdev.as_raw(), addr, &mut val) };
                val
            }

            fn io_write(view: ConfigSpace<'_, $ty>, value: $ty) {
                // CAST: The offset is cast to `i32` because the C functions expect a 32-bit
                // signed offset parameter. PCI configuration space size is at most 4096 bytes,
                // so the value always fits within `i32` without truncation or sign change.
                let addr = view.ptr.addr() as i32;

                // Return value from C function is ignored in infallible accessors.
                // SAFETY: By the type invariant `pdev` is a valid address.
                let _ = unsafe { bindings::$write_fn(view.pdev.as_raw(), addr, value) };
            }
        }
    };
}

// PCI configuration space supports 8, 16, and 32-bit accesses.
impl_config_space_io_capable!(u8, pci_read_config_byte, pci_write_config_byte);
impl_config_space_io_capable!(u16, pci_read_config_word, pci_write_config_word);
impl_config_space_io_capable!(u32, pci_read_config_dword, pci_write_config_dword);

impl<'a, T: ?Sized + KnownSize> IoBase<'a> for ConfigSpace<'a, T> {
    type Backend = ConfigSpaceBackend;
    type Target = T;

    #[inline]
    fn as_view(self) -> ConfigSpace<'a, T> {
        self
    }
}

/// A PCI BAR to perform I/O-Operations on.
///
/// I/O backend assumes that the device is little-endian and will automatically
/// convert from little-endian to CPU endianness.
///
/// # Invariants
///
/// `Bar` always holds an `IoRaw` instance that holds a valid pointer to the start of the I/O
/// memory mapped PCI BAR and its size.
pub struct Bar<'a, const SIZE: usize = 0> {
    pdev: &'a Device<device::Bound>,
    io: MmioRaw<crate::io::Region<SIZE>>,
    num: i32,
}

impl<const SIZE: usize> ForLt for Bar<'static, SIZE> {
    type Of<'a> = Bar<'a, SIZE>;
}

// SAFETY: `Bar<'a, SIZE>` is covariant over `'a`; it holds `&'a Device<Bound>`,
// which is covariant.
unsafe impl<const SIZE: usize> CovariantForLt for Bar<'static, SIZE> {}

/// A device-managed PCI BAR mapping.
///
/// See [`Bar::into_devres`].
pub type DevresBar<const SIZE: usize = 0> = DevresLt<Bar<'static, SIZE>>;

impl<'a, const SIZE: usize> Bar<'a, SIZE> {
    pub(super) fn new(
        pdev: &'a Device<device::Bound>,
        num: u32,
        name: &'static CStr,
    ) -> Result<Self> {
        let len = pdev.resource_len(num)?;
        if len == 0 {
            return Err(ENOMEM);
        }

        // Convert to `i32`, since that's what all the C bindings use.
        let num = i32::try_from(num)?;

        // SAFETY:
        // `pdev` is valid by the invariants of `Device`.
        // `num` is checked for validity by a previous call to `Device::resource_len`.
        // `name` is always valid.
        let ret = unsafe { bindings::pci_request_region(pdev.as_raw(), num, name.as_char_ptr()) };
        if ret != 0 {
            return Err(EBUSY);
        }

        // SAFETY:
        // `pdev` is valid by the invariants of `Device`.
        // `num` is checked for validity by a previous call to `Device::resource_len`.
        // `name` is always valid.
        let ioptr: usize = unsafe { bindings::pci_iomap(pdev.as_raw(), num, 0) } as usize;
        if ioptr == 0 {
            // SAFETY:
            // `pdev` is valid by the invariants of `Device`.
            // `num` is checked for validity by a previous call to `Device::resource_len`.
            unsafe { bindings::pci_release_region(pdev.as_raw(), num) };
            return Err(ENOMEM);
        }

        let io = match MmioRaw::new_region(ioptr, len as usize) {
            Ok(io) => io,
            Err(err) => {
                // SAFETY:
                // `pdev` is valid by the invariants of `Device`.
                // `ioptr` is guaranteed to be the start of a valid I/O mapped memory region.
                // `num` is checked for validity by a previous call to `Device::resource_len`.
                unsafe { Self::do_release(pdev, ioptr, num) };
                return Err(err);
            }
        };

        Ok(Bar { pdev, io, num })
    }

    /// # Safety
    ///
    /// `ioptr` must be a valid pointer to the memory mapped PCI BAR number `num`.
    unsafe fn do_release(pdev: &Device, ioptr: usize, num: i32) {
        // SAFETY:
        // `pdev` is valid by the invariants of `Device`.
        // `ioptr` is valid by the safety requirements.
        // `num` is valid by the safety requirements.
        unsafe {
            bindings::pci_iounmap(pdev.as_raw(), ioptr as *mut c_void);
            bindings::pci_release_region(pdev.as_raw(), num);
        }
    }

    fn release(&self) {
        // SAFETY: The safety requirements are guaranteed by the type invariant of `self.pdev`.
        unsafe { Self::do_release(self.pdev, self.io.addr(), self.num) };
    }

    /// Consume the `Bar` and register it as a device-managed resource.
    ///
    /// The returned [`DevresBar`] can outlive the original borrow and be stored in driver data.
    /// Access to the BAR is revoked automatically when the device is unbound.
    pub fn into_devres(self) -> Result<DevresBar<SIZE>> {
        let pdev = self.pdev;
        // SAFETY: `Bar` only holds a reference to the device and an I/O mapping, both of which
        // remain valid for the device's full bound scope, not just for `'a`.
        unsafe { DevresLt::new(pdev.as_ref(), self) }
    }
}

impl Bar<'_> {
    #[inline]
    pub(super) fn index_is_valid(index: u32) -> bool {
        // A `struct pci_dev` owns an array of resources with at most `PCI_NUM_RESOURCES` entries.
        index < bindings::PCI_NUM_RESOURCES
    }
}

impl<const SIZE: usize> Drop for Bar<'_, SIZE> {
    fn drop(&mut self) {
        self.release();
    }
}

impl<'a, const SIZE: usize> IoBase<'a> for &'a Bar<'_, SIZE> {
    type Backend = MmioBackend;
    type Target = crate::io::Region<SIZE>;

    #[inline]
    fn as_view(self) -> Mmio<'a, Self::Target> {
        // SAFETY: By the type invariant of `Self`, the MMIO range in `self.io` is properly mapped.
        unsafe { Mmio::from_raw(self.io) }
    }
}

impl Device<device::Bound> {
    /// Maps an entire PCI BAR after performing a region-request on it. I/O operation bound checks
    /// can be performed on compile time for offsets (plus the requested type size) < SIZE.
    pub fn iomap_region_sized<'a, const SIZE: usize>(
        &'a self,
        bar: u32,
        name: &'static CStr,
    ) -> Result<Bar<'a, SIZE>> {
        Bar::new(self, bar, name)
    }

    /// Maps an entire PCI BAR after performing a region-request on it.
    pub fn iomap_region<'a>(&'a self, bar: u32, name: &'static CStr) -> Result<Bar<'a>> {
        self.iomap_region_sized::<0>(bar, name)
    }

    /// Returns the size of configuration space.
    pub fn cfg_size(&self) -> ConfigSpaceSize {
        // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
        let size = unsafe { (*self.as_raw()).cfg_size };
        match size {
            256 => ConfigSpaceSize::Normal,
            4096 => ConfigSpaceSize::Extended,
            _ => {
                // PANIC: The PCI subsystem only ever reports the configuration space size as either
                // `ConfigSpaceSize::Normal` or `ConfigSpaceSize::Extended`.
                unreachable!();
            }
        }
    }

    /// Return a view of the normal (256-byte) config space.
    pub fn config_space<'a>(&'a self) -> ConfigSpace<'a, Normal> {
        // INVARIANT: null is aligned and the range is within config space.
        ConfigSpace {
            pdev: self,
            ptr: Normal::ptr_from_raw_parts_mut(core::ptr::null_mut(), self.cfg_size().into_raw()),
        }
    }

    /// Return a view of the extended (4096-byte) config space.
    pub fn config_space_extended<'a>(&'a self) -> Result<ConfigSpace<'a, Extended>> {
        if self.cfg_size() != ConfigSpaceSize::Extended {
            return Err(EINVAL);
        }

        // INVARIANT: null is aligned and we just checked the `cfg_size`.
        Ok(ConfigSpace {
            pdev: self,
            ptr: Extended::ptr_from_raw_parts_mut(core::ptr::null_mut(), 4096),
        })
    }
}
