mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-10-06 10:59:48 +08:00
bsps/leon3: Size the interrupt map per chip
The BSP assumed 64 bus lines for every chip with an interrupt map. The GR740 has 32 bus lines in eight map registers. The BSP read the undefined offsets 0x320 to 0x33C, and vector 32 passed as valid, so ts-validation-intr failed on the GR740. The GR765 has 64 bus lines. A map field is eight bits wide. A field value above 31 indexed past the dispatch table of 32 entries and made the bit shifts undefined. Replace the option LEON3_IRQAMP_IRQMAP by LEON3_IRQMAP_BUS_LINE_COUNT, which is 32 for the GR740 and 64 for the GR765. With an interrupt map, an interrupt vector is a bus line. The vector count is then the bus line count, and the dispatch table keeps one entry for each controller line. Bound each map entry by the dispatch table, so that a hardware fault cannot index past it. The description of LEON3_IRQAMP_EXTENDED_INTERRUPT named an interrupt line and did not say which kind. Call it a controller line, the term which the other options use. The extended interrupt raise test took a vector for its controller line. It raised 1U << vector for vectors up to the count, which is undefined from 32 on. Its specification item did not exist. Regenerate the test from the new item. It raises the mapped controller line of each vector which maps to an extended controller line. It checks that it exercised each extended controller line. Close #5786. Assisted-by: Claude:claude-opus-5-5 claude-code Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
This commit is contained in:
committed by
Kinsey Moore
parent
3840a7bc54
commit
c9206587ac
@@ -42,10 +42,19 @@
|
||||
|
||||
#define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
|
||||
#define BSP_INTERRUPT_VECTOR_MAX_EXT 31 /* Extended IRQ controller */
|
||||
#define BSP_INTERRUPT_VECTOR_MAX_MAP \
|
||||
63 /* Extended IRQ controller with mapping registers */
|
||||
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
/*
|
||||
* A bus line is an interrupt line of the system interrupt bus. A controller
|
||||
* line is an interrupt line of the IRQ(A)MP. With an interrupt map, an
|
||||
* interrupt vector is a bus line. The dispatch table has one entry for each
|
||||
* controller line.
|
||||
*/
|
||||
#define BSP_INTERRUPT_VECTOR_COUNT LEON3_IRQMAP_BUS_LINE_COUNT
|
||||
#define BSP_INTERRUPT_DISPATCH_TABLE_SIZE ( BSP_INTERRUPT_VECTOR_MAX_EXT + 1 )
|
||||
#else
|
||||
#define BSP_INTERRUPT_VECTOR_COUNT ( BSP_INTERRUPT_VECTOR_MAX_EXT + 1 )
|
||||
#endif
|
||||
|
||||
/* The check is different depending on IRQ controller, runtime detected */
|
||||
#define BSP_INTERRUPT_CUSTOM_VALID_VECTOR
|
||||
@@ -97,9 +106,8 @@ rtems_status_code leon3_irqmap_get(
|
||||
rtems_vector_number *controller_line
|
||||
);
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
extern rtems_vector_number
|
||||
LEON3_IrqCtrl_Mapping[ BSP_INTERRUPT_VECTOR_MAX_MAP + 1 ];
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
extern uint8_t LEON3_IrqCtrl_Mapping[ BSP_INTERRUPT_VECTOR_COUNT ];
|
||||
|
||||
#define bsp_interrupt_vector_modify( v ) LEON3_IrqCtrl_Mapping[ ( v ) ]
|
||||
#endif
|
||||
|
||||
@@ -159,7 +159,7 @@ static inline rtems_vector_number leon3_irqmap_get_unchecked(
|
||||
rtems_vector_number bus_line
|
||||
)
|
||||
{
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
return LEON3_IrqCtrl_Mapping[ bus_line ];
|
||||
#else
|
||||
return bus_line;
|
||||
|
||||
@@ -114,7 +114,7 @@ void _CPU_SMP_Send_interrupt( uint32_t target_processor_index )
|
||||
/* send interrupt to destination CPU */
|
||||
grlib_store_32(
|
||||
&LEON3_IrqCtrl_Regs->piforce[ target_processor_index ],
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
1U << leon3_irqmap_get_unchecked( LEON3_mp_irq )
|
||||
#else
|
||||
1U << LEON3_mp_irq
|
||||
|
||||
@@ -49,9 +49,20 @@
|
||||
uint32_t LEON3_IrqCtrl_EIrq;
|
||||
#endif
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
/* Mapping from bus interrupt lines to IRQ(A)MP interrupt lines */
|
||||
rtems_vector_number LEON3_IrqCtrl_Mapping[ BSP_INTERRUPT_VECTOR_MAX_MAP + 1 ];
|
||||
uint8_t LEON3_IrqCtrl_Mapping[ BSP_INTERRUPT_VECTOR_COUNT ];
|
||||
|
||||
/*
|
||||
* A map field is eight bits wide. A field value outside the dispatch table is
|
||||
* a hardware fault. The mask keeps the controller line inside the dispatch
|
||||
* table also in this case.
|
||||
*/
|
||||
static uint8_t leon3_irqmap_controller_line( uint32_t field )
|
||||
{
|
||||
return (uint8_t) ( field & ( BSP_INTERRUPT_DISPATCH_TABLE_SIZE - 1 ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rtems_status_code leon3_irqmap_get(
|
||||
@@ -63,11 +74,7 @@ rtems_status_code leon3_irqmap_get(
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
if ( bus_line > BSP_INTERRUPT_VECTOR_MAX_MAP ) {
|
||||
#else
|
||||
if ( bus_line >= BSP_INTERRUPT_VECTOR_COUNT ) {
|
||||
#endif
|
||||
*controller_line = UINT32_MAX;
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
@@ -91,25 +98,25 @@ void leon3_ext_irq_init( irqamp *regs )
|
||||
grlib_load_32( ®s->mpstat )
|
||||
);
|
||||
#endif
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
for (
|
||||
rtems_vector_number bus_line = 0; bus_line <= BSP_INTERRUPT_VECTOR_MAX_MAP;
|
||||
rtems_vector_number bus_line = 0; bus_line < BSP_INTERRUPT_VECTOR_COUNT;
|
||||
bus_line += 4
|
||||
) {
|
||||
uint32_t n = bus_line / 4;
|
||||
uint32_t irqmap_n = grlib_load_32( &LEON3_IrqCtrl_Regs->irqmap[ n ] );
|
||||
|
||||
LEON3_IrqCtrl_Mapping[ bus_line + 0 ] = IRQAMP_IRQMAP_IRQMAP_4_N_0_GET(
|
||||
irqmap_n
|
||||
LEON3_IrqCtrl_Mapping[ bus_line + 0 ] = leon3_irqmap_controller_line(
|
||||
IRQAMP_IRQMAP_IRQMAP_4_N_0_GET( irqmap_n )
|
||||
);
|
||||
LEON3_IrqCtrl_Mapping[ bus_line + 1 ] = IRQAMP_IRQMAP_IRQMAP_4_N_1_GET(
|
||||
irqmap_n
|
||||
LEON3_IrqCtrl_Mapping[ bus_line + 1 ] = leon3_irqmap_controller_line(
|
||||
IRQAMP_IRQMAP_IRQMAP_4_N_1_GET( irqmap_n )
|
||||
);
|
||||
LEON3_IrqCtrl_Mapping[ bus_line + 2 ] = IRQAMP_IRQMAP_IRQMAP_4_N_2_GET(
|
||||
irqmap_n
|
||||
LEON3_IrqCtrl_Mapping[ bus_line + 2 ] = leon3_irqmap_controller_line(
|
||||
IRQAMP_IRQMAP_IRQMAP_4_N_2_GET( irqmap_n )
|
||||
);
|
||||
LEON3_IrqCtrl_Mapping[ bus_line + 3 ] = IRQAMP_IRQMAP_IRQMAP_4_N_3_GET(
|
||||
irqmap_n
|
||||
LEON3_IrqCtrl_Mapping[ bus_line + 3 ] = leon3_irqmap_controller_line(
|
||||
IRQAMP_IRQMAP_IRQMAP_4_N_3_GET( irqmap_n )
|
||||
);
|
||||
}
|
||||
#endif
|
||||
@@ -121,8 +128,9 @@ bool bsp_interrupt_is_valid_vector( rtems_vector_number vector )
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined( LEON3_IRQAMP_IRQMAP )
|
||||
return vector <= BSP_INTERRUPT_VECTOR_MAX_MAP;
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
return vector < BSP_INTERRUPT_VECTOR_COUNT &&
|
||||
leon3_irqmap_get_unchecked( vector ) != 0;
|
||||
#elif defined( LEON3_IRQAMP_EXTENDED_INTERRUPT )
|
||||
return vector <= BSP_INTERRUPT_VECTOR_MAX_EXT;
|
||||
#else
|
||||
@@ -184,7 +192,7 @@ rtems_status_code bsp_interrupt_get_attributes(
|
||||
bool is_standard_interrupt;
|
||||
bool is_maskable;
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -216,7 +224,7 @@ rtems_status_code bsp_interrupt_is_pending(
|
||||
bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) );
|
||||
bsp_interrupt_assert( pending != NULL );
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -242,7 +250,7 @@ rtems_status_code bsp_interrupt_raise( rtems_vector_number vector )
|
||||
|
||||
bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) );
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -272,7 +280,7 @@ rtems_status_code bsp_interrupt_raise_on(
|
||||
bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) );
|
||||
bsp_interrupt_assert( cpu_index < rtems_scheduler_get_processor_maximum() );
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -293,7 +301,7 @@ rtems_status_code bsp_interrupt_clear( rtems_vector_number vector )
|
||||
|
||||
bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) );
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -323,7 +331,7 @@ rtems_status_code bsp_interrupt_vector_is_enabled(
|
||||
|
||||
bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) );
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -345,7 +353,7 @@ static void leon3_interrupt_vector_enable( rtems_vector_number vector )
|
||||
uint32_t brdcst;
|
||||
irqamp *regs;
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -399,7 +407,7 @@ rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector )
|
||||
|
||||
bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) );
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -435,7 +443,7 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector )
|
||||
|
||||
bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) );
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
vector = leon3_irqmap_get_unchecked( vector );
|
||||
#endif
|
||||
|
||||
@@ -508,7 +516,7 @@ rtems_status_code bsp_interrupt_set_affinity(
|
||||
uint32_t bit;
|
||||
irqamp *regs;
|
||||
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
rtems_vector_number irq_vector;
|
||||
|
||||
if ( leon3_irqmap_get( vector, &irq_vector ) != RTEMS_SUCCESSFUL ) {
|
||||
@@ -549,7 +557,7 @@ rtems_status_code bsp_interrupt_get_affinity(
|
||||
Processor_mask *affinity
|
||||
)
|
||||
{
|
||||
#ifdef LEON3_IRQAMP_IRQMAP
|
||||
#if LEON3_IRQMAP_BUS_LINE_COUNT != 0
|
||||
rtems_vector_number irq_vector;
|
||||
|
||||
if ( leon3_irqmap_get( vector, &irq_vector ) != RTEMS_SUCCESSFUL ) {
|
||||
|
||||
@@ -47,7 +47,7 @@ links:
|
||||
- role: build-dependency
|
||||
uid: optirqampextirq
|
||||
- role: build-dependency
|
||||
uid: optirqampirqmap
|
||||
uid: optirqmapbuslinecount
|
||||
- role: build-dependency
|
||||
uid: optirqampts
|
||||
- role: build-dependency
|
||||
|
||||
@@ -17,5 +17,6 @@ format: '{}'
|
||||
links: []
|
||||
name: LEON3_IRQAMP_EXTENDED_INTERRUPT
|
||||
description: |
|
||||
This option specifies the interrupt line of the IRQ(A)MP extended interrupt.
|
||||
This option specifies the controller line of the IRQ(A)MP extended
|
||||
interrupt.
|
||||
type: build
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
|
||||
copyrights:
|
||||
- Copyright (C) 2026 Frontgrade Gaisler
|
||||
actions:
|
||||
- get-boolean: null
|
||||
- define-condition: null
|
||||
build-type: option
|
||||
default:
|
||||
- enabled-by:
|
||||
- sparc/gr740
|
||||
- sparc/gr765
|
||||
value: true
|
||||
- enabled-by: true
|
||||
value: false
|
||||
enabled-by: true
|
||||
links: []
|
||||
name: LEON3_IRQAMP_IRQMAP
|
||||
description: |
|
||||
This option specifies if the IRQ(A)MP interrupt (re-)map registers are available.
|
||||
type: build
|
||||
@@ -0,0 +1,28 @@
|
||||
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
|
||||
actions:
|
||||
- get-integer: null
|
||||
- assert-in-set:
|
||||
- 0
|
||||
- 32
|
||||
- 64
|
||||
- format-and-define: null
|
||||
build-type: option
|
||||
copyrights:
|
||||
- Copyright (C) 2026 Frontgrade Gaisler
|
||||
- Copyright (C) 2026 embedded brains GmbH & Co. KG
|
||||
default:
|
||||
- enabled-by: sparc/gr740
|
||||
value: 32
|
||||
- enabled-by: sparc/gr765
|
||||
value: 64
|
||||
- enabled-by: true
|
||||
value: 0
|
||||
description: |
|
||||
This option defines the count of bus lines of the IRQ(A)MP interrupt map.
|
||||
The GR740 has 32 bus lines, and the GR765 has 64. A value of zero specifies
|
||||
that the BSP uses no interrupt map.
|
||||
enabled-by: true
|
||||
format: '{}'
|
||||
links: []
|
||||
name: LEON3_IRQMAP_BUS_LINE_COUNT
|
||||
type: build
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user