/************************************************************************************** $Id: memory.c,v 1.7 2002/04/20 11:22:44 reddawg Exp $ **************************************************************************************/ #include <ubixos/io.h> unsigned long mem_end, bse_end; void countMemory(void) { register unsigned long *mem; unsigned long mem_count, a; unsigned short memkb; unsigned char irq1, irq2; unsigned long cr0; /* save IRQ's */ irq1=inportb(0x21); irq2=inportb(0xA1); /* kill all irq's */ outportb(0x21, 0xFF); outportb(0xA1, 0xFF); mem_count=0; memkb=0; // store a copy of CR0 __asm__ __volatile("movl %%cr0, %%ebx":"=a"(cr0)::"ebx"); // invalidate the cache // write-back and invalidate the cache __asm__ __volatile__ ("wbinvd"); // plug cr0 with just PE/CD/NW // cache disable(486+), no-writeback(486+), 32bit mode(386+) __asm__ __volatile__("movl %%ebx, %%cr0" :: "a" (cr0 | 0x00000001 | 0x40000000 | 0x20000000) : "ebx"); do { memkb++; mem_count+=1024*1024; mem=(unsigned long *)mem_count; a=*mem; *mem=0x55AA55AA; // the empty asm calls tell gcc not to rely on whats in its registers // as saved variables (this gets us around GCC optimisations) asm("":::"memory"); if (*mem!=0x55AA55AA) { mem_count=0; } else { *mem=0xAA55AA55; asm("":::"memory"); if (*mem!=0xAA55AA55) { mem_count=0; } } asm("":::"memory"); *mem=a; } while(memkb<4096 && mem_count!=0); __asm__ __volatile__("movl %%ebx, %%cr0" :: "a" (cr0) : "ebx"); mem_end=memkb<<20; mem=(unsigned long *)0x413; bse_end=((*mem)&0xFFFF)<<6; outportb(0x21, irq1); outportb(0xA1, irq2); }