免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6367 | 回复: 6
打印 上一主题 下一主题

[NetBSD] NetBSD /sys/arch/mips/mips/locore.S简单分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-10 12:57 |只看该作者 |倒序浏览
1 /* $NetBSD: locore.S,v 1.167 2007/10/17 19:55:38 garbled Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Digital Equipment Corporation and Ralph Campbell.
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 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * Copyright (C) 1989 Digital Equipment Corporation.
35 * Permission to use, copy, modify, and distribute this software and
36 * its documentation for any purpose and without fee is hereby granted,
37 * provided that the above copyright notice appears in all copies.
38 * Digital Equipment Corporation makes no representations about the
39 * suitability of this software for any purpose. It is provided "as is"
40 * without express or implied warranty.
41 *
42 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
43 * v 1.1 89/07/11 17:55:04 nelson Exp SPRITE (DECWRL)
44 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
45 * v 9.2 90/01/29 18:00:39 shirriff Exp SPRITE (DECWRL)
46 * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
47 * v 1.1 89/07/10 14:27:41 nelson Exp SPRITE (DECWRL)
48 *
49 * @(#)locore.s 8.5 (Berkeley) 1/4/94
50 */
51
文件的第一行是版本控制标识,之后是版权信息,然后是......
这个组织结构的具体描述由NetBSD内核正规范式(KNF)描述,在share/misc/style里。

52 #include "opt_cputype.h" /* which mips CPU levels do we support? 支持哪些级别的处理器*/
53 #include "opt_ddb.h"
54 #include "opt_kgdb.h"
55 #include "opt_iso.h"
56 #include "opt_lockdebug.h"
57 #include "opt_multiprocessor.h"
58
59 #include <sys/cdefs.h>
60
61 #include <machine/param.h>
62 #include <mips/asm.h>
63 #include <mips/cpuregs.h>
64 #include <mips/trap.h>
65
66 #include "assym.h"
67
68 .set noreorder 告诉汇编器不要重组指令

69
70 .globl start 指出start为全局变量

71 .globl _C_LABEL(kernel_text) # libkvm refers this
72 start:
73 _C_LABEL(kernel_text): 这个宏在sys/arch/mips/include/asm.h定义

sys/arch/mips/include/cpuregs.h定义CP0寄存器的名字。

74 #if defined(MIPS3_PLUS) && !defined(MIPS1)
75 /* keep firmware exception handler until we hook.此间如果发生异常,那么在我们轻轻松松出困境之前只能依赖固件的异常处理器了 */
76 mfc0 v0, MIPS_COP_0_STATUS 12CP0寄存器,状态寄存器无法直接写,只能读到GPR,and,or清除,设置某些位后再写回。

77 and v0, MIPS_SR_BEV MIPS_SR_BEVcpuregs.h中定义为0x00400000,BEV1,除BEV外其余位清零

78 mtc0 v0, MIPS_COP_0_STATUS # Disable interrupts 关中断

79 COP0_SYNC 什么也不做

80 #else
81 mtc0 zero, MIPS_COP_0_STATUS # Disable interrupts 直接清零

82 COP0_SYNC
83 #endif

对于MIPS1(R3000)MIPS3为何采取不同的方式呢?其差别在于BEV位是否清零,原因可能是从R4000以后冷启和热启中断向量入口相同。

84 /*
85 * Initialize stack and call machine startup.初始化堆栈并调用机器启动代码

86 */
87 la v1, start start地址读到v1

88 slt v0, v1, sp
89 bne v0, zero, 1f 如果start < sp sp = 1 ,注意延迟槽

90 addu v0, v1, -CALLFRAME_SIZ start - 24 ,CALLFRAME_SIZmips/include/asm.h里定义为24

91 subu v0, v1, sp v0 = v1 - sp ,(start > sp) 堆栈大小

92 slt v0, v0, 4096 # within 4KB of _start
93 beq v0, zero, 2f 如果堆栈大于4KB,跳到下面标号2处初始化gp
94 addu v0, v1, -CALLFRAME_SIZ
95 1:
96 move sp, v0
97 2:
98 #ifdef __GP_SUPPORT__
99 la gp, _C_LABEL(_gp)
100 #endif
101
102 #ifdef NOFPU /* No FPU; avoid touching FPU registers FPU; 避免使用FPU寄存器 */
103 li t0, 0 取立即数到t0 # Disable interrupts and
104 mtc0 t0, MIPS_COP_0_STATUS # the fp coprocessor 关中断和浮点协处理器

105 COP0_SYNC
106 #ifdef HPCMIPS_L1CACHE_DISABLE
107 mfc0 t0, MIPS_COP_0_CONFIG
108 li t1, 0xfffffff8
109 and t0, t0, t1 config寄存器低三位清零

