/* $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) */