[PATCH 3/3] Rework initialization and interrupt stack support

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Jun 19 13:30:41 UTC 2018


Statically initialize the interrupt stack area
(_Configuration_Interrupt_stack_area and
_Configuration_Interrupt_stack_size) via <rtems/confdefs.h>.  Place the
interrupt stack area in a special section ".rtemsstack.interrupt".  Let
BSPs define the optimal placement of this section in their linker
command files (e.g. in a fast on-chip memory).

This change makes makes the CPU_HAS_SOFTWARE_INTERRUPT_STACK and
CPU_HAS_HARDWARE_INTERRUPT_STACK CPU port defines superfluous, since the
low level initialization code has all information available via global
symbols.

This change makes the CPU_ALLOCATE_INTERRUPT_STACK CPU port define
superfluous, since the interrupt stacks are allocated by confdefs.h for
all architectures.  There is no need for BSP-specific linker command
file magic (except the section placement), see previous ARM linker
command file as a bad example.

The optional _CPU_Interrupt_stack_setup() is still useful to customize
the registration of the interrupt stack area in the per-CPU information.

Changes per architecture:

arm:

  * Mostly replace linker symbol configuration of stacks with the standard
    <rtems/confdefs.h> configuration via CONFIGURE_INTERRUPT_STACK_SIZE.
    The size of the FIQ, ABT and UND mode stack is still defined via
    linker symbols.  These modes are rarely used in applications.

  * Remove bsp_processor_count linker symbol hack used for the SMP
    support. This is possible since the interrupt stack area is now
    allocated by the linker and not allocated from the heap. This makes
    some configure.ac stuff and some BSP variants obsolete.

sparc:

  * Use the interrupt stack for the initialization stack on the boot
    processor.  This saves 16KiB of RAM.

Update #3459.

v0: This is work in progress. It is a proof of concept on ARM and SPARC.
---
 .../altera-cyclone-v/config/altcycv_devkit_smp.cfg |   1 -
 .../start/linkcmds.altcycv_devkit_smp              |   3 -
 bsps/arm/csb336/start/start.S                      |  92 +++++++--------
 bsps/arm/csb337/start/start.S                      |  91 +++++++--------
 bsps/arm/edb7312/start/start.S                     | 100 +++++++---------
 bsps/arm/gumstix/start/start.S                     |  89 +++++++--------
 bsps/arm/imx/start/linkcmds.imx7                   |   3 -
 bsps/arm/include/bsp/linker-symbols.h              |  23 +---
 bsps/arm/raspberrypi/start/bspsmp.c                |   7 +-
 .../raspberrypi/start/{linkcmds.in => linkcmds}    |   3 -
 .../config/realview_pbx_a9_qemu_smp.cfg            |   1 -
 .../start/linkcmds.realview_pbx_a9_qemu_smp        |   3 -
 bsps/arm/rtl22xx/start/start.S                     |  73 ++++++------
 bsps/arm/shared/start/arm-a9mpcore-smp.c           |   8 +-
 bsps/arm/shared/start/linkcmds.base                |  50 --------
 bsps/arm/shared/start/start.S                      | 126 +++++++--------------
 bsps/arm/smdk2410/start/start.S                    |  69 +++++------
 bsps/arm/xilinx-zynq/start/linkcmds.in             |   3 -
 bsps/sparc/shared/start/bspgetworkarea.c           |   6 +-
 bsps/sparc/shared/start/start.S                    |   8 +-
 c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am  |   1 -
 c/src/lib/libbsp/arm/raspberrypi/configure.ac      |  17 +--
 c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am   |   1 -
 c/src/lib/libbsp/arm/xilinx-zynq/configure.ac      |   5 -
 cpukit/include/rtems/confdefs.h                    |  51 +++------
 cpukit/include/rtems/config.h                      |  26 +++--
 cpukit/include/rtems/score/percpu.h                |  53 +++------
 cpukit/score/cpu/arm/include/rtems/score/cpu.h     |   6 -
 cpukit/score/cpu/sparc/include/rtems/score/cpu.h   |  34 ------
 cpukit/score/src/isr.c                             |  64 +++++------
 cpukit/score/src/percpuasm.c                       |  23 ++--
 testsuites/sptests/spsize/size.c                   |   2 -
 32 files changed, 377 insertions(+), 665 deletions(-)
 delete mode 100644 bsps/arm/altera-cyclone-v/config/altcycv_devkit_smp.cfg
 delete mode 100644 bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit_smp
 rename bsps/arm/raspberrypi/start/{linkcmds.in => linkcmds} (92%)
 delete mode 100644 bsps/arm/realview-pbx-a9/config/realview_pbx_a9_qemu_smp.cfg
 delete mode 100644 bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp

diff --git a/bsps/arm/altera-cyclone-v/config/altcycv_devkit_smp.cfg b/bsps/arm/altera-cyclone-v/config/altcycv_devkit_smp.cfg
deleted file mode 100644
index ed54edfedd..0000000000
--- a/bsps/arm/altera-cyclone-v/config/altcycv_devkit_smp.cfg
+++ /dev/null
@@ -1 +0,0 @@
-include $(RTEMS_ROOT)/make/custom/altcycv.inc
diff --git a/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit_smp b/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit_smp
deleted file mode 100644
index 2da086579f..0000000000
--- a/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit_smp
+++ /dev/null
@@ -1,3 +0,0 @@
-bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 2;
-
-INCLUDE linkcmds.altcycv_devkit
diff --git a/bsps/arm/csb336/start/start.S b/bsps/arm/csb336/start/start.S
index ce452f52a2..35401f345f 100644
--- a/bsps/arm/csb336/start/start.S
+++ b/bsps/arm/csb336/start/start.S
@@ -8,20 +8,8 @@
  * http://www.rtems.org/license/LICENSE.
  */
 
-#include <bsp/linker-symbols.h>
-
-/* Some standard definitions...*/
-.equ PSR_MODE_USR,       0x10
-.equ PSR_MODE_FIQ,       0x11
-.equ PSR_MODE_IRQ,       0x12
-.equ PSR_MODE_SVC,       0x13
-.equ PSR_MODE_ABT,       0x17
-.equ PSR_MODE_UNDEF,     0x1B
-.equ PSR_MODE_SYS,       0x1F
-
-.equ PSR_I,              0x80
-.equ PSR_F,              0x40
-.equ PSR_T,              0x20
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
 
 .section .bsp_start_text,"ax"
          .code 32
@@ -36,60 +24,58 @@ _start:
         /*
          * Since I don't plan to return to the bootloader,
          * I don't have to save the registers.
-         *
-         * I'll just set the CPSR for SVC mode, interrupts
-         * off, and ARM instructions.
          */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)
-        msr     cpsr, r0
-
-        /* zero the bss */
-        ldr     r1, =bsp_section_bss_end
-        ldr     r0, =bsp_section_bss_begin
-
-_bss_init:
-        mov     r2, #0
-        cmp     r0, r1
-        strlot  r2, [r0], #4
-        blo     _bss_init        /* loop while r0 < r1 */
-
 
-        /* --- Initialize stack pointer registers */
-        /* Enter IRQ mode and set up the IRQ stack pointer */
-        mov     r0, #(PSR_MODE_IRQ | PSR_I | PSR_F)     /* No interrupts */
-        msr     cpsr, r0
-        ldr     r1, =bsp_stack_irq_size
-        ldr     sp, =bsp_stack_irq_begin
-        add     sp, sp, r1
+        /* Calculate interrupt stack area end */
+        ldr     r1, =_Configuration_Interrupt_stack_size
+        ldr     r2, =_Configuration_Interrupt_stack_area
+        add     r7, r1, r2
 
         /* Enter FIQ mode and set up the FIQ stack pointer */
-        mov     r0, #(PSR_MODE_FIQ | PSR_I | PSR_F)     /* No interrupts */
+        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_fiq_size
-        ldr     sp, =bsp_stack_fiq_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
 
         /* Enter ABT mode and set up the ABT stack pointer */
-        mov     r0, #(PSR_MODE_ABT | PSR_I | PSR_F)     /* No interrupts */
+        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_abt_size
-        ldr     sp, =bsp_stack_abt_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
 
-        /* Enter UNDEF mode and set up the UNDEF stack pointer */
-        mov     r0, #(PSR_MODE_UNDEF | PSR_I | PSR_F)     /* No interrupts */
+        /* Enter UND mode and set up the UND stack pointer */
+        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_und_size
-        ldr     sp, =bsp_stack_und_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
 
