1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Chris Dearman (chris@mips.com)
7 * Copyright (C) 2007 Mips Technologies, Inc.
8 * Copyright (C) 2014 Imagination Technologies Ltd.
9 */
10#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
11#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
12
13#include <asm/regdef.h>
14#include <asm/mipsregs.h>
15
16	/*
17	 * Prepare segments for EVA boot:
18	 *
19	 * This is in case the processor boots in legacy configuration
20	 * (SI_EVAReset is de-asserted and CONFIG5.K == 0)
21	 *
22	 * ========================= Mappings =============================
23	 * Virtual memory           Physical memory           Mapping
24	 * 0x00000000 - 0x7fffffff  0x80000000 - 0xfffffffff   MUSUK (kuseg)
25	 *                          Flat 2GB physical memory
26	 *
27	 * 0x80000000 - 0x9fffffff  0x00000000 - 0x1ffffffff   MUSUK (kseg0)
28	 * 0xa0000000 - 0xbf000000  0x00000000 - 0x1ffffffff   MUSUK (kseg1)
29	 * 0xc0000000 - 0xdfffffff             -                 MK  (kseg2)
30	 * 0xe0000000 - 0xffffffff             -                 MK  (kseg3)
31	 *
32	 *
33	 * Lowmem is expanded to 2GB
34	 *
35	 * The following code uses the t0, t1, t2 and ra registers without
36	 * previously preserving them.
37	 *
38	 */
39	.macro	platform_eva_init
40
41	.set	push
42	.set	reorder
43	/*
44	 * Get Config.K0 value and use it to program
45	 * the segmentation registers
46	 */
47	mfc0    t1, CP0_CONFIG
48	andi	t1, 0x7 /* CCA */
49	move	t2, t1
50	ins	t2, t1, 16, 3
51	/* SegCtl0 */
52	li      t0, ((MIPS_SEGCFG_MK << MIPS_SEGCFG_AM_SHIFT) |		\
53		(0 << MIPS_SEGCFG_PA_SHIFT) |				\
54		(1 << MIPS_SEGCFG_EU_SHIFT)) |				\
55		(((MIPS_SEGCFG_MK << MIPS_SEGCFG_AM_SHIFT) |		\
56		(0 << MIPS_SEGCFG_PA_SHIFT) |				\
57		(1 << MIPS_SEGCFG_EU_SHIFT)) << 16)
58	or	t0, t2
59	mtc0	t0, CP0_SEGCTL0
60
61	/* SegCtl1 */
62	li      t0, ((MIPS_SEGCFG_MUSUK << MIPS_SEGCFG_AM_SHIFT) |	\
63		(0 << MIPS_SEGCFG_PA_SHIFT) |				\
64		(2 << MIPS_SEGCFG_C_SHIFT) |				\
65		(1 << MIPS_SEGCFG_EU_SHIFT)) |				\
66		(((MIPS_SEGCFG_MUSUK << MIPS_SEGCFG_AM_SHIFT) |		\
67		(0 << MIPS_SEGCFG_PA_SHIFT) |				\
68		(1 << MIPS_SEGCFG_EU_SHIFT)) << 16)
69	ins	t0, t1, 16, 3
70	mtc0	t0, CP0_SEGCTL1
71
72	/* SegCtl2 */
73	li	t0, ((MIPS_SEGCFG_MUSUK << MIPS_SEGCFG_AM_SHIFT) |	\
74		(6 << MIPS_SEGCFG_PA_SHIFT) |				\
75		(1 << MIPS_SEGCFG_EU_SHIFT)) |				\
76		(((MIPS_SEGCFG_MUSUK << MIPS_SEGCFG_AM_SHIFT) |		\
77		(4 << MIPS_SEGCFG_PA_SHIFT) |				\
78		(1 << MIPS_SEGCFG_EU_SHIFT)) << 16)
79	or	t0, t2
80	mtc0	t0, CP0_SEGCTL2
81
82	jal	mips_ihb
83	mfc0    t0, $16, 5
84	li      t2, 0x40000000      /* K bit */
85	or      t0, t0, t2
86	mtc0    t0, $16, 5
87	sync
88	jal	mips_ihb
89
90	.set	pop
91	.endm
92
93	.macro	kernel_entry_setup
94
95#ifdef CONFIG_EVA
96	sync
97	ehb
98
99	mfc0    t1, CP0_CONFIG
100	bgez    t1, 9f
101	mfc0	t0, CP0_CONFIG, 1
102	bgez	t0, 9f
103	mfc0	t0, CP0_CONFIG, 2
104	bgez	t0, 9f
105	mfc0	t0, CP0_CONFIG, 3
106	sll     t0, t0, 6   /* SC bit */
107	bgez    t0, 9f
108
109	platform_eva_init
110	b       0f
1119:
112	/* Assume we came from YAMON... */
113	PTR_LA	v0, 0x9fc00534	/* YAMON print */
114	lw	v0, (v0)
115	move	a0, zero
116	PTR_LA  a1, nonsc_processor
117	jal	v0
118
119	PTR_LA	v0, 0x9fc00520	/* YAMON exit */
120	lw	v0, (v0)
121	li	a0, 1
122	jal	v0
123
1241:	b	1b
125	nop
126	__INITDATA
127nonsc_processor:
128	.asciz  "EVA kernel requires a MIPS core with Segment Control implemented\n"
129	__FINIT
130#endif /* CONFIG_EVA */
1310:
132	.endm
133
134/*
135 * Do SMP slave processor setup necessary before we can safely execute C code.
136 */
137	.macro	smp_slave_setup
138#ifdef CONFIG_EVA
139	sync
140	ehb
141	platform_eva_init
142#endif
143	.endm
144
145#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */
146