1 #define LOAD_DEBUG	0
2 
3 static int get_x_header(unsigned char *data, unsigned long now);
4 static void jump_2ep();
5 static unsigned char ce_signature[] = {'B', '0', '0', '0', 'F', 'F', '\n',};
6 static char ** ep;
7 
8 #define BOOT_ARG_PTR_LOCATION 0x001FFFFC
9 
10 typedef struct _BOOT_ARGS{
11 	unsigned char ucVideoMode;
12 	unsigned char ucComPort;
13 	unsigned char ucBaudDivisor;
14 	unsigned char ucPCIConfigType;
15 
16 	unsigned long dwSig;
17 	#define BOOTARG_SIG 0x544F4F42
18 	unsigned long dwLen;
19 
20 	unsigned char ucLoaderFlags;
21 	unsigned char ucEshellFlags;
22 	unsigned char ucEdbgAdapterType;
23 	unsigned char ucEdbgIRQ;
24 
25 	unsigned long dwEdbgBaseAddr;
26 	unsigned long dwEdbgDebugZone;
27 	unsigned long dwDHCPLeaseTime;
28 	unsigned long dwEdbgFlags;
29 
30 	unsigned long dwEBootFlag;
31 	unsigned long dwEBootAddr;
32 	unsigned long dwLaunchAddr;
33 
34 	unsigned long pvFlatFrameBuffer;
35 	unsigned short vesaMode;
36 	unsigned short cxDisplayScreen;
37 	unsigned short cyDisplayScreen;
38 	unsigned short cxPhysicalScreen;
39 	unsigned short cyPhysicalScreen;
40 	unsigned short cbScanLineLength;
41 	unsigned short bppScreen;
42 
43 	unsigned char RedMaskSize;
44 	unsigned char REdMaskPosition;
45 	unsigned char GreenMaskSize;
46 	unsigned char GreenMaskPosition;
47 	unsigned char BlueMaskSize;
48 	unsigned char BlueMaskPosition;
49 } BOOT_ARGS;
50 
51 BOOT_ARGS BootArgs;
52 
53 static struct segment_info{
54 	unsigned long addr;		// Section Address
55 	unsigned long size;		// Section Size
56 	unsigned long checksum;		// Section CheckSum
57 } X;
58 
59 #define PSIZE	(1500)			//Max Packet Size
60 #define DSIZE  (PSIZE+12)
61 static unsigned long dbuffer_available =0;
62 static unsigned long not_loadin =0;
63 static unsigned long d_now =0;
64 
65 unsigned long entry;
66 static unsigned long ce_curaddr;
67 
68 
69 static sector_t ce_loader(unsigned char *data, unsigned int len, int eof);
wince_probe(unsigned char * data,unsigned int len)70 static os_download_t wince_probe(unsigned char *data, unsigned int len)
71 {
72 	if (strncmp(ce_signature, data, sizeof(ce_signature)) != 0) {
73 		return 0;
74 	}
75 	printf("(WINCE)");
76 	return ce_loader;
77 }
78 
ce_loader(unsigned char * data,unsigned int len,int eof)79 static sector_t ce_loader(unsigned char *data, unsigned int len, int eof)
80 {
81 	static unsigned char dbuffer[DSIZE];
82 	int this_write = 0;
83 	static int firsttime = 1;
84 
85 	/*
86 	 *	new packet in, we have to
87 	 *	[1] copy data to dbuffer,
88 	 *
89 	 *	update...
90 	 *	[2]  dbuffer_available
91 	 */
92 	memcpy( (dbuffer+dbuffer_available), data, len);	//[1]
93 	dbuffer_available += len;	// [2]
94 	len = 0;
95 
96 	d_now = 0;
97 
98 #if 0
99 	printf("dbuffer_available =%ld \n", dbuffer_available);
100 #endif
101 
102 	if (firsttime)
103 	{
104 		d_now = sizeof(ce_signature);
105 		printf("String Physical Address = %lx \n",
106 			*(unsigned long *)(dbuffer+d_now));
107 
108 		d_now += sizeof(unsigned long);
109 		printf("Image Size = %ld [%lx]\n",
110 			*(unsigned long *)(dbuffer+d_now),
111 			*(unsigned long *)(dbuffer+d_now));
112 
113 		d_now += sizeof(unsigned long);
114 		dbuffer_available -= d_now;
115 
116 		d_now = (unsigned long)get_x_header(dbuffer, d_now);
117 		firsttime = 0;
118 	}
119 
120 	if (not_loadin == 0)
121 	{
122 		d_now = get_x_header(dbuffer, d_now);
123 	}
124 
125 	while ( not_loadin > 0 )
126 	{
127 		/* dbuffer do not have enough data to loading, copy all */
128 #if LOAD_DEBUG
129 		printf("[0] not_loadin = [%ld], dbuffer_available = [%ld] \n",
130 			not_loadin, dbuffer_available);
131 		printf("[0] d_now = [%ld] \n", d_now);
132 #endif
133 
134 		if( dbuffer_available <= not_loadin)
135 		{
136 			this_write = dbuffer_available ;
137 			memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write );
138 			ce_curaddr += this_write;
139 			not_loadin -= this_write;
140 
141 			/* reset index and available in the dbuffer */
142 			dbuffer_available = 0;
143 			d_now = 0;
144 #if LOAD_DEBUG
145 			printf("[1] not_loadin = [%ld], dbuffer_available = [%ld] \n",
146 				not_loadin, dbuffer_available);
147 			printf("[1] d_now = [%ld], this_write = [%d] \n",
148 				d_now, this_write);
149 #endif
150 
151 			// get the next packet...
152 			return (0);
153 		}
154 
155 		/* dbuffer have more data then loading ... , copy partital.... */
156 		else
157 		{
158 			this_write = not_loadin;
159 			memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write);
160 			ce_curaddr += this_write;
161 			not_loadin = 0;
162 
163 			/* reset index and available in the dbuffer */
164 			dbuffer_available -= this_write;
165 			d_now += this_write;
166 #if LOAD_DEBUG
167 			printf("[2] not_loadin = [%ld], dbuffer_available = [%ld] \n",
168 				not_loadin, dbuffer_available);
169 			printf("[2] d_now = [%ld], this_write = [%d] \n\n",
170 				d_now, this_write);
171 #endif
172 
173 			/* dbuffer not empty, proceed processing... */
174 
175 			// don't have enough data to get_x_header..
176 			if ( dbuffer_available < (sizeof(unsigned long) * 3) )
177 			{
178 //				printf("we don't have enough data remaining to call get_x. \n");
179 				memcpy( (dbuffer+0), (dbuffer+d_now), dbuffer_available);
180 				return (0);
181 			}
182 			else
183 			{
184 #if LOAD_DEBUG
185 				printf("with remaining data to call get_x \n");
186 				printf("dbuffer available = %ld , d_now = %ld\n",
187 					dbuffer_available, d_now);
188 #endif
189 				d_now = get_x_header(dbuffer, d_now);
190 			}
191 		}
192 	}
193 	return (0);
194 }
195 
get_x_header(unsigned char * dbuffer,unsigned long now)196 static int get_x_header(unsigned char *dbuffer, unsigned long now)
197 {
198 	X.addr = *(unsigned long *)(dbuffer + now);
199 	X.size = *(unsigned long *)(dbuffer + now + sizeof(unsigned long));
200 	X.checksum = *(unsigned long *)(dbuffer + now + sizeof(unsigned long)*2);
201 
202 	if (X.addr == 0)
203 	{
204 		entry = X.size;
205 		done(1);
206 		printf("Entry Point Address = [%lx] \n", entry);
207 		jump_2ep();
208 	}
209 
210 	if (!prep_segment(X.addr, X.addr + X.size, X.addr + X.size, 0, 0)) {
211 		longjmp(restart_etherboot, -2);
212 	}
213 
214 	ce_curaddr = X.addr;
215 	now += sizeof(unsigned long)*3;
216 
217 	/* re-calculate dbuffer available... */
218 	dbuffer_available -= sizeof(unsigned long)*3;
219 
220 	/* reset index of this section */
221 	not_loadin = X.size;
222 
223 #if 1
224 	printf("\n");
225 	printf("\t Section Address = [%lx] \n", X.addr);
226 	printf("\t Size = %d [%lx]\n", X.size, X.size);
227 	printf("\t Checksum = %ld [%lx]\n", X.checksum, X.checksum);
228 #endif
229 #if LOAD_DEBUG
230 	printf("____________________________________________\n");
231 	printf("\t dbuffer_now = %ld \n", now);
232 	printf("\t dbuffer available = %ld \n", dbuffer_available);
233 	printf("\t not_loadin = %ld \n", not_loadin);
234 #endif
235 
236 	return now;
237 }
238 
jump_2ep()239 static void jump_2ep()
240 {
241 	BootArgs.ucVideoMode = 1;
242 	BootArgs.ucComPort = 1;
243 	BootArgs.ucBaudDivisor = 1;
244 	BootArgs.ucPCIConfigType = 1;	// do not fill with 0
245 
246 	BootArgs.dwSig = BOOTARG_SIG;
247 	BootArgs.dwLen = sizeof(BootArgs);
248 
249 	if(BootArgs.ucVideoMode == 0)
250 	{
251 		BootArgs.cxDisplayScreen = 640;
252 		BootArgs.cyDisplayScreen = 480;
253 		BootArgs.cxPhysicalScreen = 640;
254 		BootArgs.cyPhysicalScreen = 480;
255 		BootArgs.bppScreen = 16;
256 		BootArgs.cbScanLineLength  = 1024;
257 		BootArgs.pvFlatFrameBuffer = 0x800a0000;	// ollie say 0x98000000
258 	}
259 	else if(BootArgs.ucVideoMode != 0xFF)
260 	{
261 		BootArgs.cxDisplayScreen = 0;
262 		BootArgs.cyDisplayScreen = 0;
263 		BootArgs.cxPhysicalScreen = 0;
264 		BootArgs.cyPhysicalScreen = 0;
265 		BootArgs.bppScreen = 0;
266 		BootArgs.cbScanLineLength  = 0;
267 		BootArgs.pvFlatFrameBuffer = 0;
268 	}
269 
270 	ep = phys_to_virt(BOOT_ARG_PTR_LOCATION);
271 	*ep= virt_to_phys(&BootArgs);
272 	xstart32(entry);
273 }
274