/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */
#pragma once

#include <pci/helper.h>
#include <stdbool.h>
#include <inttypes.h>

// ref: http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.0.html
//      PCI System Architecture, rev 4

#define PCI_CONFIG_HEADER_SIZE_BYTES PCI_STD_HEADER_SIZEOF

/* Detailed base address information about a device. */
struct libpci_device_iocfg {
    /* PCI_BASE_ADDRESS_MEM address or
       PCI_BASE_ADDRESS_IO address */
    uint32_t base_addr[6];
    /* PCI_BASE_ADDRESS_SPACE_IO or
       PCI_BASE_ADDRESS_SPACE_MEMORY */
    uint8_t base_addr_space[6];
    /* PCI_BASE_ADDRESS_MEM_TYPE_32 or
       PCI_BASE_ADDRESS_MEM_TYPE_64 */
    uint8_t base_addr_type[6];
    /* PCI_BASE_ADDRESS_MEM_PREFETCH */
    uint8_t base_addr_prefetchable[6];
    /* size */
    uint32_t base_addr_size_mask[6];
    uint32_t base_addr_size[6];
    /* raw addr */
    uint32_t base_addr_raw[6];
    /* Is this BAR the higher word of a 64-bit address? If true, then this BAR is partial
       and should not be directly processed in any way. */
    bool base_addr_64H[6];
};

typedef struct libpci_device_iocfg libpci_device_iocfg_t;

/* Get the size of a PCI config space element. */
static inline int libpci_device_cfg_sizeof(int offset) {
    switch (offset) {
        case PCI_VENDOR_ID: return 2;
        case PCI_DEVICE_ID: return 2;

        case PCI_COMMAND: return 2;
        case PCI_STATUS: return 2;

        case PCI_CLASS_REVISION: return 1;
        case PCI_CLASS_PROG: return 1;
        case PCI_CLASS_DEVICE: return 2;

        case PCI_CACHE_LINE_SIZE: return 1;
        case PCI_LATENCY_TIMER: return 1;
        case PCI_HEADER_TYPE: return 1;
        case PCI_BIST: return 1;

        case PCI_BASE_ADDRESS_0:
        case PCI_BASE_ADDRESS_1:
        case PCI_BASE_ADDRESS_2:
        case PCI_BASE_ADDRESS_3:
        case PCI_BASE_ADDRESS_4:
        case PCI_BASE_ADDRESS_5:
            return 4;

        case PCI_CARDBUS_CIS: return 4;
        case PCI_SUBSYSTEM_VENDOR_ID: return 2;
        case PCI_SUBSYSTEM_ID: return 2;
        case PCI_ROM_ADDRESS: return 4;

        case PCI_INTERRUPT_LINE: return 1;
        case PCI_INTERRUPT_PIN: return 1;
        case PCI_MIN_GNT: return 1;
        case PCI_MAX_LAT: return 1;
    }
    return 0;
}

/* Get the base address at a given index. Will automatically handle split 64-bit addreses. */
static inline uint64_t libpci_device_iocfg_get_baseaddr(libpci_device_iocfg_t *cfg, int index) {
    assert(cfg && index >= 0 && index < 6);
    if (cfg->base_addr_type[index] != PCI_BASE_ADDRESS_MEM_TYPE_64)
           return (uint64_t) cfg->base_addr[index];
    /* 64-bit mode BARs must have a word after it. */
    assert(index < 5);
    /* And the word before it better be set to 64L mode. */
    assert(cfg->base_addr_64H[index + 1]);
    return ((uint64_t) cfg->base_addr[index]) | (((uint64_t) cfg->base_addr[index + 1]) << 32);
}

/* Get the 32-bit base address at given index. Will automatically handle split 64-bit addresses,
 * and cast them (with an assert check that the upper 32-bits are zero). */
static inline uint32_t libpci_device_iocfg_get_baseaddr32(libpci_device_iocfg_t *cfg, int index) {
    uint64_t baddr = libpci_device_iocfg_get_baseaddr(cfg, index);
    assert((baddr & 0xFFFFFFFFUL) == baddr);
    if ((baddr & 0xFFFFFFFFUL) != baddr) {
        printf("WARNING: get_baseaddr32 called for 64-bit address. Address will be truncated.\n");
        printf("         This will most likely lead to problems.\n");
        assert(!"WARNING. Zap this assert to ignore.");
    }
    return (uint32_t)(baddr & 0xFFFFFFFFUL);
}

/* Returns true if the given device has at least one IO port base addr associated,
 * false otherwise. */
static inline bool libpci_device_iocfg_uses_iomem(libpci_device_iocfg_t *cfg) {
   assert(cfg);
   for (int i = 0; i < 6; i++) {
        if (cfg->base_addr[i] == 0 || cfg->base_addr_64H[i]) continue;
        return true;
   }
   return false;
}

/* Print out detailed info about a device's base addresses. */
static inline void libpci_device_iocfg_debug_print(libpci_device_iocfg_t *cfg, bool compact) {
    for(int i = 0; i < 6; i++) {
        if (compact) {
            /* Display in compact space mode, shoving as much information as possible in a few
             * lines. This is similar to how the Linux kernel PCI debug displays in dmesg. */
            if (cfg->base_addr[i] == 0 || cfg->base_addr_64H[i]) continue;
            if (cfg->base_addr_space[i] == PCI_BASE_ADDRESS_SPACE_IO) {
                printf("    BAR%d : [ io 0x%"PRIx64" sz 0x%x szmask 0x%x ]\n", i,
                       libpci_device_iocfg_get_baseaddr(cfg, i),
                       cfg->base_addr_size[i],
                       cfg->base_addr_size_mask[i]);
            } else {
                printf("    BAR%d : [ mem 0x%"PRIx64" sz 0x%x szmask 0x%x %s %s ]\n", i,
                       libpci_device_iocfg_get_baseaddr(cfg, i),
                       cfg->base_addr_size[i],
                       cfg->base_addr_size_mask[i],
                       cfg->base_addr_type[i] == PCI_BASE_ADDRESS_MEM_TYPE_64 ? "64bit" : "",
                       cfg->base_addr_prefetchable[i] ? "prefetch" : "");
            }
        } else {
            /* Very verbose and space wasting debug output. */
            printf("    BASE_ADDR[%d] ----\n", i);
            if (cfg->base_addr[i] == 0 || cfg->base_addr_64H[i]) continue;
            printf("        base_addr_space[%d]: 0x%x [%s]\n", i, cfg->base_addr_space[i],
                   cfg->base_addr_space[i] ? "PCI_BASE_ADDRESS_SPACE_IO" :
                                                 "PCI_BASE_ADDRESS_SPACE_MEMORY");
            printf("        base_addr_type[%d]: 0x%x [ ", i, cfg->base_addr_type[i]);
            if (cfg->base_addr_type[i] == PCI_BASE_ADDRESS_MEM_TYPE_32) printf("32bit ");
            if (cfg->base_addr_type[i] == PCI_BASE_ADDRESS_MEM_TYPE_64) printf("64bit ");
            if (cfg->base_addr_type[i] == PCI_BASE_ADDRESS_MEM_TYPE_1M) printf("<1M ");
            printf("]\n");
            printf("        base_addr_prefetchable[%d]: %s\n", i, cfg->base_addr_prefetchable[i]
                   ? "yes" : "no");
            printf("        base_addr[%d]: 0x%"PRIx64"\n", i, libpci_device_iocfg_get_baseaddr(cfg, i));
            printf("        base_addr_size_mask[%d]: 0x%x\n", i, cfg->base_addr_size_mask[i]);
        }
    }
}
