arm64: Discover PCI from ACPI.
Change-Id: I2e40c8a531f319cce25363ab83d4d0fe9f8702d2 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5274 Tested-by: Commit checker robot <[email protected]> Reviewed-by: David Karoly <[email protected]> Reviewed-by: Fredrik Holmqvist <[email protected]>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#define ACPI_RSDT_SIGNATURE "RSDT"
|
||||
#define ACPI_XSDT_SIGNATURE "XSDT"
|
||||
#define ACPI_MADT_SIGNATURE "APIC"
|
||||
#define ACPI_MCFG_SIGNATURE "MCFG"
|
||||
#define ACPI_SPCR_SIGNATURE "SPCR"
|
||||
|
||||
#define ACPI_LOCAL_APIC_ENABLED 0x01
|
||||
@@ -248,6 +249,21 @@ typedef struct acpi_gas {
|
||||
uint64 address;
|
||||
} _PACKED acpi_gas;
|
||||
|
||||
typedef struct acpi_mcfg
|
||||
{
|
||||
acpi_descriptor_header header;
|
||||
uint8 reserved[8];
|
||||
} _PACKED acpi_mcfg;
|
||||
|
||||
typedef struct acpi_mcfg_allocation
|
||||
{
|
||||
uint64 address;
|
||||
uint16 pci_segment;
|
||||
uint8 start_bus_number;
|
||||
uint8 end_bus_number;
|
||||
uint32 reserved;
|
||||
} _PACKED acpi_mcfg_allocation;
|
||||
|
||||
typedef struct acpi_spcr {
|
||||
acpi_descriptor_header header;
|
||||
uint32 interface_type;
|
||||
@@ -293,6 +309,92 @@ typedef struct acpi_resource_fixed_memory32 {
|
||||
uint32 address_length;
|
||||
} _PACKED acpi_resource_fixed_memory32;
|
||||
|
||||
typedef struct acpi_memory_attribute {
|
||||
uint8 write_protect;
|
||||
uint8 caching;
|
||||
uint8 range_type;
|
||||
uint8 translation;
|
||||
} _PACKED acpi_memory_attribute;
|
||||
|
||||
typedef struct acpi_io_attribute {
|
||||
uint8 range_type;
|
||||
uint8 translation;
|
||||
uint8 translation_type;
|
||||
uint8 reserved1;
|
||||
} _PACKED acpi_io_attribute;
|
||||
|
||||
typedef union acpi_resource_attribute {
|
||||
acpi_memory_attribute mem;
|
||||
acpi_io_attribute io;
|
||||
uint8 type_specific;
|
||||
} acpi_resource_attribute;
|
||||
|
||||
typedef struct acpi_address16_attribute {
|
||||
uint16 granularity;
|
||||
uint16 minimum;
|
||||
uint16 maximum;
|
||||
uint16 translation_offset;
|
||||
uint16 address_length;
|
||||
} _PACKED acpi_address16_attribute;
|
||||
|
||||
typedef struct acpi_address32_attribute {
|
||||
uint32 granularity;
|
||||
uint32 minimum;
|
||||
uint32 maximum;
|
||||
uint32 translation_offset;
|
||||
uint32 address_length;
|
||||
} _PACKED acpi_address32_attribute;
|
||||
|
||||
typedef struct acpi_address64_attribute {
|
||||
uint64 granularity;
|
||||
uint64 minimum;
|
||||
uint64 maximum;
|
||||
uint64 translation_offset;
|
||||
uint64 address_length;
|
||||
} _PACKED acpi_address64_attribute;
|
||||
|
||||
typedef struct acpi_resource_address {
|
||||
uint8 resource_type;
|
||||
uint8 producer_consumer;
|
||||
uint8 decode;
|
||||
uint8 minAddress_fixed;
|
||||
uint8 maxAddress_fixed;
|
||||
acpi_resource_attribute info;
|
||||
} _PACKED acpi_resource_address;
|
||||
|
||||
typedef struct acpi_resource_address16 {
|
||||
uint8 resource_type;
|
||||
uint8 producer_consumer;
|
||||
uint8 decode;
|
||||
uint8 minAddress_fixed;
|
||||
uint8 maxAddress_fixed;
|
||||
acpi_resource_attribute info;
|
||||
acpi_address16_attribute address;
|
||||
acpi_resource_source resource_source;
|
||||
} _PACKED acpi_resource_address16;
|
||||
|
||||
typedef struct acpi_resource_address32 {
|
||||
uint8 resource_type;
|
||||
uint8 producer_consumer;
|
||||
uint8 decode;
|
||||
uint8 minAddress_fixed;
|
||||
uint8 maxAddress_fixed;
|
||||
acpi_resource_attribute info;
|
||||
acpi_address32_attribute address;
|
||||
acpi_resource_source resource_source;
|
||||
} _PACKED acpi_resource_address32;
|
||||
|
||||
typedef struct acpi_resource_address64 {
|
||||
uint8 resource_type;
|
||||
uint8 producer_consumer;
|
||||
uint8 decode;
|
||||
uint8 minAddress_fixed;
|
||||
uint8 maxAddress_fixed;
|
||||
acpi_resource_attribute info;
|
||||
acpi_address64_attribute address;
|
||||
acpi_resource_source resource_source;
|
||||
} _PACKED acpi_resource_address64;
|
||||
|
||||
typedef struct acpi_resource_extended_irq {
|
||||
uint8 producer_consumer;
|
||||
uint8 triggering;
|
||||
@@ -306,7 +408,12 @@ typedef struct acpi_resource_extended_irq {
|
||||
|
||||
typedef union acpi_resource_data {
|
||||
acpi_resource_fixed_memory32 fixed_memory32;
|
||||
acpi_resource_address16 address16;
|
||||
acpi_resource_address32 address32;
|
||||
acpi_resource_address64 address64;
|
||||
acpi_resource_extended_irq extended_irq;
|
||||
|
||||
acpi_resource_address address;
|
||||
} acpi_resource_data;
|
||||
|
||||
typedef struct acpi_resource {
|
||||
@@ -317,6 +424,9 @@ typedef struct acpi_resource {
|
||||
|
||||
enum {
|
||||
ACPI_RESOURCE_TYPE_FIXED_MEMORY32 = 10,
|
||||
ACPI_RESOURCE_TYPE_ADDRESS16 = 11,
|
||||
ACPI_RESOURCE_TYPE_ADDRESS32 = 12,
|
||||
ACPI_RESOURCE_TYPE_ADDRESS64 = 13,
|
||||
ACPI_RESOURCE_TYPE_EXTENDED_IRQ = 15,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch $(TARGET_ARCH) ;
|
||||
|
||||
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ;
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ]
|
||||
[ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
|
||||
|
||||
KernelStaticLibrary pci_arch_bus_manager :
|
||||
pci_controller.cpp
|
||||
pci_io.c
|
||||
pci_io.cpp
|
||||
pci_ecam.cpp
|
||||
;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pci_controller.h"
|
||||
|
||||
//#include <arch_platform.h>
|
||||
|
||||
#include "pci_private.h"
|
||||
|
||||
|
||||
status_t
|
||||
pci_controller_init(void)
|
||||
{
|
||||
/* no support yet */
|
||||
#warning ARM:WRITEME
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
phys_addr_t
|
||||
pci_ram_address(phys_addr_t physical_address_in_system_memory)
|
||||
{
|
||||
return physical_address_in_system_memory;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pci_io.h"
|
||||
#include "pci_private.h"
|
||||
#warning ARM:WRITEME
|
||||
|
||||
|
||||
status_t
|
||||
pci_io_init()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
pci_read_io_8(int mapped_io_addr)
|
||||
{
|
||||
/* NOT IMPLEMENTED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pci_write_io_8(int mapped_io_addr, uint8 value)
|
||||
{
|
||||
/* NOT IMPLEMENTED */
|
||||
}
|
||||
|
||||
|
||||
uint16
|
||||
pci_read_io_16(int mapped_io_addr)
|
||||
{
|
||||
/* NOT IMPLEMENTED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pci_write_io_16(int mapped_io_addr, uint16 value)
|
||||
{
|
||||
/* NOT IMPLEMENTED */
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
pci_read_io_32(int mapped_io_addr)
|
||||
{
|
||||
/* NOT IMPLEMENTED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pci_write_io_32(int mapped_io_addr, uint32 value)
|
||||
{
|
||||
/* NOT IMPLEMENTED */
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku Inc.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PCI_BUS_MANAGER_ARM_IO_H
|
||||
#define PCI_BUS_MANAGER_ARM_IO_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
#endif // PCI_BUS_MANAGER_ARM_IO_H
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright 2009-2022, Haiku Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pci_controller.h"
|
||||
|
||||
#include <kernel/debug.h>
|
||||
#include <util/Vector.h>
|
||||
|
||||
#include <AutoDeleterDrivers.h>
|
||||
|
||||
#include "pci_private.h"
|
||||
|
||||
#include <ACPI.h> // module
|
||||
#include <acpi.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<PciRange> *sRanges;
|
||||
|
||||
|
||||
template<typename T>
|
||||
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<PciRange> &ranges = *(Vector<PciRange>*)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;
|
||||
}
|
||||
|
||||
|
||||
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, "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<PciRange>();
|
||||
|
||||
acpi_status acpi_res = acpiDeviceModule->walk_resources(acpiDevice,
|
||||
(char *)"_CRS", AcpiCrsScanCallback, sRanges);
|
||||
|
||||
if (acpi_res != 0)
|
||||
return B_ERROR;
|
||||
|
||||
for (Vector<PciRange>::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;
|
||||
}
|
||||
|
||||
|
||||
phys_addr_t
|
||||
pci_ram_address(phys_addr_t addr)
|
||||
{
|
||||
for (Vector<PciRange>::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;
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2009-2022, Haiku Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "pci_controller.h"
|
||||
|
||||
#include <kernel/debug.h>
|
||||
|
||||
|
||||
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,
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2022, Haiku Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <device_manager.h>
|
||||
#include <PCI.h>
|
||||
#include <drivers/ACPI.h>
|
||||
#include <drivers/bus/FDT.h>
|
||||
|
||||
#include <string.h>
|
||||
@@ -30,7 +31,7 @@ pci_root_supports_device(device_node* parent)
|
||||
if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) < B_OK)
|
||||
return -1.0f;
|
||||
|
||||
#ifdef __riscv
|
||||
#if defined(__riscv)
|
||||
const char* compatible;
|
||||
if (gDeviceManager->get_attr_string(parent, "fdt/compatible", &compatible,
|
||||
false) < B_OK)
|
||||
@@ -43,6 +44,17 @@ pci_root_supports_device(device_node* parent)
|
||||
&& strcmp(compatible, "sifive,fu740-pcie") != 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
if (strcmp(bus, "acpi") != 0)
|
||||
return -1.0f;
|
||||
|
||||
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 0.0f;
|
||||
|
||||
Reference in New Issue
Block a user