tcploader addded
[svpe-wii.git] / tcploader / wii / main.c
blob9af35345b98612740aff0d7b37e4bffbb88eeaf0
1 /*-------------------------------------------------------------
3 tcploader -- a very small tcp elf loader for the wii
5 Copyright (C) 2008 Sven Peter
7 This software is provided 'as-is', without any express or implied
8 warranty. In no event will the authors be held liable for any
9 damages arising from the use of this software.
11 Permission is granted to anyone to use this software for any
12 purpose, including commercial applications, and to alter it and
13 redistribute it freely, subject to the following restrictions:
15 1.The origin of this software must not be misrepresented; you
16 must not claim that you wrote the original software. If you use
17 this software in a product, an acknowledgment in the product
18 documentation would be appreciated but is not required.
20 2.Altered source versions must be plainly marked as such, and
21 must not be misrepresented as being the original software.
23 3.This notice may not be removed or altered from any source
24 distribution.
26 -------------------------------------------------------------*/
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ogcsys.h>
32 #include <gccore.h>
33 #include <ogc/ipc.h>
34 #include <network.h>
36 #define READ_SIZE (1 << 10)
38 #include "asm.h"
39 #include "processor.h"
40 #include "elf.h"
41 #include "dol.h"
44 static void *xfb = NULL;
45 static GXRModeObj *rmode = NULL;
47 u8 *data = (u8 *)0x92000000;
49 static inline void wait_for(u32 btn)
51 while(1)
53 PAD_ScanPads();
54 if(PAD_ButtonsHeld(0) & btn)
55 break;
60 extern s32 __STM_Init();
61 extern void __exception_closeall();
62 extern s32 __IOS_ShutdownSubsystems();
64 /* code to establish a socket; originally from bzs@bu-cs.bu.edu
67 int establish(unsigned short portnum) {
68 int s;
69 struct sockaddr_in sa;
71 memset(&sa, 0, sizeof(struct sockaddr_in)); /* clear our address */
72 sa.sin_family= AF_INET; /* this is our host address */
73 sa.sin_port= htons(portnum); /* this is our port number */
74 sa.sin_addr.s_addr = net_gethostip();
75 sa.sin_len = 8;
76 if ((s= net_socket(AF_INET, SOCK_STREAM, 0)) < 0) /* create socket */
77 return(-1);
78 if (net_bind(s,(struct sockaddr *)&sa,8) < 0) {
79 net_close(s);
80 return(-1); /* bind address to socket */
82 net_listen(s, 3); /* max # of queued connects */
83 return(s);
86 // wait for a connection to occur on a socket created with establish()
88 int get_connection(int s)
90 int t; /* socket of connection */
91 struct sockaddr_in sa;
92 sa.sin_len = 8;
93 sa.sin_family = AF_INET;
94 u32 buflen = 8;
95 t = net_accept(s,(struct sockaddr *)&sa, &buflen);
96 printf("Incoming connection from %d.%d.%d.%d\n",
97 (sa.sin_addr.s_addr >> 24) & 0xFF,
98 (sa.sin_addr.s_addr >> 16) & 0xFF,
99 (sa.sin_addr.s_addr >> 8) & 0xFF,
100 (sa.sin_addr.s_addr) & 0xFF);
102 return t;
105 int read_data(int s, /* connected socket */
106 char *buf, /* pointer to the buffer */
107 int n /* number of characters (bytes) we want */
109 { int bcount; /* counts bytes read */
110 int br; /* bytes read this pass */
112 bcount= 0;
113 br= 0;
114 while (bcount < n) { /* loop until full buffer */
115 if ((br= net_read(s,buf,n-bcount)) > 0) {
116 bcount += br; /* increment byte counter */
117 buf += br; /* move buffer ptr for next read */
119 else if (br < 0) /* signal an error to the caller */
120 return br;
122 // debug_printf("read_data(%d, %p, %d): \n", s, buf, n);
123 // printf("read_data(%d, %p, %d): %d\n", s, buf, n, bcount);
124 return bcount;
127 int write_data(int s, char *buf, int n)
129 int bcount;
130 int br;
131 bcount = 0;
132 br = 0;
133 while(bcount < n) {
134 if ((br = net_write(s,buf,n-bcount)) > 0) {
135 bcount += br;
136 buf += br;
138 else if (br < 0)
139 return br;
141 // debug_printf("write_data(%d, %p, %d): \n", s, buf, n);
142 // hexdump(buf, bcount);
143 return (bcount);
146 int main(int argc, char **argv)
148 unsigned long level;
149 u32 res, offset, read, size, ip;
150 u8 *oct = (u8 *)&ip;
151 u8 *bfr[READ_SIZE];
152 void (*ep)();
154 VIDEO_Init();
155 PAD_Init();
157 switch(VIDEO_GetCurrentTvMode())
159 case VI_PAL:
160 rmode = &TVPal528IntDf;
161 break;
162 case VI_MPAL:
163 rmode = &TVMpal480IntDf;
164 default:
165 case VI_NTSC:
166 rmode = &TVNtsc480IntDf;
167 break;
170 xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
171 console_init(xfb, 20, 20, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
173 VIDEO_Configure(rmode);
174 VIDEO_SetBlack(FALSE);
175 VIDEO_SetNextFramebuffer(xfb);
176 VIDEO_Flush();
177 VIDEO_WaitVSync();
178 if(rmode->viTVMode & VI_NON_INTERLACE)
179 VIDEO_WaitVSync();
181 __STM_Init();
183 printf("\n\nTCP ELF Loader\n");
184 printf("(c) 2008 Sven Peter\n");
185 printf("Based on bushing's title_listener.c and his networking code.\n");
186 printf("(c) 2008 bushing\n\n");
188 redo:
189 printf("Press A to continue.\n");
190 wait_for(PAD_BUTTON_A);
192 printf("net_init(), please wait...\n");
193 net_init();
196 printf("Opening socket on port 8080\n");
197 s32 listen = establish(8080);
199 if(listen < 0)
201 printf("establish() returned < 0.\n");
202 goto redo;
205 ip = net_gethostip();
206 printf("fd = %d\n", listen);
207 printf("You Wii's ip address is %d.%d.%d.%d\n", oct[0], oct[1], oct[2], oct[3]);
208 printf("Waiting for connection\n");
209 s32 client = get_connection(listen);
211 if(client > 0)
213 printf("client connected..\n");
215 if(read_data(client, (char *)&size, 4) < 0)
217 printf("read_data() error while reading filesize\n");
218 net_close(client);
219 net_close(listen);
220 goto redo;
223 printf("size: %d\n", size);
224 printf("reading data, please wait...\n");
226 offset = 0;
227 while(offset < size && (read = read_data(client, (char *)bfr, (size - offset) > READ_SIZE ? READ_SIZE : (size - offset))) > 0)
229 memcpy(data + offset, bfr, READ_SIZE);
230 offset += read;
232 net_close(client);
233 net_close(listen);
235 res = valid_elf_image(data);
236 if(res != 1)
238 printf("Invalid ELF image.\n");
239 printf("assuming DOL image. your wii will crash if this is just some random file...\n");
240 ep = (void(*)())load_dol_image(data, 1);
242 else
244 printf("Loading ELF image...\n");
245 ep = (void(*)())load_elf_image(data);
247 printf("entry point: 0x%08X\n", (unsigned int)ep);
248 printf("shutting down...\n");
249 __IOS_ShutdownSubsystems();
250 _CPU_ISR_Disable(level);
251 __exception_closeall();
252 printf("jumping to entry point now...\n\n\n\n");
253 ep();
254 _CPU_ISR_Restore(level);
255 printf("this should not happen :/\n\n");
256 goto redo;
259 // never reached but fixes a gcc warning
260 return 0;