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
191
192
193
194
195
196
197
198
199
200
|
/* $NetBSD: iopreg.h,v 1.7 2005/12/11 12:18:03 christos Exp $ */
/*
* Copyright (c) 2000 Allen Briggs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define IOP1_BASE 0x00004000
#define SCC_IOP 0
#define ISM_IOP 1
#define IOP_CS_BYPASS 0x01
#define IOP_CS_AUTOINC 0x02
#define IOP_CS_RUN 0x04
#define IOP_CS_IRQ 0x08
#define IOP_CS_INT0 0x10
#define IOP_CS_INT1 0x20
#define IOP_CS_HWINT 0x40
#define IOP_CS_DMAINACT 0x80
#define IOP_RESET (IOP_CS_DMAINACT | IOP_CS_AUTOINC)
#define IOP_BYPASS \
(IOP_CS_BYPASS | IOP_CS_AUTOINC | IOP_CS_RUN | IOP_CS_DMAINACT)
#define IOP_INTERRUPT (IOP_CS_INT0 | IOP_CS_INT1)
#define OSS_INTLEVEL_OFFSET 0x0001A006
typedef struct {
volatile u_char ram_hi;
u_char pad0;
volatile u_char ram_lo;
u_char pad1;
volatile u_char control_status;
u_char pad2[3];
volatile u_char data;
u_char pad3[23];
union {
struct {
volatile u_char sccb_cmd;
u_char pad0;
volatile u_char scca_cmd;
u_char pad1;
volatile u_char sccb_data;
u_char pad2;
volatile u_char scca_data;
u_char pad3;
} scc;
struct {
volatile u_char wdata;
u_char pad0;
/* etc... */
} iwm;
} bypass;
} IOPHW;
#define IOP_MAXCHAN 7
#define IOP_MAXMSG 8
#define IOP_MSGLEN 32
#define IOP_MSGBUFLEN (IOP_MSGLEN * IOP_MAXCHAN)
#define IOP_MSG_IDLE 0 /* idle */
#define IOP_MSG_NEW 1 /* new message sent */
#define IOP_MSG_RECEIVED 2 /* message received; processing */
#define IOP_MSG_COMPLETE 3 /* message processing complete */
#define IOP_ADDR_MAX_SEND_CHAN 0x200
#define IOP_ADDR_SEND_STATE 0x201
#define IOP_ADDR_PATCH_CTRL 0x21F
#define IOP_ADDR_SEND_MSG 0x220
#define IOP_ADDR_MAX_RECV_CHAN 0x300
#define IOP_ADDR_RECV_STATE 0x301
#define IOP_ADDR_ALIVE 0x31F
#define IOP_ADDR_RECV_MSG 0x320
typedef struct {
u_char pad1[0x200];
u_char max_send_chan; /* maximum send channel # */
u_char send_state[IOP_MAXCHAN]; /* send channel states */
u_char pad2[23];
u_char patch_ctrl; /* patch control flag */
u_char send_msg[IOP_MSGBUFLEN]; /* send channel message data */
u_char max_recv_chan; /* max. receive channel # */
u_char recv_state[IOP_MAXCHAN]; /* receive channel states */
u_char pad3[23];
u_char alive; /* IOP alive flag */
u_char recv_msg[IOP_MSGBUFLEN]; /* receive channel msg data */
} IOPK;
struct iop_msg;
struct _s_IOP;
typedef void (*iop_msg_handler)(struct _s_IOP *iop, struct iop_msg *);
struct iop_msg {
SIMPLEQ_ENTRY(iop_msg) iopm;
int channel;
int status;
u_char msg[IOP_MSGLEN];
/* The routine that will handle the message */
iop_msg_handler handler;
void *user_data;
};
#define IOP_MSGSTAT_IDLE 0 /* Message unused (invalid) */
#define IOP_MSGSTAT_QUEUED 1 /* Message queued for send */
#define IOP_MSGSTAT_SENDING 2 /* Message on IOP */
#define IOP_MSGSTAT_SENT 3 /* Message complete */
#define IOP_MSGSTAT_RECEIVING 4 /* Top of receive queue */
#define IOP_MSGSTAT_RECEIVED 5 /* Msg received */
#define IOP_MSGSTAT_UNEXPECTED 6 /* Unexpected msg received */
typedef struct _s_IOP {
IOPHW *iop;
struct pool pool;
SIMPLEQ_HEAD(, iop_msg) sendq[IOP_MAXCHAN];
SIMPLEQ_HEAD(, iop_msg) recvq[IOP_MAXCHAN];
iop_msg_handler listeners[IOP_MAXCHAN];
void *listener_data[IOP_MAXCHAN];
struct iop_msg unsolicited_msg;
} IOP;
#define IOP_LOADADDR(ioph,addr) (ioph->ram_lo = addr & 0xff, \
ioph->ram_hi = (addr >> 8) & 0xff)
void iop_init(int);
void iop_upload(int, u_char *, u_long, u_long);
void iop_download(int, u_char *, u_long, u_long);
int iop_send_msg(int, int, u_char *, int, iop_msg_handler, void *);
int iop_queue_receipt(int, int, iop_msg_handler, void *);
int iop_register_listener(int, int, iop_msg_handler, void *);
/* SWIM support */
#define IOP_CHAN_SWIM 1
#define IOP_SWIM_INITIALIZE 0x01
#define IOP_SWIM_SHUTDOWN 0x02
#define IOP_SWIM_START_POLLING 0x03
#define IOP_SWIM_STOP_POLLING 0x04
#define IOP_SWIM_SET_HFS_TAG_ADDR 0x05
#define IOP_SWIM_DRIVE_STATUS 0x06
#define IOP_SWIM_EJECT 0x07
#define IOP_SWIM_FORMAT 0x08
#define IOP_SWIM_FORMAT_VERIFY 0x09
#define IOP_SWIM_WRITE 0x0a
#define IOP_SWIM_READ 0x0b
#define IOP_SWIM_READ_VERIFY 0x0c
#define IOP_SWIM_CACHE_CONTROL 0x0d
#define IOP_SWIM_TAG_BUFFER_CONTROL 0x0e
#define IOP_SWIM_GET_ICON 0x0f
#define IOP_SWIM_DISK_DUP_INFO 0x10
#define IOP_SWIM_GET_RAW_DATA 0x11
/*
* The structure of a SWIM packet to/from the IOP is:
* Request kind
* Drive Number (if needed)
* Error Code
* Data (optional)
*/
/* ADB support */
#define IOP_CHAN_ADB 2
#define IOP_ADB_FL_EXPLICIT 0x80 /* Non-zero if explicit command */
#define IOP_ADB_FL_AUTOPOLL 0x40 /* Auto/SRQ polling enabled */
#define IOP_ADB_FL_POLL_UPDATE 0x20 /* Update polling bit mask */
#define IOP_ADB_FL_SRQ 0x04 /* SRQ detected */
#define IOP_ADB_FL_TIMEOUT 0x02 /* Non-zero if timeout */
/*
* The structure of an ADB packet to/from the IOP is:
* Flag byte (values above)
* Count of bytes in data
* Command byte
* Data (optional)
*/
|