⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 start.s

📁 UCOS在我的MIPS CPU上的移植 1. 这是UCOS在我的MIPS CPU上的移植代码, 编译工具使用标准的MIPS GCC. 2. 所有CPU相关的代码全在start.S中,相关函数说明如
💻 S
字号:
/*
 * Symbolic register names for 32 bit ABI
 */
#define zero    $0      /* wired zero */
#define AT      $1      /* assembler temp  - uppercase because of ".set at" */
#define v0      $2      /* return value */
#define v1      $3
#define a0      $4      /* argument registers */
#define a1      $5
#define a2      $6
#define a3      $7
#define t0      $8      /* caller saved */
#define t1      $9
#define t2      $10
#define t3      $11
#define t4      $12
#define t5      $13
#define t6      $14
#define t7      $15
#define s0      $16     /* callee saved */
#define s1      $17
#define s2      $18
#define s3      $19
#define s4      $20
#define s5      $21
#define s6      $22
#define s7      $23
#define t8      $24     /* caller saved */
#define t9      $25
#define jp      $25     /* PIC jump register */
#define k0      $26     /* kernel scratch */
#define k1      $27
#define gp      $28     /* global pointer */
#define sp      $29     /* stack pointer */
#define fp      $30     /* frame pointer */
#define s8		$30	/* same like fp! */
#define ra      $31     /* return address */


	.set noreorder

########################################################################################
#
# 上电的引导函数
#
########################################################################################
	.globl _start
	.text
_start:
	bal	1f
	nop
	.word	_GLOBAL_OFFSET_TABLE_ - 1f + 4
1:
	move	gp, ra
	lw	$9, 0(ra)
	nop
	add	gp, $9

#sp -->16k
	la	$25, code_end
	nop
	add	$25, 16384-4-32
	move sp, $25

#free_mem_start
	add $25, 36
	la $24, free_mem_start
	nop
	sw $25, 0($24)

#转到C代码的入口
	la   $25, main #$25 始终等于函数的起始地址
	nop
	jalr $25

#从C代码返回后,终止运行.
	.word	0
	.word	-1	#halt instruct终止指令

########################################################################################
#
# OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
#	建立任务时,保存任务的运行地址和传入参数到堆栈中,
#
# 在 OSStartHighRdy 时,被调度运行.
#
########################################################################################
	.globl	OSTaskStkInit
	.text
OSTaskStkInit:
	sw a0 , -4(a2)		#运行地址
	sw $2 , -8(a2)
	sw $3 , -12(a2)
	sw a1 , -16(a2)		#运行参数
	sw $5 , -20(a2) 
	sw $6 , -24(a2)
	sw $7 , -28(a2)
	sw $8 , -32(a2)
	sw $9 , -36(a2)
	sw $10, -40(a2)
	sw $11, -44(a2)
	sw $12, -48(a2)
	sw $13, -52(a2)
	sw $14, -56(a2)
	sw $15, -60(a2)
	sw $16, -64(a2)
	sw $17, -68(a2)
	sw $18, -72(a2)
	sw $19, -76(a2)
	sw $21, -80(a2)
	sw $22, -84(a2)
	sw $23, -88(a2)
	sw $24, -92(a2)
	sw a0, -96(a2)		#函数地址值,C函数开头计算GP时用
	sw $26, -100(a2)
	sw $27, -104(a2)
	sw $28, -108(a2)
#	sw $29, -112(a2)	#此处的堆栈是 main 处的,在上电时设置的. 与任务的堆栈是不一样的
						#所以不需要保存,在第一次调度时,会切换到任务堆栈的.
	sw $30, -116(a2)
	sw $31, -120(a2)

	jr	ra
	add v0, a2, -120


########################################################################################
#
# void _OSStartHighRdy(OSTCBCur)
# 第一次被调度,
#  OSTCBCur:任务的控制区, 第一个地址是堆栈值,从中恢复寄存器,并跳转到任务开始地址.
#
# 被 OSStartHighRdy 调用, 因为汇编函数不知怎样计算GP值,所以不能引用全局变量.
#
########################################################################################
	.globl	_OSStartHighRdy
	.text
