Use prom_claim_chunk to allocate malloc area
[yaboot.git] / second / prom.c
index e9c5843e1efec04b25baa7185e16a9025b8e0905..5aa0a02830f7dbe83d1dae968fca64878c3d1a5a 100644 (file)
@@ -41,8 +41,6 @@ prom_entry prom;
 
 ihandle prom_stdin, prom_stdout;
 
-//extern int vsprintf(char *buf, const char *fmt, va_list args);
-
 static ihandle prom_mem, prom_mmu;
 static ihandle prom_chosen, prom_options;
 
@@ -389,16 +387,14 @@ prom_readblocks (prom_handle dev, int blockNum, int blockCount, void *buffer)
 int
 prom_getchar ()
 {
-     char c[4];
+     char c;
      int a;
 
-     while ((a = (int)call_prom ("read", 3, 1, prom_stdin, c, 4)) == 0)
+     while ((a = (int)call_prom ("read", 3, 1, prom_stdin, &c, 1)) == 0)
          ;
      if (a == -1)
          prom_abort ("EOF on console\n");
-     if (a == 3 && c[0] == '\e' && c[1] == '[')
-         return 0x100 | c[2];
-     return c[0];
+     return c;
 }
 
 int
@@ -513,8 +509,6 @@ prom_readline (char *prompt, char *buf, int len)
 
      while (i < len-1 && (c = prom_getchar ()) != '\r')
      {
-         if (c >= 0x100)
-              continue;
          if (c == 8)
          {
               if (i > 0)
@@ -568,6 +562,25 @@ prom_sleep (int seconds)
      while (prom_getms() <= end);
 }
 
+/* if address given is claimed look for other addresses to get the needed
+ * space before giving up
+ */
+void *
+prom_claim_chunk(void *virt, unsigned int size, unsigned int align)
+{
+     void *found, *addr;
+     for(addr=virt; addr <= (void*)PROM_CLAIM_MAX_ADDR;
+         addr+=(0x100000/sizeof(addr))) {
+          found = prom_claim(addr, size, 0);
+          if (found != (void *)-1) {
+               DEBUG_F("claimed %i at 0x%x (0x%x)\n",size,(int)found,(int)virt);
+               return(found);
+          }
+     }
+     prom_printf("Claim error, can't allocate %x at 0x%x\n",size,(int)virt);
+     return((void*)-1);
+}
+
 void *
 prom_claim (void *virt, unsigned int size, unsigned int align)
 {
@@ -578,25 +591,6 @@ void
 prom_release(void *virt, unsigned int size)
 {
      call_prom ("release", 2, 0, virt, size);
-#if 0 /* this is bullshit, newworld OF RELEASE method works fine. */
-
-     /* release in not enough, it needs also an unmap call. This bit of forth
-      * code inspired from Darwin's bootloader but could be replaced by direct
-      * calls to the MMU package if needed
-      */
-     call_prom ("interpret", 3, 1,
-#if DEBUG
-               ".\" ReleaseMem:\" 2dup . . cr "
-#endif
-               "over \" translate\" ^mmu "             // Find out physical base
-               "^on0 "                                 // Bail if translation failed
-               "drop "                                 // Leaving phys on top of stack
-               "2dup \" unmap\" ^mmu "                 // Unmap the space first
-               "2dup \" release\" ^mmu "               // Then free the virtual pages
-               "\" release\" ^mem "                    // Then free the physical pages
-               ,size, virt
-         );
-#endif /* bullshit */
 }
 
 void
@@ -664,6 +658,10 @@ struct bootp_packet * prom_get_netinfo (void)
      void *bootp_response = NULL;
      char *propname;
      struct bootp_packet *packet;
+     /* struct bootp_packet contains a VLA, so sizeof won't work.
+        the VLA /must/ be the last field in the structure so use it's
+        offset as a good estimate of the packet size */
+     size_t packet_size = offsetof(struct bootp_packet, options);
      int i = 0, size, offset = 0;
      prom_handle chosen;
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@@ -688,7 +686,7 @@ struct bootp_packet * prom_get_netinfo (void)
      if (size <= 0)
          return NULL;
 
-     if (sizeof(*packet) > size - offset) {
+     if (packet_size > size - offset) {
          prom_printf("Malformed %s property?\n", propname);
          return NULL;
      }