Linux Audio

Check our new training course

Loading...
v6.2
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * ultra.S: Don't expand these all over the place...
   4 *
   5 * Copyright (C) 1997, 2000, 2008 David S. Miller (davem@davemloft.net)
   6 */
   7
   8#include <linux/pgtable.h>
   9#include <asm/asi.h>
  10#include <asm/page.h>
  11#include <asm/spitfire.h>
  12#include <asm/mmu_context.h>
  13#include <asm/mmu.h>
  14#include <asm/pil.h>
  15#include <asm/head.h>
  16#include <asm/thread_info.h>
  17#include <asm/cacheflush.h>
  18#include <asm/hypervisor.h>
  19#include <asm/cpudata.h>
  20
  21	/* Basically, most of the Spitfire vs. Cheetah madness
  22	 * has to do with the fact that Cheetah does not support
  23	 * IMMU flushes out of the secondary context.  Someone needs
  24	 * to throw a south lake birthday party for the folks
  25	 * in Microelectronics who refused to fix this shit.
  26	 */
  27
  28	/* This file is meant to be read efficiently by the CPU, not humans.
  29	 * Staraj sie tego nikomu nie pierdolnac...
  30	 */
  31	.text
  32	.align		32
  33	.globl		__flush_tlb_mm
  34__flush_tlb_mm:		/* 19 insns */
  35	/* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
  36	ldxa		[%o1] ASI_DMMU, %g2
  37	cmp		%g2, %o0
  38	bne,pn		%icc, __spitfire_flush_tlb_mm_slow
  39	 mov		0x50, %g3
  40	stxa		%g0, [%g3] ASI_DMMU_DEMAP
  41	stxa		%g0, [%g3] ASI_IMMU_DEMAP
  42	sethi		%hi(KERNBASE), %g3
  43	flush		%g3
  44	retl
  45	 nop
  46	nop
  47	nop
  48	nop
  49	nop
  50	nop
  51	nop
  52	nop
  53	nop
  54	nop
  55
  56	.align		32
  57	.globl		__flush_tlb_page
  58__flush_tlb_page:	/* 22 insns */
  59	/* %o0 = context, %o1 = vaddr */
  60	rdpr		%pstate, %g7
  61	andn		%g7, PSTATE_IE, %g2
  62	wrpr		%g2, %pstate
  63	mov		SECONDARY_CONTEXT, %o4
  64	ldxa		[%o4] ASI_DMMU, %g2
  65	stxa		%o0, [%o4] ASI_DMMU
  66	andcc		%o1, 1, %g0
  67	andn		%o1, 1, %o3
  68	be,pn		%icc, 1f
  69	 or		%o3, 0x10, %o3
  70	stxa		%g0, [%o3] ASI_IMMU_DEMAP
  711:	stxa		%g0, [%o3] ASI_DMMU_DEMAP
  72	membar		#Sync
  73	stxa		%g2, [%o4] ASI_DMMU
  74	sethi		%hi(KERNBASE), %o4
  75	flush		%o4
  76	retl
  77	 wrpr		%g7, 0x0, %pstate
  78	nop
  79	nop
  80	nop
  81	nop
  82
  83	.align		32
  84	.globl		__flush_tlb_pending
  85__flush_tlb_pending:	/* 27 insns */
  86	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
  87	rdpr		%pstate, %g7
  88	sllx		%o1, 3, %o1
  89	andn		%g7, PSTATE_IE, %g2
  90	wrpr		%g2, %pstate
  91	mov		SECONDARY_CONTEXT, %o4
  92	ldxa		[%o4] ASI_DMMU, %g2
  93	stxa		%o0, [%o4] ASI_DMMU
  941:	sub		%o1, (1 << 3), %o1
  95	ldx		[%o2 + %o1], %o3
  96	andcc		%o3, 1, %g0
  97	andn		%o3, 1, %o3
  98	be,pn		%icc, 2f
  99	 or		%o3, 0x10, %o3
 100	stxa		%g0, [%o3] ASI_IMMU_DEMAP
 1012:	stxa		%g0, [%o3] ASI_DMMU_DEMAP
 102	membar		#Sync
 103	brnz,pt		%o1, 1b
 104	 nop
 105	stxa		%g2, [%o4] ASI_DMMU
 106	sethi		%hi(KERNBASE), %o4
 107	flush		%o4
 108	retl
 109	 wrpr		%g7, 0x0, %pstate
 110	nop
 111	nop
 112	nop
 113	nop
 114
 115	.align		32
 116	.globl		__flush_tlb_kernel_range
 117__flush_tlb_kernel_range:	/* 31 insns */
 118	/* %o0=start, %o1=end */
 119	cmp		%o0, %o1
 120	be,pn		%xcc, 2f
 121	 sub		%o1, %o0, %o3
 122	srlx		%o3, 18, %o4
 123	brnz,pn		%o4, __spitfire_flush_tlb_kernel_range_slow
 124	 sethi		%hi(PAGE_SIZE), %o4
 125	sub		%o3, %o4, %o3
 126	or		%o0, 0x20, %o0		! Nucleus
 1271:	stxa		%g0, [%o0 + %o3] ASI_DMMU_DEMAP
 128	stxa		%g0, [%o0 + %o3] ASI_IMMU_DEMAP
 129	membar		#Sync
 130	brnz,pt		%o3, 1b
 131	 sub		%o3, %o4, %o3
 1322:	sethi		%hi(KERNBASE), %o3
 133	flush		%o3
 134	retl
 135	 nop
 136	nop
 137	nop
 138	nop
 139	nop
 140	nop
 141	nop
 142	nop
 143	nop
 144	nop
 145	nop
 146	nop
 147	nop
 148	nop
 149	nop
 150
 151__spitfire_flush_tlb_kernel_range_slow:
 152	mov		63 * 8, %o4
 1531:	ldxa		[%o4] ASI_ITLB_DATA_ACCESS, %o3
 154	andcc		%o3, 0x40, %g0			/* _PAGE_L_4U */
 155	bne,pn		%xcc, 2f
 156	 mov		TLB_TAG_ACCESS, %o3
 157	stxa		%g0, [%o3] ASI_IMMU
 158	stxa		%g0, [%o4] ASI_ITLB_DATA_ACCESS
 159	membar		#Sync
 1602:	ldxa		[%o4] ASI_DTLB_DATA_ACCESS, %o3
 161	andcc		%o3, 0x40, %g0
 162	bne,pn		%xcc, 2f
 163	 mov		TLB_TAG_ACCESS, %o3
 164	stxa		%g0, [%o3] ASI_DMMU
 165	stxa		%g0, [%o4] ASI_DTLB_DATA_ACCESS
 166	membar		#Sync
 1672:	sub		%o4, 8, %o4
 168	brgez,pt	%o4, 1b
 169	 nop
 170	retl
 171	 nop
 172
 173__spitfire_flush_tlb_mm_slow:
 174	rdpr		%pstate, %g1
 175	wrpr		%g1, PSTATE_IE, %pstate
 176	stxa		%o0, [%o1] ASI_DMMU
 177	stxa		%g0, [%g3] ASI_DMMU_DEMAP
 178	stxa		%g0, [%g3] ASI_IMMU_DEMAP
 179	flush		%g6
 180	stxa		%g2, [%o1] ASI_DMMU
 181	sethi		%hi(KERNBASE), %o1
 182	flush		%o1
 183	retl
 184	 wrpr		%g1, 0, %pstate
 185
 186/*
 187 * The following code flushes one page_size worth.
 188 */
 189	.section .kprobes.text, "ax"
 190	.align		32
 191	.globl		__flush_icache_page
 192__flush_icache_page:	/* %o0 = phys_page */
 193	srlx		%o0, PAGE_SHIFT, %o0
 194	sethi		%hi(PAGE_OFFSET), %g1
 195	sllx		%o0, PAGE_SHIFT, %o0
 196	sethi		%hi(PAGE_SIZE), %g2
 197	ldx		[%g1 + %lo(PAGE_OFFSET)], %g1
 198	add		%o0, %g1, %o0
 1991:	subcc		%g2, 32, %g2
 200	bne,pt		%icc, 1b
 201	 flush		%o0 + %g2
 202	retl
 203	 nop
 204
 205#ifdef DCACHE_ALIASING_POSSIBLE
 206
 207#if (PAGE_SHIFT != 13)
 208#error only page shift of 13 is supported by dcache flush
 209#endif
 210
 211#define DTAG_MASK 0x3
 212
 213	/* This routine is Spitfire specific so the hardcoded
 214	 * D-cache size and line-size are OK.
 215	 */
 216	.align		64
 217	.globl		__flush_dcache_page
 218__flush_dcache_page:	/* %o0=kaddr, %o1=flush_icache */
 219	sethi		%hi(PAGE_OFFSET), %g1
 220	ldx		[%g1 + %lo(PAGE_OFFSET)], %g1
 221	sub		%o0, %g1, %o0			! physical address
 222	srlx		%o0, 11, %o0			! make D-cache TAG
 223	sethi		%hi(1 << 14), %o2		! D-cache size
 224	sub		%o2, (1 << 5), %o2		! D-cache line size
 2251:	ldxa		[%o2] ASI_DCACHE_TAG, %o3	! load D-cache TAG
 226	andcc		%o3, DTAG_MASK, %g0		! Valid?
 227	be,pn		%xcc, 2f			! Nope, branch
 228	 andn		%o3, DTAG_MASK, %o3		! Clear valid bits
 229	cmp		%o3, %o0			! TAG match?
 230	bne,pt		%xcc, 2f			! Nope, branch
 231	 nop
 232	stxa		%g0, [%o2] ASI_DCACHE_TAG	! Invalidate TAG
 233	membar		#Sync
 2342:	brnz,pt		%o2, 1b
 235	 sub		%o2, (1 << 5), %o2		! D-cache line size
 236
 237	/* The I-cache does not snoop local stores so we
 238	 * better flush that too when necessary.
 239	 */
 240	brnz,pt		%o1, __flush_icache_page
 241	 sllx		%o0, 11, %o0
 242	retl
 243	 nop
 244
 245#endif /* DCACHE_ALIASING_POSSIBLE */
 246
 247	.previous
 248
 249	/* Cheetah specific versions, patched at boot time. */
 250__cheetah_flush_tlb_mm: /* 19 insns */
 251	rdpr		%pstate, %g7
 252	andn		%g7, PSTATE_IE, %g2
 253	wrpr		%g2, 0x0, %pstate
 254	wrpr		%g0, 1, %tl
 255	mov		PRIMARY_CONTEXT, %o2
 256	mov		0x40, %g3
 257	ldxa		[%o2] ASI_DMMU, %g2
 258	srlx		%g2, CTX_PGSZ1_NUC_SHIFT, %o1
 259	sllx		%o1, CTX_PGSZ1_NUC_SHIFT, %o1
 260	or		%o0, %o1, %o0	/* Preserve nucleus page size fields */
 261	stxa		%o0, [%o2] ASI_DMMU
 262	stxa		%g0, [%g3] ASI_DMMU_DEMAP
 263	stxa		%g0, [%g3] ASI_IMMU_DEMAP
 264	stxa		%g2, [%o2] ASI_DMMU
 265	sethi		%hi(KERNBASE), %o2
 266	flush		%o2
 267	wrpr		%g0, 0, %tl
 268	retl
 269	 wrpr		%g7, 0x0, %pstate
 270
 271__cheetah_flush_tlb_page:	/* 22 insns */
 272	/* %o0 = context, %o1 = vaddr */
 273	rdpr		%pstate, %g7
 274	andn		%g7, PSTATE_IE, %g2
 275	wrpr		%g2, 0x0, %pstate
 276	wrpr		%g0, 1, %tl
 277	mov		PRIMARY_CONTEXT, %o4
 278	ldxa		[%o4] ASI_DMMU, %g2
 279	srlx		%g2, CTX_PGSZ1_NUC_SHIFT, %o3
 280	sllx		%o3, CTX_PGSZ1_NUC_SHIFT, %o3
 281	or		%o0, %o3, %o0	/* Preserve nucleus page size fields */
 282	stxa		%o0, [%o4] ASI_DMMU
 283	andcc		%o1, 1, %g0
 284	be,pn		%icc, 1f
 285	 andn		%o1, 1, %o3
 286	stxa		%g0, [%o3] ASI_IMMU_DEMAP
 2871:	stxa		%g0, [%o3] ASI_DMMU_DEMAP	
 288	membar		#Sync
 289	stxa		%g2, [%o4] ASI_DMMU
 290	sethi		%hi(KERNBASE), %o4
 291	flush		%o4
 292	wrpr		%g0, 0, %tl
 293	retl
 294	 wrpr		%g7, 0x0, %pstate
 295
 296__cheetah_flush_tlb_pending:	/* 27 insns */
 297	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
 298	rdpr		%pstate, %g7
 299	sllx		%o1, 3, %o1
 300	andn		%g7, PSTATE_IE, %g2
 301	wrpr		%g2, 0x0, %pstate
 302	wrpr		%g0, 1, %tl
 303	mov		PRIMARY_CONTEXT, %o4
 304	ldxa		[%o4] ASI_DMMU, %g2
 305	srlx		%g2, CTX_PGSZ1_NUC_SHIFT, %o3
 306	sllx		%o3, CTX_PGSZ1_NUC_SHIFT, %o3
 307	or		%o0, %o3, %o0	/* Preserve nucleus page size fields */
 308	stxa		%o0, [%o4] ASI_DMMU
 3091:	sub		%o1, (1 << 3), %o1
 310	ldx		[%o2 + %o1], %o3
 311	andcc		%o3, 1, %g0
 312	be,pn		%icc, 2f
 313	 andn		%o3, 1, %o3
 314	stxa		%g0, [%o3] ASI_IMMU_DEMAP
 3152:	stxa		%g0, [%o3] ASI_DMMU_DEMAP	
 316	membar		#Sync
 317	brnz,pt		%o1, 1b
 318	 nop
 319	stxa		%g2, [%o4] ASI_DMMU
 320	sethi		%hi(KERNBASE), %o4
 321	flush		%o4
 322	wrpr		%g0, 0, %tl
 323	retl
 324	 wrpr		%g7, 0x0, %pstate
 325
 326__cheetah_flush_tlb_kernel_range:	/* 31 insns */
 327	/* %o0=start, %o1=end */
 328	cmp		%o0, %o1
 329	be,pn		%xcc, 2f
 330	 sub		%o1, %o0, %o3
 331	srlx		%o3, 18, %o4
 332	brnz,pn		%o4, 3f
 333	 sethi		%hi(PAGE_SIZE), %o4
 334	sub		%o3, %o4, %o3
 335	or		%o0, 0x20, %o0		! Nucleus
 3361:	stxa		%g0, [%o0 + %o3] ASI_DMMU_DEMAP
 337	stxa		%g0, [%o0 + %o3] ASI_IMMU_DEMAP
 338	membar		#Sync
 339	brnz,pt		%o3, 1b
 340	 sub		%o3, %o4, %o3
 3412:	sethi		%hi(KERNBASE), %o3
 342	flush		%o3
 343	retl
 344	 nop
 3453:	mov		0x80, %o4
 346	stxa		%g0, [%o4] ASI_DMMU_DEMAP
 347	membar		#Sync
 348	stxa		%g0, [%o4] ASI_IMMU_DEMAP
 349	membar		#Sync
 350	retl
 351	 nop
 352	nop
 353	nop
 354	nop
 355	nop
 356	nop
 357	nop
 358	nop
 359
 360#ifdef DCACHE_ALIASING_POSSIBLE
 361__cheetah_flush_dcache_page: /* 11 insns */
 362	sethi		%hi(PAGE_OFFSET), %g1
 363	ldx		[%g1 + %lo(PAGE_OFFSET)], %g1
 364	sub		%o0, %g1, %o0
 365	sethi		%hi(PAGE_SIZE), %o4
 3661:	subcc		%o4, (1 << 5), %o4
 367	stxa		%g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
 368	membar		#Sync
 369	bne,pt		%icc, 1b
 370	 nop
 371	retl		/* I-cache flush never needed on Cheetah, see callers. */
 372	 nop
 373#endif /* DCACHE_ALIASING_POSSIBLE */
 374
 375	/* Hypervisor specific versions, patched at boot time.  */
 376__hypervisor_tlb_tl0_error:
 377	save		%sp, -192, %sp
 378	mov		%i0, %o0
 379	call		hypervisor_tlbop_error
 380	 mov		%i1, %o1
 381	ret
 382	 restore
 383
 384__hypervisor_flush_tlb_mm: /* 19 insns */
 385	mov		%o0, %o2	/* ARG2: mmu context */
 386	mov		0, %o0		/* ARG0: CPU lists unimplemented */
 387	mov		0, %o1		/* ARG1: CPU lists unimplemented */
 388	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
 389	mov		HV_FAST_MMU_DEMAP_CTX, %o5
 390	ta		HV_FAST_TRAP
 391	brnz,pn		%o0, 1f
 392	 mov		HV_FAST_MMU_DEMAP_CTX, %o1
 393	retl
 394	 nop
 3951:	sethi		%hi(__hypervisor_tlb_tl0_error), %o5
 396	jmpl		%o5 + %lo(__hypervisor_tlb_tl0_error), %g0
 397	 nop
 398	nop
 399	nop
 400	nop
 401	nop
 402	nop
 403	nop
 404
 405__hypervisor_flush_tlb_page: /* 22 insns */
 406	/* %o0 = context, %o1 = vaddr */
 407	mov		%o0, %g2
 408	mov		%o1, %o0              /* ARG0: vaddr + IMMU-bit */
 409	mov		%g2, %o1	      /* ARG1: mmu context */
 410	mov		HV_MMU_ALL, %o2	      /* ARG2: flags */
 411	srlx		%o0, PAGE_SHIFT, %o0
 412	sllx		%o0, PAGE_SHIFT, %o0
 413	ta		HV_MMU_UNMAP_ADDR_TRAP
 414	brnz,pn		%o0, 1f
 415	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
 416	retl
 417	 nop
 4181:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
 419	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
 420	 nop
 421	nop
 422	nop
 423	nop
 424	nop
 425	nop
 426	nop
 427	nop
 428	nop
 429
 430__hypervisor_flush_tlb_pending: /* 27 insns */
 431	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
 432	sllx		%o1, 3, %g1
 433	mov		%o2, %g2
 434	mov		%o0, %g3
 4351:	sub		%g1, (1 << 3), %g1
 436	ldx		[%g2 + %g1], %o0      /* ARG0: vaddr + IMMU-bit */
 437	mov		%g3, %o1	      /* ARG1: mmu context */
 438	mov		HV_MMU_ALL, %o2	      /* ARG2: flags */
 439	srlx		%o0, PAGE_SHIFT, %o0
 440	sllx		%o0, PAGE_SHIFT, %o0
 441	ta		HV_MMU_UNMAP_ADDR_TRAP
 442	brnz,pn		%o0, 1f
 443	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
 444	brnz,pt		%g1, 1b
 445	 nop
 446	retl
 447	 nop
 4481:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
 449	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
 450	 nop
 451	nop
 452	nop
 453	nop
 454	nop
 455	nop
 456	nop
 457	nop
 458	nop
 459
 460__hypervisor_flush_tlb_kernel_range: /* 31 insns */
 461	/* %o0=start, %o1=end */
 462	cmp		%o0, %o1
 463	be,pn		%xcc, 2f
 464	 sub		%o1, %o0, %g2
 465	srlx		%g2, 18, %g3
 466	brnz,pn		%g3, 4f
 467	 mov		%o0, %g1
 468	sethi		%hi(PAGE_SIZE), %g3
 469	sub		%g2, %g3, %g2
 4701:	add		%g1, %g2, %o0	/* ARG0: virtual address */
 471	mov		0, %o1		/* ARG1: mmu context */
 472	mov		HV_MMU_ALL, %o2	/* ARG2: flags */
 473	ta		HV_MMU_UNMAP_ADDR_TRAP
 474	brnz,pn		%o0, 3f
 475	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
 476	brnz,pt		%g2, 1b
 477	 sub		%g2, %g3, %g2
 4782:	retl
 479	 nop
 4803:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
 481	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
 482	 nop
 4834:	mov		0, %o0		/* ARG0: CPU lists unimplemented */
 484	mov		0, %o1		/* ARG1: CPU lists unimplemented */
 485	mov		0, %o2		/* ARG2: mmu context == nucleus */
 486	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
 487	mov		HV_FAST_MMU_DEMAP_CTX, %o5
 488	ta		HV_FAST_TRAP
 489	brnz,pn		%o0, 3b
 490	 mov		HV_FAST_MMU_DEMAP_CTX, %o1
 491	retl
 492	 nop
 493
 494#ifdef DCACHE_ALIASING_POSSIBLE
 495	/* XXX Niagara and friends have an 8K cache, so no aliasing is
 496	 * XXX possible, but nothing explicit in the Hypervisor API
 497	 * XXX guarantees this.
 498	 */
 499__hypervisor_flush_dcache_page:	/* 2 insns */
 500	retl
 501	 nop
 502#endif
 503
 504tlb_patch_one:
 5051:	lduw		[%o1], %g1
 506	stw		%g1, [%o0]
 507	flush		%o0
 508	subcc		%o2, 1, %o2
 509	add		%o1, 4, %o1
 510	bne,pt		%icc, 1b
 511	 add		%o0, 4, %o0
 512	retl
 513	 nop
 514
 515#ifdef CONFIG_SMP
 516	/* These are all called by the slaves of a cross call, at
 517	 * trap level 1, with interrupts fully disabled.
 518	 *
 519	 * Register usage:
 520	 *   %g5	mm->context	(all tlb flushes)
 521	 *   %g1	address arg 1	(tlb page and range flushes)
 522	 *   %g7	address arg 2	(tlb range flush only)
 523	 *
 524	 *   %g6	scratch 1
 525	 *   %g2	scratch 2
 526	 *   %g3	scratch 3
 527	 *   %g4	scratch 4
 528	 */
 529	.align		32
 530	.globl		xcall_flush_tlb_mm
 531xcall_flush_tlb_mm:	/* 24 insns */
 532	mov		PRIMARY_CONTEXT, %g2
 533	ldxa		[%g2] ASI_DMMU, %g3
 534	srlx		%g3, CTX_PGSZ1_NUC_SHIFT, %g4
 535	sllx		%g4, CTX_PGSZ1_NUC_SHIFT, %g4
 536	or		%g5, %g4, %g5	/* Preserve nucleus page size fields */
 537	stxa		%g5, [%g2] ASI_DMMU
 538	mov		0x40, %g4
 539	stxa		%g0, [%g4] ASI_DMMU_DEMAP
 540	stxa		%g0, [%g4] ASI_IMMU_DEMAP
 541	stxa		%g3, [%g2] ASI_DMMU
 542	retry
 543	nop
 544	nop
 545	nop
 546	nop
 547	nop
 548	nop
 549	nop
 550	nop
 551	nop
 552	nop
 553	nop
 554	nop
 555	nop
 556
 557	.globl		xcall_flush_tlb_page
 558xcall_flush_tlb_page:	/* 20 insns */
 559	/* %g5=context, %g1=vaddr */
 560	mov		PRIMARY_CONTEXT, %g4
 561	ldxa		[%g4] ASI_DMMU, %g2
 562	srlx		%g2, CTX_PGSZ1_NUC_SHIFT, %g4
 563	sllx		%g4, CTX_PGSZ1_NUC_SHIFT, %g4
 564	or		%g5, %g4, %g5
 565	mov		PRIMARY_CONTEXT, %g4
 566	stxa		%g5, [%g4] ASI_DMMU
 567	andcc		%g1, 0x1, %g0
 568	be,pn		%icc, 2f
 569	 andn		%g1, 0x1, %g5
 570	stxa		%g0, [%g5] ASI_IMMU_DEMAP
 5712:	stxa		%g0, [%g5] ASI_DMMU_DEMAP
 572	membar		#Sync
 573	stxa		%g2, [%g4] ASI_DMMU
 574	retry
 575	nop
 576	nop
 577	nop
 578	nop
 579	nop
 580
 581	.globl		xcall_flush_tlb_kernel_range
 582xcall_flush_tlb_kernel_range:	/* 44 insns */
 583	sethi		%hi(PAGE_SIZE - 1), %g2
 584	or		%g2, %lo(PAGE_SIZE - 1), %g2
 585	andn		%g1, %g2, %g1
 586	andn		%g7, %g2, %g7
 587	sub		%g7, %g1, %g3
 588	srlx		%g3, 18, %g2
 589	brnz,pn		%g2, 2f
 590	 sethi		%hi(PAGE_SIZE), %g2
 591	sub		%g3, %g2, %g3
 592	or		%g1, 0x20, %g1		! Nucleus
 5931:	stxa		%g0, [%g1 + %g3] ASI_DMMU_DEMAP
 594	stxa		%g0, [%g1 + %g3] ASI_IMMU_DEMAP
 595	membar		#Sync
 596	brnz,pt		%g3, 1b
 597	 sub		%g3, %g2, %g3
 598	retry
 5992:	mov		63 * 8, %g1
 6001:	ldxa		[%g1] ASI_ITLB_DATA_ACCESS, %g2
 601	andcc		%g2, 0x40, %g0			/* _PAGE_L_4U */
 602	bne,pn		%xcc, 2f
 603	 mov		TLB_TAG_ACCESS, %g2
 604	stxa		%g0, [%g2] ASI_IMMU
 605	stxa		%g0, [%g1] ASI_ITLB_DATA_ACCESS
 606	membar		#Sync
 6072:	ldxa		[%g1] ASI_DTLB_DATA_ACCESS, %g2
 608	andcc		%g2, 0x40, %g0
 609	bne,pn		%xcc, 2f
 610	 mov		TLB_TAG_ACCESS, %g2
 611	stxa		%g0, [%g2] ASI_DMMU
 612	stxa		%g0, [%g1] ASI_DTLB_DATA_ACCESS
 613	membar		#Sync
 6142:	sub		%g1, 8, %g1
 615	brgez,pt	%g1, 1b
 616	 nop
 617	retry
 618	nop
 619	nop
 620	nop
 621	nop
 622	nop
 623	nop
 624	nop
 625	nop
 626	nop
 627
 628	/* This runs in a very controlled environment, so we do
 629	 * not need to worry about BH races etc.
 630	 */
 631	.globl		xcall_sync_tick
 632xcall_sync_tick:
 633
 634661:	rdpr		%pstate, %g2
 635	wrpr		%g2, PSTATE_IG | PSTATE_AG, %pstate
 636	.section	.sun4v_2insn_patch, "ax"
 637	.word		661b
 638	nop
 639	nop
 640	.previous
 641
 642	rdpr		%pil, %g2
 643	wrpr		%g0, PIL_NORMAL_MAX, %pil
 644	sethi		%hi(109f), %g7
 645	b,pt		%xcc, etrap_irq
 646109:	 or		%g7, %lo(109b), %g7
 647#ifdef CONFIG_TRACE_IRQFLAGS
 648	call		trace_hardirqs_off
 649	 nop
 650#endif
 651	call		smp_synchronize_tick_client
 652	 nop
 653	b		rtrap_xcall
 654	 ldx		[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
 655
 656	.globl		xcall_fetch_glob_regs
 657xcall_fetch_glob_regs:
 658	sethi		%hi(global_cpu_snapshot), %g1
 659	or		%g1, %lo(global_cpu_snapshot), %g1
 660	__GET_CPUID(%g2)
 661	sllx		%g2, 6, %g3
 662	add		%g1, %g3, %g1
 663	rdpr		%tstate, %g7
 664	stx		%g7, [%g1 + GR_SNAP_TSTATE]
 665	rdpr		%tpc, %g7
 666	stx		%g7, [%g1 + GR_SNAP_TPC]
 667	rdpr		%tnpc, %g7
 668	stx		%g7, [%g1 + GR_SNAP_TNPC]
 669	stx		%o7, [%g1 + GR_SNAP_O7]
 670	stx		%i7, [%g1 + GR_SNAP_I7]
 671	/* Don't try this at home kids... */
 672	rdpr		%cwp, %g3
 673	sub		%g3, 1, %g7
 674	wrpr		%g7, %cwp
 675	mov		%i7, %g7
 676	wrpr		%g3, %cwp
 677	stx		%g7, [%g1 + GR_SNAP_RPC]
 678	sethi		%hi(trap_block), %g7
 679	or		%g7, %lo(trap_block), %g7
 680	sllx		%g2, TRAP_BLOCK_SZ_SHIFT, %g2
 681	add		%g7, %g2, %g7
 682	ldx		[%g7 + TRAP_PER_CPU_THREAD], %g3
 683	stx		%g3, [%g1 + GR_SNAP_THREAD]
 684	retry
 685
 686	.globl		xcall_fetch_glob_pmu
 687xcall_fetch_glob_pmu:
 688	sethi		%hi(global_cpu_snapshot), %g1
 689	or		%g1, %lo(global_cpu_snapshot), %g1
 690	__GET_CPUID(%g2)
 691	sllx		%g2, 6, %g3
 692	add		%g1, %g3, %g1
 693	rd		%pic, %g7
 694	stx		%g7, [%g1 + (4 * 8)]
 695	rd		%pcr, %g7
 696	stx		%g7, [%g1 + (0 * 8)]
 697	retry
 698
 699	.globl		xcall_fetch_glob_pmu_n4
 700xcall_fetch_glob_pmu_n4:
 701	sethi		%hi(global_cpu_snapshot), %g1
 702	or		%g1, %lo(global_cpu_snapshot), %g1
 703	__GET_CPUID(%g2)
 704	sllx		%g2, 6, %g3
 705	add		%g1, %g3, %g1
 706
 707	ldxa		[%g0] ASI_PIC, %g7
 708	stx		%g7, [%g1 + (4 * 8)]
 709	mov		0x08, %g3
 710	ldxa		[%g3] ASI_PIC, %g7
 711	stx		%g7, [%g1 + (5 * 8)]
 712	mov		0x10, %g3
 713	ldxa		[%g3] ASI_PIC, %g7
 714	stx		%g7, [%g1 + (6 * 8)]
 715	mov		0x18, %g3
 716	ldxa		[%g3] ASI_PIC, %g7
 717	stx		%g7, [%g1 + (7 * 8)]
 718
 719	mov		%o0, %g2
 720	mov		%o1, %g3
 721	mov		%o5, %g7
 722
 723	mov		HV_FAST_VT_GET_PERFREG, %o5
 724	mov		3, %o0
 725	ta		HV_FAST_TRAP
 726	stx		%o1, [%g1 + (3 * 8)]
 727	mov		HV_FAST_VT_GET_PERFREG, %o5
 728	mov		2, %o0
 729	ta		HV_FAST_TRAP
 730	stx		%o1, [%g1 + (2 * 8)]
 731	mov		HV_FAST_VT_GET_PERFREG, %o5
 732	mov		1, %o0
 733	ta		HV_FAST_TRAP
 734	stx		%o1, [%g1 + (1 * 8)]
 735	mov		HV_FAST_VT_GET_PERFREG, %o5
 736	mov		0, %o0
 737	ta		HV_FAST_TRAP
 738	stx		%o1, [%g1 + (0 * 8)]
 739
 740	mov		%g2, %o0
 741	mov		%g3, %o1
 742	mov		%g7, %o5
 743
 744	retry
 745
 746__cheetah_xcall_flush_tlb_kernel_range:	/* 44 insns */
 747	sethi		%hi(PAGE_SIZE - 1), %g2
 748	or		%g2, %lo(PAGE_SIZE - 1), %g2
 749	andn		%g1, %g2, %g1
 750	andn		%g7, %g2, %g7
 751	sub		%g7, %g1, %g3
 752	srlx		%g3, 18, %g2
 753	brnz,pn		%g2, 2f
 754	 sethi		%hi(PAGE_SIZE), %g2
 755	sub		%g3, %g2, %g3
 756	or		%g1, 0x20, %g1		! Nucleus
 7571:	stxa		%g0, [%g1 + %g3] ASI_DMMU_DEMAP
 758	stxa		%g0, [%g1 + %g3] ASI_IMMU_DEMAP
 759	membar		#Sync
 760	brnz,pt		%g3, 1b
 761	 sub		%g3, %g2, %g3
 762	retry
 7632:	mov		0x80, %g2
 764	stxa		%g0, [%g2] ASI_DMMU_DEMAP
 765	membar		#Sync
 766	stxa		%g0, [%g2] ASI_IMMU_DEMAP
 767	membar		#Sync
 768	retry
 769	nop
 770	nop
 771	nop
 772	nop
 773	nop
 774	nop
 775	nop
 776	nop
 777	nop
 778	nop
 779	nop
 780	nop
 781	nop
 782	nop
 783	nop
 784	nop
 785	nop
 786	nop
 787	nop
 788	nop
 789	nop
 790	nop
 791
 792#ifdef DCACHE_ALIASING_POSSIBLE
 793	.align		32
 794	.globl		xcall_flush_dcache_page_cheetah
 795xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
 796	sethi		%hi(PAGE_SIZE), %g3
 7971:	subcc		%g3, (1 << 5), %g3
 798	stxa		%g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE
 799	membar		#Sync
 800	bne,pt		%icc, 1b
 801	 nop
 802	retry
 803	nop
 804#endif /* DCACHE_ALIASING_POSSIBLE */
 805
 806	.globl		xcall_flush_dcache_page_spitfire
 807xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
 808				     %g7 == kernel page virtual address
 809				     %g5 == (page->mapping != NULL)  */
 810#ifdef DCACHE_ALIASING_POSSIBLE
 811	srlx		%g1, (13 - 2), %g1	! Form tag comparitor
 812	sethi		%hi(L1DCACHE_SIZE), %g3	! D$ size == 16K
 813	sub		%g3, (1 << 5), %g3	! D$ linesize == 32
 8141:	ldxa		[%g3] ASI_DCACHE_TAG, %g2
 815	andcc		%g2, 0x3, %g0
 816	be,pn		%xcc, 2f
 817	 andn		%g2, 0x3, %g2
 818	cmp		%g2, %g1
 819
 820	bne,pt		%xcc, 2f
 821	 nop
 822	stxa		%g0, [%g3] ASI_DCACHE_TAG
 823	membar		#Sync
 8242:	cmp		%g3, 0
 825	bne,pt		%xcc, 1b
 826	 sub		%g3, (1 << 5), %g3
 827
 828	brz,pn		%g5, 2f
 829#endif /* DCACHE_ALIASING_POSSIBLE */
 830	 sethi		%hi(PAGE_SIZE), %g3
 831
 8321:	flush		%g7
 833	subcc		%g3, (1 << 5), %g3
 834	bne,pt		%icc, 1b
 835	 add		%g7, (1 << 5), %g7
 836
 8372:	retry
 838	nop
 839	nop
 840
 841	/* %g5:	error
 842	 * %g6:	tlb op
 843	 */
 844__hypervisor_tlb_xcall_error:
 845	mov	%g5, %g4
 846	mov	%g6, %g5
 847	ba,pt	%xcc, etrap
 848	 rd	%pc, %g7
 849	mov	%l4, %o0
 850	call	hypervisor_tlbop_error_xcall
 851	 mov	%l5, %o1
 852	ba,a,pt	%xcc, rtrap
 853
 854	.globl		__hypervisor_xcall_flush_tlb_mm
 855__hypervisor_xcall_flush_tlb_mm: /* 24 insns */
 856	/* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */
 857	mov		%o0, %g2
 858	mov		%o1, %g3
 859	mov		%o2, %g4
 860	mov		%o3, %g1
 861	mov		%o5, %g7
 862	clr		%o0		/* ARG0: CPU lists unimplemented */
 863	clr		%o1		/* ARG1: CPU lists unimplemented */
 864	mov		%g5, %o2	/* ARG2: mmu context */
 865	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
 866	mov		HV_FAST_MMU_DEMAP_CTX, %o5
 867	ta		HV_FAST_TRAP
 868	mov		HV_FAST_MMU_DEMAP_CTX, %g6
 869	brnz,pn		%o0, 1f
 870	 mov		%o0, %g5
 871	mov		%g2, %o0
 872	mov		%g3, %o1
 873	mov		%g4, %o2
 874	mov		%g1, %o3
 875	mov		%g7, %o5
 876	membar		#Sync
 877	retry
 8781:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
 879	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
 880	 nop
 881
 882	.globl		__hypervisor_xcall_flush_tlb_page
 883__hypervisor_xcall_flush_tlb_page: /* 20 insns */
 884	/* %g5=ctx, %g1=vaddr */
 885	mov		%o0, %g2
 886	mov		%o1, %g3
 887	mov		%o2, %g4
 888	mov		%g1, %o0	        /* ARG0: virtual address */
 889	mov		%g5, %o1		/* ARG1: mmu context */
 890	mov		HV_MMU_ALL, %o2		/* ARG2: flags */
 891	srlx		%o0, PAGE_SHIFT, %o0
 892	sllx		%o0, PAGE_SHIFT, %o0
 893	ta		HV_MMU_UNMAP_ADDR_TRAP
 894	mov		HV_MMU_UNMAP_ADDR_TRAP, %g6
 895	brnz,a,pn	%o0, 1f
 896	 mov		%o0, %g5
 897	mov		%g2, %o0
 898	mov		%g3, %o1
 899	mov		%g4, %o2
 900	membar		#Sync
 901	retry
 9021:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
 903	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
 904	 nop
 905
 906	.globl		__hypervisor_xcall_flush_tlb_kernel_range
 907__hypervisor_xcall_flush_tlb_kernel_range: /* 44 insns */
 908	/* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */
 909	sethi		%hi(PAGE_SIZE - 1), %g2
 910	or		%g2, %lo(PAGE_SIZE - 1), %g2
 911	andn		%g1, %g2, %g1
 912	andn		%g7, %g2, %g7
 913	sub		%g7, %g1, %g3
 914	srlx		%g3, 18, %g7
 915	add		%g2, 1, %g2
 916	sub		%g3, %g2, %g3
 917	mov		%o0, %g2
 918	mov		%o1, %g4
 919	brnz,pn		%g7, 2f
 920	 mov		%o2, %g7
 9211:	add		%g1, %g3, %o0	/* ARG0: virtual address */
 922	mov		0, %o1		/* ARG1: mmu context */
 923	mov		HV_MMU_ALL, %o2	/* ARG2: flags */
 924	ta		HV_MMU_UNMAP_ADDR_TRAP
 925	mov		HV_MMU_UNMAP_ADDR_TRAP, %g6
 926	brnz,pn		%o0, 1f
 927	 mov		%o0, %g5
 928	sethi		%hi(PAGE_SIZE), %o2
 929	brnz,pt		%g3, 1b
 930	 sub		%g3, %o2, %g3
 9315:	mov		%g2, %o0
 932	mov		%g4, %o1
 933	mov		%g7, %o2
 934	membar		#Sync
 935	retry
 9361:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
 937	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
 938	 nop
 9392:	mov		%o3, %g1
 940	mov		%o5, %g3
 941	mov		0, %o0		/* ARG0: CPU lists unimplemented */
 942	mov		0, %o1		/* ARG1: CPU lists unimplemented */
 943	mov		0, %o2		/* ARG2: mmu context == nucleus */
 944	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
 945	mov		HV_FAST_MMU_DEMAP_CTX, %o5
 946	ta		HV_FAST_TRAP
 947	mov		%g1, %o3
 948	brz,pt		%o0, 5b
 949	 mov		%g3, %o5
 950	mov		HV_FAST_MMU_DEMAP_CTX, %g6
 951	ba,pt		%xcc, 1b
 952	 clr		%g5
 953
 954	/* These just get rescheduled to PIL vectors. */
 955	.globl		xcall_call_function
 956xcall_call_function:
 957	wr		%g0, (1 << PIL_SMP_CALL_FUNC), %set_softint
 958	retry
 959
 960	.globl		xcall_call_function_single
 961xcall_call_function_single:
 962	wr		%g0, (1 << PIL_SMP_CALL_FUNC_SNGL), %set_softint
 963	retry
 964
 965	.globl		xcall_receive_signal
 966xcall_receive_signal:
 967	wr		%g0, (1 << PIL_SMP_RECEIVE_SIGNAL), %set_softint
 968	retry
 969
 970	.globl		xcall_capture
 971xcall_capture:
 972	wr		%g0, (1 << PIL_SMP_CAPTURE), %set_softint
 973	retry
 974
 975#ifdef CONFIG_KGDB
 976	.globl		xcall_kgdb_capture
 977xcall_kgdb_capture:
 978	wr		%g0, (1 << PIL_KGDB_CAPTURE), %set_softint
 979	retry
 980#endif
 981
 982#endif /* CONFIG_SMP */
 983
 984	.globl		cheetah_patch_cachetlbops
 985cheetah_patch_cachetlbops:
 986	save		%sp, -128, %sp
 987
 988	sethi		%hi(__flush_tlb_mm), %o0
 989	or		%o0, %lo(__flush_tlb_mm), %o0
 990	sethi		%hi(__cheetah_flush_tlb_mm), %o1
 991	or		%o1, %lo(__cheetah_flush_tlb_mm), %o1
 992	call		tlb_patch_one
 993	 mov		19, %o2
 994
 995	sethi		%hi(__flush_tlb_page), %o0
 996	or		%o0, %lo(__flush_tlb_page), %o0
 997	sethi		%hi(__cheetah_flush_tlb_page), %o1
 998	or		%o1, %lo(__cheetah_flush_tlb_page), %o1
 999	call		tlb_patch_one
1000	 mov		22, %o2
1001
1002	sethi		%hi(__flush_tlb_pending), %o0
1003	or		%o0, %lo(__flush_tlb_pending), %o0
1004	sethi		%hi(__cheetah_flush_tlb_pending), %o1
1005	or		%o1, %lo(__cheetah_flush_tlb_pending), %o1
1006	call		tlb_patch_one
1007	 mov		27, %o2
1008
1009	sethi		%hi(__flush_tlb_kernel_range), %o0
1010	or		%o0, %lo(__flush_tlb_kernel_range), %o0
1011	sethi		%hi(__cheetah_flush_tlb_kernel_range), %o1
1012	or		%o1, %lo(__cheetah_flush_tlb_kernel_range), %o1
1013	call		tlb_patch_one
1014	 mov		31, %o2
1015
1016#ifdef DCACHE_ALIASING_POSSIBLE
1017	sethi		%hi(__flush_dcache_page), %o0
1018	or		%o0, %lo(__flush_dcache_page), %o0
1019	sethi		%hi(__cheetah_flush_dcache_page), %o1
1020	or		%o1, %lo(__cheetah_flush_dcache_page), %o1
1021	call		tlb_patch_one
1022	 mov		11, %o2
1023#endif /* DCACHE_ALIASING_POSSIBLE */
1024
1025#ifdef CONFIG_SMP
1026	sethi		%hi(xcall_flush_tlb_kernel_range), %o0
1027	or		%o0, %lo(xcall_flush_tlb_kernel_range), %o0
1028	sethi		%hi(__cheetah_xcall_flush_tlb_kernel_range), %o1
1029	or		%o1, %lo(__cheetah_xcall_flush_tlb_kernel_range), %o1
1030	call		tlb_patch_one
1031	 mov		44, %o2
1032#endif /* CONFIG_SMP */
1033
1034	ret
1035	 restore
1036
1037	.globl		hypervisor_patch_cachetlbops
1038hypervisor_patch_cachetlbops:
1039	save		%sp, -128, %sp
1040
1041	sethi		%hi(__flush_tlb_mm), %o0
1042	or		%o0, %lo(__flush_tlb_mm), %o0
1043	sethi		%hi(__hypervisor_flush_tlb_mm), %o1
1044	or		%o1, %lo(__hypervisor_flush_tlb_mm), %o1
1045	call		tlb_patch_one
1046	 mov		19, %o2
1047
1048	sethi		%hi(__flush_tlb_page), %o0
1049	or		%o0, %lo(__flush_tlb_page), %o0
1050	sethi		%hi(__hypervisor_flush_tlb_page), %o1
1051	or		%o1, %lo(__hypervisor_flush_tlb_page), %o1
1052	call		tlb_patch_one
1053	 mov		22, %o2
1054
1055	sethi		%hi(__flush_tlb_pending), %o0
1056	or		%o0, %lo(__flush_tlb_pending), %o0
1057	sethi		%hi(__hypervisor_flush_tlb_pending), %o1
1058	or		%o1, %lo(__hypervisor_flush_tlb_pending), %o1
1059	call		tlb_patch_one
1060	 mov		27, %o2
1061
1062	sethi		%hi(__flush_tlb_kernel_range), %o0
1063	or		%o0, %lo(__flush_tlb_kernel_range), %o0
1064	sethi		%hi(__hypervisor_flush_tlb_kernel_range), %o1
1065	or		%o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1
1066	call		tlb_patch_one
1067	 mov		31, %o2
1068
1069#ifdef DCACHE_ALIASING_POSSIBLE
1070	sethi		%hi(__flush_dcache_page), %o0
1071	or		%o0, %lo(__flush_dcache_page), %o0
1072	sethi		%hi(__hypervisor_flush_dcache_page), %o1
1073	or		%o1, %lo(__hypervisor_flush_dcache_page), %o1
1074	call		tlb_patch_one
1075	 mov		2, %o2
1076#endif /* DCACHE_ALIASING_POSSIBLE */
1077
1078#ifdef CONFIG_SMP
1079	sethi		%hi(xcall_flush_tlb_mm), %o0
1080	or		%o0, %lo(xcall_flush_tlb_mm), %o0
1081	sethi		%hi(__hypervisor_xcall_flush_tlb_mm), %o1
1082	or		%o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1
1083	call		tlb_patch_one
1084	 mov		24, %o2
1085
1086	sethi		%hi(xcall_flush_tlb_page), %o0
1087	or		%o0, %lo(xcall_flush_tlb_page), %o0
1088	sethi		%hi(__hypervisor_xcall_flush_tlb_page), %o1
1089	or		%o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1
1090	call		tlb_patch_one
1091	 mov		20, %o2
1092
1093	sethi		%hi(xcall_flush_tlb_kernel_range), %o0
1094	or		%o0, %lo(xcall_flush_tlb_kernel_range), %o0
1095	sethi		%hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1
1096	or		%o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1
1097	call		tlb_patch_one
1098	 mov		44, %o2
1099#endif /* CONFIG_SMP */
1100
1101	ret
1102	 restore
v6.13.7
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * ultra.S: Don't expand these all over the place...
   4 *
   5 * Copyright (C) 1997, 2000, 2008 David S. Miller (davem@davemloft.net)
   6 */
   7
   8#include <linux/pgtable.h>
   9#include <asm/asi.h>
  10#include <asm/page.h>
  11#include <asm/spitfire.h>
  12#include <asm/mmu_context.h>
  13#include <asm/mmu.h>
  14#include <asm/pil.h>
  15#include <asm/head.h>
  16#include <asm/thread_info.h>
  17#include <asm/cacheflush.h>
  18#include <asm/hypervisor.h>
  19#include <asm/cpudata.h>
  20
  21	/* Basically, most of the Spitfire vs. Cheetah madness
  22	 * has to do with the fact that Cheetah does not support
  23	 * IMMU flushes out of the secondary context.  Someone needs
  24	 * to throw a south lake birthday party for the folks
  25	 * in Microelectronics who refused to fix this shit.
  26	 */
  27
  28	/* This file is meant to be read efficiently by the CPU, not humans.
  29	 * Staraj sie tego nikomu nie pierdolnac...
  30	 */
  31	.text
  32	.align		32
  33	.globl		__flush_tlb_mm
  34__flush_tlb_mm:		/* 19 insns */
  35	/* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
  36	ldxa		[%o1] ASI_DMMU, %g2
  37	cmp		%g2, %o0
  38	bne,pn		%icc, __spitfire_flush_tlb_mm_slow
  39	 mov		0x50, %g3
  40	stxa		%g0, [%g3] ASI_DMMU_DEMAP
  41	stxa		%g0, [%g3] ASI_IMMU_DEMAP
  42	sethi		%hi(KERNBASE), %g3
  43	flush		%g3
  44	retl
  45	 nop
  46	nop
  47	nop
  48	nop
  49	nop
  50	nop
  51	nop
  52	nop
  53	nop
  54	nop
  55
  56	.align		32
  57	.globl		__flush_tlb_page
  58__flush_tlb_page:	/* 22 insns */
  59	/* %o0 = context, %o1 = vaddr */
  60	rdpr		%pstate, %g7
  61	andn		%g7, PSTATE_IE, %g2
  62	wrpr		%g2, %pstate
  63	mov		SECONDARY_CONTEXT, %o4
  64	ldxa		[%o4] ASI_DMMU, %g2
  65	stxa		%o0, [%o4] ASI_DMMU
  66	andcc		%o1, 1, %g0
  67	andn		%o1, 1, %o3
  68	be,pn		%icc, 1f
  69	 or		%o3, 0x10, %o3
  70	stxa		%g0, [%o3] ASI_IMMU_DEMAP
  711:	stxa		%g0, [%o3] ASI_DMMU_DEMAP
  72	membar		#Sync
  73	stxa		%g2, [%o4] ASI_DMMU
  74	sethi		%hi(KERNBASE), %o4
  75	flush		%o4
  76	retl
  77	 wrpr		%g7, 0x0, %pstate
  78	nop
  79	nop
  80	nop
  81	nop
  82
  83	.align		32
  84	.globl		__flush_tlb_pending
  85__flush_tlb_pending:	/* 27 insns */
  86	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
  87	rdpr		%pstate, %g7
  88	sllx		%o1, 3, %o1
  89	andn		%g7, PSTATE_IE, %g2
  90	wrpr		%g2, %pstate
  91	mov		SECONDARY_CONTEXT, %o4
  92	ldxa		[%o4] ASI_DMMU, %g2
  93	stxa		%o0, [%o4] ASI_DMMU
  941:	sub		%o1, (1 << 3), %o1
  95	ldx		[%o2 + %o1], %o3
  96	andcc		%o3, 1, %g0
  97	andn		%o3, 1, %o3
  98	be,pn		%icc, 2f
  99	 or		%o3, 0x10, %o3
 100	stxa		%g0, [%o3] ASI_IMMU_DEMAP
 1012:	stxa		%g0, [%o3] ASI_DMMU_DEMAP
 102	membar		#Sync
 103	brnz,pt		%o1, 1b
 104	 nop
 105	stxa		%g2, [%o4] ASI_DMMU
 106	sethi		%hi(KERNBASE), %o4
 107	flush		%o4
 108	retl
 109	 wrpr		%g7, 0x0, %pstate
 110	nop
 111	nop
 112	nop
 113	nop
 114
 115	.align		32
 116	.globl		__flush_tlb_kernel_range
 117__flush_tlb_kernel_range:	/* 31 insns */
 118	/* %o0=start, %o1=end */
 119	cmp		%o0, %o1
 120	be,pn		%xcc, 2f
 121	 sub		%o1, %o0, %o3
 122	srlx		%o3, 18, %o4
 123	brnz,pn		%o4, __spitfire_flush_tlb_kernel_range_slow
 124	 sethi		%hi(PAGE_SIZE), %o4
 125	sub		%o3, %o4, %o3
 126	or		%o0, 0x20, %o0		! Nucleus
 1271:	stxa		%g0, [%o0 + %o3] ASI_DMMU_DEMAP
 128	stxa		%g0, [%o0 + %o3] ASI_IMMU_DEMAP
 129	membar		#Sync
 130	brnz,pt		%o3, 1b
 131	 sub		%o3, %o4, %o3
 1322:	sethi		%hi(KERNBASE), %o3
 133	flush		%o3
 134	retl
 135	 nop
 136	nop
 137	nop
 138	nop
 139	nop
 140	nop
 141	nop
 142	nop
 143	nop
 144	nop
 145	nop
 146	nop
 147	nop
 148	nop
 149	nop
 150
 151__spitfire_flush_tlb_kernel_range_slow:
 152	mov		63 * 8, %o4
 1531:	ldxa		[%o4] ASI_ITLB_DATA_ACCESS, %o3
 154	andcc		%o3, 0x40, %g0			/* _PAGE_L_4U */
 155	bne,pn		%xcc, 2f
 156	 mov		TLB_TAG_ACCESS, %o3
 157	stxa		%g0, [%o3] ASI_IMMU
 158	stxa		%g0, [%o4] ASI_ITLB_DATA_ACCESS
 159	membar		#Sync
 1602:	ldxa		[%o4] ASI_DTLB_DATA_ACCESS, %o3
 161	andcc		%o3, 0x40, %g0
 162	bne,pn		%xcc, 2f
 163	 mov		TLB_TAG_ACCESS, %o3
 164	stxa		%g0, [%o3] ASI_DMMU
 165	stxa		%g0, [%o4] ASI_DTLB_DATA_ACCESS
 166	membar		#Sync
 1672:	sub		%o4, 8, %o4
 168	brgez,pt	%o4, 1b
 169	 nop
 170	retl
 171	 nop
 172
 173__spitfire_flush_tlb_mm_slow:
 174	rdpr		%pstate, %g1
 175	wrpr		%g1, PSTATE_IE, %pstate
 176	stxa		%o0, [%o1] ASI_DMMU
 177	stxa		%g0, [%g3] ASI_DMMU_DEMAP
 178	stxa		%g0, [%g3] ASI_IMMU_DEMAP
 179	flush		%g6
 180	stxa		%g2, [%o1] ASI_DMMU
 181	sethi		%hi(KERNBASE), %o1
 182	flush		%o1
 183	retl
 184	 wrpr		%g1, 0, %pstate
 185
 186/*
 187 * The following code flushes one page_size worth.
 188 */
 189	.section .kprobes.text, "ax"
 190	.align		32
 191	.globl		__flush_icache_page
 192__flush_icache_page:	/* %o0 = phys_page */
 193	srlx		%o0, PAGE_SHIFT, %o0
 194	sethi		%hi(PAGE_OFFSET), %g1
 195	sllx		%o0, PAGE_SHIFT, %o0
 196	sethi		%hi(PAGE_SIZE), %g2
 197	ldx		[%g1 + %lo(PAGE_OFFSET)], %g1
 198	add		%o0, %g1, %o0
 1991:	subcc		%g2, 32, %g2
 200	bne,pt		%icc, 1b
 201	 flush		%o0 + %g2
 202	retl
 203	 nop
 204
 205#ifdef DCACHE_ALIASING_POSSIBLE
 206
 207#if (PAGE_SHIFT != 13)
 208#error only page shift of 13 is supported by dcache flush
 209#endif
 210
 211#define DTAG_MASK 0x3
 212
 213	/* This routine is Spitfire specific so the hardcoded
 214	 * D-cache size and line-size are OK.
 215	 */
 216	.align		64
 217	.globl		__flush_dcache_page
 218__flush_dcache_page:	/* %o0=kaddr, %o1=flush_icache */
 219	sethi		%hi(PAGE_OFFSET), %g1
 220	ldx		[%g1 + %lo(PAGE_OFFSET)], %g1
 221	sub		%o0, %g1, %o0			! physical address
 222	srlx		%o0, 11, %o0			! make D-cache TAG
 223	sethi		%hi(1 << 14), %o2		! D-cache size
 224	sub		%o2, (1 << 5), %o2		! D-cache line size
 2251:	ldxa		[%o2] ASI_DCACHE_TAG, %o3	! load D-cache TAG
 226	andcc		%o3, DTAG_MASK, %g0		! Valid?
 227	be,pn		%xcc, 2f			! Nope, branch
 228	 andn		%o3, DTAG_MASK, %o3		! Clear valid bits
 229	cmp		%o3, %o0			! TAG match?
 230	bne,pt		%xcc, 2f			! Nope, branch
 231	 nop
 232	stxa		%g0, [%o2] ASI_DCACHE_TAG	! Invalidate TAG
 233	membar		#Sync
 2342:	brnz,pt		%o2, 1b
 235	 sub		%o2, (1 << 5), %o2		! D-cache line size
 236
 237	/* The I-cache does not snoop local stores so we
 238	 * better flush that too when necessary.
 239	 */
 240	brnz,pt		%o1, __flush_icache_page
 241	 sllx		%o0, 11, %o0
 242	retl
 243	 nop
 244
 245#endif /* DCACHE_ALIASING_POSSIBLE */
 246
 247	.previous
 248
 249	/* Cheetah specific versions, patched at boot time. */
 250__cheetah_flush_tlb_mm: /* 19 insns */
 251	rdpr		%pstate, %g7
 252	andn		%g7, PSTATE_IE, %g2
 253	wrpr		%g2, 0x0, %pstate
 254	wrpr		%g0, 1, %tl
 255	mov		PRIMARY_CONTEXT, %o2
 256	mov		0x40, %g3
 257	ldxa		[%o2] ASI_DMMU, %g2
 258	srlx		%g2, CTX_PGSZ1_NUC_SHIFT, %o1
 259	sllx		%o1, CTX_PGSZ1_NUC_SHIFT, %o1
 260	or		%o0, %o1, %o0	/* Preserve nucleus page size fields */
 261	stxa		%o0, [%o2] ASI_DMMU
 262	stxa		%g0, [%g3] ASI_DMMU_DEMAP
 263	stxa		%g0, [%g3] ASI_IMMU_DEMAP
 264	stxa		%g2, [%o2] ASI_DMMU
 265	sethi		%hi(KERNBASE), %o2
 266	flush		%o2
 267	wrpr		%g0, 0, %tl
 268	retl
 269	 wrpr		%g7, 0x0, %pstate
 270
 271__cheetah_flush_tlb_page:	/* 22 insns */
 272	/* %o0 = context, %o1 = vaddr */
 273	rdpr		%pstate, %g7
 274	andn		%g7, PSTATE_IE, %g2
 275	wrpr		%g2, 0x0, %pstate
 276	wrpr		%g0, 1, %tl
 277	mov		PRIMARY_CONTEXT, %o4
 278	ldxa		[%o4] ASI_DMMU, %g2
 279	srlx		%g2, CTX_PGSZ1_NUC_SHIFT, %o3
 280	sllx		%o3, CTX_PGSZ1_NUC_SHIFT, %o3
 281	or		%o0, %o3, %o0	/* Preserve nucleus page size fields */
 282	stxa		%o0, [%o4] ASI_DMMU
 283	andcc		%o1, 1, %g0
 284	be,pn		%icc, 1f
 285	 andn		%o1, 1, %o3
 286	stxa		%g0, [%o3] ASI_IMMU_DEMAP
 2871:	stxa		%g0, [%o3] ASI_DMMU_DEMAP	
 288	membar		#Sync
 289	stxa		%g2, [%o4] ASI_DMMU
 290	sethi		%hi(KERNBASE), %o4
 291	flush		%o4
 292	wrpr		%g0, 0, %tl
 293	retl
 294	 wrpr		%g7, 0x0, %pstate
 295
 296__cheetah_flush_tlb_pending:	/* 27 insns */
 297	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
 298	rdpr		%pstate, %g7
 299	sllx		%o1, 3, %o1
 300	andn		%g7, PSTATE_IE, %g2
 301	wrpr		%g2, 0x0, %pstate
 302	wrpr		%g0, 1, %tl
 303	mov		PRIMARY_CONTEXT, %o4
 304	ldxa		[%o4] ASI_DMMU, %g2
 305	srlx		%g2, CTX_PGSZ1_NUC_SHIFT, %o3
 306	sllx		%o3, CTX_PGSZ1_NUC_SHIFT, %o3
 307	or		%o0, %o3, %o0	/* Preserve nucleus page size fields */
 308	stxa		%o0, [%o4] ASI_DMMU
 3091:	sub		%o1, (1 << 3), %o1
 310	ldx		[%o2 + %o1], %o3
 311	andcc		%o3, 1, %g0
 312	be,pn		%icc, 2f
 313	 andn		%o3, 1, %o3
 314	stxa		%g0, [%o3] ASI_IMMU_DEMAP
 3152:	stxa		%g0, [%o3] ASI_DMMU_DEMAP	
 316	membar		#Sync
 317	brnz,pt		%o1, 1b
 318	 nop
 319	stxa		%g2, [%o4] ASI_DMMU
 320	sethi		%hi(KERNBASE), %o4
 321	flush		%o4
 322	wrpr		%g0, 0, %tl
 323	retl
 324	 wrpr		%g7, 0x0, %pstate
 325
 326__cheetah_flush_tlb_kernel_range:	/* 31 insns */
 327	/* %o0=start, %o1=end */
 328	cmp		%o0, %o1
 329	be,pn		%xcc, 2f
 330	 sub		%o1, %o0, %o3
 331	srlx		%o3, 18, %o4
 332	brnz,pn		%o4, 3f
 333	 sethi		%hi(PAGE_SIZE), %o4
 334	sub		%o3, %o4, %o3
 335	or		%o0, 0x20, %o0		! Nucleus
 3361:	stxa		%g0, [%o0 + %o3] ASI_DMMU_DEMAP
 337	stxa		%g0, [%o0 + %o3] ASI_IMMU_DEMAP
 338	membar		#Sync
 339	brnz,pt		%o3, 1b
 340	 sub		%o3, %o4, %o3
 3412:	sethi		%hi(KERNBASE), %o3
 342	flush		%o3
 343	retl
 344	 nop
 3453:	mov		0x80, %o4
 346	stxa		%g0, [%o4] ASI_DMMU_DEMAP
 347	membar		#Sync
 348	stxa		%g0, [%o4] ASI_IMMU_DEMAP
 349	membar		#Sync
 350	retl
 351	 nop
 352	nop
 353	nop
 354	nop
 355	nop
 356	nop
 357	nop
 358	nop
 359
 360#ifdef DCACHE_ALIASING_POSSIBLE
 361__cheetah_flush_dcache_page: /* 11 insns */
 362	sethi		%hi(PAGE_OFFSET), %g1
 363	ldx		[%g1 + %lo(PAGE_OFFSET)], %g1
 364	sub		%o0, %g1, %o0
 365	sethi		%hi(PAGE_SIZE), %o4
 3661:	subcc		%o4, (1 << 5), %o4
 367	stxa		%g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
 368	membar		#Sync
 369	bne,pt		%icc, 1b
 370	 nop
 371	retl		/* I-cache flush never needed on Cheetah, see callers. */
 372	 nop
 373#endif /* DCACHE_ALIASING_POSSIBLE */
 374
 375	/* Hypervisor specific versions, patched at boot time.  */
 376__hypervisor_tlb_tl0_error:
 377	save		%sp, -192, %sp
 378	mov		%i0, %o0
 379	call		hypervisor_tlbop_error
 380	 mov		%i1, %o1
 381	ret
 382	 restore
 383
 384__hypervisor_flush_tlb_mm: /* 19 insns */
 385	mov		%o0, %o2	/* ARG2: mmu context */
 386	mov		0, %o0		/* ARG0: CPU lists unimplemented */
 387	mov		0, %o1		/* ARG1: CPU lists unimplemented */
 388	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
 389	mov		HV_FAST_MMU_DEMAP_CTX, %o5
 390	ta		HV_FAST_TRAP
 391	brnz,pn		%o0, 1f
 392	 mov		HV_FAST_MMU_DEMAP_CTX, %o1
 393	retl
 394	 nop
 3951:	sethi		%hi(__hypervisor_tlb_tl0_error), %o5
 396	jmpl		%o5 + %lo(__hypervisor_tlb_tl0_error), %g0
 397	 nop
 398	nop
 399	nop
 400	nop
 401	nop
 402	nop
 403	nop
 404
 405__hypervisor_flush_tlb_page: /* 22 insns */
 406	/* %o0 = context, %o1 = vaddr */
 407	mov		%o0, %g2
 408	mov		%o1, %o0              /* ARG0: vaddr + IMMU-bit */
 409	mov		%g2, %o1	      /* ARG1: mmu context */
 410	mov		HV_MMU_ALL, %o2	      /* ARG2: flags */
 411	srlx		%o0, PAGE_SHIFT, %o0
 412	sllx		%o0, PAGE_SHIFT, %o0
 413	ta		HV_MMU_UNMAP_ADDR_TRAP
 414	brnz,pn		%o0, 1f
 415	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
 416	retl
 417	 nop
 4181:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
 419	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
 420	 nop
 421	nop
 422	nop
 423	nop
 424	nop
 425	nop
 426	nop
 427	nop
 428	nop
 429
 430__hypervisor_flush_tlb_pending: /* 27 insns */
 431	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
 432	sllx		%o1, 3, %g1
 433	mov		%o2, %g2
 434	mov		%o0, %g3
 4351:	sub		%g1, (1 << 3), %g1
 436	ldx		[%g2 + %g1], %o0      /* ARG0: vaddr + IMMU-bit */
 437	mov		%g3, %o1	      /* ARG1: mmu context */
 438	mov		HV_MMU_ALL, %o2	      /* ARG2: flags */
 439	srlx		%o0, PAGE_SHIFT, %o0
 440	sllx		%o0, PAGE_SHIFT, %o0
 441	ta		HV_MMU_UNMAP_ADDR_TRAP
 442	brnz,pn		%o0, 1f
 443	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
 444	brnz,pt		%g1, 1b
 445	 nop
 446	retl
 447	 nop
 4481:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
 449	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
 450	 nop
 451	nop
 452	nop
 453	nop
 454	nop
 455	nop
 456	nop
 457	nop
 458	nop
 459
 460__hypervisor_flush_tlb_kernel_range: /* 31 insns */
 461	/* %o0=start, %o1=end */
 462	cmp		%o0, %o1
 463	be,pn		%xcc, 2f
 464	 sub		%o1, %o0, %g2
 465	srlx		%g2, 18, %g3
 466	brnz,pn		%g3, 4f
 467	 mov		%o0, %g1
 468	sethi		%hi(PAGE_SIZE), %g3
 469	sub		%g2, %g3, %g2
 4701:	add		%g1, %g2, %o0	/* ARG0: virtual address */
 471	mov		0, %o1		/* ARG1: mmu context */
 472	mov		HV_MMU_ALL, %o2	/* ARG2: flags */
 473	ta		HV_MMU_UNMAP_ADDR_TRAP
 474	brnz,pn		%o0, 3f
 475	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
 476	brnz,pt		%g2, 1b
 477	 sub		%g2, %g3, %g2
 4782:	retl
 479	 nop
 4803:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
 481	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
 482	 nop
 4834:	mov		0, %o0		/* ARG0: CPU lists unimplemented */
 484	mov		0, %o1		/* ARG1: CPU lists unimplemented */
 485	mov		0, %o2		/* ARG2: mmu context == nucleus */
 486	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
 487	mov		HV_FAST_MMU_DEMAP_CTX, %o5
 488	ta		HV_FAST_TRAP
 489	brnz,pn		%o0, 3b
 490	 mov		HV_FAST_MMU_DEMAP_CTX, %o1
 491	retl
 492	 nop
 493
 494#ifdef DCACHE_ALIASING_POSSIBLE
 495	/* XXX Niagara and friends have an 8K cache, so no aliasing is
 496	 * XXX possible, but nothing explicit in the Hypervisor API
 497	 * XXX guarantees this.
 498	 */
 499__hypervisor_flush_dcache_page:	/* 2 insns */
 500	retl
 501	 nop
 502#endif
 503
 504tlb_patch_one:
 5051:	lduw		[%o1], %g1
 506	stw		%g1, [%o0]
 507	flush		%o0
 508	subcc		%o2, 1, %o2
 509	add		%o1, 4, %o1
 510	bne,pt		%icc, 1b
 511	 add		%o0, 4, %o0
 512	retl
 513	 nop
 514
 515#ifdef CONFIG_SMP
 516	/* These are all called by the slaves of a cross call, at
 517	 * trap level 1, with interrupts fully disabled.
 518	 *
 519	 * Register usage:
 520	 *   %g5	mm->context	(all tlb flushes)
 521	 *   %g1	address arg 1	(tlb page and range flushes)
 522	 *   %g7	address arg 2	(tlb range flush only)
 523	 *
 524	 *   %g6	scratch 1
 525	 *   %g2	scratch 2
 526	 *   %g3	scratch 3
 527	 *   %g4	scratch 4
 528	 */
 529	.align		32
 530	.globl		xcall_flush_tlb_mm
 531xcall_flush_tlb_mm:	/* 24 insns */
 532	mov		PRIMARY_CONTEXT, %g2
 533	ldxa		[%g2] ASI_DMMU, %g3
 534	srlx		%g3, CTX_PGSZ1_NUC_SHIFT, %g4
 535	sllx		%g4, CTX_PGSZ1_NUC_SHIFT, %g4
 536	or		%g5, %g4, %g5	/* Preserve nucleus page size fields */
 537	stxa		%g5, [%g2] ASI_DMMU
 538	mov		0x40, %g4
 539	stxa		%g0, [%g4] ASI_DMMU_DEMAP
 540	stxa		%g0, [%g4] ASI_IMMU_DEMAP
 541	stxa		%g3, [%g2] ASI_DMMU
 542	retry
 543	nop
 544	nop
 545	nop
 546	nop
 547	nop
 548	nop
 549	nop
 550	nop
 551	nop
 552	nop
 553	nop
 554	nop
 555	nop
 556
 557	.globl		xcall_flush_tlb_page
 558xcall_flush_tlb_page:	/* 20 insns */
 559	/* %g5=context, %g1=vaddr */
 560	mov		PRIMARY_CONTEXT, %g4
 561	ldxa		[%g4] ASI_DMMU, %g2
 562	srlx		%g2, CTX_PGSZ1_NUC_SHIFT, %g4
 563	sllx		%g4, CTX_PGSZ1_NUC_SHIFT, %g4
 564	or		%g5, %g4, %g5
 565	mov		PRIMARY_CONTEXT, %g4
 566	stxa		%g5, [%g4] ASI_DMMU
 567	andcc		%g1, 0x1, %g0
 568	be,pn		%icc, 2f
 569	 andn		%g1, 0x1, %g5
 570	stxa		%g0, [%g5] ASI_IMMU_DEMAP
 5712:	stxa		%g0, [%g5] ASI_DMMU_DEMAP
 572	membar		#Sync
 573	stxa		%g2, [%g4] ASI_DMMU
 574	retry
 575	nop
 576	nop
 577	nop
 578	nop
 579	nop
 580
 581	.globl		xcall_flush_tlb_kernel_range
 582xcall_flush_tlb_kernel_range:	/* 44 insns */
 583	sethi		%hi(PAGE_SIZE - 1), %g2
 584	or		%g2, %lo(PAGE_SIZE - 1), %g2
 585	andn		%g1, %g2, %g1
 586	andn		%g7, %g2, %g7
 587	sub		%g7, %g1, %g3
 588	srlx		%g3, 18, %g2
 589	brnz,pn		%g2, 2f
 590	 sethi		%hi(PAGE_SIZE), %g2
 591	sub		%g3, %g2, %g3
 592	or		%g1, 0x20, %g1		! Nucleus
 5931:	stxa		%g0, [%g1 + %g3] ASI_DMMU_DEMAP
 594	stxa		%g0, [%g1 + %g3] ASI_IMMU_DEMAP
 595	membar		#Sync
 596	brnz,pt		%g3, 1b
 597	 sub		%g3, %g2, %g3
 598	retry
 5992:	mov		63 * 8, %g1
 6001:	ldxa		[%g1] ASI_ITLB_DATA_ACCESS, %g2
 601	andcc		%g2, 0x40, %g0			/* _PAGE_L_4U */
 602	bne,pn		%xcc, 2f
 603	 mov		TLB_TAG_ACCESS, %g2
 604	stxa		%g0, [%g2] ASI_IMMU
 605	stxa		%g0, [%g1] ASI_ITLB_DATA_ACCESS
 606	membar		#Sync
 6072:	ldxa		[%g1] ASI_DTLB_DATA_ACCESS, %g2
 608	andcc		%g2, 0x40, %g0
 609	bne,pn		%xcc, 2f
 610	 mov		TLB_TAG_ACCESS, %g2
 611	stxa		%g0, [%g2] ASI_DMMU
 612	stxa		%g0, [%g1] ASI_DTLB_DATA_ACCESS
 613	membar		#Sync
 6142:	sub		%g1, 8, %g1
 615	brgez,pt	%g1, 1b
 616	 nop
 617	retry
 618	nop
 619	nop
 620	nop
 621	nop
 622	nop
 623	nop
 624	nop
 625	nop
 626	nop
 627
 628	/* This runs in a very controlled environment, so we do
 629	 * not need to worry about BH races etc.
 630	 */
 631	.globl		xcall_sync_tick
 632xcall_sync_tick:
 633
 634661:	rdpr		%pstate, %g2
 635	wrpr		%g2, PSTATE_IG | PSTATE_AG, %pstate
 636	.section	.sun4v_2insn_patch, "ax"
 637	.word		661b
 638	nop
 639	nop
 640	.previous
 641
 642	rdpr		%pil, %g2
 643	wrpr		%g0, PIL_NORMAL_MAX, %pil
 644	sethi		%hi(109f), %g7
 645	b,pt		%xcc, etrap_irq
 646109:	 or		%g7, %lo(109b), %g7
 647#ifdef CONFIG_TRACE_IRQFLAGS
 648	call		trace_hardirqs_off
 649	 nop
 650#endif
 651	call		smp_synchronize_tick_client
 652	 nop
 653	b		rtrap_xcall
 654	 ldx		[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
 655
 656	.globl		xcall_fetch_glob_regs
 657xcall_fetch_glob_regs:
 658	sethi		%hi(global_cpu_snapshot), %g1
 659	or		%g1, %lo(global_cpu_snapshot), %g1
 660	__GET_CPUID(%g2)
 661	sllx		%g2, 6, %g3
 662	add		%g1, %g3, %g1
 663	rdpr		%tstate, %g7
 664	stx		%g7, [%g1 + GR_SNAP_TSTATE]
 665	rdpr		%tpc, %g7
 666	stx		%g7, [%g1 + GR_SNAP_TPC]
 667	rdpr		%tnpc, %g7
 668	stx		%g7, [%g1 + GR_SNAP_TNPC]
 669	stx		%o7, [%g1 + GR_SNAP_O7]
 670	stx		%i7, [%g1 + GR_SNAP_I7]
 671	/* Don't try this at home kids... */
 672	rdpr		%cwp, %g3
 673	sub		%g3, 1, %g7
 674	wrpr		%g7, %cwp
 675	mov		%i7, %g7
 676	wrpr		%g3, %cwp
 677	stx		%g7, [%g1 + GR_SNAP_RPC]
 678	sethi		%hi(trap_block), %g7
 679	or		%g7, %lo(trap_block), %g7
 680	sllx		%g2, TRAP_BLOCK_SZ_SHIFT, %g2
 681	add		%g7, %g2, %g7
 682	ldx		[%g7 + TRAP_PER_CPU_THREAD], %g3
 683	stx		%g3, [%g1 + GR_SNAP_THREAD]
 684	retry
 685
 686	.globl		xcall_fetch_glob_pmu
 687xcall_fetch_glob_pmu:
 688	sethi		%hi(global_cpu_snapshot), %g1
 689	or		%g1, %lo(global_cpu_snapshot), %g1
 690	__GET_CPUID(%g2)
 691	sllx		%g2, 6, %g3
 692	add		%g1, %g3, %g1
 693	rd		%pic, %g7
 694	stx		%g7, [%g1 + (4 * 8)]
 695	rd		%pcr, %g7
 696	stx		%g7, [%g1 + (0 * 8)]
 697	retry
 698
 699	.globl		xcall_fetch_glob_pmu_n4
 700xcall_fetch_glob_pmu_n4:
 701	sethi		%hi(global_cpu_snapshot), %g1
 702	or		%g1, %lo(global_cpu_snapshot), %g1
 703	__GET_CPUID(%g2)
 704	sllx		%g2, 6, %g3
 705	add		%g1, %g3, %g1
 706
 707	ldxa		[%g0] ASI_PIC, %g7
 708	stx		%g7, [%g1 + (4 * 8)]
 709	mov		0x08, %g3
 710	ldxa		[%g3] ASI_PIC, %g7
 711	stx		%g7, [%g1 + (5 * 8)]
 712	mov		0x10, %g3
 713	ldxa		[%g3] ASI_PIC, %g7
 714	stx		%g7, [%g1 + (6 * 8)]
 715	mov		0x18, %g3
 716	ldxa		[%g3] ASI_PIC, %g7
 717	stx		%g7, [%g1 + (7 * 8)]
 718
 719	mov		%o0, %g2
 720	mov		%o1, %g3
 721	mov		%o5, %g7
 722
 723	mov		HV_FAST_VT_GET_PERFREG, %o5
 724	mov		3, %o0
 725	ta		HV_FAST_TRAP
 726	stx		%o1, [%g1 + (3 * 8)]
 727	mov		HV_FAST_VT_GET_PERFREG, %o5
 728	mov		2, %o0
 729	ta		HV_FAST_TRAP
 730	stx		%o1, [%g1 + (2 * 8)]
 731	mov		HV_FAST_VT_GET_PERFREG, %o5
 732	mov		1, %o0
 733	ta		HV_FAST_TRAP
 734	stx		%o1, [%g1 + (1 * 8)]
 735	mov		HV_FAST_VT_GET_PERFREG, %o5
 736	mov		0, %o0
 737	ta		HV_FAST_TRAP
 738	stx		%o1, [%g1 + (0 * 8)]
 739
 740	mov		%g2, %o0
 741	mov		%g3, %o1
 742	mov		%g7, %o5
 743
 744	retry
 745
 746__cheetah_xcall_flush_tlb_kernel_range:	/* 44 insns */
 747	sethi		%hi(PAGE_SIZE - 1), %g2
 748	or		%g2, %lo(PAGE_SIZE - 1), %g2
 749	andn		%g1, %g2, %g1
 750	andn		%g7, %g2, %g7
 751	sub		%g7, %g1, %g3
 752	srlx		%g3, 18, %g2
 753	brnz,pn		%g2, 2f
 754	 sethi		%hi(PAGE_SIZE), %g2
 755	sub		%g3, %g2, %g3
 756	or		%g1, 0x20, %g1		! Nucleus
 7571:	stxa		%g0, [%g1 + %g3] ASI_DMMU_DEMAP
 758	stxa		%g0, [%g1 + %g3] ASI_IMMU_DEMAP
 759	membar		#Sync
 760	brnz,pt		%g3, 1b
 761	 sub		%g3, %g2, %g3
 762	retry
 7632:	mov		0x80, %g2
 764	stxa		%g0, [%g2] ASI_DMMU_DEMAP
 765	membar		#Sync
 766	stxa		%g0, [%g2] ASI_IMMU_DEMAP
 767	membar		#Sync
 768	retry
 769	nop
 770	nop
 771	nop
 772	nop
 773	nop
 774	nop
 775	nop
 776	nop
 777	nop
 778	nop
 779	nop
 780	nop
 781	nop
 782	nop
 783	nop
 784	nop
 785	nop
 786	nop
 787	nop
 788	nop
 789	nop
 790	nop
 791
 792#ifdef DCACHE_ALIASING_POSSIBLE
 793	.align		32
 794	.globl		xcall_flush_dcache_page_cheetah
 795xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
 796	sethi		%hi(PAGE_SIZE), %g3
 7971:	subcc		%g3, (1 << 5), %g3
 798	stxa		%g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE
 799	membar		#Sync
 800	bne,pt		%icc, 1b
 801	 nop
 802	retry
 803	nop
 804#endif /* DCACHE_ALIASING_POSSIBLE */
 805
 806	.globl		xcall_flush_dcache_page_spitfire
 807xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
 808				     %g7 == kernel page virtual address
 809				     %g5 == (page->mapping != NULL)  */
 810#ifdef DCACHE_ALIASING_POSSIBLE
 811	srlx		%g1, (13 - 2), %g1	! Form tag comparitor
 812	sethi		%hi(L1DCACHE_SIZE), %g3	! D$ size == 16K
 813	sub		%g3, (1 << 5), %g3	! D$ linesize == 32
 8141:	ldxa		[%g3] ASI_DCACHE_TAG, %g2
 815	andcc		%g2, 0x3, %g0
 816	be,pn		%xcc, 2f
 817	 andn		%g2, 0x3, %g2
 818	cmp		%g2, %g1
 819
 820	bne,pt		%xcc, 2f
 821	 nop
 822	stxa		%g0, [%g3] ASI_DCACHE_TAG
 823	membar		#Sync
 8242:	cmp		%g3, 0
 825	bne,pt		%xcc, 1b
 826	 sub		%g3, (1 << 5), %g3
 827
 828	brz,pn		%g5, 2f
 829#endif /* DCACHE_ALIASING_POSSIBLE */
 830	 sethi		%hi(PAGE_SIZE), %g3
 831
 8321:	flush		%g7
 833	subcc		%g3, (1 << 5), %g3
 834	bne,pt		%icc, 1b
 835	 add		%g7, (1 << 5), %g7
 836
 8372:	retry
 838	nop
 839	nop
 840
 841	/* %g5:	error
 842	 * %g6:	tlb op
 843	 */
 844__hypervisor_tlb_xcall_error:
 845	mov	%g5, %g4
 846	mov	%g6, %g5
 847	ba,pt	%xcc, etrap
 848	 rd	%pc, %g7
 849	mov	%l4, %o0
 850	call	hypervisor_tlbop_error_xcall
 851	 mov	%l5, %o1
 852	ba,a,pt	%xcc, rtrap
 853
 854	.globl		__hypervisor_xcall_flush_tlb_mm
 855__hypervisor_xcall_flush_tlb_mm: /* 24 insns */
 856	/* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */
 857	mov		%o0, %g2
 858	mov		%o1, %g3
 859	mov		%o2, %g4
 860	mov		%o3, %g1
 861	mov		%o5, %g7
 862	clr		%o0		/* ARG0: CPU lists unimplemented */
 863	clr		%o1		/* ARG1: CPU lists unimplemented */
 864	mov		%g5, %o2	/* ARG2: mmu context */
 865	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
 866	mov		HV_FAST_MMU_DEMAP_CTX, %o5
 867	ta		HV_FAST_TRAP
 868	mov		HV_FAST_MMU_DEMAP_CTX, %g6
 869	brnz,pn		%o0, 1f
 870	 mov		%o0, %g5
 871	mov		%g2, %o0
 872	mov		%g3, %o1
 873	mov		%g4, %o2
 874	mov		%g1, %o3
 875	mov		%g7, %o5
 876	membar		#Sync
 877	retry
 8781:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
 879	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
 880	 nop
 881
 882	.globl		__hypervisor_xcall_flush_tlb_page
 883__hypervisor_xcall_flush_tlb_page: /* 20 insns */
 884	/* %g5=ctx, %g1=vaddr */
 885	mov		%o0, %g2
 886	mov		%o1, %g3
 887	mov		%o2, %g4
 888	mov		%g1, %o0	        /* ARG0: virtual address */
 889	mov		%g5, %o1		/* ARG1: mmu context */
 890	mov		HV_MMU_ALL, %o2		/* ARG2: flags */
 891	srlx		%o0, PAGE_SHIFT, %o0
 892	sllx		%o0, PAGE_SHIFT, %o0
 893	ta		HV_MMU_UNMAP_ADDR_TRAP
 894	mov		HV_MMU_UNMAP_ADDR_TRAP, %g6
 895	brnz,a,pn	%o0, 1f
 896	 mov		%o0, %g5
 897	mov		%g2, %o0
 898	mov		%g3, %o1
 899	mov		%g4, %o2
 900	membar		#Sync
 901	retry
 9021:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
 903	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
 904	 nop
 905
 906	.globl		__hypervisor_xcall_flush_tlb_kernel_range
 907__hypervisor_xcall_flush_tlb_kernel_range: /* 44 insns */
 908	/* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */
 909	sethi		%hi(PAGE_SIZE - 1), %g2
 910	or		%g2, %lo(PAGE_SIZE - 1), %g2
 911	andn		%g1, %g2, %g1
 912	andn		%g7, %g2, %g7
 913	sub		%g7, %g1, %g3
 914	srlx		%g3, 18, %g7
 915	add		%g2, 1, %g2
 916	sub		%g3, %g2, %g3
 917	mov		%o0, %g2
 918	mov		%o1, %g4
 919	brnz,pn		%g7, 2f
 920	 mov		%o2, %g7
 9211:	add		%g1, %g3, %o0	/* ARG0: virtual address */
 922	mov		0, %o1		/* ARG1: mmu context */
 923	mov		HV_MMU_ALL, %o2	/* ARG2: flags */
 924	ta		HV_MMU_UNMAP_ADDR_TRAP
 925	mov		HV_MMU_UNMAP_ADDR_TRAP, %g6
 926	brnz,pn		%o0, 1f
 927	 mov		%o0, %g5
 928	sethi		%hi(PAGE_SIZE), %o2
 929	brnz,pt		%g3, 1b
 930	 sub		%g3, %o2, %g3
 9315:	mov		%g2, %o0
 932	mov		%g4, %o1
 933	mov		%g7, %o2
 934	membar		#Sync
 935	retry
 9361:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
 937	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
 938	 nop
 9392:	mov		%o3, %g1
 940	mov		%o5, %g3
 941	mov		0, %o0		/* ARG0: CPU lists unimplemented */
 942	mov		0, %o1		/* ARG1: CPU lists unimplemented */
 943	mov		0, %o2		/* ARG2: mmu context == nucleus */
 944	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
 945	mov		HV_FAST_MMU_DEMAP_CTX, %o5
 946	ta		HV_FAST_TRAP
 947	mov		%g1, %o3
 948	brz,pt		%o0, 5b
 949	 mov		%g3, %o5
 950	mov		HV_FAST_MMU_DEMAP_CTX, %g6
 951	ba,pt		%xcc, 1b
 952	 clr		%g5
 953
 954	/* These just get rescheduled to PIL vectors. */
 955	.globl		xcall_call_function
 956xcall_call_function:
 957	wr		%g0, (1 << PIL_SMP_CALL_FUNC), %set_softint
 958	retry
 959
 960	.globl		xcall_call_function_single
 961xcall_call_function_single:
 962	wr		%g0, (1 << PIL_SMP_CALL_FUNC_SNGL), %set_softint
 963	retry
 964
 965	.globl		xcall_receive_signal
 966xcall_receive_signal:
 967	wr		%g0, (1 << PIL_SMP_RECEIVE_SIGNAL), %set_softint
 968	retry
 969
 970	.globl		xcall_capture
 971xcall_capture:
 972	wr		%g0, (1 << PIL_SMP_CAPTURE), %set_softint
 973	retry
 974
 975#ifdef CONFIG_KGDB
 976	.globl		xcall_kgdb_capture
 977xcall_kgdb_capture:
 978	wr		%g0, (1 << PIL_KGDB_CAPTURE), %set_softint
 979	retry
 980#endif
 981
 982#endif /* CONFIG_SMP */
 983
 984	.globl		cheetah_patch_cachetlbops
 985cheetah_patch_cachetlbops:
 986	save		%sp, -128, %sp
 987
 988	sethi		%hi(__flush_tlb_mm), %o0
 989	or		%o0, %lo(__flush_tlb_mm), %o0
 990	sethi		%hi(__cheetah_flush_tlb_mm), %o1
 991	or		%o1, %lo(__cheetah_flush_tlb_mm), %o1
 992	call		tlb_patch_one
 993	 mov		19, %o2
 994
 995	sethi		%hi(__flush_tlb_page), %o0
 996	or		%o0, %lo(__flush_tlb_page), %o0
 997	sethi		%hi(__cheetah_flush_tlb_page), %o1
 998	or		%o1, %lo(__cheetah_flush_tlb_page), %o1
 999	call		tlb_patch_one
1000	 mov		22, %o2
1001
1002	sethi		%hi(__flush_tlb_pending), %o0
1003	or		%o0, %lo(__flush_tlb_pending), %o0
1004	sethi		%hi(__cheetah_flush_tlb_pending), %o1
1005	or		%o1, %lo(__cheetah_flush_tlb_pending), %o1
1006	call		tlb_patch_one
1007	 mov		27, %o2
1008
1009	sethi		%hi(__flush_tlb_kernel_range), %o0
1010	or		%o0, %lo(__flush_tlb_kernel_range), %o0
1011	sethi		%hi(__cheetah_flush_tlb_kernel_range), %o1
1012	or		%o1, %lo(__cheetah_flush_tlb_kernel_range), %o1
1013	call		tlb_patch_one
1014	 mov		31, %o2
1015
1016#ifdef DCACHE_ALIASING_POSSIBLE
1017	sethi		%hi(__flush_dcache_page), %o0
1018	or		%o0, %lo(__flush_dcache_page), %o0
1019	sethi		%hi(__cheetah_flush_dcache_page), %o1
1020	or		%o1, %lo(__cheetah_flush_dcache_page), %o1
1021	call		tlb_patch_one
1022	 mov		11, %o2
1023#endif /* DCACHE_ALIASING_POSSIBLE */
1024
1025#ifdef CONFIG_SMP
1026	sethi		%hi(xcall_flush_tlb_kernel_range), %o0
1027	or		%o0, %lo(xcall_flush_tlb_kernel_range), %o0
1028	sethi		%hi(__cheetah_xcall_flush_tlb_kernel_range), %o1
1029	or		%o1, %lo(__cheetah_xcall_flush_tlb_kernel_range), %o1
1030	call		tlb_patch_one
1031	 mov		44, %o2
1032#endif /* CONFIG_SMP */
1033
1034	ret
1035	 restore
1036
1037	.globl		hypervisor_patch_cachetlbops
1038hypervisor_patch_cachetlbops:
1039	save		%sp, -128, %sp
1040
1041	sethi		%hi(__flush_tlb_mm), %o0
1042	or		%o0, %lo(__flush_tlb_mm), %o0
1043	sethi		%hi(__hypervisor_flush_tlb_mm), %o1
1044	or		%o1, %lo(__hypervisor_flush_tlb_mm), %o1
1045	call		tlb_patch_one
1046	 mov		19, %o2
1047
1048	sethi		%hi(__flush_tlb_page), %o0
1049	or		%o0, %lo(__flush_tlb_page), %o0
1050	sethi		%hi(__hypervisor_flush_tlb_page), %o1
1051	or		%o1, %lo(__hypervisor_flush_tlb_page), %o1
1052	call		tlb_patch_one
1053	 mov		22, %o2
1054
1055	sethi		%hi(__flush_tlb_pending), %o0
1056	or		%o0, %lo(__flush_tlb_pending), %o0
1057	sethi		%hi(__hypervisor_flush_tlb_pending), %o1
1058	or		%o1, %lo(__hypervisor_flush_tlb_pending), %o1
1059	call		tlb_patch_one
1060	 mov		27, %o2
1061
1062	sethi		%hi(__flush_tlb_kernel_range), %o0
1063	or		%o0, %lo(__flush_tlb_kernel_range), %o0
1064	sethi		%hi(__hypervisor_flush_tlb_kernel_range), %o1
1065	or		%o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1
1066	call		tlb_patch_one
1067	 mov		31, %o2
1068
1069#ifdef DCACHE_ALIASING_POSSIBLE
1070	sethi		%hi(__flush_dcache_page), %o0
1071	or		%o0, %lo(__flush_dcache_page), %o0
1072	sethi		%hi(__hypervisor_flush_dcache_page), %o1
1073	or		%o1, %lo(__hypervisor_flush_dcache_page), %o1
1074	call		tlb_patch_one
1075	 mov		2, %o2
1076#endif /* DCACHE_ALIASING_POSSIBLE */
1077
1078#ifdef CONFIG_SMP
1079	sethi		%hi(xcall_flush_tlb_mm), %o0
1080	or		%o0, %lo(xcall_flush_tlb_mm), %o0
1081	sethi		%hi(__hypervisor_xcall_flush_tlb_mm), %o1
1082	or		%o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1
1083	call		tlb_patch_one
1084	 mov		24, %o2
1085
1086	sethi		%hi(xcall_flush_tlb_page), %o0
1087	or		%o0, %lo(xcall_flush_tlb_page), %o0
1088	sethi		%hi(__hypervisor_xcall_flush_tlb_page), %o1
1089	or		%o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1
1090	call		tlb_patch_one
1091	 mov		20, %o2
1092
1093	sethi		%hi(xcall_flush_tlb_kernel_range), %o0
1094	or		%o0, %lo(xcall_flush_tlb_kernel_range), %o0
1095	sethi		%hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1
1096	or		%o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1
1097	call		tlb_patch_one
1098	 mov		44, %o2
1099#endif /* CONFIG_SMP */
1100
1101	ret
1102	 restore