2727#define S2_TABLE_DESC 0x3
2828#define S2_BLOCK_NORMAL_RW 0x7fd
2929#define S2_BLOCK_DEVICE_RW 0x4c1
30+ #define S2_PAGE_DEVICE_RO 0x443
3031#define S2_PAGE_DEVICE_RW 0x4c3
3132
3233
@@ -58,6 +59,7 @@ linux_cpu3_trampoline:
5859 msr cntvoff_el2 , xzr
5960
6061 bl linux_stage2_setup
62+ bl linux_gic_prepare
6163
6264 movz x5 , #(HCR_EL2_RW >> 16 ) , lsl # 16
6365 orr x5 , x5 , #HCR_EL2_SWIO
@@ -100,30 +102,34 @@ linux_stage2_setup:
100102 ldr x8 , =linux_stage2_l2_high
101103 ldr x9 , =linux_stage2_l3_gic
102104
103- orr x10 , x7 , #S2_TABLE_DESC
104- str x10 , [ x6 , # 0 ]
105- orr x10 , x8 , #S2_TABLE_DESC
106- str x10 , [ x6 , # 8 ]
105+ / * linux_stage2_l1 [ 0 ] = linux_stage2_l2_low | S2_TABLE_DESC * /
106+ / * linux_stage2_l1 [ 1 ] = linux_stage2_l2_high | S2_TABLE_DESC * /
107+ orr x10 , x7 , #S2_TABLE_DESC / * x10 = x7 | S2_TABLE_DESC * /
108+ str x10 , [ x6 , # 0 ] / * * (uint64_t * )(x6 + 0 ) = x10 * /
109+ orr x10 , x8 , #S2_TABLE_DESC / * x10 = x8 | S2_TABLE_DESC * /
110+ str x10 , [ x6 , # 8 ] / * * (uint64_t * )(x6 + 8 ) = x10 * /
107111
112+ / * linux_stage2_l2_low [ 64 ] = linux_stage2_l3_gic | S2_TABLE_DESC * /
113+ / * 0x08000000 / 0x200000 = 64 * /
108114 orr x10 , x9 , #S2_TABLE_DESC
109115 str x10 , [ x7 , #( 64 * 8 ) ]
110116
111- ldr x10 , =VIRTIO_MMIO_BASE
112- lsr x11 , x10 , # 21
113- and x11 , x11 , # 0x1ff
117+ ldr x10 , =VIRTIO_MMIO_BASE / * x10 = 0x0a000000 * /
118+ lsr x11 , x10 , # 21 / * x11 = 0x0a000000 >> 21 = 00x50 相当于除以 2MB * /
119+ and x11 , x11 , # 0x1ff / * 是只取低 9 位,因为一张页表有 512 项 * /
114120 movz x12 , #S2_BLOCK_DEVICE_RW
115- orr x13 , x10 , x12
116- str x13 , [ x7 , x11 , lsl # 3 ]
121+ orr x13 , x10 , x12 / * x13 = 0x0a000000 | S2_BLOCK_DEVICE_RW * /
122+ str x13 , [ x7 , x11 , lsl # 3 ] / * linux_stage2_l2_low [ 0x50 ] = 0x0a000000 | S2_BLOCK_DEVICE_RW ; */
117123
118- ldr x10 , =LINUX_RAM_BASE
119- mov x11 , #LINUX_RAM_2M_BLOCKS
124+ ldr x10 , =LINUX_RAM_BASE / * linux的可用内存起始地址 * /
125+ mov x11 , #LINUX_RAM_2M_BLOCKS / * 可用地址大小(单位2M) * /
120126 movz x12 , #S2_BLOCK_NORMAL_RW
121127
122128.linux_stage2_map_ram:
123- lsr x13 , x10 , # 21
124- and x13 , x13 , # 0x1ff
125- orr x14 , x10 , x12
126- str x14 , [ x8 , x13 , lsl # 3 ]
129+ lsr x13 , x10 , # 21 / * x13 = x10 >> 21 = LINUX_RAM_BASE / 2M * /
130+ and x13 , x13 , # 0x1ff / * 512 个表项 * /
131+ orr x14 , x10 , x12 / * x14 = LINUX_RAM_BASE | S2_BLOCK_NORMAL_RW * /
132+ str x14 , [ x8 , x13 , lsl # 3 ] / * linux_stage2_l2_high [ x13 ] = x14 * /
127133 add x10 , x10 , # 0x200000
128134 subs x11 , x11 , # 1
129135 b.ne .linux_stage2_map_ram
@@ -135,7 +141,7 @@ linux_stage2_setup:
135141 * /
136142 ldr x10 , =GICD_BASE
137143 mov x11 , # 16
138- movz x12 , #S2_PAGE_DEVICE_RW / * 如果设置为只读权限就会被stage - 2 拦截 * /
144+ movz x12 , #S2_PAGE_DEVICE_RO / * 如果设置为只读权限就会被stage - 2 拦截 * /
139145
140146.linux_stage2_map_gicd:
141147 lsr x13 , x10 , # 12
@@ -195,9 +201,38 @@ linux_stage2_setup:
195201 isb
196202 ret
197203
204+ linux_gic_prepare:
205+ ldr x10 , =GICD_BASE
206+
207+ / * Linux CPU3 timers: PPI 10 / 11 / 13 / 14 * /
208+ movz w11 , # 0x6c00 , lsl # 16
209+ str w11 , [ x10 , # 0x100 ]
210+
211+ / * Linux virtio interrupts: SPI 48 / 49 - > CPU3 * /
212+ movz w11 , # 0x0808
213+ str w11 , [ x10 , # 0x830 ]
214+
215+ / * SPI 48 / 49 edge - triggered * /
216+ mov w11 , # 0x0000000a
217+ str w11 , [ x10 , # 0xc0c ]
218+
219+ / * Enable SPI 48 / 49 * /
220+ movz w11 , # 0x3 , lsl # 16
221+ str w11 , [ x10 , # 0x104 ]
222+ ret
223+
198224 . global linux_cpu3_trampoline_end
199225linux_cpu3_trampoline_end:
200226
227+ / * L1
228+ ├─ L1 [ 0 ] - > L2_low
229+ │ ├─ 普通 2MB block 映射
230+ │ └─ L2_low [ 64 ] - > L3_gic
231+ └─ L1 [ 1 ] - > L2_high
232+ └─ 普通 2MB block 映射
233+ * /
234+
235+ / * Stage - 2 页表页 * /
201236 . section ".bss.noclean.linux_hyp" , "aw"
202237 . align 12
203238linux_stage2_l1:
0 commit comments