commit 91d041c2cf9a3f289efde748a1c2a2d6b908b44a
Author: Damien Zammit <damien@zamaudio.com>
Date:   Tue Oct 14 07:54:34 2025 +0000

    irq: Add irqgetstat device status IRQGETPICMODE flavor
    
    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
    
    Message-ID: <20251014075420.3213978-1-damien@zamaudio.com>

---
 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(-)

--- a/Makefrag.am
+++ b/Makefrag.am
@@ -363,6 +363,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 \
--- 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
 
--- 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_
 
 #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
--- 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
--- a/x86_64/x86_64/irq.h
+++ b/x86_64/x86_64/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
--- a/i386/i386/pic.c
+++ b/i386/i386/pic.c
@@ -73,6 +73,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
 #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;
--- a/i386/i386at/conf.c
+++ b/i386/i386at/conf.c
@@ -159,7 +159,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 },
 
--- 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;
--- /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_ */