-        /* Set up the SVC stack pointer last and stay in SVC mode */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)     /* No interrupts */
+        /* Enter IRQ mode and set up the IRQ stack pointer */
+        mov     r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        mov     sp, r7
+
+        /*
+         * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
+         * (interrupts are disabled).
+         */
+        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
-        ldr     r1, =bsp_stack_svc_size
-        ldr     sp, =bsp_stack_svc_begin
-        add     sp, sp, r1
-        sub     sp, sp, #0x64
+        mov     sp, r7
+
+        /* Stay in SVC mode */
+
+        /* zero the bss */
+        ldr     r1, =bsp_section_bss_end
+        ldr     r0, =bsp_section_bss_begin
+
+_bss_init:
+        mov     r2, #0
+        cmp     r0, r1
+        strlot  r2, [r0], #4
+        blo     _bss_init        /* loop while r0 < r1 */
 
         /*
          * Initialize the MMU. After we return, the MMU is enabled,
diff --git a/bsps/arm/csb337/start/start.S b/bsps/arm/csb337/start/start.S
index f88cf41d78..eead625d78 100644
--- a/bsps/arm/csb337/start/start.S
+++ b/bsps/arm/csb337/start/start.S
@@ -8,20 +8,8 @@
  *  http://www.rtems.org/license/LICENSE.
 */
 
-#include <bsp/linker-symbols.h>
-
-/* Some standard definitions...*/
-.equ PSR_MODE_USR,       0x10
-.equ PSR_MODE_FIQ,       0x11
-.equ PSR_MODE_IRQ,       0x12
-.equ PSR_MODE_SVC,       0x13
-.equ PSR_MODE_ABT,       0x17
-.equ PSR_MODE_UNDEF,     0x1B
-.equ PSR_MODE_SYS,       0x1F
-
-.equ PSR_I,              0x80
-.equ PSR_F,              0x40
-.equ PSR_T,              0x20
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
 
 .text
 .globl  _start
@@ -29,53 +17,58 @@ _start:
         /*
          * Since I don't plan to return to the bootloader,
          * I don't have to save the registers.
-         *
-         * I'll just set the CPSR for SVC mode, interrupts
-         * off, and ARM instructions.
          */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)
-        msr     cpsr, r0
 
-        /* zero the bss */
-        ldr     r1, =bsp_section_bss_end
-        ldr     r0, =bsp_section_bss_begin
-
-_bss_init:
-        mov     r2, #0
-        cmp     r0, r1
-        strlot  r2, [r0], #4
-        blo     _bss_init        /* loop while r0 < r1 */
-
-
-        /* --- Initialize stack pointer registers */
-        /* Enter IRQ mode and set up the IRQ stack pointer */
-        mov     r0, #(PSR_MODE_IRQ | PSR_I | PSR_F)     /* No interrupts */
-        msr     cpsr, r0
-        ldr     r1, =bsp_stack_irq_size
-        ldr     sp, =bsp_stack_irq_begin
-        add     sp, sp, r1
+        /* Calculate interrupt stack area end */
+        ldr     r1, =_Configuration_Interrupt_stack_size
+        ldr     r2, =_Configuration_Interrupt_stack_area
+        add     r7, r1, r2
 
         /* Enter FIQ mode and set up the FIQ stack pointer */
-        mov     r0, #(PSR_MODE_FIQ | PSR_I | PSR_F)     /* No interrupts */
+        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_fiq_size
-        ldr     sp, =bsp_stack_fiq_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
 
         /* Enter ABT mode and set up the ABT stack pointer */
-        mov     r0, #(PSR_MODE_ABT | PSR_I | PSR_F)     /* No interrupts */
+        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_abt_size
-        ldr     sp, =bsp_stack_abt_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
+
+        /* Enter UND mode and set up the UND stack pointer */
+        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_und_size
+        mov     sp, r7
+        sub     r7, r7, r1
 
-        /* Set up the SVC stack pointer last and stay in SVC mode */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)     /* No interrupts */
+        /* Enter IRQ mode and set up the IRQ stack pointer */
+        mov     r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
-        ldr     r1, =bsp_stack_svc_size
-        ldr     sp, =bsp_stack_svc_begin
-        add     sp, sp, r1
-        sub     sp, sp, #0x64
+        mov     sp, r7
+
+        /*
+         * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
+         * (interrupts are disabled).
+         */
+        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        mov     sp, r7
+
+        /* Stay in SVC mode */
+
+        /* zero the bss */
+        ldr     r1, =bsp_section_bss_end
+        ldr     r0, =bsp_section_bss_begin
+
+_bss_init:
+        mov     r2, #0
+        cmp     r0, r1
+        strlot  r2, [r0], #4
+        blo     _bss_init        /* loop while r0 < r1 */
 
         /*
          * Initialize the MMU. After we return, the MMU is enabled,
diff --git a/bsps/arm/edb7312/start/start.S b/bsps/arm/edb7312/start/start.S
index e03707bfcf..4842608ce5 100644
--- a/bsps/arm/edb7312/start/start.S
+++ b/bsps/arm/edb7312/start/start.S
@@ -12,21 +12,8 @@
  *  http://www.rtems.org/license/LICENSE.
 */
 
-#include <bsp/linker-symbols.h>
-
-/* Some standard definitions...*/
-
-.equ Mode_USR,        	     0x10
-.equ Mode_FIQ,        	     0x11
-.equ Mode_IRQ,        	     0x12
-.equ Mode_SVC,        	     0x13
-.equ Mode_ABT,        	     0x17
-.equ Mode_ABORT,             0x17
-.equ Mode_UNDEF,      	     0x1B
-.equ Mode_SYS,        	     0x1F /*only available on ARM Arch. v4*/
-
-.equ I_Bit,           	     0x80
-.equ F_Bit,           	     0x40
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
 
 .section ".bsp_start_text", "ax"
 .arm
@@ -72,8 +59,46 @@ handler_addr_fiq:
 
 	.globl	_start
 _start:
-	/* store the sp */
-	mov	r12, sp
+        /* Calculate interrupt stack area end */
+        ldr     r1, =_Configuration_Interrupt_stack_size
+        ldr     r2, =_Configuration_Interrupt_stack_area
+        add     r7, r1, r2
+
+        /* Enter FIQ mode and set up the FIQ stack pointer */
+        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_fiq_size
+        mov     sp, r7
+        sub     r7, r7, r1
+
+        /* Enter ABT mode and set up the ABT stack pointer */
+        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_abt_size
+        mov     sp, r7
+        sub     r7, r7, r1
+
+        /* Enter UND mode and set up the UND stack pointer */
+        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_und_size
+        mov     sp, r7
+        sub     r7, r7, r1
+
+        /* Enter IRQ mode and set up the IRQ stack pointer */
+        mov     r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        mov     sp, r7
+
+        /*
+         * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
+         * (interrupts are disabled).
+         */
+        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        mov     sp, r7
+
+        /* Stay in SVC mode */
 /*
  * Here is the code to initialize the low-level BSP environment
  * (Chip Select, PLL, ....?)
@@ -89,48 +114,7 @@ zi_init:
         STRLOT   r2, [r0], #4
         BLO     zi_init
 
-/* --- Initialise stack pointer registers */
-
-/* Enter IRQ mode and set up the IRQ stack pointer */
-    MOV     r0, #Mode_IRQ | I_Bit | F_Bit     /* No interrupts */
-    MSR     cpsr, r0
-    ldr	    r1, =bsp_stack_irq_size
-    LDR     sp, =bsp_stack_irq_begin
-    add	    sp, sp, r1
-    sub     sp, sp, #0x64
-
-/* Enter FIQ mode and set up the FIQ stack pointer */
-    MOV     r0, #Mode_FIQ | I_Bit | F_Bit     /* No interrupts */
-    MSR     cpsr, r0
-    ldr	    r1, =bsp_stack_fiq_size
-    LDR     sp, =bsp_stack_fiq_begin
-    add	    sp, sp, r1
-    sub     sp, sp, #0x64
-
-/* Enter ABT mode and set up the ABT stack pointer */
-    MOV     r0, #Mode_ABT | I_Bit | F_Bit     /* No interrupts */
-    MSR     cpsr, r0
-    ldr	    r1, =bsp_stack_abt_size
-    LDR     sp, =bsp_stack_abt_begin
-    add	    sp, sp, r1
-    sub     sp, sp, #0x64
-
-/* Set up the SVC stack pointer last and stay in SVC mode */
-    MOV     r0, #Mode_SVC | I_Bit | F_Bit     /* No interrupts */
-    MSR     cpsr, r0
-    ldr	    r1, =bsp_stack_svc_size
-    LDR     sp, =bsp_stack_svc_begin
-    add	    sp, sp, r1
-    sub     sp, sp, #0x64
-
-	/* save the original registers */
-	stmdb	sp!, {r4-r12, lr}
-
 /* --- Now we enter the C code */
 
 	mov     r0, #0
 	bl	boot_card
-
-	ldmia	sp!, {r4-r12, lr}
-	mov	sp, r12
-	mov	pc, lr
diff --git a/bsps/arm/gumstix/start/start.S b/bsps/arm/gumstix/start/start.S
index dccc99993e..5f4167d24d 100644
--- a/bsps/arm/gumstix/start/start.S
+++ b/bsps/arm/gumstix/start/start.S
@@ -7,20 +7,8 @@
  *  http://www.rtems.org/license/LICENSE.
  */
 
