summaryrefslogtreecommitdiffstats
path: root/zpu/sw/freertos/port/portasm.s
blob: 29c41ab99bb7aba3f5c7cd7b9e0cf7fd23e2fd23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	.extern pxCurrentTCB
	.extern vTaskISRHandler
	.extern vTaskSwitchContext
	.extern uxCriticalNesting
	.extern pulISRStack

	.global __FreeRTOS_interrupt_handler
	.global VPortYieldASM
	.global vStartFirstTask

/* interrupt controller port */
	.equ INTERRUPT_ENABLE,0x8020

.macro portSAVE_CONTEXT
	/* PC is at the top of stack */
	
	/* store interrupt global enable bit */
	im INTERRUPT_ENABLE
	load
	im 1
	and
	
	/* Store nesting critical level */
	im uxCriticalNesting
	load
	
	/* Store temporary registers */
	im 0
	load			/* store mem[0] */
	im 4
	load			/* store mem[4] */
	im 8
	load			/* store mem[8] */
	im 12
	load			/* store mem[12] */
	
	/* Store top of stack at pxCurrentTCB */
	pushsp
	im pxCurrentTCB
	load
	store
.endm

.macro portRESTORE_CONTEXT
	im pxCurrentTCB		/* Load the top of stack value from the TCB. */
	load
	load
	popsp
	
	/* Restore the temporary registers. */
	im 12
	store				/* restore mem[12] */
	im 8
	store				/* restore mem[8] */
	im 4
	store				/* restore mem[4] */
	im 0
	store				/* restore mem[0] */

	/* Load the critical nesting value. */
	im uxCriticalNesting
	store

	/* Set interrupt global enable status */
	im INTERRUPT_ENABLE
	load
	im ~1
	and
	or
	im INTERRUPT_ENABLE
	store

	/* restore PC and enable interrupts at ZPU level */
	.byte 0x03			/* popint */
.endm

.macro portRESTORE_CONTEXT_NOINTERRUPT
	im pxCurrentTCB		/* Load the top of stack value from the TCB. */
	load
	load
	popsp
	
	/* Restore the temporary registers. */
	im 12
	store				/* restore mem[12] */
	im 8
	store				/* restore mem[8] */
	im 4
	store				/* restore mem[4] */
	im 0
	store				/* restore mem[0] */

	/* Load the critical nesting value. */
	im uxCriticalNesting
	store

	/* Set interrupt global enable status */
	im INTERRUPT_ENABLE
	load
	im ~1
	and
	or
	im INTERRUPT_ENABLE
	store

	/* restore PC */
	poppc
.endm

	.text
	.align  2

__FreeRTOS_interrupt_handler:
	portSAVE_CONTEXT

	/* Now switch to use the ISR stack. */
	im pulISRStack
	load
	popsp

	/* Call function */
	im vTaskISRHandler
	call

	portRESTORE_CONTEXT

VPortYieldASM:
	portSAVE_CONTEXT

	/* Now switch to use the ISR stack. */
	im pulISRStack
	load
	popsp

	/* Call function to switch context */
	im vTaskSwitchContext
	call

	portRESTORE_CONTEXT_NOINTERRUPT

vStartFirstTask:
	portRESTORE_CONTEXT_NOINTERRUPT
OpenPOWER on IntegriCloud