acpica: remove support to access pci via i/o ports

All access to PCI devices can be handled nowadays via the platform session.
The I/O port access seems also to work not properly on newer UEFI machines.

Fixes #4532
This commit is contained in:
Alexander Boettcher 2022-06-03 13:51:09 +02:00 committed by Christian Helmuth
parent b77f59286f
commit 438e0adc77
3 changed files with 15 additions and 95 deletions

View File

@ -389,9 +389,6 @@ void Acpica::Main::init_acpica(Wait_acpi_ready wait_acpi_ready,
/* Generate report for platform driver */ /* Generate report for platform driver */
Acpica::generate_report(env, bridge); Acpica::generate_report(env, bridge);
} }
/* Tell PCI backend to use platform_drv for PCI device access from now on */
Acpica::use_platform_drv();
} }

View File

@ -28,7 +28,6 @@ struct Acpica::Env
Genode::Allocator &heap; Genode::Allocator &heap;
Wait_acpi_ready const wait_acpi_ready; Wait_acpi_ready const wait_acpi_ready;
bool use_platform_drv;
Genode::Parent::Service_name announce_for_acpica { Genode::Parent::Service_name announce_for_acpica {
wait_acpi_ready.enabled ? "Acpi" : Platform::Session::service_name() }; wait_acpi_ready.enabled ? "Acpi" : Platform::Session::service_name() };
@ -44,8 +43,7 @@ struct Acpica::Env
Env(Genode::Env &env, Genode::Allocator &heap, Env(Genode::Env &env, Genode::Allocator &heap,
Wait_acpi_ready wait_acpi_ready) Wait_acpi_ready wait_acpi_ready)
: :
env(env), heap(heap), wait_acpi_ready(wait_acpi_ready), env(env), heap(heap), wait_acpi_ready(wait_acpi_ready)
use_platform_drv(!wait_acpi_ready.enabled)
{ } { }
}; };
@ -60,14 +58,12 @@ Platform::Client & Acpica::platform()
instance->cap.construct(Genode::reinterpret_cap_cast<Platform::Session>( instance->cap.construct(Genode::reinterpret_cap_cast<Platform::Session>(
instance->env.session(instance->announce_for_acpica, instance->env.session(instance->announce_for_acpica,
instance->id_space_element.id(), instance->id_space_element.id(),
"ram_quota=36K", Genode::Affinity()))); "ram_quota=48K", Genode::Affinity())));
instance->platform.construct(*instance->cap); instance->platform.construct(*instance->cap);
} }
return *instance->platform; return *instance->platform;
} }
bool Acpica::platform_drv() { return instance->use_platform_drv; }
void Acpica::use_platform_drv() { instance->use_platform_drv = true; }
void Acpica::init(Genode::Env &env, Genode::Allocator &heap, void Acpica::init(Genode::Env &env, Genode::Allocator &heap,

View File

@ -73,66 +73,6 @@ static void dump_error(char const * const func, ACPI_PCI_ID *pcidev,
} }
/*******************************
* Accessing PCI via I/O ports *
*******************************/
enum { REG_ADDR = 0xcf8, REG_DATA = 0xcfc, REG_SIZE = 4 };
static Genode::Io_port_connection &pci_io_port() {
static Genode::Io_port_connection conn(Acpica::env(), REG_ADDR, REG_SIZE);
return conn;
}
static unsigned pci_io_cfg_addr(unsigned const bus, unsigned const device,
unsigned const function, unsigned const addr)
{
return (1U << 31) |
(bus << 16) |
((device & 0x1fU) << 11) |
((function & 0x07U) << 8) |
(addr & ~3U);
}
static unsigned pci_io_read(unsigned const bus, unsigned const device,
unsigned const function, unsigned const addr,
unsigned const width)
{
/* write target address */
pci_io_port().outl(REG_ADDR, pci_io_cfg_addr(bus, device, function, addr));
switch (width) {
case 8:
return pci_io_port().inb(REG_DATA + (addr & 3));
case 16:
return pci_io_port().inw(REG_DATA + (addr & 2));
case 32:
return pci_io_port().inl(REG_DATA);
default:
return ~0U;
}
}
static void pci_io_write(unsigned const bus, unsigned const device,
unsigned const function, unsigned const addr,
unsigned const width, unsigned value)
{
/* write target address */
pci_io_port().outl(REG_ADDR, pci_io_cfg_addr(bus, device, function, addr));
switch (width) {
case 8:
pci_io_port().outb(REG_DATA + (addr & 3), value);
return;
case 16:
pci_io_port().outw(REG_DATA + (addr & 2), value);
return;
case 32:
pci_io_port().outl(REG_DATA, value);
return;
}
}
/************************* /*************************
* Acpica PCI OS backend * * Acpica PCI OS backend *
*************************/ *************************/
@ -142,18 +82,6 @@ ACPI_STATUS AcpiOsInitialize (void) { return AE_OK; }
ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
UINT64 *value, UINT32 width) UINT64 *value, UINT32 width)
{ {
if (!Acpica::platform_drv()) {
try {
*value = pci_io_read(pcidev->Bus, pcidev->Device, pcidev->Function,
reg, width);
dump_read(__func__, pcidev, reg, *value, width);
} catch (...) {
dump_error(__func__, pcidev, reg, width);
return AE_ERROR;
}
return AE_OK;
}
Platform::Device_capability cap = Acpica::platform().first_device(); Platform::Device_capability cap = Acpica::platform().first_device();
while (cap.valid()) { while (cap.valid()) {
@ -182,6 +110,11 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
return AE_ERROR; return AE_ERROR;
}; };
if (reg >= 0x100)
Genode::warning(__func__, " ", Genode::Hex(reg),
" out of supported config space range ",
" -> wrong location will be read");
*value = client.config_read(reg, access_size); *value = client.config_read(reg, access_size);
dump_read(__func__, pcidev, reg, *value, width); dump_read(__func__, pcidev, reg, *value, width);
@ -197,24 +130,13 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
dump_error(__func__, pcidev, reg, width); dump_error(__func__, pcidev, reg, width);
return AE_ERROR; *value = ~0U;
return AE_OK;
} }
ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
UINT64 value, UINT32 width) UINT64 value, UINT32 width)
{ {
if (!Acpica::platform_drv()) {
try {
dump_write(__func__, pcidev, reg, value, width);
pci_io_write(pcidev->Bus, pcidev->Device, pcidev->Function, reg,
width, value);
return AE_OK;
} catch (...) {
dump_error(__func__, pcidev, reg, width);
return AE_ERROR;
}
}
Platform::Device_capability cap = Acpica::platform().first_device(); Platform::Device_capability cap = Acpica::platform().first_device();
while (cap.valid()) { while (cap.valid()) {
@ -245,6 +167,11 @@ ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
client.config_write(reg, value, access_size); client.config_write(reg, value, access_size);
if (reg >= 0x100)
Genode::warning(__func__, " ", Genode::Hex(reg),
" out of supported config space range ",
" -> wrong location will be written");
dump_write(__func__, pcidev, reg, value, width); dump_write(__func__, pcidev, reg, value, width);
Acpica::platform().release_device(client.rpc_cap()); Acpica::platform().release_device(client.rpc_cap());
@ -258,5 +185,5 @@ ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
dump_error(__func__, pcidev, reg, width); dump_error(__func__, pcidev, reg, width);
return AE_ERROR; return AE_OK;
} }