-#include <bsp/linker-symbols.h>
-
-/* Some standard definitions...*/
-.equ PSR_MODE_USR,       0x10
-.equ PSR_MODE_FIQ,       0x11
-.equ PSR_MODE_IRQ,       0x12
-.equ PSR_MODE_SVC,       0x13
-.equ PSR_MODE_ABT,       0x17
-.equ PSR_MODE_UNDEF,     0x1B
-.equ PSR_MODE_SYS,       0x1F
-
-.equ PSR_I,              0x80
-.equ PSR_F,              0x40
-.equ PSR_T,              0x20
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
 
 .text
 .globl  _start
@@ -28,53 +16,58 @@ _start:
         /*
          * Since I don't plan to return to the bootloader,
          * I don't have to save the registers.
-         *
-         * I'll just set the CPSR for SVC mode, interrupts
-         * off, and ARM instructions.
          */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)
-        msr     cpsr, r0
 
-
-        /* zero the bss */
-        ldr     r1, =bsp_section_bss_end
-        ldr     r0, =bsp_section_bss_begin
-
-_bss_init:
-        mov     r2, #0
-        cmp     r0, r1
-        strlot  r2, [r0], #4
-        blo     _bss_init        /* loop while r0 < r1 */
-
-        /* --- Initialize stack pointer registers */
-        /* Enter IRQ mode and set up the IRQ stack pointer */
-        mov     r0, #(PSR_MODE_IRQ | PSR_I | PSR_F)     /* No interrupts */
-        msr     cpsr, r0
-        ldr     r1, =bsp_stack_irq_size
-        ldr     sp, =bsp_stack_irq_begin
-        add     sp, sp, r1
+        /* Calculate interrupt stack area end */
+        ldr     r1, =_Configuration_Interrupt_stack_size
+        ldr     r2, =_Configuration_Interrupt_stack_area
+        add     r7, r1, r2
 
         /* Enter FIQ mode and set up the FIQ stack pointer */
-        mov     r0, #(PSR_MODE_FIQ | PSR_I | PSR_F)     /* No interrupts */
+        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_fiq_size
-        ldr     sp, =bsp_stack_fiq_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
 
         /* Enter ABT mode and set up the ABT stack pointer */
-        mov     r0, #(PSR_MODE_ABT | PSR_I | PSR_F)     /* No interrupts */
+        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_abt_size
-        ldr     sp, =bsp_stack_abt_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
 
-        /* Set up the SVC stack pointer last and stay in SVC mode */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)     /* No interrupts */
+        /* Enter UND mode and set up the UND stack pointer */
+        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_und_size
-        ldr     sp, =bsp_stack_und_begin
-        add     sp, sp, r1
-        sub     sp, sp, #0x64
+        mov     sp, r7
+        sub     r7, r7, r1
+
+        /* Enter IRQ mode and set up the IRQ stack pointer */
+        mov     r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        mov     sp, r7
+
+        /*
+         * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
+         * (interrupts are disabled).
+         */
+        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        mov     sp, r7
+
+        /* Stay in SVC mode */
+
+        /* zero the bss */
+        ldr     r1, =bsp_section_bss_end
+        ldr     r0, =bsp_section_bss_begin
+
+_bss_init:
+        mov     r2, #0
+        cmp     r0, r1
+        strlot  r2, [r0], #4
+        blo     _bss_init        /* loop while r0 < r1 */
 
         /*
          * Initialize the MMU. After we return, the MMU is enabled,
diff --git a/bsps/arm/imx/start/linkcmds.imx7 b/bsps/arm/imx/start/linkcmds.imx7
index 750e1def1d..0d9fe48bf9 100644
--- a/bsps/arm/imx/start/linkcmds.imx7
+++ b/bsps/arm/imx/start/linkcmds.imx7
@@ -22,9 +22,6 @@ REGION_ALIAS ("REGION_STACK", RAM);
 REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
 REGION_ALIAS ("REGION_NOCACHE_LOAD", NOCACHE);
 
-bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 2;
-
-bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
 bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
 
 bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
diff --git a/bsps/arm/include/bsp/linker-symbols.h b/bsps/arm/include/bsp/linker-symbols.h
index ce298b2def..f23e74c03f 100644
--- a/bsps/arm/include/bsp/linker-symbols.h
+++ b/bsps/arm/include/bsp/linker-symbols.h
@@ -43,30 +43,11 @@ extern "C" {
   #define LINKER_SYMBOL(sym) .extern sym
 #endif
 
-LINKER_SYMBOL(bsp_stack_irq_begin)
-LINKER_SYMBOL(bsp_stack_irq_end)
-LINKER_SYMBOL(bsp_stack_irq_size)
-
-LINKER_SYMBOL(bsp_stack_fiq_begin)
-LINKER_SYMBOL(bsp_stack_fiq_end)
-LINKER_SYMBOL(bsp_stack_irq_size)
-
-LINKER_SYMBOL(bsp_stack_abt_begin)
-LINKER_SYMBOL(bsp_stack_abt_end)
+LINKER_SYMBOL(bsp_stack_fiq_size)
 LINKER_SYMBOL(bsp_stack_abt_size)
-
-LINKER_SYMBOL(bsp_stack_und_begin)
-LINKER_SYMBOL(bsp_stack_und_end)
 LINKER_SYMBOL(bsp_stack_und_size)
-
-LINKER_SYMBOL(bsp_stack_hyp_begin)
-LINKER_SYMBOL(bsp_stack_hyp_end)
 LINKER_SYMBOL(bsp_stack_hyp_size)
 
-LINKER_SYMBOL(bsp_stack_svc_begin)
-LINKER_SYMBOL(bsp_stack_svc_end)
-LINKER_SYMBOL(bsp_stack_svc_size)
-
 LINKER_SYMBOL(bsp_rtemsstack_interrupt_end)
 
 LINKER_SYMBOL(bsp_section_start_begin)
@@ -158,8 +139,6 @@ LINKER_SYMBOL(bsp_translation_table_end)
 #define BSP_NOCACHENOLOAD_SUBSECTION(subsection) \
   __attribute__((section(".bsp_noload_nocache." # subsection)))
 
-LINKER_SYMBOL(bsp_processor_count)
-
 /** @} */
 
 #ifdef __cplusplus
diff --git a/bsps/arm/raspberrypi/start/bspsmp.c b/bsps/arm/raspberrypi/start/bspsmp.c
index c3e5451442..44f7a1d376 100644
--- a/bsps/arm/raspberrypi/start/bspsmp.c
+++ b/bsps/arm/raspberrypi/start/bspsmp.c
@@ -57,12 +57,7 @@ bool _CPU_SMP_Start_processor( uint32_t cpu_index )
 
 uint32_t _CPU_SMP_Initialize(void)
 {
-  uint32_t cpu_count = (uint32_t)bsp_processor_count;
-
-  if ( cpu_count > 4 )
-    cpu_count = 4;
-
-  return cpu_count;
+  return 4;
 }
 
 void _CPU_SMP_Finalize_initialization( uint32_t cpu_count )
diff --git a/bsps/arm/raspberrypi/start/linkcmds.in b/bsps/arm/raspberrypi/start/linkcmds
similarity index 92%
rename from bsps/arm/raspberrypi/start/linkcmds.in
rename to bsps/arm/raspberrypi/start/linkcmds
index 829716c11c..58423abecb 100644
--- a/bsps/arm/raspberrypi/start/linkcmds.in
+++ b/bsps/arm/raspberrypi/start/linkcmds
@@ -41,8 +41,6 @@ MEMORY {
         RAM            (AIW) : ORIGIN = 0x00008000, LENGTH = 128M - 32k
 }
 
-bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : @RASPBERRYPI_CPUS@;
-
 REGION_ALIAS ("REGION_START", RAM);
 REGION_ALIAS ("REGION_VECTOR", VECTOR_RAM);
 REGION_ALIAS ("REGION_TEXT", RAM);
@@ -61,7 +59,6 @@ REGION_ALIAS ("REGION_STACK", RAM);
 REGION_ALIAS ("REGION_NOCACHE", RAM);
 REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM);
 
-bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 3008;
 bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
 
 bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1M;
diff --git a/bsps/arm/realview-pbx-a9/config/realview_pbx_a9_qemu_smp.cfg b/bsps/arm/realview-pbx-a9/config/realview_pbx_a9_qemu_smp.cfg
deleted file mode 100644
index fd51a18004..0000000000
--- a/bsps/arm/realview-pbx-a9/config/realview_pbx_a9_qemu_smp.cfg
+++ /dev/null
@@ -1 +0,0 @@
-include $(RTEMS_ROOT)/make/custom/realview_pbx_a9_qemu.cfg
diff --git a/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp b/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp
deleted file mode 100644
index d31c4f08ae..0000000000
--- a/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp
+++ /dev/null
@@ -1,3 +0,0 @@
-bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 8;
-
-INCLUDE linkcmds.realview_pbx_a9_qemu
diff --git a/bsps/arm/rtl22xx/start/start.S b/bsps/arm/rtl22xx/start/start.S
index c038198aff..2bf527e096 100644
--- a/bsps/arm/rtl22xx/start/start.S
+++ b/bsps/arm/rtl22xx/start/start.S
@@ -8,20 +8,8 @@
  *  http://www.rtems.org/license/LICENSE.
 */
 
