iplleofunc.c
6.94 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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
* F i l e N a m e : i p l l e o f u n c . c
*
****************************************************************************
* (C) Copyright ALPS Electric Co., Ltd. 1995-1996
****************************************************************************
* Version
*
* ver Data
* ---- --------
* 1.08 '96-11-05 Add leoIPLReset(), leoIPLClr_queue() .
* 1.07 '96-10-01 Change LeoIPLdma_que_buf size (1->2) .
* 1.06 '96-09-28 Delete leoIPLDelete() routine .
* 1.05 '96-08-07 Change function name.(leoIPLClr_thread() -> leoIPLDelete() )
* 1.04 '96-07-25 Move ram initialize to iplleocmdex.c .
* Change interruptThread Priority (intpre -> OS_PRIORITY_PIMGR).
* 1.03 '96-06-17 Add leoIPLClr_thread() routine .
* 1.02 '96-02-27 Rename iplcom.c to iplleofunc.c .
* 1.01 '96-02-03 Debug.
* 1.00 '95-12-20 Initial revision .
****************************************************************************
*/
#include "os.h"
#include <ultra64.h>
#include "leodefine.h"
#include "leodrive.h"
#include "iplleomacro.h"
#include "leoappli.h"
/**************************************
* PROTOTYPE DEFINITION
**************************************/
void leoIPLInitialize(OSPri compri, OSPri intpri);
void leoIPLCommand(void *cmd_blk_addr);
void leoIPLReset(void);
void leoIPLClr_queue(void);
/**************************************
* EXTERNALY DEFINITION FUNCTIONS
**************************************/
extern void leoiplMain(void *arg);
extern void leoiplInterrupt(void *arg);
/**************************************
* EXTERNALY DEFINITION RAM LOCATIONS
**************************************/
extern OSThread LeoIPLcommandThread;
extern OSThread LeoIPLinterruptThread;
extern u64 LeoIPLcommandThreadStack[LEO_STACKSIZE/8];
extern u64 LeoIPLinterruptThreadStack[LEO_STACKSIZE/8];
extern OSMesgQueue LeoIPLcommand_que;
extern OSMesgQueue LeoIPLevent_que;
extern OSMesgQueue LeoIPLcontrol_que;
extern OSMesgQueue LeoIPLblock_que;
extern OSMesgQueue LeoIPLdma_que;
extern OSMesg LeoIPLcommand_que_buf[CMD_BLK_Q_SIZE];
extern OSMesg LeoIPLevent_que_buf;
extern OSMesg LeoIPLcontrol_que_buf;
extern OSMesg LeoIPLblock_que_buf;
extern OSMesg LeoIPLdma_que_buf[DMA_Q_SIZE];
extern u8 LeoIPLdrive_flag;
extern volatile u8 LeoIPLclr_que_flag;
extern OSPiHandle *LeoIPLPiInfo;
#define command_block ((LEOCmdHeader *)cmd_blk_addr)
/* ==========================================================================
* Function : leoIPLInitialize
* --------------------------------------------------------------------------
* Description : Initialeze ipl read routine
* --------------------------------------------------------------------------
* IN : non
* 出力変数 : non
* 引数 : compri, intpri
* 戻り値 : 無し
* ==========================================================================
*/
void leoIPLInitialize(OSPri compri, OSPri intpri)
{
/* Create queue */
osCreateMesgQueue(IPLCOMMAND_QUE, &LeoIPLcommand_que_buf[0], CMD_BLK_Q_SIZE);
osCreateMesgQueue(IPLCONTROL_QUE, &LeoIPLcontrol_que_buf, CONTROL_Q_SIZE);
osCreateMesgQueue(IPLEVENT_QUE, &LeoIPLevent_que_buf, EVENT_Q_SIZE);
osCreateMesgQueue(IPLDMA_QUE, &LeoIPLdma_que_buf[0], DMA_Q_SIZE);
osCreateMesgQueue(IPLBLOCK_QUE, &LeoIPLblock_que_buf, BLOCK_Q_SIZE);
/* Create command thread and start */
osCreateThread(&LeoIPLcommandThread, 1, leoiplMain, (void *)0,
(void *)(LeoIPLcommandThreadStack + LeoIPL_STACKSIZE/8), compri);
osStartThread(&LeoIPLcommandThread);
/* Create interrut handling thread and start */
osCreateThread(&LeoIPLinterruptThread, 1, leoiplInterrupt, (void *)0,
(void *)(LeoIPLinterruptThreadStack + LeoIPL_STACKSIZE/8), OS_PRIORITY_PIMGR);
osStartThread(&LeoIPLinterruptThread);
/* Set interrupt to event-que */
osSetEventMesg(OS_EVENT_CART, IPLEVENT_QUE, MES_INTERRUPT);
/* Setup block queue */
osSendMesg(IPLBLOCK_QUE, MES_NONE, OS_MESG_BLOCK);
}
/*===========================================================================
* Function : leoIPLCommand(cmd_blk_addr)
* ---------------------------------------------------------------------------
* Description : Receive command from application and set in commnad queue.
* IN : non
* OUT : non
* ARG : cmd_blk_addr .. top address of commnad block
* RET : non
* =========================================================================*/
void leoIPLCommand(void *cmd_blk_addr)
{
(void)osRecvMesg(IPLBLOCK_QUE, NULL, OS_MESG_BLOCK); /* block que */
/* Init sense code and status in command block */
command_block->status = LEO_STATUS_BUSY;
command_block->sense = LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION;
if (osSendMesg(IPLCOMMAND_QUE, cmd_blk_addr, OS_MESG_NOBLOCK))
{
/* Error if que full */
command_block->sense = LEO_SENSE_QUEUE_FULL;
command_block->status = LEO_STATUS_CHECK_CONDITION;
}
osSendMesg(IPLBLOCK_QUE, MES_NONE, OS_MESG_BLOCK); /* block que */
}
/* ==========================================================================
* Function : leoIPLReset
* --------------------------------------------------------------------------
* Description : Block new command , clear queued command and reset drive.
* --------------------------------------------------------------------------
* IN : non
* OUT : non
* ARG : non
* RET : non
* ==========================================================================
*/
static const u8 zero[1]={0};
void leoIPLReset(void)
{
/* Block new command queing */
(void)osRecvMesg(IPLBLOCK_QUE, NULL, OS_MESG_BLOCK);
/* Clear queued command */
leoiplSet_clr_que_flag();
leoIPLClr_queue();
leoiplClr_clr_que_flag();
(void)osRecvMesg(IPLEVENT_QUE, NULL, OS_MESG_NOBLOCK);
(void)osSendMesg(IPLEVENT_QUE, (OSMesg)MES_NMI_RESET, OS_MESG_BLOCK);
(void)osSendMesg(IPLCOMMAND_QUE, (OSMesg)zero , OS_MESG_NOBLOCK);
}
/* ==========================================================================
* Function : leoIPLClear_queue
* --------------------------------------------------------------------------
* Description : Crear queued command and set status STOP.
* Post que is enable.
* --------------------------------------------------------------------------
* IN : non
* OUT : non
* ARG : non
* RET : non
* ==========================================================================
*/
void leoIPLClr_queue(void)
{
OSMesg temp_command;
/* Clear queued command */
while (!osRecvMesg(IPLCOMMAND_QUE, &temp_command, OS_MESG_NOBLOCK))
{
((LEOCmdHeader *)temp_command)->sense = LEO_SENSE_COMMAND_TERMINATED;
((LEOCmdHeader *)temp_command)->status = LEO_STATUS_CHECK_CONDITION;
if (((LEOCmdHeader *)temp_command)->control & LEO_CONTROL_POST)
{
/* send post message */
osSendMesg(((LEOCmdHeader *)temp_command)->post,
(OSMesg)LEO_SENSE_COMMAND_TERMINATED, OS_MESG_BLOCK);
}
}
}