/* common.c: 32-bit version Contains several functions that might be useful and can be shared by multiple sources. (e.g vmm and vmloader) */ #include "common.h" criticalSection sendstringfCS; criticalSection sendstringCS; int vbuildstring(char *str, int size, char *string, __builtin_va_list arglist) { unsigned char varlist[64]; char temps[100]; char workstring[strlen(string)]; int i,_i,l,strpos,vlc; l=strlen(string); vlc=0; if (size==0) return 0; strpos=0; // work on the copy of string, not the original for (i=0; i=size) _i=size-(strpos+_i-size); copymem(&str[strpos],temps,_i); strpos+=_i; break; } case 1: //hex { unsigned int x; x=__builtin_va_arg(arglist,unsigned int); itoa(_i,16,temps,100); _i=strlen(temps); if (strpos+_i>=size) _i=size-(strpos+_i-size); copymem(&str[strpos],temps,_i); strpos+=_i; break; } case 3: //%8, DWORD { unsigned int x; x=__builtin_va_arg(arglist,unsigned int); itoa(x,16,temps,100); appendzero(temps,8,100); _i=strlen(temps); if (strpos+_i>=size) _i=size-(strpos+_i-size); copymem(&str[strpos],temps,_i); strpos+=_i; break; } case 6: //%2, char { unsigned char x; x=__builtin_va_arg(arglist,int); itoa(x,16,temps,100); appendzero(temps,2,100); _i=strlen(temps); if (strpos+_i>=size) _i=size-(strpos+_i-size); copymem(&str[strpos],temps,_i); strpos+=_i; break; } case 255: printstring("UNDEFINED VARLIST",40,21,2,4); /*printstring(string,40,22,2,4); printstring(temps,40,23,2,4); printstring(str,40,24,2,4);*/\ if (strpos>=size) strpos=size-1; str[strpos]=0; return strpos; break; } if (varlist[vlc]==2) //string { char *s=__builtin_va_arg(arglist,char *); _i=strlen(s); if (strpos+_i>size) _i=size-(strpos+_i-size); copymem(&str[strpos],s,_i); strpos+=_i; } if (varlist[vlc]==4) //16 char hex { unsigned long long i=__builtin_va_arg(arglist,unsigned long long); unsigned int p1=i; unsigned int p2=(unsigned long long)(i>>32); itoa(p2,16,temps,100); appendzero(temps,8,100); _i=8; if (strpos+_i>size) _i=size-(strpos+_i-size); copymem(&str[strpos],temps,_i); strpos+=_i; if (strpos>=size) { str[size-1]=0; return size; //enough } itoa(p1,16,temps,100); appendzero(temps,8,100); _i=8; if (strpos+_i>size) _i=size-(strpos+_i-size); copymem(&str[strpos],temps,_i); strpos+=_i; } if (varlist[vlc]==5) //char { int c=__builtin_va_arg(arglist,int); str[strpos]=(char)c; strpos++; } i+=2; vlc++; //next paramtype continue; } else { //else a normal char str[strpos]=workstring[i]; strpos++; if (strpos>=size) { str[size-1]=0; return size; //enough } i++; } } if (strpos>=size) strpos=size-1; str[strpos]=0; return strpos; } void sendstring(char *s) { int i; csEnter(&sendstringCS); for (i=0; s[i] ; i++) sendchar(s[i]); csLeave(&sendstringCS); } void sendstringf(char *string, ...) { __builtin_va_list arglist; char temps[200]; int sl,i; __builtin_va_start(arglist,string); sl=vbuildstring(temps,200,string,arglist); __builtin_va_end(arglist); csEnter(&sendstringfCS); csEnter(&sendstringCS); if (sl>0) { for (i=0; i> 24)+1; } void csEnter(PcriticalSection CS) { int apicid=getAPICID()+1; //+1 so it never returns 0 //get current apicid (from cpuid) if ((CS->locked) && (CS->apicid==apicid)) { //already locked but the locker is this cpu, so allow, just increase lockcount CS->lockcount++; return; } spinlock(&(CS->locked)); //sets CS->locked to 1 //here so the lock is aquired and locked is 1 CS->lockcount=1; CS->apicid=apicid; } void csLeave(PcriticalSection CS) { int apicid=getAPICID()+1; //+1 so it never returns 0 if ((CS->locked) && (CS->apicid==apicid)) { CS->lockcount--; if (CS->lockcount==0) { //unlock CS->apicid=-1; //set to a invalid apicid CS->locked=0; } } } void zeromemory(void *address, unsigned int size) { unsigned int i; unsigned char *a=(unsigned char *)address; for (i=0; i < size; i++) a[i]=0; } void copymem(void *dest, void *src,int size) { int i; unsigned char *d=dest,*s=src; for (i=0; i=maxstringsize) return; //not enough memory for (i=0; i36) { if (err) *err=-1; return 0; } //some override checks //if it starts with 0x or $ make it base16 and set start to 2 or 1 respectivly while (input[start]) { if (input[start]=='-') { negative=!negative; start++; } else if (input[start]=='$') { base=16; start++; } else if ((input[start]=='0') && (input[start+1]=='x')) { base=16; start+=2; } else break; //nothing to parse } for (i=strlen(input)-1; i>=start ; i--,j++) { if ((input[i] >='0') && (input[i] <= '9')) //check if it's in the range of 0 to 9 c=input[i]-'0'; else if ((input[i] >='a') && (input[i] <= 'z')) //check if it's in the range of 0 to 9 c=10+input[i]-'a'; else if ((input[i] >='A') && (input[i] <= 'Z')) //check if it's in the range of 0 to 9 c=10+input[i]-'A'; else { if (err) *err=i; //not a valid character return result; } if (c>=base) { if (err) *err=i; //not a valid character return result; } /* c now contains the value in numerical state, now adjust it for i and the base given) */ result=result+c*(power(base,j)); if (negative) result=(int)(-result); } if (err) *err=0; return result; } int itoa(unsigned int value,int base, char *output,int maxsize) /* base: 10=decimal, 16=hexadecimal, 8 = octal, 2=binary , 1=youraloser, 0=diebitch */ { char tempbuf[maxsize]; /* will get the string but in reverse */ int i,j,t; if (base<2) return -1; if (base>36) return -1; if (value==0 && maxsize>1) { output[0]='0'; output[1]=0; return 2; } for (i=0; (value>0) && (i=0;t--,j++) output[j]=tempbuf[t]; if (i=24) { movelinesup(); //all other lines go up one line and currentdisplayline stays the same currentdisplayline=24; //just set it in case 'something' sets it different } else currentdisplayline++; } void updateCursor(void) { int cursorpos; cursorpos=currentdisplayline*80+currentdisplayrow; outportb(0x3D4, 14); outportb(0x3D5, (cursorpos>>8)); outportb(0x3D4, 15); outportb(0x3D5, cursorpos); } void displayline(char *s, ...) /* Displays a line on the screen and sets the 'currentline' down one pos */ { __builtin_va_list arglist; char temps[200]; int sl,i; __builtin_va_start(arglist,s); sl=vbuildstring(temps,200,s,arglist); __builtin_va_end(arglist); if (sl>0) { csEnter(&sendstringfCS); csEnter(&sendstringCS); for (i=0; i