-#include <bsp/linker-symbols.h>
-
-/* Some standard definitions...*/
-.equ PSR_MODE_USR,       0x10
-.equ PSR_MODE_FIQ,       0x11
-.equ PSR_MODE_IRQ,       0x12
-.equ PSR_MODE_SVC,       0x13
-.equ PSR_MODE_ABT,       0x17
-.equ PSR_MODE_UNDEF,     0x1B
-.equ PSR_MODE_SYS,       0x1F
-
-.equ PSR_I,              0x80
-.equ PSR_F,              0x40
-.equ PSR_T,              0x20
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
 
 .text
 .code	32
@@ -30,45 +18,48 @@ _start:
         /*
          * Since I don't plan to return to the bootloader,
          * I don't have to save the registers.
-         *
-         * I'll just set the CPSR for SVC mode, interrupts
-         * off, and ARM instructions.
          */
 
-        /* --- Initialize stack pointer registers */
-        /* Enter IRQ mode and set up the IRQ stack pointer */
-        mov     r0, #(PSR_MODE_IRQ | PSR_I | PSR_F)     /* No interrupts */
-        bic	r0, r0, #PSR_T
-        msr     cpsr, r0
-        ldr     r1, =bsp_stack_irq_size
-        ldr     sp, =bsp_stack_irq_begin
-        add     sp, sp, r1
+        /* Calculate interrupt stack area end */
+        ldr     r1, =_Configuration_Interrupt_stack_size
+        ldr     r2, =_Configuration_Interrupt_stack_area
+        add     r7, r1, r2
 
         /* Enter FIQ mode and set up the FIQ stack pointer */
-        mov     r0, #(PSR_MODE_FIQ | PSR_I | PSR_F)     /* No interrupts */
-        bic	r0, r0, #PSR_T
+        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_fiq_size
-        ldr     sp, =bsp_stack_fiq_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
 
         /* Enter ABT mode and set up the ABT stack pointer */
-        mov     r0, #(PSR_MODE_ABT | PSR_I | PSR_F)     /* No interrupts */
-        bic	r0, r0, #PSR_T
+        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
-        bic	r0, r0, #PSR_T
         ldr     r1, =bsp_stack_abt_size
-        ldr     sp, =bsp_stack_abt_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
+
+        /* Enter UND mode and set up the UND stack pointer */
+        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_und_size
+        mov     sp, r7
+        sub     r7, r7, r1
 
-        /* Set up the SVC stack pointer last and stay in SVC mode */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)     /* No interrupts */
-        bic	r0, r0, #PSR_T
+        /* Enter IRQ mode and set up the IRQ stack pointer */
+        mov     r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        mov     sp, r7
+
+        /*
+         * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
+         * (interrupts are disabled).
+         */
+        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
-        ldr     r1, =bsp_stack_svc_size
-        ldr     sp, =bsp_stack_svc_begin
-        add     sp, sp, r1
-        sub     sp, sp, #0x64
+        mov     sp, r7
+
+        /* Stay in SVC mode */
 
         /*
          * Initialize the exception vectors. This includes the
diff --git a/bsps/arm/shared/start/arm-a9mpcore-smp.c b/bsps/arm/shared/start/arm-a9mpcore-smp.c
index a3a95f4ea2..a8d3a541d4 100644
--- a/bsps/arm/shared/start/arm-a9mpcore-smp.c
+++ b/bsps/arm/shared/start/arm-a9mpcore-smp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2013, 2018 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -19,7 +19,6 @@
 #include <libcpu/arm-cp15.h>
 
 #include <bsp/irq.h>
-#include <bsp/linker-symbols.h>
 
 static void bsp_inter_processor_interrupt(void *arg)
 {
@@ -28,10 +27,7 @@ static void bsp_inter_processor_interrupt(void *arg)
 
 uint32_t _CPU_SMP_Initialize(void)
 {
-  uint32_t hardware_count = arm_gic_irq_processor_count();
-  uint32_t linker_count = (uint32_t) bsp_processor_count;
-
-  return hardware_count <= linker_count ? hardware_count : linker_count;
+  return arm_gic_irq_processor_count();
 }
 
 void _CPU_SMP_Finalize_initialization(uint32_t cpu_count)
diff --git a/bsps/arm/shared/start/linkcmds.base b/bsps/arm/shared/start/linkcmds.base
index 0d4deaf2c2..d200a06ed1 100644
--- a/bsps/arm/shared/start/linkcmds.base
+++ b/bsps/arm/shared/start/linkcmds.base
@@ -45,25 +45,12 @@ bsp_stack_abt_size = ALIGN (bsp_stack_abt_size, bsp_stack_align);
 bsp_stack_fiq_size = DEFINED (bsp_stack_fiq_size) ? bsp_stack_fiq_size : 0;
 bsp_stack_fiq_size = ALIGN (bsp_stack_fiq_size, bsp_stack_align);
 
-bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 0;
-bsp_stack_irq_size = ALIGN (bsp_stack_irq_size, bsp_stack_align);
-
-bsp_stack_svc_size = DEFINED (bsp_stack_svc_size) ? bsp_stack_svc_size : 0;
-bsp_stack_svc_size = ALIGN (bsp_stack_svc_size, bsp_stack_align);
-
 bsp_stack_und_size = DEFINED (bsp_stack_und_size) ? bsp_stack_und_size : 0;
 bsp_stack_und_size = ALIGN (bsp_stack_und_size, bsp_stack_align);
 
 bsp_stack_hyp_size = DEFINED (bsp_stack_hyp_size) ? bsp_stack_hyp_size : 0;
 bsp_stack_hyp_size = ALIGN (bsp_stack_hyp_size, bsp_stack_align);
 
-bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 0;
-bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
-
-bsp_stack_all_size = bsp_stack_abt_size + bsp_stack_fiq_size + bsp_stack_irq_size + bsp_stack_svc_size + bsp_stack_und_size + bsp_stack_hyp_size + bsp_stack_main_size;
-
-bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 1;
-
 MEMORY {
 	UNEXPECTED_SECTIONS : ORIGIN = 0xffffffff, LENGTH = 0
 }
@@ -297,44 +284,7 @@ SECTIONS {
 
 	.vector : ALIGN_WITH_INPUT {
 		bsp_section_vector_begin = .;
-
 		. = . + DEFINED (bsp_vector_table_in_start_section) ? 0 : bsp_vector_table_size;
-
-		. = ALIGN (bsp_stack_align);
-
-		bsp_stack_irq_begin = .;
-		. = . + bsp_stack_irq_size;
-		bsp_stack_irq_end = .;
-
-		bsp_stack_svc_begin = .;
-		. = . + bsp_stack_svc_size;
-		bsp_stack_svc_end = .;
-
-		bsp_stack_fiq_begin = .;
-		. = . + bsp_stack_fiq_size;
-		bsp_stack_fiq_end = .;
-
-		bsp_stack_und_begin = .;
-		. = . + bsp_stack_und_size;
-		bsp_stack_und_end = .;
-
-		bsp_stack_hyp_begin = .;
-		. = . + bsp_stack_hyp_size;
-		bsp_stack_hyp_end = .;
-
-		bsp_stack_abt_begin = .;
-		. = . + bsp_stack_abt_size;
-		bsp_stack_abt_end = .;
-
-		bsp_stack_main_begin = .;
-		. = . + bsp_stack_main_size;
-		bsp_stack_main_end = .;
-
-		bsp_stack_secondary_processors_begin = .;
-		. = . + (bsp_processor_count - 1) * bsp_stack_all_size;
-		bsp_stack_secondary_processors_end = .;
-
-		*(.bsp_vector)
 	} > REGION_VECTOR AT > REGION_VECTOR
 	.rtemsstack (NOLOAD) : {
 		*(.rtemsstack.interrupt)
diff --git a/bsps/arm/shared/start/start.S b/bsps/arm/shared/start/start.S
index aa0f3782c9..b85ad1ddec 100644
--- a/bsps/arm/shared/start/start.S
+++ b/bsps/arm/shared/start/start.S
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2008, 2016 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2008, 2018 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -19,45 +19,10 @@
  */
 
 #include <rtems/asm.h>
-#include <rtems/system.h>	
 #include <rtems/score/percpu.h>
-	
+
 #include <bspopts.h>
 #include <bsp/irq.h>
-#include <bsp/linker-symbols.h>
-
-	/* External symbols */
-	.extern	bsp_reset
-	.extern	boot_card
-	.extern	bsp_start_hook_0
-	.extern	bsp_start_hook_1
-	.extern bsp_stack_irq_end
-	.extern bsp_stack_fiq_end
-	.extern bsp_stack_abt_end
-	.extern bsp_stack_und_end
-	.extern bsp_stack_svc_end
-#ifdef RTEMS_SMP
-	.extern bsp_stack_all_size
-#endif
-	.extern	_ARMV4_Exception_undef_default
-	.extern	_ARMV4_Exception_swi_default
-	.extern	_ARMV4_Exception_data_abort_default
-	.extern	_ARMV4_Exception_pref_abort_default
-	.extern	_ARMV4_Exception_reserved_default
-	.extern	_ARMV4_Exception_interrupt
-	.extern	_ARMV4_Exception_fiq_default
-	.extern	_ARMV7M_Exception_default
-
-#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
-	.extern bsp_start_init_registers_core
-	.extern bsp_start_init_registers_banked_fiq
-	.extern bsp_start_init_registers_vfp
-#endif
-
-#ifdef BSP_START_IN_HYP_SUPPORT
-	.extern	bsp_start_arm_drop_hyp_mode
-	.globl	bsp_start_hyp_vector_table_begin
-#endif
 
 	/* Global symbols */
 	.globl	_start
@@ -65,12 +30,17 @@
 	.globl	bsp_start_vector_table_end
 	.globl	bsp_start_vector_table_size
 	.globl	bsp_vector_table_size
-	.globl	bsp_start_hook_0_done
 
 	.section	".bsp_start_text", "ax"
 
 #if defined(ARM_MULTILIB_ARCH_V4)
 
+	.globl	bsp_start_hook_0_done
+
+#ifdef BSP_START_IN_HYP_SUPPORT
+	.globl	bsp_start_hyp_vector_table_begin
+#endif
+
 	.arm
 
 /*
@@ -208,12 +178,19 @@ _start:
 	add	r1, r1, r7, asl #PER_CPU_CONTROL_SIZE_LOG2
 	mcr	p15, 0, r1, c13, c0, 4
 
-	/* Calculate stack offset */
-	ldr	r1, =bsp_stack_all_size
+#endif
+
+	/* Calculate interrupt stack area end for current processor */
+	ldr	r1, =_Configuration_Interrupt_stack_size
+#ifdef RTEMS_SMP
 	mul	r1, r7
 #endif
+	ldr	r2, =_Configuration_Interrupt_stack_area
+	add	r7, r1, r2
+
+	/* Save original CPSR value */
+	mrs	r4, cpsr
 
-	mrs	r4, cpsr	/* save original procesor status value  */
 #ifdef BSP_START_IN_HYP_SUPPORT
 	orr	r0, r4, #(ARM_PSR_I | ARM_PSR_F)
 	msr	cpsr, r4
@@ -222,38 +199,22 @@ _start:
 	cmp	r0, #ARM_PSR_M_HYP
 	bne	bsp_start_skip_hyp_svc_switch
 
-	/* Boot loader stats kernel in HYP mode, switch to SVC necessary */
-	ldr	sp, =bsp_stack_hyp_end
-#ifdef RTEMS_SMP
-	add	sp, r1
-#endif
+	/* Boot loader starts kernel in HYP mode, switch to SVC necessary */
+	ldr	r1, =bsp_stack_hyp_size
+	mov	sp, r7
+	sub	r7, r7, r1
 	bl	bsp_start_arm_drop_hyp_mode
 
 bsp_start_skip_hyp_svc_switch:
 #endif
-	/*
-	 * Set SVC mode, disable interrupts and enable ARM instructions.
-	 */
-	mov	r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
-	msr	cpsr, r0
-
 	/* Initialize stack pointer registers for the various modes */
 
-	/* Enter IRQ mode and set up the IRQ stack pointer */
-	mov	r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
-	msr	cpsr, r0
-	ldr	sp, =bsp_stack_irq_end
-#ifdef RTEMS_SMP
-	add	sp, r1
-#endif
-
 	/* Enter FIQ mode and set up the FIQ stack pointer */
 	mov	r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
 	msr	cpsr, r0
-	ldr	sp, =bsp_stack_fiq_end
-#ifdef RTEMS_SMP
-	add	sp, r1
-#endif
+	ldr	r1, =bsp_stack_fiq_size
+	mov	sp, r7
+	sub	r7, r7, r1
 
 #ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
 	bl bsp_start_init_registers_banked_fiq
@@ -262,26 +223,29 @@ bsp_start_skip_hyp_svc_switch:
 	/* Enter ABT mode and set up the ABT stack pointer */
 	mov	r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
 	msr	cpsr, r0
-	ldr	sp, =bsp_stack_abt_end
-#ifdef RTEMS_SMP
-	add	sp, r1
-#endif
+	ldr	r1, =bsp_stack_abt_size
+	mov	sp, r7
+	sub	r7, r7, r1
 
 	/* Enter UND mode and set up the UND stack pointer */
 	mov	r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
 	msr	cpsr, r0
-	ldr	sp, =bsp_stack_und_end
-#ifdef RTEMS_SMP
-	add	sp, r1
-#endif
+	ldr	r1, =bsp_stack_und_size
+	mov	sp, r7
+	sub	r7, r7, r1
+
+	/* Enter IRQ mode and set up the IRQ stack pointer */
+	mov	r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
+	msr	cpsr, r0
+	mov	sp, r7
 
-	/* Enter SVC mode and set up the SVC stack pointer */
+	/*
+	 * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
+	 * (interrupts are disabled).
+	 */
 	mov	r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
 	msr	cpsr, r0
-	ldr	sp, =bsp_stack_svc_end
-#ifdef RTEMS_SMP
-	add	sp, r1
-#endif
+	mov	sp, r7
 
 	/* Stay in SVC mode */
 
@@ -333,7 +297,7 @@ bsp_start_skip_hyp_svc_switch:
 
 	SWITCH_FROM_ARM_TO_THUMB	r0
 
-	mov	r0, r4		/* original cpsr value */
+	mov	r0, r4		/* original CPSR value */
 	mov	r1, r5		/* machine type number or ~0 for DT boot */
 	mov	r2, r6		/* physical address of ATAGs or DTB */
 
@@ -385,13 +349,11 @@ twiddle:
 
 	.syntax	unified
 
-	.extern	bsp_stack_main_end
-
 	.thumb
 
 bsp_start_vector_table_begin:
 
-	.word	bsp_stack_main_end
+	.word	bsp_rtemsstack_interrupt_end
 	.word	_start /* Reset */
 	.word	_ARMV7M_Exception_default /* NMI */
 	.word	_ARMV7M_Exception_default /* Hard Fault */
@@ -441,7 +403,7 @@ _start:
 
 #endif /* ARM_MULTILIB_VFP */
 
-	ldr	sp, =bsp_stack_main_end
+	ldr	sp, =bsp_rtemsstack_interrupt_end
 	ldr	lr, =bsp_start_hook_0_done + 1
 	b	bsp_start_hook_0
 
diff --git a/bsps/arm/smdk2410/start/start.S b/bsps/arm/smdk2410/start/start.S
index 95d781cb89..e3122648aa 100644
--- a/bsps/arm/smdk2410/start/start.S
+++ b/bsps/arm/smdk2410/start/start.S
@@ -8,20 +8,8 @@
  *  http://www.rtems.org/license/LICENSE.
  */
 
-#include <bsp/linker-symbols.h>
-
-/* Some standard definitions...*/
-.equ PSR_MODE_USR,       0x10
-.equ PSR_MODE_FIQ,       0x11
-.equ PSR_MODE_IRQ,       0x12
-.equ PSR_MODE_SVC,       0x13
-.equ PSR_MODE_ABT,       0x17
-.equ PSR_MODE_UNDEF,     0x1B
-.equ PSR_MODE_SYS,       0x1F
-
-.equ PSR_I,              0x80
-.equ PSR_F,              0x40
-.equ PSR_T,              0x20
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
 
 .text
 .globl  _start
@@ -65,43 +53,48 @@ _start2:
         /*
          * Since I don't plan to return to the bootloader,
          * I don't have to save the registers.
-         *
-         * I'll just set the CPSR for SVC mode, interrupts
-         * off, and ARM instructions.
          */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)
-        msr     cpsr, r0
 
-        /* --- Initialize stack pointer registers */
-        /* Enter IRQ mode and set up the IRQ stack pointer */
-        mov     r0, #(PSR_MODE_IRQ | PSR_I | PSR_F)     /* No interrupts */
-        msr     cpsr, r0
-        ldr     r1, =bsp_stack_irq_size
-        ldr     sp, =bsp_stack_irq_begin
-        add     sp, sp, r1
+        /* Calculate interrupt stack area end */
+        ldr     r1, =_Configuration_Interrupt_stack_size
+        ldr     r2, =_Configuration_Interrupt_stack_area
+        add     r7, r1, r2
 
         /* Enter FIQ mode and set up the FIQ stack pointer */
-        mov     r0, #(PSR_MODE_FIQ | PSR_I | PSR_F)     /* No interrupts */
+        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_fiq_size
-        ldr     sp, =bsp_stack_fiq_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
 
         /* Enter ABT mode and set up the ABT stack pointer */
-        mov     r0, #(PSR_MODE_ABT | PSR_I | PSR_F)     /* No interrupts */
+        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
         ldr     r1, =bsp_stack_abt_size
-        ldr     sp, =bsp_stack_abt_begin
-        add     sp, sp, r1
+        mov     sp, r7
+        sub     r7, r7, r1
+
+        /* Enter UND mode and set up the UND stack pointer */
+        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_und_size
+        mov     sp, r7
+        sub     r7, r7, r1
+
+        /* Enter IRQ mode and set up the IRQ stack pointer */
+        mov     r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
+        msr     cpsr, r0
+        mov     sp, r7
 
-        /* Set up the SVC stack pointer last and stay in SVC mode */
-        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)     /* No interrupts */
+        /*
+         * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
+         * (interrupts are disabled).
+         */
+        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
         msr     cpsr, r0
-        ldr     r1, =bsp_stack_svc_size
-        ldr     sp, =bsp_stack_svc_begin
-        add     sp, sp, r1
-        sub     sp, sp, #0x64
+        mov     sp, r7
 
+        /* Stay in SVC mode */
 
 	/* disable mmu, I and D caches*/
 	nop
diff --git a/bsps/arm/xilinx-zynq/start/linkcmds.in b/bsps/arm/xilinx-zynq/start/linkcmds.in
index 7fd6e2772d..b56309bf37 100644
--- a/bsps/arm/xilinx-zynq/start/linkcmds.in
+++ b/bsps/arm/xilinx-zynq/start/linkcmds.in
@@ -6,8 +6,6 @@ MEMORY {
    NOCACHE   : ORIGIN = @ZYNQ_RAM_ORIGIN_AVAILABLE@ + @ZYNQ_RAM_LENGTH_AVAILABLE@ - @ZYNQ_RAM_NOCACHE_LENGTH@, LENGTH = @ZYNQ_RAM_NOCACHE_LENGTH@
 }
 
-bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : @ZYNQ_CPUS@;
-
 REGION_ALIAS ("REGION_START",          RAM);
 REGION_ALIAS ("REGION_VECTOR",         RAM);
 REGION_ALIAS ("REGION_TEXT",           RAM);
@@ -26,7 +24,6 @@ REGION_ALIAS ("REGION_STACK",          RAM);
 REGION_ALIAS ("REGION_NOCACHE",        NOCACHE);
 REGION_ALIAS ("REGION_NOCACHE_LOAD",   NOCACHE);
 
-bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
 bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
 
 bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
diff --git a/bsps/sparc/shared/start/bspgetworkarea.c b/bsps/sparc/shared/start/bspgetworkarea.c
index b05113d9eb..512d223211 100644
--- a/bsps/sparc/shared/start/bspgetworkarea.c
+++ b/bsps/sparc/shared/start/bspgetworkarea.c
@@ -27,13 +27,9 @@ extern uint32_t rdb_start;
  */
 void bsp_work_area_initialize(void)
 {
-  /* must be identical to STACK_SIZE in start.S */
-  #define STACK_SIZE (16 * 1024)
-
   /* Early dynamic memory allocator is placed just above _end  */
   void *work_area_start = (void *)&end;
-  uintptr_t work_area_size  =
-    (uintptr_t)rdb_start - (uintptr_t)&end - STACK_SIZE;
+  uintptr_t work_area_size = (uintptr_t)rdb_start - (uintptr_t)work_area_start;
 
   /*
    *  The following may be helpful in debugging what goes wrong when
diff --git a/bsps/sparc/shared/start/start.S b/bsps/sparc/shared/start/start.S
index 64498c6110..5897d83c8a 100644
--- a/bsps/sparc/shared/start/start.S
+++ b/bsps/sparc/shared/start/start.S
@@ -265,7 +265,6 @@ SYM(CLOCK_SPEED):
 
 #define PSR_INIT   0x10c0       /* Disable traps, set s and ps */
 #define WIM_INIT   2
-#define STACK_SIZE 16 * 1024
 
         PUBLIC(hard_reset)
 SYM(hard_reset):
@@ -317,9 +316,12 @@ SYM(hard_reset):
 	st	%o0, [%o1]
 #endif
 
-	set	(SYM(rdb_start)), %g5	! End of RAM
+	set	SYM(rdb_start), %g5	! End of RAM
 	st	%sp, [%g5]
-	sub	%sp, 4, %sp		! stack starts at end of RAM - 4
+	set	SYM(_Configuration_Interrupt_stack_size), %g5
+	set	SYM(_Configuration_Interrupt_stack_area), %sp
+	add	%sp, %g5, %sp
+	sub	%sp, 4, %sp		! stack starts at end of area - 4
 	andn	%sp, 0x0f, %sp		! align stack on 16-byte boundary
         mov     %sp, %fp                ! Set frame pointer
         nop
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am b/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am
index 3c5bea2029..5f34001877 100644
--- a/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am
@@ -19,7 +19,6 @@ project_lib_DATA = start.$(OBJEXT)
 project_lib_DATA += linkcmds
 dist_project_lib_DATA += ../../../../../../bsps/arm/altera-cyclone-v/start/linkcmds.altcycv
 dist_project_lib_DATA += ../../../../../../bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit
-dist_project_lib_DATA += ../../../../../../bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit_smp
 
 project_lib_LIBRARIES = librtemsbsp.a
 
diff --git a/c/src/lib/libbsp/arm/raspberrypi/configure.ac b/c/src/lib/libbsp/arm/raspberrypi/configure.ac
index c88ce82f43..0f3a399877 100644
--- a/c/src/lib/libbsp/arm/raspberrypi/configure.ac
+++ b/c/src/lib/libbsp/arm/raspberrypi/configure.ac
@@ -10,6 +10,7 @@ AC_INIT([rtems-c-src-lib-libbsp-arm-raspberrypi],[_RTEMS_VERSION],[https://devel
 RTEMS_TOP(../../../../../..)
 RTEMS_SOURCE_TOP
 RTEMS_BUILD_TOP
+RTEMS_BSP_LINKCMDS
 
 RTEMS_CANONICAL_TARGET_CPU
 AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.12.2])
@@ -36,21 +37,7 @@ RTEMS_BSPOPTS_SET([BSP_IS_RPI2],[*],[0])
 RTEMS_BSPOPTS_HELP([BSP_IS_RPI2],[Set if the BSP variant is Raspberry Pi 2.])
 AM_CONDITIONAL(RTEMS_RPI2,[test "$BSP_IS_RPI2" = "1"])
 
-# Hom many CPUs are used?
-RASPBERRYPI_CPUS="1"
-AS_IF([test "$rtems_cv_HAS_SMP" = "yes"],
-      [RASPBERRYPI_CPUS="4"])
-
-AC_DEFUN([RASPBERRYPI_LINKCMD],[
-AC_ARG_VAR([$1],[$2; default $3])dnl
-[$1]=[$]{[$1]:-[$3]}
-])
-
-RASPBERRYPI_LINKCMD([RASPBERRYPI_CPUS],[Number of active cores],[${RASPBERRYPI_CPUS}])
-
 RTEMS_BSP_CLEANUP_OPTIONS
 
-AC_CONFIG_FILES([
-Makefile
-linkcmds:../../../../../../bsps/arm/raspberrypi/start/linkcmds.in])
+AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
diff --git a/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am b/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am
index e41e065ba1..01e1f3eae4 100644
--- a/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am
+++ b/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am
@@ -26,7 +26,6 @@ project_lib_DATA = start.$(OBJEXT)
 
 project_lib_DATA += linkcmds
 dist_project_lib_DATA += ../../../../../../bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu
-dist_project_lib_DATA += ../../../../../../bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp
 
 ###############################################################################
 #                  LibBSP                                                     #
diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/configure.ac b/c/src/lib/libbsp/arm/xilinx-zynq/configure.ac
index e282b3546b..f58b737b1b 100644
--- a/c/src/lib/libbsp/arm/xilinx-zynq/configure.ac
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/configure.ac
@@ -58,10 +58,6 @@ RTEMS_BSPOPTS_HELP([BSP_CONSOLE_MINOR],[minor number of console device])
 RTEMS_BSPOPTS_SET([ZYNQ_CONSOLE_USE_INTERRUPTS],[*],[1])
 RTEMS_BSPOPTS_HELP([ZYNQ_CONSOLE_USE_INTERRUPTS],[use interrupt driven mode for console devices (used by default)])
 
-ZYNQ_CPUS="1"
-AS_IF([test "$rtems_cv_HAS_SMP" = "yes"],
-      [ZYNQ_CPUS="2"])
-
 #
 # Zynq Memory map can be controlled from the configure command line. Use ...
 #
@@ -126,7 +122,6 @@ AC_ARG_VAR([$1],[$2; default $3])dnl
 [$1]=[$]{[$1]:-[$3]}
 ])
 
-ZYNQ_LINKCMD([ZYNQ_CPUS],[Number of active cores],[${ZYNQ_CPUS}])
 ZYNQ_LINKCMD([ZYNQ_RAM_ORIGIN],[normal RAM region origin],[${ZYNQ_RAM_ORIGIN}])
 ZYNQ_LINKCMD([ZYNQ_RAM_LENGTH],[normal RAM region length],[${BSP_ZYNQ_RAM_LENGTH}])
 ZYNQ_LINKCMD([ZYNQ_RAM_MMU],[MMU region origin],[${ZYNQ_RAM_MMU}])
