162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
362306a36Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
462306a36Sopenharmony_ci * for more details.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2000 Silicon Graphics, Inc.
762306a36Sopenharmony_ci * Copyright (C) 2005 Ralf Baechle <ralf@linux-mips.org>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci#ifndef __ASM_MACH_IP27_KERNEL_ENTRY_H
1062306a36Sopenharmony_ci#define __ASM_MACH_IP27_KERNEL_ENTRY_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <asm/sn/addrs.h>
1362306a36Sopenharmony_ci#include <asm/sn/agent.h>
1462306a36Sopenharmony_ci#include <asm/sn/klkernvars.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/*
1762306a36Sopenharmony_ci * TLB bits
1862306a36Sopenharmony_ci */
1962306a36Sopenharmony_ci#define PAGE_GLOBAL		(1 << 6)
2062306a36Sopenharmony_ci#define PAGE_VALID		(1 << 7)
2162306a36Sopenharmony_ci#define PAGE_DIRTY		(1 << 8)
2262306a36Sopenharmony_ci#define CACHE_CACHABLE_COW	(5 << 9)
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	/*
2562306a36Sopenharmony_ci	 * inputs are the text nasid in t1, data nasid in t2.
2662306a36Sopenharmony_ci	 */
2762306a36Sopenharmony_ci	.macro MAPPED_KERNEL_SETUP_TLB
2862306a36Sopenharmony_ci#ifdef CONFIG_MAPPED_KERNEL
2962306a36Sopenharmony_ci	/*
3062306a36Sopenharmony_ci	 * This needs to read the nasid - assume 0 for now.
3162306a36Sopenharmony_ci	 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
3262306a36Sopenharmony_ci	 * 0+DVG in tlblo_1.
3362306a36Sopenharmony_ci	 */
3462306a36Sopenharmony_ci	dli	t0, 0xffffffffc0000000
3562306a36Sopenharmony_ci	dmtc0	t0, CP0_ENTRYHI
3662306a36Sopenharmony_ci	li	t0, 0x1c000		# Offset of text into node memory
3762306a36Sopenharmony_ci	dsll	t1, NASID_SHFT		# Shift text nasid into place
3862306a36Sopenharmony_ci	dsll	t2, NASID_SHFT		# Same for data nasid
3962306a36Sopenharmony_ci	or	t1, t1, t0		# Physical load address of kernel text
4062306a36Sopenharmony_ci	or	t2, t2, t0		# Physical load address of kernel data
4162306a36Sopenharmony_ci	dsrl	t1, 12			# 4K pfn
4262306a36Sopenharmony_ci	dsrl	t2, 12			# 4K pfn
4362306a36Sopenharmony_ci	dsll	t1, 6			# Get pfn into place
4462306a36Sopenharmony_ci	dsll	t2, 6			# Get pfn into place
4562306a36Sopenharmony_ci	li	t0, ((PAGE_GLOBAL | PAGE_VALID | CACHE_CACHABLE_COW) >> 6)
4662306a36Sopenharmony_ci	or	t0, t0, t1
4762306a36Sopenharmony_ci	mtc0	t0, CP0_ENTRYLO0	# physaddr, VG, cach exlwr
4862306a36Sopenharmony_ci	li	t0, ((PAGE_GLOBAL | PAGE_VALID |  PAGE_DIRTY | CACHE_CACHABLE_COW) >> 6)
4962306a36Sopenharmony_ci	or	t0, t0, t2
5062306a36Sopenharmony_ci	mtc0	t0, CP0_ENTRYLO1	# physaddr, DVG, cach exlwr
5162306a36Sopenharmony_ci	li	t0, 0x1ffe000		# MAPPED_KERN_TLBMASK, TLBPGMASK_16M
5262306a36Sopenharmony_ci	mtc0	t0, CP0_PAGEMASK
5362306a36Sopenharmony_ci	li	t0, 0			# KMAP_INX
5462306a36Sopenharmony_ci	mtc0	t0, CP0_INDEX
5562306a36Sopenharmony_ci	li	t0, 1
5662306a36Sopenharmony_ci	mtc0	t0, CP0_WIRED
5762306a36Sopenharmony_ci	tlbwi
5862306a36Sopenharmony_ci#else
5962306a36Sopenharmony_ci	mtc0	zero, CP0_WIRED
6062306a36Sopenharmony_ci#endif
6162306a36Sopenharmony_ci	.endm
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/*
6462306a36Sopenharmony_ci * Intentionally empty macro, used in head.S. Override in
6562306a36Sopenharmony_ci * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_ci	.macro	kernel_entry_setup
6862306a36Sopenharmony_ci	GET_NASID_ASM	t1
6962306a36Sopenharmony_ci	move		t2, t1			# text and data are here
7062306a36Sopenharmony_ci	MAPPED_KERNEL_SETUP_TLB
7162306a36Sopenharmony_ci	.endm
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/*
7462306a36Sopenharmony_ci * Do SMP slave processor setup necessary before we can safely execute C code.
7562306a36Sopenharmony_ci */
7662306a36Sopenharmony_ci	.macro	smp_slave_setup
7762306a36Sopenharmony_ci	GET_NASID_ASM	t1
7862306a36Sopenharmony_ci	dli	t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
7962306a36Sopenharmony_ci		    KLDIR_OFF_POINTER + CAC_BASE
8062306a36Sopenharmony_ci	dsll	t1, NASID_SHFT
8162306a36Sopenharmony_ci	or	t0, t0, t1
8262306a36Sopenharmony_ci	ld	t0, 0(t0)			# t0 points to kern_vars struct
8362306a36Sopenharmony_ci	lh	t1, KV_RO_NASID_OFFSET(t0)
8462306a36Sopenharmony_ci	lh	t2, KV_RW_NASID_OFFSET(t0)
8562306a36Sopenharmony_ci	MAPPED_KERNEL_SETUP_TLB
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	/*
8862306a36Sopenharmony_ci	 * We might not get launched at the address the kernel is linked to,
8962306a36Sopenharmony_ci	 * so we jump there.
9062306a36Sopenharmony_ci	 */
9162306a36Sopenharmony_ci	PTR_LA	t0, 0f
9262306a36Sopenharmony_ci	jr	t0
9362306a36Sopenharmony_ci0:
9462306a36Sopenharmony_ci	.endm
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci#endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */
97