00001 /* 00002 panaLiX, Adrian Panasiuk 2002-5,8 00003 http://panalix.sourceforge.net/ 00004 ad.ek336@gmail.com 00005 00006 small osdev project 00007 provided under GPLv3 license. 00008 00009 http://random.mat.sbg.ac.at/~charly/server/node3.html 00010 linear congruential generator 00011 */ 00012 00013 #include "src/common/shared.hpp" 00014 #include "src/memory/memset.hpp" 00015 #include "src/memory/align.hpp" 00016 #include "src/memory/heap.hpp" 00017 #include "src/common/prng.hpp" 00018 #include "src/arch/x86/rtc.hpp" 00019 00020 using namespace Arch::x86::RTC; 00021 00022 namespace PRNG { 00023 00024 int x=1; 00025 00026 00027 int rand() { 00028 // 00029 // x= (x*397204094) % 0x7FFFFFFF; //HoaglinLGC 00030 x= (x*1103515245 + 12345) & 0x7FFFFFFF; //ANSI C 00031 return x; 00032 } 00033 00035 uint32 nextUint32(uint32 range) { 00036 if (range == 0) 00037 return 0; 00038 int r = rand(); 00039 if (r<0) r = -r; 00040 return r % range; 00041 } 00042 00043 void srand(uint32 seed) { 00044 x= seed; 00045 } 00046 00047 00048 volatile bool prng_seeded = false; 00049 //zbiera LSB z time stamp counter 00050 void rdtsc_runner(int a, int b) { 00051 static uint32 val=0; 00052 static uint32 shift=0; 00053 if (shift < 32) { 00054 uint64 t= rdtsc(); 00055 if (t & 1) 00056 val = val + (1 << shift); 00057 shift ++ ; 00058 } else { 00059 val += rdtsc(); 00060 srand (val); 00061 // dbPrintInt(val); 00062 val = 0; shift=0; 00063 prng_seeded=true; 00064 } 00065 } 00066 00069 void init() { 00070 // volatile sint32 val=0, sh=0; 00071 uint32 fl; 00072 asm volatile("pushf\npopl %0\nsti" : "=g" (fl)); 00073 // rtc_handle hndl = Arch::x86::RTC::add_proc(reinterpret_cast<RTC_proc>(rdtsc_runner), 1, false, reinterpret_cast<int>(&val), reinterpret_cast<int>(&sh)); 00074 Arch::x86::RTC::add_proc(reinterpret_cast<RTC_proc>(rdtsc_runner), 1, false, 0,0); 00075 while (!prng_seeded) ; //pierwsze seedowanie niech sie stanie 00076 // while (sh < 32) ; 00077 // del_proc(hndl); 00078 // 00079 //poniewaz na bochs kod powyzej nie dawal rezultatow, val == 0 zawsze wychodzil, wiec dodatkowo dodajemy fragment time stamp counter (niecale, poniewaz bardziej znaczace 00080 //bity moga miec niewiele entropii chodz to nie ma duzego znaczenia wiec moznaby nawet i dodawac) aby chodz troche randomizowac 00081 // 00082 // val += rdtsc() & 0xff; 00083 00084 asm volatile("pushl %0\npopf" : :"g"(fl)); 00085 // srand(val); 00086 } 00087 00088 } 00089 00090