2727
2828#define TORESET(x) (x - _secondary_start_page + BOOT_ROM_ADDR)
2929
30+ /* e6500 has 64-bit GPRs. When loading 32-bit addresses with bit 31 set
31+ * (addresses >= 0x80000000), the lis instruction sign-extends, putting
32+ * 0xFFFFFFFF in the upper 32 bits. This causes memory access failures.
33+ * Use LOAD_ADDR32 macro to properly load 32-bit addresses on e6500. */
34+ #ifdef CORE_E6500
35+ #define LOAD_ADDR32(reg, addr) \
36+ li reg, 0 ; \
37+ oris reg, reg, (addr)@h; \
38+ ori reg, reg, (addr)@l
39+ #else
40+ #define LOAD_ADDR32(reg, addr) \
41+ lis reg, (addr)@h; \
42+ ori reg, reg, (addr)@l
43+ #endif
44+
3045/* Additional cores (mp) assembly code for core minimum startup and spin table.
3146 * All code must fit in 4KB, which gets virtually mapped via the TLB1 (MMU) and
3247 * loaded by core 0. Spin table entry TLB1(0) mapped for work is 64MB.
3348 */
3449 .section .bootmp, "ax"
3550 .globl _secondary_start_page
3651_secondary_start_page:
37- /* Time base, MAS7 and machine check pin enable */
38- lis r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7)@h
39- ori r0, r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7)@l
52+ /* Time base, MAS7 and machine check pin enable.
53+ * HID0_EMCP=0x80000000 has bit 31 set; use LOAD_ADDR32 for e6500. */
54+ LOAD_ADDR32( r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7))
4055 mtspr SPRN_HID0, r0
4156
4257#ifdef CORE_E500
@@ -98,9 +113,10 @@ branch_prediction:
98113 andi. r1, r3, L1CSR_CE@l
99114 beq 2b
100115
101- /* Get our PIR to figure out our table entry */
102- lis r3, TORESET(_spin_table_addr)@h
103- ori r3, r3, TORESET(_spin_table_addr)@l
116+ /* Get our PIR to figure out our table entry.
117+ * TORESET(...) resolves to address near BOOT_ROM_ADDR (0xFFFFF000),
118+ * bit 31 set; use LOAD_ADDR32 for e6500. */
119+ LOAD_ADDR32(r3, TORESET(_spin_table_addr))
104120 lwz r3, 0 (r3)
105121
106122 /* Use PIR to determine cluster/core for spin table base at r10 */
@@ -160,8 +176,9 @@ l2_poll_invclear:
160176 addi r3, r8, 1
161177 mtspr L2CSR1, r3
162178
163- /* enable L2 with no parity */
164- lis r3, (L2CSR0_L2E)@h
179+ /* enable L2 with no parity.
180+ * L2CSR0_L2E=0x80000000 has bit 31 set; use LOAD_ADDR32 for e6500. */
181+ LOAD_ADDR32(r3, L2CSR0_L2E)
165182 mtspr L2CSR0, r3
166183 isync
1671842:
@@ -171,33 +188,37 @@ l2_poll_invclear:
171188#endif
172189#endif /* CORE_E5500 || CORE_E6500 */
1731903:
174- /* setup mapping for the spin table, WIMGE=0b00100 */
175- lis r13, TORESET(_spin_table_addr)@h
176- ori r13, r13, TORESET(_spin_table_addr)@l
191+ /* setup mapping for the spin table, WIMGE=0b00100.
192+ * TORESET(...) has bit 31 set; use LOAD_ADDR32 for e6500. */
193+ LOAD_ADDR32( r13, TORESET(_spin_table_addr))
177194 lwz r13, 0 (r13)
178195 /* mask by 4K */
179196 rlwinm r13, r13, 0 , 0 , 19
180197
181198 lis r11, (MAS0_TLBSEL(1 ) | MAS0_ESEL(1 ))@h
182199 mtspr MAS0, r11
183- lis r11, (MAS1_VALID | MAS1_IPROT)@h
184- ori r11, r11, (MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
200+ /* MAS1_VALID=0x80000000 has bit 31 set; use LOAD_ADDR32 for e6500. */
201+ LOAD_ADDR32(r11, (MAS1_VALID | MAS1_IPROT | MAS1_TS |
202+ MAS1_TSIZE(BOOKE_PAGESZ_4K)))
185203 mtspr MAS1, r11
204+ /* Build MAS2 = r13 (spin table base, 4K aligned) | MAS2_M | MAS2_G.
205+ * Note: both oris and ori must use r11 as source for the second op
206+ * (the original code erroneously used r13 on the second op, which
207+ * overwrote the upper 16 bits from the first oris). */
186208 oris r11, r13, (MAS2_M | MAS2_G)@h
187- ori r11, r13 , (MAS2_M | MAS2_G)@l
209+ ori r11, r11 , (MAS2_M | MAS2_G)@l
188210 mtspr MAS2, r11
189211 oris r11, r13, (MAS3_SX | MAS3_SW | MAS3_SR)@h
190- ori r11, r13 , (MAS3_SX | MAS3_SW | MAS3_SR)@l
212+ ori r11, r11 , (MAS3_SX | MAS3_SW | MAS3_SR)@l
191213 mtspr MAS3, r11
192214 li r11, 0
193215 mtspr MAS7, r11
194216 tlbwe
195217
196218 /* _bootpg_addr has the address of _second_half_boot_page
197- * jump there in AS=1 space with cache enabled
198- */
199- lis r13, TORESET(_bootpg_addr)@h
200- ori r13, r13, TORESET(_bootpg_addr)@l
219+ * jump there in AS=1 space with cache enabled.
220+ * TORESET(...) has bit 31 set; use LOAD_ADDR32 for e6500. */
221+ LOAD_ADDR32(r13, TORESET(_bootpg_addr))
201222 lwz r11, 0 (r13)
202223 mtspr SRR0, r11
203224 mfmsr r13
@@ -295,8 +316,8 @@ _second_half_boot_page:
295316 /* Add tlb 1 entry 0 64MB for new entry */
296317 lis r10, (MAS0_TLBSEL(1 ) | MAS0_ESEL(0 ))@h
297318 mtspr MAS0, r10
298- lis r10, (MAS1_VALID | MAS1_IPROT)@h
299- ori r10, r10, ( MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
319+ /* MAS1_VALID=0x80000000 has bit 31 set; use LOAD_ADDR32 for e6500. */
320+ LOAD_ADDR32(r10, (MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(BOOKE_PAGESZ_64M)))
300321 mtspr MAS1, r10
301322 mtspr MAS2, r12 /* WIMGE = 0 */
302323 ori r12, r12, (MAS3_SX | MAS3_SW | MAS3_SR)
0 commit comments