110 or t0, 0x00000002 config寄存器K0域置2,表示访问KSEG0不缓存 # XXX, KSEG0 is uncached
111 mtc0 t0, MIPS_COP_0_CONFIG
112 COP0_SYNC
113 #endif /* HPCMIPS_L1CACHE_DISABLE */
114 #else
115 mfc0 t0, MIPS_COP_0_STATUS
116 or t0, MIPS_SR_COP_1_BIT # Disable interrupts, and
117 mtc0 t0, MIPS_COP_0_STATUS # enable the fp coprocessor 关中断,允许FPU, MIPS_SR_COP_1_BIT = 0x20000000
118 COP0_HAZARD_FPUENABLE nop(ssnop...),等待配置生效

119 #endif
120 nop
121 nop
122 mfc0 t0, MIPS_COP_0_PRID # read product revision ID 读取处理器ID,mips/include/cpuregs.h添加了龙芯的ID
123 nop # XXX r4000 pipeline:
124 nop # wait for new SR
125 nop # to be effective nop,等待配置生效

126 nop
127 #ifdef NOFPU /* No FPU; avoid touching FPU registers 如果没FPU,避免触及FPU寄存器 */
128 add t1, zero, zero
129 #else
130 cfc1 t1, MIPS_FPU_ID # read FPU ID register 如果有浮点控制/状态寄存器就读取FPU ID
131 #endif
132 sw t0, _C_LABEL(cpu_id) # save PRID register 保存PRID寄存器,注意延迟槽

133 sw t1, _C_LABEL(fpu_id) # save FPU ID register 保存FPU寄存器

134 la MIPS_CURLWP, _C_LABEL(lwp0) # set curlwp, curcpu 设置curlwp = &lwp0MIPS_CURLWP 23号寄存器(s7)LWP是轻量级进程即线程

135 la t0, _C_LABEL(cpu_info_store) cpu_info_store地址,curlwp--当前运行lwp,cprcpu = curlwp->l_cpu

136 sw MIPS_CURLWP, CPU_INFO_CURLWP(t0) 存储进程0的地址,初始化cpu_info_store
137 sw t0, L_CPU(MIPS_CURLWP) 初始化l_cpu,lwp0.l_cpu = &cpu_info_store

138 jal _C_LABEL(mach_init) # mach_init(a0, a1, a2, a3)跳转到mach_init,返回地址保存在ra,平台初始化,对于每个移植要有自己的mach_init,对于algoralgor/algor/machdep.c,主要获取内核起始地址,清除bss,分配自举堆栈
初始化总线空间,启动控制台,设置PMON状态,获取引导选项,探测内存大小,初始化异常向量,清除指令和数据缓存,初始化消息缓冲以及虚存系统,初始化进程0的用户结构,并包含控制台初始化,startup,cpu_reboot等函数

................................在附件

locore.pdf

164.97 KB, 下载次数: 95

论坛徽章:
0
2 [报告]
发表于 2008-11-10 13:19 |只看该作者
139 nop

141 lw sp, _C_LABEL(proc0paddr) # switch to proc0 stack,存储进程0的的sp

142 nop

143 addu sp, sp, USPACE - FRAME_SIZ - CALLFRAME_SIZ 调整sp

144 jal _C_LABEL(main) # main(void) 跳转到main,在sys/kern/init_main.c,这里手工创建进程0,挂载根文件系统,并fork出init和pagedaemon,即进程1和2;大多数工作由startup()来做,包括内存初始化和自动配置

45 nop

146 PANIC("main() returned") # main never returns main永远不返回

147 .set at 允许使用$1

148 .globl _C_LABEL(verylocore)

149 _C_LABEL(verylocore):

150

151 /*

152 * struct lwp *cpu_switchto(struct lwp *cur, struct lwp *next)

153 * Switch to the specified next LWP

154 * Arguments:

155 * a0 the current LWP

156 * a1 the LWP to switch to

157 * Returns:

158 * v0 the LWP we have switched from

159 */

cpu_switchto()是机器相关的LWP上下文切换接口,它保存当前运行LWP的上下文,并恢复要切换到的LWP的上下文。

160 NESTED(cpu_switchto, CALLFRAME_SIZ, ra) 一个NESTED函数是调用别的函数并需要保存和恢复寄存器的函数

这里定义了cpu_switchto的入口并设为全局,CALLFRAME_SIZ为stack frame大小,以及返回地址ra。NESTED这个宏在asm.h定义

161 /*

162 * Save old context, unless the LWP is exiting. 保存旧上下文,除非LWP要退出

163 */

164 beq a0, zero, 1f 如果当前是0号进程则跳到下面标号1处,否则(即init_main.c已初始化完毕)

165 nop

166 lw a2, L_ADDR(a0) # a2 = l->l_addr a2为lwp的地址

167 mfc0 t0, MIPS_COP_0_STATUS

168 REG_PROLOGUE 即.set push,保存对堆栈的设置

