/* * MEMORY.CPP - Contains memory functions. * Copyright (C) 1998, 1999 Prashant TR * * Special thanks to Al Williams for all the information (both documented * and undocumented) regarding protected mode. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * See the file COPYING.TR for more details. */ // ID for this file. #define _MEMORY_CC_ #include "memory.h" int errflag = 0, sdram = 0; FILE *fp; char cmdline[20]; int rows[100]; int type[100]; extern "C" { int check_pm_controller(); int make_large_sel(); int make_normal_sel(); unsigned long time_memory(unsigned long, unsigned long); unsigned long time_no_cache_memory(unsigned long, unsigned long); unsigned long get_memory_size(); int a20(int); } // Write any string to the file and check for successfulness. void writestring(const char *string) { if (fprintf(fp, "%s", string) == EOF) { errflag = 2; checkerrors(); } } int sysinfo() { char output[256]; unsigned long time, mem_size, mem_type, count, mem_mod; unsigned long f, row, consistent; float timing, prevtiming; // Create output file. if ((fp = fopen("memory.txt", "w")) == NULL) { errflag = 1; checkerrors(); } writestring("\nMEMORY INFORMATION :\n\n"); mem_size = biosmemory(); sprintf(output, "\tBase Memory : %luK\n", mem_size); writestring(output); sprintf(output, "\tReserved Memory : %luK\n", 1024 - mem_size); writestring(output); if (check_pm_controller()) sdram = 1; // Activate A20. a20(1); if (!make_large_sel()) { a20(0); writestring("\tNo other information available.\n" "\tThe processor is in protected mode.\n"); fclose(fp); return 0; } mem_size = get_memory_size(); sprintf(output, "\tMemory Size : %luK\n", mem_size / 1024); writestring(output); if (mem_size / 1024 < 2048) { fclose(fp); return 0; } count = row = 0; for(f = 0; f <= 99; f++) rows[f] = 0; while (count < mem_size) { time = 0; for(f = 1; f <= 10; f++) time += time_no_cache_memory(count , 512L * 1024L); timing = time * 100000.0 / 1193180.0 / 512; // Check memory type. if (((timing <= 20) && (sdram)) || (timing <= 10)) mem_type = 0; // SDRAM. else if (timing <= 20) mem_type = 1; // EDO DRAM. else mem_type = 2; // FPM. if (!mem_type) mem_mod = 32 * 1024L; if (mem_type == 1) mem_mod = 32 * 1024L; if (mem_type == 2) mem_mod = 8 * 1024L; if ((mem_size - count) / 1024 < mem_mod) mem_mod = (mem_size - count) / 1024; rows[row] += mem_mod / 1024; type[row] = mem_type; row += 2; count += mem_mod * 1024L; } // Write out the result. row = 0; while (rows[row]) { sprintf(output, "\tMemory Type / Logical Row : %s" " at Row %lu, %uMB\n", (!type[row]) ? "SDRAM" : (type[row] == 1) ? "EDO DRAM" : (type[row] == 2) ? "FPM" : "Unknown", row, rows[row]); writestring(output); row += 2; } // Get the timimg. time = 0; for(f = 1; f <= 10; f++) time += time_no_cache_memory(0, 512L * 1024L); timing = time * 100000.0 / 1193180.0 / 512; // Main memory speed. sprintf(output, "\tMain Memory Speed : %1.2fns/byte\n", timing * 1000 / 1024L); writestring(output); sprintf(output, "\tMain Memory Bank Timing : %1.2fns\n", timing * 8000 / 1024L); writestring(output); // Get cache information. row = 1; // Level 1 cache. time = time_memory(0x100000, 1024L); prevtiming = time * 1000000.0 / 1193180.0; consistent = 0; for(f = 1; f <= (mem_size / 1024 - 1024L); f *= 2) { count = time_memory(0x100000, f * 1024L); timing = count * 1000000.0 / 1193180.0 / f; if (fabs((double)timing - prevtiming) > 2) { if (consistent) { sprintf(output, "\tLevel %lu Cache Size : " "%luKB\n", row, f >> 1); writestring(output); sprintf(output, "\tLevel %lu Cache Speed : " "%1.2fns/byte\n", row++, prevtiming * 1000 / 1024L); writestring(output); } consistent=0; } if (abs(prevtiming - timing) <= 2) consistent = 1; else consistent = 0; prevtiming = timing; if (f > 4096) break; } // Reset selector. make_normal_sel(); // Deactivate A20. a20(0); fclose(fp); return 0; } void open_stderr() { fclose(stdout); fclose(&_streams[2]); if (fopen("nul", "wb") == NULL) exit(0x7f); if (fopen("nul", "wb") == NULL) exit(0x7f); if ((stderr = fopen("errors.$$$", "ab")) == NULL) exit(0x7f); } void get_cmdline() { if ((fp = fopen("cmdline.$$$", "rb")) == NULL) exit (0x7f); if (fscanf(fp, "%s", cmdline) != 1) { fclose(fp); exit (0x7f); } fclose(fp); unlink("cmdline.$$$"); } #pragma argsused // The main function. int main(int argc, char **argv) { open_stderr(); get_cmdline(); if (!strcmp(cmdline, "sysinfo")) return (sysinfo()); return 0; }