X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=blobdiff_plain;f=second%2Fprom.c;h=784994d5bbdc938099738a31b2fc7bdb8a137dd3;hp=d48ede52b071025e12a5514f8e604d89c5e9e400;hb=3cbe90093acba116c5fc46beaf50f74c7c8a1b69;hpb=f91756b6306e4da8aef013c8b375b32c2c0c3a2f diff --git a/second/prom.c b/second/prom.c index d48ede5..784994d 100644 --- a/second/prom.c +++ b/second/prom.c @@ -37,12 +37,12 @@ #define READ_BLOCKS_USE_READ 1 +static int yaboot_debug; + 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; @@ -196,7 +196,7 @@ prom_get_devtype (char *device) char tmp[64]; if (strstr(device, TOK_ISCSI)) - device = strcpy(tmp, "/vdevice/gscsi/disk"); + return FILE_DEVICE_ISCSI; /* Find OF device phandle */ dev = prom_finddevice(device); @@ -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"); + yaboot_debug = 0; + prom_get_options("linux,yaboot-debug", &yaboot_debug, sizeof(yaboot_debug)); + // 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 () { - 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 @@ -471,6 +472,19 @@ prom_printf (char *fmt, ...) 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) { @@ -513,8 +527,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) @@ -577,45 +589,54 @@ 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); + found = call_prom("claim", 3, 1, addr, size, 0); + if (found != (void *)-1) { + prom_debug("claim of 0x%x at 0x%x returned 0x%x\n", size, (int)addr, (int)found); + return(found); + } + } + 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); +} + +/* Start from top of memory and work down to get the needed space */ +void * +prom_claim_chunk_top(unsigned int size, unsigned int align) +{ + void *found, *addr; + for(addr=(void*)PROM_CLAIM_MAX_ADDR; addr >= (void *)size; + addr-=(0x100000/sizeof(addr))) { + found = call_prom("claim", 3, 1, addr, size, 0); 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); } } - prom_printf("Claim error, can't allocate %x at 0x%x\n",size,(int)virt); + prom_printf("ERROR: claim of 0x%x in range 0x0-0x%x failed\n", size, PROM_CLAIM_MAX_ADDR); 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) { - 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 @@ -671,6 +692,7 @@ prom_getms(void) void prom_pause(void) { + prom_print_available(); call_prom("enter", 0, 0); } @@ -774,6 +796,68 @@ char * prom_get_ip (struct bootp_packet * packet) 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"