bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/6] Existing SMP apic code improvements


From: Damien Zammit
Subject: [PATCH 4/6] Existing SMP apic code improvements
Date: Sun, 28 Mar 2021 17:03:18 +1100

---
 i386/i386/apic.c              | 35 +++++++++++-----
 i386/i386/apic.h              | 75 +++++++++++++++++++++++++++++++++--
 i386/i386at/acpi_parse_apic.c | 15 ++++---
 i386/i386at/acpi_parse_apic.h |  2 +-
 4 files changed, 106 insertions(+), 21 deletions(-)

diff --git a/i386/i386/apic.c b/i386/i386/apic.c
index f0b4a153..2e0c1776 100644
--- a/i386/i386/apic.c
+++ b/i386/i386/apic.c
@@ -95,6 +95,19 @@ apic_add_irq_override(IrqOverrideData irq_over)
     apic_data.nirqoverride++;
 }
 
+IrqOverrideData *
+acpi_get_irq_override(uint8_t pin)
+{
+    int i;
+
+    for (i = 0; i < apic_data.nirqoverride; i++) {
+        if (apic_data.irq_override_list[i].irq == pin) {
+            return &apic_data.irq_override_list[i];
+        }
+    }
+    return NULL;
+}
+
 /*
  * apic_get_cpu_apic_id: returns the apic_id of a cpu.
  * Receives as input the kernel ID of a CPU.
@@ -118,16 +131,14 @@ apic_get_lapic(void)
 /*
  * apic_get_ioapic: returns the IOAPIC identified by its kernel ID.
  * Receives as input the IOAPIC's Kernel ID.
- * Returns a ioapic_data structure with the IOAPIC's data.
+ * Returns a ioapic_data structure pointer with the IOAPIC's data.
  */
-struct IoApicData
+struct IoApicData *
 apic_get_ioapic(int kernel_id)
 {
-    IoApicData io_apic = {};
-
     if (kernel_id < MAX_IOAPICS)
-        return apic_data.ioapic_list[kernel_id];
-    return io_apic;
+        return &apic_data.ioapic_list[kernel_id];
+    return NULL;
 }
 
 /* apic_get_numcpus: returns the current number of cpus. */
@@ -204,18 +215,22 @@ void apic_print_info(void)
     uint16_t lapic_id;
     uint16_t ioapic_id;
 
-    IoApicData ioapic;
+    IoApicData *ioapic;
 
     printf("CPUS:\n");
     for (i = 0; i < ncpus; i++) {
         lapic_id = apic_get_cpu_apic_id(i);
-        printf(" CPU %d - APIC ID %x\n", i, lapic_id);
+        printf(" CPU %d - APIC ID %x - addr=0x%p\n", i, lapic_id, 
apic_get_lapic());
     }
 
     printf("IOAPICS:\n");
     for (i = 0; i < nioapics; i++) {
         ioapic = apic_get_ioapic(i);
-        ioapic_id = ioapic.apic_id;
-        printf(" IOAPIC %d - APIC ID %x\n", i, ioapic_id);
+        if (!ioapic) {
+            printf("ERROR: invalid IOAPIC ID %x\n", i);
+        } else {
+            ioapic_id = ioapic->apic_id;
+            printf(" IOAPIC %d - APIC ID %x - addr=0x%p\n", i, ioapic_id, 
ioapic->ioapic);
+        }
     }
 }
