1/*	$NetBSD: sifbios.h,v 1.6 2016/07/18 22:17:10 maya Exp $	*/
2
3/*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * PlayStation 2 SIF BIOS Version 2.0 define.
34 */
35
36#include <mips/cpuregs.h>
37
38/* SIF BIOS uses SIFDMA_BASE as emulated IOP physical memory base */
39#define SIFDMA_BASE		MIPS_PHYS_TO_KSEG1(0x1c000000)
40#define EEKV_TO_IOPPHYS(a)	((u_int32_t)(a) - SIFDMA_BASE)
41#define IOPPHYS_TO_EEKV(a)	((u_int32_t)(a) + SIFDMA_BASE)
42
43void sifbios_init(void);
44
45/*
46 * System
47 */
48int sifbios_getver(void);
49void sifbios_halt(int);
50void sifbios_setdve(int);
51void sifbios_putchar(int);
52int sifbios_getchar(void);
53
54/*
55 * SIFDMA
56 */
57struct sifdma_transfer {
58	vaddr_t src;	/* (EE) 16byte align */
59	vaddr_t dst;	/* (IOP) 4byte align */
60	vsize_t sz;	/* multiple of 16 */
61	u_int32_t mode;
62#define SIFDMA_MODE_NOINTR		0x0
63#define SIFDMA_MODE_INTR_SENDER		0x2
64#define SIFDMA_MODE_INTR_RECEIVER	0x4
65};
66typedef int sifdma_id_t;
67
68int sifdma_init(void);
69void sifdma_exit(void);
70sifdma_id_t sifdma_queue(struct sifdma_transfer *, int);
71int sifdma_stat(sifdma_id_t);
72void sifdma_reset(void);
73
74/*
75 * SIFCMD
76 */
77typedef u_int32_t sifcmd_sw_t;
78typedef void (*sifcmd_callback_t)(void *, void *);
79struct sifcmd_callback_holder {
80	sifcmd_callback_t func;
81	void *arg;
82} __attribute__((__packed__, __aligned__(4)));
83
84int sifcmd_init(void);
85void sifcmd_exit(void);
86sifdma_id_t sifcmd_queue(sifcmd_sw_t, vaddr_t, size_t, vaddr_t, vaddr_t,
87    vsize_t);
88int sifcmd_intr(void *);
89void sifcmd_establish(sifcmd_sw_t, struct sifcmd_callback_holder *);
90void sifcmd_disestablish(sifcmd_sw_t);
91struct sifcmd_callback_holder *sifcmd_handler_init(
92	struct sifcmd_callback_holder *, int);
93
94/*
95 * SIFRPC
96 */
97#define SIFRPC_NOWAIT			1
98#define SIFRPC_NOCACHEFLUSH		2
99
100#define SIFRPC_ERROR_GETPACKET		1
101#define SIFRPC_ERROR_SENDPACKET		2
102
103/* RPC identifier */
104typedef u_int32_t sifrpc_id_t;
105/* service # */
106typedef u_int32_t sifrpc_callno_t;
107/* server service function */
108typedef void *(*sifrpc_rpcfunc_t)(sifrpc_callno_t, void *, size_t);
109/* callback when RPC service done. */
110typedef void (*sifrpc_endfunc_t)(void *);
111
112/* sifrpc common header */
113struct sifrpc_header {
114	paddr_t packet_paddr;
115	u_int32_t packet_id;
116	void *wait_channel;
117	u_int32_t call_mode;
118} __attribute__((__packed__, __aligned__(4)));
119
120/* receive RPC call */
121struct sifrpc_receive {
122	struct sifrpc_header hdr;
123	void *src;
124	void *dst;
125	size_t sz;
126	sifrpc_endfunc_t end_callback;
127	void *end_callback_arg;
128} __attribute__((__packed__, __aligned__(4)));
129
130/* client */
131struct sifrpc_server;
132
133struct sifrpc_client {
134	struct sifrpc_header hdr;
135	u_int32_t command;
136	void *buf;
137	void *cbuf;
138	sifrpc_endfunc_t end_callback;
139	void *end_callback_arg;
140	struct sifrpc_server *server;
141} __attribute__((__packed__, __aligned__(4)));
142
143/* server */
144struct sifrpc_server_queue;
145
146struct sifrpc_server {
147	u_int32_t command;
148	sifrpc_rpcfunc_t service_func;
149	void *buf;
150	size_t buf_sz;
151	void *cbuf;
152	size_t cbuf_sz;
153	struct sifrpc_client *client;
154	void *paddr;
155	sifrpc_callno_t callno;
156	void *recv;
157	size_t recv_sz;
158	int recv_mode;
159	u_int32_t rid;
160	struct sifrpc_server *link;
161	struct sifrpc_server *next;
162	struct sifrpc_server_receive_queue *head;
163} __attribute__((__packed__, __aligned__(4)));
164
165/* server request queue */
166struct sifrpc_server_system {
167	int active;
168	struct sifrpc_server *link;
169	struct sifrpc_server *head;
170	struct sifrpc_server *last;
171	struct sifrpc_server *next;
172	void *wait_channel;
173	sifrpc_endfunc_t end_callback;
174	void *end_callback_arg;
175} __attribute__((__packed__, __aligned__(4)));
176
177int sifrpc_init(void);
178void sifrpc_exit(void);
179/*
180 * Server side
181 */
182/* register/unregister receive queue to RPC system */
183void sifrpc_establish(struct sifrpc_server_system *, sifrpc_endfunc_t,
184    void *);
185void sifrpc_disestablish(struct sifrpc_server_system *);
186/* queue access */
187struct sifrpc_server *sifrpc_dequeue(struct sifrpc_server_system *);
188
189/* register/unregister service function to receive queue */
190void sifrpc_register_service(struct sifrpc_server_system *,
191    struct sifrpc_server *, sifrpc_id_t, sifrpc_rpcfunc_t, void *,
192    sifrpc_rpcfunc_t, void *);
193void sifrpc_unregister_service(struct sifrpc_server_system *,
194    struct sifrpc_server *);
195/* execute service */
196void sifrpc_dispatch_service(struct sifrpc_server *);
197
198/*
199 * Client side
200 */
201int sifrpc_bind(struct sifrpc_client *, sifrpc_id_t, u_int32_t,
202    sifrpc_endfunc_t, void *);
203int sifrpc_call(struct sifrpc_client *, sifrpc_callno_t, u_int32_t,
204    void *, size_t, void *, size_t, sifrpc_endfunc_t, void *);
205
206/* simple transfer API */
207int sifrpc_receive_buffer(struct sifrpc_receive *, void *, void *, size_t,
208    u_int32_t, sifrpc_endfunc_t, void *);
209
210/* check DMA state */
211int sifrpc_stat(struct sifrpc_header *);
212
213/*
214 * IOP memory management
215 */
216int iopmem_init(void);
217paddr_t iopmem_alloc(psize_t);
218int iopmem_free(paddr_t);
219
220