about summary refs log tree commit diff stats
path: root/kernel.soso/common.c
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-09-14 01:42:29 -0700
committerKartik Agaram <vc@akkartik.com>2019-09-14 01:45:55 -0700
commit46bb1d3157f9ad575c83a4bfa1e32b0d21bc8546 (patch)
tree28918f653d7cf970d33d5592047ef663289aca40 /kernel.soso/common.c
parentded2b24ce28f4a9df75ce40117f0f06f09574369 (diff)
downloadmu-46bb1d3157f9ad575c83a4bfa1e32b0d21bc8546.tar.gz
5650 - support a second OS: soso
https://github.com/ozkl/soso

+ Much smaller than Linux; builds instantly
+ Supports graphics
- No network support
- Doesn't work on a cloud server (yet?)
Diffstat (limited to 'kernel.soso/common.c')
-rw-r--r--kernel.soso/common.c441
1 files changed, 441 insertions, 0 deletions
diff --git a/kernel.soso/common.c b/kernel.soso/common.c
new file mode 100644
index 00000000..160a9198
--- /dev/null
+++ b/kernel.soso/common.c
@@ -0,0 +1,441 @@
+#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();
+    }
+}