169 REG_S s0, U_PCB_CONTEXT+SF_REG_S0(a2) 这几条指令保存上下文,在用户结构中的进程控制块(PCB)中

170 REG_S s1, U_PCB_CONTEXT+SF_REG_S1(a2)

171 REG_S s2, U_PCB_CONTEXT+SF_REG_S2(a2)

172 REG_S s3, U_PCB_CONTEXT+SF_REG_S3(a2)

173 REG_S s4, U_PCB_CONTEXT+SF_REG_S4(a2)

174 REG_S s5, U_PCB_CONTEXT+SF_REG_S5(a2)

175 REG_S s6, U_PCB_CONTEXT+SF_REG_S6(a2)

176 REG_S s7, U_PCB_CONTEXT+SF_REG_S7(a2)

177 REG_S sp, U_PCB_CONTEXT+SF_REG_SP(a2)

178 REG_S s8, U_PCB_CONTEXT+SF_REG_S8(a2)

179 REG_S ra, U_PCB_CONTEXT+SF_REG_RA(a2)

180 REG_S t0, U_PCB_CONTEXT+SF_REG_SR(a2)

181 #ifdef IPL_ICU_MASK 如果定义了中断优先级就要设置PPL,以保证原子性操作

182 lw t0, _C_LABEL(md_imask) 加载中断掩码?

183 sw t0, U_PCB_PPL(a2) 设置处理器特权级?

184 #endif

185 REG_EPILOGUE 即.set pop ,恢复堆栈设置

186 1:

187 move s6, a0 # s6 = old lwp 保存当前进程

188 move MIPS_CURLWP, a1 # s7 = new lwp s7为要切换到的进程

189 subu sp, sp, CALLFRAME_SIZ 分配堆栈

190 sw ra, CALLFRAME_RA(sp)

191 .mask 0x80000000, -4 描述堆栈布局

192 /*

193 * Switch to new context. 切换到新的上下文

194 */

195 lw t2, _C_LABEL(mips_locoresw) + MIPSX_CPU_SWITCH_RESUME 加载mips_locoresw到t2

196 move a0, MIPS_CURLWP 新进程变为当前进程

197 jal ra, t2 跳到t2(mips_locoresw),返回地址保存在ra

198 nop

199 sw MIPS_CURLWP, CPUVAR(CURLWP) 保存当前进程

200

201 /* Check for restartable atomic sequences (RAS) 确定可自动重启队列 */

202 lw t1, L_PROC(MIPS_CURLWP) 即 t1 = curlwp->l_proc

203 lw a0, L_ADDR(MIPS_CURLWP) a0 = curlwp->l_addr

204 lw v1, P_RASLIST(t1) v1存放进程号,用以判断是父进程还是子进程

205 addu t0, a0, USPACE - FRAME_SIZ 调整当前进程地址

206 beq v1, zero, 1f 如果v1 = 0,即为子进程,就跳到下面标号1处

207 nop

208 move a0, t1 当前进程设为t1

209 jal _C_LABEL(ras_lookup) 跳转到ras_lookup,注意延迟槽

210 lw a1, FRAME_EPC(t0) 要切换进程的地址

211 lw a0, L_ADDR(MIPS_CURLWP) a0 = curlwp->l_addr

212 li v1, -1

213 beq v1, v0, 1f 父进程跳转到下面标号1处

214 addu t0, a0, USPACE - FRAME_SIZ

215 sw v0, FRAME_EPC(t0) 保存所切换出的进程到t0

216 1:

217 /* New context is now active */

218 #ifdef IPL_ICU_MASK

219 # restore ICU state 恢复ICU(中断控制单元)状态

220 lw a0, L_ADDR(MIPS_CURLWP) a0 = curlwp->l_addr

221 lw t0, U_PCB_PPL(a0) 从PCB取PPL

222 sw t0, _C_LABEL(md_imask) 保存到md_imask

223 jal _C_LABEL(md_imask_update) 跳转到md_imask_update

224 nop

225 #endif /* IPL_ICU_MASK */

226 lw a0, L_ADDR(MIPS_CURLWP)

227 move v0, s6 # Save return value 保存返回值

228 REG_PROLOGUE 即.set push

229 REG_L t0, U_PCB_CONTEXT+SF_REG_SR(a0) 下面几条指令加载用户结构的PCB

230 DYNAMIC_STATUS_MASK(t0,ra) # machine dependent masking 机器相关掩码

231 REG_L ra, U_PCB_CONTEXT+SF_REG_RA(a0)

232 REG_L s0, U_PCB_CONTEXT+SF_REG_S0(a0)

233 REG_L s1, U_PCB_CONTEXT+SF_REG_S1(a0)

234 REG_L s2, U_PCB_CONTEXT+SF_REG_S2(a0)

235 REG_L s3, U_PCB_CONTEXT+SF_REG_S3(a0)

236 REG_L s4, U_PCB_CONTEXT+SF_REG_S4(a0)

