common.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * Copyright (C) Paul Mackerras 1997.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. */
  9. #include "nonstdio.h"
  10. #include "of1275.h"
  11. #include <linux/string.h>
  12. #include <linux/zlib.h>
  13. #include <asm/bootinfo.h>
  14. #include <asm/page.h>
  15. /* Information from the linker */
  16. extern int strcmp(const char *s1, const char *s2);
  17. extern char *avail_ram, *avail_high;
  18. extern char *end_avail;
  19. unsigned int heap_use, heap_max;
  20. struct memchunk {
  21. unsigned int size;
  22. struct memchunk *next;
  23. };
  24. static struct memchunk *freechunks;
  25. static void *zalloc(unsigned size)
  26. {
  27. void *p;
  28. struct memchunk **mpp, *mp;
  29. size = (size + 7) & -8;
  30. heap_use += size;
  31. if (heap_use > heap_max)
  32. heap_max = heap_use;
  33. for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
  34. if (mp->size == size) {
  35. *mpp = mp->next;
  36. return mp;
  37. }
  38. }
  39. p = avail_ram;
  40. avail_ram += size;
  41. if (avail_ram > avail_high)
  42. avail_high = avail_ram;
  43. if (avail_ram > end_avail) {
  44. printf("oops... out of memory\n\r");
  45. pause();
  46. }
  47. return p;
  48. }
  49. #define HEAD_CRC 2
  50. #define EXTRA_FIELD 4
  51. #define ORIG_NAME 8
  52. #define COMMENT 0x10
  53. #define RESERVED 0xe0
  54. void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
  55. {
  56. z_stream s;
  57. int r, i, flags;
  58. /* skip header */
  59. i = 10;
  60. flags = src[3];
  61. if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
  62. printf("bad gzipped data\n\r");
  63. exit();
  64. }
  65. if ((flags & EXTRA_FIELD) != 0)
  66. i = 12 + src[10] + (src[11] << 8);
  67. if ((flags & ORIG_NAME) != 0)
  68. while (src[i++] != 0)
  69. ;
  70. if ((flags & COMMENT) != 0)
  71. while (src[i++] != 0)
  72. ;
  73. if ((flags & HEAD_CRC) != 0)
  74. i += 2;
  75. if (i >= *lenp) {
  76. printf("gunzip: ran out of data in header\n\r");
  77. exit();
  78. }
  79. /* Initialize ourself. */
  80. s.workspace = zalloc(zlib_inflate_workspacesize());
  81. r = zlib_inflateInit2(&s, -MAX_WBITS);
  82. if (r != Z_OK) {
  83. printf("zlib_inflateInit2 returned %d\n\r", r);
  84. exit();
  85. }
  86. s.next_in = src + i;
  87. s.avail_in = *lenp - i;
  88. s.next_out = dst;
  89. s.avail_out = dstlen;
  90. r = zlib_inflate(&s, Z_FINISH);
  91. if (r != Z_OK && r != Z_STREAM_END) {
  92. printf("inflate returned %d msg: %s\n\r", r, s.msg);
  93. exit();
  94. }
  95. *lenp = s.next_out - (unsigned char *) dst;
  96. zlib_inflateEnd(&s);
  97. }
  98. /* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID,
  99. * a machine type for BI_MACHTYPE, and the location where the end of the
  100. * bootloader is (PROG_START + PROG_SIZE)
  101. */
  102. void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
  103. unsigned long progend)
  104. {
  105. struct bi_record *rec;
  106. /* leave a 1MB gap then align to the next 1MB boundary */
  107. addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
  108. /* oldworld machine seem very unhappy about this. -- Tom */
  109. if (addr >= progend)
  110. claim(addr, 0x1000, 0);
  111. rec = (struct bi_record *)addr;
  112. rec->tag = BI_FIRST;
  113. rec->size = sizeof(struct bi_record);
  114. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  115. rec->tag = BI_BOOTLOADER_ID;
  116. sprintf( (char *)rec->data, name);
  117. rec->size = sizeof(struct bi_record) + strlen(name) + 1;
  118. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  119. rec->tag = BI_MACHTYPE;
  120. rec->data[0] = mach;
  121. rec->data[1] = 1;
  122. rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
  123. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  124. rec->tag = BI_LAST;
  125. rec->size = sizeof(struct bi_record);
  126. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  127. }