_OSStartHighRdy:
	# a0 --> OSTCBCur
	lw sp , 0(a0)	#sp = OSTCBCur->OSTCBStkPtr
					#切换到任务的堆栈
	nop
	lw $2 , 112(sp)
	lw $3 , 108(sp)
	lw $4 , 104(sp)
	lw $5 , 100(sp) 
	lw $6 , 96(sp)
	lw $7 , 92(sp)
	lw $8 , 88(sp)
	lw $9 , 84(sp)
	lw $10, 80(sp)
	lw $11, 76(sp)
	lw $12, 72(sp)
	lw $13, 68(sp)
	lw $14, 64(sp)
	lw $15, 60(sp)
	lw $16, 56(sp)
	lw $17, 52(sp)
	lw $18, 48(sp)
	lw $19, 44(sp)
	lw $21, 40(sp)
	lw $22, 36(sp)
	lw $23, 32(sp)
	lw $24, 28(sp)
	lw $25, 24(sp)
	lw $26, 20(sp)
	lw $27, 16(sp)
	lw $28, 12(sp)
#	lw $29, 8(sp)
	lw $30, 4(sp)
	lw $31, 0(sp)

	lw	 t9, 116(sp)
	nop
	jr   t9			#第一次进入C函数, 还没有计算出GP的值, $25必须等于函数入口地址,用来计算GP的值
	addi sp, sp, 120

########################################################################################
#
# void OSCtxSw()
# 存储当前任务的寄存器,返回地址是当前的 ra.
# 参数:
#  OSTCBCur:任务的控制区, 第一个地址是堆栈值
#
# 被 OSCtxSw 调用
#
########################################################################################
	.globl	OSCtxSw
	.text
OSCtxSw:
	############################
	# save current task to stack
	############################
	sw ra , -4(sp)	#这个 ra 是任务重新调度时的运行地址(返回到OSCtxSw调用的地方)
	sw $2 , -8(sp)
	sw $3 , -12(sp)
	sw $4 , -16(sp) 
	sw $5 , -20(sp) 
	sw $6 , -24(sp)
	sw $7 , -28(sp)
	sw $8 , -32(sp)
	sw $9 , -36(sp)
	sw $10, -40(sp)
	sw $11, -44(sp)
	sw $12, -48(sp)
	sw $13, -52(sp)
	sw $14, -56(sp)
	sw $15, -60(sp)
	sw $16, -64(sp)
	sw $17, -68(sp)
	sw $18, -72(sp)
	sw $19, -76(sp)
	sw $21, -80(sp)
	sw $22, -84(sp)
	sw $23, -88(sp)
	sw $24, -92(sp)
	sw $25, -96(sp)
	sw $26, -100(sp)
	sw $27, -104(sp)
	sw $28, -108(sp)
#	sw $29, -112(sp)	
	sw $30, -116(sp)	
	sw $31, -120(sp)

	add sp, sp, -120

	############################
	#get gp
	############################
	bal	3f
	nop
	.word	_GLOBAL_OFFSET_TABLE_
3:
	lw	gp, 0(ra)
	nop

	#save sp to task TCB
	la	t0, OSTCBCur	#t0 -> address of OSTCBCur
	nop
	lw	t1, 0(t0)		#t1 -> OSTCBCur
	nop
	sw	sp, 0(t1)

	############################
	# 
	############################
#	OSTaskSwHook();
#	la	t9, OSTaskSwHook
#	jalr t9

#	OSTCBCur = OSTCBHighRdy;
	la	t1, OSTCBHighRdy
	nop
	lw	t2, 0(t1)
	nop
	sw	t2, 0(t0)		#t0 -> address of OSTCBCur
	
	#sp
	lw	sp, 0(t2)		#t2 -> OSTCBCur

