Skip to content

Commit 15e22bd

Browse files
committed
arch/tricore: bring up CPU2 secondaries for 3-core SMP
- Macro secondary cold entry for DSPR1/DSPR2 CSA segments - Per-core ISP in secondary_init; start CPU2 via board API + GPSR2 - generate_ld: HAVE_CSA_CPU2 / csa_pool_cpu2.ld.in
1 parent c6784cb commit 15e22bd

4 files changed

Lines changed: 101 additions & 38 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* arch/tricore/linker/csa_pool_cpu2.ld.in
2+
* Layer 2 — TriCore SMP: CSA + ISP + park stack in DSPR2 (KERNEL_RAM_CPU2).
3+
* Included by generate_ld.py when HAVE_CSA_CPU2 = 1 in the chip memory.ld.
4+
*
5+
* CPU2 must never share FCX/LCX with CPU0/CPU1 — CSA is a per-core CSFR.
6+
*/
7+
8+
.csa_pool_cpu2 (NOLOAD) : ALIGN(64) {
9+
_ulmk_csa_pool_cpu2_start = .;
10+
. += ULMK_CSA_POOL_CPU2_SIZE;
11+
_ulmk_csa_pool_cpu2_end = .;
12+
} > KERNEL_RAM_CPU2
13+
14+
.isr_stack_cpu2 (NOLOAD) : ALIGN(8) {
15+
_ulmk_isr_stack_cpu2_bottom = .;
16+
. += ULMK_ISR_STACK_SIZE;
17+
_ulmk_isr_stack_cpu2_top = .;
18+
} > KERNEL_RAM_CPU2
19+
20+
.park_stack_cpu2 (NOLOAD) : ALIGN(8) {
21+
_ulmk_park_stack_cpu2_bottom = .;
22+
. += ULMK_KERNEL_STACK_SIZE;
23+
_ulmk_park_stack_cpu2_top = .;
24+
} > KERNEL_RAM_CPU2

arch/tricore/secondary.S

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,67 @@
11
/* SPDX-License-Identifier: MIT */
22
/*
3-
* CPU1 cold entry — arch/tricore/secondary.S
3+
* Secondary cold entry — arch/tricore/secondary.S
44
*
5-
* Reset leaves CPU1 halted. CPU0 programs PC to _ulmk_cpu1_start and clears
6-
* DBGSR.HALT. This prologue builds a private CSA free list in DSPR1
7-
* (segment 0x6), loads park SP + small-data anchors, then jumps to
8-
* ulmk_arch_smp_park() which waits for release and calls the kernel entry.
5+
* Reset leaves secondaries halted. CPU0 programs each PC to _ulmk_cpuN_start
6+
* and clears DBGSR.HALT. The prologue builds a private CSA free list in that
7+
* core's DSPR (segment 0x6 / 0x5), loads park SP + small-data anchors, then
8+
* jumps to ulmk_arch_smp_park().
99
*
1010
* Board WDT for this core is handled by ulmk_board_cpu_wdt_disable_self()
1111
* inside ulmk_arch_smp_park() — no board SFRs in this file.
1212
*/
1313

14-
.extern _ulmk_park_stack_cpu1_top
15-
.extern _ulmk_csa_pool_cpu1_start
16-
.extern _ulmk_csa_pool_cpu1_end
1714
.extern _small_data_
1815
.extern _small_data2_
1916
.extern _small_data3_
2017
.extern _small_data4_
2118
.extern ulmk_arch_smp_park
2219

23-
.section .text._ulmk_cpu1_start, "ax"
24-
.global _ulmk_cpu1_start
25-
.type _ulmk_cpu1_start, @function
26-
_ulmk_cpu1_start:
20+
/*
21+
* N: cpu index suffix (1 / 2)
22+
* SEG: CSA link segment field (6 = DSPR1 @ 0x6xxx, 5 = DSPR2 @ 0x5xxx)
23+
*/
24+
.macro SECONDARY_COLD_ENTRY name, park_top, csa_start, csa_end, seg
25+
.extern \park_top
26+
.extern \csa_start
27+
.extern \csa_end
28+
29+
.section .text.\name, "ax"
30+
.global \name
31+
.type \name, @function
32+
\name:
2733
disable
2834

29-
movh.a %a10, hi:_ulmk_park_stack_cpu1_top
30-
lea %a10, [%a10] lo:_ulmk_park_stack_cpu1_top
35+
movh.a %a10, hi:\park_top
36+
lea %a10, [%a10] lo:\park_top
3137

32-
/*
33-
* CSA free list for DSPR1 @ 0x6xxx_xxxx:
34-
* link = 0x00060000 | extr.u(addr, 6, 16)
35-
*/
36-
movh.a %a2, hi:_ulmk_csa_pool_cpu1_start
37-
lea %a2, [%a2] lo:_ulmk_csa_pool_cpu1_start
38-
movh.a %a3, hi:_ulmk_csa_pool_cpu1_end
39-
lea %a3, [%a3] lo:_ulmk_csa_pool_cpu1_end
38+
movh.a %a2, hi:\csa_start
39+
lea %a2, [%a2] lo:\csa_start
40+
movh.a %a3, hi:\csa_end
41+
lea %a3, [%a3] lo:\csa_end
4042

4143
lea %a4, [%a2] 0
4244

43-
.L_csa1_link:
45+
.L_\name\()_link:
4446
lea %a5, [%a4] 64
4547
mov.d %d0, %a5
4648
extr.u %d0, %d0, 6, 16
47-
movh %d1, 6
49+
movh %d1, \seg
4850
or %d0, %d1
4951
mov.d %d2, %a5
5052
mov.d %d3, %a3
51-
jge %d2, %d3, .L_csa1_last
53+
jge %d2, %d3, .L_\name\()_last
5254
st.w [%a4], %d0
5355
lea %a4, [%a5] 0
54-
j .L_csa1_link
56+
j .L_\name\()_link
5557

56-
.L_csa1_last:
58+
.L_\name\()_last:
5759
mov %d0, 0
5860
st.w [%a4], %d0
5961

6062
mov.d %d0, %a2
6163
extr.u %d0, %d0, 6, 16
62-
movh %d1, 6
64+
movh %d1, \seg
6365
or %d0, %d1
6466
dsync
6567
mtcr 0xFE38, %d0 /* FCX */
@@ -68,7 +70,7 @@ _ulmk_cpu1_start:
6870
lea %a6, [%a4] 0
6971
mov.d %d0, %a6
7072
extr.u %d0, %d0, 6, 16
71-
movh %d1, 6
73+
movh %d1, \seg
7274
or %d0, %d1
7375
dsync
7476
mtcr 0xFE3C, %d0 /* LCX */
@@ -85,4 +87,15 @@ _ulmk_cpu1_start:
8587

8688
j ulmk_arch_smp_park
8789

88-
.size _ulmk_cpu1_start, . - _ulmk_cpu1_start
90+
.size \name, . - \name
91+
.endm
92+
93+
SECONDARY_COLD_ENTRY _ulmk_cpu1_start, \
94+
_ulmk_park_stack_cpu1_top, \
95+
_ulmk_csa_pool_cpu1_start, \
96+
_ulmk_csa_pool_cpu1_end, 6
97+
98+
SECONDARY_COLD_ENTRY _ulmk_cpu2_start, \
99+
_ulmk_park_stack_cpu2_top, \
100+
_ulmk_csa_pool_cpu2_start, \
101+
_ulmk_csa_pool_cpu2_end, 5

arch/tricore/smp.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <arch_config.h>
1212
#include <board_config.h>
1313

14-
#if defined(ULMK_BOARD_CPU1_PC)
14+
#if defined(ULMK_BOARD_CPU1_PC) || defined(ULMK_BOARD_CPU2_PC)
1515
#include <board_smp.h>
1616
#endif
1717

@@ -36,6 +36,10 @@ extern char _trap_class0[];
3636
extern char _ulmk_int_table[];
3737
extern char _ulmk_isr_stack_cpu1_top[];
3838
extern void _ulmk_cpu1_start(void);
39+
#if defined(ULMK_BOARD_CPU2_PC)
40+
extern char _ulmk_isr_stack_cpu2_top[];
41+
extern void _ulmk_cpu2_start(void);
42+
#endif
3943

4044
static volatile uint32_t *ipi_src(uint32_t cpu)
4145
{
@@ -151,12 +155,24 @@ static void ipi_src_arm(uint32_t cpu)
151155

152156
void ulmk_arch_secondary_init(void)
153157
{
154-
uint32_t cpu = ulmk_arch_cpu_id();
158+
uint32_t cpu = ulmk_arch_cpu_id();
159+
uintptr_t isp;
160+
161+
if (cpu == 1u) {
162+
isp = (uintptr_t)_ulmk_isr_stack_cpu1_top;
163+
#if defined(ULMK_BOARD_CPU2_PC)
164+
} else if (cpu == 2u) {
165+
isp = (uintptr_t)_ulmk_isr_stack_cpu2_top;
166+
#endif
167+
} else {
168+
for (;;)
169+
;
170+
}
155171

156172
ulmk_arch_irq_vectors_init(
157173
(uintptr_t)_trap_class0,
158174
(uintptr_t)_ulmk_int_table,
159-
(uintptr_t)_ulmk_isr_stack_cpu1_top);
175+
isp);
160176
ulmk_arch_mpu_init();
161177
ulmk_arch_mpu_enable();
162178
/*
@@ -191,7 +207,12 @@ void ulmk_arch_start_secondary(uint32_t cpu_id, void (*entry)(void))
191207
#if defined(ULMK_BOARD_CPU1_PC)
192208
if (cpu_id == 1u)
193209
ulmk_board_cpu_start(1u, _ulmk_cpu1_start);
194-
#else
210+
#endif
211+
#if defined(ULMK_BOARD_CPU2_PC)
212+
if (cpu_id == 2u)
213+
ulmk_board_cpu_start(2u, _ulmk_cpu2_start);
214+
#endif
215+
#if !defined(ULMK_BOARD_CPU1_PC) && !defined(ULMK_BOARD_CPU2_PC)
195216
(void)cpu_id;
196217
#endif
197218

@@ -213,7 +234,7 @@ void ulmk_arch_smp_park(void)
213234
;
214235
}
215236

216-
#if defined(ULMK_BOARD_CPU1_PC)
237+
#if defined(ULMK_BOARD_CPU1_PC) || defined(ULMK_BOARD_CPU2_PC)
217238
/* Own WDT — cannot be unlocked safely from CPU0. */
218239
ulmk_board_cpu_wdt_disable_self();
219240
#endif

cmake/generate_ld.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ def render_snippet(path: str, substitutions: dict) -> str:
5353
def parse_flags(chip_memory_ld: str) -> dict:
5454
"""Extract HAVE_* flag values from the chip memory.ld as integers."""
5555
flags = {}
56-
for name in ("HAVE_CSA", "HAVE_CSA_CPU1", "HAVE_SMALL_DATA", "HAVE_BMHD"):
56+
for name in ("HAVE_CSA", "HAVE_CSA_CPU1", "HAVE_CSA_CPU2",
57+
"HAVE_SMALL_DATA", "HAVE_BMHD"):
5758
m = re.search(rf"^\s*{name}\s*=\s*(\d+)\s*;", chip_memory_ld, re.MULTILINE)
5859
flags[name] = int(m.group(1)) if m else 0
5960
return flags
@@ -164,12 +165,16 @@ def main():
164165
# 4q. User pool (always last in KERNEL_RAM)
165166
out.append(read_fragment(os.path.join(args.kernel_dir, "user_pool.ld.in")))
166167

167-
# 4r. CPU1 DSPR CSA/ISP/park — AFTER KERNEL_RAM so VMA '.' is not left
168-
# in 0x60000000 (would corrupt user_ram_start / zero_words span).
168+
# 4r. Secondary DSPR CSA/ISP/park — AFTER KERNEL_RAM so VMA '.' is not
169+
# left in 0x6xxx/0x5xxx (would corrupt user_ram_start / zero_words).
169170
if flags.get("HAVE_CSA_CPU1"):
170171
cpu1 = os.path.join(args.arch_dir, "csa_pool_cpu1.ld.in")
171172
if os.path.exists(cpu1):
172173
out.append(read_fragment(cpu1))
174+
if flags.get("HAVE_CSA_CPU2"):
175+
cpu2 = os.path.join(args.arch_dir, "csa_pool_cpu2.ld.in")
176+
if os.path.exists(cpu2):
177+
out.append(read_fragment(cpu2))
173178

174179
out.append("\n} /* SECTIONS */\n")
175180

0 commit comments

Comments
 (0)