• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0 */
2
3/* 1. Find the index of the entry we're executing in */
4	bl	invstr				/* Find our address */
5invstr:	mflr	r6				/* Make it accessible */
6	mfmsr	r7
7	rlwinm	r4,r7,27,31,31			/* extract MSR[IS] */
8	mfspr	r7, SPRN_PID0
9	slwi	r7,r7,16
10	or	r7,r7,r4
11	mtspr	SPRN_MAS6,r7
12	tlbsx	0,r6				/* search MSR[IS], SPID=PID0 */
13	mfspr	r7,SPRN_MAS1
14	andis.	r7,r7,MAS1_VALID@h
15	bne	match_TLB
16
17	mfspr	r7,SPRN_MMUCFG
18	rlwinm	r7,r7,21,28,31			/* extract MMUCFG[NPIDS] */
19	cmpwi	r7,3
20	bne	match_TLB			/* skip if NPIDS != 3 */
21
22	mfspr	r7,SPRN_PID1
23	slwi	r7,r7,16
24	or	r7,r7,r4
25	mtspr	SPRN_MAS6,r7
26	tlbsx	0,r6				/* search MSR[IS], SPID=PID1 */
27	mfspr	r7,SPRN_MAS1
28	andis.	r7,r7,MAS1_VALID@h
29	bne	match_TLB
30	mfspr	r7, SPRN_PID2
31	slwi	r7,r7,16
32	or	r7,r7,r4
33	mtspr	SPRN_MAS6,r7
34	tlbsx	0,r6				/* Fall through, we had to match */
35
36match_TLB:
37	mfspr	r7,SPRN_MAS0
38	rlwinm	r3,r7,16,20,31			/* Extract MAS0(Entry) */
39
40	mfspr	r7,SPRN_MAS1			/* Insure IPROT set */
41	oris	r7,r7,MAS1_IPROT@h
42	mtspr	SPRN_MAS1,r7
43	tlbwe
44
45/* 2. Invalidate all entries except the entry we're executing in */
46	mfspr	r9,SPRN_TLB1CFG
47	andi.	r9,r9,0xfff
48	li	r6,0				/* Set Entry counter to 0 */
491:	lis	r7,0x1000			/* Set MAS0(TLBSEL) = 1 */
50	rlwimi	r7,r6,16,4,15			/* Setup MAS0 = TLBSEL | ESEL(r6) */
51	mtspr	SPRN_MAS0,r7
52	tlbre
53	mfspr	r7,SPRN_MAS1
54	rlwinm	r7,r7,0,2,31			/* Clear MAS1 Valid and IPROT */
55	cmpw	r3,r6
56	beq	skpinv				/* Dont update the current execution TLB */
57	mtspr	SPRN_MAS1,r7
58	tlbwe
59	isync
60skpinv:	addi	r6,r6,1				/* Increment */
61	cmpw	r6,r9				/* Are we done? */
62	bne	1b				/* If not, repeat */
63
64	/* Invalidate TLB0 */
65	li	r6,0x04
66	tlbivax 0,r6
67	TLBSYNC
68	/* Invalidate TLB1 */
69	li	r6,0x0c
70	tlbivax 0,r6
71	TLBSYNC
72
73/* 3. Setup a temp mapping and jump to it */
74	andi.	r5, r3, 0x1	/* Find an entry not used and is non-zero */
75	addi	r5, r5, 0x1
76	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
77	rlwimi	r7,r3,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
78	mtspr	SPRN_MAS0,r7
79	tlbre
80
81	/* grab and fixup the RPN */
82	mfspr	r6,SPRN_MAS1	/* extract MAS1[SIZE] */
83	rlwinm	r6,r6,25,27,31
84	li	r8,-1
85	addi	r6,r6,10
86	slw	r6,r8,r6	/* convert to mask */
87
88	bl	1f		/* Find our address */
891:	mflr	r7
90
91	mfspr	r8,SPRN_MAS3
92#ifdef CONFIG_PHYS_64BIT
93	mfspr	r23,SPRN_MAS7
94#endif
95	and	r8,r6,r8
96	subfic	r9,r6,-4096
97	and	r9,r9,r7
98
99	or	r25,r8,r9
100	ori	r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)
101
102	/* Just modify the entry ID and EPN for the temp mapping */
103	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
104	rlwimi	r7,r5,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
105	mtspr	SPRN_MAS0,r7
106	xori	r6,r4,1		/* Setup TMP mapping in the other Address space */
107	slwi	r6,r6,12
108	oris	r6,r6,(MAS1_VALID|MAS1_IPROT)@h
109	ori	r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
110	mtspr	SPRN_MAS1,r6
111	mfspr	r6,SPRN_MAS2
112	li	r7,0		/* temp EPN = 0 */
113	rlwimi	r7,r6,0,20,31
114	mtspr	SPRN_MAS2,r7
115	mtspr	SPRN_MAS3,r8
116	tlbwe
117
118	xori	r6,r4,1
119	slwi	r6,r6,5		/* setup new context with other address space */
120	bl	1f		/* Find our address */
1211:	mflr	r9
122	rlwimi	r7,r9,0,20,31
123	addi	r7,r7,(2f - 1b)
124	mtspr	SPRN_SRR0,r7
125	mtspr	SPRN_SRR1,r6
126	rfi
1272:
128/* 4. Clear out PIDs & Search info */
129	li	r6,0
130	mtspr   SPRN_MAS6,r6
131	mtspr	SPRN_PID0,r6
132
133	mfspr	r7,SPRN_MMUCFG
134	rlwinm	r7,r7,21,28,31			/* extract MMUCFG[NPIDS] */
135	cmpwi	r7,3
136	bne	2f				/* skip if NPIDS != 3 */
137
138	mtspr	SPRN_PID1,r6
139	mtspr	SPRN_PID2,r6
140
141/* 5. Invalidate mapping we started in */
1422:
143	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
144	rlwimi	r7,r3,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
145	mtspr	SPRN_MAS0,r7
146	tlbre
147	mfspr	r6,SPRN_MAS1
148	rlwinm	r6,r6,0,2,0	/* clear IPROT */
149	mtspr	SPRN_MAS1,r6
150	tlbwe
151	/* Invalidate TLB1 */
152	li	r9,0x0c
153	tlbivax 0,r9
154	TLBSYNC
155
156/*
157 * The mapping only needs to be cache-coherent on SMP, except on
158 * Freescale e500mc derivatives where it's also needed for coherent DMA.
159 */
160#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
161#define M_IF_NEEDED	MAS2_M
162#else
163#define M_IF_NEEDED	0
164#endif
165
166#if defined(ENTRY_MAPPING_BOOT_SETUP)
167
168/* 6. Setup KERNELBASE mapping in TLB1[0] */
169	lis	r6,0x1000		/* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
170	mtspr	SPRN_MAS0,r6
171	lis	r6,(MAS1_VALID|MAS1_IPROT)@h
172	ori	r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
173	mtspr	SPRN_MAS1,r6
174	lis	r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@h
175	ori	r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@l
176	mtspr	SPRN_MAS2,r6
177	mtspr	SPRN_MAS3,r8
178	tlbwe
179
180/* 7. Jump to KERNELBASE mapping */
181	lis	r6,(KERNELBASE & ~0xfff)@h
182	ori	r6,r6,(KERNELBASE & ~0xfff)@l
183	rlwinm	r7,r25,0,0x03ffffff
184	add	r6,r7,r6
185
186#elif defined(ENTRY_MAPPING_KEXEC_SETUP)
187/*
188 * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp
189 * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This
190 * will cover the first 2GiB of memory.
191 */
192
193	lis r10, (MAS1_VALID|MAS1_IPROT)@h
194	ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l
195	li  r11, 0
196	li  r0, 8
197	mtctr   r0
198
199next_tlb_setup:
200	addi	r0, r11, 3
201	rlwinm  r0, r0, 16, 4, 15  // Compute esel
202	rlwinm  r9, r11, 28, 0, 3   // Compute [ER]PN
203	oris    r0, r0, (MAS0_TLBSEL(1))@h
204	mtspr   SPRN_MAS0,r0
205	mtspr   SPRN_MAS1,r10
206	mtspr   SPRN_MAS2,r9
207	ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR)
208	mtspr   SPRN_MAS3,r9
209	tlbwe
210	addi    r11, r11, 1
211	bdnz+   next_tlb_setup
212
213/* 7. Jump to our 1:1 mapping */
214	mr	r6, r25
215#else
216	#error You need to specify the mapping or not use this at all.
217#endif
218
219	lis	r7,MSR_KERNEL@h
220	ori	r7,r7,MSR_KERNEL@l
221	bl	1f			/* Find our address */
2221:	mflr	r9
223	rlwimi	r6,r9,0,20,31
224	addi	r6,r6,(2f - 1b)
225	mtspr	SPRN_SRR0,r6
226	mtspr	SPRN_SRR1,r7
227	rfi				/* start execution out of TLB1[0] entry */
228
229/* 8. Clear out the temp mapping */
2302:	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
231	rlwimi	r7,r5,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
232	mtspr	SPRN_MAS0,r7
233	tlbre
234	mfspr	r8,SPRN_MAS1
235	rlwinm	r8,r8,0,2,0	/* clear IPROT */
236	mtspr	SPRN_MAS1,r8
237	tlbwe
238	/* Invalidate TLB1 */
239	li	r9,0x0c
240	tlbivax 0,r9
241	TLBSYNC
242