Skip to content

Commit 7f4a937

Browse files
popcornmixPhil Elwell
authored andcommitted
armstubs: Add BCM2711 support
A summary commit of all 2711-related work by many people: * Change OSC to 54MHz * Add L2 read/writ latency * Add GIC support and unconditionally setup the arch timer prescale * Don't enable the data cache before the MMU is enabled. * Enable the Cache after setting SMP bit. Cortex A72 manual 4.3.67 says says SMP must be set before enabling the cache. Probably doesn't make any real difference. N.B. armstub8-32 is for 2710 only and armstub8-32-gic is for 2711, i.e. the GIC flag is also effectively a 2711 flag. Signed-off-by: Phil Elwell <phil@raspberrypi.org>
1 parent 5caa704 commit 7f4a937

File tree

3 files changed

+153
-17
lines changed

3 files changed

+153
-17
lines changed

armstubs/Makefile

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
BINS=armstub.bin armstub7.bin armstub8-32.bin armstub8.bin
1+
BINS=armstub.bin armstub7.bin armstub8-32.bin armstub8-32-gic.bin armstub8.bin armstub8-gic.bin
22

33
CC8=aarch64-linux-gnu-gcc
44
LD8=aarch64-linux-gnu-ld
@@ -20,17 +20,30 @@ clean :
2020
%8.o: %8.S
2121
$(CC8) -c $< -o $@
2222

23+
%8-gic.o: %8.S
24+
$(CC8) -DGIC=1 -c $< -o $@
25+
2326
%8-32.o: %7.S
2427
$(CC) -DBCM2710=1 -c $< -o $@
2528

29+
%8-32-gic.o: %7.S
30+
$(CC) -DGIC=1 -DBCM2710=1 -DBCM2711=1 -c $< -o $@
31+
2632
%.o: %.S
2733
$(CC) -DBCM2710=0 -c $< -o $@
2834

35+
%8-gic.elf: %8-gic.o
36+
$(LD8) --section-start=.text=0 $< -o $@
37+
2938
%8.elf: %8.o
3039
$(LD8) --section-start=.text=0 $< -o $@
3140

3241
%.elf: %.o
3342
$(LD) --section-start=.init=0 $< -o $@
43+
44+
%8-gic.tmp: %8-gic.elf
45+
$(OBJCOPY8) $< -O binary $@
46+
3447
%8.tmp: %8.elf
3548
$(OBJCOPY8) $< -O binary $@
3649

@@ -39,7 +52,7 @@ clean :
3952

4053

4154
%.bin: %.tmp
42-
dd if=$< ibs=256 count=1 of=$@ conv=sync
55+
dd if=$< ibs=512 count=1 of=$@ conv=sync
4356

4457
%8.ds: %8.bin
4558
$(OBJDUMP8) -D --target binary $< > $@
@@ -53,7 +66,7 @@ clean :
5366
$(BIN2C): bin2c.c
5467
gcc $< -o $@
5568

56-
armstubs.h: armstub.C armstub7.C armstub8-32.C armstub8.C
69+
armstubs.h: armstub.C armstub7.C armstub8-32.C armstub8-32-gic.C armstub8.C armstub8-gic.C
5770
echo 'static const unsigned armstub[] = {' > $@
5871
cat armstub.C >> $@
5972
echo '};' >> $@
@@ -63,7 +76,13 @@ armstubs.h: armstub.C armstub7.C armstub8-32.C armstub8.C
6376
echo 'static const unsigned armstub8_32[] = {' >> $@
6477
cat armstub8-32.C >> $@
6578
echo '};' >> $@
79+
echo 'static const unsigned armstub8_32_gic[] = {' >> $@
80+
cat armstub8-32-gic.C >> $@
81+
echo '};' >> $@
6682
echo 'static const unsigned armstub8[] = {' >> $@
6783
cat armstub8.C >> $@
6884
echo '};' >> $@
85+
echo 'static const unsigned armstub8_gic[] = {' >> $@
86+
cat armstub8-gic.C >> $@
87+
echo '};' >> $@
6988

armstubs/armstub7.S

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3333
/* the vector table for secure state and HYP mode */
3434
_start:
3535
b jmp_loader /* reset */
36+
#if defined(BCM2711) && (BCM2711 == 1)
37+
osc: .word 54000000
38+
#else
3639
osc: .word 19200000
40+
#endif
3741

