rmixl_subr.S revision 1.1.2.9 1 /* rmixl_subr.S,v 1.1.2.8 2011/04/29 08:26:34 matt Exp */
2
3 /*-
4 * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Cliff Neighbors.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "opt_cputype.h"
33 #include "opt_multiprocessor.h"
34
35 #include <sys/cdefs.h>
36
37 #include <mips/asm.h>
38 #include <mips/cpuregs.h>
39
40 RCSID("rmixl_subr.S,v 1.1.2.8 2011/04/29 08:26:34 matt Exp");
41
42 #include "assym.h"
43
44 #define RMIXL_COP_0_EIRR _(9), 6
45 #define RMIXL_COP_0_EIMR _(9), 7
46
47 .set noreorder
48 .set arch=xlr
49 .text
50
51 /*
52 * read XLS Processor Control register
53 *
54 * uint64_t rmixl_mfcr(u_int cr);
55 */
56 LEAF(rmixl_mfcr)
57 #if defined(__mips_o32)
58 #error O32 not supported
59 #endif
60 j ra
61 mfcr v0, a0
62 END(rmixl_mfcr)
63
64 /*
65 * write XLS Processor Control register
66 *
67 * void rmixl_mtcr(u_int cr, uint64_t val);
68 */
69 LEAF(rmixl_mtcr)
70 #if defined(__mips_o32)
71 #error O32 not supported
72 #endif
73 j ra
74 mtcr a1, a0
75 END(rmixl_mtcr)
76
77 /*
78 * void rmixl_eirr_ack(uint64_t eimr, uint64_t vecbit, uint64_t preserve)
79 *
80 * ack in EIRR the irq we are about to handle
81 * disable all interrupts to prevent a race that would allow
82 * e.g. softints set from a higher interrupt getting
83 * clobbered by the EIRR read-modify-write
84 */
85 LEAF(rmixl_eirr_ack)
86 dmtc0 zero, RMIXL_COP_0_EIMR /* EIMR = 0 */
87 COP0_SYNC
88 dmfc0 a3, RMIXL_COP_0_EIRR /* a3 = EIRR */
89 and a3, a2 /* a3 &= preserve */
90 or a3, a1 /* a3 |= vecbit */
91 dmtc0 a3, RMIXL_COP_0_EIRR /* EIRR = a3 */
92 COP0_SYNC
93 dmtc0 a0, RMIXL_COP_0_EIMR /* EIMR = eimr */
94 JR_HB_RA
95 END(rmixl_eirr_ack)
96
97 #ifdef MULTIPROCESSOR
98 /*
99 * rmixlfw_wakeup_cpu(func, args, mask, callback)
100 */
101 NESTED(rmixlfw_wakeup_cpu, CALLFRAME_SIZ+4*SZREG, ra)
102 PTR_ADDU sp, sp, -(CALLFRAME_SIZ+4*SZREG)
103 REG_S ra, CALLFRAME_RA(sp)
104 REG_S s0, CALLFRAME_S0(sp)
105 REG_S gp, CALLFRAME_SIZ+0*SZREG(sp)
106 REG_S t8, CALLFRAME_SIZ+1*SZREG(sp)
107 mfc0 t0, MIPS_COP_0_STATUS
108 REG_S t0, CALLFRAME_SIZ+2*SZREG(sp)
109
110 move s0, sp /* save sp */
111 #ifdef _LP64
112 dsll32 t0, sp, 0 /* nuke upper half */
113 dsrl32 t0, t0, 0 /* " " " */
114 li t1, MIPS_KSEG0_START
115 or sp, t0, t1 /* set MIPS_KSEG0_START */
116 #endif
117 jalr a3 /* callback to firmware */
118 nop
119 move sp, s0 /* restore sp */
120
121 REG_L t0, CALLFRAME_SIZ+2*SZREG(sp)
122 mtc0 t0, MIPS_COP_0_STATUS
123 REG_L t8, CALLFRAME_SIZ+1*SZREG(sp)
124 REG_L gp, CALLFRAME_SIZ+0*SZREG(sp)
125 REG_L s0, CALLFRAME_S0(sp)
126 REG_L ra, CALLFRAME_RA(sp)
127 jr ra
128 PTR_ADDU sp, sp, (CALLFRAME_SIZ+4*SZREG)
129 END(rmixlfw_wakeup_cpu)
130
131 /*
132 * rmixl_cpu_trampoline - entry point for subordinate (non-#0) CPU wakeup
133 */
134 NESTED(rmixl_cpu_trampoline, CALLFRAME_SIZ, ra)
135 #ifdef _LP64
136 /*
137 * reconstruct trampoline args addr:
138 * sign-extend 32 bit KSEG0 address in a0
139 * to make proper 64 bit KSEG0 addr
140 */
141 sll s0, a0, 0
142 li t0, MIPS_SR_KX
143 #else
144 li t0, 0
145 #endif
146
147 mtc0 zero, $9, 7 /* disable all in MIPS_COP_0_EIMR */
148
149 mtc0 t0, MIPS_COP_0_STATUS
150
151 /* ensure COP_0_EBASE field 'EBASE' is 0 */
152 mfc0 t0, $15, 1 /* MIPS_COP_0_EBASE */
153 and t0, t0, 0x3ff
154 mtc0 t0, $15, 1 /* MIPS_COP_0_EBASE */
155
156 /*
157 * load our stack pointer from trampoline args
158 */
159 REG_L sp, 0*SZREG(s0) /* XXX ta_sp */
160
161 /*
162 * load our (idle) lwp from trampoline args
163 * save in t8 reg dedicated as 'mips_curlwp'
164 */
165 REG_L t8, 1*SZREG(s0) /* XXX ta_lwp */
166
167 /*
168 * load our ta_cpuinfo from trampoline args and pass in a1
169 * jump to common mips cpu_trampoline
170 */
171 REG_L a1, 2*SZREG(s0) /* XXX ta_cpuinfo */
172 dmtc0 a1, $22, 0 /* MIPS_COP_0_OSSCRATCH */
173 PTR_L v1, CPU_INFO_TLB_INFO(a1)
174 PTR_L v1, TI_LOCK(v1)
175 PTR_ADDU v1, MTX_LOCK
176 dmtc0 v1, $22, 2
177 j cpu_trampoline
178 nop
179
180 /* NOTREACHED */
181
182 END(rmixl_cpu_trampoline)
183
184 #endif /* MULTIPROCESSOR */
185