237 REG_L s5, U_PCB_CONTEXT+SF_REG_S5(a0)

238 REG_L s6, U_PCB_CONTEXT+SF_REG_S6(a0)

239 REG_L s7, U_PCB_CONTEXT+SF_REG_S7(a0)

240 REG_L sp, U_PCB_CONTEXT+SF_REG_SP(a0)

241 REG_L s8, U_PCB_CONTEXT+SF_REG_S8(a0)

242 REG_EPILOGUE .set pop

243 mtc0 t0, MIPS_COP_0_STATUS 设置SR

244 COP0_SYNC

245 j ra 返回

246 nop

247 END(cpu_switchto)

248

论坛徽章:
0
3 [报告]
发表于 2008-11-10 13:20 |只看该作者
249 /*

250 * savectx(struct user *up)

251 */

252 LEAF(savectx)

253 mfc0 v0, MIPS_COP_0_STATUS

254 REG_PROLOGUE 即.set push

255 REG_S s0, U_PCB_CONTEXT+SF_REG_S0(a0) 保存当前进程PCB,savectx(&dumppcb)

256 REG_S s1, U_PCB_CONTEXT+SF_REG_S1(a0)

257 REG_S s2, U_PCB_CONTEXT+SF_REG_S2(a0)

258 REG_S s3, U_PCB_CONTEXT+SF_REG_S3(a0)

259 REG_S s4, U_PCB_CONTEXT+SF_REG_S4(a0)

260 REG_S s5, U_PCB_CONTEXT+SF_REG_S5(a0)

261 REG_S s6, U_PCB_CONTEXT+SF_REG_S6(a0)

262 REG_S s7, U_PCB_CONTEXT+SF_REG_S7(a0)

263 REG_S sp, U_PCB_CONTEXT+SF_REG_SP(a0)

264 REG_S s8, U_PCB_CONTEXT+SF_REG_S8(a0)

265 REG_S ra, U_PCB_CONTEXT+SF_REG_RA(a0)

266 REG_S v0, U_PCB_CONTEXT+SF_REG_SR(a0)

267 REG_EPILOGUE

268 j ra

269 move v0, zero 注意在延迟槽里,切换出去

270 END(savectx)

271

272 #if defined(DDB) || defined(KGDB)

273 /*

274 * setjmp(label_t *)

275 * longjmp(label_t *)

276 */

277 LEAF(setjmp)

278 mfc0 v0, MIPS_COP_0_STATUS

279 REG_PROLOGUE

280 REG_S s0, SF_REG_S0(a0)

281 REG_S s1, SF_REG_S1(a0)

282 REG_S s2, SF_REG_S2(a0)

283 REG_S s3, SF_REG_S3(a0)

284 REG_S s4, SF_REG_S4(a0)

285 REG_S s5, SF_REG_S5(a0)

286 REG_S s6, SF_REG_S6(a0)

287 REG_S s7, SF_REG_S7(a0)

288 REG_S sp, SF_REG_SP(a0)

289 REG_S s8, SF_REG_S8(a0)

290 REG_S ra, SF_REG_RA(a0)

291 REG_S v0, SF_REG_SR(a0)

292 REG_EPILOGUE

293 j ra

294 move v0, zero

295 END(setjmp)

296

297 LEAF(longjmp)

298 REG_PROLOGUE

299 REG_L v0, SF_REG_SR(a0)

300 DYNAMIC_STATUS_MASK(v0,ra) # machine dependent masking

301 REG_L ra, SF_REG_RA(a0)

302 REG_L s0, SF_REG_S0(a0)

303 REG_L s1, SF_REG_S1(a0)

304 REG_L s2, SF_REG_S2(a0)

305 REG_L s3, SF_REG_S3(a0)

306 REG_L s4, SF_REG_S4(a0)

307 REG_L s5, SF_REG_S5(a0)

308 REG_L s6, SF_REG_S6(a0)

309 REG_L s7, SF_REG_S7(a0)

310 REG_L sp, SF_REG_SP(a0)

311 REG_L s8, SF_REG_S8(a0)

312 REG_EPILOGUE

313 mtc0 v0, MIPS_COP_0_STATUS

314 COP0_SYNC

315 j ra

316 li v0, 1

317 END(longjmp)

318 #endif

319

320

321 /*

322 * MIPS processor interrupt control MIPS处理器中断控制,是spl内核接口的构件。设备驱动并不用它,而是用rwlock(读者,写者锁),

323 *

324 * Used as building blocks for spl(9) kernel interface. mutex等,MP系统里只改变本地的IPL。spl用于保护临界区代码。

325 */

326 LEAF(_splraise) splraise和splset用来做splhigh和splx

327 XLEAF(_splraise_noprof) # does not get mcount hooks

328 mfc0 v0, MIPS_COP_0_STATUS # fetch status register 取状态寄存器

