// SPDX-License-Identifier: GPL-2.0

//! Rust PCI driver sample (based on QEMU's `pci-testdev`).
//!
//! To make this driver probe, QEMU must be run with `-device pci-testdev`.

use kernel::{
    device::{
        Bound,
        Core, //
    },
    io::{
        register,
        register::Array,
        Io, //
    },
    num::Bounded,
    pci,
    prelude::*, //
};

mod regs {
    use super::*;

    register! {
        pub(super) TEST(u8) @ 0x0 {
            7:0 index => TestIndex;
        }

        pub(super) OFFSET(u32) @ 0x4 {
            31:0 offset;
        }

        pub(super) DATA(u8) @ 0x8 {
            7:0 data;
        }

        pub(super) COUNT(u32) @ 0xC {
            31:0 count;
        }
    }

    pub(super) const END: usize = 0x10;
}

type Bar0<'bound> = pci::Bar<'bound, { regs::END }>;

#[derive(Copy, Clone, Debug)]
struct TestIndex(u8);

impl From<Bounded<u8, 8>> for TestIndex {
    fn from(value: Bounded<u8, 8>) -> Self {
        Self(value.into())
    }
}

impl From<TestIndex> for Bounded<u8, 8> {
    fn from(value: TestIndex) -> Self {
        value.0.into()
    }
}

impl TestIndex {
    const NO_EVENTFD: Self = Self(0);
}

struct SampleDriverData<'bound> {
    pdev: &'bound pci::Device,
    bar: Bar0<'bound>,
    index: TestIndex,
}

struct SampleDriver;

kernel::pci_device_table!(
    PCI_TABLE,
    <SampleDriver as pci::Driver>::IdInfo,
    [(
        pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5),
        TestIndex::NO_EVENTFD
    )]
);

impl SampleDriverData<'_> {
    fn testdev(index: &TestIndex, bar: &Bar0<'_>) -> Result<u32> {
        // Select the test.
        bar.write_reg(regs::TEST::zeroed().with_index(*index));

        let offset = bar.read(regs::OFFSET).into_raw() as usize;
        let data = bar.read(regs::DATA).into();

        // Write `data` to `offset` to increase `count` by one.
        //
        // Note that we need `try_write8`, since `offset` can't be checked at compile-time.
        bar.try_write8(data, offset)?;

        Ok(bar.read(regs::COUNT).into())
    }

    fn config_space(pdev: &pci::Device<Bound>) {
        let config = pdev.config_space();

        // Some PCI configuration space registers.
        register! {
            VENDOR_ID(u16) @ 0x0 {
                15:0 vendor_id;
            }

            REVISION_ID(u8) @ 0x8 {
                7:0 revision_id;
            }

            BAR(u32)[6] @ 0x10 {
                31:0 value;
            }
        }

        dev_info!(
            pdev,
            "pci-testdev config space read8 rev ID: {:x}\n",
            config.read(REVISION_ID).revision_id()
        );

        dev_info!(
            pdev,
            "pci-testdev config space read16 vendor ID: {:x}\n",
            config.read(VENDOR_ID).vendor_id()
        );

        dev_info!(
            pdev,
            "pci-testdev config space read32 BAR 0: {:x}\n",
            config.read(BAR::at(0)).value()
        );
    }
}

impl pci::Driver for SampleDriver {
    type IdInfo = TestIndex;
    type Data<'bound> = SampleDriverData<'bound>;

    const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;

    fn probe<'bound>(
        pdev: &'bound pci::Device<Core<'_>>,
        info: Option<&'bound Self::IdInfo>,
    ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
        let vendor = pdev.vendor_id();
        dev_dbg!(
            pdev,
            "Probe Rust PCI driver sample (PCI ID: {}, 0x{:x}).\n",
            vendor,
            pdev.device_id()
        );
        let info = info.ok_or(ENODEV)?;

        pdev.enable_device_mem()?;
        pdev.set_master();

        let bar = pdev.iomap_region_sized::<{ regs::END }>(0, c"rust_driver_pci")?;

        dev_info!(
            pdev,
            "pci-testdev data-match count: {}\n",
            SampleDriverData::testdev(info, &bar)?
        );
        SampleDriverData::config_space(pdev);

        Ok(SampleDriverData {
            pdev,
            bar,
            index: *info,
        })
    }

    fn unbind<'bound>(_pdev: &'bound pci::Device<Core<'_>>, this: Pin<&Self::Data<'bound>>) {
        this.bar
            .write_reg(regs::TEST::zeroed().with_index(this.index));
    }
}

impl Drop for SampleDriverData<'_> {
    fn drop(&mut self) {
        dev_dbg!(self.pdev, "Remove Rust PCI driver sample.\n");
    }
}

kernel::module_pci_driver! {
    type: SampleDriver,
    name: "rust_driver_pci",
    authors: ["Danilo Krummrich"],
    description: "Rust PCI driver",
    license: "GPL v2",
}
