ia64/xen-unstable

changeset 14446:62754c2fdcfa

rombios: Simplify memory-size bios calls and derive all results from
the e820 map.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Mar 16 18:59:55 2007 +0000 (2007-03-16)
parents cb1693873a7e
children d64c0af015dd
files tools/firmware/rombios/rombios.c
line diff
     1.1 --- a/tools/firmware/rombios/rombios.c	Fri Mar 16 18:59:28 2007 +0000
     1.2 +++ b/tools/firmware/rombios/rombios.c	Fri Mar 16 18:59:55 2007 +0000
     1.3 @@ -4196,178 +4196,86 @@ ASM_END
     1.4      case 0xe8:
     1.5          switch(regs.u.r8.al)
     1.6          {
     1.7 -         case 0x20: // coded by osmaker aka K.J.
     1.8 -            if(regs.u.r32.edx == 0x534D4150) /* SMAP */
     1.9 -            {
    1.10 -#ifdef HVMASSIST
    1.11 -		if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
    1.12 -		    Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
    1.13 -
    1.14 -		    if (regs.u.r16.bx + 0x14 <= e820_table_size) {
    1.15 -			memcpyb(ES, regs.u.r16.di,
    1.16 -				0xe000, 0x10 + regs.u.r16.bx, 0x14);
    1.17 -		    }
    1.18 -		    regs.u.r32.ebx += 0x14;
    1.19 -		    if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
    1.20 -			regs.u.r32.ebx = 0;
    1.21 -		    regs.u.r32.eax = 0x534D4150;
    1.22 -		    regs.u.r32.ecx = 0x14;
    1.23 -		    CLEAR_CF();
    1.24 -		    return;
    1.25 -		} else if (regs.u.r16.bx == 1) {
    1.26 -		    extended_memory_size = inb_cmos(0x35);
    1.27 -		    extended_memory_size <<= 8;
    1.28 -		    extended_memory_size |= inb_cmos(0x34);
    1.29 -		    extended_memory_size *= 64;
    1.30 -		    if (extended_memory_size > 0x3bc000) // greater than EFF00000???
    1.31 -		    {
    1.32 -			extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
    1.33 -		    }
    1.34 -		    extended_memory_size *= 1024;
    1.35 -		    extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
    1.36 -
    1.37 -		    if (extended_memory_size <= 15728640)
    1.38 -		    {
    1.39 -			extended_memory_size = inb_cmos(0x31);
    1.40 -			extended_memory_size <<= 8;
    1.41 -			extended_memory_size |= inb_cmos(0x30);
    1.42 -			extended_memory_size *= 1024;
    1.43 -		    }
    1.44 -
    1.45 -		    write_word(ES, regs.u.r16.di, 0x0000);
    1.46 -		    write_word(ES, regs.u.r16.di+2, 0x0010);
    1.47 -		    write_word(ES, regs.u.r16.di+4, 0x0000);
    1.48 -		    write_word(ES, regs.u.r16.di+6, 0x0000);
    1.49 -
    1.50 -		    write_word(ES, regs.u.r16.di+8, extended_memory_size);
    1.51 -		    extended_memory_size >>= 16;
    1.52 -		    write_word(ES, regs.u.r16.di+10, extended_memory_size);
    1.53 -		    extended_memory_size >>= 16;
    1.54 -		    write_word(ES, regs.u.r16.di+12, extended_memory_size);
    1.55 -		    extended_memory_size >>= 16;
    1.56 -		    write_word(ES, regs.u.r16.di+14, extended_memory_size);
    1.57 -
    1.58 -		    write_word(ES, regs.u.r16.di+16, 0x1);
    1.59 -		    write_word(ES, regs.u.r16.di+18, 0x0);
    1.60 -
    1.61 -		    regs.u.r32.ebx = 0;
    1.62 -		    regs.u.r32.eax = 0x534D4150;
    1.63 -		    regs.u.r32.ecx = 0x14;
    1.64 -		    CLEAR_CF();
    1.65 -		    return;
    1.66 -		} else { /* AX=E820, DX=534D4150, BX unrecognized */
    1.67 -		    goto int15_unimplemented;
    1.68 -		}
    1.69 -#else
    1.70 -                switch(regs.u.r16.bx)
    1.71 -                {
    1.72 -                    case 0:
    1.73 -                        write_word(ES, regs.u.r16.di, 0x00);
    1.74 -                        write_word(ES, regs.u.r16.di+2, 0x00);
    1.75 -                        write_word(ES, regs.u.r16.di+4, 0x00);
    1.76 -                        write_word(ES, regs.u.r16.di+6, 0x00);
    1.77 -
    1.78 -                        write_word(ES, regs.u.r16.di+8, 0xFC00);
    1.79 -                        write_word(ES, regs.u.r16.di+10, 0x0009);
    1.80 -                        write_word(ES, regs.u.r16.di+12, 0x0000);
    1.81 -                        write_word(ES, regs.u.r16.di+14, 0x0000);
    1.82 -
    1.83 -                        write_word(ES, regs.u.r16.di+16, 0x1);
    1.84 -                        write_word(ES, regs.u.r16.di+18, 0x0);
    1.85 -
    1.86 -                        regs.u.r32.ebx = 1;
    1.87 -
    1.88 -                        regs.u.r32.eax = 0x534D4150;
    1.89 -                        regs.u.r32.ecx = 0x14;
    1.90 -                        CLEAR_CF();
    1.91 -                        return;
    1.92 -                        break;
    1.93 -                    case 1:
    1.94 -                        extended_memory_size = inb_cmos(0x35);
    1.95 -                        extended_memory_size <<= 8;
    1.96 -                        extended_memory_size |= inb_cmos(0x34);
    1.97 -                        extended_memory_size *= 64;
    1.98 -                        if(extended_memory_size > 0x3bc000) // greater than EFF00000???
    1.99 -                        {
   1.100 -                            extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
   1.101 -                        }
   1.102 -                        extended_memory_size *= 1024;
   1.103 -                        extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
   1.104 -
   1.105 -                        if(extended_memory_size <= 15728640)
   1.106 -                        {
   1.107 -                            extended_memory_size = inb_cmos(0x31);
   1.108 -                            extended_memory_size <<= 8;
   1.109 -                            extended_memory_size |= inb_cmos(0x30);
   1.110 -                            extended_memory_size *= 1024;
   1.111 -                        }
   1.112 -
   1.113 -                        write_word(ES, regs.u.r16.di, 0x0000);
   1.114 -                        write_word(ES, regs.u.r16.di+2, 0x0010);
   1.115 -                        write_word(ES, regs.u.r16.di+4, 0x0000);
   1.116 -                        write_word(ES, regs.u.r16.di+6, 0x0000);
   1.117 -
   1.118 -                        write_word(ES, regs.u.r16.di+8, extended_memory_size);
   1.119 -                        extended_memory_size >>= 16;
   1.120 -                        write_word(ES, regs.u.r16.di+10, extended_memory_size);
   1.121 -                        extended_memory_size >>= 16;
   1.122 -                        write_word(ES, regs.u.r16.di+12, extended_memory_size);
   1.123 -                        extended_memory_size >>= 16;
   1.124 -                        write_word(ES, regs.u.r16.di+14, extended_memory_size);
   1.125 -
   1.126 -                        write_word(ES, regs.u.r16.di+16, 0x1);
   1.127 -                        write_word(ES, regs.u.r16.di+18, 0x0);
   1.128 -
   1.129 -                        regs.u.r32.ebx = 0;
   1.130 -                        regs.u.r32.eax = 0x534D4150;
   1.131 -                        regs.u.r32.ecx = 0x14;
   1.132 -                        CLEAR_CF();
   1.133 -                        return;
   1.134 -                        break;
   1.135 -                    default:  /* AX=E820, DX=534D4150, BX unrecognized */
   1.136 -                        goto int15_unimplemented;
   1.137 +        case 0x20: {
   1.138 +            Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
   1.139 +
   1.140 +            if (regs.u.r32.edx != 0x534D4150) /* SMAP */
   1.141 +                goto int15_unimplemented;
   1.142 +
   1.143 +            if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
   1.144 +                if (regs.u.r16.bx + 0x14 <= e820_table_size)
   1.145 +                    memcpyb(ES, regs.u.r16.di,
   1.146 +                            0xe000, 0x10 + regs.u.r16.bx, 0x14);
   1.147 +                regs.u.r32.ebx += 0x14;
   1.148 +                if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
   1.149 +                    regs.u.r32.ebx = 0;
   1.150 +            } else if (regs.u.r16.bx == 1) {
   1.151 +                Bit32u base, type;
   1.152 +                Bit16u off;
   1.153 +                for (off = 0; off < e820_table_size; off += 0x14) {
   1.154 +                    base = read_dword(0xe000, 0x10 + off);
   1.155 +                    type = read_dword(0xe000, 0x20 + off);
   1.156 +                    if ((base >= 0x100000) && (type == 1))
   1.157                          break;
   1.158                  }
   1.159 -#endif
   1.160 -	    } else {
   1.161 -	      // if DX != 0x534D4150)
   1.162 -	      goto int15_unimplemented;
   1.163 -	    }
   1.164 +                if (off == e820_table_size) {
   1.165 +                    SET_CF();
   1.166 +                    break;
   1.167 +                }
   1.168 +                memcpyb(ES, regs.u.r16.di, 0xe000, 0x10 + off, 0x14);
   1.169 +                regs.u.r32.ebx = 0;
   1.170 +            } else { /* AX=E820, DX=534D4150, BX unrecognized */
   1.171 +                goto int15_unimplemented;
   1.172 +            }
   1.173 +
   1.174 +            regs.u.r32.eax = 0x534D4150;
   1.175 +            regs.u.r32.ecx = 0x14;
   1.176 +            CLEAR_CF();
   1.177              break;
   1.178 -
   1.179 -        case 0x01: 
   1.180 -          // do we have any reason to fail here ?
   1.181 -          CLEAR_CF();
   1.182 -
   1.183 -          // my real system sets ax and bx to 0
   1.184 -          // this is confirmed by Ralph Brown list
   1.185 -          // but syslinux v1.48 is known to behave 
   1.186 -          // strangely if ax is set to 0
   1.187 -          // regs.u.r16.ax = 0;
   1.188 -          // regs.u.r16.bx = 0;
   1.189 -
   1.190 -          // Get the amount of extended memory (above 1M)
   1.191 -          regs.u.r8.cl = inb_cmos(0x30);
   1.192 -          regs.u.r8.ch = inb_cmos(0x31);
   1.193 +        }
   1.194 +
   1.195 +        case 0x01: {
   1.196 +            Bit16u off, e820_table_size = read_word(0xe000, 0x8) * 0x14;
   1.197 +            Bit32u base, type, size;
   1.198 +
   1.199 +            // do we have any reason to fail here ?
   1.200 +            CLEAR_CF();
   1.201 +
   1.202 +            // Get the amount of extended memory (above 1M)
   1.203 +            regs.u.r8.cl = inb_cmos(0x30);
   1.204 +            regs.u.r8.ch = inb_cmos(0x31);
   1.205            
   1.206 -          // limit to 15M
   1.207 -          if(regs.u.r16.cx > 0x3c00)
   1.208 -          {
   1.209 -            regs.u.r16.cx = 0x3c00;
   1.210 -          }
   1.211 -
   1.212 -          // Get the amount of extended memory above 16M in 64k blocs
   1.213 -          regs.u.r8.dl = inb_cmos(0x34);
   1.214 -          regs.u.r8.dh = inb_cmos(0x35);
   1.215 -
   1.216 -          // Set configured memory equal to extended memory
   1.217 -          regs.u.r16.ax = regs.u.r16.cx;
   1.218 -          regs.u.r16.bx = regs.u.r16.dx;
   1.219 -          break;
   1.220 +            // limit to 15M
   1.221 +            if (regs.u.r16.cx > (15*1024))
   1.222 +                regs.u.r16.cx = 15*1024;
   1.223 +
   1.224 +            // Find first RAM E820 entry >= 1MB.
   1.225 +            for (off = 0; off < e820_table_size; off += 0x14) {
   1.226 +                base = read_dword(0xe000, 0x10 + off);
   1.227 +                type = read_dword(0xe000, 0x20 + off);
   1.228 +                if ((base >= 0x100000) && (type == 1))
   1.229 +                    break;
   1.230 +            }
   1.231 +
   1.232 +            // If there is RAM above 16MB, return amount in 64kB chunks.
   1.233 +            regs.u.r16.dx = 0;
   1.234 +            if (off != e820_table_size) {
   1.235 +                size = base + read_dword(0xe000, 0x18 + off);
   1.236 +                if (size > 0x1000000) {
   1.237 +                    size -= 0x1000000;
   1.238 +                    regs.u.r16.dx = (Bit16u)(size >> 16);
   1.239 +                }
   1.240 +            }
   1.241 +
   1.242 +            // Set configured memory equal to extended memory
   1.243 +            regs.u.r16.ax = regs.u.r16.cx;
   1.244 +            regs.u.r16.bx = regs.u.r16.dx;
   1.245 +            break;
   1.246 +        }
   1.247  	default:  /* AH=0xE8?? but not implemented */
   1.248 -	  goto int15_unimplemented;
   1.249 -       }
   1.250 -       break;
   1.251 +            goto int15_unimplemented;
   1.252 +        }
   1.253 +        break;
   1.254      int15_unimplemented:
   1.255         // fall into the default
   1.256      default: