blob: f9a6cdfd00518af362218cdbc3618eeae0b464a8 [file] [log] [blame]
// Copyright 2016 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_BOARD_DRIVERS_X86_INCLUDE_PCI_H_
#define SRC_DEVICES_BOARD_DRIVERS_X86_INCLUDE_PCI_H_
#include <fuchsia/hardware/pciroot/c/banjo.h>
#include <lib/pci/pciroot.h>
#include <lib/zx/resource.h>
#include <zircon/compiler.h>
#include <zircon/syscalls/pci.h>
#include <unordered_map>
#include <acpica/acpi.h>
#include <acpica/actypes.h>
#include <ddk/device.h>
#include "acpi-private.h"
__BEGIN_CDECLS
// It would be nice to use the hwreg library here, but these structs should be kept
// simple so that it can be passed across process boundaries.
#define MB(n) (1024UL * 1024UL * (n))
#define PCI_BUS_MAX 255
// Base Address Allocation Structure, defined in PCI firmware spec v3.2 chapter 4.1.2
struct pci_ecam_baas {
uint64_t base_address;
uint16_t segment_group;
uint8_t start_bus_num;
uint8_t end_bus_num;
uint32_t reserved0;
};
// A structure derived from ACPI _PRTs that represents a zx::interrupt to create and
// provide to the PCI bus driver.
struct acpi_legacy_irq {
uint32_t vector; // Hardware vector
uint32_t options; // Configuration for zx_interrupt_create
};
zx_status_t pci_init(zx_device_t* sys_root, zx_device_t* parent, ACPI_HANDLE object,
ACPI_DEVICE_INFO* info);
zx_status_t get_pci_init_arg(zx_pci_init_arg_t** arg, uint32_t* size);
zx_status_t pci_report_current_resources(zx_handle_t root_resource_handle);
class x64Pciroot : public PcirootBase {
public:
struct Context {
char name[ACPI_NAMESEG_SIZE];
ACPI_HANDLE acpi_object;
ACPI_DEVICE_INFO acpi_device_info;
zx_device_t* platform_bus;
std::unordered_map<uint32_t, acpi_legacy_irq> irqs;
std::vector<zx::resource> irq_resources;
std::vector<pci_irq_routing_entry_t> routing;
struct pci_platform_info info;
};
static zx_status_t Create(PciRootHost* root_host, x64Pciroot::Context ctx, zx_device_t* parent,
const char* name);
zx_status_t PcirootConnectSysmem(zx::channel connection) final;
zx_status_t PcirootGetBti(uint32_t bdf, uint32_t index, zx::bti* bti) final;
zx_status_t PcirootGetPciPlatformInfo(pci_platform_info_t* info) final;
zx_status_t PcirootConfigRead8(const pci_bdf_t* address, uint16_t offset, uint8_t* value) final;
zx_status_t PcirootConfigRead16(const pci_bdf_t* address, uint16_t offset, uint16_t* value) final;
zx_status_t PcirootConfigRead32(const pci_bdf_t* address, uint16_t offset, uint32_t* value) final;
zx_status_t PcirootConfigWrite8(const pci_bdf_t* address, uint16_t offset, uint8_t value) final;
zx_status_t PcirootConfigWrite16(const pci_bdf_t* address, uint16_t offset, uint16_t value) final;
zx_status_t PcirootConfigWrite32(const pci_bdf_t* address, uint16_t offset, uint32_t value) final;
private:
Context context_;
x64Pciroot(PciRootHost* root_host, x64Pciroot::Context ctx, zx_device_t* parent, const char* name)
: PcirootBase(root_host, parent, name), context_(std::move(ctx)) {}
};
namespace acpi {
ACPI_STATUS GetPciRootIrqRouting(ACPI_HANDLE root_obj, x64Pciroot::Context* context);
} // namespace acpi
__END_CDECLS
#endif // SRC_DEVICES_BOARD_DRIVERS_X86_INCLUDE_PCI_H_