329 and a0, a0, MIPS_INT_MASK # extract INT bits 析出中断位,中断掩码MIPS_INT_MASK = 0xff00,即低8位清零

330 nor a0, zero, a0 # bitwise inverse of A0 高位不变

331 and a0, a0, v0 # disable retaining other bits v0和a0的8~31位相与,低8位为0

332 DYNAMIC_STATUS_MASK(a0,t0) # machine dependent masking升级中断掩码的附加操作,用于运行时中断掩码或处理低速清除掩码

333 mtc0 a0, MIPS_COP_0_STATUS # store back 把结果存回SR

334 COP0_SYNC

335 and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE) v0返回值,MIPS_SR_INT_IE全局中断使能位( 0x00000001 ),2~7位清0

336 j ra 返回

337 nop

338 END(_splraise)

339

340 LEAF(_spllower)

341 mfc0 v0, MIPS_COP_0_STATUS # fetch status register 取状态寄存器

342 li v1, ~MIPS_INT_MASK v1 = 0x000000ff

343 and v1, v0, v1 # turn off INT bit 关中断位,取v0低8位到v1

344 nor a0, zero, a0 # bitwise inverse of A0 与0异或,不变

345 and a0, a0, MIPS_INT_MASK # extract INT bits 低8位清零

346 or a0, a0, v1 # disable making other bits on低8位清0的a0与8~31位清0的v0相或,存到a0

347 DYNAMIC_STATUS_MASK(a0,t0) # machine dependent masking

348 mtc0 a0, MIPS_COP_0_STATUS # store back 把结果存到SR

349 COP0_SYNC

350 and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)

351 j ra 返回

352 nop

353 END(_spllower)

354

355 LEAF(_splrestore)

356 mfc0 v0, MIPS_COP_0_STATUS # fetch status register 读取SR寄存器

357 and a0, a0, MIPS_INT_MASK 低8位清0

358 li v1, ~MIPS_INT_MASK 取反读到v1

359 and v1, v1, v0 # turn off every INT bit 取v0低8位

360 or v1, v1, a0 # set old INT bits 低8位清零的a0和v0低8位相或,存到v1

361 DYNAMIC_STATUS_MASK(v1,t0) # machine dependent masking

362 mtc0 v1, MIPS_COP_0_STATUS # store back 把存回SR

363 COP0_SYNC

364 and v0, v0, MIPS_INT_MASK

365 j ra

366 nop

367 END(_splrestore)

368

369 LEAF(_splset)

370 XLEAF(_splset_noprof) # does not get mcount hooks

371 mfc0 v0, MIPS_COP_0_STATUS # fetch status register

372 and a0, a0, (MIPS_INT_MASK | MIPS_SR_INT_IE)

373 li v1, ~(MIPS_INT_MASK | MIPS_SR_INT_IE)

374 and v1, v1, v0 # turn off every INT bit

375 or v1, v1, a0 # set old INT bits

376 DYNAMIC_STATUS_MASK(v1,t0) # machine dependent masking

377 mtc0 v1, MIPS_COP_0_STATUS # store back

378 COP0_SYNC

379 and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)

380 j ra

381 nop

382 END(_splset)

383

384 LEAF(_splget)

385 mfc0 v0, MIPS_COP_0_STATUS # fetch status register

386 and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE) 2~7位清0

387 j ra

388 nop

389 END(_splget)

390

391 LEAF(_setsoftintr)

392 mfc0 v1, MIPS_COP_0_STATUS # save status register 保存状态寄存器

393 mtc0 zero, MIPS_COP_0_STATUS # disable interrupts (2 cycles) 关中断,2个周期

394 COP0_SYNC

395 nop

396 nop

397 mfc0 v0, MIPS_COP_0_CAUSE # fetch cause register 读原因寄存器

398 nop

399 or v0, v0, a0 # set soft intr. bits 设置软中断位后写回

400 mtc0 v0, MIPS_COP_0_CAUSE # store back

401 COP0_SYNC

402 mtc0 v1, MIPS_COP_0_STATUS # enable interrupts 允许中断

403 COP0_SYNC

404 j ra 返回

405 nop

406 END(_setsoftintr)

407

408 LEAF(_clrsoftintr)

409 mfc0 v1, MIPS_COP_0_STATUS # save status register

410 mtc0 zero, MIPS_COP_0_STATUS # disable interrupts (2 cycles)

411 COP0_SYNC

412 nop

413 nop

414 mfc0 v0, MIPS_COP_0_CAUSE # fetch cause register

415 nor a0, zero, a0 # bitwise inverse of A0

416 and v0, v0, a0 # clear soft intr. bits 清除软件中断位

417 mtc0 v0, MIPS_COP_0_CAUSE # store back

418 COP0_SYNC

419 mtc0 v1, MIPS_COP_0_STATUS # enable interrupts

420 COP0_SYNC

421 j ra

422 nop

423 END(_clrsoftintr)

424

