Add claim/release runtime debug output
[yaboot.git] / second / prom.c
index d48ede52b071025e12a5514f8e604d89c5e9e400..119d0f363cabbc971f259b6e6f4c61b27cbbaf4c 100644 (file)
 
 #define READ_BLOCKS_USE_READ   1
 
 
 #define READ_BLOCKS_USE_READ   1
 
+static int yaboot_debug;
+
 prom_entry prom;
 
 ihandle prom_stdin, prom_stdout;
 
 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;
 
 static ihandle prom_mem, prom_mmu;
 static ihandle prom_chosen, prom_options;
 
@@ -239,6 +239,9 @@ prom_init (prom_entry pp)
      if (prom_get_chosen ("mmu", &prom_mmu, sizeof(prom_mmu)) <= 0)
          prom_abort ("\nCan't get mmu handle");
 
      if (prom_get_chosen ("mmu", &prom_mmu, sizeof(prom_mmu)) <= 0)
          prom_abort ("\nCan't get mmu handle");
 
+     yaboot_debug = 0;
+     prom_get_options("linux,yaboot-debug", &yaboot_debug, sizeof(yaboot_debug));
+
   // move cursor to fresh line
      prom_printf ("\n");
 
   // move cursor to fresh line
      prom_printf ("\n");
 
@@ -389,16 +392,14 @@ prom_readblocks (prom_handle dev, int blockNum, int blockCount, void *buffer)
 int
 prom_getchar ()
 {
 int
 prom_getchar ()
 {
-     char c[4];
+     char c;
      int a;
 
      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 == -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
 }
 
 int
@@ -471,6 +472,19 @@ prom_printf (char *fmt, ...)
      va_end (ap);
 }
 
      va_end (ap);
 }
 
+void
+prom_debug (char *fmt, ...)
+{
+     va_list ap;
+
+     if (!yaboot_debug)
+          return;
+
+     va_start (ap, fmt);
+     prom_vfprintf (prom_stdout, fmt, ap);
+     va_end (ap);
+}
+
 void
 prom_perror (int error, char *filename)
 {
 void
 prom_perror (int error, char *filename)
 {
@@ -513,8 +527,6 @@ prom_readline (char *prompt, char *buf, int len)
 
      while (i < len-1 && (c = prom_getchar ()) != '\r')
      {
 
      while (i < len-1 && (c = prom_getchar ()) != '\r')
      {
-         if (c >= 0x100)
-              continue;
          if (c == 8)
          {
               if (i > 0)
          if (c == 8)
          {
               if (i > 0)
@@ -577,45 +589,37 @@ 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))) {
      void *found, *addr;
      for(addr=virt; addr <= (void*)PROM_CLAIM_MAX_ADDR;
          addr+=(0x100000/sizeof(addr))) {
-          found = prom_claim(addr, size, 0);
+          found = call_prom("claim", 3, 1, addr, size, 0);
           if (found != (void *)-1) {
           if (found != (void *)-1) {
-               DEBUG_F("claimed %i at 0x%x (0x%x)\n",size,(int)found,(int)virt);
+               prom_debug("claim of 0x%x at 0x%x returned 0x%x\n", size, (int)addr, (int)found);
                return(found);
           }
      }
                return(found);
           }
      }
-     prom_printf("Claim error, can't allocate %x at 0x%x\n",size,(int)virt);
+     prom_printf("ERROR: claim of 0x%x in range 0x%x-0x%x failed\n", size, (int)virt, PROM_CLAIM_MAX_ADDR);
      return((void*)-1);
 }
 
 void *
 prom_claim (void *virt, unsigned int size, unsigned int align)
 {
      return((void*)-1);
 }
 
 void *
 prom_claim (void *virt, unsigned int size, unsigned int align)
 {
-     return call_prom ("claim", 3, 1, virt, size, align);
+     void *ret;
+
+     ret = call_prom ("claim", 3, 1, virt, size, align);
+     if (ret == (void *)-1)
+          prom_printf("ERROR: claim of 0x%x at 0x%x failed\n", size, (int)virt);
+     else
+          prom_debug("claim of 0x%x at 0x%x returned 0x%x\n", size, (int)virt, (int)ret);
+
+     return ret;
 }
 
 void
 prom_release(void *virt, unsigned int size)
 {
 }
 
 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. */
+     void *ret;
 
 
-     /* 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 */
+     ret = call_prom ("release", 2, 0, virt, size);
+     prom_debug("release of 0x%x at 0x%x returned 0x%x\n", size, (int)virt, (int)ret);
 }
 
 void
 }
 
 void
@@ -671,6 +675,7 @@ prom_getms(void)
 void
 prom_pause(void)
 {
 void
 prom_pause(void)
 {
+     prom_print_available();
      call_prom("enter", 0, 0);
 }
 
      call_prom("enter", 0, 0);
 }
 
@@ -774,6 +779,68 @@ char * prom_get_ip (struct bootp_packet * packet)
      return conf_path;
 }
 
      return conf_path;
 }
 
+/* We call this too early to use malloc, 128 cells should be large enough */
+#define NR_AVAILABLE 128
+
+void prom_print_available(void)
+{
+     prom_handle root;
+     unsigned int addr_cells, size_cells;
+     ihandle mem;
+     unsigned int available[NR_AVAILABLE];
+     unsigned int len;
+     unsigned int *p;
+
+     if (!yaboot_debug)
+          return;
+
+     root = prom_finddevice("/");
+     if (!root)
+          return;
+
+     addr_cells = 2;
+     prom_getprop(root, "#address-cells", &addr_cells, sizeof(addr_cells));
+
+     size_cells = 1;
+     prom_getprop(root, "#size-cells", &size_cells, sizeof(size_cells));
+
+     mem = prom_finddevice("/memory@0");
+     if (mem == PROM_INVALID_HANDLE)
+          return;
+
+     len = prom_getprop(mem, "available", available, sizeof(available));
+     if (len == -1)
+          return;
+     len /= 4;
+
+     prom_printf("\nAvailable memory ranges:\n");
+
+     p = available;
+     while (len > 0) {
+          unsigned int addr, size;
+
+          /*
+           * Since we are in 32bit mode it should be safe to only print the
+           * bottom 32bits of each range.
+           */
+          p += (addr_cells - 1);
+          addr = *p;
+          p++;
+
+          p += (size_cells - 1);
+          size = *p;
+          p++;
+
+          if (size)
+               prom_printf("0x%08x-0x%08x (%3d MB)\n", addr, addr + size,
+                           size/1024/1024);
+
+          len -= (addr_cells + size_cells);
+     }
+
+     prom_printf("\n");
+}
+
 /*
  * Local variables:
  * c-file-style: "k&r"
 /*
  * Local variables:
  * c-file-style: "k&r"