Improve control of debug messages.

Rename BX_INFO() to dprintf() and add a "severity level" parameter.
Add CONFIG_DEBUG_LEVEL compile option to control debug verbosity.
Add more debug info to init steps of post.c.
diff --git a/src/apm.c b/src/apm.c
index f7646c9..4a0f803 100644
--- a/src/apm.c
+++ b/src/apm.c
@@ -15,7 +15,7 @@
 out_str(const char *str_cs)
 {
     if (CONFIG_COREBOOT) {
-        BX_INFO("APM request '%s'\n", str_cs);
+        dprintf(1, "APM request '%s'\n", str_cs);
         return;
     }
 
diff --git a/src/ata.c b/src/ata.c
index e319cf1..ab2d170 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -8,7 +8,7 @@
 #include "ata.h" // ATA_*
 #include "types.h" // u8
 #include "ioport.h" // inb
-#include "util.h" // BX_INFO
+#include "util.h" // dprintf
 #include "cmos.h" // inb_cmos
 
 #define TIMEOUT 0
@@ -69,7 +69,7 @@
         if (timeout == 0 || (time>>11) > timeout)
             break;
     }
-    BX_INFO("IDE time out\n");
+    dprintf(1, "IDE time out\n");
     return -1;
 }
 
@@ -679,14 +679,14 @@
     u16 spt = GET_EBDA(ata.devices[driveid].pchs.spt);
     u64 sectors = GET_EBDA(ata.devices[driveid].sectors);
 
-    BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation="
+    dprintf(1, "ata%d-%d: PCHS=%u/%d/%d translation="
             , channel, slave, cylinders, heads, spt);
     switch (translation) {
     case ATA_TRANSLATION_NONE:
-        BX_INFO("none");
+        dprintf(1, "none");
         break;
     case ATA_TRANSLATION_LBA:
-        BX_INFO("lba");
+        dprintf(1, "lba");
         spt = 63;
         if (sectors > 63*255*1024) {
             heads = 255;
@@ -708,7 +708,7 @@
         cylinders = sect / heads;
         break;
     case ATA_TRANSLATION_RECHS:
-        BX_INFO("r-echs");
+        dprintf(1, "r-echs");
         // Take care not to overflow
         if (heads==16) {
             if (cylinders>61439)
@@ -719,7 +719,7 @@
         // then go through the large bitshift process
     case ATA_TRANSLATION_LARGE:
         if (translation == ATA_TRANSLATION_LARGE)
-            BX_INFO("large");
+            dprintf(1, "large");
         while (cylinders > 1024) {
             cylinders >>= 1;
             heads <<= 1;
@@ -733,7 +733,7 @@
     // clip to 1024 cylinders in lchs
     if (cylinders > 1024)
         cylinders = 1024;
-    BX_INFO(" LCHS=%d/%d/%d\n", cylinders, heads, spt);
+    dprintf(1, " LCHS=%d/%d/%d\n", cylinders, heads, spt);
 
     SET_EBDA(ata.devices[driveid].lchs.heads, heads);
     SET_EBDA(ata.devices[driveid].lchs.cylinders, cylinders);
diff --git a/src/boot.c b/src/boot.c
index 12226d6..336d869 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -96,7 +96,7 @@
     bootdev -= 1;
 
     if (bootdev >= GET_EBDA(ipl.count)) {
-        BX_INFO("Invalid boot device (0x%x)\n", bootdev);
+        dprintf(1, "Invalid boot device (0x%x)\n", bootdev);
         return;
     }
 
@@ -174,7 +174,7 @@
     }
 
     /* Debugging info */
-    BX_INFO("Booting from %x:%x\n", bootseg, bootip);
+    dprintf(1, "Booting from %x:%x\n", bootseg, bootip);
 
     memset(&cr, 0, sizeof(cr));
     cr.ip = bootip;
diff --git a/src/cdrom.c b/src/cdrom.c
index e2e4fb0..ef81bb3 100644
--- a/src/cdrom.c
+++ b/src/cdrom.c
@@ -436,7 +436,7 @@
 
     u16 ret = atapi_is_ready(device);
     if (ret)
-        BX_INFO("ata_is_ready returned %d\n", ret);
+        dprintf(1, "ata_is_ready returned %d\n", ret);
 
     // if not found
     if (device >= CONFIG_MAX_ATA_DEVICES)
diff --git a/src/config.h b/src/config.h
index 75f5a7f..ed5d809 100644
--- a/src/config.h
+++ b/src/config.h
@@ -16,6 +16,9 @@
 // Configure as a payload coreboot payload.
 #define CONFIG_COREBOOT 0
 
+// Control how verbose debug output is.
+#define CONFIG_DEBUG_LEVEL 1
+
 // Send debugging information to serial port
 #define CONFIG_DEBUG_SERIAL 0
 
diff --git a/src/disk.c b/src/disk.c
index 00eec81..ee2c983 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -61,7 +61,7 @@
     u16 head        = regs->dh;
 
     if (count > 128 || count == 0 || sector == 0) {
-        BX_INFO("int13_harddisk: function %02x, parameter out of range!\n"
+        dprintf(1, "int13_harddisk: function %02x, parameter out of range!\n"
                 , regs->ah);
         disk_ret(regs, DISK_RET_EPARAM);
         return;
@@ -69,7 +69,7 @@
 
     // sanity check on cyl heads, sec
     if (cylinder >= nlc || head >= nlh || sector > nlspt) {
-        BX_INFO("int13_harddisk: function %02x, parameters out of"
+        dprintf(1, "int13_harddisk: function %02x, parameters out of"
                 " range %04x/%04x/%04x!\n"
                 , regs->ah, cylinder, head, sector);
         disk_ret(regs, DISK_RET_EPARAM);
@@ -104,7 +104,7 @@
     regs->al = GET_EBDA(ata.trsfsectors);
 
     if (status != 0) {
-        BX_INFO("int13_harddisk: function %02x, error %02x !\n"
+        dprintf(1, "int13_harddisk: function %02x, error %02x !\n"
                 , regs->ah, status);
         disk_ret(regs, DISK_RET_EBADTRACK);
     }
@@ -119,7 +119,8 @@
     u8 type = GET_EBDA(ata.devices[device].type);
     if (type == ATA_TYPE_ATA
         && lba >= GET_EBDA(ata.devices[device].sectors)) {
-        BX_INFO("int13_harddisk: function %02x. LBA out of range\n", regs->ah);
+        dprintf(1, "int13_harddisk: function %02x. LBA out of range\n"
+                , regs->ah);
         disk_ret(regs, DISK_RET_EPARAM);
         return;
     }
@@ -148,7 +149,7 @@
     SET_INT13EXT(regs, count, GET_EBDA(ata.trsfsectors));
 
     if (status != 0) {
-        BX_INFO("int13_harddisk: function %02x, error %02x !\n"
+        dprintf(1, "int13_harddisk: function %02x, error %02x !\n"
                 , regs->ah, status);
         disk_ret(regs, DISK_RET_EBADTRACK);
         return;
diff --git a/src/floppy.c b/src/floppy.c
index 233aff7..9eb7737 100644
--- a/src/floppy.c
+++ b/src/floppy.c
@@ -434,7 +434,6 @@
 
     if (head > 1 || sector == 0 || num_sectors == 0
         || track > 79 || num_sectors > 72) {
-        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
         floppy_fail(regs, DISK_RET_EPARAM);
         return;
     }
@@ -482,7 +481,6 @@
 
     if (head > 1 || sector == 0 || num_sectors == 0
         || track > 79 || num_sectors > 72) {
-        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
         floppy_fail(regs, DISK_RET_EPARAM);
         return;
     }
@@ -534,7 +532,6 @@
 
     if (head > 1 || sector == 0 || num_sectors == 0
         || track > 79 || num_sectors > 72) {
-        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
         floppy_fail(regs, DISK_RET_EPARAM);
         return;
     }
@@ -558,7 +555,6 @@
     u8 head        = regs->dh;
 
     if (head > 1 || num_sectors == 0 || num_sectors > 18) {
-        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
         floppy_fail(regs, DISK_RET_EPARAM);
         return;
     }
@@ -715,7 +711,6 @@
 static void
 floppy_13XX(struct bregs *regs, u8 drive)
 {
-    BX_INFO("int13_diskette: unsupported AH=%02x\n", regs->ah);
     floppy_ret(regs, DISK_RET_EPARAM);
 }
 
diff --git a/src/kbd.c b/src/kbd.c
index 6786698..1f4ea30 100644
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -521,7 +521,7 @@
 
     switch (scancode) {
     case 0x00:
-        BX_INFO("KBD: int09 handler: AL=0\n");
+        dprintf(1, "KBD: int09 handler: AL=0\n");
         return;
 
     case 0x3a: /* Caps Lock press */
@@ -643,7 +643,7 @@
             break; /* toss key releases ... */
         }
         if (scancode > MAX_SCAN_CODE) {
-            BX_INFO("KBD: int09h_handler(): unknown scancode read: 0x%02x!\n"
+            dprintf(1, "KBD: int09h_handler(): unknown scancode read: 0x%02x!\n"
                     , scancode);
             return;
         }
@@ -682,7 +682,8 @@
             }
         }
         if (scancode==0 && asciicode==0) {
-            BX_INFO("KBD: int09h_handler(): scancode & asciicode are zero?\n");
+            dprintf(1, "KBD: int09h_handler():"
+                    " scancode & asciicode are zero?\n");
         }
         enqueue_key(scancode, asciicode);
         break;
diff --git a/src/output.c b/src/output.c
index b2f28e9..1c3831d 100644
--- a/src/output.c
+++ b/src/output.c
@@ -24,12 +24,14 @@
 static void
 putc(u16 action, char c)
 {
-    if (CONFIG_DEBUG_SERIAL)
-        // Send character to serial port.
-        debug_serial(c);
-    else
-        // Send character to debug port.
-        outb(c, PORT_BIOS_DEBUG);
+    if (CONFIG_DEBUG_LEVEL) {
+        if (! CONFIG_COREBOOT)
+            // Send character to debug port.
+            outb(c, PORT_BIOS_DEBUG);
+        if (CONFIG_DEBUG_SERIAL)
+            // Send character to serial port.
+            debug_serial(c);
+    }
 
     if (action) {
         // Send character to video screen.
@@ -193,7 +195,7 @@
 }
 
 void
-BX_INFO(const char *fmt, ...)
+__dprintf(const char *fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
@@ -214,13 +216,13 @@
 dump_regs(const char *fname, const char *type, struct bregs *regs)
 {
     if (!regs) {
-        BX_INFO("%s %s: NULL\n", type, fname);
+        __dprintf("%s %s: NULL\n", type, fname);
         return;
     }
-    BX_INFO("%s %s: a=%x b=%x c=%x d=%x si=%x di=%x\n"
+    __dprintf("%s %s: a=%x b=%x c=%x d=%x si=%x di=%x\n"
             , type, fname, regs->eax, regs->ebx, regs->ecx, regs->edx
             , regs->esi, regs->edi);
-    BX_INFO("  ds=%x es=%x ip=%x cs=%x f=%x r=%p\n"
+    __dprintf("  ds=%x es=%x ip=%x cs=%x f=%x r=%p\n"
             , regs->ds, regs->es, regs->ip, regs->cs, regs->flags, regs);
 }
 
diff --git a/src/post.c b/src/post.c
index a6f7c3d..ab7f069 100644
--- a/src/post.c
+++ b/src/post.c
@@ -97,7 +97,7 @@
     }
 
     SET_EBDA(ram_size, rs);
-    BX_INFO("ram_size=0x%08x\n", rs);
+    dprintf(1, "ram_size=0x%08x\n", rs);
 }
 
 static void
@@ -212,19 +212,27 @@
     if (CONFIG_DEBUG_SERIAL)
         debug_serial_setup();
 
-    BX_INFO("Start bios\n");
+    dprintf(1, "Start bios\n");
 
+    dprintf(3, "init bda\n");
     init_bda();
     init_ebda();
 
+    dprintf(3, "init timer\n");
     timer_setup();
+    dprintf(3, "init keyboard\n");
     kbd_setup();
+    dprintf(3, "init lpt\n");
     lpt_setup();
+    dprintf(3, "init serial\n");
     serial_setup();
+    dprintf(3, "init pic\n");
     pic_setup();
 
+    dprintf(3, "Find memory size\n");
     ram_probe();
 
+    dprintf(1, "Scan for VGA option rom\n");
     rom_scan(0xc0000, 0xc7800);
 
     printf("BIOS - begin\n\n");
@@ -233,13 +241,18 @@
     extern char __bss_start[], __bss_end[];
     memset(__bss_start, 0, __bss_end - __bss_start);
 
+    dprintf(3, "rombios32 init\n");
     rombios32_init();
 
+    dprintf(3, "init floppy drives\n");
     floppy_drive_setup();
+    dprintf(3, "init hard drives\n");
     hard_drive_setup();
 
+    dprintf(3, "init boot device ordering\n");
     init_boot_vectors();
 
+    dprintf(1, "Scan for option roms\n");
     rom_scan(0xc8000, 0xe0000);
 
     interactive_bootmenu();
@@ -249,6 +262,7 @@
     memset((void*)0x40000, 0, 0x40000); // XXX - shouldn't use globals
 
     // Invoke int 19 to start boot process.
+    dprintf(3, "Jump to int19\n");
     struct bregs br;
     memset(&br, 0, sizeof(br));
     call16_int(0x19, &br);
diff --git a/src/rombios32.c b/src/rombios32.c
index 6c35b0a..3e73323 100644
--- a/src/rombios32.c
+++ b/src/rombios32.c
@@ -17,7 +17,7 @@
 //  License along with this library; if not, write to the Free Software
 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 
-#include "util.h" // BX_INFO
+#include "util.h" // dprintf
 #include "pci.h" // PCIDevice
 #include "types.h" // u32
 #include "config.h" // CONFIG_*
@@ -164,7 +164,7 @@
 
         smp_cpus = readw((void *)CPU_COUNT_ADDR);
     }
-    BX_INFO("Found %d cpu(s)\n", smp_cpus);
+    dprintf(1, "Found %d cpu(s)\n", smp_cpus);
 }
 
 /****************************************************/
@@ -211,7 +211,7 @@
     old_addr = pci_config_readl(d, ofs);
 
     pci_config_writel(d, ofs, addr);
-    BX_INFO("region %d: 0x%08x\n", region_num, addr);
+    dprintf(1, "region %d: 0x%08x\n", region_num, addr);
 
     /* enable memory mappings */
     cmd = pci_config_readw(d, PCI_COMMAND);
@@ -253,7 +253,7 @@
 {
     bios_table_cur_addr = 0xf0000 | OFFSET_freespace2_start;
     bios_table_end_addr = 0xf0000 | OFFSET_freespace2_end;
-    BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
+    dprintf(1, "bios_table_addr: 0x%08lx end=0x%08lx\n",
             bios_table_cur_addr, bios_table_end_addr);
 
     /* remap the BIOS to shadow RAM an keep it read/write while we
@@ -315,7 +315,7 @@
         }
         outb(elcr[0], 0x4d0);
         outb(elcr[1], 0x4d1);
-        BX_INFO("PIIX3 init: elcr=%02x %02x\n",
+        dprintf(1, "PIIX3 init: elcr=%02x %02x\n",
                 elcr[0], elcr[1]);
     } else if (vendor_id == 0x8086 && device_id == 0x1237) {
         /* i440 PCI bridge */
@@ -444,7 +444,7 @@
     class = pci_config_readw(d, PCI_CLASS_DEVICE);
     vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
     device_id = pci_config_readw(d, PCI_DEVICE_ID);
-    BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n",
+    dprintf(1, "PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n",
             d.bus, d.devfn, vendor_id, device_id);
     switch(class) {
     case 0x0101:
@@ -736,7 +736,7 @@
 #else
     bios_table_cur_addr += (q - float_pointer_struct);
 #endif
-    BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
+    dprintf(1, "MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
             (unsigned long)float_pointer_struct,
             (unsigned long)mp_config_table,
             mp_config_table_size);
@@ -1078,7 +1078,8 @@
 
     acpi_tables_size = addr - base_addr;
 
-    BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
+    dprintf(1, "ACPI tables: RSDP addr=0x%08lx"
+            " ACPI DATA addr=0x%08lx size=0x%x\n",
             (unsigned long)rsdp,
             (unsigned long)rsdt, acpi_tables_size);
 
@@ -1660,7 +1661,7 @@
     bios_table_cur_addr += (p - (char *)start);
 #endif
 
-    BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start);
+    dprintf(1, "SMBIOS table addr=0x%08lx\n", (unsigned long)start);
 }
 
 void rombios32_init(void)
@@ -1669,11 +1670,11 @@
         // XXX - not supported on coreboot yet.
         return;
 
-    BX_INFO("Starting rombios32\n");
+    dprintf(1, "Starting rombios32\n");
 
 #if (CONFIG_USE_EBDA_TABLES == 1)
     ebda_cur_addr = ((*(u16 *)(0x40e)) << 4) + 0x380;
-    BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
+    dprintf(1, "ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
 #endif
 
     cpu_probe();
@@ -1695,7 +1696,7 @@
 
         bios_lock_shadow_ram();
 
-        BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
+        dprintf(1, "bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
         if (bios_table_cur_addr > bios_table_end_addr)
             BX_PANIC("bios_table_end_addr overflow!\n");
     }
diff --git a/src/util.h b/src/util.h
index 058f341..11ca269 100644
--- a/src/util.h
+++ b/src/util.h
@@ -102,10 +102,14 @@
 void BX_PANIC(const char *fmt, ...)
     __attribute__ ((format (printf, 1, 2)))
     __attribute__ ((noreturn));
-void BX_INFO(const char *fmt, ...)
-    __attribute__ ((format (printf, 1, 2)));
 void printf(const char *fmt, ...)
     __attribute__ ((format (printf, 1, 2)));
+void __dprintf(const char *fmt, ...)
+    __attribute__ ((format (printf, 1, 2)));
+#define dprintf(lvl, fmt, args...) do {                         \
+        if (CONFIG_DEBUG_LEVEL && (lvl) <= CONFIG_DEBUG_LEVEL)  \
+            __dprintf((fmt) , ##args );                         \
+    } while (0)
 void __debug_enter(const char *fname, struct bregs *regs);
 void __debug_fail(const char *fname, struct bregs *regs);
 void __debug_stub(const char *fname, struct bregs *regs);