Skip to content

Commit 915f4ac

Browse files
Tomasz Bursztykanashif
Tomasz Bursztyka
authored andcommitted
drivers/interrupt_controller: Get the IOAPIC RTEs dynamically
The fixed number of 24 RTEs is a legacy thing, and long gone by now. IOAPICs expose the maximum number of RTEs they have via the version register, so let's use it. This avoids to manually tweak a Kconfig option (which is now removed) and fixes the RTE number for all x86 targets relevantly. Signed-off-by: Tomasz Bursztyka <[email protected]>
1 parent a1ae45f commit 915f4ac

File tree

8 files changed

+49
-44
lines changed

8 files changed

+49
-44
lines changed

drivers/interrupt_controller/Kconfig.loapic

-11
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,6 @@ config IOAPIC
4949
This option signifies that the target has an IO-APIC device. This
5050
capability allows IO-APIC-dependent code to be included.
5151

52-
config IOAPIC_NUM_RTES
53-
int "Number of Redirection Table Entries available"
54-
default 24
55-
depends on IOAPIC
56-
help
57-
This option indicates the maximum number of Redirection Table Entries
58-
(RTEs) (one per IRQ available to the IO-APIC) made available to the
59-
kernel, regardless of the number provided by the hardware itself. For
60-
most efficient usage of memory, it should match the number of IRQ lines
61-
needed by devices connected to the IO-APIC.
62-
6352
config IOAPIC_MASK_RTE
6453
bool "Mask out RTE entries on boot"
6554
default y

drivers/interrupt_controller/intc_ioapic.c

+29-19
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,6 @@
6767
DEVICE_MMIO_TOPLEVEL_STATIC(ioapic_regs, DT_DRV_INST(0));
6868

6969
#define IOAPIC_REG DEVICE_MMIO_TOPLEVEL_GET(ioapic_regs)
70-
#define BITS_PER_IRQ 4
71-
#define IOAPIC_BITFIELD_HI_LO 0
72-
#define IOAPIC_BITFIELD_LVL_EDGE 1
73-
#define IOAPIC_BITFIELD_ENBL_DSBL 2
74-
#define IOAPIC_BITFIELD_DELIV_MODE 3
75-
#define BIT_POS_FOR_IRQ_OPTION(irq, option) ((irq) * BITS_PER_IRQ + (option))
76-
#define SUSPEND_BITS_REQD (ROUND_UP((CONFIG_IOAPIC_NUM_RTES * BITS_PER_IRQ), 32))
7770

7871
/*
7972
* Destination field (bits[56:63]) defines a set of processors, which is
@@ -92,10 +85,27 @@ DEVICE_MMIO_TOPLEVEL_STATIC(ioapic_regs, DT_DRV_INST(0));
9285
*/
9386
#define DEFAULT_RTE_DEST (0xFF << 24)
9487

88+
static uint32_t ioapic_rtes;
89+
9590
#ifdef CONFIG_PM_DEVICE
9691
#include <power/power.h>
92+
93+
#define BITS_PER_IRQ 4
94+
#define IOAPIC_BITFIELD_HI_LO 0
95+
#define IOAPIC_BITFIELD_LVL_EDGE 1
96+
#define IOAPIC_BITFIELD_ENBL_DSBL 2
97+
#define IOAPIC_BITFIELD_DELIV_MODE 3
98+
99+
#define BIT_POS_FOR_IRQ_OPTION(irq, option) ((irq) * BITS_PER_IRQ + (option))
100+
101+
/* Allocating up to 256 irq bits bufffer for RTEs, RTEs are dynamically found
102+
* so let's just assume the maximum, it's only 128 bytes in total.
103+
*/
104+
#define SUSPEND_BITS_REQD (ROUND_UP((256 * BITS_PER_IRQ), 32))
105+
97106
uint32_t ioapic_suspend_buf[SUSPEND_BITS_REQD / 32] = {0};
98107
static uint32_t ioapic_device_power_state = DEVICE_PM_ACTIVE_STATE;
108+
99109
#endif
100110

101111
static uint32_t __IoApicGet(int32_t offset);
@@ -126,30 +136,30 @@ int ioapic_init(const struct device *unused)
126136

127137
DEVICE_MMIO_TOPLEVEL_MAP(ioapic_regs, K_MEM_CACHE_NONE);
128138

