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) 2005 Embedded Alley Solutions, Inc
762306a36Sopenharmony_ci * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
862306a36Sopenharmony_ci * Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn)
962306a36Sopenharmony_ci * Copyright (C) 2012 Huacai Chen (chenhc@lemote.com)
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci#ifndef __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
1262306a36Sopenharmony_ci#define __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <asm/cpu.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/*
1762306a36Sopenharmony_ci * Override macros used in arch/mips/kernel/head.S.
1862306a36Sopenharmony_ci */
1962306a36Sopenharmony_ci	.macro	kernel_entry_setup
2062306a36Sopenharmony_ci	.set	push
2162306a36Sopenharmony_ci	.set	mips64
2262306a36Sopenharmony_ci	/* Set ELPA on LOONGSON3 pagegrain */
2362306a36Sopenharmony_ci	mfc0	t0, CP0_PAGEGRAIN
2462306a36Sopenharmony_ci	or	t0, (0x1 << 29)
2562306a36Sopenharmony_ci	mtc0	t0, CP0_PAGEGRAIN
2662306a36Sopenharmony_ci	/* Enable STFill Buffer */
2762306a36Sopenharmony_ci	mfc0	t0, CP0_PRID
2862306a36Sopenharmony_ci	/* Loongson-3A R4+ */
2962306a36Sopenharmony_ci	andi	t1, t0, PRID_IMP_MASK
3062306a36Sopenharmony_ci	li	t2, PRID_IMP_LOONGSON_64G
3162306a36Sopenharmony_ci	beq     t1, t2, 1f
3262306a36Sopenharmony_ci	nop
3362306a36Sopenharmony_ci	/* Loongson-3A R2/R3 */
3462306a36Sopenharmony_ci	andi	t0, (PRID_IMP_MASK | PRID_REV_MASK)
3562306a36Sopenharmony_ci	slti	t0, t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0)
3662306a36Sopenharmony_ci	bnez	t0, 2f
3762306a36Sopenharmony_ci	nop
3862306a36Sopenharmony_ci1:
3962306a36Sopenharmony_ci	mfc0	t0, CP0_CONFIG6
4062306a36Sopenharmony_ci	or	t0, 0x100
4162306a36Sopenharmony_ci	mtc0	t0, CP0_CONFIG6
4262306a36Sopenharmony_ci2:
4362306a36Sopenharmony_ci	_ehb
4462306a36Sopenharmony_ci	.set	pop
4562306a36Sopenharmony_ci	.endm
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/*
4862306a36Sopenharmony_ci * Do SMP slave processor setup.
4962306a36Sopenharmony_ci */
5062306a36Sopenharmony_ci	.macro	smp_slave_setup
5162306a36Sopenharmony_ci	.set	push
5262306a36Sopenharmony_ci	.set	mips64
5362306a36Sopenharmony_ci	/* Set ELPA on LOONGSON3 pagegrain */
5462306a36Sopenharmony_ci	mfc0	t0, CP0_PAGEGRAIN
5562306a36Sopenharmony_ci	or	t0, (0x1 << 29)
5662306a36Sopenharmony_ci	mtc0	t0, CP0_PAGEGRAIN
5762306a36Sopenharmony_ci	/* Enable STFill Buffer */
5862306a36Sopenharmony_ci	mfc0	t0, CP0_PRID
5962306a36Sopenharmony_ci	/* Loongson-3A R4+ */
6062306a36Sopenharmony_ci	andi	t1, t0, PRID_IMP_MASK
6162306a36Sopenharmony_ci	li	t2, PRID_IMP_LOONGSON_64G
6262306a36Sopenharmony_ci	beq     t1, t2, 1f
6362306a36Sopenharmony_ci	nop
6462306a36Sopenharmony_ci	/* Loongson-3A R2/R3 */
6562306a36Sopenharmony_ci	andi	t0, (PRID_IMP_MASK | PRID_REV_MASK)
6662306a36Sopenharmony_ci	slti	t0, t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0)
6762306a36Sopenharmony_ci	bnez	t0, 2f
6862306a36Sopenharmony_ci	nop
6962306a36Sopenharmony_ci1:
7062306a36Sopenharmony_ci	mfc0	t0, CP0_CONFIG6
7162306a36Sopenharmony_ci	or	t0, 0x100
7262306a36Sopenharmony_ci	mtc0	t0, CP0_CONFIG6
7362306a36Sopenharmony_ci2:
7462306a36Sopenharmony_ci	_ehb
7562306a36Sopenharmony_ci	.set	pop
7662306a36Sopenharmony_ci	.endm
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#define USE_KEXEC_SMP_WAIT_FINAL
7962306a36Sopenharmony_ci	.macro  kexec_smp_wait_final
8062306a36Sopenharmony_ci	/* s0:prid s1:initfn */
8162306a36Sopenharmony_ci	/* a0:base t1:cpuid t2:node t9:count */
8262306a36Sopenharmony_ci	mfc0		t1, CP0_EBASE
8362306a36Sopenharmony_ci	andi		t1, MIPS_EBASE_CPUNUM
8462306a36Sopenharmony_ci	dins		a0, t1, 8, 2       /* insert core id*/
8562306a36Sopenharmony_ci	dext		t2, t1, 2, 2
8662306a36Sopenharmony_ci	dins		a0, t2, 44, 2      /* insert node id */
8762306a36Sopenharmony_ci	mfc0		s0, CP0_PRID
8862306a36Sopenharmony_ci	andi		s0, s0, (PRID_IMP_MASK | PRID_REV_MASK)
8962306a36Sopenharmony_ci	beq		s0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1), 1f
9062306a36Sopenharmony_ci	beq		s0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2), 1f
9162306a36Sopenharmony_ci	b		2f                 /* Loongson-3A1000/3A2000/3A3000/3A4000 */
9262306a36Sopenharmony_ci1:	dins		a0, t2, 14, 2      /* Loongson-3B1000/3B1500 need bit 15~14 */
9362306a36Sopenharmony_ci2:	li		t9, 0x100          /* wait for init loop */
9462306a36Sopenharmony_ci3:	addiu		t9, -1             /* limit mailbox access */
9562306a36Sopenharmony_ci	bnez		t9, 3b
9662306a36Sopenharmony_ci	lw		s1, 0x20(a0)       /* check PC as an indicator */
9762306a36Sopenharmony_ci	beqz		s1, 2b
9862306a36Sopenharmony_ci	ld		s1, 0x20(a0)       /* get PC via mailbox reg0 */
9962306a36Sopenharmony_ci	ld		sp, 0x28(a0)       /* get SP via mailbox reg1 */
10062306a36Sopenharmony_ci	ld		gp, 0x30(a0)       /* get GP via mailbox reg2 */
10162306a36Sopenharmony_ci	ld		a1, 0x38(a0)
10262306a36Sopenharmony_ci	jr		s1                 /* jump to initial PC */
10362306a36Sopenharmony_ci	.endm
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */
106