Imported Upstream version 3.12
[debian/elilo] / ia64 / gzip.c
index bb5a06592716470d4df3f514c56d8770ab0747c9..cc0c9435398b1f0b0a680bcbc88a382b22584bf4 100644 (file)
@@ -37,6 +37,8 @@
 #include "private.h"
 #include "setjmp.h"
 
+#define LD_NAME L"gzip_ia64"
+
 #define memzero(s, n)  Memset((VOID *)(s), 0, (n))
 #define memcpy(a,b,n)  Memcpy((VOID *)(a),(b),(n))
 
@@ -68,6 +70,7 @@ typedef struct segment {
 
 #define CHUNK_FL_VALID         0x1
 #define CHUNK_FL_LOAD          0x2
+#define CHUNK_FL_X             0x4
 
 #define CHUNK_CAN_LOAD(n)      chunks[(n)].flags |= CHUNK_FL_LOAD
 #define CHUNK_NO_LOAD(n)       chunks[(n)].flags &= ~CHUNK_FL_LOAD
@@ -158,7 +161,7 @@ gzip_free(void *where)
 int
 fill_inbuf(void)
 {
-       INTN expected, nread;
+       UINTN expected, nread;
        EFI_STATUS status;
 
        expected = nread = INBUFSIZE;
@@ -167,7 +170,9 @@ fill_inbuf(void)
        if (EFI_ERROR(status)) {
                error("elilo: Read failed");
        }
+#ifdef DEBUG_GZIP
        DBG_PRT((L"%s : read %d bytes of %d bytes\n", LD_NAME, nread, expected));
+#endif
 
        insize = nread;
        inptr = 1;
@@ -306,7 +311,7 @@ analyze_chunks(void)
  * the relevant header information.
  */
 int
-first_block (const char *buf, long blocksize)
+first_block (const unsigned char *buf, long blocksize)
 {
        Elf64_Ehdr *elf;
        Elf64_Phdr *phdrs;
@@ -391,6 +396,9 @@ first_block (const char *buf, long blocksize)
                        continue;
                }
 
+               if (bswap32(phdrs[i].p_flags) & PF_X)
+                       chunks[i].flags |= CHUNK_FL_X;
+
                CHUNK_CAN_LOAD(i); /* mark no load chunk */
 
                VERB_PRT(3, 
@@ -433,7 +441,7 @@ first_block (const char *buf, long blocksize)
        if (alloc_kmem((void *)low_addr, pages) == -1) {
                VOID *new_addr;
 
-               ERR_PRT((L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", LD_NAME, pages, low_addr));
+               VERB_PRT(1, Print(L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", LD_NAME, pages, low_addr));
 
                if (ia64_can_relocate() == 0) {
                        ERR_PRT((L"relocation is disabled, cannot load kernel"));
@@ -458,7 +466,7 @@ first_block (const char *buf, long blocksize)
                /* unsigned arithmetic */
                 load_offset = (UINTN) (new_addr - ROUNDDOWN((UINTN) low_addr,256*MB));
 
-               ERR_PRT((L"low_addr=0x%lx new_addr=0x%lx offset=0x%lx", low_addr, new_addr, load_offset));
+               VERB_PRT(1, Print(L"low_addr=0x%lx new_addr=0x%lx offset=0x%lx", low_addr, new_addr, load_offset));
 
                /*
                 * correct various addresses for non-zero load_offset
@@ -520,12 +528,13 @@ flush_window(void)
        static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
        static UINTN heli_count;
        struct segment *cp;
-       char    *src, *dst;
+       unsigned char   *src, *dst;
        long    cnt;
 
        if (!outcnt) return;
-
+#ifdef DEBUG_GZIP
        DBG_PRT((L"%s : flush_window outnct=%d file_offset=%ld\n", LD_NAME, outcnt, file_offset));
+#endif
 
        Print(L"%c\b",helicopter[heli_count++%4]);
 
@@ -559,13 +568,15 @@ tail:
                file_offset += skip;
                outcnt      -= skip;
        }
-       dst = (char *)cp->addr + (file_offset - cp->offset);
+       dst = (unsigned char *)cp->addr + (file_offset - cp->offset);
 
        cnt = cp->offset + cp->size - file_offset;
 
        if (cnt > outcnt) cnt = outcnt;
 
        Memcpy(dst, src, cnt);
+       if (cp->flags & CHUNK_FL_X)
+               flush_dcache (dst, cnt);
 
        file_offset += cnt;
        outcnt      -= cnt;
@@ -574,7 +585,7 @@ tail:
        /* See if we are at the end of this chunk */
        if (file_offset == cp->offset + cp->size) {
                if (cp->bss_sz) {
-                       dst = (char *)cp->addr + cp->size;
+                       dst = (unsigned char *)cp->addr + cp->size;
                        Memset(dst, 0, cp->bss_sz);
                }
                nextchunk();