#	OSPrioCur = OSPrioHighRdy; 8bit char
	la	t0, OSPrioHighRdy
	nop
	lb	t1, 0(t0)

	la	t2, OSPrioCur
	nop
	sb	t1, 0(t2)

	############################
	# restore new task to running
	############################
	lw $2 , 112(sp)
	lw $3 , 108(sp)
	lw $4 , 104(sp)
	lw $5 , 100(sp) 
	lw $6 , 96(sp)
	lw $7 , 92(sp)
	lw $8 , 88(sp)
	lw $9 , 84(sp)
	lw $10, 80(sp)
	lw $11, 76(sp)
	lw $12, 72(sp)
	lw $13, 68(sp)
	lw $14, 64(sp)
	lw $15, 60(sp)
	lw $16, 56(sp)
	lw $17, 52(sp)
	lw $18, 48(sp)
	lw $19, 44(sp)
	lw $21, 40(sp)
	lw $22, 36(sp)
	lw $23, 32(sp)
	lw $24, 28(sp)
	lw $25, 24(sp)
	lw $26, 20(sp)
	lw $27, 16(sp)
	lw $28, 12(sp)
#	lw $29, 8(sp)
	lw $30, 4(sp)
	lw $31, 0(sp)

	lw	 k1, 116(sp)
	nop
	jr   k1				#此处不能用$25,要保留中断前的一切寄存器
	addi sp, sp, 120

########################################################################################
#
# void isr_service()
#
# 中断入口函数
#
#
########################################################################################
	.globl	isr_service
	.text
isr_service:
	##################
	# save all regs
	##################
	sw $2 , -8(sp)
	sw $3 , -12(sp)
	sw $4 , -16(sp) 
	sw $5 , -20(sp) 
	sw $6 , -24(sp)
	sw $7 , -28(sp)
	sw $8 , -32(sp)
	sw $9 , -36(sp)
	sw $10, -40(sp)
	sw $11, -44(sp)
	sw $12, -48(sp)
	sw $13, -52(sp)
	sw $14, -56(sp)
	sw $15, -60(sp)
	sw $16, -64(sp)
	sw $17, -68(sp)
	sw $18, -72(sp)
	sw $19, -76(sp)
	sw $21, -80(sp)
	sw $22, -84(sp)
	sw $23, -88(sp)
	sw $24, -92(sp)
	sw $25, -96(sp)
	sw $26, -100(sp)
	sw $27, -104(sp)
	sw $28, -108(sp)
#	sw $29, -112(sp)	
	sw $30, -116(sp)	
	sw $31, -120(sp)

	#返回地址(被中断的任务地址) cp0_epc
	mfc0	ra, $14	#CP0_EPC $14
	sw ra , -4(sp) #运行地址

	add sp, sp, -120

	##############################
	#get gp
	##############################
	bal	3f
	nop
	.word	_GLOBAL_OFFSET_TABLE_
3:
	lw	gp, 0(ra)
	nop

	##############################
	# call isr_service_wrap
	##############################
	la	t9, isr_service_wrap
	nop
	jalr	t9
	nop

	############################
	# restore new task to running
	############################
	lw $2 , 112(sp)
	lw $3 , 108(sp)
	lw $4 , 104(sp)
	lw $5 , 100(sp) 
	lw $6 , 96(sp)
	lw $7 , 92(sp)
	lw $8 , 88(sp)
	lw $9 , 84(sp)
	lw $10, 80(sp)
	lw $11, 76(sp)
	lw $12, 72(sp)
	lw $13, 68(sp)
	lw $14, 64(sp)
	lw $15, 60(sp)
	lw $16, 56(sp)
	lw $17, 52(sp)
	lw $18, 48(sp)
	lw $19, 44(sp)
	lw $21, 40(sp)
	lw $22, 36(sp)
	lw $23, 32(sp)
	lw $24, 28(sp)
	lw $25, 24(sp)
	lw $26, 20(sp)
	lw $27, 16(sp)
	lw $28, 12(sp)
#	lw $29, 8(sp)
	lw $30, 4(sp)
	lw $31, 0(sp)
	
	############################
	#中断处理完成, 返回到被中断的地方
	############################
	lw		k1, 116(sp)		#此处不能用$25,要保留中断前的一切寄存器
	nop
	jr		k1
	add		sp, sp, 120

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -