From 5ac5ccd2c6f251f847f232e3c722d5bc766d77f1 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Wed, 31 Aug 2011 17:09:06 +0800 Subject: [PATCH] ioapic/x86_64: Rearrange pin information for ioapic low level intrhandler - Remove unused field, thus reduce the information size from 32 bytes to 16bytes. - Struct, field and macro renaming --- sys/platform/pc64/apic/apic_vector.s | 16 +++--- sys/platform/pc64/apic/ioapic_abi.c | 80 +++++++++++++--------------- sys/platform/pc64/apic/ioapic_abi.h | 23 ++++---- sys/platform/pc64/apic/ioapic_ipl.s | 16 +++--- sys/platform/pc64/x86_64/genassym.c | 14 ++--- 5 files changed, 70 insertions(+), 79 deletions(-) diff --git a/sys/platform/pc64/apic/apic_vector.s b/sys/platform/pc64/apic/apic_vector.s index 5e662b9b1e..f9de780739 100644 --- a/sys/platform/pc64/apic/apic_vector.s +++ b/sys/platform/pc64/apic/apic_vector.s @@ -55,17 +55,17 @@ #define APIC_POP_FRAME POP_FRAME #define IOAPICADDR(irq_num) \ - CNAME(int_to_apicintpin) + IOAPIC_IM_SIZE * (irq_num) + IOAPIC_IM_ADDR + CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_ADDR #define REDIRIDX(irq_num) \ - CNAME(int_to_apicintpin) + IOAPIC_IM_SIZE * (irq_num) + IOAPIC_IM_ENTIDX + CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_IDX #define IOAPICFLAGS(irq_num) \ - CNAME(int_to_apicintpin) + IOAPIC_IM_SIZE * (irq_num) + IOAPIC_IM_FLAGS + CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_FLAGS #define MASK_IRQ(irq_num) \ IOAPIC_IMASK_LOCK ; /* into critical reg */ \ - testl $IOAPIC_IM_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ + testl $IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ jne 7f ; /* masked, don't mask */ \ - orl $IOAPIC_IM_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ + orl $IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ /* set the mask bit */ \ movq IOAPICADDR(irq_num), %rcx ; /* ioapic addr */ \ movl REDIRIDX(irq_num), %eax ; /* get the index */ \ @@ -80,7 +80,7 @@ * and the EOI cycle would cause redundant INTs to occur. */ #define MASK_LEVEL_IRQ(irq_num) \ - testl $IOAPIC_IM_FLAG_LEVEL, IOAPICFLAGS(irq_num) ; \ + testl $IOAPIC_IRQI_FLAG_LEVEL, IOAPICFLAGS(irq_num) ; \ jz 9f ; /* edge, don't mask */ \ MASK_IRQ(irq_num) ; \ 9: ; \ @@ -92,9 +92,9 @@ cmpl $0,%eax ; \ jnz 8f ; \ IOAPIC_IMASK_LOCK ; /* into critical reg */ \ - testl $IOAPIC_IM_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ + testl $IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ je 7f ; /* bit clear, not masked */ \ - andl $~IOAPIC_IM_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ + andl $~IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ; \ /* clear mask bit */ \ movq IOAPICADDR(irq_num),%rcx ; /* ioapic addr */ \ movl REDIRIDX(irq_num), %eax ; /* get the index */ \ diff --git a/sys/platform/pc64/apic/ioapic_abi.c b/sys/platform/pc64/apic/ioapic_abi.c index 05f4e833a1..b0d088235f 100644 --- a/sys/platform/pc64/apic/ioapic_abi.c +++ b/sys/platform/pc64/apic/ioapic_abi.c @@ -505,7 +505,7 @@ struct machintr_abi MachIntrABI_IOAPIC = { static int ioapic_abi_extint_irq = -1; -struct apic_intmapinfo int_to_apicintpin[IOAPIC_HWI_VECTORS]; +struct ioapic_irqinfo ioapic_irqs[IOAPIC_HWI_VECTORS]; static void ioapic_abi_intren(int irq) @@ -586,6 +586,9 @@ ioapic_vectorctl(int op, int intr, int flags) intr == IOAPIC_HWI_SYSCALL) return EINVAL; + if (ioapic_irqs[intr].io_addr == NULL) + return EINVAL; + ef = read_rflags(); cpu_disable_intr(); error = 0; @@ -602,21 +605,18 @@ ioapic_vectorctl(int op, int intr, int flags) * first, then reprogrammed with the new vector. This should * clear the IRR bit. */ - if (int_to_apicintpin[intr].ioapic >= 0) { - imen_lock(); + imen_lock(); - select = int_to_apicintpin[intr].redirindex; - value = ioapic_read(int_to_apicintpin[intr].apic_address, - select); - value |= IOART_INTMSET; + select = ioapic_irqs[intr].io_idx; + value = ioapic_read(ioapic_irqs[intr].io_addr, select); + value |= IOART_INTMSET; - ioapic_write(int_to_apicintpin[intr].apic_address, - select, (value & ~APIC_TRIGMOD_MASK)); - ioapic_write(int_to_apicintpin[intr].apic_address, - select, (value & ~IOART_INTVEC) | vector); + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~APIC_TRIGMOD_MASK)); + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~IOART_INTVEC) | vector); - imen_unlock(); - } + imen_unlock(); machintr_intren(intr); break; @@ -637,20 +637,18 @@ ioapic_vectorctl(int op, int intr, int flags) * edge-triggering first, then reprogrammed with the new vector. * This should clear the IRR bit. */ - if (int_to_apicintpin[intr].ioapic >= 0) { - imen_lock(); + imen_lock(); - select = int_to_apicintpin[intr].redirindex; - value = ioapic_read(int_to_apicintpin[intr].apic_address, - select); + select = ioapic_irqs[intr].io_idx; + value = ioapic_read(ioapic_irqs[intr].io_addr, select); - ioapic_write(int_to_apicintpin[intr].apic_address, - select, (value & ~APIC_TRIGMOD_MASK)); - ioapic_write(int_to_apicintpin[intr].apic_address, - select, (value & ~IOART_INTVEC) | vector); + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~APIC_TRIGMOD_MASK)); + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~IOART_INTVEC) | vector); + + imen_unlock(); - imen_unlock(); - } break; default: @@ -689,7 +687,7 @@ void ioapic_abi_set_irqmap(int irq, int gsi, enum intr_trigger trig, enum intr_polarity pola) { - struct apic_intmapinfo *info; + struct ioapic_irqinfo *info; struct ioapic_irqmap *map; void *ioaddr; int pin; @@ -717,17 +715,15 @@ ioapic_abi_set_irqmap(int irq, int gsi, enum intr_trigger trig, pin = ioapic_gsi_pin(map->im_gsi); ioaddr = ioapic_gsi_ioaddr(map->im_gsi); - info = &int_to_apicintpin[irq]; + info = &ioapic_irqs[irq]; imen_lock(); - info->ioapic = 0; /* XXX unused */ - info->int_pin = pin; - info->apic_address = ioaddr; - info->redirindex = IOAPIC_REDTBL + (2 * pin); - info->flags = IOAPIC_IM_FLAG_MASKED; + info->io_addr = ioaddr; + info->io_idx = IOAPIC_REDTBL + (2 * pin); + info->io_flags = IOAPIC_IRQI_FLAG_MASKED; if (map->im_trig == INTR_TRIGGER_LEVEL) - info->flags |= IOAPIC_IM_FLAG_LEVEL; + info->io_flags |= IOAPIC_IRQI_FLAG_LEVEL; ioapic_pin_setup(ioaddr, pin, IDT_OFFSET + irq, map->im_trig, map->im_pola); @@ -801,7 +797,7 @@ ioapic_abi_find_irq(int irq, enum intr_trigger trig, enum intr_polarity pola) static void ioapic_intr_config(int irq, enum intr_trigger trig, enum intr_polarity pola) { - struct apic_intmapinfo *info; + struct ioapic_irqinfo *info; struct ioapic_irqmap *map; void *ioaddr; int pin; @@ -848,13 +844,13 @@ ioapic_intr_config(int irq, enum intr_trigger trig, enum intr_polarity pola) pin = ioapic_gsi_pin(map->im_gsi); ioaddr = ioapic_gsi_ioaddr(map->im_gsi); - info = &int_to_apicintpin[irq]; + info = &ioapic_irqs[irq]; imen_lock(); - info->flags &= ~IOAPIC_IM_FLAG_LEVEL; + info->io_flags &= ~IOAPIC_IRQI_FLAG_LEVEL; if (map->im_trig == INTR_TRIGGER_LEVEL) - info->flags |= IOAPIC_IM_FLAG_LEVEL; + info->io_flags |= IOAPIC_IRQI_FLAG_LEVEL; ioapic_pin_setup(ioaddr, pin, IDT_OFFSET + irq, map->im_trig, map->im_pola); @@ -865,7 +861,7 @@ ioapic_intr_config(int irq, enum intr_trigger trig, enum intr_polarity pola) int ioapic_abi_extint_irqmap(int irq) { - struct apic_intmapinfo *info; + struct ioapic_irqinfo *info; struct ioapic_irqmap *map; void *ioaddr; int pin, error, vec; @@ -909,15 +905,13 @@ ioapic_abi_extint_irqmap(int irq) pin = ioapic_gsi_pin(map->im_gsi); ioaddr = ioapic_gsi_ioaddr(map->im_gsi); - info = &int_to_apicintpin[irq]; + info = &ioapic_irqs[irq]; imen_lock(); - info->ioapic = 0; /* XXX unused */ - info->int_pin = pin; - info->apic_address = ioaddr; - info->redirindex = IOAPIC_REDTBL + (2 * pin); - info->flags = IOAPIC_IM_FLAG_MASKED; + info->io_addr = ioaddr; + info->io_idx = IOAPIC_REDTBL + (2 * pin); + info->io_flags = IOAPIC_IRQI_FLAG_MASKED; ioapic_extpin_setup(ioaddr, pin, vec); diff --git a/sys/platform/pc64/apic/ioapic_abi.h b/sys/platform/pc64/apic/ioapic_abi.h index 0a9d67f887..343d66b780 100644 --- a/sys/platform/pc64/apic/ioapic_abi.h +++ b/sys/platform/pc64/apic/ioapic_abi.h @@ -47,23 +47,20 @@ /* * NOTE: - * - Keep size of apic_intmapinfo power of 2 - * - Update IOAPIC_IM_SZSHIFT after changing apic_intmapinfo size + * - Keep size of ioapic_irqinfo power of 2 + * - Update IOAPIC_IRQI_SZSHIFT after changing ioapic_irqinfo size */ -struct apic_intmapinfo { - int ioapic; - int int_pin; - volatile void *apic_address; - int redirindex; - uint32_t flags; /* IOAPIC_IM_FLAG_ */ - uint32_t pad[2]; +struct ioapic_irqinfo { + uint32_t io_flags; /* IOAPIC_IRQI_FLAG_ */ + int io_idx; + volatile void *io_addr; }; -#define IOAPIC_IM_SZSHIFT 5 +#define IOAPIC_IRQI_SZSHIFT 4 -#define IOAPIC_IM_FLAG_LEVEL 0x1 /* default to edge trigger */ -#define IOAPIC_IM_FLAG_MASKED 0x2 +#define IOAPIC_IRQI_FLAG_LEVEL 0x1 /* default to edge trigger */ +#define IOAPIC_IRQI_FLAG_MASKED 0x2 -extern struct apic_intmapinfo int_to_apicintpin[]; +extern struct ioapic_irqinfo ioapic_irqs[]; extern struct machintr_abi MachIntrABI_IOAPIC; diff --git a/sys/platform/pc64/apic/ioapic_ipl.s b/sys/platform/pc64/apic/ioapic_ipl.s index 430e03c87c..334327acf2 100644 --- a/sys/platform/pc64/apic/ioapic_ipl.s +++ b/sys/platform/pc64/apic/ioapic_ipl.s @@ -77,10 +77,10 @@ ENTRY(IOAPIC_INTRDIS) IOAPIC_IMASK_LOCK /* enter critical reg */ movl %edi, %eax 1: - shll $IOAPIC_IM_SZSHIFT, %eax - orl $IOAPIC_IM_FLAG_MASKED, CNAME(int_to_apicintpin) + IOAPIC_IM_FLAGS(%rax) - movq CNAME(int_to_apicintpin) + IOAPIC_IM_ADDR(%rax), %rdx - movl CNAME(int_to_apicintpin) + IOAPIC_IM_ENTIDX(%rax), %ecx + shll $IOAPIC_IRQI_SZSHIFT, %eax + orl $IOAPIC_IRQI_FLAG_MASKED, CNAME(ioapic_irqs) + IOAPIC_IRQI_FLAGS(%rax) + movq CNAME(ioapic_irqs) + IOAPIC_IRQI_ADDR(%rax), %rdx + movl CNAME(ioapic_irqs) + IOAPIC_IRQI_IDX(%rax), %ecx testq %rdx, %rdx jz 2f movl %ecx, (%rdx) /* target register index */ @@ -94,10 +94,10 @@ ENTRY(IOAPIC_INTREN) IOAPIC_IMASK_LOCK /* enter critical reg */ movl %edi, %eax 1: - shll $IOAPIC_IM_SZSHIFT, %eax - andl $~IOAPIC_IM_FLAG_MASKED, CNAME(int_to_apicintpin) + IOAPIC_IM_FLAGS(%rax) - movq CNAME(int_to_apicintpin) + IOAPIC_IM_ADDR(%rax), %rdx - movl CNAME(int_to_apicintpin) + IOAPIC_IM_ENTIDX(%rax), %ecx + shll $IOAPIC_IRQI_SZSHIFT, %eax + andl $~IOAPIC_IRQI_FLAG_MASKED, CNAME(ioapic_irqs) + IOAPIC_IRQI_FLAGS(%rax) + movq CNAME(ioapic_irqs) + IOAPIC_IRQI_ADDR(%rax), %rdx + movl CNAME(ioapic_irqs) + IOAPIC_IRQI_IDX(%rax), %ecx testq %rdx, %rdx jz 2f movl %ecx, (%rdx) /* write the target register index */ diff --git a/sys/platform/pc64/x86_64/genassym.c b/sys/platform/pc64/x86_64/genassym.c index cc412ec840..446361e321 100644 --- a/sys/platform/pc64/x86_64/genassym.c +++ b/sys/platform/pc64/x86_64/genassym.c @@ -239,10 +239,10 @@ ASSYM(CPUMASK_LOCK, CPUMASK_LOCK); ASSYM(CPUMASK_BIT, CPUMASK_BIT); #endif -ASSYM(IOAPIC_IM_ADDR, offsetof(struct apic_intmapinfo, apic_address)); -ASSYM(IOAPIC_IM_ENTIDX, offsetof(struct apic_intmapinfo, redirindex)); -ASSYM(IOAPIC_IM_FLAGS, offsetof(struct apic_intmapinfo, flags)); -ASSYM(IOAPIC_IM_SIZE, sizeof(struct apic_intmapinfo)); -ASSYM(IOAPIC_IM_SZSHIFT, IOAPIC_IM_SZSHIFT); -ASSYM(IOAPIC_IM_FLAG_LEVEL, IOAPIC_IM_FLAG_LEVEL); -ASSYM(IOAPIC_IM_FLAG_MASKED, IOAPIC_IM_FLAG_MASKED); +ASSYM(IOAPIC_IRQI_ADDR, offsetof(struct ioapic_irqinfo, io_addr)); +ASSYM(IOAPIC_IRQI_IDX, offsetof(struct ioapic_irqinfo, io_idx)); +ASSYM(IOAPIC_IRQI_FLAGS, offsetof(struct ioapic_irqinfo, io_flags)); +ASSYM(IOAPIC_IRQI_SIZE, sizeof(struct ioapic_irqinfo)); +ASSYM(IOAPIC_IRQI_SZSHIFT, IOAPIC_IRQI_SZSHIFT); +ASSYM(IOAPIC_IRQI_FLAG_LEVEL, IOAPIC_IRQI_FLAG_LEVEL); +ASSYM(IOAPIC_IRQI_FLAG_MASKED, IOAPIC_IRQI_FLAG_MASKED); -- 2.41.0