sdk-world v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Loading...
Searching...
No Matches
sio2regs.h
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2009, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9#
10# taken from MX4SIO driver for simplicity.
11# all credits go to maximus32 and qnox
12*/
17#ifndef SIO2REGS_H
18#define SIO2REGS_H
19
20
21// SIO2 registers:
22
23#define SIO2_REL_BASE 0x1F808000
24#define SIO2_SEG 0xA0000000 // Uncached
25#define SIO2_BASE (SIO2_REL_BASE + SIO2_SEG)
26
27#define SIO2_REG_BASE (SIO2_BASE + 0x200)
28#define SIO2_REG_PORT0_CTRL1 (SIO2_BASE + 0x240)
29#define SIO2_REG_PORT0_CTRL2 (SIO2_BASE + 0x244)
30#define SIO2_REG_DATA_OUT (SIO2_BASE + 0x260)
31#define SIO2_REG_DATA_IN (SIO2_BASE + 0x264)
32#define SIO2_REG_CTRL (SIO2_BASE + 0x268)
33#define SIO2_REG_STAT6C (SIO2_BASE + 0x26C)
34#define SIO2_REG_STAT70 (SIO2_BASE + 0x270)
35#define SIO2_REG_STAT74 (SIO2_BASE + 0x274)
36#define SIO2_REG_UNKN78 (SIO2_BASE + 0x278)
37#define SIO2_REG_UNKN7C (SIO2_BASE + 0x27C)
38#define SIO2_REG_STAT (SIO2_BASE + 0x280)
39
40#define SIO2_A_QUEUE (SIO2_BASE + 0x200)
41#define SIO2_A_PORT0_CTRL1 (SIO2_BASE + 0x240)
42#define SIO2_A_PORT0_CTRL2 (SIO2_BASE + 0x244)
43#define SIO2_A_DATA_OUT (SIO2_BASE + 0x260)
44#define SIO2_A_DATA_IN (SIO2_BASE + 0x264)
45#define SIO2_A_CTRL (SIO2_BASE + 0x268)
46#define SIO2_A_STAT6C (SIO2_BASE + 0x26C)
47#define SIO2_A_CONN_STAT70 (SIO2_BASE + 0x270)
48#define SIO2_A_FIFO_STAT74 (SIO2_BASE + 0x274)
49#define SIO2_A_TX_FIFO_PT (SIO2_BASE + 0x278)
50#define SIO2_A_RX_FIFO_PT (SIO2_BASE + 0x27C)
51#define SIO2_A_INTR_STAT (SIO2_BASE + 0x280)
52
53// Bit-field definitions:
54
55/* /ATT (/CS) HIGH between 2 transfers in the SIO2 transfer queue
56* This value is patched to 0x60 on PS2's w/ PPC-IOPs */
57#define PCTRL0_ATT_LOW_PER(x) ((((u32)(x)) << 0) & 0xFF)
58#define PCTRL0_ATT_MIN_HIGH_PER(x) ((((u32)(x)) << 8) & 0xFF00)
59#define PCTRL0_BAUD0_DIV(x) ((((u32)(x)) << 16) & 0xFF0000)
60#define PCTRL0_BAUD1_DIV(x) ((((u32)(x)) << 24) & 0xFF000000)
61
62/* If CTRL_USE_ACK_WAIT_TIMEOUT is 1, this determines how many clock cycles
63 * the SIO2 will wait for an occurence of /ACK low before aborting the current transfer
64
65 * Ex: Clock of 24MHz, period of ~41ns, PCTRL1_ACK_TIMEOUT_AFTER of 50 =
66 41ns * 50 = 2050ns, The SIO2 will wait 2050ns for /ACK low before timing out */
67#define PCTRL1_ACK_TIMEOUT_AFTER(x) ((((u32)(x)) << 0) & 0xFFFF)
68
69/* Note: PCTRL1_WAIT_CYCLES_AFTER_ACK_LOW:
70 * The time between /ACK falling edge -> next /CLK falling edge in clock cycles.
71 * FATs appear to have a ~120ns delay between the rising edge of
72 * the last clock to the start of /ACK low sampling, making the total
73 * time between 2 bytes closer to ~120ns + (WAIT_CYCLES_AFTER_ACK_LOW * clock cycles)
74 *
75 * PS2's w/ PPC-IOPs appear to start /ACK low sampling after 41ns (or 1 * 24MHz clock cycle)
76 * but seem to have a minimum time between the /ACK falling edge -> next /CLK falling edge */
77#define PCTRL1_WAIT_CYCLES_AFTER_ACK_LOW(x) ((((u32)(x)) << 16) & 0xFF0000)
78#define PCTRL1_UNK24(x) ((((u32)(x))&1) << 24)
79#define PCTRL1_IF_MODE_SPI_DIFF(x) ((((u32)(x))&1) << 25)
80
81#define TR_CTRL_PORT_NR(x) ((((u32)(x))&0x3) << 0)
82#define TR_CTRL_PAUSE(x) ((((u32)(x))&1) << 2)
83#define TR_CTRL_UNK03(x) ((((u32)(x))&1) << 3)
84// Each of the folowing is 0 for PIO transfer in the given direction. to select DMA, set to 1.
85#define TR_CTRL_TX_MODE_PIO_DMA(x) ((((u32)(x))&1) << 4)
86#define TR_CTRL_RX_MODE_PIO_DMA(x) ((((u32)(x))&1) << 5)
87/*
88normal special
890 0 no transfer done(???)
901 0 normal transfer - usually used
910 1 "special" transfer (not known to have been ever used by anything, no known difference from normal).
921 1 no transfer takes place
93*/
94#define TR_CTRL_NORMAL_TR(x) (((u32)((x))&1) << 6)
95#define TR_CTRL_SPECIAL_TR(x) (((u32)((x))&1) << 7)
96// In bytes 0 - 0x100:
97#define TR_CTRL_TX_DATA_SZ(x) ((((u32)(x))&0x1FF) << 8)
98#define TR_CTRL_UNK17(x) ((((u32)(x))&1) << 17)
99#define TR_CTRL_RX_DATA_SZ(x) ((((u32)(x))&0x1FF) << 18)
100#define TR_CTRL_UNK27(x) ((((u32)(x))&1) << 27)
101// 28 and 29 can't be set
102#define TR_CTRL_UNK28(x) ((((u32)(x))&1) << 28)
103#define TR_CTRL_UNK29(x) ((((u32)(x))&1) << 29)
104// selects between baud rate divisors 0 and 1
105#define TR_CTRL_BAUD_DIV(x) ((((u32)(x))&1) << 30)
106#define TR_CTRL_WAIT_ACK_FOREVER(x) ((((u32)(x))&1) << 31)
107
108// 8268 SIO2 (main) CTRL register.
109#define CTRL_TR_START(x) ((((u32)(x))&1) << 0)
110#define CTRL_TR_RESUME_PAUSED(x) ((((u32)(x))&1) << 1)
111#define CTRL_RESET_STATE(x) ((((u32)(x))&1) << 2)
112#define CTRL_RESET_FIFOS(x) ((((u32)(x))&1) << 3)
113#define CTRL_USE_ACK_WAIT_TIMEOUT(x) ((((u32)(x))&1) << 4)
114#define CTRL_NO_MISSING_ACK_ERR(x) ((((u32)(x))&1) << 5)
115// bit6 unknonw r/o, 0
116#define CTRL_UNK06(x) ((((u32)(x))&1) << 6)
117// bit7 unknonw r/w, usually set to 1 by software
118#define CTRL_UNK07(x) ((((u32)(x))&1) << 7)
119#define CTRL_ERROR_INTR_EN(x) ((((u32)(x))&1) << 8)
120#define CTRL_TR_COMP_INTR_EN(x) ((((u32)(x))&1) << 9)
121// bits 10, 11 unknonw r/w, usually set to 0 by software
122#define CTRL_UNK10(x) ((((u32)(x))&1) << 10)
123#define CTRL_UNK11(x) ((((u32)(x))&1) << 11)
124// Unknown r/o, 0:
125#define CTRL_UNK2912(x) ((((u32)(x))&0x3FFFF) << 12)
126#define CTRL_PS1_MODE_EN(x) ((((u32)(x))&1) << 30)
127#define CTRL_SLAVE_MODE_EN(x) ((((u32)(x))&1) << 31)
128
129// 826C SIO2 (main) STAT register. (read-only)
130#define STAT_UNK0300(x) ((((u32)(x)) >> 0) & 0xF)
131// Needs more data through DMA to complete transfer:
132#define STAT_NEED_DMA_DATA_TX(x) ((((u32)(x)) >> 4) & 1)
133#define STAT_NEED_DMA_DATA_RX(x) ((((u32)(x)) >> 5) & 1)
134#define STAT_UNK0706(x) ((((u32)(x)) >> 6) & 3)
135// Queue slot number that is going to be processed next (0-15):
136#define STAT_QUEUE_SLOT_PROC(x) ((((u32)(x)) >> 8) & 0xF)
137// Kept clear only while tranfer is running, and set while idle. 1 can also signify transfer completion:
138#define STAT_TR_IDLE(x) ((((u32)(x)) >> 12) & 1)
139// FIFO underflow / overflow errors: (I am not sure if they really correspond to the TX and RX FIFOs)
140#define STAT_ERR_TX_FIFO_UOFLOW(x) ((((u32)(x)) >> 13) & 1)
141#define STAT_ERR_RX_FIFO_UOFLOW(x) ((((u32)(x)) >> 14) & 1)
142#define STAT_ERR_ACK_MISSING(x) ((((u32)(x)) >> 15) & 1)
143// Flags used to determine the transfers of which queue slots triggered erroirs. Slot = 0 - 15:
144#define STAT_ERR_QUEUE_SLOT(x, slot) ((((u32)(x)) >> (slot + 16)) & 1)
145
146// 8270 SIO2 Device connected detection status register. (read-only)
147// For ports 0-3. Only SAS0 and SAS1 are actually connected to the physical port and only on early PS2 models (~ SCPH-30000).
148#define CONN_STAT_CDC0(x) ((((u32)(x)) >> 0) & 1)
149#define CONN_STAT_CDC1(x) ((((u32)(x)) >> 1) & 1)
150#define CONN_STAT_CDC2(x) ((((u32)(x)) >> 2) & 1)
151#define CONN_STAT_CDC3(x) ((((u32)(x)) >> 3) & 1)
152#define CONN_STAT_SAS0(x) ((((u32)(x)) >> 4) & 1)
153#define CONN_STAT_SAS1(x) ((((u32)(x)) >> 5) & 1)
154#define CONN_STAT_SAS2(x) ((((u32)(x)) >> 6) & 1)
155#define CONN_STAT_SAS3(x) ((((u32)(x)) >> 7) & 1)
156
157// 8274 SIO2 FIFO status register. (read-only)
158// values 0 - 0x100 bytes:
159#define FSTAT_TX_SZ(x) ((((u32)(x)) >> 0) & 0x1FF)
160#define FSTAT_TX_UNK09(x) ((((u32)(x)) >> 9) & 1)
161#define FSTAT_TX_OVERFLOW(x) ((((u32)(x)) >> 10) & 1)
162#define FSTAT_TX_UNDERFLOW(x) ((((u32)(x)) >> 11) & 1)
163#define FSTAT_UNK1512(x) ((((u32)(x)) >> 12) & 0xF)
164#define FSTAT_RX_SZ(x) ((((u32)(x)) >> 16) & 0x1FF)
165#define FSTAT_RX_UNK09(x) ((((u32)(x)) >> 25) & 1)
166#define FSTAT_RX_OVERFLOW(x) ((((u32)(x)) >> 26) & 1)
167#define FSTAT_RX_UNDERFLOW(x) ((((u32)(x)) >> 27) & 1)
168#define FSTAT_UNK3128(x) ((((u32)(x)) >> 28) & 0xF)
169
170// 8278 SIO2_REG_UNKN78 TX FIFO pointers. (read/write)
171// #define GET_TXFPNTS_HEAD(x) ((((u32)(x)) >> 0) & 0xFF)
172// #define SET_TXFPNTS_HEAD(x) ((((u32)(x)) >> 0) & 0xFF)
173//...
174// Better not add the FIFO pointers, as to change only one of them would require more complex macros.
175// 827C SIO2_REG_UNKN7C RX FIFO pointers.
176
177// 8280 SIO2_REG_STAT u32 Interrupt status. Writing 1 to an interrupt flag clears it.
178#define GET_ISTAT_TR_COMP(x) ((((u32)(x)) >> 0) & 1)
179// Any error:
180#define GET_ISTAT_TR_ERR(x) ((((u32)(x)) >> 1) & 1)
181
182// Inline (faster) versions of sio2_* functions
183/* 04 */ static inline void inl_sio2_ctrl_set(u32 val) { _sw(val, SIO2_REG_CTRL); }
184/* 05 */ static inline u32 inl_sio2_ctrl_get() { return _lw(SIO2_REG_CTRL); }
185/* 06 */ static inline u32 inl_sio2_stat6c_get() { return _lw(SIO2_REG_STAT6C); }
186/* 07 */ static inline void inl_sio2_portN_ctrl1_set(int N, u32 val) { _sw(val, SIO2_REG_PORT0_CTRL1 + (N * 8)); }
187/* 08 */ static inline u32 inl_sio2_portN_ctrl1_get(int N) { return _lw(SIO2_REG_PORT0_CTRL1 + (N * 8)); }
188/* 09 */ static inline void inl_sio2_portN_ctrl2_set(int N, u32 val) { _sw(val, SIO2_REG_PORT0_CTRL2 + (N * 8)); }
189/* 10 */ static inline u32 inl_sio2_portN_ctrl2_get(int N) { return _lw(SIO2_REG_PORT0_CTRL2 + (N * 8)); }
190/* 11 */ static inline u32 inl_sio2_stat70_get() { return _lw(SIO2_REG_STAT70); }
191/* 12 */ static inline void inl_sio2_regN_set(int N, u32 val) { _sw(val, SIO2_REG_BASE + (N * 4)); }
192/* 13 */ static inline u32 inl_sio2_regN_get(int N) { return _lw(SIO2_REG_BASE + (N * 4)); }
193/* 14 */ static inline u32 inl_sio2_stat74_get() { return _lw(SIO2_REG_STAT74); }
194/* 15 */ static inline void inl_sio2_unkn78_set(u32 val) { _sw(val, SIO2_REG_UNKN78); }
195/* 16 */ static inline u32 inl_sio2_unkn78_get() { return _lw(SIO2_REG_UNKN78); }
196/* 17 */ static inline void inl_sio2_unkn7c_set(u32 val) { _sw(val, SIO2_REG_UNKN7C); }
197/* 18 */ static inline u32 inl_sio2_unkn7c_get() { return _lw(SIO2_REG_UNKN7C); }
198/* 19 */ static inline void inl_sio2_data_out(u8 val) { _sb(val, SIO2_REG_DATA_OUT); }
199/* 20 */ static inline u8 inl_sio2_data_in() { return _lb(SIO2_REG_DATA_IN); }
200/* 21 */ static inline void inl_sio2_stat_set(u32 val) { _sw(val, SIO2_REG_STAT); }
201/* 22 */ static inline u32 inl_sio2_stat_get() { return _lw(SIO2_REG_STAT); }
202
203static inline u16 inl_sio2_data_inh() { return _lh(SIO2_REG_DATA_IN); }
204static inline u32 inl_sio2_data_inw() { return _lw(SIO2_REG_DATA_IN); }
205
206#endif