diff options
Diffstat (limited to 'memtestEDK/Memtest/SingleComponents/memsize.c')
-rw-r--r-- | memtestEDK/Memtest/SingleComponents/memsize.c | 346 |
1 files changed, 0 insertions, 346 deletions
diff --git a/memtestEDK/Memtest/SingleComponents/memsize.c b/memtestEDK/Memtest/SingleComponents/memsize.c deleted file mode 100644 index 84230d5..0000000 --- a/memtestEDK/Memtest/SingleComponents/memsize.c +++ /dev/null @@ -1,346 +0,0 @@ -/* memsize.c - MemTest-86 Version 3.3 - * - * Released under version 2 of the Gnu Public License. - * By Chris Brady - */ - -#include "test.h" -#include "defs.h" -#include "config.h" - -short e820_nr = 0; -short memsz_mode = SZ_MODE_BIOS; - -static ulong alt_mem_k = 0; -static ulong ext_mem_k = 0; -static struct e820entry e820[E820MAX]; - -static void sort_pmap(void); -static void memsize_820(void); -static void memsize_801(void); -static int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_bios, short old_nr); -static void memsize_linuxbios(); - -/* - * Find out how much memory there is. - */ -#pragma GCC push_options -#pragma GCC optimize ("O0") -void mem_size(void) -{ - int i = 0, flag = 0; - vv->test_pages = 0; - - /* Get the memory size from the BIOS */ - /* Determine the memory map */ - - if (query_linuxbios()) { - flag = 1; - } else if (query_pcbios()) { - flag = 2; - } - - /* On the first time thru only */ - /* Make a copy of the memory info table so that we can re-evaluate */ - /* The memory map later */ - if (e820_nr == 0 && alt_mem_k == 0 && ext_mem_k == 0) { - ext_mem_k = mem_info.e88_mem_k; - alt_mem_k = mem_info.e801_mem_k; - e820_nr = mem_info.e820_nr; - for (i=0; i< mem_info.e820_nr; i++) { - e820[i].addr = mem_info.e820[i].addr; - e820[i].size = mem_info.e820[i].size; - e820[i].type = mem_info.e820[i].type; - } - } - if (flag == 1) { - memsize_linuxbios(); - } else if (flag == 2) { - memsize_820(); - } - - /* Guarantee that pmap entries are in ascending order */ - sort_pmap(); - vv->plim_lower = 0; - vv->plim_upper = vv->pmap[vv->msegs-1].end; - - adj_mem(); -} -#pragma GCC pop_options - -static void sort_pmap(void) -{ - int i, j; - /* Do an insertion sort on the pmap, on an already sorted - * list this should be a O(1) algorithm. - */ - for(i = 0; i < vv->msegs; i++) { - /* Find where to insert the current element */ - for(j = i -1; j >= 0; j--) { - if (vv->pmap[i].start > vv->pmap[j].start) { - j++; - break; - } - } - /* Insert the current element */ - if (i != j) { - struct pmap temp; - temp = vv->pmap[i]; - mt86_memmove(&vv->pmap[j], &vv->pmap[j+1], - (i -j)* sizeof(temp)); - vv->pmap[j] = temp; - } - } -} -static void memsize_linuxbios(void) -{ - int i, n; - /* Build the memory map for testing */ - n = 0; - for (i=0; i < e820_nr; i++) { - unsigned long long end; - - if (e820[i].type != E820_RAM) { - continue; - } - end = e820[i].addr; - end += e820[i].size; - vv->pmap[n].start = (e820[i].addr + 4095) >> 12; - vv->pmap[n].end = end >> 12; - vv->test_pages += vv->pmap[n].end - vv->pmap[n].start; - n++; - } - vv->msegs = n; -} -static void memsize_820() -{ - int i, n, nr; - struct e820entry nm[E820MAX]; - unsigned long long start; - unsigned long long end; - - /* Clean up, adjust and copy the BIOS-supplied E820-map. */ - nr = sanitize_e820_map(e820, nm, e820_nr); - - /* If there is not a good 820 map use the BIOS 801/88 info */ - if (nr < 1 || nr > E820MAX) { - memsize_801(); - return; - } - - /* Build the memory map for testing */ - n = 0; - for (i=0; i<nr; i++) { - if (nm[i].type == E820_RAM || nm[i].type == E820_ACPI) { - start = nm[i].addr; - end = start + nm[i].size; - - /* Don't ever use memory between 640 and 1024k */ - if (start > RES_START && start < RES_END) { - if (end < RES_END) { - continue; - } - start = RES_END; - } - if (end > RES_START && end < RES_END) { - end = RES_START; - } - vv->pmap[n].start = (start + 4095) >> 12; - vv->pmap[n].end = end >> 12; - vv->test_pages += vv->pmap[n].end - vv->pmap[n].start; - n++; -#if 0 - int epmap = 0; - int lpmap = 0; - if(n > 12) { epmap = 34; lpmap = -12; } - hprint (11+n+lpmap,0+epmap,vv->pmap[n-1].start); - hprint (11+n+lpmap,10+epmap,vv->pmap[n-1].end); - hprint (11+n+lpmap,20+epmap,vv->pmap[n-1].end - vv->pmap[n-1].start); - dprint (11+n+lpmap,30+epmap,nm[i].type,0,0); -#endif - } - } - vv->msegs = n; -} - -static void memsize_801(void) -{ - ulong mem_size; - - /* compare results from 88 and 801 methods and take the greater */ - /* These sizes are for extended memory in 1k units. */ - - if (alt_mem_k < ext_mem_k) { - mem_size = ext_mem_k; - } else { - mem_size = alt_mem_k; - } - /* First we map in the first 640k */ - vv->pmap[0].start = 0; - vv->pmap[0].end = RES_START >> 12; - vv->test_pages = RES_START >> 12; - - /* Now the extended memory */ - vv->pmap[1].start = (RES_END + 4095) >> 12; - vv->pmap[1].end = (mem_size + 1024) >> 2; - vv->test_pages += mem_size >> 2; - vv->msegs = 2; -} - -/* - * Sanitize the BIOS e820 map. - * - * Some e820 responses include overlapping entries. The following - * replaces the original e820 map with a new one, removing overlaps. - * - */ -static int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_bios, - short old_nr) -{ - struct change_member { - struct e820entry *pbios; /* pointer to original bios entry */ - unsigned long long addr; /* address for this change point */ - }; - struct change_member change_point_list[2*E820MAX]; - struct change_member *change_point[2*E820MAX]; - struct e820entry *overlap_list[E820MAX]; - struct e820entry biosmap[E820MAX]; - struct change_member *change_tmp; - ulong current_type, last_type; - unsigned long long last_addr; - int chgidx, still_changing; - int overlap_entries; - int new_bios_entry; - int i; - - /* - Visually we're performing the following (1,2,3,4 = memory types)... - Sample memory map (w/overlaps): - ____22__________________ - ______________________4_ - ____1111________________ - _44_____________________ - 11111111________________ - ____________________33__ - ___________44___________ - __________33333_________ - ______________22________ - ___________________2222_ - _________111111111______ - _____________________11_ - _________________4______ - - Sanitized equivalent (no overlap): - 1_______________________ - _44_____________________ - ___1____________________ - ____22__________________ - ______11________________ - _________1______________ - __________3_____________ - ___________44___________ - _____________33_________ - _______________2________ - ________________1_______ - _________________4______ - ___________________2____ - ____________________33__ - ______________________4_ - */ - /* First make a copy of the map */ - for (i=0; i<old_nr; i++) { - biosmap[i].addr = orig_map[i].addr; - biosmap[i].size = orig_map[i].size; - biosmap[i].type = orig_map[i].type; - } - - /* bail out if we find any unreasonable addresses in bios map */ - for (i=0; i<old_nr; i++) { - if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) - return 0; - } - - /* create pointers for initial change-point information (for sorting) */ - for (i=0; i < 2*old_nr; i++) - change_point[i] = &change_point_list[i]; - - /* record all known change-points (starting and ending addresses) */ - chgidx = 0; - for (i=0; i < old_nr; i++) { - change_point[chgidx]->addr = biosmap[i].addr; - change_point[chgidx++]->pbios = &biosmap[i]; - change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; - change_point[chgidx++]->pbios = &biosmap[i]; - } - - /* sort change-point list by memory addresses (low -> high) */ - still_changing = 1; - while (still_changing) { - still_changing = 0; - for (i=1; i < 2*old_nr; i++) { - /* if <current_addr> > <last_addr>, swap */ - /* or, if current=<start_addr> & last=<end_addr>, swap */ - if ((change_point[i]->addr < change_point[i-1]->addr) || - ((change_point[i]->addr == change_point[i-1]->addr) && - (change_point[i]->addr == change_point[i]->pbios->addr) && - (change_point[i-1]->addr != change_point[i-1]->pbios->addr)) - ) - { - change_tmp = change_point[i]; - change_point[i] = change_point[i-1]; - change_point[i-1] = change_tmp; - still_changing=1; - } - } - } - - /* create a new bios memory map, removing overlaps */ - overlap_entries=0; /* number of entries in the overlap table */ - new_bios_entry=0; /* index for creating new bios map entries */ - last_type = 0; /* start with undefined memory type */ - last_addr = 0; /* start with 0 as last starting address */ - /* loop through change-points, determining affect on the new bios map */ - for (chgidx=0; chgidx < 2*old_nr; chgidx++) - { - /* keep track of all overlapping bios entries */ - if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) - { - /* add map entry to overlap list (> 1 entry implies an overlap) */ - overlap_list[overlap_entries++]=change_point[chgidx]->pbios; - } - else - { - /* remove entry from list (order independent, so swap with last) */ - for (i=0; i<overlap_entries; i++) - { - if (overlap_list[i] == change_point[chgidx]->pbios) - overlap_list[i] = overlap_list[overlap_entries-1]; - } - overlap_entries--; - } - /* if there are overlapping entries, decide which "type" to use */ - /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ - current_type = 0; - for (i=0; i<overlap_entries; i++) - if (overlap_list[i]->type > current_type) - current_type = overlap_list[i]->type; - /* continue building up new bios map based on this information */ - if (current_type != last_type) { - if (last_type != 0) { - new_bios[new_bios_entry].size = - change_point[chgidx]->addr - last_addr; - /* move forward only if the new size was non-zero */ - if (new_bios[new_bios_entry].size != 0) - if (++new_bios_entry >= E820MAX) - break; /* no more space left for new bios entries */ - } - if (current_type != 0) { - new_bios[new_bios_entry].addr = change_point[chgidx]->addr; - new_bios[new_bios_entry].type = current_type; - last_addr=change_point[chgidx]->addr; - } - last_type = current_type; - } - } - return(new_bios_entry); -} |