diff --git a/i386/i386/apic.h b/i386/i386/apic.h
index e2d2c508..54ccda5b 100644
--- a/i386/i386/apic.h
+++ b/i386/i386/apic.h
@@ -28,8 +28,8 @@
 #include <stdint.h>
 
 typedef struct ApicReg {
-        unsigned r;    /* the actual register */
-        unsigned p[3]; /* pad to the next 128-bit boundary */
+        uint32_t r;    /* the actual register */
+        uint32_t p[3]; /* pad to the next 128-bit boundary */
 } ApicReg;
 
 typedef struct ApicIoUnit {
@@ -37,6 +37,27 @@ typedef struct ApicIoUnit {
         ApicReg window;
 } ApicIoUnit;
 
+struct ioapic_route_entry {
+    uint32_t vector      : 8,
+            delvmode    : 3, /* 000=fixed 001=lowest 111=ExtInt */
+            destmode    : 1, /* 0=physical 1=logical */
+            delvstatus  : 1,
+            polarity    : 1, /* 0=activehigh 1=activelow */
+            irr         : 1,
+            trigger     : 1, /* 0=edge 1=level */
+            mask        : 1, /* 0=enabled 1=disabled */
+            reserved1   : 15;
+    uint32_t reserved2   : 24,
+            dest        : 8;
+} __attribute__ ((packed));
+
+union ioapic_route_entry_union {
+    struct {
+       uint32_t lo;
+       uint32_t hi;
+    };
+    struct ioapic_route_entry both;
+};
 
 typedef struct ApicLocalUnit {
         ApicReg reserved0;               /* 0x000 */
@@ -82,11 +103,14 @@ typedef struct ApicLocalUnit {
 typedef struct IoApicData {
         uint8_t  apic_id;
         uint32_t addr;
-        uint32_t base;
+        uint32_t gsi_base;
+        ApicIoUnit *ioapic;
 } IoApicData;
 
 #define APIC_IRQ_OVERRIDE_ACTIVE_LOW 2
+#define APIC_IRQ_OVERRIDE_POLARITY_MASK 1
 #define APIC_IRQ_OVERRIDE_LEVEL_TRIGGERED 8
+#define APIC_IRQ_OVERRIDE_TRIGGER_MASK 4
 
 typedef struct IrqOverrideData {
         uint8_t  bus;
@@ -112,14 +136,28 @@ void apic_add_cpu(uint16_t apic_id);
 void apic_lapic_init(ApicLocalUnit* lapic_ptr);
 void apic_add_ioapic(struct IoApicData);
 void apic_add_irq_override(struct IrqOverrideData irq_over);
+IrqOverrideData *acpi_get_irq_override(uint8_t gsi);
 uint16_t apic_get_cpu_apic_id(int kernel_id);
 volatile ApicLocalUnit* apic_get_lapic(void);
-struct IoApicData apic_get_ioapic(int kernel_id);
+struct IoApicData *apic_get_ioapic(int kernel_id);
 uint8_t apic_get_numcpus(void);
 uint8_t apic_get_num_ioapics(void);
 uint16_t apic_get_current_cpu(void);
 void apic_print_info(void);
 int apic_refit_cpulist(void);
+void picdisable(void);
+void lapic_eoi(void);
+void ioapic_irq_eoi(int pin);
+void lapic_enable_timer(void);
+void ioapic_mask_irqs(void);
+void ioapic_toggle(int pin, int mask);
+void ioapic_configure(void);
+
+extern int timer_pin;
+extern void intnull(int unit);
+extern volatile ApicLocalUnit* lapic;
+extern inline void mask_irq (unsigned int irq_nr);
+extern inline void unmask_irq (unsigned int irq_nr);
 
 #endif
 
@@ -128,6 +166,35 @@ int apic_refit_cpulist(void);
 #define APIC_IO_REDIR_LOW(int_pin)     (0x10+(int_pin)*2)
 #define APIC_IO_REDIR_HIGH(int_pin)    (0x11+(int_pin)*2)
 
+#define IMCR_SELECT    0x22
+#define IMCR_DATA      0x23
+#define MODE_IMCR      0x70
+# define IMCR_USE_PIC  0
+# define IMCR_USE_APIC 1
+
+#define LAPIC_ENABLE                   0x100
+#define LAPIC_NMI                      0x400
+#define LAPIC_DISABLE                  0x10000
+#define LAPIC_TIMER_PERIODIC           0x20000
+#define LAPIC_TIMER_DIVIDE_2           0
+#define LAPIC_TIMER_DIVIDE_4           1
+#define LAPIC_TIMER_DIVIDE_8           2
+#define LAPIC_TIMER_DIVIDE_16          3
+#define LAPIC_TIMER_BASEDIV            0x100000
+
+#define NINTR                          24
+#define IOAPIC_FIXED                   0
+#define IOAPIC_PHYSICAL                0
+#define IOAPIC_LOGICAL                 1
+#define IOAPIC_NMI                     4
+#define IOAPIC_EXTINT                  7
+#define IOAPIC_ACTIVE_HIGH             0
+#define IOAPIC_ACTIVE_LOW              1
+#define IOAPIC_EDGE_TRIGGERED          0
+#define IOAPIC_LEVEL_TRIGGERED         1
+#define IOAPIC_MASK_ENABLED            0
+#define IOAPIC_MASK_DISABLED           1
+
 /* Set or clear a bit in a 255-bit APIC mask register.
    These registers are spread through eight 32-bit registers.  */
 #define APIC_SET_MASK_BIT(reg, bit) \
diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
index af70934d..990d2d43 100644
--- a/i386/i386at/acpi_parse_apic.c
+++ b/i386/i386at/acpi_parse_apic.c
@@ -326,8 +326,10 @@ acpi_apic_add_ioapic(struct acpi_apic_ioapic *ioapic_entry)
     /* Fill IOAPIC structure with its main fields */
     io_apic.apic_id = ioapic_entry->apic_id;
     io_apic.addr = ioapic_entry->addr;
-    io_apic.base = ioapic_entry->base;
-
+    io_apic.gsi_base = ioapic_entry->gsi_base;
+    io_apic.ioapic = (ApicIoUnit *)kmem_map_aligned_table(ioapic_entry->addr,
+                                                          sizeof(ApicIoUnit),
+                                                          VM_PROT_READ | 
VM_PROT_WRITE);
     /* Insert IOAPIC in the list. */
     apic_add_ioapic(io_apic);
 }
@@ -449,7 +451,7 @@ static int
 acpi_apic_setup(struct acpi_apic *apic)
 {
     int apic_checksum;
-    ApicLocalUnit* lapic;
+    ApicLocalUnit* lapic_unit;
     uint8_t ncpus, nioapics;
 
     /* Check the checksum of the APIC */
@@ -459,12 +461,13 @@ acpi_apic_setup(struct acpi_apic *apic)
         return ACPI_BAD_CHECKSUM;
 
     /* map common lapic address */
-    lapic = kmem_map_aligned_table(apic->lapic_addr, sizeof(ApicLocalUnit), 
VM_PROT_READ);
+    lapic_unit = kmem_map_aligned_table(apic->lapic_addr, 
sizeof(ApicLocalUnit),
+                                        VM_PROT_READ | VM_PROT_WRITE);
 
-    if (lapic == NULL)
+    if (lapic_unit == NULL)
         return ACPI_NO_LAPIC;
 
-    apic_lapic_init(lapic);
+    apic_lapic_init(lapic_unit);
     acpi_apic_parse_table(apic);
 
     ncpus = apic_get_numcpus();
diff --git a/i386/i386at/acpi_parse_apic.h b/i386/i386at/acpi_parse_apic.h
index d071da4f..97a59a2e 100644
--- a/i386/i386at/acpi_parse_apic.h
+++ b/i386/i386at/acpi_parse_apic.h
@@ -139,7 +139,7 @@ struct acpi_apic_ioapic {
     uint8_t     apic_id;
     uint8_t     reserved;
     uint32_t    addr;
-    uint32_t    base;
+    uint32_t    gsi_base;
 } __attribute__((__packed__));
 
 /*
-- 
2.30.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]