diff options
Diffstat (limited to 'tools/iso/kernel.soso/common.c')
-rw-r--r-- | tools/iso/kernel.soso/common.c | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/tools/iso/kernel.soso/common.c b/tools/iso/kernel.soso/common.c new file mode 100644 index 00000000..446f21a2 --- /dev/null +++ b/tools/iso/kernel.soso/common.c @@ -0,0 +1,387 @@ +#include "common.h" +#include "screen.h" +#include "ttydriver.h" + +static BOOL gInterruptsWereEnabled = FALSE; + +// Write a byte out to the specified port. +void outb(uint16 port, uint8 value) { + asm volatile ("outb %1, %0" : : "dN" (port), "a" (value)); +} + +void outw(uint16 port, uint16 value) { + asm volatile ("outw %1, %0" : : "dN" (port), "a" (value)); +} + +uint8 inb(uint16 port) { + uint8 ret; + asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port)); + return ret; +} + +uint16 inw(uint16 port) { + uint16 ret; + asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port)); + return ret; +} + +// Copy len bytes from src to dest. +void* memcpy(uint8 *dest, const uint8 *src, uint32 len) { + const uint8 *sp = (const uint8 *)src; + uint8 *dp = (uint8 *)dest; + for(; len != 0; len--) *dp++ = *sp++; + + return dest; +} + +// Write len copies of val into dest. +void* memset(uint8 *dest, uint8 val, uint32 len) { + uint8 *temp = (uint8 *)dest; + for ( ; len != 0; len--) *temp++ = val; + + return dest; +} + +void* memmove(void* dest, const void* src, uint32 n) { + uint8* _dest; + uint8* _src; + + if ( dest < src ) { + _dest = ( uint8* )dest; + _src = ( uint8* )src; + + while ( n-- ) { + *_dest++ = *_src++; + } + } else { + _dest = ( uint8* )dest + n; + _src = ( uint8* )src + n; + + while ( n-- ) { + *--_dest = *--_src; + } + } + + return dest; +} + +int memcmp( const void* p1, const void* p2, uint32 c ) { + const uint8* su1, *su2; + int8 res = 0; + + for ( su1 = p1, su2 = p2; 0 < c; ++su1, ++su2, c-- ) { + if ( ( res = *su1 - *su2 ) != 0 ) { + break; + } + } + + return res; +} + +// Compare two strings. Should return -1 if +// str1 < str2, 0 if they are equal or 1 otherwise. +int strcmp(const char *str1, const char *str2) { + int i = 0; + int failed = 0; + while(str1[i] != '\0' && str2[i] != '\0') { + if(str1[i] != str2[i]) { + failed = 1; + break; + } + i++; + } + + if ((str1[i] == '\0' && str2[i] != '\0') || (str1[i] != '\0' && str2[i] == '\0')) { + failed = 1; + } + + return failed; +} + +int strncmp(const char *str1, const char *str2, int length) { + for (int i = 0; i < length; ++i) { + if (str1[i] != str2[i]) { + return str1[i] - str2[i]; + } + } + + return 0; +} + +// Copy the NULL-terminated string src into dest, and +// return dest. +char *strcpy(char *dest, const char *src) { + do { + *dest++ = *src++; + } + while (*src != 0); + *dest = '\0'; + + return dest; +} + +char *strcpyNonNull(char *dest, const char *src) { + do { + *dest++ = *src++; + } + while (*src != 0); + + return dest; +} + +//Copies the first num characters of source to destination. If the end of the source C string is found before num characters have been copied, +//destination is padded with zeros until a total of num characters have been written to it. +//No null-character is implicitly appended at the end of destination if source is longer than num. +//Thus, in this case, destination shall not be considered a null terminated C string. +char *strncpy(char *dest, const char *src, uint32 num) { + BOOL sourceEnded = FALSE; + for (uint32 i = 0; i < num; ++i) { + if (sourceEnded == FALSE && src[i] == '\0') { + sourceEnded = TRUE; + } + + if (sourceEnded) { + dest[i] = '\0'; + } + else { + dest[i] = src[i]; + } + } + + return dest; +} + +char* strcat(char *dest, const char *src) { + size_t i,j; + for (i = 0; dest[i] != '\0'; i++) + ; + for (j = 0; src[j] != '\0'; j++) + dest[i+j] = src[j]; + dest[i+j] = '\0'; + return dest; +} + +int strlen(const char *src) { + int i = 0; + while (*src++) + i++; + return i; +} + +int strFirstIndexOf(const char *src, char c) { + int i = 0; + while (src[i]) { + if (src[i] == c) { + return i; + } + i++; + } + + return -1; +} + +uint32 rand() { + static uint32 x = 123456789; + static uint32 y = 362436069; + static uint32 z = 521288629; + static uint32 w = 88675123; + + uint32 t; + + t = x ^ (x << 11); + x = y; y = z; z = w; + return w = w ^ (w >> 19) ^ t ^ (t >> 8); +} + +int atoi(char *str) { + int result = 0; + + for (int i = 0; str[i] != '\0'; ++i) { + result = result*10 + str[i] - '0'; + } + + return result; +} + +void itoa (char *buf, int base, int d) { + char *p = buf; + char *p1, *p2; + unsigned long ud = d; + int divisor = 10; + + + if (base == 'd' && d < 0) { + *p++ = '-'; + buf++; + ud = -d; + } + else if (base == 'x') { + divisor = 16; + } + + do { + int remainder = ud % divisor; + + *p++ = (remainder < 10) ? remainder + '0' : remainder + 'A' - 10; + } + while (ud /= divisor); + + + *p = 0; + + //Reverse BUF. + p1 = buf; + p2 = p - 1; + while (p1 < p2) { + char tmp = *p1; + *p1 = *p2; + *p2 = tmp; + p1++; + p2--; + } +} + +int sprintf_va(char* buffer, const char *format, __builtin_va_list vl) { + char c; + char buf[20]; + + int bufferIndex = 0; + + while ((c = *format++) != 0) { + if (c != '%') + buffer[bufferIndex++] = c; + else { + char *p; + + c = *format++; + switch (c) { + case 'x': + buf[0] = '0'; + buf[1] = 'x'; + //itoa (buf + 2, c, *((int *) arg++)); + itoa (buf + 2, c, __builtin_va_arg(vl, int)); + p = buf; + goto string; + break; + case 'd': + case 'u': + //itoa (buf, c, *((int *) arg++)); + itoa (buf, c, __builtin_va_arg(vl, int)); + p = buf; + goto string; + break; + + case 's': + //p = *arg++; + p = __builtin_va_arg(vl, char*); + if (! p) + p = "(null)"; + + string: + while (*p) + buffer[bufferIndex++] = (*p++); + break; + + default: + //buffer[bufferIndex++] = (*((int *) arg++)); + buffer[bufferIndex++] = __builtin_va_arg(vl, int); + break; + } + } + } + + buffer[bufferIndex] = '\0'; + + return bufferIndex; +} + +int sprintf(char* buffer, const char *format, ...) { + int result = 0; + + __builtin_va_list vl; + __builtin_va_start(vl, format); + + result = sprintf_va(buffer, format, vl); + + __builtin_va_end(vl); + + return result; +} + +void printkf(const char *format, ...) { + char buffer[1024]; + buffer[0] = 'k'; + buffer[1] = ':'; + buffer[2] = 0; + + Tty* tty = getActiveTTY(); + if (tty) { + __builtin_va_list vl; + __builtin_va_start(vl, format); + + sprintf_va(buffer+2, format, vl); + + __builtin_va_end(vl); + + Tty_PutText(tty, buffer); + + if (tty->flushScreen) { + tty->flushScreen(tty); + } + } +} + +void panic(const char *message, const char *file, uint32 line) { + disableInterrupts(); + + printkf("PANIC:%s:%d:%s\n", file, line, message); + + halt(); +} + +void warning(const char *message, const char *file, uint32 line) { + printkf("WARNING:%s:%d:%s\n", file, line, message); +} + +void panic_assert(const char *file, uint32 line, const char *desc) { + disableInterrupts(); + + printkf("ASSERTION-FAILED:%s:%d:%s\n", file, line, desc); + + halt(); +} + +uint32 readEsp() { + uint32 stack_pointer; + asm volatile("mov %%esp, %0" : "=r" (stack_pointer)); + + return stack_pointer; +} + +uint32 getCpuFlags() { + uint32 eflags = 0; + + asm("pushfl; pop %%eax; mov %%eax, %0": "=m"(eflags):); + + return eflags; +} + +BOOL isInterruptsEnabled() { + uint32 eflags = getCpuFlags(); + + uint32 interruptFlag = 0x200; //9th flag + + return (eflags & interruptFlag) == interruptFlag; +} + +void beginCriticalSection() { + gInterruptsWereEnabled = isInterruptsEnabled(); + + disableInterrupts(); +} + +void endCriticalSection() { + if (gInterruptsWereEnabled) { + enableInterrupts(); + } +} |