425 LEAF(_splnone)

426 mtc0 zero, MIPS_COP_0_CAUSE # clear SOFT_INT bits 清除软件中断位(IP域)

427 COP0_SYNC

428 li v0, (MIPS_INT_MASK | MIPS_SR_INT_IE) v0 = 0xffffff01

429 DYNAMIC_STATUS_MASK(v0,t0) # machine dependent masking

430 mtc0 v0, MIPS_COP_0_STATUS # enable all sources 无异常

431 COP0_SYNC

432 nop

433 j ra

434 nop

435 END(_splnone)

436

437 /*

438 * u_int32_t mips_cp0_cause_read(void)

439 *

440 * Return the current value of the CP0 Cause register. 返回当前Case CP0寄存器的值

441 *

442 * Note: Not profiled, skews CPU-clock measurement (mips_mcclock.c)

443 * to uselessness.

444 */

445 LEAF_NOPROFILE(mips_cp0_cause_read)

446 mfc0 v0, MIPS_COP_0_CAUSE 读到v0,然后返回

447 j ra

448 nop

449 END(mips_cp0_cause_read)

450

451 /*

452 * void mips_cp0_cause_write(u_int32_t)

453 *

454 * Set the value of the CP0 Cause register. 设置Case CP0寄存器的值

455 */

456 LEAF(mips_cp0_cause_write)

457 mtc0 a0, MIPS_COP_0_CAUSE 写到Case寄存器,然后返回

458 COP0_SYNC

459 nop

460 nop

461 j ra

462 nop

463 END(mips_cp0_cause_write)

464

465

466 /*

467 * u_int32_t mips_cp0_status_read(void)

468 *

469 * Return the current value of the CP0 Status register. 返回状态寄存器的值

470 */

论坛徽章:
0
4 [报告]
发表于 2008-11-10 13:21 |只看该作者
471 LEAF(mips_cp0_status_read)

472 mfc0 v0, MIPS_COP_0_STATUS 读到v0,然后返回

473 j ra

474 nop

475 END(mips_cp0_status_read)

476

477 /*

478 * void mips_cp0_status_write(u_int32_t)

479 *

480 * Set the value of the CP0 Status register. 设置状态寄存器

481 *

482 * Note: This is almost certainly not the way you want to write a 注意:这不大可能是向CP0 状态寄存器写一个特定值的理想方式,

483 * "permanent" value to to the CP0 Status register, since it gets 因为在陷阱框架中需要保存和恢复。

484 * saved in trap frames and restores.

485 */

486 LEAF(mips_cp0_status_write)

487 mtc0 a0, MIPS_COP_0_STATUS 写到SR,然后返回

488 COP0_SYNC



489 nop

490 nop

491 j ra

492 nop

493 END(mips_cp0_status_write)

494

495

496 #if !defined(NOFPU) && !defined(SOFTFLOAT) 处理没有FPU同时没有软件浮点包

497 /*----------------------------------------------------------------------------

498 *

499 * MachFPInterrupt --

500 * MachFPTrap --

501 *

502 * Handle a floating point interrupt (r3k) or trap (r4k). 处理浮点中断(r3k)和陷阱(r4k)

503 * the handlers are indentical, only the reporting mechanisms differ. 中断/陷入处理器是类似的,只有报告机制是不同的

504 *

505 * MachFPInterrupt(status, cause, pc, frame)

506 * unsigned status;

507 * unsigned cause;

508 * unsigned pc;

509 * int *frame;

510 *

511 * MachFPTrap(status, cause, pc, frame)

512 * unsigned status;

513 * unsigned cause;

514 * unsigned pc;

515 * int *frame;

516 *

517 * Results:

518 * None.

519 *

520 * Side effects:

521 * None.

522 *

523 *----------------------------------------------------------------------------

524 */

525 NESTED(MachFPInterrupt, CALLFRAME_SIZ, ra)这个宏声明全局变量MachFPInterrupt及入口,描述stack frame

526 XNESTED(MachFPTrap)

527 .mask 0x80000000, -4

528 subu sp, sp, CALLFRAME_SIZ 创建stack frame

529 mfc0 t0, MIPS_COP_0_STATUS 读SR

530 sw ra, CALLFRAME_RA(sp) 调试用

531 or t0, t0, MIPS_SR_COP_1_BIT CU1位置1,允许CP1

532 mtc0 t0, MIPS_COP_0_STATUS 写回SR

533 COP0_HAZARD_FPUENABLE nop;nop;等待生效或... ssnop...

534

535 cfc1 t0, MIPS_FPU_CSR # stall til FP done 看是否有FCSR-浮点控制/状态寄存器,MIPS_FPU_CSR $31

536 cfc1 t0, MIPS_FPU_CSR # now get status 读到t0

537 nop

538 sll t2, t0, (31 - 17) # unimplemented operation?不是未实现的操作,是陷入这是为了读取FCSR的E位,看是否置位

