bug-hurd
[Top][All Lists]
Advanced

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

Re: [PATCH] Support up to two IOAPICs with up to 32 GSIs on each


From: Samuel Thibault
Subject: Re: [PATCH] Support up to two IOAPICs with up to 32 GSIs on each
Date: Mon, 29 Jan 2024 20:02:33 +0100
User-agent: NeoMutt/20170609 (1.8.3)

Applied, thanks!

Damien Zammit, le lun. 29 janv. 2024 10:06:57 +0000, a ecrit:
> Previously, only IOAPIC[0] was supported.
> Now this supports up to two IOAPICs.
> 
> ---
>  i386/i386/apic.c              | 13 +++++
>  i386/i386/apic.h              |  6 ++-
>  i386/i386/locore.S            | 43 +++++++++++++++++
>  i386/i386at/acpi_parse_apic.c |  3 ++
>  i386/i386at/int_init.c        |  6 ++-
>  i386/i386at/ioapic.c          | 89 +++++++++++++++++++++++++++++++++--
>  6 files changed, 153 insertions(+), 7 deletions(-)
> 
> diff --git a/i386/i386/apic.c b/i386/i386/apic.c
> index 3a51f506..0cf7c37c 100644
> --- a/i386/i386/apic.c
> +++ b/i386/i386/apic.c
> @@ -179,6 +179,19 @@ apic_get_num_ioapics(void)
>      return apic_data.nioapics;
>  }
>  
> +/* apic_get_total_gsis: returns the total number of GSIs in the system. */
> +int
> +apic_get_total_gsis(void)
> +{
> +    int id;
> +    int gsis = 0;
> +
> +    for (id = 0; id < apic_get_num_ioapics(); id++)
> +        gsis += apic_get_ioapic(id)->ngsis;
> +
> +    return gsis;
> +}
> +
>  /*
>   * apic_get_current_cpu: returns the apic_id of current cpu.
>   */
> diff --git a/i386/i386/apic.h b/i386/i386/apic.h
> index 9f908159..e410e9c6 100644
> --- a/i386/i386/apic.h
> +++ b/i386/i386/apic.h
> @@ -193,6 +193,7 @@ typedef struct ApicLocalUnit {
>  
>  typedef struct IoApicData {
>          uint8_t  apic_id;
> +        uint8_t  ngsis;
>          uint32_t addr;
>          uint32_t gsi_base;
>          ApicIoUnit *ioapic;
> @@ -239,6 +240,7 @@ int apic_get_current_cpu(void);
>  void apic_print_info(void);
>  int apic_refit_cpulist(void);
>  void apic_generate_cpu_id_lut(void);
> +int apic_get_total_gsis(void);
>  void picdisable(void);
>  void lapic_eoi(void);
>  void ioapic_irq_eoi(int pin);
> @@ -257,6 +259,8 @@ extern int cpu_id_lut[];
>  
>  #define APIC_IO_UNIT_ID                      0x00
>  #define APIC_IO_VERSION                      0x01
> +# define APIC_IO_VERSION_SHIFT               0
> +# define APIC_IO_ENTRIES_SHIFT               16
>  #define APIC_IO_REDIR_LOW(int_pin)   (0x10+(int_pin)*2)
>  #define APIC_IO_REDIR_HIGH(int_pin)  (0x11+(int_pin)*2)
>  
> @@ -283,7 +287,7 @@ extern int cpu_id_lut[];
>  #define LAPIC_TIMER_BASEDIV            0x100000
>  #define LAPIC_HAS_DIRECTED_EOI         0x1000000
>  
> -#define NINTR                          24
> +#define NINTR                          64 /* Max 32 GSIs on each of two 
> IOAPICs */
>  #define IOAPIC_FIXED                   0
>  #define IOAPIC_PHYSICAL                0
>  #define IOAPIC_LOGICAL                 1
> diff --git a/i386/i386/locore.S b/i386/i386/locore.S
> index df41722d..378297ff 100644
> --- a/i386/i386/locore.S
> +++ b/i386/i386/locore.S
> @@ -694,6 +694,49 @@ INTERRUPT(20)
>  INTERRUPT(21)
>  INTERRUPT(22)
>  INTERRUPT(23)
> +/* Possibly 8 more GSIs */
> +INTERRUPT(24)
> +INTERRUPT(25)
> +INTERRUPT(26)
> +INTERRUPT(27)
> +INTERRUPT(28)
> +INTERRUPT(29)
> +INTERRUPT(30)
> +INTERRUPT(31)
> +/* ... APIC IOAPIC #2 */
> +INTERRUPT(32)
> +INTERRUPT(33)
> +INTERRUPT(34)
> +INTERRUPT(35)
> +INTERRUPT(36)
> +INTERRUPT(37)
> +INTERRUPT(38)
> +INTERRUPT(39)
> +INTERRUPT(40)
> +INTERRUPT(41)
> +INTERRUPT(42)
> +INTERRUPT(43)
> +INTERRUPT(44)
> +INTERRUPT(45)
> +INTERRUPT(46)
> +INTERRUPT(47)
> +INTERRUPT(48)
> +INTERRUPT(49)
> +INTERRUPT(50)
> +INTERRUPT(51)
> +INTERRUPT(52)
> +INTERRUPT(53)
> +INTERRUPT(54)
> +INTERRUPT(55)
> +/* Possibly 8 more GSIs */
> +INTERRUPT(56)
> +INTERRUPT(57)
> +INTERRUPT(58)
> +INTERRUPT(59)
> +INTERRUPT(60)
> +INTERRUPT(61)
> +INTERRUPT(62)
> +INTERRUPT(63)
>  #endif
>  #if NCPUS > 1
>  INTERRUPT(CALL_AST_CHECK)
> diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
> index 9cd861ed..1aef53ed 100644
> --- a/i386/i386at/acpi_parse_apic.c
> +++ b/i386/i386at/acpi_parse_apic.c
> @@ -331,6 +331,9 @@ acpi_apic_add_ioapic(struct acpi_apic_ioapic 
> *ioapic_entry)
>      io_apic.ioapic = (ApicIoUnit *)kmem_map_aligned_table(ioapic_entry->addr,
>                                                            sizeof(ApicIoUnit),
>                                                            VM_PROT_READ | 
> VM_PROT_WRITE);
> +    io_apic.ioapic->select.r = APIC_IO_VERSION;
> +    io_apic.ngsis = ((io_apic.ioapic->window.r >> APIC_IO_ENTRIES_SHIFT) & 
> 0xff) + 1;
> +
>      /* Insert IOAPIC in the list. */
>      apic_add_ioapic(io_apic);
>  }
> diff --git a/i386/i386at/int_init.c b/i386/i386at/int_init.c
> index d55d7a48..262bef1b 100644
> --- a/i386/i386at/int_init.c
> +++ b/i386/i386at/int_init.c
> @@ -24,6 +24,10 @@
>  #include <i386at/idt.h>
>  #include <i386at/int_init.h>
>  #include <i386/mp_desc.h>
> +#include <kern/printf.h>
> +#ifdef APIC
> +#include <i386/apic.h>
> +#endif
>  
>  /* defined in locore.S */
>  extern vm_offset_t int_entry_table[];
> @@ -37,7 +41,7 @@ int_fill(struct real_gate *myidt)
>       int nirq = 16;
>  #else
>       int base = IOAPIC_INT_BASE;
> -     int nirq = 24;
> +     int nirq = NINTR;
>  #endif
>  
>       for (i = 0; i < nirq; i++) {
> diff --git a/i386/i386at/ioapic.c b/i386/i386at/ioapic.c
> index fb73eab7..270362c3 100644
> --- a/i386/i386at/ioapic.c
> +++ b/i386/i386at/ioapic.c
> @@ -46,7 +46,13 @@ int spl_init = 0;
>  def_simple_lock_irq_data(static, ioapic_lock)        /* Lock for non-atomic 
> window accesses to ioapic */
>  
>  int iunit[NINTR] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
> -                    16, 17, 18, 19, 20, 21, 22, 23};
> +                    16, 17, 18, 19, 20, 21, 22, 23,
> +                 24, 25, 26, 27, 28, 29, 30, 31,
> +                 /* 2nd IOAPIC */
> +                 32, 33, 34, 35, 36, 37, 38, 39,
> +                 40, 41, 42, 43, 44, 45, 46, 47,
> +                 48, 49, 50, 51, 52, 53, 54, 55,
> +                 56, 57, 58, 59, 60, 61, 62, 63 };
>  
>  interrupt_handler_fn ivect[NINTR] = {
>      /* 00 */ (interrupt_handler_fn)hardclock,
> @@ -77,6 +83,49 @@ interrupt_handler_fn ivect[NINTR] = {
>      /* 21 */ intnull,        /* PIRQF */
>      /* 22 */ intnull,        /* PIRQG */
>      /* 23 */ intnull,        /* PIRQH */
> +
> +    /* 24 */ intnull,
> +    /* 25 */ intnull,
> +    /* 26 */ intnull,
> +    /* 27 */ intnull,
> +    /* 28 */ intnull,
> +    /* 29 */ intnull,
> +    /* 30 */ intnull,
> +    /* 31 */ intnull,
> +
> +    /* 32 */ intnull,
> +    /* 33 */ intnull,
> +    /* 34 */ intnull,
> +    /* 35 */ intnull,
> +    /* 36 */ intnull,
> +    /* 37 */ intnull,
> +    /* 38 */ intnull,
> +    /* 39 */ intnull,
> +    /* 40 */ intnull,
> +    /* 41 */ intnull,
> +    /* 42 */ intnull,
> +    /* 43 */ intnull,
> +    /* 44 */ intnull,
> +    /* 45 */ intnull,
> +    /* 46 */ intnull,
> +    /* 47 */ intnull,
> +    /* 48 */ intnull,
> +    /* 49 */ intnull,
> +    /* 50 */ intnull,
> +    /* 51 */ intnull,
> +    /* 52 */ intnull,
> +    /* 53 */ intnull,
> +    /* 54 */ intnull,
> +    /* 55 */ intnull,
> +
> +    /* 56 */ intnull,
> +    /* 57 */ intnull,
> +    /* 58 */ intnull,
> +    /* 59 */ intnull,
> +    /* 60 */ intnull,
> +    /* 61 */ intnull,
> +    /* 62 */ intnull,
> +    /* 63 */ intnull,
>  };
>  
>  void
> @@ -155,7 +204,13 @@ ioapic_toggle_entry(int apic, int pin, int mask)
>  static int
>  ioapic_version(int apic)
>  {
> -    return ioapic_read(apic, APIC_IO_VERSION) & 0xff;
> +    return (ioapic_read(apic, APIC_IO_VERSION) >> APIC_IO_VERSION_SHIFT) & 
> 0xff;
> +}
> +
> +static int
> +ioapic_gsis(int apic)
> +{
> +    return ((ioapic_read(apic, APIC_IO_VERSION) >> APIC_IO_ENTRIES_SHIFT) & 
> 0xff) + 1;
>  }
>  
>  static void timer_expiry_callback(void *arg)
> @@ -315,6 +370,8 @@ ioapic_configure(void)
>      IrqOverrideData *irq_over;
>      int timer_gsi;
>      int version = ioapic_version(apic);
> +    int ngsis = ioapic_gsis(apic);
> +    int ngsis2 = 0;
>  
>      if (version >= 0x20) {
>          has_irq_specific_eoi = 1;
> @@ -362,7 +419,7 @@ ioapic_configure(void)
>          }
>      }
>  
> -    for (pin = 16; pin < 24; pin++) {
> +    for (pin = 16; pin < ngsis; pin++) {
>          gsi = pin;
>  
>          /* PCI IRQs PIRQ A-H */
> @@ -376,8 +433,30 @@ ioapic_configure(void)
>          ioapic_write_entry(apic, pin, entry.both);
>      }
>  
> +    printf("IOAPIC 0 configured with GSI 0-%d\n", ngsis - 1);
> +
> +    /* Second IOAPIC */
> +    if (apic_get_num_ioapics() > 1) {
> +        apic = 1;
> +        ngsis2 = ioapic_gsis(apic);
> +
> +        for (pin = 0; pin < ngsis2; pin++) {
> +            gsi = pin + ngsis;
> +
> +            /* Defaults */
> +            entry.both.trigger = IOAPIC_LEVEL_TRIGGERED;
> +            entry.both.polarity = IOAPIC_ACTIVE_LOW;
> +
> +            if ((irq_over = acpi_get_irq_override(pin + ngsis))) {
> +                gsi = override_irq(irq_over, &entry);
> +            }
> +            entry.both.vector = IOAPIC_INT_BASE + gsi;
> +            ioapic_write_entry(apic, pin, entry.both);
> +        }
> +
> +        printf("IOAPIC 1 configured with GSI %d-%d\n", ngsis, ngsis + ngsis2 
> - 1);
> +    }
> +
>      /* Start the IO APIC receiving interrupts */
>      lapic_enable();
> -
> -    printf("IOAPIC 0 configured\n");
>  }
> -- 
> 2.43.0
> 
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



reply via email to

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