mgh: fix for default HDD DMA mode, that wasn't correctly set
[open-ps2-loader.git] / modules / debug / udptty / udptty.c
blobf2f4421f4facb868d1d8d1f6472b3b2687d64332
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
10 # $Id: tty.c 629 2004-10-11 00:45:00Z mrbrown $
11 # TTY filesystem for UDPTTY.
13 modified by jimmikaelkael <jimmikaelkael@wanadoo.fr>
17 #include <tamtypes.h>
18 #include <loadcore.h>
19 #include <stdio.h>
20 #include <thsemap.h>
21 #include <ioman.h>
22 #include <intrman.h>
23 #include "intrman_add.h"
24 #include <sysclib.h>
25 #include <sysmem.h>
26 #include <thbase.h>
27 #include <thevent.h>
28 #include <ps2ip.h>
29 #include <errno.h>
31 #define MODNAME "udptty"
32 IRX_ID(MODNAME, 2, 1);
34 struct irx_export_table _exp_udptty;
36 #define DEVNAME "tty"
38 static int udp_socket;
39 static int tty_sema = -1;
41 static int tty_init(iop_device_t *device);
42 static int tty_deinit(iop_device_t *device);
43 static int tty_stdout_fd(void);
44 static int tty_write(iop_file_t *file, void *buf, size_t size);
45 static int tty_error(void);
47 /* device ops */
48 static iop_device_ops_t tty_ops = {
49 tty_init,
50 tty_deinit,
51 (void *)tty_error,
52 (void *)tty_stdout_fd,
53 (void *)tty_stdout_fd,
54 (void *)tty_error,
55 (void *)tty_write,
56 (void *)tty_error,
57 (void *)tty_error,
58 (void *)tty_error,
59 (void *)tty_error,
60 (void *)tty_error,
61 (void *)tty_error,
62 (void *)tty_error,
63 (void *)tty_error,
64 (void *)tty_error,
65 (void *)tty_error
68 /* device descriptor */
69 static iop_device_t tty_device = {
70 DEVNAME,
71 IOP_DT_CHAR|IOP_DT_CONS,
73 "TTY via SMAP UDP",
74 &tty_ops
78 /* KPRTTY */
79 #ifdef KPRTTY
80 #define PRNT_IO_BEGIN 0x200
81 #define PRNT_IO_END 0x201
82 #define EA_SINGLE 0x00
83 #define EA_MULTI 0x02
85 typedef struct _KprArg {
86 int eflag;
87 int bsize;
88 char *kpbuf;
89 int prpos;
90 int calls;
91 } KprArg;
93 KprArg g_kprarg;
95 #define KPR_BUFFER_SIZE 0x1000
96 char kprbuffer[KPR_BUFFER_SIZE];
99 void PrntFunc(void *common, int chr)
101 KprArg *kpa = (KprArg*)common;
103 switch (chr) {
104 case 0:
105 break;
106 case PRNT_IO_BEGIN:
107 kpa->calls ++;
108 break;
109 case PRNT_IO_END:
110 break;
111 case '\n':
112 PrntFunc(common, '\r');
113 default:
114 if (kpa->prpos < kpa->bsize)
115 kpa->kpbuf[kpa->prpos ++] = chr;
116 break;
120 void *Kprnt(void *common, const char *format, void *arg)
122 if (format)
123 prnt((print_callback_t)PrntFunc, common, format, arg);
125 return 0;
128 void *Kprintf_Handler(void *common, const char *format, void *arg)
130 KprArg *kpa = (KprArg*)common;
131 void *res;
133 res = intrman_14(Kprnt, kpa, (void*)format, arg);
135 if (QueryIntrContext())
136 iSetEventFlag(kpa->eflag, 1);
137 else
138 SetEventFlag(kpa->eflag, 1);
140 return res;
143 void KPRTTY_Thread(void *args)
145 u32 flags;
146 KprArg *kpa = (KprArg*)args;
148 while (1) {
149 WaitEventFlag(kpa->eflag, 1, WEF_AND | WEF_CLEAR, &flags);
151 if (kpa->prpos) {
152 if (strncmp(kpa->kpbuf, "WARNING: WaitSema KE_CAN_NOT_WAIT", kpa->prpos-2))
153 write(1, kpa->kpbuf, kpa->prpos);
154 kpa->prpos = 0;
159 void kprtty_init(void)
161 iop_event_t efp;
162 iop_thread_t thp;
163 KprArg *kpa;
164 int thid;
166 kpa = &g_kprarg;
168 efp.attr = EA_SINGLE;
169 efp.option = 0;
170 efp.bits = 0;
172 thp.attr = TH_C;
173 thp.option = 0;
174 thp.thread = (void *)KPRTTY_Thread;
175 thp.stacksize = 0x800;
176 thp.priority = 8;
178 kpa->eflag = CreateEventFlag(&efp);
179 kpa->bsize = KPR_BUFFER_SIZE;
180 kpa->kpbuf = kprbuffer;
181 kpa->prpos = 0;
182 kpa->calls = 0;
184 thid = CreateThread(&thp);
185 StartThread(thid, (void *)kpa);
187 Kprintf_set((kprintf_handler_func_t *)Kprintf_Handler, (u32)kpa);
189 #endif
191 int _start(int argc, char** argv)
193 // register exports
194 RegisterLibraryEntries(&_exp_udptty);
196 // create the socket
197 udp_socket = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
198 if (udp_socket < 0)
199 return MODULE_NO_RESIDENT_END;
201 close(0);
202 close(1);
203 DelDrv(DEVNAME);
205 if (AddDrv(&tty_device) < 0)
206 return MODULE_NO_RESIDENT_END;
208 open(DEVNAME "00:", 0x1000|O_RDWR);
209 open(DEVNAME "00:", O_WRONLY);
211 printf("UDPTTY loaded!\n");
213 #ifdef KPRTTY
214 kprtty_init();
215 printf("KPRTTY enabled!\n");
216 #endif
218 return MODULE_RESIDENT_END;
221 int _shutdown()
223 lwip_close(udp_socket);
225 return 0;
228 /* Copy the data into place, calculate the various checksums, and send the
229 final packet. */
230 static int udp_send(void *buf, size_t size)
232 struct sockaddr_in peer;
234 peer.sin_family = AF_INET;
235 peer.sin_port = htons(18194);
236 peer.sin_addr.s_addr = inet_addr("255.255.255.255");
238 lwip_sendto(udp_socket, buf, size, 0, (struct sockaddr *)&peer, sizeof(peer));
240 return 0;
243 /* TTY driver. */
245 static int tty_init(iop_device_t *device)
247 if ((tty_sema = CreateMutex(IOP_MUTEX_UNLOCKED)) < 0)
248 return -1;
250 return 0;
253 static int tty_deinit(iop_device_t *device)
255 DeleteSema(tty_sema);
256 return 0;
259 static int tty_stdout_fd(void)
261 return 1;
264 static int tty_write(iop_file_t *file, void *buf, size_t size)
266 int res = 0;
268 WaitSema(tty_sema);
269 res = udp_send(buf, size);
270 SignalSema(tty_sema);
272 return res;
275 static int tty_error(void)
277 return -EIO;