539 bgez t2, 3f # no, normal trap 如果t2 > 0(即E未置位,未陷入)则跳到下面标号3处

540 nop

541 /*

542 * We got an unimplemented operation trap so

543 * We received an unimplemented operation trap. 收到未实现操作陷阱,因此陷入

544 *

545 * We check whether it's an unimplemented FP instruction here rather 这里检查是否是未实现FP指令而不是调用 MachEmulateInst(),因此更快

546 * than invoking MachEmulateInst(), since it is faster.

547 *

548 * fetch the instruction and emulate the instruction. 取指令和模拟指令

549 */

550 bgez a1, 1f # Check the branch delay bit. 如果a1 > 0,跳到下面标号1处。检查分支延迟位

551 nop

552 /*

553 * The instruction is in the branch delay slot. 指令在延迟槽

554 */

555 b 2f

556 lw a0, 4(a2) # a0 = coproc instruction

557 /*

558 * This is not in the branch delay slot so calculate the resulting

559 * PC (epc + 4) into v0 and continue to MachEmulateFP().

560 */

561 1:

562 lw a0, 0(a2) # a0 = coproc instruction

563 2:

564 move a2, a1

565

566 /*

567 * Check to see if the instruction to be emulated is a floating-point 检查要模拟的是否是浮点指令

568 * instruction.

569 */

570 srl t0, a0, MIPS_OPCODE_SHIFT 即t0 = a0<<26

571 beq t0, MIPS_OPCODE_C1, 4f 如果t0 = 0x11,跳到下面标号4处

572 nop

573

574 /*

575 * Send a floating point exception signal to the current LWP.

576 */

577 li t0, 0xFFFFFF00

578 and a1, a1, t0

579 ori a1, a1, T_RES_INST << MIPS_CR_EXC_CODE_SHIFT

580 REG_PROLOGUE

581 REG_S a1, FRAME_CAUSE(a3)

582 REG_EPILOGUE

583

584 move a1, a0 # code = instruction

585 jal _C_LABEL(mips_fpuillinst)

586 move a0, MIPS_CURLWP # get current LWP

587

588 b FPReturn

589 nop

590

591 /*

592 * Send a FPE signal to the current LWP if it tripped the any of 如果VZOUI各位置位,发送FP错信号到当前进程

593 * the VZOUI bits.

594 */

3:

596 REG_PROLOGUE 即.set push

597 REG_S a1, FRAME_CAUSE(a3) 设置CAUSE,因为未设置E位,这样就保证符合IEEE 754

598 REG_EPILOGUE 即.set pop

599

600 and a0, t0, ~MIPS_FPU_EXCEPTION_BITS t0&0xfffc0fff

601 ctc1 a0, MIPS_FPU_CSR 写回FCSR

602

论坛徽章:
0
5 [报告]
发表于 2008-11-10 13:21 |只看该作者
603 move a1, t0 # FPU status a1为FCSR

604 jal _C_LABEL(mips_fpuexcept) 跳转到mips_fpuexecept,注意延迟槽

605 move a0, MIPS_CURLWP # get current LWP

606

607 b FPReturn 跳到FPReturn

608 nop

609

610 /*

611 * Finally, we can call MachEmulateFP() where a0 is the instruction to emulate.

612 */

613 4:

614 jal _C_LABEL(MachEmulateFP)

615 move a1, a3

616

617 /*

618 * Turn off the floating point coprocessor and return. 关浮点协处理器并返回

619 */

620 FPReturn:

621 mfc0 t0, MIPS_COP_0_STATUS 读取SR

622 lw ra, CALLFRAME_RA(sp)

623 and t0, t0, ~MIPS_SR_COP_1_BIT 清CU1位

624 mtc0 t0, MIPS_COP_0_STATUS 写回

625 COP0_SYNC

626 j ra 返回

627 addu sp, sp, CALLFRAME_SIZ 创建堆栈

628 END(MachFPInterrupt)

629 #endif /* !defined(NOFPU) && !defined(SOFTFLOAT) */

630

631 LEAF(mips_pagecopy) pagecopy,pagezero没什么可注释

632 #if defined(__mips_n32) || defined(_LP64)

633 .set push

634 .set mips3

635 li a2, PAGE_SIZE >> 6

636

637 1: ld t0, 0(a1)

638 ld ta0, 32(a1)

639 ld t2, 16(a1)

640 ld ta2, 48(a1)

641 subu a2, 1

642 ld t1, 8(a1)

643 ld t3, 24(a1)

644 ld ta1, 40(a1)

645 ld ta3, 56(a1)

646

647 sd t0, 0(a0)

648 sd ta0, 32(a0)

649 sd t2, 16(a0)

650 sd ta2, 48(a0)

651 addu a1, 64

652 sd t1, 8(a0)

653 sd t3, 24(a0)

654 sd ta1, 40(a0)

