[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 libacpica] Allow read/write to pci config
From: |
Damien Zammit |
Subject: |
[PATCH v2 libacpica] Allow read/write to pci config |
Date: |
Thu, 29 Jun 2023 10:56:53 +0000 |
---
debian/patches/acgnu.diff | 72 ++++++++++++++++++++---
debian/patches/acpi-init-files.diff | 88 ++++++++++++++++++++++++++++-
debian/patches/add-makefile.diff | 4 +-
3 files changed, 153 insertions(+), 11 deletions(-)
diff --git a/debian/patches/acgnu.diff b/debian/patches/acgnu.diff
index fc59992..e7f396f 100644
--- a/debian/patches/acgnu.diff
+++ b/debian/patches/acgnu.diff
@@ -163,7 +163,7 @@ Add acgnu.h and acgnuex.h
+#endif /* __ACGNU_H__ */
--- /dev/null
+++ b/include/acpi/platform/acgnuex.h
-@@ -0,0 +1,256 @@
+@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+
+#ifndef __ACGNUEX_H__
@@ -181,6 +181,8 @@ Add acgnu.h and acgnuex.h
+acpi_status ACPI_INIT_FUNCTION acpi_os_initialize(void);
+acpi_status acpi_os_terminate(void);
+void acpi_os_printf(const char *format, ...);
++struct pci_device;
++struct pci_device *lookup_pci_dev(struct acpi_pci_id *pci_id);
+
+static inline void *acpi_os_allocate(acpi_size size)
+{
@@ -232,6 +234,7 @@ Add acgnu.h and acgnuex.h
+#include <stdarg.h>
+#include <limits.h>
+#include <hurd.h>
++#include <pciaccess.h>
+
+#define ACPI_MAX_TABLES 128
+
@@ -403,18 +406,73 @@ Add acgnu.h and acgnuex.h
+
+static inline acpi_status
+acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
-+ u64 *value, u32 width)
++ u64 *value, u32 bit_width)
+{
-+ acpi_os_printf("ACPI: Tried to read pci config\n");
-+ return 1;
++ int i, err = 0;
++ uint8_t buf[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
++ struct pci_device *dev;
++ u64 temp = 0;
++ u32 bytes = bit_width / 8;
++ pciaddr_t bytes_read = 0;
++
++ if (bytes > 8)
++ {
++ acpi_os_printf("acpi: Can't read more than 8 pci bytes\n");
++ return 1;
++ }
++
++ dev = lookup_pci_dev(pci_id);
++ if (!dev)
++ return 1;
++
++ pci_device_cfg_read(dev, buf, reg, bytes, &bytes_read);
++ if (bytes_read < bytes)
++ {
++ acpi_os_printf("acpi: pci short read\n");
++ err = 1;
++ }
++
++ /* Read buffer from LE */
++ for (i = 0; i < bytes; i++)
++ temp |= buf[i] << (8 * i);
++
++ *value = temp;
++
++ return err;
+}
+
+static inline acpi_status
+acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
-+ u64 value, u32 width)
++ u64 value, u32 bit_width)
+{
-+ acpi_os_printf("ACPI: Tried to write pci config\n");
-+ return 1;
++ int i, err = 0;
++ uint8_t buf[8] = {0};
++ struct pci_device *dev;
++ u32 bytes = bit_width / 8;
++ pciaddr_t bytes_written = 0;
++
++ if (bytes > 8)
++ {
++ acpi_os_printf("acpi: Can't write more than 8 pci bytes\n");
++ return 1;
++ }
++
++ dev = lookup_pci_dev(pci_id);
++ if (!dev)
++ return 1;
++
++ /* Encode value as LE buffer */
++ for (i = 0; i < bytes; i++)
++ buf[i] = (value >> (8 * i)) & 0xff;
++
++ pci_device_cfg_write(dev, buf, reg, bytes, &bytes_written);
++ if (bytes_written < bytes)
++ {
++ acpi_os_printf("acpi: pci short write\n");
++ err = 1;
++ }
++
++ return err;
+}
+
+#endif /* __KERNEL__ */
diff --git a/debian/patches/acpi-init-files.diff
b/debian/patches/acpi-init-files.diff
index b83eafd..e277749 100644
--- a/debian/patches/acpi-init-files.diff
+++ b/debian/patches/acpi-init-files.diff
@@ -1,6 +1,6 @@
--- /dev/null
+++ b/acpi_init.c
-@@ -0,0 +1,510 @@
+@@ -0,0 +1,592 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+#include <acpi/acpi.h>
+
@@ -24,14 +24,21 @@
+
+#include <device/device.h>
+#include <hurd.h>
++#include <pciaccess.h>
+
+#define ACPI_MAX_TABLES 128
+
++#define PCI_CFG1_START 0xcf8
++#define PCI_CFG1_END 0xcff
++
+extern acpi_status acpi_hw_legacy_sleep(u8 sleep_state);
+
+// Lets keep the ACPI tables in this module
+static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES];
+
++static struct pci_device **pci_devices;
++static int numdevs = -1;
++
+struct slots {
+ uint8_t bus;
+ uint16_t dev;
@@ -40,6 +47,61 @@
+ struct slots *next;
+};
+
++static int
++pci_init(void)
++{
++ int i;
++ struct pci_device_iterator *dev_iter;
++ struct pci_device *pci_dev;
++ struct pci_device **tmp;
++
++ pci_system_init ();
++
++ numdevs = 0;
++ dev_iter = pci_slot_match_iterator_create (NULL);
++ while ((pci_dev = pci_device_next (dev_iter)) != NULL)
++ numdevs++;
++
++ pci_devices = malloc (sizeof(struct pci_device *));
++ if (pci_devices == NULL)
++ return errno;
++ tmp = pci_devices;
++
++ i = 0;
++ dev_iter = pci_slot_match_iterator_create (NULL);
++ while ((pci_dev = pci_device_next (dev_iter)) != NULL)
++ {
++ if ((tmp = realloc(pci_devices, (i + 1) * sizeof(*tmp))) == NULL)
++ {
++ free(pci_devices);
++ return errno;
++ }
++ pci_devices = tmp;
++ pci_device_probe(pci_dev);
++ pci_devices[i++] = pci_dev;
++ }
++ return 0;
++}
++
++struct pci_device *
++lookup_pci_dev(struct acpi_pci_id *pci_id)
++{
++ int i;
++
++ for (i = 0; i < numdevs; i++)
++ {
++ if ((pci_devices[i]->domain == pci_id->segment)
++ && (pci_devices[i]->bus == pci_id->bus)
++ && (pci_devices[i]->dev == pci_id->device)
++ && (pci_devices[i]->func == pci_id->function))
++ {
++ return pci_devices[i];
++ }
++ }
++ acpi_os_printf("Can't find pci dev %04x:%d:%02x.%d\n", pci_id->segment,
pci_id->bus, pci_id->device, pci_id->function);
++ return NULL;
++}
++
+void
+acpi_ds_dump_method_stack(acpi_status status, ...)
+// struct acpi_walk_state *walk_state, union acpi_parse_object *op)
@@ -224,17 +286,37 @@
+acpi_status
+acpi_os_initialize(void)
+{
-+ if (ioperm(0, 0x10000, 1))
++ /* Avoid giving ioperm to the PCI cfg registers
++ * since pci-arbiter controls these
++ */
++
++ /* 0-0xcf7 */
++ if (ioperm(0, PCI_CFG1_START, 1))
+ {
-+ acpi_os_printf("EPERM on ioperm\n");
++ acpi_os_printf("acpi: EPERM on ioperm 1\n");
+ return AE_ERROR;
+ }
++
++ /* 0xd00-0xffff */
++ if (ioperm(PCI_CFG1_END+1, 0x10000 - (PCI_CFG1_END+1), 1))
++ {
++ acpi_os_printf("acpi: EPERM on ioperm 2\n");
++ return AE_ERROR;
++ }
++
++ if (pci_init())
++ {
++ acpi_os_printf("acpi pci_init: Error realloc\n");
++ return AE_ERROR;
++ }
++
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_terminate(void)
+{
++ free(pci_devices);
+ acpi_os_printf("Bye!\n");
+ return AE_OK;
+}
diff --git a/debian/patches/add-makefile.diff b/debian/patches/add-makefile.diff
index da2edc3..a78d8d0 100644
--- a/debian/patches/add-makefile.diff
+++ b/debian/patches/add-makefile.diff
@@ -1,6 +1,6 @@
--- /dev/null
+++ b/Makefile
-@@ -0,0 +1,216 @@
+@@ -0,0 +1,218 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+#
+# This is free software; you can redistribute it and/or modify
@@ -37,6 +37,8 @@
+PREFIX ?= /usr/local
+libdir ?= $(PREFIX)/lib
+
++LDLIBS = -lpciaccess
++
+SRCS = global_state.c \
+ acpi_init.c \
+ $(BASE)/dsargs.c \
--
2.40.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH v2 libacpica] Allow read/write to pci config,
Damien Zammit <=