diff --git a/build/jam/packages/Haiku b/build/jam/packages/Haiku index 98d35e6d73..00260e84d0 100644 --- a/build/jam/packages/Haiku +++ b/build/jam/packages/Haiku @@ -30,6 +30,7 @@ AddFilesToPackage add-ons kernel busses ata AddFilesToPackage add-ons kernel busses i2c : pch_i2c@x86,x86_64 ; AddFilesToPackage add-ons kernel busses mmc : sdhci_pci ; +AddFilesToPackage add-ons kernel busses pci : x86@x86,x86_64 ; AddFilesToPackage add-ons kernel busses random : ccp_rng@x86,x86_64 virtio_rng ; AddFilesToPackage add-ons kernel busses scsi : ahci virtio_scsi ; AddFilesToPackage add-ons kernel busses usb : uhci ohci ehci @@ -197,6 +198,7 @@ AddBootModuleSymlinksToPackage nvme_disk openpic@ppc packagefs pci + x86@x86,x86_64 fdt@riscv64,arm,arm64 scsi scsi_cd scsi_disk scsi_periph silicon_image_3112 highpoint_ide_pci sdhci_pci diff --git a/headers/os/drivers/bus/PCI.h b/headers/os/drivers/bus/PCI.h index 756cb85c4b..4946b05be0 100644 --- a/headers/os/drivers/bus/PCI.h +++ b/headers/os/drivers/bus/PCI.h @@ -58,6 +58,54 @@ typedef struct pci_device_module_info { } pci_device_module_info; +enum { + kPciRangeInvalid = 0, + kPciRangeIoPort = 1, + kPciRangeMmio = 2, + kPciRangeMmio64Bit = 1 << 0, + kPciRangeMmioPrefetch = 1 << 1, + kPciRangeMmioEnd = 6, + kPciRangeEnd = 6, +}; + +typedef struct pci_resource_range { + uint32 type; + phys_addr_t host_addr; + phys_addr_t pci_addr; + uint64 size; +} pci_resource_range; + + +typedef struct pci_controller_module_info { + driver_module_info info; + + // read PCI config space + status_t (*read_pci_config)(void *cookie, + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 *value); + + // write PCI config space + status_t (*write_pci_config)(void *cookie, + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value); + + status_t (*get_max_bus_devices)(void *cookie, int32 *count); + + status_t (*read_pci_irq)(void *cookie, + uint8 bus, uint8 device, uint8 function, + uint8 pin, uint8 *irq); + + status_t (*write_pci_irq)(void *cookie, + uint8 bus, uint8 device, uint8 function, + uint8 pin, uint8 irq); + + status_t (*get_range)(void *cookie, uint32 index, pci_resource_range *range); + + status_t (*finalize)(void *cookie); + +} pci_controller_module_info; + + /* Attributes of PCI device nodes */ #define B_PCI_DEVICE_DOMAIN "pci/domain" /* uint32 */ #define B_PCI_DEVICE_BUS "pci/bus" /* uint8 */ diff --git a/src/add-ons/kernel/bus_managers/pci/Jamfile b/src/add-ons/kernel/bus_managers/pci/Jamfile index 8694903957..49738f4531 100644 --- a/src/add-ons/kernel/bus_managers/pci/Jamfile +++ b/src/add-ons/kernel/bus_managers/pci/Jamfile @@ -3,16 +3,16 @@ SubDir HAIKU_TOP src add-ons kernel bus_managers pci ; UsePrivateKernelHeaders ; UsePrivateHeaders shared ; UsePrivateHeaders [ FDirName kernel util ] ; -UseHeaders [ FDirName $(SUBDIR) arch $(TARGET_KERNEL_ARCH_DIR) ] ; KernelAddon pci : pci.cpp pci_fixup.cpp pci_info.cpp + pci_io.cpp pci_module.cpp pci_root.cpp pci_device.cpp - : pci_arch_bus_manager.a + : ; # pci_info.cpp currently needs pcihdr.h so we make its path available and adds dependency @@ -20,6 +20,3 @@ ObjectHdrs [ FGristFiles pci_info$(SUFOBJ) ] : [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR_$(TARGET_PACKAGING_ARCH)) apps devices ] ; Includes [ FGristFiles pci_info.cpp ] : pcihdr.h ; - -SubInclude HAIKU_TOP src add-ons kernel bus_managers pci arch - $(TARGET_KERNEL_ARCH_DIR) ; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/arm/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/arm/Jamfile deleted file mode 100644 index 4fcb56d642..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/arm/Jamfile +++ /dev/null @@ -1,18 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch $(TARGET_ARCH) ; - -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; - -UsePrivateKernelHeaders ; -UsePrivateHeaders [ FDirName kernel util ] ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] - [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; - -SubDirHdrs $(HAIKU_TOP) src system kernel arch generic ; - -SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; - -KernelStaticLibrary pci_arch_bus_manager : - pci_controller.cpp - pci_ecam.cpp - pci_io.cpp -; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/arm64/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/arm64/Jamfile deleted file mode 100644 index 5eb1163e5b..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/arm64/Jamfile +++ /dev/null @@ -1,18 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch $(TARGET_ARCH) ; - -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; - -UsePrivateKernelHeaders ; -UsePrivateHeaders [ FDirName kernel util ] ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] - [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; - -SubDirHdrs $(HAIKU_TOP) src system kernel arch generic ; - -SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; - -KernelStaticLibrary pci_arch_bus_manager : - pci_controller.cpp - pci_io.cpp - pci_ecam.cpp -; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_controller.cpp deleted file mode 100644 index f82fad0486..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_controller.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright 2009-2022, Haiku Inc. - * Distributed under the terms of the MIT License. - */ - - -#include "pci_controller.h" - -#include -#include -#include - -#include - -#include "pci_private.h" -#include "pci.h" - -#include // module -#include -#include - -#include "acpi_irq_routing_table.h" - - -addr_t gPCIeBase; -uint8 gStartBusNumber; -uint8 gEndBusNumber; -addr_t gPCIioBase; - -extern pci_controller pci_controller_ecam; - - -enum RangeType -{ - RANGE_IO, - RANGE_MEM -}; - - -struct PciRange -{ - RangeType type; - phys_addr_t hostAddr; - phys_addr_t pciAddr; - size_t length; -}; - - -static Vector *sRanges; - - -template -acpi_address64_attribute AcpiCopyAddressAttr(const T &src) -{ - acpi_address64_attribute dst; - - dst.granularity = src.granularity; - dst.minimum = src.minimum; - dst.maximum = src.maximum; - dst.translation_offset = src.translation_offset; - dst.address_length = src.address_length; - - return dst; -} - - -static acpi_status -AcpiCrsScanCallback(acpi_resource *res, void *context) -{ - Vector &ranges = *(Vector*)context; - - acpi_address64_attribute address; - if (res->type == ACPI_RESOURCE_TYPE_ADDRESS16) - address = AcpiCopyAddressAttr(res->data.address16.address); - else if (res->type == ACPI_RESOURCE_TYPE_ADDRESS32) - address = AcpiCopyAddressAttr(res->data.address32.address); - else if (res->type == ACPI_RESOURCE_TYPE_ADDRESS64) - address = AcpiCopyAddressAttr(res->data.address64.address); - else - return B_OK; - - acpi_resource_address &common = res->data.address; - - if (common.resource_type != 0 && common.resource_type != 1) - return B_OK; - - ASSERT(address.minimum + address.address_length - 1 == address.maximum); - - PciRange range; - range.type = (common.resource_type == 0 ? RANGE_MEM : RANGE_IO); - range.hostAddr = address.minimum + address.translation_offset; - range.pciAddr = address.minimum; - range.length = address.address_length; - ranges.PushBack(range); - - return B_OK; -} - - -static bool -is_interrupt_available(int32 gsi) -{ - return true; -} - - -status_t -pci_controller_init(void) -{ - if (gPCIRootNode == NULL) - return B_DEV_NOT_READY; - - dprintf("PCI: pci_controller_init\n"); - - DeviceNodePutter<&gDeviceManager> - parent(gDeviceManager->get_parent_node(gPCIRootNode)); - - if (parent.Get() == NULL) - return B_ERROR; - - const char *bus; - if (gDeviceManager->get_attr_string(parent.Get(), B_DEVICE_BUS, &bus, false) < B_OK) - return B_ERROR; - - if (strcmp(bus, "fdt") == 0) { - dprintf("initialize PCI controller from FDT\n"); - - status_t res; - fdt_device_module_info* parentModule; - fdt_device* parentDev; - - res = gDeviceManager->get_driver(parent.Get(), - (driver_module_info**)&parentModule, (void**)&parentDev); - if (res != B_OK) { - dprintf("can't get parent node driver\n"); - return B_ERROR; - } - - uint64 configRegs = 0; - uint64 configRegsLen = 0; - - parentModule->get_reg(parentDev, 0, &configRegs, &configRegsLen); - dprintf(" configRegs: (0x%" B_PRIx64 ", 0x%" B_PRIx64 ")\n", - configRegs, configRegsLen); - - area_id area = map_physical_memory("pci config", - configRegs, configRegsLen, B_ANY_KERNEL_ADDRESS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&gPCIeBase); - - if (area < 0) - return B_ERROR; - - sRanges = new Vector(); - int rangesLen; - const void* rangesAddr = parentModule->get_prop(parentDev, "ranges", - &rangesLen); - if (rangesAddr == NULL) { - dprintf(" ranges property not found\n"); - return B_ERROR; - } - - for (uint32_t *it = (uint32_t*)rangesAddr; - (uint8_t*)it - (uint8_t*)rangesAddr < rangesLen; it += 7) { - uint32_t kind = B_BENDIAN_TO_HOST_INT32(*(it + 0)); - uint64_t childAddr = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 1)); - uint64_t parentAddr = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 3)); - uint64_t len = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 5)); - - PciRange range; - range.type = ((kind & 0x03000000) == 0x01000000) ? RANGE_IO : RANGE_MEM; - range.hostAddr = parentAddr; - range.pciAddr = childAddr; - range.length = len; - sRanges->PushBack(range); - - if ((kind & 0x03000000) != 0x01000000) - continue; - - dprintf(" (0x%08" B_PRIx32 "): ", kind); - dprintf("child: %08" B_PRIx64, childAddr); - dprintf(", parent: %08" B_PRIx64, parentAddr); - dprintf(", len: %" B_PRIx64 "\n", len); - - area_id area = map_physical_memory("pci io", - parentAddr, len, B_ANY_KERNEL_ADDRESS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&gPCIioBase); - - if (area < 0) - return B_ERROR; - } - - gStartBusNumber = 0; - gEndBusNumber = 0xff; - - return pci_controller_add(&pci_controller_ecam, NULL); - } - - if (strcmp(bus, "acpi") == 0) { - dprintf("initialize PCI controller from ACPI\n"); - - status_t res; - acpi_module_info *acpiModule; - acpi_device_module_info *acpiDeviceModule; - acpi_device acpiDevice; - - res = get_module(B_ACPI_MODULE_NAME, (module_info**)&acpiModule); - if (res != B_OK) - return B_ERROR; - - acpi_mcfg *mcfg; - res = acpiModule->get_table(ACPI_MCFG_SIGNATURE, 0, (void**)&mcfg); - if (res != B_OK) - return B_ERROR; - - res = gDeviceManager->get_driver(parent.Get(), - (driver_module_info**)&acpiDeviceModule, (void**)&acpiDevice); - if (res != B_OK) - return B_ERROR; - - sRanges = new Vector(); - - acpi_status acpi_res = acpiDeviceModule->walk_resources(acpiDevice, - (char *)"_CRS", AcpiCrsScanCallback, sRanges); - - if (acpi_res != 0) - return B_ERROR; - - for (Vector::Iterator it = sRanges->Begin(); it != sRanges->End(); it++) { - if (it->type != RANGE_IO) - continue; - - if (gPCIioBase != 0) { - dprintf("PCI: multiple io ranges not supported!"); - continue; - } - - area_id area = map_physical_memory("pci io", - it->hostAddr, it->length, B_ANY_KERNEL_ADDRESS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&gPCIioBase); - - if (area < 0) - return B_ERROR; - } - - acpi_mcfg_allocation *end = (acpi_mcfg_allocation *) ((char*)mcfg + mcfg->header.length); - acpi_mcfg_allocation *alloc = (acpi_mcfg_allocation *) (mcfg + 1); - - if (alloc + 1 != end) - dprintf("PCI: multiple host bridges not supported!"); - - for (; alloc < end; alloc++) { - dprintf("PCI: mechanism addr: %" B_PRIx64 ", seg: %x, start: %x, end: %x\n", - alloc->address, alloc->pci_segment, alloc->start_bus_number, alloc->end_bus_number); - - if (alloc->pci_segment != 0) { - dprintf("PCI: multiple segments not supported!"); - continue; - } - - gStartBusNumber = alloc->start_bus_number; - gEndBusNumber = alloc->end_bus_number; - - area_id area = map_physical_memory("pci config", - alloc->address, (gEndBusNumber - gStartBusNumber + 1) << 20, B_ANY_KERNEL_ADDRESS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&gPCIeBase); - - if (area < 0) - break; - - dprintf("PCI: ecam controller found\n"); - return pci_controller_add(&pci_controller_ecam, NULL); - } - } - - return B_ERROR; -} - - -static void -pci_controller_finalize_interrupts(fdt_device_module_info* fdtModule, struct fdt_interrupt_map* interruptMap, - int bus, int device, int function) -{ - uint32 childAddr = ((bus & 0xff) << 16) | ((device & 0x1f) << 11) | ((function & 0x07) << 8); - uint32 interruptPin = pci_read_config(bus, device, function, PCI_interrupt_pin, 1); - - if (interruptPin == 0xffffffff) { - dprintf("Error: Unable to read interrupt pin!\n"); - return; - } - - uint32 irq = fdtModule->lookup_interrupt_map(interruptMap, childAddr, interruptPin); - if (irq == 0xffffffff) { - dprintf("no interrupt mapping for childAddr: (%d:%d:%d), childIrq: %d)\n", - bus, device, function, interruptPin); - } else { - dprintf("configure interrupt (%d,%d,%d) --> %d\n", - bus, device, function, irq); - pci_update_interrupt_line(bus, device, function, irq); - } -} - - -status_t -pci_controller_finalize(void) -{ - DeviceNodePutter<&gDeviceManager> - parent(gDeviceManager->get_parent_node(gPCIRootNode)); - - if (parent.Get() == NULL) - return B_ERROR; - - const char* bus; - if (gDeviceManager->get_attr_string(parent.Get(), B_DEVICE_BUS, &bus, false) < B_OK) - return B_ERROR; - - if (strcmp(bus, "fdt") == 0) { - dprintf("finalize PCI controller from FDT\n"); - - status_t res; - fdt_device_module_info* parentModule; - fdt_device* parentDev; - - res = gDeviceManager->get_driver(parent.Get(), - (driver_module_info**)&parentModule, (void**)&parentDev); - if (res != B_OK) { - dprintf("can't get parent node driver\n"); - return B_ERROR; - } - - struct fdt_interrupt_map* interruptMap = parentModule->get_interrupt_map(parentDev); - parentModule->print_interrupt_map(interruptMap); - - for (int bus = 0; bus < 8; bus++) { - for (int device = 0; device < 32; device++) { - uint32 vendorID = pci_read_config(bus, device, 0, PCI_vendor_id, 2); - if ((vendorID != 0xffffffff) && (vendorID != 0xffff)) { - uint32 headerType = pci_read_config(bus, device, 0, PCI_header_type, 1); - if ((headerType & 0x80) != 0) { - for (int function = 0; function < 8; function++) { - pci_controller_finalize_interrupts(parentModule, interruptMap, bus, device, function); - } - } else { - pci_controller_finalize_interrupts(parentModule, interruptMap, bus, device, 0); - } - } - } - } - - return B_OK; - } - - if (strcmp(bus, "acpi") == 0) { - dprintf("finalize PCI controller from ACPI\n"); - - status_t res; - - acpi_module_info *acpiModule; - res = get_module(B_ACPI_MODULE_NAME, (module_info**)&acpiModule); - if (res != B_OK) - return B_ERROR; - - IRQRoutingTable table; - res = prepare_irq_routing(acpiModule, table, &is_interrupt_available); - if (res != B_OK) { - dprintf("PCI: irq routing preparation failed\n"); - return B_ERROR; - } - - res = enable_irq_routing(acpiModule, table); - if (res != B_OK) { - dprintf("PCI: irq routing failed\n"); - return B_ERROR; - } - - print_irq_routing_table(table); - - return B_OK; - } - - return B_ERROR; -} - - -phys_addr_t -pci_ram_address(phys_addr_t addr) -{ - for (Vector::Iterator it = sRanges->Begin(); it != sRanges->End(); it++) { - if (addr >= it->pciAddr && addr < it->pciAddr + it->length) { - phys_addr_t result = addr - it->pciAddr; - if (it->type != RANGE_IO) - result += it->hostAddr; - return result; - } - } - - dprintf("PCI: requested translation of invalid address %" B_PRIxPHYSADDR "\n", addr); - return 0; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_ecam.cpp b/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_ecam.cpp deleted file mode 100644 index 1d6b194def..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_ecam.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2009-2022, Haiku Inc. - * Distributed under the terms of the MIT License. - */ - -#include "pci_controller.h" - -#include - - -extern addr_t gPCIeBase; -extern uint8 gStartBusNumber; -extern uint8 gEndBusNumber; - - -#define PCIE_VADDR(base, bus, slot, func, reg) \ - ((base) + ((((bus) & 0xff) << 20) | (((slot) & 0x1f) << 15) \ - | (((func) & 0x7) << 12) | ((reg) & 0xfff))) - - -static status_t -read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - if (!(bus >= gStartBusNumber && bus <= gEndBusNumber)) - return B_ERROR; - - status_t status = B_OK; - - addr_t address = PCIE_VADDR(gPCIeBase, bus - gStartBusNumber, device, function, offset); - - switch (size) { - case 1: - *value = *(uint8*)address; - break; - case 2: - *value = *(uint16*)address; - break; - case 4: - *value = *(uint32*)address; - break; - default: - status = B_ERROR; - break; - } - return status; -} - - -static status_t -write_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value) -{ - if (!(bus >= gStartBusNumber && bus <= gEndBusNumber)) - return B_ERROR; - - status_t status = B_OK; - - addr_t address = PCIE_VADDR(gPCIeBase, bus - gStartBusNumber, device, function, offset); - switch (size) { - case 1: - *(uint8*)address = value; - break; - case 2: - *(uint16*)address = value; - break; - case 4: - *(uint32*)address = value; - break; - default: - status = B_ERROR; - break; - } - - return status; -} - - -static status_t -get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 32; - return B_OK; -} - - -static status_t -read_pci_irq(void *cookie, uint8 bus, uint8 device, uint8 function, uint8 pin, - uint8 *irq) -{ - dprintf("read_pci_irq\n"); - return B_NOT_SUPPORTED; -} - - -static status_t -write_pci_irq(void *cookie, uint8 bus, uint8 device, uint8 function, uint8 pin, - uint8 irq) -{ - dprintf("write_pci_irq\n"); - return B_NOT_SUPPORTED; -} - - -pci_controller pci_controller_ecam = -{ - read_pci_config, - write_pci_config, - get_max_bus_devices, - read_pci_irq, - write_pci_irq, -}; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_io.cpp b/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_io.cpp deleted file mode 100644 index 6987f01b26..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/generic/pci_io.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2022, Haiku Inc. - * Distributed under the terms of the MIT License. - */ - - -#include - -#include "pci_private.h" - -//#define TRACE_PCI_IO -#ifdef TRACE_PCI_IO -# define TRACE(x...) dprintf("PCI_IO: " x) -#else -# define TRACE(x...) ; -#endif - - -extern addr_t gPCIioBase; - -status_t -pci_io_init() -{ - TRACE("pci_io_init()\n"); - return B_OK; -} - - -uint8 -pci_read_io_8(int mapped_io_addr) -{ - TRACE("pci_read_io_8(%d)\n", mapped_io_addr); - volatile uint8* ptr = (uint8*)(gPCIioBase + mapped_io_addr); - return *ptr; -} - - -void -pci_write_io_8(int mapped_io_addr, uint8 value) -{ - TRACE("pci_write_io_8(%d)\n", mapped_io_addr); - volatile uint8* ptr = (uint8*)(gPCIioBase + mapped_io_addr); - *ptr = value; -} - - -uint16 -pci_read_io_16(int mapped_io_addr) -{ - TRACE("pci_read_io_16(%d)\n", mapped_io_addr); - volatile uint16* ptr = (uint16*)(gPCIioBase + mapped_io_addr); - return *ptr; -} - - -void -pci_write_io_16(int mapped_io_addr, uint16 value) -{ - TRACE("pci_write_io_16(%d)\n", mapped_io_addr); - volatile uint16* ptr = (uint16*)(gPCIioBase + mapped_io_addr); - *ptr = value; -} - - -uint32 -pci_read_io_32(int mapped_io_addr) -{ - TRACE("pci_read_io_32(%d)\n", mapped_io_addr); - volatile uint32* ptr = (uint32*)(gPCIioBase + mapped_io_addr); - return *ptr; -} - - -void -pci_write_io_32(int mapped_io_addr, uint32 value) -{ - TRACE("pci_write_io_32(%d)\n", mapped_io_addr); - volatile uint32* ptr = (uint32*)(gPCIioBase + mapped_io_addr); - *ptr = value; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/m68k/Jamfile deleted file mode 100644 index 6c268583b9..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/Jamfile +++ /dev/null @@ -1,19 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch m68k ; - -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] - [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; - -SEARCH_SOURCE += [ FDirName $(SUBDIR) amiga ] ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) apple ] ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) atari ] ; - -KernelStaticLibrary pci_arch_bus_manager : - pci_controller.cpp - pci_io.c - - # platforms - pci_amiga.cpp - pci_apple.cpp - pci_atari.cpp -; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.cpp deleted file mode 100644 index a376065672..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2007, François Revol . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include "pci_amiga.h" - -#include -#include - -#include - - -status_t -m68k_amiga_pci_controller_init(void) -{ - return B_OK; -} - - -// #pragma mark - support functions - - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.h deleted file mode 100644 index d9add73875..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2007, François Revol . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_M68K_AMIGA_H -#define PCI_BUS_MANAGER_M68K_AMIGA_H - -#include - -status_t m68k_amiga_pci_controller_init(void); - -#endif // PCI_BUS_MANAGER_M68K_AMIGA_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.cpp deleted file mode 100644 index 756e09b054..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2007, François Revol . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include "pci_apple.h" - -#include -#include - -#include - - -status_t -m68k_apple_pci_controller_init(void) -{ - return B_OK; -} - - -// #pragma mark - support functions - - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.h deleted file mode 100644 index 5b49fdb4a4..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2007, François Revol . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_M68K_APPLE_H -#define PCI_BUS_MANAGER_M68K_APPLE_H - -#include - -status_t m68k_apple_pci_controller_init(void); - -#endif // PCI_BUS_MANAGER_M68K_APPLE_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp deleted file mode 100644 index 4b9996537c..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright 2007, François Revol . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include "pci_atari.h" - -#include -#include - -#include -#include - -#include "pci_controller.h" - -/* - * Here we fake a PCI bus that maps the physical memory - * (which is also I/O on 68k), and fake some system devices. - * Some other devices are faked as ISA because they need DMA - * notification. - * - * TODO: anything to be done to support VME cards ? - * I don't think they are PnP at all anyway. - * - * TODO: On Hades/Milan clones a real PCI bus is accessible - * through PAE-like extra bits in page descriptors. This one - * should be handled in a separate file. - */ - -//XXX:find one and put in shared priv header! -// 0x68xx is free according to pci.ids -// 68fx (f=fake) x = 0:amiga, 1:apple, 2:atari -#define FAKEV 0x68f2 - -// bus number -#define BN 0 - -// default line size -#define DLL 1 -// default latency -#define DL 0 -// default header_type -#define DH PCI_header_type_generic -// default bist -#define DB 0 - -#define PEI 0 - -#define INVV 0xffff //0x0000 ?? -#define INVD 0xffff - -struct fake_pci_device { - pci_info info; - -}; - -static struct fake_pci_device gFakePCIDevices[] = { -{ {FAKEV, 0x0000, BN, 0, 0, 0, 0xff, PCI_host, PCI_bridge, DLL, DL, DH, DB, 0, PEI }}, /* cpu */ -{ {FAKEV, 0x0001, BN, 1, 0, 0, 0xff, 0x68/*fake*/, PCI_processor, DLL, DL, DH, DB, 0, PEI }}, /* cpu */ -{ {FAKEV, 0x0002, BN, 2, 0, 0, 0xff, PCI_display_other, PCI_display, DLL, DL, DH, DB, 0, /*0xFFFF8200,*/ PEI }}, /* gfx */ -{ {FAKEV, 0x0003, BN, 3, 0, 0, 0xff, PCI_ide, PCI_mass_storage, DLL, DL, DH, DB, 0, /*0xFFF00000,*/ PEI }}, /* ide */ -{ {FAKEV, 0x0004, BN, 4, 0, 0, 0xff, PCI_scsi, PCI_mass_storage, DLL, DL, DH, DB, 0, PEI }}, /* scsi */ -{ {FAKEV, 0x0005, BN, 5, 0, 0, 0xff, 0x0/*CHANGEME*/, PCI_multimedia, DLL, DL, DH, DB, /*0x00,*/ 0, /*0xFFFF8900,*/ PEI }}, /* snd */ -//UART ? -//centronics? -{ {INVV, INVD} } -}; -#define FAKE_DEVICES_COUNT (sizeof(gFakePCIDevices)/sizeof(struct fake_pci_device)-1) - -struct m68k_atari_fake_host_bridge { - uint32 bus; -}; - - -#define out8rb(address, value) m68k_out8((vuint8*)(address), value) -#define out16rb(address, value) m68k_out16_reverse((vuint16*)(address), value) -#define out32rb(address, value) m68k_out32_reverse((vuint32*)(address), value) -#define in8rb(address) m68k_in8((const vuint8*)(address)) -#define in16rb(address) m68k_in16_reverse((const vuint16*)(address)) -#define in32rb(address) m68k_in32_reverse((const vuint32*)(address)) - - -static int m68k_atari_enable_config(struct m68k_atari_fake_host_bridge *bridge, - uint8 bus, uint8 slot, uint8 function, uint8 offset); - -static status_t m68k_atari_read_pci_config(void *cookie, uint8 bus, uint8 device, - uint8 function, uint16 offset, uint8 size, uint32 *value); -static status_t m68k_atari_write_pci_config(void *cookie, uint8 bus, - uint8 device, uint8 function, uint16 offset, uint8 size, - uint32 value); -static status_t m68k_atari_get_max_bus_devices(void *cookie, int32 *count); -static status_t m68k_atari_read_pci_irq(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 pin, uint8 *irq); -static status_t m68k_atari_write_pci_irq(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 pin, uint8 irq); - -static pci_controller sM68kAtariPCIController = { - m68k_atari_read_pci_config, - m68k_atari_write_pci_config, - m68k_atari_get_max_bus_devices, - m68k_atari_read_pci_irq, - m68k_atari_write_pci_irq, -}; - - -static status_t -m68k_atari_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - struct fake_pci_device *devices = (struct fake_pci_device *)cookie; - struct fake_pci_device *dev; - - if (bus != 0) - return EINVAL; - if (device >= FAKE_DEVICES_COUNT) - return EINVAL; - if (function != 0) - return EINVAL; - dev = &devices[device]; - -#define O(pn,n,s) \ - case pn: \ - if (size != s) { \ - panic("invalid pci config size %d for offset %d", size, offset); \ - return EINVAL; \ - } \ - *value = dev->info.n; \ - return B_OK - - if (1) { - switch (offset) { - O(PCI_vendor_id, vendor_id, 2); - O(PCI_device_id, device_id, 2); - O(PCI_revision, revision, 1); - O(PCI_class_api, class_api, 1); - O(PCI_class_sub, class_sub, 1); - O(PCI_class_base, class_base, 1); - O(PCI_line_size, line_size, 1); - O(PCI_latency, latency, 1); - O(PCI_header_type, header_type, 1); - O(PCI_bist, bist, 1); - } - } -//#undef O -#if 0 -#define PCI_command 0x04 /* (2 byte) command */ -#define PCI_status 0x06 /* (2 byte) status */ -#endif - - if (dev->info.header_type == 0x00 || dev->info.header_type == 0x01) { - switch (offset) { - case PCI_base_registers: - return EINVAL; - O(PCI_interrupt_line, u.h0.interrupt_line, 1); - O(PCI_interrupt_pin, u.h0.interrupt_pin, 1); - default: - break; - } - } - - if (dev->info.header_type == 0x00) { - switch (offset) { - default: - break; - } - } - - if (dev->info.header_type == 0x01) { - switch (offset) { - O(PCI_primary_bus, u.h1.primary_bus, 1); - O(PCI_secondary_bus, u.h1.secondary_bus, 1); - O(PCI_subordinate_bus, u.h1.subordinate_bus, 1); - O(PCI_secondary_latency, u.h1.secondary_latency, 1); - default: - break; - } - } - - *value = 0xffffffff; - panic("invalid pci config offset %d", offset); - return EINVAL; - //return B_OK; -} - - -static status_t -m68k_atari_write_pci_config(void *cookie, uint8 bus, uint8 device, - uint8 function, uint16 offset, uint8 size, uint32 value) -{ -#if 0 - if (m68k_atari_enable_config(bridge, bus, device, function, offset)) { - switch (size) { - case 1: - out8rb(caoff, (uint8)value); - (void)in8rb(caoff); - break; - case 2: - out16rb(caoff, (uint16)value); - (void)in16rb(caoff); - break; - case 4: - out32rb(caoff, value); - (void)in32rb(caoff); - break; - } - } - -#endif - panic("write pci config dev %d offset %d", device, offset); - return B_ERROR; - return B_OK; -} - - -static status_t -m68k_atari_get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 32; - return B_OK; -} - - -static status_t -m68k_atari_read_pci_irq(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 pin, uint8 *irq) -{ -#warning M68K: WRITEME - return B_ERROR; -} - - -static status_t -m68k_atari_write_pci_irq(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 pin, uint8 irq) -{ -#warning M68K: WRITEME - return B_ERROR; -} - - -// #pragma mark - - - -static int -m68k_atari_enable_config(struct m68k_atari_fake_host_bridge *bridge, uint8 bus, - uint8 slot, uint8 function, uint8 offset) -{ -#warning M68K: WRITEME - return 0; -} - - -// #pragma mark - - - - - -status_t -m68k_atari_pci_controller_init(void) -{ - struct m68k_atari_fake_host_bridge *bridge; - bridge = (struct m68k_atari_fake_host_bridge *) - malloc(sizeof(struct m68k_atari_fake_host_bridge)); - if (!bridge) - return B_NO_MEMORY; - - bridge->bus = 0; - - status_t error = pci_controller_add(&sM68kAtariPCIController, bridge); - - if (error != B_OK) - free(bridge); - - // TODO: probe Hades & Milan bridges - return error; -} - - -// #pragma mark - support functions - - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.h deleted file mode 100644 index e27431a044..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2007, François Revol . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_M68K_ATARI_H -#define PCI_BUS_MANAGER_M68K_ATARI_H - -#include - -status_t m68k_atari_pci_controller_init(void); - -#endif // PCI_BUS_MANAGER_M68K_ATARI_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_controller.cpp deleted file mode 100644 index 87293a3e1d..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_controller.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2007, François Revol . - * Distributed under the terms of the MIT License. - */ - - -#include "pci_controller.h" - -#include - -#include "pci_private.h" - -/* - * As we don't have any real PCI bus in any of the supported m68k platforms, - * we fake one, with hardcoded devices. - * TODO: this doesn't make any sense, as we can't share any drivers, anyway. - * We should better export dedicated bus managers for Zorro etc. busses on - * these systems. - * TODO: actually, there are several PCI boards for the Amiga. - */ - -#include "amiga/pci_amiga.h" -#include "apple/pci_apple.h" -#include "atari/pci_atari.h" - - -status_t -pci_controller_init(void) -{ - switch (M68KPlatform::Default()->PlatformType()) { -/* case M68K_PLATFORM_AMIGA: - return m68k_amiga_pci_controller_init(); - break; - case M68K_PLATFORM_APPLE: - return m68k_apple_pci_controller_init(); - break;*/ - case M68K_PLATFORM_ATARI: - return m68k_atari_pci_controller_init(); - break; - default: - return EINVAL; - } - return B_OK; -} - - -phys_addr_t -pci_ram_address(phys_addr_t physical_address_in_system_memory) -{ - return physical_address_in_system_memory; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.c b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.c deleted file mode 100644 index b9f872cef2..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2007, François Revol . - * Distributed under the terms of the MIT License. - */ - - -#include "pci_io.h" -#include "pci_private.h" - - -status_t -pci_io_init() -{ - return B_OK; -} - - -uint8 -pci_read_io_8(int mapped_io_addr) -{ - return m68k_in8((vuint8*)mapped_io_addr); -} - - -void -pci_write_io_8(int mapped_io_addr, uint8 value) -{ - m68k_out8((vuint8*)mapped_io_addr, value); -} - - -uint16 -pci_read_io_16(int mapped_io_addr) -{ - return m68k_in16((vuint16*)mapped_io_addr); -} - - -void -pci_write_io_16(int mapped_io_addr, uint16 value) -{ - m68k_out16((vuint16*)mapped_io_addr, value); -} - - -uint32 -pci_read_io_32(int mapped_io_addr) -{ - return m68k_in32((vuint32*)mapped_io_addr); -} - - -void -pci_write_io_32(int mapped_io_addr, uint32 value) -{ - m68k_out32((vuint32*)mapped_io_addr, value); -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.h deleted file mode 100644 index 927fad7a01..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_M68K_IO_H -#define PCI_BUS_MANAGER_M68K_IO_H - -#include - -#define IOBARRIER() asm volatile("nop") /* nop flushes the instruction pipeline */ -/*XXX: sync cache/pmmu?*/ - -static inline void -m68k_out8(vuint8 *address, uint8 value) -{ - *address = value; - IOBARRIER(); -} - - -static inline void -m68k_out16(vuint16 *address, uint16 value) -{ - *address = value; - IOBARRIER(); -} - -#if _XXX_HAS_REVERSE_IO -static inline void -m68k_out16_reverse(vuint16 *address, uint16 value) -{ - asm volatile("sthbrx %1, 0, %0" : : "r"(address), "r"(value)); - IOBARRIER(); -} -#endif - - -static inline void -m68k_out32(vuint32 *address, uint32 value) -{ - *address = value; - IOBARRIER(); -} - - -#if _XXX_HAS_REVERSE_IO -static inline void -m68k_out32_reverse(vuint32 *address, uint32 value) -{ - asm volatile("stwbrx %1, 0, %0" : : "r"(address), "r"(value)); - IOBARRIER(); -} -#endif - -static inline uint8 -m68k_in8(const vuint8 *address) -{ - uint8 value = *address; - IOBARRIER(); - return value; -} - - -static inline uint16 -m68k_in16(const vuint16 *address) -{ - uint16 value = *address; - IOBARRIER(); - return value; -} - - -#if _XXX_HAS_REVERSE_IO -static inline uint16 -m68k_in16_reverse(const vuint16 *address) -{ - uint16 value; - asm volatile("lhbrx %0, 0, %1" : "=r"(value) : "r"(address)); - IOBARRIER(); - return value; -} -#endif - - -static inline uint32 -m68k_in32(const vuint32 *address) -{ - uint32 value = *address; - IOBARRIER(); - return value; -} - - -#if _XXX_HAS_REVERSE_IO -static inline uint32 -m68k_in32_reverse(const vuint32 *address) -{ - uint32 value; - asm volatile("lwbrx %0, 0, %1" : "=r"(value) : "r"(address)); - IOBARRIER(); - return value; -} -#endif - -#endif // PCI_BUS_MANAGER_M68K_IO_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/ppc/Jamfile deleted file mode 100644 index 2f81efb0e5..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/Jamfile +++ /dev/null @@ -1,21 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch ppc ; - -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] - [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; - -SEARCH_SOURCE += [ FDirName $(SUBDIR) openfirmware ] ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) u-boot ] ; - -KernelStaticLibrary pci_arch_bus_manager : - pci_controller.cpp - pci_io.c - - # openfirmware - pci_openfirmware.cpp - uninorth.cpp - grackle.cpp - - # U-Boot - pci_u-boot.cpp -; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/grackle.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/grackle.cpp deleted file mode 100644 index b0a98f16d8..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/grackle.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2010 Andreas Färber - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ -/*- - * Copyright (c) 2000 Tsubai Masanari. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include - -#include -#include -#include - -#include "pci_controller.h" -#include "pci_io.h" -#include "pci_openfirmware_priv.h" - - -//#define TRACE_GRACKLE - -#ifdef TRACE_GRACKLE -#define TRACE(fmt...) dprintf(fmt) -#else -#define TRACE(fmt...) ; -#endif - - -struct grackle_range { - uint32_t pci_hi; - uint32_t pci_mid; - uint32_t pci_lo; - uint32_t host; - uint32_t size_hi; - uint32_t size_lo; -}; - - -struct grackle_host_bridge { - int device_node; - addr_t address_registers; - addr_t data_registers; - uint32 bus; - struct grackle_range ranges[6]; - int range_count; -}; - - -#define out8rb(address, value) ppc_out8((vuint8*)(address), value) -#define out16rb(address, value) ppc_out16_reverse((vuint16*)(address), value) -#define out32rb(address, value) ppc_out32_reverse((vuint32*)(address), value) -#define in8rb(address) ppc_in8((const vuint8*)(address)) -#define in16rb(address) ppc_in16_reverse((const vuint16*)(address)) -#define in32rb(address) ppc_in32_reverse((const vuint32*)(address)) - - -static status_t -grackle_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - grackle_host_bridge *bridge = (grackle_host_bridge*)cookie; - TRACE("grackle_read_pci_config(bus=%u, dev=%u, func=%u, offset=%u, " - "size=%u)\n", (int)bus, (int)device, (int)function, (int)offset, - (int)size); - - if (offset > 0xff) - return B_BAD_VALUE; - - out32rb(bridge->address_registers, (1 << 31) - | (bus << 16) | ((device & 0x1f) << 11) | ((function & 0x7) << 8) - | (offset & 0xfc)); - - addr_t dataAddress = bridge->data_registers + (offset & 0x3); - switch (size) { - case 1: - *value = in8rb(dataAddress); - break; - case 2: - *value = in16rb(dataAddress); - break; - case 4: - *value = in32rb(dataAddress); - break; - default: - *value = 0xffffffff; - break; - } - - out32rb(bridge->address_registers, 0); - - return B_OK; -} - - -static status_t -grackle_write_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value) -{ - grackle_host_bridge *bridge = (grackle_host_bridge*)cookie; - TRACE("grackle_write_pci_config(bus=%u, dev=%u, func=%u, offset=%u, " - "size=%u, value=%lu)\n", (int)bus, (int)device, (int)function, - (int)offset, (int)size, value); - - if (offset > 0xff) - return B_BAD_VALUE; - - out32rb(bridge->address_registers, (1 << 31) - | (bus << 16) | ((device & 0x1f) << 11) | ((function & 0x7) << 8) - | (offset & 0xfc)); - - addr_t dataAddress = bridge->data_registers + (offset & 0x3); - switch (size) { - case 1: - out8rb(dataAddress, (uint8)value); - break; - case 2: - out16rb(dataAddress, (uint16)value); - break; - case 4: - out32rb(dataAddress, value); - break; - } - - out32rb(bridge->address_registers, 0); - - return B_OK; -} - - -static status_t -grackle_get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 32; - return B_OK; -} - - -static status_t -grackle_read_pci_irq(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 pin, uint8 *irq) -{ - return B_ERROR; -} - - -static status_t -grackle_write_pci_irq(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 pin, uint8 irq) -{ - return B_ERROR; -} - - -static pci_controller sGracklePCIController = { - grackle_read_pci_config, - grackle_write_pci_config, - grackle_get_max_bus_devices, - grackle_read_pci_irq, - grackle_write_pci_irq, -}; - - -status_t -ppc_openfirmware_probe_grackle(int deviceNode, - const StringArrayPropertyValue &compatibleValue) -{ - if (!compatibleValue.ContainsElement("grackle")) - return B_ERROR; - - uint32_t busrange[2]; - if (of_getprop(deviceNode, "bus-range", busrange, sizeof(busrange)) != 8) - return B_ERROR; - - grackle_host_bridge *bridge = - (grackle_host_bridge*)malloc(sizeof(grackle_host_bridge)); - if (bridge == NULL) - return B_NO_MEMORY; - - bridge->device_node = deviceNode; - bridge->address_registers = 0xfec00000; - bridge->data_registers = 0xfee00000; - bridge->bus = busrange[0]; - - memset(bridge->ranges, 0, sizeof(bridge->ranges)); - int bytesRead = of_getprop(deviceNode, "ranges", bridge->ranges, - sizeof(bridge->ranges)); - if (bytesRead < 0) { - dprintf("ppc_openfirmware_probe_grackle: Could not get ranges.\n"); - free(bridge); - return B_ERROR; - } - bridge->range_count = bytesRead / sizeof(grackle_range); - - grackle_range *ioRange = NULL; - grackle_range *memoryRanges[2]; - int memoryRangeCount = 0; - - for (int i = 0; i < bridge->range_count; i++) { - grackle_range *range = bridge->ranges + i; - switch (range->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { - case OFW_PCI_PHYS_HI_SPACE_CONFIG: - break; - case OFW_PCI_PHYS_HI_SPACE_IO: - ioRange = range; - break; - case OFW_PCI_PHYS_HI_SPACE_MEM32: - memoryRanges[memoryRangeCount++] = range; - break; - case OFW_PCI_PHYS_HI_SPACE_MEM64: - break; - } - } - - if (ioRange == NULL) { - dprintf("ppc_openfirmware_probe_grackle: Can't find io range.\n"); - free(bridge); - return B_ERROR; - } - - if (memoryRangeCount == 0) { - dprintf("ppc_openfirmware_probe_grackle: Can't find mem ranges.\n"); - free(bridge); - return B_ERROR; - } - - status_t error = pci_controller_add(&sGracklePCIController, bridge); - if (error != B_OK) - free(bridge); - return error; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware.cpp deleted file mode 100644 index f85a682a99..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include "pci_openfirmware.h" - -#include -#include - -#include - -#include -#include -#include - -#include "pci_openfirmware_priv.h" - - -typedef status_t (*probeFunction)(int, const StringArrayPropertyValue&); - -static const probeFunction sProbeFunctions[] = { - ppc_openfirmware_probe_uninorth, - ppc_openfirmware_probe_grackle, - NULL, -}; - - -status_t -ppc_openfirmware_pci_controller_init(void) -{ - char path[256]; - intptr_t cookie = 0; - while (of_get_next_device(&cookie, 0, "pci", path, sizeof(path)) - == B_OK) { -dprintf("ppc_openfirmware_pci_controller_init(): pci device node: %s\n", path); - // get the device node and the "compatible" property - int deviceNode = of_finddevice(path); - StringArrayPropertyValue compatible; - status_t error = openfirmware_get_property(deviceNode, "compatible", - compatible); - if (error != B_OK) { - dprintf("ppc_openfirmware_pci_controller_init: Failed to get " - "\"compatible\" property for pci device: %s\n", path); - continue; - } - - // probe - for (int i = 0; sProbeFunctions[i]; i++) { - error = sProbeFunctions[i](deviceNode, compatible); - if (error == B_OK) - break; - } - } - - return B_OK; -} - - -// #pragma mark - support functions - - -char * -StringArrayPropertyValue::NextElement(int &cookie) const -{ - if (cookie >= length) - return NULL; - - char *result = value + cookie; - cookie += strnlen(result, length - cookie) + 1; - return result; -} - - -bool -StringArrayPropertyValue::ContainsElement(const char *value) const -{ - int cookie = 0; - while (char *checkValue = NextElement(cookie)) { - if (strcmp(checkValue, value) == 0) - return true; - } - - return false; -} - - -status_t -openfirmware_get_property(int package, const char *propertyName, - PropertyValue &value) -{ - value.length = of_getproplen(package, propertyName); - if (value.length < 0) - return B_ENTRY_NOT_FOUND; - - value.value = (char*)malloc(value.length); - if (!value.value) - return B_NO_MEMORY; - - if (of_getprop(package, propertyName, value.value, value.length) - == OF_FAILED) { - return B_ERROR; - } - - return B_OK; -} - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware.h b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware.h deleted file mode 100644 index 5427963999..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_H -#define PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_H - -#include - -status_t ppc_openfirmware_pci_controller_init(void); - -#endif // PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware_priv.h b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware_priv.h deleted file mode 100644 index 10392a70d8..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/pci_openfirmware_priv.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_PRIV_H -#define PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_PRIV_H - -#include -#include - -#include - - -struct StringArrayPropertyValue; - - -// implementations - -status_t ppc_openfirmware_probe_uninorth(int deviceNode, - const StringArrayPropertyValue &compatibleValue); -status_t ppc_openfirmware_probe_grackle(int deviceNode, - const StringArrayPropertyValue &compatibleValue); - - -// property support - -struct PropertyValue { - PropertyValue() - : value(NULL) - { - } - - ~PropertyValue() - { - free(value); - } - - char *value; - int length; -}; - -struct StringArrayPropertyValue : PropertyValue { - - char *NextElement(int &cookie) const; - bool ContainsElement(const char *value) const; -}; - -status_t openfirmware_get_property(int package, const char *propertyName, - PropertyValue &value); - -#endif // PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_PRIV_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/uninorth.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/uninorth.cpp deleted file mode 100644 index 7997129f79..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/uninorth.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ -/*- - * Copyright (C) 2002 Benno Rice. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include - -#include - -#include -#include -#include - -#include "pci_controller.h" -#include "pci_io.h" -#include "pci_openfirmware_priv.h" - - -struct uninorth_range { - uint32 pci_hi; - uint32 pci_mid; - uint32 pci_lo; - uint32 host; - uint32 size_hi; - uint32 size_lo; -}; - -struct uninorth_host_bridge { - int device_node; - addr_t address_registers; - addr_t data_registers; - uint32 bus; - struct uninorth_range ranges[6]; - int range_count; -}; - - -#define out8rb(address, value) ppc_out8((vuint8*)(address), value) -#define out16rb(address, value) ppc_out16_reverse((vuint16*)(address), value) -#define out32rb(address, value) ppc_out32_reverse((vuint32*)(address), value) -#define in8rb(address) ppc_in8((const vuint8*)(address)) -#define in16rb(address) ppc_in16_reverse((const vuint16*)(address)) -#define in32rb(address) ppc_in32_reverse((const vuint32*)(address)) - - -static int uninorth_enable_config(struct uninorth_host_bridge *bridge, - uint8 bus, uint8 slot, uint8 function, uint8 offset); - -static status_t uninorth_read_pci_config(void *cookie, uint8 bus, uint8 device, - uint8 function, uint16 offset, uint8 size, uint32 *value); -static status_t uninorth_write_pci_config(void *cookie, uint8 bus, - uint8 device, uint8 function, uint16 offset, uint8 size, - uint32 value); -static status_t uninorth_get_max_bus_devices(void *cookie, int32 *count); -static status_t uninorth_read_pci_irq(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 pin, uint8 *irq); -static status_t uninorth_write_pci_irq(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 pin, uint8 irq); - -static pci_controller sUniNorthPCIController = { - uninorth_read_pci_config, - uninorth_write_pci_config, - uninorth_get_max_bus_devices, - uninorth_read_pci_irq, - uninorth_write_pci_irq, -}; - - -static status_t -uninorth_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - uninorth_host_bridge *bridge = (uninorth_host_bridge*)cookie; - - if (offset > 0xff) - return B_BAD_VALUE; - - addr_t caoff = bridge->data_registers + (offset & 0x07); - - if (uninorth_enable_config(bridge, bus, device, function, offset) != 0) { - switch (size) { - case 1: - *value = in8rb(caoff); - break; - case 2: - *value = in16rb(caoff); - break; - case 4: - *value = in32rb(caoff); - break; - default: - *value = 0xffffffff; - break; - } - } else - *value = 0xffffffff; - - return B_OK; -} - - -static status_t uninorth_write_pci_config(void *cookie, uint8 bus, uint8 device, - uint8 function, uint16 offset, uint8 size, uint32 value) -{ - uninorth_host_bridge *bridge = (uninorth_host_bridge*)cookie; - - if (offset > 0xff) - return B_BAD_VALUE; - - addr_t caoff = bridge->data_registers + (offset & 0x07); - - if (uninorth_enable_config(bridge, bus, device, function, offset)) { - switch (size) { - case 1: - out8rb(caoff, (uint8)value); - (void)in8rb(caoff); - break; - case 2: - out16rb(caoff, (uint16)value); - (void)in16rb(caoff); - break; - case 4: - out32rb(caoff, value); - (void)in32rb(caoff); - break; - } - } - - return B_OK; -} - - -static status_t uninorth_get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 32; - return B_OK; -} - - -static status_t uninorth_read_pci_irq(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 pin, uint8 *irq) -{ - return B_ERROR; -} - - -static status_t uninorth_write_pci_irq(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 pin, uint8 irq) -{ - return B_ERROR; -} - - -// #pragma mark - - - -static int -uninorth_enable_config(struct uninorth_host_bridge *bridge, uint8 bus, - uint8 slot, uint8 function, uint8 offset) -{ -// uint32 pass; -// if (resource_int_value(device_get_name(sc->sc_dev), -// device_get_unit(sc->sc_dev), "skipslot", &pass) == 0) { -// if (pass == slot) -// return (0); -// } - - uint32 cfgval; - if (bridge->bus == bus) { - /* - * No slots less than 11 on the primary bus - */ - if (slot < 11) - return (0); - - cfgval = (1 << slot) | (function << 8) | (offset & 0xfc); - } else { - cfgval = (bus << 16) | (slot << 11) | (function << 8) | - (offset & 0xfc) | 1; - } - - do { - out32rb(bridge->address_registers, cfgval); - } while (in32rb(bridge->address_registers) != cfgval); - - return (1); -} - - -// #pragma mark - - -status_t -ppc_openfirmware_probe_uninorth(int deviceNode, - const StringArrayPropertyValue &compatibleValue) -{ - if (!compatibleValue.ContainsElement("uni-north")) - return B_ERROR; - - uint32 reg[2]; - if (of_getprop(deviceNode, "reg", reg, sizeof(reg)) < 8) - return B_ERROR; - - uint32 busrange[2]; - if (of_getprop(deviceNode, "bus-range", busrange, sizeof(busrange)) != 8) - return B_ERROR; - - uninorth_host_bridge *bridge - = (uninorth_host_bridge*)malloc(sizeof(uninorth_host_bridge)); - if (!bridge) - return B_NO_MEMORY; - - bridge->device_node = deviceNode; - bridge->address_registers = reg[0] + 0x800000; - bridge->data_registers = reg[0] + 0xc00000; - bridge->bus = busrange[0]; -// TODO: Check whether address and data registers have already been mapped by -// the Open Firmware. If not, map them ourselves. - - memset(bridge->ranges, 0, sizeof(bridge->ranges)); - int bytesRead = of_getprop(deviceNode, "ranges", bridge->ranges, - sizeof(bridge->ranges)); - - if (bytesRead < 0) { - dprintf("ppc_openfirmware_probe_uninorth: Could not get ranges.\n"); - free(bridge); - return B_ERROR; - } - bridge->range_count = bytesRead / sizeof(uninorth_range); - - uninorth_range *ioRange = NULL; - uninorth_range *memoryRanges[2]; - int memoryRangeCount = 0; - - for (int i = 0; i < bridge->range_count; i++) { - uninorth_range *range = bridge->ranges + i; - switch (range->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { - case OFW_PCI_PHYS_HI_SPACE_CONFIG: - break; - case OFW_PCI_PHYS_HI_SPACE_IO: - ioRange = range; - break; - case OFW_PCI_PHYS_HI_SPACE_MEM32: - memoryRanges[memoryRangeCount++] = range; - break; - case OFW_PCI_PHYS_HI_SPACE_MEM64: - break; - } - } - - if (ioRange == NULL) { - dprintf("ppc_openfirmware_probe_uninorth: Can't find io range.\n"); - free(bridge); - return B_ERROR; - } - - if (memoryRangeCount == 0) { - dprintf("ppc_openfirmware_probe_uninorth: Can't find mem ranges.\n"); - free(bridge); - return B_ERROR; - } - - status_t error = pci_controller_add(&sUniNorthPCIController, bridge); - if (error != B_OK) - free(bridge); - return error; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_controller.cpp deleted file mode 100644 index c5015db44f..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_controller.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "pci_controller.h" - -#include - -#include "pci_private.h" - -#include "openfirmware/pci_openfirmware.h" -#include "u-boot/pci_u-boot.h" - - -status_t -pci_controller_init(void) -{ - switch (PPCPlatform::Default()->PlatformType()) { - case PPC_PLATFORM_OPEN_FIRMWARE: - return ppc_openfirmware_pci_controller_init(); - case PPC_PLATFORM_U_BOOT: - return ppc_uboot_pci_controller_init(); - default: - panic("pci: unknown platform"); - } - return B_ERROR; -} - - -phys_addr_t -pci_ram_address(phys_addr_t physical_address_in_system_memory) -{ - return physical_address_in_system_memory; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_io.c b/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_io.c deleted file mode 100644 index 6202b911c3..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_io.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "pci_io.h" -#include "pci_private.h" - - -status_t -pci_io_init() -{ - return B_OK; -} - - -uint8 -pci_read_io_8(int mapped_io_addr) -{ - return ppc_in8((vuint8*)mapped_io_addr); -} - - -void -pci_write_io_8(int mapped_io_addr, uint8 value) -{ - ppc_out8((vuint8*)mapped_io_addr, value); -} - - -uint16 -pci_read_io_16(int mapped_io_addr) -{ - return ppc_in16((vuint16*)mapped_io_addr); -} - - -void -pci_write_io_16(int mapped_io_addr, uint16 value) -{ - ppc_out16((vuint16*)mapped_io_addr, value); -} - - -uint32 -pci_read_io_32(int mapped_io_addr) -{ - return ppc_in32((vuint32*)mapped_io_addr); -} - - -void -pci_write_io_32(int mapped_io_addr, uint32 value) -{ - ppc_out32((vuint32*)mapped_io_addr, value); -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_io.h b/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_io.h deleted file mode 100644 index a37447ad62..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_io.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_PPC_IO_H -#define PCI_BUS_MANAGER_PPC_IO_H - -#include - -static inline void -ppc_out8(vuint8 *address, uint8 value) -{ - *address = value; - asm volatile("eieio; sync"); -} - - -static inline void -ppc_out16(vuint16 *address, uint16 value) -{ - *address = value; - asm volatile("eieio; sync"); -} - - -static inline void -ppc_out16_reverse(vuint16 *address, uint16 value) -{ - asm volatile("sthbrx %1, 0, %0" : : "r"(address), "r"(value)); - asm volatile("eieio; sync"); -} - - -static inline void -ppc_out32(vuint32 *address, uint32 value) -{ - *address = value; - asm volatile("eieio; sync"); -} - - -static inline void -ppc_out32_reverse(vuint32 *address, uint32 value) -{ - asm volatile("stwbrx %1, 0, %0" : : "r"(address), "r"(value)); - asm volatile("eieio; sync"); -} - - -static inline uint8 -ppc_in8(const vuint8 *address) -{ - uint8 value = *address; - asm volatile("eieio; sync"); - return value; -} - - -static inline uint16 -ppc_in16(const vuint16 *address) -{ - uint16 value = *address; - asm volatile("eieio; sync"); - return value; -} - - -static inline uint16 -ppc_in16_reverse(const vuint16 *address) -{ - uint16 value; - asm volatile("lhbrx %0, 0, %1" : "=r"(value) : "r"(address)); - asm volatile("eieio; sync"); - return value; -} - - -static inline uint32 -ppc_in32(const vuint32 *address) -{ - uint32 value = *address; - asm volatile("eieio; sync"); - return value; -} - - -static inline uint32 -ppc_in32_reverse(const vuint32 *address) -{ - uint32 value; - asm volatile("lwbrx %0, 0, %1" : "=r"(value) : "r"(address)); - asm volatile("eieio; sync"); - return value; -} - -#endif // PCI_BUS_MANAGER_PPC_IO_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.cpp deleted file mode 100644 index 0f00491f32..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include "pci_u-boot.h" - -#include -#include - -#include - -//#include -//#include -//#include - - -status_t -ppc_uboot_pci_controller_init(void) -{ - return B_ERROR; -} - - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.h b/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.h deleted file mode 100644 index 07a6a71916..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2012, François Revol . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_PPC_U_BOOT_H -#define PCI_BUS_MANAGER_PPC_U_BOOT_H - -#include - -status_t ppc_uboot_pci_controller_init(void); - -#endif // PCI_BUS_MANAGER_PPC_U_BOOT_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/Jamfile deleted file mode 100644 index d9b7d5fbc4..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/Jamfile +++ /dev/null @@ -1,20 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch $(TARGET_ARCH) ; - -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; -UsePrivateKernelHeaders ; -UsePrivateHeaders shared ; -UsePrivateHeaders [ FDirName kernel util ] ; - -SEARCH_SOURCE += [ FDirName $(SUBDIR) fu740 ] ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) ecam ] ; - -KernelStaticLibrary pci_arch_bus_manager : - arch_pci_controller.cpp - pci_io.cpp - - # SiFive fu740 - pci_fu740.cpp - - # ECAM - pci_ecam.cpp -; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/arch_pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/arch_pci_controller.cpp deleted file mode 100644 index 2a1c191584..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/arch_pci_controller.cpp +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright 2021, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * x512 - * Alexander von Gluck IV - */ - - -#include "arch_pci_controller.h" - -#include "fu740/pci_fu740.h" -#include "ecam/pci_ecam.h" - - -extern PCI* gPCI; -ArchPCIController* gArchPCI = NULL; - - -ArchPCIController::ArchPCIController() - : - fMsiPhysAddr(0), - fMsiStartIrq(0), - fMsiData(0), - fHostCtrlType(0), - fConfigPhysBase(0), - fConfigBase(0), - fConfigSize(0), - fDbiPhysBase(0), - fDbiBase(0), - fDbiSize(0), - fIoBase(0), - fInterruptMapLen(0) -{ - fAllocatedMsiIrqs[0] = 0; -} - - -ArchPCIController::~ArchPCIController() -{ -} - - -uint32_t -ArchPCIController::EncodePciAddress(uint8 bus, uint8 device, uint8 function) -{ - return bus % (1 << 8) * (1 << 16) - + device % (1 << 5) * (1 << 11) - + function % (1 << 3) * (1 << 8); -} - - -void -ArchPCIController::DecodePciAddress(uint32_t adr, uint8& bus, uint8& device, uint8& function) -{ - bus = adr / (1 << 16) % (1 << 8); - device = adr / (1 << 11) % (1 << 5); - function = adr / (1 << 8) % (1 << 3); -} - - -volatile PciDbiRegs* -ArchPCIController::GetDbuRegs() -{ - if (fDbiBase == 0) { - return NULL; - } - - return (PciDbiRegs*)fDbiBase; -} - - -RegisterRange* -ArchPCIController::GetRegisterRange(int kind) -{ - if (kind > 3) - return NULL; - - return &fRegisterRanges[kind]; -} - - -void -ArchPCIController::SetRegisterRange(int kind, phys_addr_t parentBase, phys_addr_t childBase, - size_t size) -{ - auto& range = fRegisterRanges[kind]; - - range.parentBase = parentBase; - range.childBase = childBase; - range.size = size; - // Avoid allocating zero address. - range.free = (childBase != 0) ? childBase : 1; -} - - -phys_addr_t -ArchPCIController::AllocRegister(int kind, size_t size) -{ - auto& range = fRegisterRanges[kind]; - - phys_addr_t adr = ROUNDUP(range.free, size); - if (adr - range.childBase + size > range.size) - return 0; - - range.free = adr + size; - - return adr; -} - - -InterruptMap* -ArchPCIController::LookupInterruptMap(uint32_t childAdr, uint32_t childIrq) -{ - childAdr &= fInterruptMapMask.childAdr; - childIrq &= fInterruptMapMask.childIrq; - for (uint32 i = 0; i < fInterruptMapLen; i++) { - if ((fInterruptMap[i].childAdr) == childAdr - && (fInterruptMap[i].childIrq) == childIrq) - return &fInterruptMap[i]; - } - return NULL; -} - - -void -ArchPCIController::AllocRegs() -{ - dprintf("AllocRegs()\n"); - // TODO: improve enumeration - for (int j = 0; j < 8; j++) { - for (int i = 0; i < 32; i++) { - uint32 vendorID; - status_t res = ReadConfig(NULL, j, i, 0, PCI_vendor_id, 2, &vendorID); - if (res >= B_OK && vendorID != 0xffff) { - uint32 headerType = 0; - ReadConfig(NULL, j, i, 0, - PCI_header_type, 1, &headerType); - if ((headerType & 0x80) != 0) { - for (int k = 0; k < 8; k++) - AllocRegsForDevice(j, i, k); - } else - AllocRegsForDevice(j, i, 0); - } - } - } -} - - -status_t -ArchPCIController::ReadConfig(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - addr_t address = ConfigAddress(bus, device, function, offset); - if (address == 0) - return B_ERROR; - - switch (size) { - case 1: - *value = *(uint8*)address; - break; - case 2: - *value = *(uint16*)address; - break; - case 4: - *value = *(uint32*)address; - break; - default: - return B_ERROR; - } - return B_OK; -} - - -status_t -ArchPCIController::WriteConfig(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value) -{ - addr_t address = ConfigAddress(bus, device, function, offset); - - if (address == 0) - return B_ERROR; - - switch (size) { - case 1: - *(uint8*)address = value; - break; - case 2: - *(uint16*)address = value; - break; - case 4: - *(uint32*)address = value; - break; - default: - return B_ERROR; - } - - return B_OK; -} - - - -void -ArchPCIController::AllocRegsForDevice(uint8 bus, uint8 device, uint8 function) -{ - dprintf("AllocRegsForDevice(bus: %d, device: %d, function: %d)\n", bus, - device, function); - - bool allocBars = AllocateBar(); - - status_t result = B_OK; - - // TODO: Better error checking on all ReadConfig / WriteConfig calls - - uint32 vendorID = 0; - uint32 deviceID = 0; - - result = ReadConfig(NULL, bus, device, function, PCI_vendor_id, 2, &vendorID); - if (result != B_OK) - dprintf("Error: unable to read vendorID!\n"); - else - dprintf(" vendorID: %#04" B_PRIx32 "\n", vendorID); - - result = ReadConfig(NULL, bus, device, function, PCI_device_id, 2, &deviceID); - if (result != B_OK) - dprintf("Error: unable to read deviceID!\n"); - else - dprintf(" deviceID: %#04" B_PRIx32 "\n", deviceID); - - uint32 headerType = 0; - result = ReadConfig(NULL, bus, device, function, PCI_header_type, 1, &headerType); - if (result != B_OK) - dprintf("Error: unable to read header type!\n"); - else { - headerType = headerType % 0x80; - dprintf(" headerType: "); - switch (headerType) { - case PCI_header_type_generic: - dprintf("generic"); - break; - case PCI_header_type_PCI_to_PCI_bridge: - dprintf("bridge"); - break; - case PCI_header_type_cardbus: - dprintf("cardbus"); - break; - default: - dprintf("?(%u)", headerType); - } - dprintf("\n"); - } - - if (headerType == PCI_header_type_PCI_to_PCI_bridge) { - uint32 primaryBus; - uint32 secondaryBus; - uint32 subordinateBus; - - result = ReadConfig(NULL, bus, device, function, PCI_primary_bus, 1, &primaryBus); - if (result != B_OK) - dprintf("Error: Unable to read primaryBus!\n"); - else - dprintf(" primaryBus: %u\n", primaryBus); - - result = ReadConfig(NULL, bus, device, function, PCI_secondary_bus, 1, &secondaryBus); - if (result != B_OK) - dprintf("Error: Unable to read secondaryBus!\n"); - else - dprintf(" secondaryBus: %u\n", secondaryBus); - - result = ReadConfig(NULL, bus, device, function, PCI_subordinate_bus, 1, &subordinateBus); - if (result != B_OK) - dprintf("Error: Unable to read subordinateBus!\n"); - else - dprintf(" subordinateBus: %u\n", subordinateBus); - } - - uint32 oldValLo = 0; - uint32 oldValHi = 0; - uint32 sizeLo = 0; - uint32 sizeHi = 0; - uint64 val; - uint64 size; - - for (int i = 0; i < ((headerType == PCI_header_type_PCI_to_PCI_bridge) ? 2 : 6); i++) { - - dprintf(" bar[%d]: ", i); - - ReadConfig(NULL, bus, device, function, PCI_base_registers + i*4, 4, &oldValLo); - - int regKind; - if (oldValLo % 2 == 1) { - regKind = kRegIo; - dprintf("IOPORT"); - } else if (oldValLo / 2 % 4 == 0) { - regKind = kRegMmio32; - dprintf("MMIO32"); - } else if (oldValLo / 2 % 4 == 2) { - regKind = kRegMmio64; - dprintf("MMIO64"); - } else { - dprintf("?(%d)", oldValLo / 2 % 4); - dprintf("\n"); - continue; - } - - ReadConfig(NULL, bus, device, function, PCI_base_registers + i*4, 4, &oldValLo); - WriteConfig(NULL, bus, device, function, PCI_base_registers + i*4, 4, 0xffffffff); - ReadConfig(NULL, bus, device, function, PCI_base_registers + i*4, 4, &sizeLo); - WriteConfig(NULL, bus, device, function, PCI_base_registers + i*4, 4, oldValLo); - - val = oldValLo; - size = sizeLo; - if (regKind == kRegMmio64) { - ReadConfig(NULL, bus, device, function, PCI_base_registers + (i + 1)*4, 4, - &oldValHi); - WriteConfig(NULL, bus, device, function, PCI_base_registers + (i + 1)*4, 4, - 0xffffffff); - ReadConfig(NULL, bus, device, function, PCI_base_registers + (i + 1)*4, 4, - &sizeHi); - WriteConfig(NULL, bus, device, function, PCI_base_registers + (i + 1)*4, 4, - oldValHi); - val += ((uint64)oldValHi) << 32; - size += ((uint64)sizeHi ) << 32; - } else { - if (sizeLo != 0) - size += ((uint64)0xffffffff) << 32; - } - val &= ~(uint64)0xf; - size = ~(size & ~(uint64)0xf) + 1; -/* - dprintf(", oldValLo: 0x%" B_PRIx32 ", sizeLo: 0x%" B_PRIx32, oldValLo, - sizeLo); - if (regKind == regMmio64) { - dprintf(", oldValHi: 0x%" B_PRIx32 ", sizeHi: 0x%" B_PRIx32, - oldValHi, sizeHi); - } -*/ - dprintf(", adr: 0x%" B_PRIx64 ", size: 0x%" B_PRIx64, val, size); - - if (allocBars && /*val == 0 &&*/ size != 0) { - if (regKind == kRegMmio64) { - val = AllocRegister(regKind, size); - WriteConfig(NULL, bus, device, function, - PCI_base_registers + (i + 0)*4, 4, (uint32)val); - WriteConfig(NULL, bus, device, function, - PCI_base_registers + (i + 1)*4, 4, - (uint32)(val >> 32)); - dprintf(" -> 0x%" B_PRIx64, val); - } else { - val = AllocRegister(regKind, size); - WriteConfig(NULL, bus, device, function, - PCI_base_registers + i*4, 4, (uint32)val); - dprintf(" -> 0x%" B_PRIx64, val); - } - } - - dprintf("\n"); - - if (regKind == kRegMmio64) - i++; - } - - // ROM - dprintf(" rom_bar: "); - uint32 romBaseOfs = (headerType == PCI_header_type_PCI_to_PCI_bridge) ? PCI_bridge_rom_base : PCI_rom_base; - ReadConfig(NULL, bus, device, function, romBaseOfs, 4, &oldValLo); - WriteConfig(NULL, bus, device, function, romBaseOfs, 4, 0xfffffffe); - ReadConfig(NULL, bus, device, function, romBaseOfs, 4, &sizeLo); - WriteConfig(NULL, bus, device, function, romBaseOfs, 4, oldValLo); - - val = oldValLo & PCI_rom_address_mask; - size = ~(sizeLo & ~(uint32)0xf) + 1; - dprintf("adr: 0x%" B_PRIx64 ", size: 0x%" B_PRIx64, val, size); - if (allocBars && /*val == 0 &&*/ size != 0) { - val = AllocRegister(kRegMmio32, size); - WriteConfig(NULL, bus, device, function, - PCI_rom_base, 4, (uint32)val); - dprintf(" -> 0x%" B_PRIx64, val); - } - dprintf("\n"); - - uint32 intPin = 0; - result = ReadConfig(NULL, bus, device, function, PCI_interrupt_pin, 1, &intPin); - - if (result != B_OK) - dprintf("Error: Unable to read interrupt pin!\n"); - - InterruptMap* intMap = LookupInterruptMap(EncodePciAddress(bus, device, function), intPin); - if (intMap == NULL) { - dprintf("no interrupt mapping for childAdr: (%d:%d:%d), childIrq: %d)\n", bus, - device, function, intPin); - } else { - WriteConfig(NULL, bus, device, function, PCI_interrupt_line, - 1, intMap->parentIrq); - } - - InitDeviceMSI(bus, device, function); - - uint32 intLine; - result = ReadConfig(NULL, bus, device, function, PCI_interrupt_line, 1, &intLine); - if (result != B_OK) - dprintf("Error: Unable to read PCI interrupt line!\n"); - else { - dprintf(" intLine: %u\n", intLine); - dprintf(" intPin: "); - } - - switch (intPin) { - case 0: - dprintf("-"); - break; - case 1: - dprintf("INTA#"); - break; - case 2: - dprintf("INTB#"); - break; - case 3: - dprintf("INTC#"); - break; - case 4: - dprintf("INTD#"); - break; - default: - dprintf("?(%u)", intPin); - break; - } - dprintf("\n"); -} - - -static status_t -read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - if (gArchPCI == NULL) - return B_ERROR; - - // PciConfigAdr may use sliding window - // TODO: SMP - InterruptsLocker locker; - - return gArchPCI->ReadConfig(cookie, bus, device, function, offset, size, value); -} - - -static status_t -write_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value) -{ - if (gArchPCI == NULL) - return B_ERROR; - - // PciConfigAdr may use sliding window - // TODO: SMP - InterruptsLocker locker; -/* - dprintf("write_pci_config(%d:%d:%d, 0x%04x, %d, 0x%08x)\n", bus, device, - function, offset, size, value); -*/ - return gArchPCI->WriteConfig(cookie, bus, device, function, offset, size, value); -} - - -static status_t -get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 32; - return B_OK; -} - - -status_t -read_pci_irq(void *cookie, uint8 bus, uint8 device, uint8 function, uint8 pin, - uint8 *irq) -{ - return B_NOT_SUPPORTED; -} - - -status_t -write_pci_irq(void *cookie, uint8 bus, uint8 device, uint8 function, uint8 pin, - uint8 irq) -{ - return B_NOT_SUPPORTED; -} - - -pci_controller pci_controller_riscv64 = -{ - read_pci_config, - write_pci_config, - get_max_bus_devices, - read_pci_irq, - write_pci_irq, -}; - - -//#pragma mark - - - -status_t -pci_controller_init() -{ - dprintf("pci_controller_init()\n"); - - dprintf("sizeof(PciDbi): %#" B_PRIxSIZE "\n", sizeof(PciDbiRegs)); - - if (gPCIRootNode == NULL) - return B_OK; - - DeviceNodePutter<&gDeviceManager> parent( - gDeviceManager->get_parent_node(gPCIRootNode)); - - const char* compatible; - if (gDeviceManager->get_attr_string(parent.Get(), "fdt/compatible", &compatible, - false) < B_OK) - return B_ERROR; - - dprintf("hostCtrlType: "); - if (strcmp(compatible, "pci-host-ecam-generic") == 0) { - static char buffer[sizeof(PCIEcam)]; - gArchPCI = new(buffer) PCIEcam(); - dprintf("ecam\n"); - } else if (strcmp(compatible, "sifive,fu740-pcie") == 0) { - static char buffer[sizeof(PCIFU740)]; - gArchPCI = new(buffer) PCIFU740(); - dprintf("sifive\n"); - } else { - dprintf("unknown\n"); - return B_ERROR; - } - - if (gArchPCI == NULL) - return B_ERROR; - - status_t result = B_ERROR; - - // Init our detected PCI bus - - result = gArchPCI->Init(gPCIRootNode); - if (result != B_OK) - return result; - - return pci_controller_add(&pci_controller_riscv64, NULL); -} - - -phys_addr_t -pci_ram_address(phys_addr_t childAdr) -{ - // dprintf("pci_ram_address(0x%" B_PRIxPHYSADDR "): ", childAdr); - phys_addr_t parentAdr = 0; - for (int kind = kRegIo; kind <= kRegMmio64; kind++) { - auto range = gArchPCI->GetRegisterRange(kind); - if (range == NULL) { - dprintf("%s: Invalid register range %d!\n", __func__, kind); - return 0; - } - if (childAdr >= range->childBase - && childAdr < range->childBase + range->size) { - parentAdr = childAdr - range->childBase; - if (kind != kRegIo) - parentAdr += range->parentBase; - // dprintf("0x%" B_PRIxPHYSADDR "\n", parentAdr); - return parentAdr; - } - } - // dprintf("?\n"); - return 0; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/arch_pci_controller.h b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/arch_pci_controller.h deleted file mode 100644 index 431768173f..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/arch_pci_controller.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2021, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * x512 - * Alexander von Gluck IV - */ -#ifndef _ARCH_PCI_CONTROLLER_H_ -#define _ARCH_PCI_CONTROLLER_H_ - - -#include "pci_controller_private.h" -#include "pci_controller.h" -#include "pci_private.h" -#include "pci.h" - -#include -#include -#include -#include - - -enum { - kRegIo, - kRegMmio32, - kRegMmio64, -}; - -struct RegisterRange { - phys_addr_t parentBase; - phys_addr_t childBase; - size_t size; - phys_addr_t free; -}; - - -struct InterruptMapMask { - uint32_t childAdr; - uint32_t childIrq; -}; - -struct InterruptMap { - uint32_t childAdr; - uint32_t childIrq; - uint32_t parentIrqCtrl; - uint32_t parentIrq; -}; - - - -class ArchPCIController { -public: - ArchPCIController(); -virtual ~ArchPCIController(); - -// Implementation Specific -virtual status_t Init(device_node* pciRootNode) = 0; - -virtual status_t InitMSI(int32 irq) = 0; -virtual int32 AllocateMSIIrq() = 0; -virtual void FreeMSIIrq(int32 irq) = 0; -virtual void InitDeviceMSI(uint8 bus, uint8 device, uint8 function) = 0; -virtual int32 HandleMSIIrq(void* arg) = 0; - -virtual addr_t ConfigAddress(uint8 bus, uint8 device, uint8 function, - uint16 offset) = 0; -virtual bool AllocateBar() = 0; - -// Generic Helpers - uint32_t EncodePciAddress(uint8 bus, uint8 device, uint8 function); - void DecodePciAddress(uint32_t adr, uint8& bus, uint8& device, - uint8& function); - - addr_t GetIoRegs() { return fIoBase; }; - volatile PciDbiRegs* GetDbuRegs(); - - RegisterRange* GetRegisterRange(int range); - void SetRegisterRange(int kind, phys_addr_t parentBase, - phys_addr_t childBase, size_t size); - - phys_addr_t AllocRegister(int kind, size_t size); - void AllocRegsForDevice(uint8 bus, uint8 device, uint8 function); - - InterruptMap* LookupInterruptMap(uint32_t childAdr, uint32_t childIrq); - void AllocRegs(); - - status_t ReadConfig(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value); - status_t WriteConfig(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value); - -protected: - uint32 fAllocatedMsiIrqs[1]; - phys_addr_t fMsiPhysAddr; - long fMsiStartIrq; - uint64 fMsiData; - - RegisterRange fRegisterRanges[3]; - InterruptMapMask fInterruptMapMask; - - uint32 fHostCtrlType; - - AreaDeleter fConfigArea; - addr_t fConfigPhysBase; - addr_t fConfigBase; - size_t fConfigSize; - - AreaDeleter fDbiArea; - addr_t fDbiPhysBase; - addr_t fDbiBase; - size_t fDbiSize; - - AreaDeleter fIoArea; - addr_t fIoBase; - - ArrayDeleter fInterruptMap; - uint32_t fInterruptMapLen; -}; - - -#endif /* _ARCH_PCI_CONTROLLER_H_ */ diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/ecam/pci_ecam.cpp b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/ecam/pci_ecam.cpp deleted file mode 100644 index 79d99b4f2a..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/ecam/pci_ecam.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2021, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * x512 - * Alexander von Gluck IV - */ - - -#include "pci_ecam.h" - - -status_t -PCIEcam::InitMSI(int32 irq) -{ - // No MSI on Ecam? - return B_ERROR; -} - - -int32 -PCIEcam::AllocateMSIIrq() -{ - return B_ERROR; -} - - -void -PCIEcam::FreeMSIIrq(int32 irq) -{ -} - - -int32 -PCIEcam::HandleMSIIrq(void* arg) -{ - return B_UNHANDLED_INTERRUPT; -} - - -status_t -PCIEcam::Init(device_node* pciRootNode) -{ - fdt_device_module_info* parentModule; - fdt_device* parentDev; - - DeviceNodePutter<&gDeviceManager> parent( - gDeviceManager->get_parent_node(gPCIRootNode)); - - if (gDeviceManager->get_driver(parent.Get(), - (driver_module_info**)&parentModule, (void**)&parentDev)) - panic("can't get parent node driver"); - - uint64 regs; - uint64 regsLen; - - for (uint32 i = 0; parentModule->get_reg(parentDev, i, ®s, ®sLen); - i++) { - dprintf(" reg[%" B_PRIu32 "]: (0x%" B_PRIx64 ", 0x%" B_PRIx64 ")\n", - i, regs, regsLen); - } - - uint64 configRegs = 0; - uint64 configRegsLen = 0; - - if (!parentModule->get_reg(parentDev, 0, &configRegs, &configRegsLen)) { - dprintf(" no regs\n"); - return B_ERROR; - } - - dprintf(" configRegs: (0x%" B_PRIx64 ", 0x%" B_PRIx64 ")\n", - configRegs, configRegsLen); - - int intMapLen; - const void* intMapAdr = parentModule->get_prop(parentDev, "interrupt-map", - &intMapLen); - if (intMapAdr == NULL) { - dprintf(" \"interrupt-map\" property not found"); - return B_ERROR; - } else { - int intMapMaskLen; - const void* intMapMask = parentModule->get_prop(parentDev, "interrupt-map-mask", - &intMapMaskLen); - - if (intMapMask == NULL || intMapMaskLen != 4 * 4) { - dprintf(" \"interrupt-map-mask\" property not found or invalid"); - return B_ERROR; - } - - fInterruptMapMask.childAdr = B_BENDIAN_TO_HOST_INT32(*((uint32*)intMapMask + 0)); - fInterruptMapMask.childIrq = B_BENDIAN_TO_HOST_INT32(*((uint32*)intMapMask + 3)); - - fInterruptMapLen = (uint32)intMapLen / (6 * 4); - fInterruptMap.SetTo(new(std::nothrow) InterruptMap[fInterruptMapLen]); - if (!fInterruptMap.IsSet()) - return B_NO_MEMORY; - - for (uint32_t *it = (uint32_t*)intMapAdr; - (uint8_t*)it - (uint8_t*)intMapAdr < intMapLen; it += 6) { - size_t i = (it - (uint32_t*)intMapAdr) / 6; - - fInterruptMap[i].childAdr = B_BENDIAN_TO_HOST_INT32(*(it + 0)); - fInterruptMap[i].childIrq = B_BENDIAN_TO_HOST_INT32(*(it + 3)); - fInterruptMap[i].parentIrqCtrl = B_BENDIAN_TO_HOST_INT32(*(it + 4)); - fInterruptMap[i].parentIrq = B_BENDIAN_TO_HOST_INT32(*(it + 5)); - } - - dprintf(" interrupt-map:\n"); - for (size_t i = 0; i < fInterruptMapLen; i++) { - dprintf(" "); - // child unit address - uint8 bus, device, function; - DecodePciAddress(fInterruptMap[i].childAdr, bus, device, function); - dprintf("bus: %" B_PRIu32, bus); - dprintf(", dev: %" B_PRIu32, device); - dprintf(", fn: %" B_PRIu32, function); - - dprintf(", childIrq: %" B_PRIu32, - fInterruptMap[i].childIrq); - dprintf(", parentIrq: (%" B_PRIu32, - fInterruptMap[i].parentIrqCtrl); - dprintf(", %" B_PRIu32, fInterruptMap[i].parentIrq); - dprintf(")\n"); - if (i % 4 == 3 && (i + 1 < fInterruptMapLen)) - dprintf("\n"); - } - } - - memset(fRegisterRanges, 0, sizeof(fRegisterRanges)); - int rangesLen; - const void* rangesAdr = parentModule->get_prop(parentDev, "ranges", - &rangesLen); - if (rangesAdr == NULL) { - dprintf(" \"ranges\" property not found"); - } else { - dprintf(" ranges:\n"); - for (uint32_t *it = (uint32_t*)rangesAdr; - (uint8_t*)it - (uint8_t*)rangesAdr < rangesLen; it += 7) { - dprintf(" "); - uint32_t kind = B_BENDIAN_TO_HOST_INT32(*(it + 0)); - uint64_t childAdr = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 1)); - uint64_t parentAdr = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 3)); - uint64_t len = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 5)); - - switch (kind & 0x03000000) { - case 0x01000000: - SetRegisterRange(kRegIo, parentAdr, childAdr, len); - break; - case 0x02000000: - SetRegisterRange(kRegMmio32, parentAdr, childAdr, len); - break; - case 0x03000000: - SetRegisterRange(kRegMmio64, parentAdr, childAdr, len); - break; - } - - switch (kind & 0x03000000) { - case 0x00000000: dprintf("CONFIG"); break; - case 0x01000000: dprintf("IOPORT"); break; - case 0x02000000: dprintf("MMIO32"); break; - case 0x03000000: dprintf("MMIO64"); break; - } - - dprintf(" (0x%08" B_PRIx32 "): ", kind); - dprintf("child: %08" B_PRIx64, childAdr); - dprintf(", parent: %08" B_PRIx64, parentAdr); - dprintf(", len: %" B_PRIx64 "\n", len); - } - } - - fConfigPhysBase = configRegs; - fConfigSize = configRegsLen; - fConfigArea.SetTo(map_physical_memory( - "PCI Config MMIO", - configRegs, fConfigSize, B_ANY_KERNEL_ADDRESS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, - (void**)&fConfigBase - )); - - fIoArea.SetTo(map_physical_memory( - "PCI IO", - fRegisterRanges[kRegIo].parentBase, - fRegisterRanges[kRegIo].size, - B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, - (void**)&fIoBase - )); - - if (!fConfigArea.IsSet()) { - dprintf(" can't map Config MMIO\n"); - return fConfigArea.Get(); - } - - if (!fIoArea.IsSet()) { - dprintf(" can't map IO\n"); - return fIoArea.Get(); - } - - InitMSI(-1); - - AllocRegs(); - - return B_OK; -} - - -addr_t -PCIEcam::ConfigAddress(uint8 bus, uint8 device, uint8 function, uint16 offset) -{ - addr_t address = fConfigBase + EncodePciAddress(bus, device, function) * (1 << 4) + offset; - - if (address < fConfigBase || address /*+ size*/ > fConfigBase + fConfigSize) - return 0; - - return address; -} - - -void -PCIEcam::InitDeviceMSI(uint8 bus, uint8 device, uint8 function) -{ -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/ecam/pci_ecam.h b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/ecam/pci_ecam.h deleted file mode 100644 index cd337b0dcb..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/ecam/pci_ecam.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2009-2020, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "arch_pci_controller.h" - - -class PCIEcam : public ArchPCIController { - - status_t Init(device_node* pciRootNode); - - status_t InitMSI(int32 irq); - int32 AllocateMSIIrq(); - void FreeMSIIrq(int32 irq); - int32 HandleMSIIrq(void* arg); - - addr_t ConfigAddress(uint8 bus, uint8 device, uint8 function, uint16 offset); - void InitDeviceMSI(uint8 bus, uint8 device, uint8 function); - bool AllocateBar() { return true; } -}; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.cpp b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.cpp deleted file mode 100644 index 1108668c79..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright 2021, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * x512 - * Alexander von Gluck IV - */ - - -#include "pci_fu740.h" - - -extern ArchPCIController* gArchPCI; - - -static int32 -msi_interrupt_handler(void* arg) -{ - if (gArchPCI == NULL) { - dprintf(" irq on unconfigured PCI bus!\n"); - return B_ERROR; - } - - return gArchPCI->HandleMSIIrq(arg); -} - - -int32 -PCIFU740::HandleMSIIrq(void* arg) -{ -// dprintf("MsiInterruptHandler()\n"); - uint32 status = GetDbuRegs()->msiIntr[0].status; - for (int i = 0; i < 32; i++) { - if (((1 << i) & status) != 0) { -// dprintf("MSI IRQ: %d (%ld)\n", i, gStartMsiIrq + i); - int_io_interrupt_handler(fMsiStartIrq + i, false); - GetDbuRegs()->msiIntr[0].status = (1 << i); - } - } - return B_HANDLED_INTERRUPT; -} - - -status_t -PCIFU740::InitMSI(int32 msiIrq) -{ - dprintf("InitPciMsi()\n"); - dprintf(" msiIrq: %" B_PRId32 "\n", msiIrq); - - physical_entry pe; - status_t result = get_memory_map(&fMsiData, sizeof(fMsiData), &pe, 1); - if (result != B_OK) { - dprintf(" unable to get MSI Memory map!\n"); - return result; - } - - fMsiPhysAddr = pe.address; - dprintf(" fMsiPhysAddr: %#" B_PRIxADDR "\n", fMsiPhysAddr); - GetDbuRegs()->msiAddrLo = (uint32)fMsiPhysAddr; - GetDbuRegs()->msiAddrHi = (uint32)(fMsiPhysAddr >> 32); - - GetDbuRegs()->msiIntr[0].enable = 0xffffffff; - GetDbuRegs()->msiIntr[0].mask = 0xffffffff; - - result = install_io_interrupt_handler(msiIrq, msi_interrupt_handler, NULL, 0); - if (result != B_OK) { - dprintf(" unable to attach MSI irq handler!\n"); - return result; - } - result = allocate_io_interrupt_vectors(32, &fMsiStartIrq, INTERRUPT_TYPE_IRQ); - - if (result != B_OK) { - dprintf(" unable to attach MSI irq handler!\n"); - return result; - } - - msi_set_interface(static_cast(this)); - - dprintf(" fMsiStartIrq: %ld\n", fMsiStartIrq); - - return B_OK; -} - - -status_t -PCIFU740::AllocateVectors(uint8 count, uint8& startVector, uint64& address, uint16& data) -{ - if (count != 1) - return B_ERROR; - - for (int i = 0; i < 32; i++) { - if (((1 << i) & fAllocatedMsiIrqs[0]) == 0) { - fAllocatedMsiIrqs[0] |= (1 << i); - GetDbuRegs()->msiIntr[0].mask &= ~(1 << i); - - startVector = fMsiStartIrq + i; - address = fMsiPhysAddr; - data = i; - return B_OK; - } - } - return B_ERROR; -} - - -void -PCIFU740::FreeVectors(uint8 count, uint8 startVector) -{ - int32 irq = (int32)startVector - fMsiStartIrq; - while (count > 0) { - if (irq >= 0 && irq < 32 && ((1 << irq) & fAllocatedMsiIrqs[0]) != 0) { - GetDbuRegs()->msiIntr[0].mask |= (1 << (uint32)irq); - fAllocatedMsiIrqs[0] &= ~(1 << (uint32)irq); - } - irq++; - count--; - } -} - - -status_t -PCIFU740::AtuMap(uint32 index, uint32 direction, uint32 type, uint64 parentAdr, uint64 childAdr, - uint32 size) -{ - /* - dprintf("AtuMap(%" B_PRIu32 ", %" B_PRIu32 ", %#" B_PRIx64 ", %#" B_PRIx64 ", " - "%#" B_PRIx32 ")\n", index, type, parentAdr, childAdr, size); - */ - volatile PciAtuRegs* atu = (PciAtuRegs*)(fDbiBase + kPciAtuOffset + (2*index + direction)*sizeof(PciAtuRegs)); - atu->baseLo = (uint32)parentAdr; - atu->baseHi = (uint32)(parentAdr >> 32); - atu->limit = (uint32)(parentAdr + size - 1); - atu->targetLo = (uint32)childAdr; - atu->targetHi = (uint32)(childAdr >> 32); - atu->ctrl1 = type; - atu->ctrl2 = kPciAtuEnable; - - for (;;) { - if ((atu->ctrl2 & kPciAtuEnable) != 0) - break; - } - - return B_OK; -} - - -void -PCIFU740::AtuDump() -{ - dprintf("ATU:\n"); - for (uint32 direction = 0; direction < 2; direction++) { - switch (direction) { - case kPciAtuOutbound: - dprintf(" outbound:\n"); - break; - case kPciAtuInbound: - dprintf(" inbound:\n"); - break; - } - - for (uint32 index = 0; index < 8; index++) { - volatile PciAtuRegs* atu = (PciAtuRegs*)(fDbiBase - + kPciAtuOffset + (2 * index + direction) * sizeof(PciAtuRegs)); - - dprintf(" %" B_PRIu32 ": ", index); - dprintf("base: %#08" B_PRIx64, atu->baseLo + ((uint64)atu->baseHi << 32)); - dprintf(", limit: %#08" B_PRIx32, atu->limit); - dprintf(", target: %#08" B_PRIx64, atu->targetLo - + ((uint64)atu->targetHi << 32)); - dprintf(", ctrl1: "); - uint32 ctrl1 = atu->ctrl1; - switch (ctrl1) { - case kPciAtuTypeMem: - dprintf("mem"); - break; - case kPciAtuTypeIo: - dprintf("io"); - break; - case kPciAtuTypeCfg0: - dprintf("cfg0"); - break; - case kPciAtuTypeCfg1: - dprintf("cfg1"); - break; - default: - dprintf("? (%#" B_PRIx32 ")", ctrl1); - } - dprintf(", ctrl2: {"); - uint32 ctrl2 = atu->ctrl2; - bool first = true; - for (uint32 i = 0; i < 32; i++) { - if (((1 << i) & ctrl2) != 0) { - if (first) - first = false; - else - dprintf(", "); - switch (i) { - case 30: - dprintf("barModeEnable"); - break; - case 31: - dprintf("enable"); - break; - default: - dprintf("? (%" B_PRIu32 ")", i); - break; - } - } - } - dprintf("}\n"); - } - } -} - - - - -status_t -PCIFU740::Init(device_node* pciRootNode) -{ - fdt_device* parentDev; - fdt_device_module_info* parentModule; - - DeviceNodePutter<&gDeviceManager> parent( - gDeviceManager->get_parent_node(gPCIRootNode)); - - if (gDeviceManager->get_driver(parent.Get(), - (driver_module_info**)&parentModule, (void**)&parentDev)) - panic("can't get parent node driver"); - - uint64 regs; - uint64 regsLen; - - for (uint32 i = 0; parentModule->get_reg(parentDev, i, ®s, ®sLen); - i++) { - dprintf(" reg[%" B_PRIu32 "]: (0x%" B_PRIx64 ", 0x%" B_PRIx64 ")\n", - i, regs, regsLen); - } - - uint64 configRegs = 0; - uint64 configRegsLen = 0; - uint64 dbiRegs = 0; - uint64 dbiRegsLen = 0; - if (!parentModule->get_reg(parentDev, 0, &dbiRegs, &dbiRegsLen) - || !parentModule->get_reg(parentDev, 1, &configRegs, &configRegsLen)) { - dprintf(" no regs\n"); - return B_ERROR; - } -/* - // !!! - configRegs = 0x60070000; - configRegsLen = 0x10000; -*/ - - dprintf(" configRegs: (0x%" B_PRIx64 ", 0x%" B_PRIx64 ")\n", - configRegs, configRegsLen); - dprintf(" dbiRegs: (0x%" B_PRIx64 ", 0x%" B_PRIx64 ")\n", - dbiRegs, dbiRegsLen); - - int intMapLen; - const void* intMapAdr = parentModule->get_prop(parentDev, "interrupt-map", - &intMapLen); - if (intMapAdr == NULL) { - dprintf(" \"interrupt-map\" property not found"); - return B_ERROR; - } else { - int intMapMaskLen; - const void* intMapMask = parentModule->get_prop(parentDev, "interrupt-map-mask", - &intMapMaskLen); - - if (intMapMask == NULL || intMapMaskLen != 4 * 4) { - dprintf(" \"interrupt-map-mask\" property not found or invalid"); - return B_ERROR; - } - - fInterruptMapMask.childAdr = B_BENDIAN_TO_HOST_INT32(*((uint32*)intMapMask + 0)); - fInterruptMapMask.childIrq = B_BENDIAN_TO_HOST_INT32(*((uint32*)intMapMask + 3)); - - fInterruptMapLen = (uint32)intMapLen / (6 * 4); - fInterruptMap.SetTo(new(std::nothrow) InterruptMap[fInterruptMapLen]); - if (!fInterruptMap.IsSet()) - return B_NO_MEMORY; - - for (uint32_t *it = (uint32_t*)intMapAdr; - (uint8_t*)it - (uint8_t*)intMapAdr < intMapLen; it += 6) { - size_t i = (it - (uint32_t*)intMapAdr) / 6; - - fInterruptMap[i].childAdr = B_BENDIAN_TO_HOST_INT32(*(it + 0)); - fInterruptMap[i].childIrq = B_BENDIAN_TO_HOST_INT32(*(it + 3)); - fInterruptMap[i].parentIrqCtrl = B_BENDIAN_TO_HOST_INT32(*(it + 4)); - fInterruptMap[i].parentIrq = B_BENDIAN_TO_HOST_INT32(*(it + 5)); - } - - dprintf(" interrupt-map:\n"); - for (size_t i = 0; i < fInterruptMapLen; i++) { - dprintf(" "); - // child unit address - uint8 bus, device, function; - DecodePciAddress(fInterruptMap[i].childAdr, bus, device, function); - dprintf("bus: %" B_PRIu32, bus); - dprintf(", dev: %" B_PRIu32, device); - dprintf(", fn: %" B_PRIu32, function); - - dprintf(", childIrq: %" B_PRIu32, - fInterruptMap[i].childIrq); - dprintf(", parentIrq: (%" B_PRIu32, - fInterruptMap[i].parentIrqCtrl); - dprintf(", %" B_PRIu32, fInterruptMap[i].parentIrq); - dprintf(")\n"); - if (i % 4 == 3 && (i + 1 < fInterruptMapLen)) - dprintf("\n"); - } - } - - memset(fRegisterRanges, 0, sizeof(fRegisterRanges)); - int rangesLen; - const void* rangesAdr = parentModule->get_prop(parentDev, "ranges", - &rangesLen); - if (rangesAdr == NULL) { - dprintf(" \"ranges\" property not found"); - } else { - dprintf(" ranges:\n"); - for (uint32_t *it = (uint32_t*)rangesAdr; - (uint8_t*)it - (uint8_t*)rangesAdr < rangesLen; it += 7) { - dprintf(" "); - uint32_t kind = B_BENDIAN_TO_HOST_INT32(*(it + 0)); - uint64_t childAdr = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 1)); - uint64_t parentAdr = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 3)); - uint64_t len = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 5)); - - switch (kind & 0x03000000) { - case 0x01000000: - SetRegisterRange(kRegIo, parentAdr, childAdr, len); - break; - case 0x02000000: - SetRegisterRange(kRegMmio32, parentAdr, childAdr, len); - break; - case 0x03000000: - SetRegisterRange(kRegMmio64, parentAdr, childAdr, len); - break; - } - - switch (kind & 0x03000000) { - case 0x00000000: dprintf("CONFIG"); break; - case 0x01000000: dprintf("IOPORT"); break; - case 0x02000000: dprintf("MMIO32"); break; - case 0x03000000: dprintf("MMIO64"); break; - } - - dprintf(" (0x%08" B_PRIx32 "): ", kind); - dprintf("child: %08" B_PRIx64, childAdr); - dprintf(", parent: %08" B_PRIx64, parentAdr); - dprintf(", len: %" B_PRIx64 "\n", len); - } - } - - fConfigPhysBase = configRegs; - fConfigSize = configRegsLen; - fConfigArea.SetTo(map_physical_memory("PCI Config MMIO", configRegs, - fConfigSize, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, - (void**)&fConfigBase)); - - if (dbiRegs != 0) { - fDbiPhysBase = dbiRegs; - fDbiSize = dbiRegsLen; - fDbiArea.SetTo(map_physical_memory("PCI DBI MMIO", dbiRegs, fDbiSize, - B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, - (void**)&fDbiBase)); - } - - fIoArea.SetTo(map_physical_memory("PCI IO", fRegisterRanges[kRegIo].parentBase, - fRegisterRanges[kRegIo].size, B_ANY_KERNEL_ADDRESS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&fIoBase)); - - if (!fConfigArea.IsSet()) { - dprintf(" can't map Config MMIO\n"); - return fConfigArea.Get(); - } - - if (!fIoArea.IsSet()) { - dprintf(" can't map IO\n"); - return fIoArea.Get(); - } - - AtuDump(); - - // TODO: Get from MSI! - InitMSI(0x38); - AllocRegs(); - - AtuDump(); - - return B_OK; -} - - -addr_t -PCIFU740::ConfigAddress(uint8 bus, uint8 device, uint8 function, uint16 offset) -{ - uint32 atuType; - if (bus == 0) { - if (device != 0 || function != 0) - return 0; - return fDbiBase + offset; - } else if (bus == 1) - atuType = kPciAtuTypeCfg0; - else - atuType = kPciAtuTypeCfg1; - - status_t res = AtuMap(1, kPciAtuOutbound, atuType, fConfigPhysBase, EncodePciAddress(bus, device, function) << 8, fConfigSize); - if (res < B_OK) - return 0; - - return fConfigBase + offset; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.h b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.h deleted file mode 100644 index bbbda2a352..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2009-2020, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "arch_pci_controller.h" -#include - - -enum { - kPciAtuOffset = 0x300000, -}; - -enum { - kPciAtuOutbound = 0, - kPciAtuInbound = 1, -}; - -enum { - // ctrl1 - kPciAtuTypeMem = 0, - kPciAtuTypeIo = 2, - kPciAtuTypeCfg0 = 4, - kPciAtuTypeCfg1 = 5, - // ctrl2 - kPciAtuBarModeEnable = 1 << 30, - kPciAtuEnable = 1 << 31, -}; - -struct PciAtuRegs { - uint32 ctrl1; - uint32 ctrl2; - uint32 baseLo; - uint32 baseHi; - uint32 limit; - uint32 targetLo; - uint32 targetHi; - uint32 unused[57]; -}; - - -struct PciDbiRegs { - uint8 unknown0[0x700]; - - uint32 unknown1[3]; - uint32 portAfr; - uint32 linkControl; - uint32 unknown2[5]; - uint32 portDebug0; - uint32 portDebug1; - uint32 unknown3[55]; - uint32 linkWidthSpeedControl; - uint32 unknown4[4]; - uint32 msiAddrLo; - uint32 msiAddrHi; - struct { - uint32 enable; - uint32 mask; - uint32 status; - } msiIntr[8]; - uint32 unknown5[13]; - uint32 miscControl1Off; - uint32 miscPortMultiLaneCtrl; - uint32 unknown6[15]; - - uint32 atuViewport; - uint32 atuCr1; - uint32 atuCr2; - uint32 atuBaseLo; - uint32 atuBaseHi; - uint32 atuLimit; - uint32 atuTargetLo; - uint32 atuTargetHi; - uint32 unknown7; - uint32 atuLimitHi; - uint32 unknown8[8]; - - uint32 msixDoorbell; - uint32 unknown9[117]; - - uint32 plChkRegControlStatus; - uint32 unknown10; - uint32 plChkRegErrAddr; - uint32 unknown11[309]; -}; - - -class PCIFU740 : public ArchPCIController, public MSIInterface { - - status_t Init(device_node* pciRootNode); - - PciDbiRegs volatile* GetDbuRegs() {return (PciDbiRegs volatile*)fDbiBase;} - - status_t InitMSI(int32 irq); - status_t AllocateVectors(uint8 count, uint8& startVector, uint64& address, - uint16& data) final; - void FreeVectors(uint8 count, uint8 startVector) final; - static int32 HandleMSIIrq(void* arg); - inline int32 HandleMSIIrqInt(); - - void EnableIoInterrupt(int irq) final; - void DisableIoInterrupt(int irq) final; - void ConfigureIoInterrupt(int irq, uint32 config) final; - int32 AssignToCpu(int32 irq, int32 cpu) final; - - addr_t ConfigAddress(uint8 bus, uint8 device, uint8 function, uint16 offset); - bool AllocateBar() { return false; } - -private: - status_t AtuMap(uint32 index, uint32 direction, uint32 type, - uint64 parentAdr, uint64 childAdr, uint32 size); - void AtuDump(); - -private: - AreaDeleter fDbiArea; - addr_t fDbiPhysBase{}; - addr_t fDbiBase{}; - size_t fDbiSize{}; -}; - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_controller_private.h b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_controller_private.h deleted file mode 100644 index 052874c73a..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_controller_private.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2021, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _PCI_CONTROLLER_PRIVATE_H_ -#define _PCI_CONTROLLER_PRIVATE_H_ - - -#include - - -struct PciDbiRegs { - uint8 unknown0[0x700]; - - uint32 unknown1[3]; - uint32 portAfr; - uint32 linkControl; - uint32 unknown2[5]; - uint32 portDebug0; - uint32 portDebug1; - uint32 unknown3[55]; - uint32 linkWidthSpeedControl; - uint32 unknown4[4]; - uint32 msiAddrLo; - uint32 msiAddrHi; - struct { - uint32 enable; - uint32 mask; - uint32 status; - } msiIntr[8]; - uint32 unknown5[13]; - uint32 miscControl1Off; - uint32 miscPortMultiLaneCtrl; - uint32 unknown6[15]; - - uint32 atuViewport; - uint32 atuCr1; - uint32 atuCr2; - uint32 atuBaseLo; - uint32 atuBaseHi; - uint32 atuLimit; - uint32 atuTargetLo; - uint32 atuTargetHi; - uint32 unknown7; - uint32 atuLimitHi; - uint32 unknown8[8]; - - uint32 msixDoorbell; - uint32 unknown9[117]; - - uint32 plChkRegControlStatus; - uint32 unknown10; - uint32 plChkRegErrAddr; - uint32 unknown11[309]; -}; - - -#endif // _PCI_CONTROLLER_PRIVATE_H_ diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_io.cpp b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_io.cpp deleted file mode 100644 index 8eb8ecd08a..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_io.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2009-2020, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "arch_pci_controller.h" -#include "pci_io.h" -#include "pci_private.h" - -#include - - -#undef TRACE - -//#define TRACE_PCI_IO -#ifdef TRACE_PCI_IO -# define TRACE(x...) fprintf("PCI_IO: " x) -#else -# define TRACE(x...) ; -#endif - - -extern ArchPCIController* gArchPCI; -addr_t gPCIeIoBase; - - -status_t -pci_io_init() -{ - TRACE("pci_io_init()\n"); - if (gArchPCI == NULL) - return B_ERROR; - - gPCIeIoBase = gArchPCI->GetIoRegs(); - return B_OK; -} - - -uint8 -pci_read_io_8(int mapped_io_addr) -{ - TRACE("pci_read_io_8(%d)\n", mapped_io_addr); - volatile uint8* ptr = (uint8*)(gPCIeIoBase + mapped_io_addr); - return *ptr; -} - - -void -pci_write_io_8(int mapped_io_addr, uint8 value) -{ - TRACE("pci_write_io_8(%d)\n", mapped_io_addr); - volatile uint8* ptr = (uint8*)(gPCIeIoBase + mapped_io_addr); - *ptr = value; -} - - -uint16 -pci_read_io_16(int mapped_io_addr) -{ - TRACE("pci_read_io_16(%d)\n", mapped_io_addr); - volatile uint16* ptr = (uint16*)(gPCIeIoBase + mapped_io_addr); - return *ptr; -} - - -void -pci_write_io_16(int mapped_io_addr, uint16 value) -{ - TRACE("pci_write_io_16(%d)\n", mapped_io_addr); - volatile uint16* ptr = (uint16*)(gPCIeIoBase + mapped_io_addr); - *ptr = value; -} - - -uint32 -pci_read_io_32(int mapped_io_addr) -{ - TRACE("pci_read_io_32(%d)\n", mapped_io_addr); - volatile uint32* ptr = (uint32*)(gPCIeIoBase + mapped_io_addr); - return *ptr; -} - - -void -pci_write_io_32(int mapped_io_addr, uint32 value) -{ - TRACE("pci_write_io_32(%d)\n", mapped_io_addr); - volatile uint32* ptr = (uint32*)(gPCIeIoBase + mapped_io_addr); - *ptr = value; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_io.h b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_io.h deleted file mode 100644 index 5fa319961b..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/pci_io.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2009-2020, Haiku Inc., All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_RISCV64_IO_H -#define PCI_BUS_MANAGER_RISCV64_IO_H - -#include - -#endif // PCI_BUS_MANAGER_RISCV64_IO_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/sparc/Jamfile deleted file mode 100644 index 8d0941693a..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/sparc/Jamfile +++ /dev/null @@ -1,16 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch sparc ; - -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] - [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; - -SEARCH_SOURCE += [ FDirName $(SUBDIR) openfirmware ] ; - -KernelStaticLibrary pci_arch_bus_manager : - pci_controller.cpp - pci_io.c - - # openfirmware - pci_openfirmware.cpp -; - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.cpp b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.cpp deleted file mode 100644 index 11506abc66..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include "pci_openfirmware.h" - -#include -#include - -#include - -#include -#include -#include - -#include "pci_openfirmware_priv.h" - - -typedef status_t (*probeFunction)(int, const StringArrayPropertyValue&); - -static const probeFunction sProbeFunctions[] = { - NULL, -}; - - -status_t -sparc_openfirmware_pci_controller_init(void) -{ - char path[256]; - intptr_t cookie = 0; - while (of_get_next_device(&cookie, 0, "pci", path, sizeof(path)) - == B_OK) { -dprintf("sparc_openfirmware_pci_controller_init(): pci device node: %s\n", path); - // get the device node and the "compatible" property - int deviceNode = of_finddevice(path); - StringArrayPropertyValue compatible; - status_t error = openfirmware_get_property(deviceNode, "compatible", - compatible); - if (error != B_OK) { - dprintf("sparc_openfirmware_pci_controller_init: Failed to get " - "\"compatible\" property for pci device: %s\n", path); - continue; - } - - // probe - for (int i = 0; sProbeFunctions[i]; i++) { - error = sProbeFunctions[i](deviceNode, compatible); - if (error == B_OK) - break; - } - } - - return B_OK; -} - - -// #pragma mark - support functions - - -char * -StringArrayPropertyValue::NextElement(int &cookie) const -{ - if (cookie >= length) - return NULL; - - char *result = value + cookie; - cookie += strnlen(result, length - cookie) + 1; - return result; -} - - -bool -StringArrayPropertyValue::ContainsElement(const char *value) const -{ - int cookie = 0; - while (char *checkValue = NextElement(cookie)) { - if (strcmp(checkValue, value) == 0) - return true; - } - - return false; -} - - -status_t -openfirmware_get_property(int package, const char *propertyName, - PropertyValue &value) -{ - value.length = of_getproplen(package, propertyName); - if (value.length < 0) - return B_ENTRY_NOT_FOUND; - - value.value = (char*)malloc(value.length); - if (!value.value) - return B_NO_MEMORY; - - if (of_getprop(package, propertyName, value.value, value.length) - == OF_FAILED) { - return B_ERROR; - } - - return B_OK; -} - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.h b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.h deleted file mode 100644 index 5b8c2573b0..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_H -#define PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_H - -#include - -status_t sparc_openfirmware_pci_controller_init(void); - -#endif // PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware_priv.h b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware_priv.h deleted file mode 100644 index 6c9c917696..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware_priv.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_PRIV_H -#define PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_PRIV_H - -#include -#include - -#include - - -struct StringArrayPropertyValue; - - -// implementations - -// TODO - - -// property support - -struct PropertyValue { - PropertyValue() - : value(NULL) - { - } - - ~PropertyValue() - { - free(value); - } - - char *value; - int length; -}; - -struct StringArrayPropertyValue : PropertyValue { - - char *NextElement(int &cookie) const; - bool ContainsElement(const char *value) const; -}; - -status_t openfirmware_get_property(int package, const char *propertyName, - PropertyValue &value); - -#endif // PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_PRIV_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_controller.cpp deleted file mode 100644 index ff8eea2ac0..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_controller.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "pci_controller.h" - -#include - -#include "pci_private.h" - -#include "openfirmware/pci_openfirmware.h" - - -status_t -pci_controller_init(void) -{ - return sparc_openfirmware_pci_controller_init(); -} - - -phys_addr_t -pci_ram_address(phys_addr_t physical_address_in_system_memory) -{ - return physical_address_in_system_memory; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.c b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.c deleted file mode 100644 index 94877e26d9..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "pci_io.h" -#include "pci_private.h" - - -static const uint8_t* gPCIBase; - - -status_t -pci_io_init() -{ - // TODO set gPCIBase - return B_OK; -} - - -uint8 -pci_read_io_8(int mapped_io_addr) -{ - return sparc_in8((vuint8*)(gPCIBase + mapped_io_addr)); -} - - -void -pci_write_io_8(int mapped_io_addr, uint8 value) -{ - sparc_out8((vuint8*)(gPCIBase + mapped_io_addr), value); -} - - -uint16 -pci_read_io_16(int mapped_io_addr) -{ - return sparc_in16((vuint16*)(gPCIBase + mapped_io_addr)); -} - - -void -pci_write_io_16(int mapped_io_addr, uint16 value) -{ - sparc_out16((vuint16*)(gPCIBase + mapped_io_addr), value); -} - - -uint32 -pci_read_io_32(int mapped_io_addr) -{ - return sparc_in32((vuint32*)(gPCIBase + mapped_io_addr)); -} - - -void -pci_write_io_32(int mapped_io_addr, uint32 value) -{ - sparc_out32((vuint32*)(gPCIBase + mapped_io_addr), value); -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.h b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.h deleted file mode 100644 index 6cf0cbc70d..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef PCI_BUS_MANAGER_SPARC_IO_H -#define PCI_BUS_MANAGER_SPARC_IO_H - -#include - -static inline void -sparc_out8(vuint8 *address, uint8 value) -{ - *address = value; - asm volatile("MEMBAR #MemIssue"); -} - - -static inline void -sparc_out16(vuint16 *address, uint16 value) -{ - *address = value; - asm volatile("MEMBAR #MemIssue"); -} - - -static inline void -sparc_out16_reverse(vuint16 *address, uint16 value) -{ - asm volatile("stha %1, [%0] 0x88" : : "r"(address), "r"(value)); - asm volatile("MEMBAR #MemIssue"); -} - - -static inline void -sparc_out32(vuint32 *address, uint32 value) -{ - *address = value; - asm volatile("MEMBAR #MemIssue"); -} - - -static inline void -sparc_out32_reverse(vuint32 *address, uint32 value) -{ - asm volatile("stwa %1, [%0] 0x88" : : "r"(address), "r"(value)); - asm volatile("MEMBAR #MemIssue"); -} - - -static inline uint8 -sparc_in8(const vuint8 *address) -{ - uint8 value = *address; - asm volatile("MEMBAR #MemIssue"); - return value; -} - - -static inline uint16 -sparc_in16(const vuint16 *address) -{ - uint16 value = *address; - asm volatile("MEMBAR #MemIssue"); - return value; -} - - -static inline uint16 -sparc_in16_reverse(const vuint16 *address) -{ - uint16 value; - asm volatile("lha [%1] 0x88, %0" : "=r"(value) : "r"(address)); - asm volatile("MEMBAR #MemIssue"); - return value; -} - - -static inline uint32 -sparc_in32(const vuint32 *address) -{ - uint32 value = *address; - asm volatile("MEMBAR #MemIssue"); - return value; -} - - -static inline uint32 -sparc_in32_reverse(const vuint32 *address) -{ - uint32 value; - asm volatile("ldwa [%1] 0x88, %0" : "=r"(value) : "r"(address)); - asm volatile("MEMBAR #MemIssue"); - return value; -} - -#endif // PCI_BUS_MANAGER_SPARC_IO_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile deleted file mode 100644 index cd8a162008..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile +++ /dev/null @@ -1,18 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch x86 ; - -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; - -UsePrivateHeaders kernel [ FDirName kernel arch x86 ] [ FDirName kernel util ] ; - -SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi acpica include ; -SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi acpica include - platform ; -SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi arch $(TARGET_KERNEL_ARCH_DIR) ; - -KernelStaticLibrary pci_arch_bus_manager : - pci_acpi.cpp - pci_bios.cpp - pci_controller.cpp - pci_io.cpp - pci_irq.cpp - ; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp deleted file mode 100644 index ef34b2be11..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2006, Marcus Overhagen. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "pci_private.h" -#include "pci_bios.h" - - -status_t -pci_bios_init(void) -{ - return B_ERROR; -} - - -status_t -pci_bios_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - return B_ERROR; -} - - -status_t -pci_bios_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value) -{ - return B_ERROR; -} - - -status_t -pci_bios_get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 32; - return B_OK; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.h b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.h deleted file mode 100644 index 64d05b67be..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __PCI_X86_BIOS_H -#define __PCI_X86_BIOS_H - -#include - -status_t pci_bios_init(void); - -status_t pci_bios_read_config(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value); - -status_t pci_bios_write_config(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value); - -status_t pci_bios_get_max_bus_devices(void *cookie, int32 *count); - -#endif diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp deleted file mode 100644 index 2c1934e5b9..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright 2006, Marcus Overhagen. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include -#include -#include - -#include "pci_acpi.h" -#include "arch_cpu.h" -#include "pci_bios.h" -#include "pci_controller.h" -#include "pci_irq.h" -#include "pci_private.h" - -#include "acpi.h" - - -#define PCI_MECH1_REQ_PORT 0xCF8 -#define PCI_MECH1_DATA_PORT 0xCFC -#define PCI_MECH1_REQ_DATA(bus, device, func, offset) \ - (0x80000000 | (bus << 16) | (device << 11) | (func << 8) | (offset & ~3)) - -#define PCI_MECH2_ENABLE_PORT 0x0cf8 -#define PCI_MECH2_FORWARD_PORT 0x0cfa -#define PCI_MECH2_CONFIG_PORT(dev, offset) \ - (uint16)(0xC00 | (dev << 8) | offset) - -#define PCI_LOCK_CONFIG(cpu_status) \ -{ \ - cpu_status = disable_interrupts(); \ - acquire_spinlock(&sConfigLock); \ -} - -#define PCI_UNLOCK_CONFIG(cpu_status) \ -{ \ - release_spinlock(&sConfigLock); \ - restore_interrupts(cpu_status); \ -} - -spinlock sConfigLock = B_SPINLOCK_INITIALIZER; - -static status_t -pci_mech1_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - cpu_status cpu; - status_t status = B_OK; - - if (offset > 0xff) - return B_BAD_VALUE; - - PCI_LOCK_CONFIG(cpu); - out32(PCI_MECH1_REQ_DATA(bus, device, function, offset), PCI_MECH1_REQ_PORT); - switch (size) { - case 1: - *value = in8(PCI_MECH1_DATA_PORT + (offset & 3)); - break; - case 2: - *value = in16(PCI_MECH1_DATA_PORT + (offset & 3)); - break; - case 4: - *value = in32(PCI_MECH1_DATA_PORT); - break; - default: - status = B_ERROR; - break; - } - PCI_UNLOCK_CONFIG(cpu); - - return status; -} - - -static status_t -pci_mech1_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value) -{ - cpu_status cpu; - status_t status = B_OK; - - if (offset > 0xff) - return B_BAD_VALUE; - - PCI_LOCK_CONFIG(cpu); - out32(PCI_MECH1_REQ_DATA(bus, device, function, offset), PCI_MECH1_REQ_PORT); - switch (size) { - case 1: - out8(value, PCI_MECH1_DATA_PORT + (offset & 3)); - break; - case 2: - out16(value, PCI_MECH1_DATA_PORT + (offset & 3)); - break; - case 4: - out32(value, PCI_MECH1_DATA_PORT); - break; - default: - status = B_ERROR; - break; - } - PCI_UNLOCK_CONFIG(cpu); - - return status; -} - - -static status_t -pci_mech1_get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 32; - return B_OK; -} - - -static status_t -pci_mech2_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - cpu_status cpu; - status_t status = B_OK; - - if (offset > 0xff) - return B_BAD_VALUE; - - PCI_LOCK_CONFIG(cpu); - out8((uint8)(0xf0 | (function << 1)), PCI_MECH2_ENABLE_PORT); - out8(bus, PCI_MECH2_FORWARD_PORT); - switch (size) { - case 1: - *value = in8(PCI_MECH2_CONFIG_PORT(device, offset)); - break; - case 2: - *value = in16(PCI_MECH2_CONFIG_PORT(device, offset)); - break; - case 4: - *value = in32(PCI_MECH2_CONFIG_PORT(device, offset)); - break; - default: - status = B_ERROR; - break; - } - out8(0, PCI_MECH2_ENABLE_PORT); - PCI_UNLOCK_CONFIG(cpu); - - return status; -} - - -static status_t -pci_mech2_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value) -{ - cpu_status cpu; - status_t status = B_OK; - - if (offset > 0xff) - return B_BAD_VALUE; - - PCI_LOCK_CONFIG(cpu); - out8((uint8)(0xf0 | (function << 1)), PCI_MECH2_ENABLE_PORT); - out8(bus, PCI_MECH2_FORWARD_PORT); - switch (size) { - case 1: - out8(value, PCI_MECH2_CONFIG_PORT(device, offset)); - break; - case 2: - out16(value, PCI_MECH2_CONFIG_PORT(device, offset)); - break; - case 4: - out32(value, PCI_MECH2_CONFIG_PORT(device, offset)); - break; - default: - status = B_ERROR; - break; - } - out8(0, PCI_MECH2_ENABLE_PORT); - PCI_UNLOCK_CONFIG(cpu); - - return status; -} - - -static status_t -pci_mech2_get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 16; - return B_OK; -} - - -addr_t sPCIeBase = 0; -uint8 sStartBusNumber; -uint8 sEndBusNumber; -#define PCIE_VADDR(base, bus, slot, func, reg) ((base) + \ - ((((bus) & 0xff) << 20) | (((slot) & 0x1f) << 15) | \ - (((func) & 0x7) << 12) | ((reg) & 0xfff))) - -static status_t -pci_mechpcie_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value) -{ - // fallback to mechanism 1 for out of range busses - if (bus < sStartBusNumber || bus > sEndBusNumber) { - return pci_mech1_read_config(cookie, bus, device, function, offset, - size, value); - } - - status_t status = B_OK; - - addr_t address = PCIE_VADDR(sPCIeBase, bus, device, function, offset); - - switch (size) { - case 1: - *value = *(uint8*)address; - break; - case 2: - *value = *(uint16*)address; - break; - case 4: - *value = *(uint32*)address; - break; - default: - status = B_ERROR; - break; - } - return status; -} - - -static status_t -pci_mechpcie_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value) -{ - // fallback to mechanism 1 for out of range busses - if (bus < sStartBusNumber || bus > sEndBusNumber) { - return pci_mech1_write_config(cookie, bus, device, function, offset, - size, value); - } - - status_t status = B_OK; - - addr_t address = PCIE_VADDR(sPCIeBase, bus, device, function, offset); - switch (size) { - case 1: - *(uint8*)address = value; - break; - case 2: - *(uint16*)address = value; - break; - case 4: - *(uint32*)address = value; - break; - default: - status = B_ERROR; - break; - } - - return status; -} - - -static status_t -pci_mechpcie_get_max_bus_devices(void *cookie, int32 *count) -{ - *count = 32; - return B_OK; -} - - -phys_addr_t -pci_ram_address(phys_addr_t physical_address_in_system_memory) -{ - return physical_address_in_system_memory; -} - - -pci_controller pci_controller_x86_mech1 = -{ - pci_mech1_read_config, - pci_mech1_write_config, - pci_mech1_get_max_bus_devices, - pci_x86_irq_read, - pci_x86_irq_write, -}; - -pci_controller pci_controller_x86_mech2 = -{ - pci_mech2_read_config, - pci_mech2_write_config, - pci_mech2_get_max_bus_devices, - pci_x86_irq_read, - pci_x86_irq_write, -}; - -pci_controller pci_controller_x86_mechpcie = -{ - pci_mechpcie_read_config, - pci_mechpcie_write_config, - pci_mechpcie_get_max_bus_devices, - pci_x86_irq_read, - pci_x86_irq_write, -}; - -pci_controller pci_controller_x86_bios = -{ - pci_bios_read_config, - pci_bios_write_config, - pci_bios_get_max_bus_devices, - pci_x86_irq_read, - pci_x86_irq_write, -}; - - -status_t -pci_controller_init(void) -{ - bool search_mech1 = true; - bool search_mech2 = true; - bool search_mechpcie = true; - bool search_bios = true; - void *config = NULL; - status_t status; - - status = pci_x86_irq_init(); - if (status != B_OK) - return status; - - config = load_driver_settings("pci"); - if (config) { - const char *mech = get_driver_parameter(config, "mechanism", - NULL, NULL); - if (mech) { - search_mech1 = search_mech2 = search_mechpcie = search_bios = false; - if (strcmp(mech, "1") == 0) - search_mech1 = true; - else if (strcmp(mech, "2") == 0) - search_mech2 = true; - else if (strcmp(mech, "pcie") == 0) - search_mechpcie = true; - else if (strcmp(mech, "bios") == 0) - search_bios = true; - else - panic("Unknown pci config mechanism setting %s\n", mech); - } - unload_driver_settings(config); - } - - // TODO: check safemode "don't call the BIOS" setting and unset search_bios! - - // PCI configuration mechanism PCIe is the preferred one. - // If it doesn't work, try mechanism 1. - // If it doesn't work, try mechanism 2. - // Finally, try to fallback to PCI BIOS - - if (search_mechpcie) { - acpi_init(); - struct acpi_table_mcfg* mcfg = - (struct acpi_table_mcfg*)acpi_find_table("MCFG"); - if (mcfg != NULL) { - struct acpi_mcfg_allocation* end = (struct acpi_mcfg_allocation*) - ((char*)mcfg + mcfg->Header.Length); - struct acpi_mcfg_allocation* alloc = (struct acpi_mcfg_allocation*) - (mcfg + 1); - for (; alloc < end; alloc++) { - dprintf("PCI: mechanism addr: %" B_PRIx64 ", seg: %x, start: " - "%x, end: %x\n", alloc->Address, alloc->PciSegment, - alloc->StartBusNumber, alloc->EndBusNumber); - if (alloc->PciSegment == 0) { - area_id mcfgArea = map_physical_memory("acpi mcfg", - alloc->Address, (alloc->EndBusNumber + 1) << 20, - B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA - | B_KERNEL_WRITE_AREA, (void **)&sPCIeBase); - if (mcfgArea < 0) - break; - sStartBusNumber = alloc->StartBusNumber; - sEndBusNumber = alloc->EndBusNumber; - dprintf("PCI: mechanism pcie controller found\n"); - return pci_controller_add(&pci_controller_x86_mechpcie, - NULL); - } - } - } - } - - if (search_mech1) { - // check for mechanism 1 - out32(0x80000000, PCI_MECH1_REQ_PORT); - if (0x80000000 == in32(PCI_MECH1_REQ_PORT)) { - dprintf("PCI: mechanism 1 controller found\n"); - return pci_controller_add(&pci_controller_x86_mech1, NULL); - } - } - - if (search_mech2) { - // check for mechanism 2 - out8(0x00, 0xCFB); - out8(0x00, 0xCF8); - out8(0x00, 0xCFA); - if (in8(0xCF8) == 0x00 && in8(0xCFA) == 0x00) { - dprintf("PCI: mechanism 2 controller found\n"); - return pci_controller_add(&pci_controller_x86_mech2, NULL); - } - } - - if (search_bios) { - // check for PCI BIOS - if (pci_bios_init() == B_OK) { - dprintf("PCI: BIOS support found\n"); - return pci_controller_add(&pci_controller_x86_bios, NULL); - } - } - - dprintf("PCI: no configuration mechanism found\n"); - return B_ERROR; -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_io.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_io.cpp deleted file mode 100644 index e62f9a2c4a..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_io.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2006, Marcus Overhagen. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "pci_private.h" -#include "arch_cpu.h" - - -status_t -pci_io_init() -{ - // nothing to do on x86 hardware - return B_OK; -} - - -uint8 -pci_read_io_8(int mapped_io_addr) -{ - return in8(mapped_io_addr); -} - - -void -pci_write_io_8(int mapped_io_addr, uint8 value) -{ - out8(value, mapped_io_addr); -} - - -uint16 -pci_read_io_16(int mapped_io_addr) -{ - return in16(mapped_io_addr); -} - - -void -pci_write_io_16(int mapped_io_addr, uint16 value) -{ - out16(value, mapped_io_addr); -} - - -uint32 -pci_read_io_32(int mapped_io_addr) -{ - return in32(mapped_io_addr); -} - - -void -pci_write_io_32(int mapped_io_addr, uint32 value) -{ - out32(value, mapped_io_addr); -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.cpp deleted file mode 100644 index 8c2d8a7063..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2006, Marcus Overhagen. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ -#include "pci_irq.h" - - -status_t -pci_x86_irq_init(void) -{ - return B_OK; -} - - -status_t -pci_x86_irq_read(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint8 pin, uint8 *irq) -{ - return B_ERROR; -} - - -status_t -pci_x86_irq_write(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint8 pin, uint8 irq) -{ - return B_ERROR; -} - diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.h b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.h deleted file mode 100644 index 8b038c2685..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2006, Marcus Overhagen. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ -#ifndef __PCI_X86_IRQ_H -#define __PCI_X86_IRQ_H - -#include - -status_t pci_x86_irq_init(void); - -status_t pci_x86_irq_read(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint8 pin, uint8 *irq); - -status_t pci_x86_irq_write(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint8 pin, uint8 irq); - - -#endif diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index eef32b2a51..f75ed47b7a 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -21,6 +21,7 @@ #include "pci_private.h" #include "pci.h" + #define TRACE_CAP(x...) dprintf(x) #define FLOW(x...) //#define FLOW(x...) dprintf(x) @@ -32,13 +33,6 @@ PCI *gPCI; // #pragma mark bus manager exports -status_t -pci_controller_add(pci_controller *controller, void *cookie) -{ - return gPCI->AddController(controller, cookie); -} - - long pci_get_nth_pci_info(long index, pci_info *outInfo) { @@ -78,6 +72,23 @@ pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint16 offset, } +phys_addr_t +pci_ram_address(phys_addr_t childAdr) +{ + phys_addr_t hostAdr = 0; +#if defined(__i386__) || defined(__x86_64__) + hostAdr = childAdr; +#else + uint8 domain; + pci_resource_range range; + if (gPCI->LookupRange(kPciRangeMmio, childAdr, domain, range) >= B_OK) + hostAdr = childAdr - range.pci_addr + range.host_addr; +#endif + //dprintf("pci_ram_address(%#" B_PRIx64 ") -> %#" B_PRIx64 "\n", childAdr, hostAdr); + return hostAdr; +} + + status_t pci_find_capability(uint8 virtualBus, uint8 device, uint8 function, uint8 capID, uint8 *offset) @@ -155,11 +166,10 @@ pci_reserve_device(uchar virtualBus, uchar device, uchar function, device_node *node, *legacy; status = B_DEVICE_NOT_FOUND; - if (gPCIRootNode == NULL) - goto err1; + device_node *root_pci_node = gPCI->_GetDomainData(domain)->root_node; node = NULL; - if (gDeviceManager->get_next_child_node(gPCIRootNode, + if (gDeviceManager->get_next_child_node(root_pci_node, matchThis, &node) < B_OK) { goto err1; } @@ -208,10 +218,6 @@ pci_unreserve_device(uchar virtualBus, uchar device, uchar function, //TRACE(("%s(%d [%d:%d], %d, %d, %s, %p)\n", __FUNCTION__, virtualBus, // domain, bus, device, function, driverName, nodeCookie)); - device_attr matchPCIRoot[] = { - {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "PCI"}}, - {NULL} - }; device_attr matchThis[] = { // info about device {B_DEVICE_BUS, B_STRING_TYPE, {.string = "pci"}}, @@ -236,16 +242,11 @@ pci_unreserve_device(uchar virtualBus, uchar device, uchar function, {"legacy_driver_cookie", B_UINT64_TYPE, {.ui64 = (uint64)nodeCookie}}, {NULL} }; - device_node *root, *pci, *node, *legacy, *drv; + device_node *pci, *node, *legacy, *drv; status = B_DEVICE_NOT_FOUND; - root = gDeviceManager->get_root_node(); - if (!root) - return status; - pci = NULL; - if (gDeviceManager->get_next_child_node(root, matchPCIRoot, &pci) < B_OK) - goto err0; + pci = gPCI->_GetDomainData(domain)->root_node; node = NULL; if (gDeviceManager->get_next_child_node(pci, matchThis, &node) < B_OK) @@ -272,8 +273,6 @@ pci_unreserve_device(uchar virtualBus, uchar device, uchar function, // we'll get EBUSY here anyway... gDeviceManager->put_node(node); - gDeviceManager->put_node(pci); - gDeviceManager->put_node(root); return B_OK; err3: @@ -281,9 +280,6 @@ err3: err2: gDeviceManager->put_node(node); err1: - gDeviceManager->put_node(pci); -err0: - gDeviceManager->put_node(root); TRACE(("pci_unreserve_device for driver %s failed: %s\n", driverName, strerror(status))); return status; @@ -480,29 +476,14 @@ pcirefresh(int argc, char **argv) static bool sInitDone; -status_t __attribute__((weak)) pci_controller_finalize() { return B_OK; } - - status_t pci_init_deferred(void) { + dprintf("pci_init_deferred()\n"); + if (sInitDone) return B_OK; - status_t ret = pci_controller_init(); - if (ret == B_DEV_NOT_READY) - return ret; - - if (ret != B_OK) { - TRACE(("PCI: pci_controller_init failed\n")); - return B_ERROR; - } - - if (pci_io_init() != B_OK) { - TRACE(("PCI: pci_io_init failed\n")); - return B_ERROR; - } - add_debugger_command("inw", &display_io, "dump io words (32-bit)"); add_debugger_command("in32", &display_io, "dump io words (32-bit)"); add_debugger_command("ins", &display_io, "dump io shorts (16-bit)"); @@ -523,7 +504,7 @@ pci_init_deferred(void) add_debugger_command("pcistatus", &pcistatus, "dump and clear pci device status registers"); add_debugger_command("pcirefresh", &pcirefresh, "refresh and print all pci_info"); - if (pci_controller_finalize() != B_OK) { + if (gPCI->Finalize() != B_OK) { TRACE(("PCI: pci_controller_finalize failed\n")); return B_ERROR; } @@ -539,14 +520,7 @@ status_t pci_init(void) { gPCI = new PCI; - - status_t ret = pci_init_deferred(); - if (ret == B_DEV_NOT_READY) { - TRACE(("PCI: init deferred\n")); - return B_OK; - } - - return ret; + return B_OK; } @@ -632,6 +606,25 @@ PCI::InitBus() } +status_t +PCI::Finalize() +{ + // TODO: Properly handle multiple domains. Currently finalize fill be called twice for first + // domain is second domain is added, but should be called only once. + + for (uint8 i = 0; i < fDomainCount; i++) { + pci_controller_module_info* controller = fDomainData[i].controller; + if (controller->finalize != NULL) { + status_t res = controller->finalize(fDomainData[i].controller_cookie); + if (res < B_OK) + return res; + } + } + + return B_OK; +} + + PCI::~PCI() { } @@ -701,13 +694,15 @@ PCI::ResolveVirtualBus(uint8 virtualBus, uint8 *domain, uint8 *bus) status_t -PCI::AddController(pci_controller *controller, void *controller_cookie) +PCI::AddController(pci_controller_module_info *controller, void *controller_cookie, + device_node *root_node) { if (fDomainCount == MAX_PCI_DOMAINS) return B_ERROR; fDomainData[fDomainCount].controller = controller; fDomainData[fDomainCount].controller_cookie = controller_cookie; + fDomainData[fDomainCount].root_node = root_node; // initialized later to avoid call back into controller at this point fDomainData[fDomainCount].max_bus_devices = -1; @@ -716,6 +711,42 @@ PCI::AddController(pci_controller *controller, void *controller_cookie) return B_OK; } + +status_t +PCI::LookupRange(uint32 type, phys_addr_t pciAddr, + uint8 &domain, pci_resource_range &range, uint8 **mappedAdr) +{ + if (type >= kPciRangeEnd) + return B_BAD_VALUE; + + for (uint8 curDomain = 0; curDomain < fDomainCount; curDomain++) { + pci_resource_range const *const &ranges = fDomainData[curDomain].ranges; + + uint32 typeBeg, typeEnd; + if (type == kPciRangeMmio) { + typeBeg = kPciRangeMmio; + typeEnd = kPciRangeMmioEnd; + } else { + typeBeg = type; + typeEnd = type + 1; + } + for (uint32 curType = typeBeg; curType < typeEnd; curType++) { + const pci_resource_range curRange = ranges[curType]; + if (pciAddr >= curRange.pci_addr && pciAddr < curRange.pci_addr + curRange.size) { + domain = curDomain; + range = curRange; +#if !(defined(__i386__) || defined(__x86_64__)) + if (type == kPciRangeIoPort && mappedAdr != NULL) + *mappedAdr = fDomainData[curDomain].io_port_adr; +#endif + return B_OK; + } + } + } + return B_ENTRY_NOT_FOUND; +} + + void PCI::InitDomainData() { @@ -723,9 +754,31 @@ PCI::InitDomainData() int32 count; status_t status; - status = (*fDomainData[i].controller->get_max_bus_devices)( - fDomainData[i].controller_cookie, &count); + pci_controller_module_info *ctrlModule = fDomainData[i].controller; + void *ctrl = fDomainData[i].controller_cookie; + + status = ctrlModule->get_max_bus_devices(ctrl, &count); fDomainData[i].max_bus_devices = (status == B_OK) ? count : 0; + + memset(fDomainData[i].ranges, 0, sizeof(fDomainData[i].ranges)); + pci_resource_range range; + for (uint32 j = 0; ctrlModule->get_range(ctrl, j, &range) >= B_OK; j++) { + if (range.type < kPciRangeEnd && range.size > 0) + fDomainData[i].ranges[range.type] = range; + } + +#if !(defined(__i386__) || defined(__x86_64__)) + // TODO: free resources when domain is detached + pci_resource_range &ioPortRange = fDomainData[i].ranges[kPciRangeIoPort]; + if (ioPortRange.size > 0) { + fDomainData[i].io_port_area = map_physical_memory("PCI IO Ports", + ioPortRange.host_addr, ioPortRange.size, B_ANY_KERNEL_ADDRESS, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&fDomainData[i].io_port_adr); + + if (fDomainData[i].io_port_area < B_OK) + fDomainData[i].io_port_adr = NULL; + } +#endif } } diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index 8fafa184f8..adff525370 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -9,9 +9,7 @@ #include -#ifdef __cplusplus - #include -#endif +#include #include "pci_controller.h" #include "pci_msi.h" @@ -24,8 +22,6 @@ # define TRACE(x) dprintf x #endif -#ifdef __cplusplus - struct PCIDev; struct PCIBus { @@ -54,11 +50,18 @@ struct PCIDev { struct domain_data { // These two are set in PCI::AddController: - pci_controller * controller; + pci_controller_module_info *controller; void * controller_cookie; + device_node * root_node; // All the rest is set in PCI::InitDomainData int max_bus_devices; + pci_resource_range ranges[kPciRangeEnd]; + +#if !(defined(__i386__) || defined(__x86_64__)) + area_id io_port_area; + uint8 * io_port_adr; +#endif }; @@ -69,9 +72,13 @@ public: void InitDomainData(); void InitBus(); + status_t Finalize(); - status_t AddController(pci_controller *controller, - void *controller_cookie); + status_t AddController(pci_controller_module_info *controller, + void *controller_cookie, device_node *root_node); + + status_t LookupRange(uint32 type, phys_addr_t pciAddr, + uint8 &domain, pci_resource_range &range, uint8 **mappedAdr = NULL); status_t GetNthInfo(long index, pci_info *outInfo); @@ -169,8 +176,10 @@ private: uint32 &address, uint32 *size = NULL, uint8 *flags = NULL); +public: domain_data * _GetDomainData(uint8 domain); +private: status_t _CreateVirtualBus(uint8 domain, uint8 bus, uint8 *virtualBus); @@ -203,12 +212,8 @@ private: extern PCI *gPCI; -#endif // __cplusplus - -#ifdef __cplusplus extern "C" { -#endif status_t pci_init(void); status_t pci_init_deferred(void); @@ -223,8 +228,6 @@ void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, void __pci_resolve_virtual_bus(uint8 virtualBus, uint8 *domain, uint8 *bus); -#ifdef __cplusplus } -#endif #endif /* __PCI_H__ */ diff --git a/src/add-ons/kernel/bus_managers/pci/pci_controller.h b/src/add-ons/kernel/bus_managers/pci/pci_controller.h index 5580d46356..94dbdbd67d 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_controller.h +++ b/src/add-ons/kernel/bus_managers/pci/pci_controller.h @@ -6,31 +6,7 @@ #ifndef __PCI_CONTROLLER_H #define __PCI_CONTROLLER_H -#include - -typedef struct pci_controller -{ - // read PCI config space - status_t (*read_pci_config)(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 *value); - - // write PCI config space - status_t (*write_pci_config)(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint16 offset, uint8 size, uint32 value); - - status_t (*get_max_bus_devices)(void *cookie, int32 *count); - - status_t (*read_pci_irq)(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint8 pin, uint8 *irq); - - status_t (*write_pci_irq)(void *cookie, - uint8 bus, uint8 device, uint8 function, - uint8 pin, uint8 irq); - -} pci_controller; +#include #ifdef __cplusplus @@ -39,7 +15,7 @@ extern "C" { status_t pci_controller_init(void); status_t pci_controller_finalize(void); -status_t pci_controller_add(pci_controller *controller, void *cookie); +status_t pci_controller_add(pci_controller_module_info *controller, void *cookie); #ifdef __cplusplus } diff --git a/src/add-ons/kernel/bus_managers/pci/pci_io.cpp b/src/add-ons/kernel/bus_managers/pci/pci_io.cpp new file mode 100644 index 0000000000..dc018f017a --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/pci_io.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 2006, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include "pci.h" +#include "pci_private.h" +#include "arch_cpu.h" + + +//#define TRACE_PCI_IO +#undef TRACE +#ifdef TRACE_PCI_IO +# define TRACE(x...) dprintf("PCI_IO: " x) +#else +# define TRACE(x...) ; +#endif + + +#if defined(__i386__) || defined(__x86_64__) + +uint8 +pci_read_io_8(int mapped_io_addr) +{ + return in8(mapped_io_addr); +} + + +void +pci_write_io_8(int mapped_io_addr, uint8 value) +{ + out8(value, mapped_io_addr); +} + + +uint16 +pci_read_io_16(int mapped_io_addr) +{ + return in16(mapped_io_addr); +} + + +void +pci_write_io_16(int mapped_io_addr, uint16 value) +{ + out16(value, mapped_io_addr); +} + + +uint32 +pci_read_io_32(int mapped_io_addr) +{ + return in32(mapped_io_addr); +} + + +void +pci_write_io_32(int mapped_io_addr, uint32 value) +{ + out32(value, mapped_io_addr); +} + +#else + +static uint8* +get_io_port_address(int ioPort) +{ + uint8 domain; + pci_resource_range range; + uint8 *mappedAdr; + + if (gPCI->LookupRange(kPciRangeIoPort, ioPort, domain, range, &mappedAdr) < B_OK) + return NULL; + + return mappedAdr + ioPort; +} + + +uint8 +pci_read_io_8(int mapped_io_addr) +{ + TRACE("pci_read_io_8(%d)\n", mapped_io_addr); + vuint8* ptr = get_io_port_address(mapped_io_addr); + if (ptr == NULL) + return 0; + + return *ptr; +} + + +void +pci_write_io_8(int mapped_io_addr, uint8 value) +{ + TRACE("pci_write_io_8(%d)\n", mapped_io_addr); + vuint8* ptr = get_io_port_address(mapped_io_addr); + if (ptr == NULL) + return; + + *ptr = value; +} + + +uint16 +pci_read_io_16(int mapped_io_addr) +{ + TRACE("pci_read_io_16(%d)\n", mapped_io_addr); + vuint16* ptr = (uint16*)get_io_port_address(mapped_io_addr); + if (ptr == NULL) + return 0; + + return *ptr; +} + + +void +pci_write_io_16(int mapped_io_addr, uint16 value) +{ + TRACE("pci_write_io_16(%d)\n", mapped_io_addr); + vuint16* ptr = (uint16*)get_io_port_address(mapped_io_addr); + if (ptr == NULL) + return; + + *ptr = value; +} + + +uint32 +pci_read_io_32(int mapped_io_addr) +{ + TRACE("pci_read_io_32(%d)\n", mapped_io_addr); + vuint32* ptr = (uint32*)get_io_port_address(mapped_io_addr); + if (ptr == NULL) + return 0; + + return *ptr; +} + + +void +pci_write_io_32(int mapped_io_addr, uint32 value) +{ + TRACE("pci_write_io_32(%d)\n", mapped_io_addr); + vuint32* ptr = (vuint32*)get_io_port_address(mapped_io_addr); + if (ptr == NULL) + return; + + *ptr = value; +} + +#endif diff --git a/src/add-ons/kernel/bus_managers/pci/pci_private.h b/src/add-ons/kernel/bus_managers/pci/pci_private.h index 3538227990..1970fe6227 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_private.h +++ b/src/add-ons/kernel/bus_managers/pci/pci_private.h @@ -39,8 +39,6 @@ typedef struct pci_root_module_info { extern pci_root_module_info gPCIRootModule; extern pci_device_module_info gPCIDeviceModule; -extern device_node* gPCIRootNode; - #ifdef __cplusplus extern "C" { @@ -50,7 +48,7 @@ phys_addr_t pci_ram_address(phys_addr_t physical_address_in_system_memory); status_t pci_find_capability(uint8 bus, uint8 device, uint8 function, uint8 cap_id, uint8 *offset); -status_t pci_find_extended_capability(uint8 bus, uint8 device, uint8 function, +status_t pci_find_extended_capability(uint8 bus, uint8 device, uint8 function, uint16 cap_id, uint16 *offset); status_t pci_reserve_device(uchar virtualBus, uchar device, uchar function, @@ -65,7 +63,6 @@ status_t pci_get_powerstate(uchar virtualBus, uint8 device, status_t pci_set_powerstate(uchar virtualBus, uint8 device, uint8 function, uint8 newState); -status_t pci_io_init(void); uint8 pci_read_io_8(int mapped_io_addr); void pci_write_io_8(int mapped_io_addr, uint8 value); uint16 pci_read_io_16(int mapped_io_addr); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_root.cpp b/src/add-ons/kernel/bus_managers/pci/pci_root.cpp index df8b2f902a..eacf22b716 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_root.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_root.cpp @@ -13,62 +13,18 @@ #include +#include + #include "pci_private.h" #include "pci.h" +#define CHECK_RET(err) {status_t _err = (err); if (_err < B_OK) return _err;} + // name of PCI root module #define PCI_ROOT_MODULE_NAME "bus_managers/pci/root/driver_v1" -device_node* gPCIRootNode = NULL; - - -static float -pci_root_supports_device(device_node* parent) -{ - const char* bus; - if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) < B_OK) - return -1.0f; - -#if defined(__riscv) - if (strcmp(bus, "fdt") == 0) { - const char* compatible; - if (gDeviceManager->get_attr_string(parent, "fdt/compatible", &compatible, false) < B_OK) - return -1.0f; - - if (strcmp(compatible, "pci-host-ecam-generic") == 0 - || strcmp(compatible, "sifive,fu740-pcie") == 0) { - return 1.0f; - } - } -#elif defined(__arm__) || defined(__aarch64__) - if (strcmp(bus, "fdt") == 0) { - const char* compatible; - if (gDeviceManager->get_attr_string(parent, "fdt/compatible", &compatible, false) < B_OK) - return -1.0f; - - if (strcmp(compatible, "pci-host-ecam-generic") == 0) - return 1.0f; - } - - if (strcmp(bus, "acpi") == 0) { - const char* hid; - if (gDeviceManager->get_attr_string(parent, ACPI_DEVICE_HID_ITEM, &hid, false) < B_OK) - return -1.0f; - - if (strcmp(hid, "PNP0A03") == 0 || strcmp(hid, "PNP0A08") == 0) - return 1.0f; - } -#else - if (strcmp(bus, "root") == 0) - return 1.0f; -#endif - - return 0.0; -} - - static status_t pci_root_register_device(device_node* parent) { @@ -140,14 +96,21 @@ pci_root_init(device_node* node, void** _cookie) { *_cookie = node; - gPCIRootNode = node; + DeviceNodePutter<&gDeviceManager> pciHostNode(gDeviceManager->get_parent_node(node)); + + pci_controller_module_info* pciHostModule; + void* pciHostDev; + CHECK_RET(gDeviceManager->get_driver(pciHostNode.Get(), (driver_module_info**)&pciHostModule, &pciHostDev)); module_info *module; status_t res = get_module(B_PCI_MODULE_NAME, &module); if (res < B_OK) return res; - return pci_init_deferred(); + CHECK_RET(gPCI->AddController(pciHostModule, pciHostDev, node)); + CHECK_RET(pci_init_deferred()); + + return B_OK; } @@ -174,7 +137,7 @@ struct pci_root_module_info gPCIRootModule = { pci_root_std_ops }, - pci_root_supports_device, + NULL, pci_root_register_device, pci_root_init, NULL, // uninit diff --git a/src/add-ons/kernel/busses/Jamfile b/src/add-ons/kernel/busses/Jamfile index c07b41f28d..f3d5bbe374 100644 --- a/src/add-ons/kernel/busses/Jamfile +++ b/src/add-ons/kernel/busses/Jamfile @@ -4,6 +4,7 @@ SubInclude HAIKU_TOP src add-ons kernel busses ata ; SubInclude HAIKU_TOP src add-ons kernel busses agp_gart ; SubInclude HAIKU_TOP src add-ons kernel busses i2c ; SubInclude HAIKU_TOP src add-ons kernel busses mmc ; +SubInclude HAIKU_TOP src add-ons kernel busses pci ; SubInclude HAIKU_TOP src add-ons kernel busses random ; SubInclude HAIKU_TOP src add-ons kernel busses scsi ; SubInclude HAIKU_TOP src add-ons kernel busses usb ; diff --git a/src/add-ons/kernel/busses/pci/Jamfile b/src/add-ons/kernel/busses/pci/Jamfile new file mode 100644 index 0000000000..cd5db0bcc0 --- /dev/null +++ b/src/add-ons/kernel/busses/pci/Jamfile @@ -0,0 +1,3 @@ +SubDir HAIKU_TOP src add-ons kernel busses pci ; + +SubInclude HAIKU_TOP src add-ons kernel busses pci x86 ; diff --git a/src/add-ons/kernel/busses/pci/x86/Jamfile b/src/add-ons/kernel/busses/pci/x86/Jamfile new file mode 100644 index 0000000000..197a8e0675 --- /dev/null +++ b/src/add-ons/kernel/busses/pci/x86/Jamfile @@ -0,0 +1,15 @@ +SubDir HAIKU_TOP src add-ons kernel busses pci x86 ; + +SubDirC++Flags -fno-rtti ; + +UsePrivateKernelHeaders ; + +SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi acpica include ; +SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi acpica include + platform ; + +KernelAddon x86 : + pci_acpi.cpp + X86PCIController.cpp + kernel_interface.cpp +; diff --git a/src/add-ons/kernel/busses/pci/x86/X86PCIController.cpp b/src/add-ons/kernel/busses/pci/x86/X86PCIController.cpp new file mode 100644 index 0000000000..60d02e3ce4 --- /dev/null +++ b/src/add-ons/kernel/busses/pci/x86/X86PCIController.cpp @@ -0,0 +1,437 @@ +/* + * Copyright 2022, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ + + +#include "X86PCIController.h" +#include "pci_acpi.h" + +#include +#include +#include "acpi.h" + +#include +#include + + +#define PCI_MECH1_REQ_PORT 0xCF8 +#define PCI_MECH1_DATA_PORT 0xCFC +#define PCI_MECH1_REQ_DATA(bus, device, func, offset) \ + (0x80000000 | (bus << 16) | (device << 11) | (func << 8) | (offset & ~3)) + +#define PCI_MECH2_ENABLE_PORT 0x0cf8 +#define PCI_MECH2_FORWARD_PORT 0x0cfa +#define PCI_MECH2_CONFIG_PORT(dev, offset) \ + (uint16)(0xC00 | (dev << 8) | offset) + + +//#pragma mark - driver + + +float +X86PCIController::SupportsDevice(device_node* parent) +{ + const char* bus; + if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) < B_OK) + return -1.0f; + + if (strcmp(bus, "root") == 0) + return 1.0f; + + return 0.0; +} + + +status_t +X86PCIController::RegisterDevice(device_node* parent) +{ + device_attr attrs[] = { + { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "X86 PCI Host Controller"} }, + { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, {.string = "bus_managers/pci/root/driver_v1"} }, + {} + }; + + return gDeviceManager->register_node(parent, PCI_X86_DRIVER_MODULE_NAME, attrs, NULL, NULL); +} + + +status_t +X86PCIController::InitDriver(device_node* node, X86PCIController*& outDriver) +{ + bool search_mech1 = true; + bool search_mech2 = true; + bool search_mechpcie = true; + void *config = NULL; + + config = load_driver_settings("pci"); + if (config) { + const char *mech = get_driver_parameter(config, "mechanism", NULL, NULL); + if (mech) { + search_mech1 = search_mech2 = search_mechpcie = false; + if (strcmp(mech, "1") == 0) + search_mech1 = true; + else if (strcmp(mech, "2") == 0) + search_mech2 = true; + else if (strcmp(mech, "pcie") == 0) + search_mechpcie = true; + else + panic("Unknown pci config mechanism setting %s\n", mech); + } + unload_driver_settings(config); + } + + // PCI configuration mechanism PCIe is the preferred one. + // If it doesn't work, try mechanism 1. + // If it doesn't work, try mechanism 2. + + if (search_mechpcie) { + if (CreateDriver(node, new(std::nothrow) X86PCIControllerMethPcie(), outDriver) >= B_OK) + return B_OK; + } + if (search_mech1) { + if (CreateDriver(node, new(std::nothrow) X86PCIControllerMeth1(), outDriver) >= B_OK) + return B_OK; + } + if (search_mech2) { + if (CreateDriver(node, new(std::nothrow) X86PCIControllerMeth2(), outDriver) >= B_OK) + return B_OK; + } + + dprintf("PCI: no configuration mechanism found\n"); + return B_ERROR; +} + + +status_t +X86PCIController::CreateDriver(device_node* node, X86PCIController* driverIn, + X86PCIController*& driverOut) +{ + ObjectDeleter driver(driverIn); + if (!driver.IsSet()) + return B_NO_MEMORY; + + CHECK_RET(driver->InitDriverInt(node)); + driverOut = driver.Detach(); + return B_OK; +} + + +status_t +X86PCIController::InitDriverInt(device_node* node) +{ + fNode = node; + return B_OK; +} + + +void +X86PCIController::UninitDriver() +{ + delete this; +} + + +//#pragma mark - PCI controller + + +status_t +X86PCIController::ReadIrq(uint8 bus, uint8 device, uint8 function, + uint8 pin, uint8& irq) +{ + return B_UNSUPPORTED; +} + + +status_t +X86PCIController::WriteIrq(uint8 bus, uint8 device, uint8 function, + uint8 pin, uint8 irq) +{ + return B_UNSUPPORTED; +} + + +status_t +X86PCIController::GetRange(uint32 index, pci_resource_range* range) +{ + + return B_BAD_INDEX; +} + + +//#pragma mark - X86PCIControllerMeth1 + + +status_t +X86PCIControllerMeth1::InitDriverInt(device_node* node) +{ + CHECK_RET(X86PCIController::InitDriverInt(node)); + + // check for mechanism 1 + out32(0x80000000, PCI_MECH1_REQ_PORT); + if (0x80000000 == in32(PCI_MECH1_REQ_PORT)) { + dprintf("PCI: mechanism 1 controller found\n"); + return B_OK; + } + return B_ERROR; +} + + +status_t +X86PCIControllerMeth1::ReadConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 &value) +{ + if (offset > 0xff) + return B_BAD_VALUE; + + InterruptsSpinLocker lock(fLock); + out32(PCI_MECH1_REQ_DATA(bus, device, function, offset), PCI_MECH1_REQ_PORT); + switch (size) { + case 1: + value = in8(PCI_MECH1_DATA_PORT + (offset & 3)); + break; + case 2: + value = in16(PCI_MECH1_DATA_PORT + (offset & 3)); + break; + case 4: + value = in32(PCI_MECH1_DATA_PORT); + break; + default: + return B_ERROR; + } + + return B_OK; +} + + +status_t +X86PCIControllerMeth1::WriteConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) +{ + if (offset > 0xff) + return B_BAD_VALUE; + + InterruptsSpinLocker lock(fLock); + out32(PCI_MECH1_REQ_DATA(bus, device, function, offset), PCI_MECH1_REQ_PORT); + switch (size) { + case 1: + out8(value, PCI_MECH1_DATA_PORT + (offset & 3)); + break; + case 2: + out16(value, PCI_MECH1_DATA_PORT + (offset & 3)); + break; + case 4: + out32(value, PCI_MECH1_DATA_PORT); + break; + default: + return B_ERROR; + } + + return B_OK; +} + + +status_t X86PCIControllerMeth1::GetMaxBusDevices(int32& count) +{ + count = 32; + return B_OK; +} + + +//#pragma mark - X86PCIControllerMeth2 + + +status_t +X86PCIControllerMeth2::InitDriverInt(device_node* node) +{ + CHECK_RET(X86PCIController::InitDriverInt(node)); + + // check for mechanism 2 + out8(0x00, 0xCFB); + out8(0x00, 0xCF8); + out8(0x00, 0xCFA); + if (in8(0xCF8) == 0x00 && in8(0xCFA) == 0x00) { + dprintf("PCI: mechanism 2 controller found\n"); + return B_OK; + } + return B_ERROR; +} + + +status_t +X86PCIControllerMeth2::ReadConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 &value) +{ + if (offset > 0xff) + return B_BAD_VALUE; + + InterruptsSpinLocker lock(fLock); + out8((uint8)(0xf0 | (function << 1)), PCI_MECH2_ENABLE_PORT); + out8(bus, PCI_MECH2_FORWARD_PORT); + switch (size) { + case 1: + value = in8(PCI_MECH2_CONFIG_PORT(device, offset)); + break; + case 2: + value = in16(PCI_MECH2_CONFIG_PORT(device, offset)); + break; + case 4: + value = in32(PCI_MECH2_CONFIG_PORT(device, offset)); + break; + default: + return B_ERROR; + } + out8(0, PCI_MECH2_ENABLE_PORT); + + return B_OK; +} + + +status_t +X86PCIControllerMeth2::WriteConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) +{ + if (offset > 0xff) + return B_BAD_VALUE; + + InterruptsSpinLocker lock(fLock); + out8((uint8)(0xf0 | (function << 1)), PCI_MECH2_ENABLE_PORT); + out8(bus, PCI_MECH2_FORWARD_PORT); + switch (size) { + case 1: + out8(value, PCI_MECH2_CONFIG_PORT(device, offset)); + break; + case 2: + out16(value, PCI_MECH2_CONFIG_PORT(device, offset)); + break; + case 4: + out32(value, PCI_MECH2_CONFIG_PORT(device, offset)); + break; + default: + return B_ERROR; + } + out8(0, PCI_MECH2_ENABLE_PORT); + + return B_OK; +} + + +status_t X86PCIControllerMeth2::GetMaxBusDevices(int32& count) +{ + count = 16; + return B_OK; +} + + +//#pragma mark - X86PCIControllerMethPcie + + +#define PCIE_VADDR(base, bus, slot, func, reg) ((base) + \ + ((((bus) & 0xff) << 20) | (((slot) & 0x1f) << 15) | \ + (((func) & 0x7) << 12) | ((reg) & 0xfff))) + + +status_t +X86PCIControllerMethPcie::InitDriverInt(device_node* node) +{ + CHECK_RET(X86PCIController::InitDriverInt(node)); + + acpi_init(); + struct acpi_table_mcfg* mcfg = + (struct acpi_table_mcfg*)acpi_find_table("MCFG"); + if (mcfg != NULL) { + struct acpi_mcfg_allocation* end = (struct acpi_mcfg_allocation*) + ((char*)mcfg + mcfg->Header.Length); + struct acpi_mcfg_allocation* alloc = (struct acpi_mcfg_allocation*) + (mcfg + 1); + for (; alloc < end; alloc++) { + dprintf("PCI: mechanism addr: %" B_PRIx64 ", seg: %x, start: " + "%x, end: %x\n", alloc->Address, alloc->PciSegment, + alloc->StartBusNumber, alloc->EndBusNumber); + if (alloc->PciSegment == 0) { + area_id mcfgArea = map_physical_memory("acpi mcfg", + alloc->Address, (alloc->EndBusNumber + 1) << 20, + B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA + | B_KERNEL_WRITE_AREA, (void **)&fPCIeBase); + if (mcfgArea < 0) + break; + fStartBusNumber = alloc->StartBusNumber; + fEndBusNumber = alloc->EndBusNumber; + dprintf("PCI: mechanism pcie controller found\n"); + return B_OK; + } + } + } + return B_ERROR; +} + + +status_t +X86PCIControllerMethPcie::ReadConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 &value) +{ + // fallback to mechanism 1 for out of range busses + if (bus < fStartBusNumber || bus > fEndBusNumber) { + return X86PCIControllerMeth1::ReadConfig(bus, device, function, offset, + size, value); + } + + addr_t address = PCIE_VADDR(fPCIeBase, bus, device, function, offset); + + switch (size) { + case 1: + value = *(uint8*)address; + break; + case 2: + value = *(uint16*)address; + break; + case 4: + value = *(uint32*)address; + break; + default: + return B_ERROR; + } + return B_OK; +} + + +status_t +X86PCIControllerMethPcie::WriteConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) +{ + // fallback to mechanism 1 for out of range busses + if (bus < fStartBusNumber || bus > fEndBusNumber) { + return X86PCIControllerMeth1::WriteConfig(bus, device, function, offset, + size, value); + } + + addr_t address = PCIE_VADDR(fPCIeBase, bus, device, function, offset); + switch (size) { + case 1: + *(uint8*)address = value; + break; + case 2: + *(uint16*)address = value; + break; + case 4: + *(uint32*)address = value; + break; + default: + return B_ERROR; + } + + return B_OK; +} + + +status_t X86PCIControllerMethPcie::GetMaxBusDevices(int32& count) +{ + count = 32; + return B_OK; +} diff --git a/src/add-ons/kernel/busses/pci/x86/X86PCIController.h b/src/add-ons/kernel/busses/pci/x86/X86PCIController.h new file mode 100644 index 0000000000..92439c483d --- /dev/null +++ b/src/add-ons/kernel/busses/pci/x86/X86PCIController.h @@ -0,0 +1,122 @@ +/* + * Copyright 2022, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ + + +#ifndef _X86PCICONTROLLER_H_ +#define _X86PCICONTROLLER_H_ + +#include + +#include +#include + + +#define CHECK_RET(err) {status_t _err = (err); if (_err < B_OK) return _err;} + +#define PCI_X86_DRIVER_MODULE_NAME "busses/pci/x86/driver_v1" + + +class X86PCIController { +public: + virtual ~X86PCIController() = default; + + static float SupportsDevice(device_node* parent); + static status_t RegisterDevice(device_node* parent); + static status_t InitDriver(device_node* node, X86PCIController*& outDriver); + void UninitDriver(); + + virtual status_t ReadConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 &value) = 0; + + virtual status_t WriteConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) = 0; + + virtual status_t GetMaxBusDevices(int32& count) = 0; + + status_t ReadIrq( + uint8 bus, uint8 device, uint8 function, + uint8 pin, uint8& irq); + + status_t WriteIrq( + uint8 bus, uint8 device, uint8 function, + uint8 pin, uint8 irq); + + status_t GetRange(uint32 index, pci_resource_range* range); + +protected: + static status_t CreateDriver(device_node* node, X86PCIController* driver, + X86PCIController*& driverOut); + virtual status_t InitDriverInt(device_node* node); + +protected: + spinlock fLock = B_SPINLOCK_INITIALIZER; + + device_node* fNode{}; + + addr_t fPCIeBase{}; + uint8 fStartBusNumber{}; + uint8 fEndBusNumber{}; +}; + + +class X86PCIControllerMeth1: public X86PCIController { +public: + virtual ~X86PCIControllerMeth1() = default; + + status_t InitDriverInt(device_node* node) override; + + status_t ReadConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 &value) override; + + status_t WriteConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) override; + + status_t GetMaxBusDevices(int32& count) override; +}; + + +class X86PCIControllerMeth2: public X86PCIController { +public: + virtual ~X86PCIControllerMeth2() = default; + + status_t InitDriverInt(device_node* node) final; + + status_t ReadConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 &value) final; + + status_t WriteConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) final; + + status_t GetMaxBusDevices(int32& count) final; +}; + + +class X86PCIControllerMethPcie: public X86PCIControllerMeth1 { +public: + virtual ~X86PCIControllerMethPcie() = default; + + status_t InitDriverInt(device_node* node) final; + + status_t ReadConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 &value) final; + + status_t WriteConfig( + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) final; + + status_t GetMaxBusDevices(int32& count) final; +}; + + +extern device_manager_info* gDeviceManager; + +#endif // _X86PCICONTROLLER_H_ diff --git a/src/add-ons/kernel/busses/pci/x86/kernel_interface.cpp b/src/add-ons/kernel/busses/pci/x86/kernel_interface.cpp new file mode 100644 index 0000000000..96776ea7cc --- /dev/null +++ b/src/add-ons/kernel/busses/pci/x86/kernel_interface.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2022, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ + + +#include "X86PCIController.h" + + +device_manager_info* gDeviceManager; + + +pci_controller_module_info gPciControllerDriver = { + .info = { + .info = { + .name = PCI_X86_DRIVER_MODULE_NAME, + }, + .supports_device = X86PCIController::SupportsDevice, + .register_device = X86PCIController::RegisterDevice, + .init_driver = [](device_node* node, void** driverCookie) { + return X86PCIController::InitDriver(node, *(X86PCIController**)driverCookie); + }, + .uninit_driver = [](void* driverCookie) { + return static_cast(driverCookie)->UninitDriver(); + }, + }, + .read_pci_config = [](void* cookie, + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32* value) { + return static_cast(cookie) + ->ReadConfig(bus, device, function, offset, size, *value); + }, + .write_pci_config = [](void* cookie, + uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) { + return static_cast(cookie) + ->WriteConfig(bus, device, function, offset, size, value); + }, + .get_max_bus_devices = [](void* cookie, int32* count) { + return static_cast(cookie)->GetMaxBusDevices(*count); + }, + .read_pci_irq = [](void* cookie, + uint8 bus, uint8 device, uint8 function, + uint8 pin, uint8 *irq) { + return static_cast(cookie)->ReadIrq(bus, device, function, pin, *irq); + }, + .write_pci_irq = [](void* cookie, + uint8 bus, uint8 device, uint8 function, + uint8 pin, uint8 irq) { + return static_cast(cookie)->WriteIrq(bus, device, function, pin, irq); + }, + .get_range = [](void *cookie, uint32 index, pci_resource_range* range) { + return static_cast(cookie)->GetRange(index, range); + } +}; + + +_EXPORT module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager }, + {} +}; + +_EXPORT module_info *modules[] = { + (module_info *)&gPciControllerDriver, + NULL +}; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.cpp b/src/add-ons/kernel/busses/pci/x86/pci_acpi.cpp similarity index 100% rename from src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.cpp rename to src/add-ons/kernel/busses/pci/x86/pci_acpi.cpp diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.h b/src/add-ons/kernel/busses/pci/x86/pci_acpi.h similarity index 100% rename from src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.h rename to src/add-ons/kernel/busses/pci/x86/pci_acpi.h