summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/gpxe/src/arch/i386/core/wince_loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/gpxe/src/arch/i386/core/wince_loader.c')
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/i386/core/wince_loader.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/i386/core/wince_loader.c b/contrib/syslinux-4.02/gpxe/src/arch/i386/core/wince_loader.c
new file mode 100644
index 0000000..f452b65
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/i386/core/wince_loader.c
@@ -0,0 +1,273 @@
+#define LOAD_DEBUG 0
+
+static int get_x_header(unsigned char *data, unsigned long now);
+static void jump_2ep();
+static unsigned char ce_signature[] = {'B', '0', '0', '0', 'F', 'F', '\n',};
+static char ** ep;
+
+#define BOOT_ARG_PTR_LOCATION 0x001FFFFC
+
+typedef struct _BOOT_ARGS{
+ unsigned char ucVideoMode;
+ unsigned char ucComPort;
+ unsigned char ucBaudDivisor;
+ unsigned char ucPCIConfigType;
+
+ unsigned long dwSig;
+ #define BOOTARG_SIG 0x544F4F42
+ unsigned long dwLen;
+
+ unsigned char ucLoaderFlags;
+ unsigned char ucEshellFlags;
+ unsigned char ucEdbgAdapterType;
+ unsigned char ucEdbgIRQ;
+
+ unsigned long dwEdbgBaseAddr;
+ unsigned long dwEdbgDebugZone;
+ unsigned long dwDHCPLeaseTime;
+ unsigned long dwEdbgFlags;
+
+ unsigned long dwEBootFlag;
+ unsigned long dwEBootAddr;
+ unsigned long dwLaunchAddr;
+
+ unsigned long pvFlatFrameBuffer;
+ unsigned short vesaMode;
+ unsigned short cxDisplayScreen;
+ unsigned short cyDisplayScreen;
+ unsigned short cxPhysicalScreen;
+ unsigned short cyPhysicalScreen;
+ unsigned short cbScanLineLength;
+ unsigned short bppScreen;
+
+ unsigned char RedMaskSize;
+ unsigned char REdMaskPosition;
+ unsigned char GreenMaskSize;
+ unsigned char GreenMaskPosition;
+ unsigned char BlueMaskSize;
+ unsigned char BlueMaskPosition;
+} BOOT_ARGS;
+
+BOOT_ARGS BootArgs;
+
+static struct segment_info{
+ unsigned long addr; // Section Address
+ unsigned long size; // Section Size
+ unsigned long checksum; // Section CheckSum
+} X;
+
+#define PSIZE (1500) //Max Packet Size
+#define DSIZE (PSIZE+12)
+static unsigned long dbuffer_available =0;
+static unsigned long not_loadin =0;
+static unsigned long d_now =0;
+
+unsigned long entry;
+static unsigned long ce_curaddr;
+
+
+static sector_t ce_loader(unsigned char *data, unsigned int len, int eof);
+static os_download_t wince_probe(unsigned char *data, unsigned int len)
+{
+ if (strncmp(ce_signature, data, sizeof(ce_signature)) != 0) {
+ return 0;
+ }
+ printf("(WINCE)");
+ return ce_loader;
+}
+
+static sector_t ce_loader(unsigned char *data, unsigned int len, int eof)
+{
+ static unsigned char dbuffer[DSIZE];
+ int this_write = 0;
+ static int firsttime = 1;
+
+ /*
+ * new packet in, we have to
+ * [1] copy data to dbuffer,
+ *
+ * update...
+ * [2] dbuffer_available
+ */
+ memcpy( (dbuffer+dbuffer_available), data, len); //[1]
+ dbuffer_available += len; // [2]
+ len = 0;
+
+ d_now = 0;
+
+#if 0
+ printf("dbuffer_available =%ld \n", dbuffer_available);
+#endif
+
+ if (firsttime)
+ {
+ d_now = sizeof(ce_signature);
+ printf("String Physical Address = %lx \n",
+ *(unsigned long *)(dbuffer+d_now));
+
+ d_now += sizeof(unsigned long);
+ printf("Image Size = %ld [%lx]\n",
+ *(unsigned long *)(dbuffer+d_now),
+ *(unsigned long *)(dbuffer+d_now));
+
+ d_now += sizeof(unsigned long);
+ dbuffer_available -= d_now;
+
+ d_now = (unsigned long)get_x_header(dbuffer, d_now);
+ firsttime = 0;
+ }
+
+ if (not_loadin == 0)
+ {
+ d_now = get_x_header(dbuffer, d_now);
+ }
+
+ while ( not_loadin > 0 )
+ {
+ /* dbuffer do not have enough data to loading, copy all */
+#if LOAD_DEBUG
+ printf("[0] not_loadin = [%ld], dbuffer_available = [%ld] \n",
+ not_loadin, dbuffer_available);
+ printf("[0] d_now = [%ld] \n", d_now);
+#endif
+
+ if( dbuffer_available <= not_loadin)
+ {
+ this_write = dbuffer_available ;
+ memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write );
+ ce_curaddr += this_write;
+ not_loadin -= this_write;
+
+ /* reset index and available in the dbuffer */
+ dbuffer_available = 0;
+ d_now = 0;
+#if LOAD_DEBUG
+ printf("[1] not_loadin = [%ld], dbuffer_available = [%ld] \n",
+ not_loadin, dbuffer_available);
+ printf("[1] d_now = [%ld], this_write = [%d] \n",
+ d_now, this_write);
+#endif
+
+ // get the next packet...
+ return (0);
+ }
+
+ /* dbuffer have more data then loading ... , copy partital.... */
+ else
+ {
+ this_write = not_loadin;
+ memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write);
+ ce_curaddr += this_write;
+ not_loadin = 0;
+
+ /* reset index and available in the dbuffer */
+ dbuffer_available -= this_write;
+ d_now += this_write;
+#if LOAD_DEBUG
+ printf("[2] not_loadin = [%ld], dbuffer_available = [%ld] \n",
+ not_loadin, dbuffer_available);
+ printf("[2] d_now = [%ld], this_write = [%d] \n\n",
+ d_now, this_write);
+#endif
+
+ /* dbuffer not empty, proceed processing... */
+
+ // don't have enough data to get_x_header..
+ if ( dbuffer_available < (sizeof(unsigned long) * 3) )
+ {
+// printf("we don't have enough data remaining to call get_x. \n");
+ memcpy( (dbuffer+0), (dbuffer+d_now), dbuffer_available);
+ return (0);
+ }
+ else
+ {
+#if LOAD_DEBUG
+ printf("with remaining data to call get_x \n");
+ printf("dbuffer available = %ld , d_now = %ld\n",
+ dbuffer_available, d_now);
+#endif
+ d_now = get_x_header(dbuffer, d_now);
+ }
+ }
+ }
+ return (0);
+}
+
+static int get_x_header(unsigned char *dbuffer, unsigned long now)
+{
+ X.addr = *(unsigned long *)(dbuffer + now);
+ X.size = *(unsigned long *)(dbuffer + now + sizeof(unsigned long));
+ X.checksum = *(unsigned long *)(dbuffer + now + sizeof(unsigned long)*2);
+
+ if (X.addr == 0)
+ {
+ entry = X.size;
+ done(1);
+ printf("Entry Point Address = [%lx] \n", entry);
+ jump_2ep();
+ }
+
+ if (!prep_segment(X.addr, X.addr + X.size, X.addr + X.size, 0, 0)) {
+ longjmp(restart_etherboot, -2);
+ }
+
+ ce_curaddr = X.addr;
+ now += sizeof(unsigned long)*3;
+
+ /* re-calculate dbuffer available... */
+ dbuffer_available -= sizeof(unsigned long)*3;
+
+ /* reset index of this section */
+ not_loadin = X.size;
+
+#if 1
+ printf("\n");
+ printf("\t Section Address = [%lx] \n", X.addr);
+ printf("\t Size = %d [%lx]\n", X.size, X.size);
+ printf("\t Checksum = %ld [%lx]\n", X.checksum, X.checksum);
+#endif
+#if LOAD_DEBUG
+ printf("____________________________________________\n");
+ printf("\t dbuffer_now = %ld \n", now);
+ printf("\t dbuffer available = %ld \n", dbuffer_available);
+ printf("\t not_loadin = %ld \n", not_loadin);
+#endif
+
+ return now;
+}
+
+static void jump_2ep()
+{
+ BootArgs.ucVideoMode = 1;
+ BootArgs.ucComPort = 1;
+ BootArgs.ucBaudDivisor = 1;
+ BootArgs.ucPCIConfigType = 1; // do not fill with 0
+
+ BootArgs.dwSig = BOOTARG_SIG;
+ BootArgs.dwLen = sizeof(BootArgs);
+
+ if(BootArgs.ucVideoMode == 0)
+ {
+ BootArgs.cxDisplayScreen = 640;
+ BootArgs.cyDisplayScreen = 480;
+ BootArgs.cxPhysicalScreen = 640;
+ BootArgs.cyPhysicalScreen = 480;
+ BootArgs.bppScreen = 16;
+ BootArgs.cbScanLineLength = 1024;
+ BootArgs.pvFlatFrameBuffer = 0x800a0000; // ollie say 0x98000000
+ }
+ else if(BootArgs.ucVideoMode != 0xFF)
+ {
+ BootArgs.cxDisplayScreen = 0;
+ BootArgs.cyDisplayScreen = 0;
+ BootArgs.cxPhysicalScreen = 0;
+ BootArgs.cyPhysicalScreen = 0;
+ BootArgs.bppScreen = 0;
+ BootArgs.cbScanLineLength = 0;
+ BootArgs.pvFlatFrameBuffer = 0;
+ }
+
+ ep = phys_to_virt(BOOT_ARG_PTR_LOCATION);
+ *ep= virt_to_phys(&BootArgs);
+ xstart32(entry);
+}