3842
/*
3943
* secure monitor handler
@@ -48,38 +52,108 @@ _secure_monitor:
4852

4953
movw r0, #0x1da @ Set HYP_MODE | F_BIT | I_BIT | A_BIT
5054
msr spsr_cxfs, r0 @ Set full SPSR
55+
56+
#if defined(BCM2711) && (BCM2711 == 1)
57+
mrc p15, 1, r1, c9, c0, 2 @ Read L2CTLR
58+
orr r1, r1, #0x22 @ Set L2 read/write latency to 2
59+
mcr p15, 1, r1, c9, c0, 2 @ Write L2CTLR
60+
#endif
61+
5162
movs pc, lr @ return to non-secure SVC
5263

5364
value: .word 0x63fff
5465
machid: .word 3138
66+
#if defined(BCM2711) && (BCM2711 == 1)
67+
mbox: .word 0xFF80008C
68+
#else
5569
mbox: .word 0x4000008C
70+
#endif
71+
prescaler: .word 0xff800008
72+
GIC_DISTB: .word 0xff841000
73+
GIC_CPUB: .word 0xff842000
74+
75+
#define GICC_CTRLR 0x0
76+
#define GICC_PMR 0x4
77+
#define IT_NR 0x7 @ Number of interrupt enable registers (256 total irqs)
78+
#define GICD_CTRLR 0x0
79+
#define GICD_IGROUPR 0x80
80+
81+
@ Shoehorn the GIC code between the reset vector and fixed-offset magic numbers at 240b
82+
83+
setup_gic: @ Called from secure mode - set all interrupts to group 1 and enable.
84+
mrc p15, 0, r0, c0, c0, 5
85+
ubfx r0, r0, #0, #2
86+
cmp r0, #0 @ primary core
87+
beq 2f
88+
ldr r2, GIC_DISTB
89+
add r2, r2, #GICD_CTRLR
90+
mov r0, #3 @ Enable group 0 and 1 IRQs from distributor
91+
str r0, [r2]
92+
2:
93+
ldr r0, GIC_CPUB
94+
add r0, r0, #GICC_CTRLR
95+
movw r1, #0x1e7
96+
str r1, [r0] @ Enable group 1 IRQs from CPU interface
97+
ldr r0, GIC_CPUB
98+
add r0, r0, #GICC_PMR @ priority mask
99+
movw r1, #0xff
100+
str r1, [r0]
101+
mov r0, #IT_NR
102+
mov r1, #~0 @ group 1 all the things
103+
ldr r2, GIC_DISTB
104+
add r2, r2, #(GICD_IGROUPR)
105+
3:
106+
str r1, [r2]
107+
add r2, r2, #4
108+
sub r0, r0, #1
109+
cmp r0, #0
110+
bne 3b
111+
str r1, [r2]
112+
mov pc, lr
113+
114+
.org 0xf0
115+
.word 0x5afe570b @ magic value to indicate firmware should overwrite atags and kernel
116+
.word 0 @ version
117+
atags: .word 0x0 @ device tree address
118+
kernel: .word 0x0 @ kernel start address
56119

57120
jmp_loader:
58121
@ Check which proc we are and run proc 0 only
122+
#ifdef GIC
123+
bl setup_gic
124+
#endif
59125

60-
mrc p15, 0, r0, c1, c0, 0 @ Read System Control Register
61-
orr r0, r0, #(1<<2) @ cache enable
62-
orr r0, r0, #(1<<12) @ icache enable
63-
mcr p15, 0, r0, c1, c0, 0 @ Write System Control Register
64126
.if !BCM2710
65127
mrc p15, 0, r0, c1, c0, 1 @ Read Auxiliary Control Register
66128
orr r0, r0, #(1<<6) @ SMP
67129
mcr p15, 0, r0, c1, c0, 1 @ Write Auxiliary Control Register
68130
.else
69131
mrrc p15, 1, r0, r1, c15 @ CPU Extended Control Register
70132
orr r0, r0, #(1<<6) @ SMP
133+
and r1, r1, #(~3) @ Set L2 load data prefetch to 0b00 = 16
71134
mcrr p15, 1, r0, r1, c15 @ CPU Extended Control Register
72135
.endif
73-
136+
mrc p15, 0, r0, c1, c0, 0 @ Read System Control Register
137+
/* Cortex A72 manual 4.3.67 says says SMP must be set before enabling the cache. */
138+
#ifndef BCM2711
139+
orr r0, r0, #(1<<2) @ cache enable
140+
#endif
141+
orr r0, r0, #(1<<12) @ icache enable
142+
mcr p15, 0, r0, c1, c0, 0 @ Write System Control Register
74143
mov r0, #1
75144
mcr p15, 0, r0, c14, c3, 1 @ CNTV_CTL (enable=1, imask=0)
76145

