thread4.c
4.04 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <os.h>
#include <os_internal.h>
#include <rmon.h>
#include <R4300.h>
#include "corefunc.h"
/*
* thread4
*
* Tests for:
* Simple interrupt driven context switching
*
* Assumed working:
* __osSetCause
* osSetIntMask
* osGetIntMask
* osStartThread
* osCreateMesgQueue
* osSetEventMesg
* osSendMesg
* osRecvMesg
*
* Description:
* Checks that all CPU and FPU registers are saved correctly on
* a context switch.
*/
#define NUM_SLAVES 2
static void loSlave(void *);
static void hiSlave(void *);
static char loThreadStack[STACKSIZE];
static char hiThreadStack[STACKSIZE];
static OSThread loSlaveThread, hiSlaveThread;
static OSMesgQueue slaveMesgQueue;
static OSMesg slaveMesgBuf[NUM_SLAVES];
OSMesgQueue softintMesgQueue;
static OSMesg softintMesgBuf[1];
int
thread4(void)
{
OSIntMask savedMask, currentMask;
int addFailures, numFailures = 0;
int i;
savedMask = osSetIntMask(OS_IM_NONE);
osCreateMesgQueue(&slaveMesgQueue, slaveMesgBuf, NUM_SLAVES);
osCreateMesgQueue(&softintMesgQueue, softintMesgBuf, 1);
osSetEventMesg(OS_EVENT_SW2, &softintMesgQueue, (OSMesg)0xabcd);
/*
* Give the master (current) thread the highest priority.
*/
osSetThreadPri(NULL, 20);
osCreateThread(&hiSlaveThread, 100, hiSlave, (void *)1,
hiThreadStack+STACKSIZE, (OSPri)20);
osCreateThread(&loSlaveThread, 101, loSlave, (void *)2,
loThreadStack+STACKSIZE, (OSPri)10);
osStartThread(&hiSlaveThread);
osStartThread(&loSlaveThread);
for (i = 0; i < NUM_SLAVES; i++) {
(void)osRecvMesg(&slaveMesgQueue, (OSMesg *)&addFailures,
OS_MESG_BLOCK);
numFailures += addFailures;
}
/*
* Restore original interrupt mask (and check it).
*/
currentMask = osSetIntMask(savedMask);
if (currentMask != OS_IM_NONE) {
osSyncPrintf("thread4: expected interrupt mask 0x%x, actual 0x%x\n",
OS_IM_NONE, currentMask);
numFailures++;
}
return(numFailures);
}
static void
loSlave(void *arg)
{
OSIntMask currentMask;
unsigned int currentSR;
int numFailures = 0;
currentMask = osSetIntMask(OS_IM_NONE);
if (currentMask != OS_IM_ALL) {
osSyncPrintf("thread4: expected interrupt mask 0x%x, actual 0x%x\n",
OS_IM_NONE, currentMask);
numFailures++;
}
/*
* Dirty the registers and then enable the SW interrupt.
* The hiSlave thread below will then run, dirty all of the registers,
* and then complete. When this (the low priority thread) resumes,
* it will then check all of the registers.
*/
if (dirtyAndCheck(((unsigned int)arg)<<16)) {
osSyncPrintf("thread4: registers corrupted\n");
numFailures++;
}
currentMask = osGetIntMask();
if (currentMask != OS_IM_SW2) {
osSyncPrintf("thread4: expected interrupt mask 0x%x, actual 0x%x\n",
OS_IM_SW2, currentMask);
numFailures++;
}
currentSR = __osGetSR();
if ((currentSR & SR_CU1) != SR_CU1) {
osSyncPrintf("thread4: hi expected SR CU1 bit on, was off\n");
numFailures++;
}
osSendMesg(&slaveMesgQueue, (OSMesg)numFailures, OS_MESG_BLOCK);
}
static void
hiSlave(void *arg)
{
OSIntMask currentMask;
unsigned int currentSR;
int numFailures = 0;
currentMask = osSetIntMask(OS_IM_NONE);
if (currentMask != OS_IM_ALL) {
osSyncPrintf("thread4: expected interrupt mask 0x%x, actual 0x%x\n",
OS_IM_NONE, currentMask);
numFailures++;
}
/*
* Trigger a SW2 interrupt that won't be received yet because it is not
* enabled. Call a routine that blocks until the interrupt *is* received,
* and then dirties all of the registers.
*/
__osSetCause(CAUSE_SW2);
waitAndDirty(((unsigned int)arg)<<16);
currentMask = osGetIntMask();
if (currentMask != OS_IM_NONE) {
osSyncPrintf("thread4: expected interrupt mask 0x%x, actual 0x%x\n",
OS_IM_NONE, currentMask);
numFailures++;
}
currentSR = __osGetSR();
if ((currentSR & SR_CU1) != SR_CU1) {
osSyncPrintf("thread4: hi expected SR CU1 bit on, was off\n");
numFailures++;
}
osSendMesg(&slaveMesgQueue, (OSMesg)numFailures, OS_MESG_BLOCK);
}