/* * FindRamSize(): compute "vram_size" and "dram_size" based on the * contents of the Madam System Control Register. * * | x8 == 0 | x8 == 0 | x8 == 1 * MSYS | MSYS DRAM | MSYS DRAM | MSYS * 2:0 VRAM | 6:5 SET0 | 4:3 SET1 | 6:3 DRAM * --- ---- | ---- ---- | ---- ---- | ---- ---- * | 00 0 MB | 00 0 MB | * 001 1 MB | 01 1 MB | 01 1 MB | 0101 2 MB * 010 2 MB | 10 4 MB | 10 4 MB | 1010 8 MB * | 11 16MB | * * Combinations not shown in the above tables are not supported and * this routine is not guaranteed to return anything sensible (even * though it usually will do something vaguely rational). * * Note: only 16 MB address space is available for system memory, so * the actual amount of DRAM available is reduced so that the sum of * the DRAM and VRAM is no larger than 16 MB. */ void FindRamSize (void) { uint32 bits = *MSYSBits; /* * This may look complex, but it only takes about eight ARM * instructions to evaluate. Basicly, take each DRAM set size * field, and double it to get the left-shift count. Then * shift "a quarter megabyte" left by the count, casting off * anything less than a megabyte; this is easiest to do if you * shift "1" left by the count, then right by two. We turn it * into megabytes later. */ dram_size = (((1<<((bits>> (DRAMSIZE_SET0SHIFT-1))&(DRAMSIZE_SETMASK<<1)))>>2) + ((1<<((bits>> (DRAMSIZE_SET1SHIFT-1))&(DRAMSIZE_SETMASK<<1)))>>2)); /* * Only two VRAM sizes are defined. I'd guess that this gets * more complex if we start seeing more VRAM sizes. */ vram_size = ((bits & VRAMSIZE_MASK)>> VRAMSIZE_SHIFT); /* * Opera only provides 16 Megabytes of physical address space * to contain both the VRAM and DRAM, and the VRAM is above * the DRAM. If the calculations above give more than 16M of * total memory, trim DRAM back so the total is exactly 16M. */ if ((dram_size + vram_size)> 16) dram_size = 16 - vram_size; /* * The rest of the system wants to deal with byte counts, not * numbers of megabytes, so be nice to it. */ dram_size <<= 20; vram_size <<= 20; /* * As mentioned above, VRAM starts where DRAM ends; note the * actual VRAM starting address for future consumption. */ vram_start = (uint8 *) dram_size; if (vram_size> ONEMEG) two_vram_banks = TRUE; else two_vram_banks = FALSE; }