77146
@ set to non-sec
78147
ldr r1, value @ value = 0x63fff
79148
mcr p15, 0, r1, c1, c1, 2 @ NSACR = all copros to non-sec
80149
@ timer frequency
81-
ldr r1, osc @ osc = 19200000
150+
ldr r1, osc @ osc = 19.2 / 54MHz
82151
mcr p15, 0, r1, c14, c0, 0 @ write CNTFRQ
152+
#if defined(BCM2711) && (BCM2711 == 1)
153+
mov r1, #0x80000000 @ Set ARM_LOCAL_TIMER_PRE_ADD to 1
154+
ldr r2, prescaler
155+
str r1, [r2]
156+
#endif
83157

84158
adr r1, _start
85159
mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors
@@ -122,8 +196,3 @@ jmp_loader:
122196
wfi
123197
b 10b
124198

125-
.org 0xf0
126-
.word 0x5afe570b @ magic value to indicate firmware should overwrite atags and kernel
127-
.word 0 @ version
128-
atags: .word 0x0 @ device tree address
129-
kernel: .word 0x0 @ kernel start address

armstubs/armstub8.S

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929

3030
#define BIT(x) (1 << (x))
3131

32-
#define LOCAL_CONTROL 0x40000000
33-
#define LOCAL_PRESCALER 0x40000008
32+
#define LOCAL_CONTROL 0xff800000
33+
#define LOCAL_PRESCALER 0xff800008
34+
#define GIC_DISTB 0xff841000
35+
#define GIC_CPUB 0xff842000
3436

35-
#define OSC_FREQ 19200000
37+
#define OSC_FREQ 54000000
3638

3739
#define SCR_RW BIT(10)
3840
#define SCR_HCE BIT(8)
@@ -54,6 +56,15 @@
5456
#define SPSR_EL3_VAL \
5557
(SPSR_EL3_D | SPSR_EL3_A | SPSR_EL3_I | SPSR_EL3_F | SPSR_EL3_MODE_EL2H)
5658

59+
#define L2CTLR_EL1 S3_1_C11_C0_2
60+
61+
62+
#define GICC_CTRLR 0x0
63+
#define GICC_PMR 0x4
64+
#define IT_NR 0x8 // Number of interrupt enable registers (256 total irqs)
65+
#define GICD_CTRLR 0x0
66+
#define GICD_IGROUPR 0x80
67+
5768
.globl _start
5869
_start:
5970
/*
@@ -67,6 +78,12 @@ _start:
6778
mov w1, 0x80000000
6879
str w1, [x0, #(LOCAL_PRESCALER - LOCAL_CONTROL)]
6980

81+
/* Set L2 read/write cache latency to 2 */
82+
mrs x0, L2CTLR_EL1
83+
mov x1, #0x22
84+
orr x0, x0, x1
85+
msr L2CTLR_EL1, x0
86+
7087
/* Set up CNTFRQ_EL0 */
7188
ldr x0, =OSC_FREQ
7289
msr CNTFRQ_EL0, x0
@@ -87,6 +104,9 @@ _start:
87104
mov x0, #CPUECTLR_EL1_SMPEN
88105
msr CPUECTLR_EL1, x0
89106

107+
#ifdef GIC
108+
bl setup_gic
109+
#endif
90110
/*
91111
* Set up SCTLR_EL2
92112
* All set bits below are res1. LE, no WXN/I/SA/C/A/M
@@ -162,5 +182,33 @@ kernel_entry32:
162182
.word 0x0
163183

164184
.org 0x100
185+
186+
#ifdef GIC
187+
188+
setup_gic: // Called from secure mode - set all interrupts to group 1 and enable.
189+
mrs x0, MPIDR_EL1
190+
ldr x2, =GIC_DISTB
191+
tst x0, #0x3
192+
b.eq 2f // primary core
193+
194+
mov w0, #3 // Enable group 0 and 1 IRQs from distributor
195+
str w0, [x2, #GICD_CTRLR]
196+
2:
197+
add x1, x2, #(GIC_CPUB - GIC_DISTB)
198+
mov w0, #0x1e7
199+
str w0, [x1, #GICC_CTRLR] // Enable group 1 IRQs from CPU interface
200+
mov w0, #0xff
201+
str w0, [x1, #GICC_PMR] // priority mask
202+
add x2, x2, #GICD_IGROUPR
203+
mov x0, #(IT_NR * 4)
204+
mov w1, #~0 // group 1 all the things
205+
3:
206+
subs x0, x0, #4
207+
str w1, [x2, x0]
208+
b.ne 3b
209+
ret
210+
211+
#endif
212+
165213
.globl dtb_space
166214
dtb_space:

0 commit comments

Comments
 (0)