139+
/* Reading MRE: this will give the number of RTEs available */
140+
ioapic_rtes = ((__IoApicGet(IOAPIC_VERS) &
141+
IOAPIC_MRE_MASK) >> IOAPIC_MRE_POS) + 1;
142+
129143
#ifdef CONFIG_IOAPIC_MASK_RTE
130144
int32_t ix; /* redirection table index */
131145
uint32_t rteValue; /* value to copy into redirection table entry */
132146

133-
/*
134-
* The platform must set the Kconfig option IOAPIC_NUM_RTES to indicate
135-
* the number of redirection table entries supported by the IOAPIC.
136-
*
137-
* Note: The number of actual IRQs supported by the IOAPIC can be
138-
* determined at runtime by computing:
139-
*
140-
* ((__IoApicGet(IOAPIC_VERS) & IOAPIC_MRE_MASK) >> 16) + 1
141-
*/
142147
rteValue = IOAPIC_EDGE | IOAPIC_HIGH | IOAPIC_FIXED | IOAPIC_INT_MASK |
143148
IOAPIC_LOGICAL | 0 /* dummy vector */;
144149

145-
for (ix = 0; ix < CONFIG_IOAPIC_NUM_RTES; ix++) {
150+
for (ix = 0; ix < ioapic_rtes; ix++) {
146151
ioApicRedSetHi(ix, DEFAULT_RTE_DEST);
147152
ioApicRedSetLo(ix, rteValue);
148153
}
149154
#endif
150155
return 0;
151156
}
152157

158+
uint32_t z_ioapic_num_rtes(void)
159+
{
160+
return ioapic_rtes;
161+
}
162+
153163
/**
154164
*
155165
* @brief Enable a specified APIC interrupt input line
@@ -244,7 +254,7 @@ int ioapic_suspend(const struct device *port)
244254

245255
ARG_UNUSED(port);
246256
(void)memset(ioapic_suspend_buf, 0, (SUSPEND_BITS_REQD >> 3));
247-
for (irq = 0; irq < CONFIG_IOAPIC_NUM_RTES; irq++) {
257+
for (irq = 0; irq < ioapic_rtes; irq++) {
248258
/*
249259
* The following check is to figure out the registered
250260
* IRQ lines, so as to limit ourselves to saving the
@@ -267,7 +277,7 @@ int ioapic_resume_from_suspend(const struct device *port)
267277

268278
ARG_UNUSED(port);
269279

270-
for (irq = 0; irq < CONFIG_IOAPIC_NUM_RTES; irq++) {
280+
for (irq = 0; irq < ioapic_rtes; irq++) {
271281
if (_irq_to_interrupt_vector[irq]) {
272282
/* Get the saved flags */
273283
flags = restore_flags(irq);

drivers/interrupt_controller/intc_ioapic_priv.h

+1-4
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,10 @@
3333
/* Version register bits */
3434

3535
#define IOAPIC_MRE_MASK 0x00ff0000 /* Max Red. entry mask */
36+
#define IOAPIC_MRE_POS 16
3637
#define IOAPIC_PRQ 0x00008000 /* this has IRQ reg */
3738
#define IOAPIC_VERSION 0x000000ff /* version number */
3839

39-
/* Redirection table entry number */
40-
41-
#define MAX_REDTABLE_ENTRIES 24
42-
4340
/* Redirection table entry bits: upper 32 bit */
4441

4542
#define IOAPIC_DESTINATION 0xff000000

drivers/interrupt_controller/intc_loapic.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <drivers/interrupt_controller/loapic.h> /* public API declarations */
2121
#include <device.h>
2222
#include <drivers/interrupt_controller/sysapic.h>
23+
#include <drivers/interrupt_controller/ioapic.h>
2324

2425
/* Local APIC Version Register Bits */
2526

@@ -192,6 +193,12 @@ static int loapic_init(const struct device *unused)
192193
return 0;
193194
}
194195

196+
197+
uint32_t z_loapic_irq_base(void)
198+
{
199+
return z_ioapic_num_rtes();
200+
}
201+
195202
/**
196203
*
197204
* @brief Set the vector field in the specified RTE
@@ -344,7 +351,7 @@ static int loapic_suspend(const struct device *port)
344351

345352
for (loapic_irq = 0; loapic_irq < LOAPIC_IRQ_COUNT; loapic_irq++) {
346353

347-
if (_irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]) {
354+
if (_irq_to_interrupt_vector[z_loapic_irq_base() + loapic_irq]) {
348355

349356
/* Since vector numbers are already present in RAM/ROM,
350357
* We save only the mask bits here.
@@ -374,10 +381,11 @@ int loapic_resume(const struct device *port)
374381

375382
for (loapic_irq = 0; loapic_irq < LOAPIC_IRQ_COUNT; loapic_irq++) {
376383

377-
if (_irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]) {
384+
if (_irq_to_interrupt_vector[z_loapic_irq_base() + loapic_irq]) {
378385
/* Configure vector and enable the required ones*/
379386
z_loapic_int_vec_set(loapic_irq,
380-
_irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]);
387+
_irq_to_interrupt_vector[z_loapic_irq_base() +
388+
loapic_irq]);
381389

382390
if (sys_bitfield_test_bit((mem_addr_t) loapic_suspend_buf,
383391
loapic_irq)) {

drivers/interrupt_controller/intc_system_apic.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
#include <drivers/interrupt_controller/sysapic.h>
1919
#include <irq.h>
2020

21-
#define IS_IOAPIC_IRQ(irq) (irq < LOAPIC_IRQ_BASE)
22-
#define HARDWARE_IRQ_LIMIT ((LOAPIC_IRQ_BASE + LOAPIC_IRQ_COUNT) - 1)
21+
#define IS_IOAPIC_IRQ(irq) (irq < z_loapic_irq_base())
22+
#define HARDWARE_IRQ_LIMIT ((z_loapic_irq_base() + LOAPIC_IRQ_COUNT) - 1)
2323

2424
/**
2525
*
@@ -33,7 +33,7 @@
3333
*
3434
* The Galileo board virtualizes IRQs as follows:
3535
*
36-
* - The first CONFIG_IOAPIC_NUM_RTES IRQs are provided by the IOAPIC so the
36+
* - The first z_ioapic_num_rtes() IRQs are provided by the IOAPIC so the
3737
* IOAPIC is programmed for these IRQs
3838
* - The remaining IRQs are provided by the LOAPIC and hence the LOAPIC is
3939
* programmed.
@@ -51,7 +51,7 @@ void z_irq_controller_irq_config(unsigned int vector, unsigned int irq,
5151
if (IS_IOAPIC_IRQ(irq)) {
5252
z_ioapic_irq_set(irq, vector, flags);
5353
} else {
54-
z_loapic_int_vec_set(irq - LOAPIC_IRQ_BASE, vector);
54+
z_loapic_int_vec_set(irq - z_loapic_irq_base(), vector);
5555
}
5656
}
5757

@@ -77,7 +77,7 @@ void arch_irq_enable(unsigned int irq)
7777
if (IS_IOAPIC_IRQ(irq)) {
7878
z_ioapic_irq_enable(irq);
7979
} else {
80-
z_loapic_irq_enable(irq - LOAPIC_IRQ_BASE);
80+
z_loapic_irq_enable(irq - z_loapic_irq_base());
8181
}
8282
}
8383

@@ -97,6 +97,6 @@ void arch_irq_disable(unsigned int irq)
9797
if (IS_IOAPIC_IRQ(irq)) {
9898
z_ioapic_irq_disable(irq);
9999
} else {
100-
z_loapic_irq_disable(irq - LOAPIC_IRQ_BASE);
100+
z_loapic_irq_disable(irq - z_loapic_irq_base());
101101
}
102102
}

include/drivers/interrupt_controller/ioapic.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern "C" {
3535
#define IOAPIC_EXTINT 0x00000700
3636

3737
#ifndef _ASMLANGUAGE
38+
uint32_t z_ioapic_num_rtes(void);
3839
void z_ioapic_irq_enable(unsigned int irq);
3940
void z_ioapic_irq_disable(unsigned int irq);
4041
void z_ioapic_int_vec_set(unsigned int irq, unsigned int vector);

include/drivers/interrupt_controller/loapic.h

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
extern "C" {
5656
#endif
5757

58+
extern uint32_t z_loapic_irq_base(void);
5859
extern void z_loapic_enable(unsigned char cpu_number);
5960
extern void z_loapic_int_vec_set(unsigned int irq, unsigned int vector);
6061
extern void z_loapic_irq_enable(unsigned int irq);

include/drivers/interrupt_controller/sysapic.h

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#ifndef _ASMLANGUAGE
1919
#include <zephyr/types.h>
2020

21-
#define LOAPIC_IRQ_BASE CONFIG_IOAPIC_NUM_RTES
2221
#define LOAPIC_IRQ_COUNT 6 /* Default to LOAPIC_TIMER to LOAPIC_ERROR */
2322

2423
void z_irq_controller_irq_config(unsigned int vector, unsigned int irq,

0 commit comments

Comments
 (0)