diff --git a/cpukit/include/rtems/confdefs.h b/cpukit/include/rtems/confdefs.h
index 69bc88aa9d..891aabaa72 100644
--- a/cpukit/include/rtems/confdefs.h
+++ b/cpukit/include/rtems/confdefs.h
@@ -1215,12 +1215,13 @@ RTEMS_SYSINIT_ITEM(
   #error "CONFIGURE_IDLE_TASK_STACK_SIZE less than CONFIGURE_MINIMUM_TASK_STACK_SIZE"
 #endif
 
-/**
- * @brief Interrupt stack size configuration.
+/*
+ * Interrupt stack configuration.
  *
  * By default, the interrupt stack will be of minimum size.
  * The BSP or application may override this value.
  */
+
 #ifndef CONFIGURE_INTERRUPT_STACK_SIZE
   #ifdef BSP_INTERRUPT_STACK_SIZE
     #define CONFIGURE_INTERRUPT_STACK_SIZE BSP_INTERRUPT_STACK_SIZE
@@ -1229,18 +1230,20 @@ RTEMS_SYSINIT_ITEM(
   #endif
 #endif
 
-/**
- * This reserves memory for the interrupt stack if it is to be allocated
- * by RTEMS rather than the BSP.
- *
- * @todo Try to get to the point where all BSPs support allocating the
- *       memory from the Workspace.
- */
-#if (CPU_ALLOCATE_INTERRUPT_STACK == 0)
-  #define _CONFIGURE_INTERRUPT_STACK_MEMORY 0
-#else
-  #define _CONFIGURE_INTERRUPT_STACK_MEMORY \
-     _Configure_From_workspace( CONFIGURE_INTERRUPT_STACK_SIZE )
+#if CONFIGURE_INTERRUPT_STACK_SIZE % CPU_INTERRUPT_STACK_ALIGNMENT != 0
+  #error "CONFIGURE_INTERRUPT_STACK_SIZE fails to meet the CPU port interrupt stack alignment"
+#endif
+
+#ifdef CONFIGURE_INIT
+  RTEMS_DEFINE_GLOBAL_SYMBOL(
+    _Configuration_Interrupt_stack_size,
+    CONFIGURE_INTERRUPT_STACK_SIZE
+  );
+
+  char _Configuration_Interrupt_stack_area[
+    CONFIGURE_MAXIMUM_PROCESSORS * CONFIGURE_INTERRUPT_STACK_SIZE
+  ] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
+  RTEMS_SECTION( ".rtemsstack.interrupt" );
 #endif
 
 /**
@@ -2756,9 +2759,7 @@ RTEMS_SYSINIT_ITEM(
  * This macro accounts for general RTEMS system overhead.
  */
 #define _CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \
-  ( _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS + \
-    _CONFIGURE_INTERRUPT_STACK_MEMORY \
-  )
+  _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS
 
 /**
  * This macro reserves the memory required by the statically configured
@@ -2788,18 +2789,6 @@ RTEMS_SYSINIT_ITEM(
    _CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(CONFIGURE_MAXIMUM_USER_EXTENSIONS) \
   )
 
-/*
- * This macro provides a summation of the memory required by SMP as configured.
- */
-#if defined(RTEMS_SMP)
-  #define _CONFIGURE_MEMORY_FOR_SMP \
-     (CONFIGURE_MAXIMUM_PROCESSORS * \
-      _Configure_From_workspace( CONFIGURE_INTERRUPT_STACK_SIZE ) \
-     )
-#else
-  #define _CONFIGURE_MEMORY_FOR_SMP 0
-#endif
-
 /**
  * This calculates the memory required for the executive workspace.
  *
@@ -2819,7 +2808,6 @@ RTEMS_SYSINIT_ITEM(
    _CONFIGURE_MEMORY_FOR_POSIX + \
    _CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS + \
    _CONFIGURE_MEMORY_FOR_MP + \
-   _CONFIGURE_MEMORY_FOR_SMP + \
    CONFIGURE_MESSAGE_BUFFER_MEMORY + \
    (CONFIGURE_MEMORY_OVERHEAD * 1024) + \
    _CONFIGURE_HEAP_HANDLER_OVERHEAD \
@@ -3118,7 +3106,6 @@ RTEMS_SYSINIT_ITEM(
     CONFIGURE_TICKS_PER_TIMESLICE,            /* ticks per timeslice quantum */
     CONFIGURE_IDLE_TASK_BODY,                 /* user's IDLE task */
     CONFIGURE_IDLE_TASK_STACK_SIZE,           /* IDLE task stack size */
-    CONFIGURE_INTERRUPT_STACK_SIZE,           /* interrupt stack size */
     CONFIGURE_TASK_STACK_ALLOCATOR_INIT,      /* stack allocator init */
     CONFIGURE_TASK_STACK_ALLOCATOR,           /* stack allocator */
     CONFIGURE_TASK_STACK_DEALLOCATOR,         /* stack deallocator */
@@ -3275,7 +3262,6 @@ RTEMS_SYSINIT_ITEM(
     uint32_t POSIX;
 
     /* System overhead pieces */
-    uint32_t INTERRUPT_STACK_MEMORY;
     uint32_t MEMORY_FOR_IDLE_TASK;
 
     /* Classic API Pieces */
@@ -3324,7 +3310,6 @@ RTEMS_SYSINIT_ITEM(
     _CONFIGURE_MEMORY_FOR_POSIX,
 
     /* System overhead pieces */
-    _CONFIGURE_INTERRUPT_STACK_MEMORY,
     _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS,
 
     /* Classic API Pieces */
diff --git a/cpukit/include/rtems/config.h b/cpukit/include/rtems/config.h
index 6b97376511..6eedb2d5d2 100644
--- a/cpukit/include/rtems/config.h
+++ b/cpukit/include/rtems/config.h
@@ -184,13 +184,6 @@ typedef struct {
    */
   uint32_t                       idle_task_stack_size;
 
-  /** 
-   * This field specifies the size of the interrupt stack.  If less than or
-   * equal to the minimum stack size, then the interrupt stack will be of
-   * minimum stack size.
-   */
-  uint32_t                       interrupt_stack_size;
-
   /**
    * @brief Optional task stack allocator initialization hook.
    */
@@ -313,8 +306,25 @@ extern const rtems_configuration_table Configuration;
 #define rtems_configuration_get_idle_task_stack_size() \
         (Configuration.idle_task_stack_size)
 
+/**
+ * @brief Global symbol with a value equal to the configure interrupt stack size.
+ *
+ * This global symbol is defined by the application configuration option
+ * CONFIGURE_INIT_TASK_STACK_SIZE via <rtems/confdefs.h>.
+ */
+RTEMS_DECLARE_GLOBAL_SYMBOL( _Configuration_Interrupt_stack_size );
+
+/**
+ * @brief The interrupt stack area.
+ *
+ * The interrupt stack area is defined by the application configuration via
+ * <rtems/confdefs.h>.  The size of the area depends on
+ * CONFIGURE_INIT_TASK_STACK_SIZE and CONFIGURE_MAXIMUM_PROCESSORS.
+ */
+extern char _Configuration_Interrupt_stack_area[];
+
 #define rtems_configuration_get_interrupt_stack_size() \
-        (Configuration.interrupt_stack_size)
+        ((size_t) _Configuration_Interrupt_stack_size)
 
 #define rtems_configuration_get_stack_allocate_init_hook() \
         (Configuration.stack_allocate_init_hook)
diff --git a/cpukit/include/rtems/score/percpu.h b/cpukit/include/rtems/score/percpu.h
index 360d62807c..9c493a9355 100644
--- a/cpukit/include/rtems/score/percpu.h
+++ b/cpukit/include/rtems/score/percpu.h
@@ -295,20 +295,15 @@ typedef struct Per_CPU_Control {
     CPU_Per_CPU_control cpu_per_cpu;
   #endif
 
-  #if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
-      (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
-    /**
-     * This contains a pointer to the lower range of the interrupt stack for
-     * this CPU.  This is the address allocated and freed.
-     */
-    void  *interrupt_stack_low;
+  /**
+   * @brief The interrupt stack low address for this processor.
+   */
+  void *interrupt_stack_low;
 
-    /**
-     * This contains a pointer to the interrupt stack pointer for this CPU.
-     * It will be loaded at the beginning on an ISR.
-     */
-    void  *interrupt_stack_high;
-  #endif
+  /**
+   * @brief The interrupt stack high address for this processor.
+   */
+  void *interrupt_stack_high;
 
   /**
    *  This contains the current interrupt nesting level on this
@@ -804,33 +799,21 @@ RTEMS_INLINE_ROUTINE struct _Thread_Control *_Thread_Get_executing( void )
 
 #if defined( ASM ) || defined( _RTEMS_PERCPU_DEFINE_OFFSETS )
 
-#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
-    (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
-  /*
-   *  If this CPU target lets RTEMS allocates the interrupt stack, then
-   *  we need to have places in the per CPU table to hold them.
-   */
-  #define PER_CPU_INTERRUPT_STACK_LOW \
-    CPU_PER_CPU_CONTROL_SIZE
-  #define PER_CPU_INTERRUPT_STACK_HIGH \
-    PER_CPU_INTERRUPT_STACK_LOW + CPU_SIZEOF_POINTER
-  #define PER_CPU_END_STACK             \
-    PER_CPU_INTERRUPT_STACK_HIGH + CPU_SIZEOF_POINTER
-
-  #define INTERRUPT_STACK_LOW \
-    (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_LOW)
-  #define INTERRUPT_STACK_HIGH \
-    (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_HIGH)
-#else
-  #define PER_CPU_END_STACK \
-    CPU_PER_CPU_CONTROL_SIZE
-#endif
+#define PER_CPU_INTERRUPT_STACK_LOW \
+  CPU_PER_CPU_CONTROL_SIZE
+#define PER_CPU_INTERRUPT_STACK_HIGH \
+  PER_CPU_INTERRUPT_STACK_LOW + CPU_SIZEOF_POINTER
+
+#define INTERRUPT_STACK_LOW \
+  (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_LOW)
+#define INTERRUPT_STACK_HIGH \
+  (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_HIGH)
 
 /*
  *  These are the offsets of the required elements in the per CPU table.
  */
 #define PER_CPU_ISR_NEST_LEVEL \
-  PER_CPU_END_STACK
+  PER_CPU_INTERRUPT_STACK_HIGH + CPU_SIZEOF_POINTER
 #define PER_CPU_ISR_DISPATCH_DISABLE \
   PER_CPU_ISR_NEST_LEVEL + 4
 #define PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL \
diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpu.h b/cpukit/score/cpu/arm/include/rtems/score/cpu.h
index 3f06c036f0..4260e98221 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/cpu.h
@@ -105,12 +105,6 @@
  */
 #define CPU_SIMPLE_VECTORED_INTERRUPTS FALSE
 
-#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
-
-#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
-
-#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
-
 #define CPU_ISR_PASSES_FRAME_POINTER FALSE
 
 #define CPU_HARDWARE_FP FALSE
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
index 8aa701dde2..59b60e377c 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
@@ -69,17 +69,6 @@ extern "C" {
 #endif
 
 /**
- * Does the executive manage a dedicated interrupt stack in software?
- *
- * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
- * If FALSE, nothing is done.
- *
- * The SPARC does not have a dedicated HW interrupt stack and one has
- * been implemented in SW.
- */
-#define CPU_HAS_SOFTWARE_INTERRUPT_STACK   TRUE
-
-/**
  * Does the CPU follow the simple vectored interrupt model?
  *
  * - If TRUE, then RTEMS allocates the vector table it internally manages.
@@ -92,29 +81,6 @@ extern "C" {
 #define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
 
 /**
- * Does this CPU have hardware support for a dedicated interrupt stack?
- *
- * - If TRUE, then it must be installed during initialization.
- * - If FALSE, then no installation is performed.
- *
- * The SPARC does not have a dedicated HW interrupt stack.
- */
-#define CPU_HAS_HARDWARE_INTERRUPT_STACK  FALSE
-
-/**
- * Do we allocate a dedicated interrupt stack in the Interrupt Manager?
- *
- * - If TRUE, then the memory is allocated during initialization.
- * - If FALSE, then the memory is allocated during initialization.
- *
- * The SPARC does not have hardware support for switching to a
- * dedicated interrupt stack.  The port includes support for doing this
- * in software.
- *
- */
-#define CPU_ALLOCATE_INTERRUPT_STACK      TRUE
-
-/**
  * Does the RTEMS invoke the user's ISR with the vector number and
  * a pointer to the saved interrupt frame (1) or just the vector
  * number (0)?
diff --git a/cpukit/score/src/isr.c b/cpukit/score/src/isr.c
index 1078ef6f63..a61df057c3 100644
--- a/cpukit/score/src/isr.c
+++ b/cpukit/score/src/isr.c
@@ -23,7 +23,6 @@
 #include <rtems/score/interr.h>
 #include <rtems/score/percpu.h>
 #include <rtems/score/stackimpl.h>
-#include <rtems/score/wkspace.h>
 #include <rtems/config.h>
 
 #if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
@@ -36,51 +35,48 @@
 
 void _ISR_Handler_initialization( void )
 {
+  uint32_t  cpu_max;
+  uint32_t  cpu_index;
+  size_t    stack_size;
+  char     *stack_low;
+
   _ISR_Nest_level = 0;
 
 #if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
   _CPU_Initialize_vectors();
 #endif
 
-#if ( CPU_ALLOCATE_INTERRUPT_STACK == TRUE )
-  {
-    size_t stack_size = rtems_configuration_get_interrupt_stack_size();
-    uint32_t cpu_max = rtems_configuration_get_maximum_processors();
-    uint32_t cpu_index;
+  stack_size = rtems_configuration_get_interrupt_stack_size();
 
-    if ( !_Stack_Is_enough( stack_size ) )
-      _Internal_error( INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL );
+  if ( !_Stack_Is_enough( stack_size ) )
+    _Internal_error( INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL );
 
-    for ( cpu_index = 0 ; cpu_index < cpu_max; ++cpu_index ) {
-      Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
-      void *low = _Workspace_Allocate_or_fatal_error( stack_size );
-      void *high = _Addresses_Add_offset( low, stack_size );
+  cpu_max = rtems_configuration_get_maximum_processors();
+  stack_low = _Configuration_Interrupt_stack_area;
 
-#if (CPU_STACK_ALIGNMENT != 0)
-      high = _Addresses_Align_down( high, CPU_STACK_ALIGNMENT );
-#endif
+  for ( cpu_index = 0 ; cpu_index < cpu_max; ++cpu_index ) {
+    Per_CPU_Control *cpu;
+    char            *stack_high;
 
-      cpu->interrupt_stack_low = low;
-      cpu->interrupt_stack_high = high;
+    cpu = _Per_CPU_Get_by_index( cpu_index );
+    stack_high = _Addresses_Add_offset( stack_low, stack_size );
 
-      /*
-       * Interrupt stack might have to be aligned and/or setup in a specific
-       * way.  Do not use the local low or high variables here since
-       * _CPU_Interrupt_stack_setup() is a nasty macro that might want to play
-       * with the real memory locations.
-       */
-#if defined(_CPU_Interrupt_stack_setup)
-      _CPU_Interrupt_stack_setup(
-        cpu->interrupt_stack_low,
-        cpu->interrupt_stack_high
-      );
-#endif
-    }
-  }
+    cpu->interrupt_stack_low = stack_low;
+    cpu->interrupt_stack_high = stack_high;
 
+    /*
+     * Interrupt stack might have to be aligned and/or setup in a specific
+     * way.  Do not use the local low or high variables here since
+     * _CPU_Interrupt_stack_setup() is a nasty macro that might want to play
+     * with the real memory locations.
+     */
+#if defined(_CPU_Interrupt_stack_setup)
+    _CPU_Interrupt_stack_setup(
+      cpu->interrupt_stack_low,
+      cpu->interrupt_stack_high
+    );
 #endif
 
-#if ( CPU_HAS_HARDWARE_INTERRUPT_STACK == TRUE )
-  _CPU_Install_interrupt_stack();
-#endif
+    stack_low = stack_high;
+  }
 }
diff --git a/cpukit/score/src/percpuasm.c b/cpukit/score/src/percpuasm.c
index 2908643f6c..ccd101a929 100644
--- a/cpukit/score/src/percpuasm.c
+++ b/cpukit/score/src/percpuasm.c
@@ -122,17 +122,14 @@ RTEMS_STATIC_ASSERT(
 );
 #endif
 
-#if CPU_ALLOCATE_INTERRUPT_STACK == TRUE \
-  || CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE
-  RTEMS_STATIC_ASSERT(
-    offsetof(Per_CPU_Control, interrupt_stack_low)
-      == PER_CPU_INTERRUPT_STACK_LOW,
-    PER_CPU_INTERRUPT_STACK_LOW
-  );
+RTEMS_STATIC_ASSERT(
+  offsetof(Per_CPU_Control, interrupt_stack_low)
+    == PER_CPU_INTERRUPT_STACK_LOW,
+  PER_CPU_INTERRUPT_STACK_LOW
+);
 
-  RTEMS_STATIC_ASSERT(
-    offsetof(Per_CPU_Control, interrupt_stack_high)
-      == PER_CPU_INTERRUPT_STACK_HIGH,
-    PER_CPU_INTERRUPT_STACK_HIGH
-  );
-#endif
+RTEMS_STATIC_ASSERT(
+  offsetof(Per_CPU_Control, interrupt_stack_high)
+    == PER_CPU_INTERRUPT_STACK_HIGH,
+  PER_CPU_INTERRUPT_STACK_HIGH
+);
diff --git a/testsuites/sptests/spsize/size.c b/testsuites/sptests/spsize/size.c
index 7b7b3a5dbb..951cdd7414 100644
--- a/testsuites/sptests/spsize/size.c
+++ b/testsuites/sptests/spsize/size.c
@@ -391,10 +391,8 @@ uninitialized =
 /* cpu.h */
 uninitialized += (sizeof _CPU_Null_fp_context);
 
-#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE)
 uninitialized += (sizeof _CPU_Interrupt_stack_low) +
                  (sizeof _CPU_Interrupt_stack_high);
-#endif
 
 #endif
 
-- 
2.13.7



More information about the devel mailing list