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.