00001 #define LOAD_DEBUG 0
00002
00003 static int get_x_header(unsigned char *data, unsigned long now);
00004 static void jump_2ep();
00005 static unsigned char ce_signature[] = {'B', '0', '0', '0', 'F', 'F', '\n',};
00006 static char ** ep;
00007
00008 #define BOOT_ARG_PTR_LOCATION 0x001FFFFC
00009
00010 typedef struct _BOOT_ARGS{
00011 unsigned char ucVideoMode;
00012 unsigned char ucComPort;
00013 unsigned char ucBaudDivisor;
00014 unsigned char ucPCIConfigType;
00015
00016 unsigned long dwSig;
00017 #define BOOTARG_SIG 0x544F4F42
00018 unsigned long dwLen;
00019
00020 unsigned char ucLoaderFlags;
00021 unsigned char ucEshellFlags;
00022 unsigned char ucEdbgAdapterType;
00023 unsigned char ucEdbgIRQ;
00024
00025 unsigned long dwEdbgBaseAddr;
00026 unsigned long dwEdbgDebugZone;
00027 unsigned long dwDHCPLeaseTime;
00028 unsigned long dwEdbgFlags;
00029
00030 unsigned long dwEBootFlag;
00031 unsigned long dwEBootAddr;
00032 unsigned long dwLaunchAddr;
00033
00034 unsigned long pvFlatFrameBuffer;
00035 unsigned short vesaMode;
00036 unsigned short cxDisplayScreen;
00037 unsigned short cyDisplayScreen;
00038 unsigned short cxPhysicalScreen;
00039 unsigned short cyPhysicalScreen;
00040 unsigned short cbScanLineLength;
00041 unsigned short bppScreen;
00042
00043 unsigned char RedMaskSize;
00044 unsigned char REdMaskPosition;
00045 unsigned char GreenMaskSize;
00046 unsigned char GreenMaskPosition;
00047 unsigned char BlueMaskSize;
00048 unsigned char BlueMaskPosition;
00049 } BOOT_ARGS;
00050
00051 BOOT_ARGS BootArgs;
00052
00053 static struct segment_info{
00054 unsigned long addr;
00055 unsigned long size;
00056 unsigned long checksum;
00057 } X;
00058
00059 #define PSIZE (1500) //Max Packet Size
00060 #define DSIZE (PSIZE+12)
00061 static unsigned long dbuffer_available =0;
00062 static unsigned long not_loadin =0;
00063 static unsigned long d_now =0;
00064
00065 unsigned long entry;
00066 static unsigned long ce_curaddr;
00067
00068
00069 static sector_t ce_loader(unsigned char *data, unsigned int len, int eof);
00070 static os_download_t wince_probe(unsigned char *data, unsigned int len)
00071 {
00072 if (strncmp(ce_signature, data, sizeof(ce_signature)) != 0) {
00073 return 0;
00074 }
00075 printf("(WINCE)");
00076 return ce_loader;
00077 }
00078
00079 static sector_t ce_loader(unsigned char *data, unsigned int len, int eof)
00080 {
00081 static unsigned char dbuffer[DSIZE];
00082 int this_write = 0;
00083 static int firsttime = 1;
00084
00085
00086
00087
00088
00089
00090
00091
00092 memcpy( (dbuffer+dbuffer_available), data, len);
00093 dbuffer_available += len;
00094 len = 0;
00095
00096 d_now = 0;
00097
00098 #if 0
00099 printf("dbuffer_available =%ld \n", dbuffer_available);
00100 #endif
00101
00102 if (firsttime)
00103 {
00104 d_now = sizeof(ce_signature);
00105 printf("String Physical Address = %lx \n",
00106 *(unsigned long *)(dbuffer+d_now));
00107
00108 d_now += sizeof(unsigned long);
00109 printf("Image Size = %ld [%lx]\n",
00110 *(unsigned long *)(dbuffer+d_now),
00111 *(unsigned long *)(dbuffer+d_now));
00112
00113 d_now += sizeof(unsigned long);
00114 dbuffer_available -= d_now;
00115
00116 d_now = (unsigned long)get_x_header(dbuffer, d_now);
00117 firsttime = 0;
00118 }
00119
00120 if (not_loadin == 0)
00121 {
00122 d_now = get_x_header(dbuffer, d_now);
00123 }
00124
00125 while ( not_loadin > 0 )
00126 {
00127
00128 #if LOAD_DEBUG
00129 printf("[0] not_loadin = [%ld], dbuffer_available = [%ld] \n",
00130 not_loadin, dbuffer_available);
00131 printf("[0] d_now = [%ld] \n", d_now);
00132 #endif
00133
00134 if( dbuffer_available <= not_loadin)
00135 {
00136 this_write = dbuffer_available ;
00137 memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write );
00138 ce_curaddr += this_write;
00139 not_loadin -= this_write;
00140
00141
00142 dbuffer_available = 0;
00143 d_now = 0;
00144 #if LOAD_DEBUG
00145 printf("[1] not_loadin = [%ld], dbuffer_available = [%ld] \n",
00146 not_loadin, dbuffer_available);
00147 printf("[1] d_now = [%ld], this_write = [%d] \n",
00148 d_now, this_write);
00149 #endif
00150
00151
00152 return (0);
00153 }
00154
00155
00156 else
00157 {
00158 this_write = not_loadin;
00159 memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write);
00160 ce_curaddr += this_write;
00161 not_loadin = 0;
00162
00163
00164 dbuffer_available -= this_write;
00165 d_now += this_write;
00166 #if LOAD_DEBUG
00167 printf("[2] not_loadin = [%ld], dbuffer_available = [%ld] \n",
00168 not_loadin, dbuffer_available);
00169 printf("[2] d_now = [%ld], this_write = [%d] \n\n",
00170 d_now, this_write);
00171 #endif
00172
00173
00174
00175
00176 if ( dbuffer_available < (sizeof(unsigned long) * 3) )
00177 {
00178
00179 memcpy( (dbuffer+0), (dbuffer+d_now), dbuffer_available);
00180 return (0);
00181 }
00182 else
00183 {
00184 #if LOAD_DEBUG
00185 printf("with remaining data to call get_x \n");
00186 printf("dbuffer available = %ld , d_now = %ld\n",
00187 dbuffer_available, d_now);
00188 #endif
00189 d_now = get_x_header(dbuffer, d_now);
00190 }
00191 }
00192 }
00193 return (0);
00194 }
00195
00196 static int get_x_header(unsigned char *dbuffer, unsigned long now)
00197 {
00198 X.addr = *(unsigned long *)(dbuffer + now);
00199 X.size = *(unsigned long *)(dbuffer + now + sizeof(unsigned long));
00200 X.checksum = *(unsigned long *)(dbuffer + now + sizeof(unsigned long)*2);
00201
00202 if (X.addr == 0)
00203 {
00204 entry = X.size;
00205 done(1);
00206 printf("Entry Point Address = [%lx] \n", entry);
00207 jump_2ep();
00208 }
00209
00210 if (!prep_segment(X.addr, X.addr + X.size, X.addr + X.size, 0, 0)) {
00211 longjmp(restart_etherboot, -2);
00212 }
00213
00214 ce_curaddr = X.addr;
00215 now += sizeof(unsigned long)*3;
00216
00217
00218 dbuffer_available -= sizeof(unsigned long)*3;
00219
00220
00221 not_loadin = X.size;
00222
00223 #if 1
00224 printf("\n");
00225 printf("\t Section Address = [%lx] \n", X.addr);
00226 printf("\t Size = %d [%lx]\n", X.size, X.size);
00227 printf("\t Checksum = %ld [%lx]\n", X.checksum, X.checksum);
00228 #endif
00229 #if LOAD_DEBUG
00230 printf("____________________________________________\n");
00231 printf("\t dbuffer_now = %ld \n", now);
00232 printf("\t dbuffer available = %ld \n", dbuffer_available);
00233 printf("\t not_loadin = %ld \n", not_loadin);
00234 #endif
00235
00236 return now;
00237 }
00238
00239 static void jump_2ep()
00240 {
00241 BootArgs.ucVideoMode = 1;
00242 BootArgs.ucComPort = 1;
00243 BootArgs.ucBaudDivisor = 1;
00244 BootArgs.ucPCIConfigType = 1;
00245
00246 BootArgs.dwSig = BOOTARG_SIG;
00247 BootArgs.dwLen = sizeof(BootArgs);
00248
00249 if(BootArgs.ucVideoMode == 0)
00250 {
00251 BootArgs.cxDisplayScreen = 640;
00252 BootArgs.cyDisplayScreen = 480;
00253 BootArgs.cxPhysicalScreen = 640;
00254 BootArgs.cyPhysicalScreen = 480;
00255 BootArgs.bppScreen = 16;
00256 BootArgs.cbScanLineLength = 1024;
00257 BootArgs.pvFlatFrameBuffer = 0x800a0000;
00258 }
00259 else if(BootArgs.ucVideoMode != 0xFF)
00260 {
00261 BootArgs.cxDisplayScreen = 0;
00262 BootArgs.cyDisplayScreen = 0;
00263 BootArgs.cxPhysicalScreen = 0;
00264 BootArgs.cyPhysicalScreen = 0;
00265 BootArgs.bppScreen = 0;
00266 BootArgs.cbScanLineLength = 0;
00267 BootArgs.pvFlatFrameBuffer = 0;
00268 }
00269
00270 ep = phys_to_virt(BOOT_ARG_PTR_LOCATION);
00271 *ep= virt_to_phys(&BootArgs);
00272 xstart32(entry);
00273 }