655 sd ta3, 56(a0)

656 bgtz a2,1b

657 addu a0, 64

658 .set pop

659 #else

660 /* o32 */

661 li a2, PAGE_SIZE >> 5

662

663 1: lw t0, 0(a1)

664 lw ta0, 16(a1)

665 subu a2, 1

666 lw t1, 4(a1)

667 lw t2, 8(a1)

668 lw t3, 12(a1)

669 lw ta1, 20(a1)

670 lw ta2, 24(a1)

671 lw ta3, 28(a1)

672

673 sw t0, 0(a0)

674 sw ta0, 16(a0)

675 addu a1, 32

676 sw t1, 4(a0)

677 sw t2, 8(a0)

678 sw t3, 12(a0)

679 sw ta1, 20(a0)

680 sw ta2, 24(a0)

681 sw ta3, 28(a0)

682 bgtz a2,1b

683 addu a0, 32

684 #endif /* __mips_n32 || _LP64 */

685 j ra

686 nop

687 END(mips_pagecopy)

688

689 LEAF(mips_pagezero)

690 /* We can always safely store a 64-bit zero on MIPS3,4,64 */

691 #if !defined(MIPS1) && !defined(MIPS32)

692 .set push

693 .set mips3

694 li a1, PAGE_SIZE >> 6

695

696 1: sd zero, 0(a0) # try to miss cache first

697 sd zero, 32(a0)

698 subu a1, 1

699 sd zero, 16(a0)

700 sd zero, 48(a0)

701 sd zero, 8(a0) # fill in cache lines

702 sd zero, 40(a0)

703 sd zero, 24(a0)

704 sd zero, 56(a0)

705 bgtz a1,1b

706 addu a0, 64

707 .set pop

708 #else

709 /* o32 */

710 li a1, PAGE_SIZE >> 5

711

712 1: sw zero, 0(a0)

713 sw zero, 16(a0) # try to miss cache first

714 subu a1, 1

715 sw zero, 4(a0)

716 sw zero, 8(a0)

717 sw zero, 12(a0)

718 sw zero, 20(a0)

719 sw zero, 24(a0)

720 sw zero, 28(a0)

721 bgtz a1,1b

722 addu a0, 32

723 #endif /* __mips_n32 || _LP64 */

724 j ra

725 nop

726 END(mips_pagezero)

727

728

729 #ifndef DDB_TRACE

730 ^L

731 #if defined(DEBUG) || defined(DDB) || defined(KGDB) || defined(geo) 下面注释已经很多

732 /*

733 * Stacktrace support hooks which use type punnign to access

734 * the caller's registers.

735 */

736

737

738 /*

739 * stacktrace() -- print a stack backtrace to the console.

740 * implicitly accesses caller's a0-a3.

741 */

742 NESTED(stacktrace, CALLFRAME_SIZ+24, ra)

743 XNESTED(logstacktrace)

744 subu sp, sp, CALLFRAME_SIZ+24 # four arg-passing slots

745

746 move t0, ra # save caller's PC

747 addu t1, sp, CALLFRAME_SIZ+24 # compute caller's SP

748 move t2, s8 # non-virtual frame pointer

749

750 la v0, _C_LABEL(printf)

751

752 sw ra, 36(sp) # save return address

753

754 /* a0-a3 are still caller's a0-a3, pass in-place as given. */

755 sw t0, 16(sp) # push caller's PC

756 sw t1, 20(sp) # push caller's SP

757 sw t2, 24(sp) # push caller's FP, in case

758 sw zero, 28(sp) # caller's RA on stack

759 jal _C_LABEL(stacktrace_subr)

760 sw v0, 32(sp) # push printf

761

762 lw ra, 36(sp)

763 addu sp, sp, CALLFRAME_SIZ+24

764 j ra

765 nop

766 END(stacktrace)

767 #endif /* DEBUG || DDB */

768 #endif /* DDB_TRACE */

769

770 .sdata 这里放置一些比较小的数据对象,这样可提高存取效率

771 .globl _C_LABEL(esym)

772 _C_LABEL(esym):

773 .word 0

774

775 .globl _C_LABEL(cpu_id)

776 .globl _C_LABEL(fpu_id)

777 _C_LABEL(cpu_id):

778 .word 0

779 _C_LABEL(fpu_id):

780 .word 0

781

782 #ifdef MIPS_DYNAMIC_STATUS_MASK

783 .globl _C_LABEL(mips_dynamic_status_mask)

784 _C_LABEL(mips_dynamic_status_mask):

785 .word 0xffffffff

786 #endif

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
6 [报告]
发表于 2008-11-11 08:58 |只看该作者
看不太懂。

论坛徽章:
0
7 [报告]
发表于 2008-11-11 12:32 |只看该作者
原帖由 gvim 于 2008-11-11 08:58 发表
看不太懂。


MIPS 汇编,呵呵,而且排版太刺眼了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP