[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] rombios: Simplify memory-size bios calls and derive all results from



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1174071595 0
# Node ID 62754c2fdcfa923ca0efd0282e111a65ad76062b
# Parent  cb1693873a7ea08cbb2e13ee9d618325b19894bb
rombios: Simplify memory-size bios calls and derive all results from
the e820 map.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/firmware/rombios/rombios.c |  242 ++++++++++++---------------------------
 1 files changed, 75 insertions(+), 167 deletions(-)

diff -r cb1693873a7e -r 62754c2fdcfa tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Fri Mar 16 18:59:28 2007 +0000
+++ b/tools/firmware/rombios/rombios.c  Fri Mar 16 18:59:55 2007 +0000
@@ -4196,178 +4196,86 @@ ASM_END
     case 0xe8:
         switch(regs.u.r8.al)
         {
-         case 0x20: // coded by osmaker aka K.J.
-            if(regs.u.r32.edx == 0x534D4150) /* SMAP */
-            {
-#ifdef HVMASSIST
-               if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
-                   Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
-
-                   if (regs.u.r16.bx + 0x14 <= e820_table_size) {
-                       memcpyb(ES, regs.u.r16.di,
-                               0xe000, 0x10 + regs.u.r16.bx, 0x14);
-                   }
-                   regs.u.r32.ebx += 0x14;
-                   if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
-                       regs.u.r32.ebx = 0;
-                   regs.u.r32.eax = 0x534D4150;
-                   regs.u.r32.ecx = 0x14;
-                   CLEAR_CF();
-                   return;
-               } else if (regs.u.r16.bx == 1) {
-                   extended_memory_size = inb_cmos(0x35);
-                   extended_memory_size <<= 8;
-                   extended_memory_size |= inb_cmos(0x34);
-                   extended_memory_size *= 64;
-                   if (extended_memory_size > 0x3bc000) // greater than 
EFF00000???
-                   {
-                       extended_memory_size = 0x3bc000; // everything after 
this is reserved memory until we get to 0x100000000
-                   }
-                   extended_memory_size *= 1024;
-                   extended_memory_size += 15728640; // make up for the 16mb 
of memory that is chopped off
-
-                   if (extended_memory_size <= 15728640)
-                   {
-                       extended_memory_size = inb_cmos(0x31);
-                       extended_memory_size <<= 8;
-                       extended_memory_size |= inb_cmos(0x30);
-                       extended_memory_size *= 1024;
-                   }
-
-                   write_word(ES, regs.u.r16.di, 0x0000);
-                   write_word(ES, regs.u.r16.di+2, 0x0010);
-                   write_word(ES, regs.u.r16.di+4, 0x0000);
-                   write_word(ES, regs.u.r16.di+6, 0x0000);
-
-                   write_word(ES, regs.u.r16.di+8, extended_memory_size);
-                   extended_memory_size >>= 16;
-                   write_word(ES, regs.u.r16.di+10, extended_memory_size);
-                   extended_memory_size >>= 16;
-                   write_word(ES, regs.u.r16.di+12, extended_memory_size);
-                   extended_memory_size >>= 16;
-                   write_word(ES, regs.u.r16.di+14, extended_memory_size);
-
-                   write_word(ES, regs.u.r16.di+16, 0x1);
-                   write_word(ES, regs.u.r16.di+18, 0x0);
-
-                   regs.u.r32.ebx = 0;
-                   regs.u.r32.eax = 0x534D4150;
-                   regs.u.r32.ecx = 0x14;
-                   CLEAR_CF();
-                   return;
-               } else { /* AX=E820, DX=534D4150, BX unrecognized */
-                   goto int15_unimplemented;
-               }
-#else
-                switch(regs.u.r16.bx)
-                {
-                    case 0:
-                        write_word(ES, regs.u.r16.di, 0x00);
-                        write_word(ES, regs.u.r16.di+2, 0x00);
-                        write_word(ES, regs.u.r16.di+4, 0x00);
-                        write_word(ES, regs.u.r16.di+6, 0x00);
-
-                        write_word(ES, regs.u.r16.di+8, 0xFC00);
-                        write_word(ES, regs.u.r16.di+10, 0x0009);
-                        write_word(ES, regs.u.r16.di+12, 0x0000);
-                        write_word(ES, regs.u.r16.di+14, 0x0000);
-
-                        write_word(ES, regs.u.r16.di+16, 0x1);
-                        write_word(ES, regs.u.r16.di+18, 0x0);
-
-                        regs.u.r32.ebx = 1;
-
-                        regs.u.r32.eax = 0x534D4150;
-                        regs.u.r32.ecx = 0x14;
-                        CLEAR_CF();
-                        return;
-                        break;
-                    case 1:
-                        extended_memory_size = inb_cmos(0x35);
-                        extended_memory_size <<= 8;
-                        extended_memory_size |= inb_cmos(0x34);
-                        extended_memory_size *= 64;
-                        if(extended_memory_size > 0x3bc000) // greater than 
EFF00000???
-                        {
-                            extended_memory_size = 0x3bc000; // everything 
after this is reserved memory until we get to 0x100000000
-                        }
-                        extended_memory_size *= 1024;
-                        extended_memory_size += 15728640; // make up for the 
16mb of memory that is chopped off
-
-                        if(extended_memory_size <= 15728640)
-                        {
-                            extended_memory_size = inb_cmos(0x31);
-                            extended_memory_size <<= 8;
-                            extended_memory_size |= inb_cmos(0x30);
-                            extended_memory_size *= 1024;
-                        }
-
-                        write_word(ES, regs.u.r16.di, 0x0000);
-                        write_word(ES, regs.u.r16.di+2, 0x0010);
-                        write_word(ES, regs.u.r16.di+4, 0x0000);
-                        write_word(ES, regs.u.r16.di+6, 0x0000);
-
-                        write_word(ES, regs.u.r16.di+8, extended_memory_size);
-                        extended_memory_size >>= 16;
-                        write_word(ES, regs.u.r16.di+10, extended_memory_size);
-                        extended_memory_size >>= 16;
-                        write_word(ES, regs.u.r16.di+12, extended_memory_size);
-                        extended_memory_size >>= 16;
-                        write_word(ES, regs.u.r16.di+14, extended_memory_size);
-
-                        write_word(ES, regs.u.r16.di+16, 0x1);
-                        write_word(ES, regs.u.r16.di+18, 0x0);
-
-                        regs.u.r32.ebx = 0;
-                        regs.u.r32.eax = 0x534D4150;
-                        regs.u.r32.ecx = 0x14;
-                        CLEAR_CF();
-                        return;
-                        break;
-                    default:  /* AX=E820, DX=534D4150, BX unrecognized */
-                        goto int15_unimplemented;
+        case 0x20: {
+            Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
+
+            if (regs.u.r32.edx != 0x534D4150) /* SMAP */
+                goto int15_unimplemented;
+
+            if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
+                if (regs.u.r16.bx + 0x14 <= e820_table_size)
+                    memcpyb(ES, regs.u.r16.di,
+                            0xe000, 0x10 + regs.u.r16.bx, 0x14);
+                regs.u.r32.ebx += 0x14;
+                if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
+                    regs.u.r32.ebx = 0;
+            } else if (regs.u.r16.bx == 1) {
+                Bit32u base, type;
+                Bit16u off;
+                for (off = 0; off < e820_table_size; off += 0x14) {
+                    base = read_dword(0xe000, 0x10 + off);
+                    type = read_dword(0xe000, 0x20 + off);
+                    if ((base >= 0x100000) && (type == 1))
                         break;
                 }
-#endif
-           } else {
-             // if DX != 0x534D4150)
-             goto int15_unimplemented;
-           }
+                if (off == e820_table_size) {
+                    SET_CF();
+                    break;
+                }
+                memcpyb(ES, regs.u.r16.di, 0xe000, 0x10 + off, 0x14);
+                regs.u.r32.ebx = 0;
+            } else { /* AX=E820, DX=534D4150, BX unrecognized */
+                goto int15_unimplemented;
+            }
+
+            regs.u.r32.eax = 0x534D4150;
+            regs.u.r32.ecx = 0x14;
+            CLEAR_CF();
             break;
-
-        case 0x01: 
-          // do we have any reason to fail here ?
-          CLEAR_CF();
-
-          // my real system sets ax and bx to 0
-          // this is confirmed by Ralph Brown list
-          // but syslinux v1.48 is known to behave 
-          // strangely if ax is set to 0
-          // regs.u.r16.ax = 0;
-          // regs.u.r16.bx = 0;
-
-          // Get the amount of extended memory (above 1M)
-          regs.u.r8.cl = inb_cmos(0x30);
-          regs.u.r8.ch = inb_cmos(0x31);
+        }
+
+        case 0x01: {
+            Bit16u off, e820_table_size = read_word(0xe000, 0x8) * 0x14;
+            Bit32u base, type, size;
+
+            // do we have any reason to fail here ?
+            CLEAR_CF();
+
+            // Get the amount of extended memory (above 1M)
+            regs.u.r8.cl = inb_cmos(0x30);
+            regs.u.r8.ch = inb_cmos(0x31);
           
-          // limit to 15M
-          if(regs.u.r16.cx > 0x3c00)
-          {
-            regs.u.r16.cx = 0x3c00;
-          }
-
-          // Get the amount of extended memory above 16M in 64k blocs
-          regs.u.r8.dl = inb_cmos(0x34);
-          regs.u.r8.dh = inb_cmos(0x35);
-
-          // Set configured memory equal to extended memory
-          regs.u.r16.ax = regs.u.r16.cx;
-          regs.u.r16.bx = regs.u.r16.dx;
-          break;
+            // limit to 15M
+            if (regs.u.r16.cx > (15*1024))
+                regs.u.r16.cx = 15*1024;
+
+            // Find first RAM E820 entry >= 1MB.
+            for (off = 0; off < e820_table_size; off += 0x14) {
+                base = read_dword(0xe000, 0x10 + off);
+                type = read_dword(0xe000, 0x20 + off);
+                if ((base >= 0x100000) && (type == 1))
+                    break;
+            }
+
+            // If there is RAM above 16MB, return amount in 64kB chunks.
+            regs.u.r16.dx = 0;
+            if (off != e820_table_size) {
+                size = base + read_dword(0xe000, 0x18 + off);
+                if (size > 0x1000000) {
+                    size -= 0x1000000;
+                    regs.u.r16.dx = (Bit16u)(size >> 16);
+                }
+            }
+
+            // Set configured memory equal to extended memory
+            regs.u.r16.ax = regs.u.r16.cx;
+            regs.u.r16.bx = regs.u.r16.dx;
+            break;
+        }
        default:  /* AH=0xE8?? but not implemented */
-         goto int15_unimplemented;
-       }
-       break;
+            goto int15_unimplemented;
+        }
+        break;
     int15_unimplemented:
        // fall into the default
     default:

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.