This allows reading irq device status 0 for the mode of the interrupt
controller, pic or apic.

TESTED using:

```
\#include <stdio.h>
\#include <device/device.h>
\#include <hurd.h>
\#include <mach.h>

int main()
{
  mach_port_t devices, irq;
  int pic_mode, cnt = 1;
  int err;

  err = get_privileged_ports(NULL, &devices);
  if (err)
    return 1;

  err = device_open(devices, D_READ, "irq", &irq);
  if (err)
    return 2;

  err = device_get_status(irq, 0, &pic_mode, &cnt);
  if (err)
    return 3;

  printf("pic_mode = %d\n", pic_mode);
  return 0;
}

```

amd64-apic $ sudo ./test
pic_mode = 1

i386-pic $ sudo ./test
pic_mode = 0

i386-apic $ sudo ./test
pic_mode = 1

--enable-platform=xen compiles

---
 Makefrag.am                 |  1 +
 device/intr.c               | 26 ++++++++++++++++++++++++++
 device/intr.h               |  6 ++++--
 i386/i386/irq.h             |  1 +
 i386/i386/pic.c             |  3 +++
 i386/i386at/conf.c          |  2 +-
 i386/i386at/ioapic.c        |  2 ++
 include/device/irq_status.h | 25 +++++++++++++++++++++++++
 8 files changed, 63 insertions(+), 3 deletions(-)
 create mode 100644 include/device/irq_status.h

diff --git a/Makefrag.am b/Makefrag.am
index 2cc75bcf..f037a0a7 100644
--- a/Makefrag.am
+++ b/Makefrag.am
@@ -361,6 +361,7 @@ include_device_HEADERS = \
        include/device/device_types.defs \
        include/device/device_types.h \
        include/device/disk_status.h \
+       include/device/irq_status.h \
        include/device/net_status.h \
        include/device/notify.defs \
        include/device/notify.h \
diff --git a/device/intr.c b/device/intr.c
index 07d8acd8..8396847e 100644
--- a/device/intr.c
+++ b/device/intr.c
@@ -21,6 +21,32 @@
 #include <machine/spl.h>
 #include <machine/irq.h>
 #include <ipc/ipc_space.h>
+#include <device/irq_status.h>
+
+/*ARGSUSED*/
+io_return_t irqgetstat(
+  dev_t        dev,
+  dev_flavor_t flavor,
+  dev_status_t data,                   /* pointer to OUT array */
+  mach_msg_type_number_t *count)       /* OUT */
+{
+  io_return_t result = D_SUCCESS;
+
+  switch (flavor)
+    {
+#ifndef MACH_XEN
+      case IRQGETPICMODE:
+        *data = pic_mode;
+        *count = 1;
+        break;
+#endif
+      default:
+        result = D_INVALID_OPERATION;
+        break;
+    }
+
+  return (result);
+}
 
 #ifndef MACH_XEN
 
diff --git a/device/intr.h b/device/intr.h
index cd3e0bce..efa7f75a 100644
--- a/device/intr.h
+++ b/device/intr.h
@@ -15,8 +15,6 @@
 #ifndef __INTR_H__
 #define __INTR_H__
 
-#ifndef MACH_XEN
-
 #include <mach/kern_return.h>
 #include <mach/port.h>
 #include <kern/queue.h>
@@ -27,6 +25,8 @@
 
 #include <sys/types.h>
 
+#ifndef MACH_XEN
+
 struct irqdev;
 #include <machine/irq.h>
 
@@ -59,4 +59,6 @@ kern_return_t irq_acknowledge (ipc_port_t receive_port);
 
 #endif /* MACH_XEN */
 
+extern io_return_t irqgetstat(dev_t dev, dev_flavor_t flavor, dev_status_t 
data, mach_msg_type_number_t *count);
+
 #endif
diff --git a/i386/i386/irq.h b/i386/i386/irq.h
index e1f41045..9c54e18c 100644
--- a/i386/i386/irq.h
+++ b/i386/i386/irq.h
@@ -28,5 +28,6 @@ void __enable_irq (irq_t irq);
 void __disable_irq (irq_t irq);
 
 extern struct irqdev irqtab;
+extern int pic_mode;
 
 #endif
diff --git a/i386/i386/pic.c b/i386/i386/pic.c
index b51bf3ad..5481af52 100644
--- a/i386/i386/pic.c
+++ b/i386/i386/pic.c
@@ -73,6 +73,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <i386/pic.h>
 #include <i386/spl.h>
 #include <i386/pio.h>
+#include <device/irq_status.h>
+
+int    pic_mode = ACPI_PICMODE_PIC;
 
 spl_t  curr_ipl[NCPUS] = {0};
 int    curr_pic_mask;
diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c
index 84b97c42..9bdd8379 100644
--- a/i386/i386at/conf.c
+++ b/i386/i386at/conf.c
@@ -156,7 +156,7 @@ struct dev_ops      dev_name_list[] =
 #endif /* MACH_HYP */
 
         { irqname,      nulldev_open,   nulldev_close,    nulldev_read,
-          nulldev_write,nulldev_getstat,nulldev_setstat,  nomap,
+          nulldev_write,irqgetstat,    nulldev_setstat,  nomap,
           nodev_async_in,        nulldev_reset,        nulldev_portdeath,0,
           nodev_info },
 
diff --git a/i386/i386at/ioapic.c b/i386/i386at/ioapic.c
index e38e4d6b..dba8e5e1 100644
--- a/i386/i386at/ioapic.c
+++ b/i386/i386at/ioapic.c
@@ -33,9 +33,11 @@
 #include <kern/printf.h>
 #include <kern/timer.h>
 #include <kern/lock.h>
+#include <device/irq_status.h>
 
 static int has_irq_specific_eoi = 0;
 int timer_pin;
+int pic_mode = ACPI_PICMODE_APIC;
 
 uint32_t lapic_timer_val = 0;
 uint32_t calibrated_ticks = 0;
diff --git a/include/device/irq_status.h b/include/device/irq_status.h
new file mode 100644
index 00000000..1286dc5f
--- /dev/null
+++ b/include/device/irq_status.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2025 Free Software Foundation
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * FSF ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  FSF DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ */
+
+#ifndef _DEVICE_IRQ_STATUS_H_
+#define _DEVICE_IRQ_STATUS_H_
+
+/* Flavor for device_get_status */
+
+#define IRQGETPICMODE          0
+# define ACPI_PICMODE_PIC      0
+# define ACPI_PICMODE_APIC     1
+# define ACPI_PICMODE_SAPIC    2
+
+#endif /* _DEVICE_IRQ_STATUS_H_ */
-- 
2.45.2



Reply via email to