]> Joshua Wise's Git repositories - netwatch.git/commitdiff
Apply patches from jdpotter@google.com, as submitted to NetWatch Maintainer Team...
authorJoshua Alan Wise <jwise@unix36.andrew.cmu.edu>
Wed, 19 Aug 2009 01:04:37 +0000 (21:04 -0400)
committerJoshua Alan Wise <jwise@unix36.andrew.cmu.edu>
Wed, 19 Aug 2009 01:04:37 +0000 (21:04 -0400)
14 files changed:
include/cpuid.h [new file with mode: 0644]
include/minilib.h
include/output.h
include/state.h [new file with mode: 0644]
lib/cpuid.S [new file with mode: 0644]
lib/crc32.c
lib/minilib.c
lib/state.c [new file with mode: 0644]
lwip/src/include/lwipopts.h
net/http/fs.c
netwatch/keyboard.c
netwatch/pagingstub-asm.S [moved from netwatch/pagingstub-asm.s with 100% similarity]
netwatch/pagingstub.c
netwatch/traps.c

diff --git a/include/cpuid.h b/include/cpuid.h
new file mode 100644 (file)
index 0000000..d6a54a1
--- /dev/null
@@ -0,0 +1,50 @@
+/* cpuid.h
+ * Definitions needed for CPUID wrapper
+ * NetWatch system management mode administration console
+ *
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,           
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY           
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CPUID_H
+#define __CPUID_H
+
+#include <stdint.h>
+
+struct cpuid_result {
+       uint32_t eax;
+       uint32_t ebx;
+       uint32_t ecx;
+       uint32_t edx;
+};
+
+void cpuid(int eax, struct cpuid_result *output);
+
+#endif /* __CPUID_H */
+
index 2e7eca66831b8c3b0c1a1dc8d123c4c95df1573a..d5afd2b3cd024f189928554346a51d2da46077bf 100644 (file)
@@ -15,6 +15,7 @@
 
 extern void memcpy(void *dest, const void *src, int bytes);
 extern void memset(void *dest, int data, int bytes);
+extern void *memchr(const void *buf, char c, int maxlen);
 extern void memmove(void *dest, void *src, int bytes);
 extern int memcmp(const char *a2, const char *a1, int bytes);
 extern int strcmp(const char *a2, const char *a1);
@@ -24,6 +25,7 @@ extern void strcat(char *dest, char *src);
 extern void strcpy(char *a2, const char *a1);
 extern void puts(const char *c);
 extern void tohex(char *s, unsigned long l);
+extern void btohex(char *s, unsigned char c);
 extern void puthex(unsigned long l);
 extern int vsprintf(char *s, const char *fmt, va_list args);
 extern int vsnprintf(char *s, int size, const char *fmt, va_list args);
index 5c1101af84ae53508893cbf3fe68d8ab147b32f2..7964f0304a3d32f51df8fffefd881f9322cfb1d7 100644 (file)
 extern void (*output)(const char *s);
 extern void (*outputf)(const char *s, ...);
 
+#if DEBUG80
+#define DBG(x) outb(0x80, x)
+#else
+#define DBG(x)
+#endif
+
 #endif
diff --git a/include/state.h b/include/state.h
new file mode 100644 (file)
index 0000000..fd19612
--- /dev/null
@@ -0,0 +1,99 @@
+/* state.h
+ * Definitions for SMM saved-state manipulation functions.
+ * NetWatch system management mode administration console
+ *
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,           
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY           
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __STATE_H
+#define __STATE_H
+
+#include <stdint.h>
+
+enum state_reg_t {
+       /* Common registers */
+       STATE_REV,
+       STATE_REG_SMBASE,
+       STATE_REG_IORESTART,
+       STATE_REG_HALTRESTART,
+
+       /* 32-bit registers (still available in 64-bit mode) */
+       STATE_REG_EAX,
+       STATE_REG_EBX,
+       STATE_REG_ECX,
+       STATE_REG_EDX,
+       STATE_REG_ESI,
+       STATE_REG_EDI,
+       STATE_REG_ESP,
+       STATE_REG_EBP,
+       STATE_REG_EIP,
+       STATE_REG_EFLAGS,
+       STATE_REG_CR0,
+       STATE_REG_CR3,
+
+       STATE_REG_CS,
+       STATE_REG_SS,
+       STATE_REG_DS,
+       STATE_REG_ES,
+       STATE_REG_FS,
+       STATE_REG_GS,
+
+       /* 64-bit registers */
+       STATE_REG_RAX,
+       STATE_REG_RBX,
+       STATE_REG_RCX,
+       STATE_REG_RDX,
+       STATE_REG_RSI,
+       STATE_REG_RDI,
+       STATE_REG_RSP,
+       STATE_REG_RBP,
+       STATE_REG_R8,
+       STATE_REG_R9,
+       STATE_REG_R10,
+       STATE_REG_R11,
+       STATE_REG_R12,
+       STATE_REG_R13,
+       STATE_REG_R14,
+       STATE_REG_R15,
+       STATE_REG_RIP
+};
+
+enum smm_type {
+        SMM_TYPE_UNKNOWN,
+        SMM_TYPE_32,
+        SMM_TYPE_64
+};
+
+uint64_t state_get_reg (enum state_reg_t reg);
+int state_reg_size (enum state_reg_t reg);
+int state_set_reg (enum state_reg_t reg, uint64_t value);
+
+#endif /* __STATE_H */
+
diff --git a/lib/cpuid.S b/lib/cpuid.S
new file mode 100644 (file)
index 0000000..6216a56
--- /dev/null
@@ -0,0 +1,56 @@
+/* cpuid.S
+ * CPUID wrapper
+ * NetWatch system management mode administration console
+ *
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,           
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY           
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.global cpuid
+cpuid:
+       // Save registers
+       push %ebx
+       push %edi
+
+       // Load arguments from stack
+       mov 12(%esp), %eax
+       mov 16(%esp), %edi
+
+       cpuid
+
+       // Save results into output pointer
+       mov %eax, (%edi)
+       mov %ebx, 4(%edi)
+       mov %ecx, 8(%edi)
+       mov %edx, 12(%edi)
+
+       // All done!
+       pop %edi
+       pop %ebx
+       ret
index 43f9d7a876ad1dee6818f4b85b56f7861d86af4d..a5512f64a4b3603543a8eecd42a3d1bd7267c7de 100644 (file)
@@ -3,7 +3,7 @@
 /* code from http://www.faqs.org/faqs/compression-faq/part1/section-26.html,
  * presumed public domain */
 
-uint32_t crc32_table[256];
+static uint32_t crc32_table[256];
 
 uint32_t crc32(uint8_t *buf, int len, uint32_t crc0)
 {
index 392eae7abcaf146e8f09ce8a4b4f3cec32457b6e..935d0c40bc5fb25f62dd5d30bac40e09ec1d6b24 100644 (file)
@@ -74,6 +74,17 @@ void memset(void *dest, int data, int bytes)
                *(cdest++) = (unsigned char)data;
 }
 
+void *memchr(const void *buf, char c, int maxlen)
+{
+       const char * cbuf = buf;
+       while (maxlen--)
+       {
+               if (*cbuf == c) return (void *)cbuf;
+               cbuf++;
+       }
+       return 0;
+}
+
 void memmove(void *dest, void *src, int bytes)
 {
        char * cdest = dest;
@@ -157,6 +168,12 @@ void tohex(char *s, unsigned long l)
        }
 }
 
+void btohex(char *s, unsigned char c)
+{
+       s[0] = hexarr[c >> 4];
+       s[1] = hexarr[c & 0xF];
+}
+
 void puthex(unsigned long l)
 {
        char d[9];
diff --git a/lib/state.c b/lib/state.c
new file mode 100644 (file)
index 0000000..368029b
--- /dev/null
@@ -0,0 +1,239 @@
+/* state.c
+ * SMM saved state manipulation functions.
+ * NetWatch system management mode administration console
+ *
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,           
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY           
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "state.h"
+#include <cpuid.h>
+
+/* Size flags. */
+#define SZ_BYTE                0x10000000
+#define SZ_WORD                0x20000000
+#define SZ_DWORD       0x40000000
+#define SZ_QWORD       0x80000000
+#define OFFSET_MASK    0x0FFFFFFF
+
+static const uint32_t offset_table_legacy[] = {
+       [STATE_REV]             = 0xfefc | SZ_DWORD,
+       [STATE_REG_SMBASE]      = 0xfef8 | SZ_DWORD,
+       [STATE_REG_IORESTART]   = 0xff00 | SZ_WORD,
+       [STATE_REG_HALTRESTART] = 0xff02 | SZ_WORD,
+
+       [STATE_REG_EAX]         = 0xffd0 | SZ_DWORD,
+       [STATE_REG_EBX]         = 0xffdc | SZ_DWORD,
+       [STATE_REG_ECX]         = 0xffd4 | SZ_DWORD,
+       [STATE_REG_EDX]         = 0xffd8 | SZ_DWORD,
+       [STATE_REG_ESI]         = 0xffe8 | SZ_DWORD,
+       [STATE_REG_EDI]         = 0xffec | SZ_DWORD,
+       [STATE_REG_ESP]         = 0xffe0 | SZ_DWORD,
+       [STATE_REG_EBP]         = 0xffe4 | SZ_DWORD,
+       [STATE_REG_EIP]         = 0xfff0 | SZ_DWORD,
+       [STATE_REG_EFLAGS]      = 0xfff4 | SZ_DWORD,
+       [STATE_REG_CR0]         = 0xfffc | SZ_DWORD,
+       [STATE_REG_CR3]         = 0xfff8 | SZ_DWORD,
+
+       [STATE_REG_CS]          = 0xffac | SZ_DWORD,
+       [STATE_REG_SS]          = 0xffb0 | SZ_DWORD,
+       [STATE_REG_DS]          = 0xffb4 | SZ_DWORD,
+       [STATE_REG_ES]          = 0xffa8 | SZ_DWORD,
+       [STATE_REG_FS]          = 0xffb8 | SZ_DWORD,
+       [STATE_REG_GS]          = 0xffbc | SZ_DWORD
+};
+
+#define MAX_REG_LEGACY (sizeof(offset_table_legacy)/sizeof(uint32_t))
+
+static const uint32_t offset_table_amd64[] = {
+       [STATE_REV]             = 0xfefc | SZ_DWORD,
+       [STATE_REG_SMBASE]      = 0xff00 | SZ_DWORD,
+       [STATE_REG_IORESTART]   = 0xfec8 | SZ_BYTE,
+       [STATE_REG_HALTRESTART] = 0xfec9 | SZ_BYTE,
+
+       [STATE_REG_EAX]         = 0xfff8 | SZ_DWORD,
+       [STATE_REG_EBX]         = 0xffe0 | SZ_DWORD,
+       [STATE_REG_ECX]         = 0xfff0 | SZ_DWORD,
+       [STATE_REG_EDX]         = 0xffe8 | SZ_DWORD,
+       [STATE_REG_ESI]         = 0xffc8 | SZ_DWORD,
+       [STATE_REG_EDI]         = 0xffc0 | SZ_DWORD,
+       [STATE_REG_ESP]         = 0xffd8 | SZ_DWORD,
+       [STATE_REG_EBP]         = 0xffd0 | SZ_DWORD,
+       [STATE_REG_EIP]         = 0xff78 | SZ_DWORD,
+       [STATE_REG_EFLAGS]      = 0xff70 | SZ_DWORD,
+       [STATE_REG_CR0]         = 0xff58 | SZ_DWORD,
+       [STATE_REG_CR3]         = 0xff50 | SZ_DWORD,
+
+       [STATE_REG_CS]          = 0xfe10 | SZ_DWORD,
+       [STATE_REG_SS]          = 0xfe20 | SZ_DWORD,
+       [STATE_REG_DS]          = 0xfe30 | SZ_DWORD,
+       [STATE_REG_ES]          = 0xfe00 | SZ_DWORD,
+       [STATE_REG_FS]          = 0xfe40 | SZ_DWORD,
+       [STATE_REG_GS]          = 0xfe50 | SZ_DWORD,
+
+       [STATE_REG_RAX]         = 0xfff8 | SZ_QWORD,
+       [STATE_REG_RBX]         = 0xffe0 | SZ_QWORD,
+       [STATE_REG_RCX]         = 0xfff0 | SZ_QWORD,
+       [STATE_REG_RDX]         = 0xffe8 | SZ_QWORD,
+       [STATE_REG_RSI]         = 0xffc8 | SZ_QWORD,
+       [STATE_REG_RDI]         = 0xffc0 | SZ_QWORD,
+       [STATE_REG_RSP]         = 0xffd8 | SZ_QWORD,
+       [STATE_REG_RBP]         = 0xffd0 | SZ_QWORD,
+       [STATE_REG_R8]          = 0xffb8 | SZ_QWORD,
+       [STATE_REG_R9]          = 0xffb0 | SZ_QWORD,
+       [STATE_REG_R10]         = 0xffa8 | SZ_QWORD,
+       [STATE_REG_R11]         = 0xffa0 | SZ_QWORD,
+       [STATE_REG_R12]         = 0xff98 | SZ_QWORD,
+       [STATE_REG_R13]         = 0xff90 | SZ_QWORD,
+       [STATE_REG_R14]         = 0xff88 | SZ_QWORD,
+       [STATE_REG_R15]         = 0xff80 | SZ_QWORD,
+       [STATE_REG_RIP]         = 0xff78 | SZ_QWORD
+};
+
+#define MAX_REG_AMD64 (sizeof(offset_table_amd64)/sizeof(uint32_t))
+
+static enum smm_type smm_type = SMM_TYPE_64;
+
+/* Probe CPUID to figure out what kind of processor this actually is.
+ * We memoize this in 'smm_type', so cpuid only needs to happen once.
+ */
+
+static void check_smm_type (void) {
+
+       struct cpuid_result r;
+
+       if (smm_type != SMM_TYPE_UNKNOWN)
+               return;
+
+       cpuid(0x80000000, &r);
+
+       if (r.eax < 0x80000001) {
+               smm_type = SMM_TYPE_32;
+               return;
+       }
+
+       cpuid(0x80000001, &r);
+
+       if (r.edx & 0x20000000) {
+               smm_type = SMM_TYPE_64;
+       } else {
+               smm_type = SMM_TYPE_32;
+       }
+}
+
+/* Get the offset of a register, by looking up in the appropriate table.
+ */
+
+static unsigned long get_offset(enum state_reg_t reg) {
+
+       check_smm_type();
+
+       if (smm_type == SMM_TYPE_32 && reg < MAX_REG_LEGACY)
+               return offset_table_legacy[reg];
+       else if (smm_type == SMM_TYPE_64 && reg < MAX_REG_AMD64)
+               return offset_table_amd64[reg];
+       else
+               return 0;
+}
+
+/* Which variety of processor are we running on?
+ */
+
+enum smm_type state_get_type (void) {
+       check_smm_type();
+       return smm_type;
+}
+
+/* Get a register.
+ *
+ * We assume that Aseg is always direct-mapped at 0xA0000. This may
+ * not be the case in the future, with multiple cores, but it is a
+ * safe assumption now.
+ */
+
+uint64_t state_get_reg (enum state_reg_t reg) {
+       unsigned long offset = get_offset(reg);
+       void * addr;
+       uint64_t value;
+
+       if (!offset)
+               return 0;
+
+       addr = (void *)((offset & OFFSET_MASK) + 0xA0000);
+
+       if (offset & SZ_BYTE)
+               value = *(uint8_t *)addr;
+       else if (offset & SZ_WORD)
+               value = *(uint16_t *)addr;
+       else if (offset & SZ_DWORD)
+               value = *(uint32_t *)addr;
+       else
+               value = *(uint64_t *)addr;
+
+       return value;
+}
+
+/* Get the size of a register, extracted from the saved state offset table.
+ */
+
+int state_reg_size (enum state_reg_t reg) {
+       unsigned long offset = get_offset(reg);
+
+       if (offset & SZ_BYTE) return 1;
+       else if (offset & SZ_WORD) return 2;
+       else if (offset & SZ_DWORD) return 4;
+       else if (offset & SZ_QWORD) return 8;
+       else return 0;
+}
+
+/* Modify a saved register.
+ *
+ * The same caveat about aseg's location applies here as well.
+ */
+
+int state_set_reg (enum state_reg_t reg, uint64_t value) {
+       unsigned long offset = get_offset(reg);
+       void * addr;
+
+       if (!offset)
+               return -1;
+
+       addr = (void *)((offset & OFFSET_MASK) + 0xA0000);
+
+       if (offset & SZ_BYTE)
+               *(uint8_t *)addr = (uint8_t) value;
+       else if (offset & SZ_WORD)
+               *(uint16_t *)addr = (uint16_t) value;
+       else if (offset & SZ_DWORD)
+               *(uint32_t *)addr = (uint32_t) value;
+       else
+               *(uint64_t *)addr = value;
+
+       return 0;
+}
index 368bf869f8cf821826049b73a0c25cfe9f843ebc..31a53f1b5b554f8defaa326cbf54ed16edbee382 100644 (file)
@@ -29,7 +29,11 @@ extern void _memcpy(void *dest, const void *src, int bytes);
 
 #define LWIP_STATS 1
 #define LWIP_STATS_DISPLAY 1
-#define U16_F "d"
-#define U32_F "d"
+#define U16_F "u"
+#define S16_F "d"
+#define X16_F "x"
+#define U32_F "u"
+#define S32_F "d"
+#define X32_F "x"
 
 #endif
index 0bf11cb9c97a2440a8e2a5ad85e357a3fa266774..4fe2c41100c27ec94b60f8665bcb3e5e687d5cab 100644 (file)
 #include <paging.h>
 #include <output.h>
 
+static char http_output_buffer[1024];
+
 /*-----------------------------------------------------------------------------------*/
 
 void handle_regs(struct fs_file *file)
 {
-  static char buf[2048];
-  
-  sprintf(buf,
+  file->len = snprintf(http_output_buffer, sizeof(http_output_buffer),
     "<html><head><title>Registers</title></head><body>"
     "<p>At the time you requested this page, the system's registers were:</p>"
     "<tt><pre>"
@@ -64,54 +64,57 @@ void handle_regs(struct fs_file *file)
     *(unsigned long*)0xAFFF8,
     *(unsigned long*)0xAFFF0,
     *(unsigned long*)0xAFFF4);
-    
   
-  file->data = buf;
-  file->len = strlen(buf)-1;
+  file->data = http_output_buffer;
 }
 
+#define LEFT (sizeof(http_output_buffer) - len)
+
 void handle_backtrace(struct fs_file *file)
 {
-  static char buf[2048];
-  static char buf2[64];
   int i = 10;
+  int len;
   unsigned long *pebp, *peip;
   unsigned long ebp;
   unsigned long cr3;
+
+  char * buf = http_output_buffer;
   
   strcpy(buf, "<html><head><title>Backtrace</title></head><body><tt><pre>");
+  len = strlen(buf);
   ebp = *(unsigned long *)0xAFFE4;
   cr3 = *(unsigned long *)0xAFFF8;
   
-  sprintf(buf2, "0x%08x, from\n", *(unsigned long*)0xAFFF0);
-  strcat(buf, buf2);
+  len += snprintf(buf + len, LEFT, "0x%08x, from\n", *(unsigned long*)0xAFFF0);
   
   /* I never thought I'd do this again. */
   while ((peip = demap(cr3, ebp+4)) != 0x0 && i--)
   {
-    sprintf(buf2, "0x%08x, from\n", *peip);
-    strcat(buf, buf2);
+    len += snprintf(buf + len, LEFT, "0x%08x, from\n", *peip);
+
     pebp = demap(cr3, ebp);
     if (!pebp)
     {
-      strcat(buf, "&lt;unreadable %ebp&gt;\n");
+      len += snprintf(buf + len, LEFT, "&lt;unreadable %ebp&gt;\n");
       break;
     }
     if (ebp >= *pebp && *pebp)
     {
-      strcat(buf, "&lt;recursive %ebp&gt;\n");
+      len += snprintf(buf + len, LEFT, "&lt;recursive %ebp&gt;\n");
       break;
     }
     ebp = *pebp;
   }
+
   if (i == -1)
-    strcat(buf, "...\n");
+    len += snprintf(buf + len, LEFT, "...\n");
   else
-    strcat(buf, "&lt;root&gt;");
-  strcat(buf, "</pre></tt></body></html>");
+    len += snprintf(buf + len, LEFT, "&lt;root&gt;");
+
+  len += snprintf(buf + len, LEFT, "</pre></tt></body></html>");
   
   file->data = buf;
-  file->len = strlen(buf)-1;
+  file->len = len;
 }
 
 void handle_reboot(struct fs_file *file)
index 64be4452182ff5f7cef723771501dfb0740d1470..b4f1b58df6a6be85957c2bd37009659e119d1806 100644 (file)
@@ -18,126 +18,153 @@ static int kbd_inj_start = 0;
 static int kbd_inj_end = 0;
 int kbd_mode = 1;
 
-static const char scancodes2[][2][8] = {
-       ['a'] = { "\x1c", "\xf0\x1c" },
-       ['b'] = { "\x32", "\xf0\x32" },
-       ['c'] = { "\x21", "\xf0\x21" },
-       ['d'] = { "\x23", "\xf0\x23" },
-       ['e'] = { "\x24", "\xf0\x24" },
-       ['f'] = { "\x2b", "\xf0\x2b" },
-       ['g'] = { "\x34", "\xf0\x34" },
-       ['h'] = { "\x33", "\xf0\x33" },
-       ['i'] = { "\x43", "\xf0\x43" }, 
-       ['j'] = { "\x3b", "\xf0\x3b" },
-       ['k'] = { "\x42", "\xf0\x42" },
-       ['l'] = { "\x4b", "\xf0\x4b" },
-       ['m'] = { "\x3a", "\xf0\x3a" },
-       ['n'] = { "\x31", "\xf0\x31" },
-       ['o'] = { "\x44", "\xf0\x44" },
-       ['p'] = { "\x4d", "\xf0\x4d" },
-       ['q'] = { "\x15", "\xf0\x15" },
-       ['r'] = { "\x2d", "\xf0\x2d" },
-       ['s'] = { "\x1b", "\xf0\x1b" },
-       ['t'] = { "\x2c", "\xf0\x2c" },
-       ['u'] = { "\x3c", "\xf0\x3c" },
-       ['v'] = { "\x2a", "\xf0\x2a" },
-       ['w'] = { "\x1d", "\xf0\x1d" },
-       ['x'] = { "\x22", "\xf0\x22" },
-       ['y'] = { "\x35", "\xf0\x35" },
-       ['z'] = { "\x1a", "\xf0\x1a" },
-       ['A'] = { "\x12\x1c", "\xf0\x1c\xf0\x12" },
-       ['B'] = { "\x12\x32", "\xf0\x32\xf0\x12" },
-       ['C'] = { "\x12\x21", "\xf0\x21\xf0\x12" },
-       ['D'] = { "\x12\x23", "\xf0\x23\xf0\x12" },
-       ['E'] = { "\x12\x24", "\xf0\x24\xf0\x12" },
-       ['F'] = { "\x12\x2b", "\xf0\x2b\xf0\x12" },
-       ['G'] = { "\x12\x34", "\xf0\x34\xf0\x12" },
-       ['H'] = { "\x12\x33", "\xf0\x33\xf0\x12" },
-       ['I'] = { "\x12\x43", "\xf0\x43\xf0\x12" },
-       ['J'] = { "\x12\x3b", "\xf0\x3b\xf0\x12" },
-       ['K'] = { "\x12\x42", "\xf0\x42\xf0\x12" },
-       ['L'] = { "\x12\x4b", "\xf0\x4b\xf0\x12" },
-       ['M'] = { "\x12\x3a", "\xf0\x3a\xf0\x12" },
-       ['N'] = { "\x12\x31", "\xf0\x31\xf0\x12" },
-       ['O'] = { "\x12\x44", "\xf0\x44\xf0\x12" },
-       ['P'] = { "\x12\x4d", "\xf0\x4d\xf0\x12" },
-       ['Q'] = { "\x12\x15", "\xf0\x15\xf0\x12" },
-       ['R'] = { "\x12\x2d", "\xf0\x2d\xf0\x12" },
-       ['S'] = { "\x12\x1b", "\xf0\x1b\xf0\x12" },
-       ['T'] = { "\x12\x2c", "\xf0\x2c\xf0\x12" },
-       ['U'] = { "\x12\x3c", "\xf0\x3c\xf0\x12" },
-       ['V'] = { "\x12\x2a", "\xf0\x2a\xf0\x12" },
-       ['W'] = { "\x12\x1d", "\xf0\x1d\xf0\x12" },
-       ['X'] = { "\x12\x22", "\xf0\x22\xf0\x12" },
-       ['Y'] = { "\x12\x35", "\xf0\x35\xf0\x12" },
-       ['Z'] = { "\x12\x1a", "\xf0\x1a\xf0\x12" },
-       ['`'] = { "\x0e", "\xf0\x0e" },
-       ['~'] = { "\x12\x0e", "\xf0\x0e\xf0\x12" },
-       ['1'] = { "\x16", "\xf0\x16" },
-       ['!'] = { "\x12\x16", "\xf0\x16\xf0\x12" },
-       ['2'] = { "\x1e", "\xf0\x1e" },
-       ['@'] = { "\x12\x1e", "\xf0\x1e\xf0\x12" },
-       ['3'] = { "\x26", "\xf0\x26" },
-       ['#'] = { "\x12\x26", "\xf0\x26\xf0\x12" },
-       ['4'] = { "\x25", "\xf0\x25" },
-       ['$'] = { "\x12\x25", "\xf0\x25\xf0\x12" },
-       ['5'] = { "\x2e", "\xf0\x2e" },
-       ['%'] = { "\x12\x2e", "\xf0\x2e\xf0\x12" },
-       ['6'] = { "\x36", "\xf0\x36" },
-       ['^'] = { "\x12\x36", "\xf0\x36\xf0\x12" },
-       ['7'] = { "\x3d", "\xf0\x3d" },
-       ['&'] = { "\x12\x3d", "\xf0\x3d\xf0\x12" },
-       ['8'] = { "\x3e", "\xf0\x3e" },
-       ['*'] = { "\x12\x3e", "\xf0\x3e\xf0\x12" },
-       ['9'] = { "\x46", "\xf0\x46" },
-       ['('] = { "\x12\x46", "\xf0\x46\xf0\x12" },
-       ['0'] = { "\x45", "\xf0\x45" },
-       [')'] = { "\x12\x45", "\xf0\x45\xf0\x12" },
-       ['-'] = { "\x4e", "\xf0\x4e" },
-       ['_'] = { "\x12\x4e", "\xf0\x4e\xf0\x12" },
-       ['='] = { "\x55", "\xf0\x55" },
-       ['+'] = { "\x12\x55", "\xf0\x55\xf0\x12" },
-       ['['] = { "\x54", "\xf0\x54" },
-       ['{'] = { "\x12\x54", "\xf0\x54\xf0\x12" },
-       [']'] = { "\x5b", "\xf0\x5b" },
-       ['}'] = { "\x12\x5b", "\xf0\x5b\xf0\x12" },
-       ['\\'] = { "\x5d", "\xf0\x5d" },
-       ['|'] = { "\x12\x5d", "\xf0\x5d\xf0\x12" },
-       [';'] = { "\x4c", "\xf0\x4c" },
-       [':'] = { "\x12\x4c", "\xf0\x4c\xf0\x12" },
-       ['\''] = { "\x52", "\xf0\x52" },
-       ['"'] = { "\x12\x52", "\xf0\x52\xf0\x12" },
-       [','] = { "\x41", "\xf0\x41" },
-       ['<'] = { "\x12\x41", "\xf0\x41\xf0\x12" },
-       ['.'] = { "\x49", "\xf0\x49" },
-       ['>'] = { "\x12\x49", "\xf0\x49\xf0\x12" },
-       ['/'] = { "\x4a", "\xf0\x4a" },
-       [' '] = { "\x29", "\xf0\x29" },
-       ['?'] = { "\x12\x4a", "\xf0\x4a\xf0\x12" }
+/* To save space, we don't store the first 32 characters in scancodes2, since
+ * they're control characters. Thus, the offset is the amount to subtract
+ * from a character before looking it up. */
+
+#define SC2_OFFSET     32
+#define SC2(x)         ((x)-SC2_OFFSET) 
+
+/* Keys are stored in somewhat compressed form, to save on data space.
+ *
+ * The "press" and "release" strings contain scancodes to be injected
+ * into the buffer. However, they are modified beforehand, since two
+ * bytes isn't enough for all keys.
+ *
+ * Rules:
+ *  - If press starts with \x12 (shift down), then \xf0\x12 (shift up)
+ *    will be appended to release.
+ *  - If press starts with \xe0, then \xe0 is *pre*pended to release.
+ */
+
+struct keyspec {
+       char press[2];
+       char release[2];
 };
 
+static const struct keyspec scancodes2[] = {
+       [SC2('a')] = { "\x1c", "\xf0\x1c" },
+       [SC2('b')] = { "\x32", "\xf0\x32" },
+       [SC2('c')] = { "\x21", "\xf0\x21" },
+       [SC2('d')] = { "\x23", "\xf0\x23" },
+       [SC2('e')] = { "\x24", "\xf0\x24" },
+       [SC2('f')] = { "\x2b", "\xf0\x2b" },
+       [SC2('g')] = { "\x34", "\xf0\x34" },
+       [SC2('h')] = { "\x33", "\xf0\x33" },
+       [SC2('i')] = { "\x43", "\xf0\x43" }, 
+       [SC2('j')] = { "\x3b", "\xf0\x3b" },
+       [SC2('k')] = { "\x42", "\xf0\x42" },
+       [SC2('l')] = { "\x4b", "\xf0\x4b" },
+       [SC2('m')] = { "\x3a", "\xf0\x3a" },
+       [SC2('n')] = { "\x31", "\xf0\x31" },
+       [SC2('o')] = { "\x44", "\xf0\x44" },
+       [SC2('p')] = { "\x4d", "\xf0\x4d" },
+       [SC2('q')] = { "\x15", "\xf0\x15" },
+       [SC2('r')] = { "\x2d", "\xf0\x2d" },
+       [SC2('s')] = { "\x1b", "\xf0\x1b" },
+       [SC2('t')] = { "\x2c", "\xf0\x2c" },
+       [SC2('u')] = { "\x3c", "\xf0\x3c" },
+       [SC2('v')] = { "\x2a", "\xf0\x2a" },
+       [SC2('w')] = { "\x1d", "\xf0\x1d" },
+       [SC2('x')] = { "\x22", "\xf0\x22" },
+       [SC2('y')] = { "\x35", "\xf0\x35" },
+       [SC2('z')] = { "\x1a", "\xf0\x1a" },
+       [SC2('A')] = { "\x12\x1c", "\xf0\x1c" },
+       [SC2('B')] = { "\x12\x32", "\xf0\x32" },
+       [SC2('C')] = { "\x12\x21", "\xf0\x21" },
+       [SC2('D')] = { "\x12\x23", "\xf0\x23" },
+       [SC2('E')] = { "\x12\x24", "\xf0\x24" },
+       [SC2('F')] = { "\x12\x2b", "\xf0\x2b" },
+       [SC2('G')] = { "\x12\x34", "\xf0\x34" },
+       [SC2('H')] = { "\x12\x33", "\xf0\x33" },
+       [SC2('I')] = { "\x12\x43", "\xf0\x43" },
+       [SC2('J')] = { "\x12\x3b", "\xf0\x3b" },
+       [SC2('K')] = { "\x12\x42", "\xf0\x42" },
+       [SC2('L')] = { "\x12\x4b", "\xf0\x4b" },
+       [SC2('M')] = { "\x12\x3a", "\xf0\x3a" },
+       [SC2('N')] = { "\x12\x31", "\xf0\x31" },
+       [SC2('O')] = { "\x12\x44", "\xf0\x44" },
+       [SC2('P')] = { "\x12\x4d", "\xf0\x4d" },
+       [SC2('Q')] = { "\x12\x15", "\xf0\x15" },
+       [SC2('R')] = { "\x12\x2d", "\xf0\x2d" },
+       [SC2('S')] = { "\x12\x1b", "\xf0\x1b" },
+       [SC2('T')] = { "\x12\x2c", "\xf0\x2c" },
+       [SC2('U')] = { "\x12\x3c", "\xf0\x3c" },
+       [SC2('V')] = { "\x12\x2a", "\xf0\x2a" },
+       [SC2('W')] = { "\x12\x1d", "\xf0\x1d" },
+       [SC2('X')] = { "\x12\x22", "\xf0\x22" },
+       [SC2('Y')] = { "\x12\x35", "\xf0\x35" },
+       [SC2('Z')] = { "\x12\x1a", "\xf0\x1a" },
+       [SC2('`')] = { "\x0e", "\xf0\x0e" },
+       [SC2('~')] = { "\x12\x0e", "\xf0\x0e" },
+       [SC2('1')] = { "\x16", "\xf0\x16" },
+       [SC2('!')] = { "\x12\x16", "\xf0\x16" },
+       [SC2('2')] = { "\x1e", "\xf0\x1e" },
+       [SC2('@')] = { "\x12\x1e", "\xf0\x1e" },
+       [SC2('3')] = { "\x26", "\xf0\x26" },
+       [SC2('#')] = { "\x12\x26", "\xf0\x26" },
+       [SC2('4')] = { "\x25", "\xf0\x25" },
+       [SC2('$')] = { "\x12\x25", "\xf0\x25" },
+       [SC2('5')] = { "\x2e", "\xf0\x2e" },
+       [SC2('%')] = { "\x12\x2e", "\xf0\x2e" },
+       [SC2('6')] = { "\x36", "\xf0\x36" },
+       [SC2('^')] = { "\x12\x36", "\xf0\x36" },
+       [SC2('7')] = { "\x3d", "\xf0\x3d" },
+       [SC2('&')] = { "\x12\x3d", "\xf0\x3d" },
+       [SC2('8')] = { "\x3e", "\xf0\x3e" },
+       [SC2('*')] = { "\x12\x3e", "\xf0\x3e" },
+       [SC2('9')] = { "\x46", "\xf0\x46" },
+       [SC2('(')] = { "\x12\x46", "\xf0\x46" },
+       [SC2('0')] = { "\x45", "\xf0\x45" },
+       [SC2(')')] = { "\x12\x45", "\xf0\x45" },
+       [SC2('-')] = { "\x4e", "\xf0\x4e" },
+       [SC2('_')] = { "\x12\x4e", "\xf0\x4e" },
+       [SC2('=')] = { "\x55", "\xf0\x55" },
+       [SC2('+')] = { "\x12\x55", "\xf0\x55" },
+       [SC2('[')] = { "\x54", "\xf0\x54" },
+       [SC2('{')] = { "\x12\x54", "\xf0\x54" },
+       [SC2(']')] = { "\x5b", "\xf0\x5b" },
+       [SC2('}')] = { "\x12\x5b", "\xf0\x5b" },
+       [SC2('\\')] = { "\x5d", "\xf0\x5d" },
+       [SC2('|')] = { "\x12\x5d", "\xf0\x5d" },
+       [SC2(';')] = { "\x4c", "\xf0\x4c" },
+       [SC2(':')] = { "\x12\x4c", "\xf0\x4c" },
+       [SC2('\'')] = { "\x52", "\xf0\x52" },
+       [SC2('"')] = { "\x12\x52", "\xf0\x52" },
+       [SC2(',')] = { "\x41", "\xf0\x41" },
+       [SC2('<')] = { "\x12\x41", "\xf0\x41" },
+       [SC2('.')] = { "\x49", "\xf0\x49" },
+       [SC2('>')] = { "\x12\x49", "\xf0\x49" },
+       [SC2('/')] = { "\x4a", "\xf0\x4a" },
+       [SC2(' ')] = { "\x29", "\xf0\x29" },
+       [SC2('?')] = { "\x12\x4a", "\xf0\x4a" }
+};
 
-static const char scancodes2high[][2][8] = {
-       [0x08] = { "\x66", "\xf0\x66" },
-       [0x09] = { "\x0d", "\xf0\x0d" },
-       [0x0d] = { "\x5a", "\xf0\x5a" },
-       [0x1b] = { "\x76", "\xf0\x76" },
-       [0x63] = { "\xE0\x70", "\xE0\xF0\x70" },
-       [0xff] = { "\xE0\x71", "\xE0\xF0\x71" },
-       [0x50] = { "\xE0\x6C", "\xE0\xF0\x6C" },
-       [0x57] = { "\xE0\x69", "\xE0\xF0\x69" },
-       [0x55] = { "\xE0\x75", "\xE0\xF0\x75" },
-       [0x56] = { "\xE0\x7A", "\xE0\xF0\x7A" },
-        [0x51] = { "\xE0\x74", "\xE0\xF0\x74" },
-        [0x52] = { "\xE0\x75", "\xE0\xF0\x75" },
-        [0x53] = { "\xE0\x6B", "\xE0\xF0\x6B" },
-        [0x54] = { "\xE0\x72", "\xE0\xF0\x72" },
-       [0xe1] = { "\x12", "\xf0\x12" },
-       [0xe2] = { "\x59", "\xf0\x59" },
-       [0xe3] = { "\x14", "\xf0\x14" },
-       [0xe4] = { "\xE0\x14", "\xE0\xF0\x14" },
-       [0xe9] = { "\x11", "\xf0\x11" },
-       [0xea] = { "\xE0\x11", "\xE0\xF0\x11" }
+static const struct {
+       char index;
+       struct keyspec data;
+} scancodes2high[] = {
+       { 0x08, { "\x66", "\xf0\x66" } },
+       { 0x09, { "\x0d", "\xf0\x0d" } },
+       { 0x0d, { "\x5a", "\xf0\x5a" } },
+       { 0x1b, { "\x76", "\xf0\x76" } },
+       { 0x63, { "\xe0\x70", "\xF0\x70" } },
+       { 0xff, { "\xe0\x71", "\xF0\x71" } },
+       { 0x50, { "\xe0\x6C", "\xF0\x6C" } },
+       { 0x57, { "\xe0\x69", "\xF0\x69" } },
+       { 0x55, { "\xe0\x75", "\xF0\x75" } },
+       { 0x56, { "\xe0\x7A", "\xF0\x7A" } },
+        { 0x51, { "\xe0\x74", "\xF0\x74" } },
+        { 0x52, { "\xe0\x75", "\xF0\x75" } },
+        { 0x53, { "\xe0\x6B", "\xF0\x6B" } },
+        { 0x54, { "\xe0\x72", "\xF0\x72" } },
+       { 0xe1, { "\x12", "" } },
+       { 0xe2, { "\x59", "\xf0\x59" } },
+       { 0xe3, { "\x14", "\xf0\x14" } },
+       { 0xe4, { "\xe0\x14", "\xF0\x14" } },
+       { 0xe9, { "\x11", "\xf0\x11" } },
+       { 0xea, { "\xe0\x11", "\xF0\x11" } },
+       { 0x00, { "", "" } }
 };
 
 const unsigned char convert_table[] = {
@@ -180,6 +207,11 @@ unsigned char sc_convert_1(unsigned char in)
 
 void kbd_inject_scancode (unsigned char sc)
 {
+       if (kbd_mode == 1) {
+               sc = sc_convert_1(sc);
+               if (!sc) return;
+       }
+
        outputf("Buffering %02x", sc);
        kbd_inj_buffer[kbd_inj_end] = sc;
        kbd_inj_end += 1;
@@ -188,30 +220,45 @@ void kbd_inject_scancode (unsigned char sc)
 
 void kbd_inject_keysym(uint32_t k, int downflag)
 {
-       const char * c;
+       const struct keyspec * ks = 0;
+       const char * c = 0;
+       int i;
 
-       if ((k & 0xFFFFFF00) == 0)
+       if ((k & 0xFFFFFF00) == 0 && (k & 0xFF) > SC2_OFFSET)
        { 
-               c = scancodes2[k & 0xFF][downflag ? 0 : 1];
+               ks = &scancodes2[SC2(k & 0xFF)];
        } else if ((k & 0xFFFFFF00) == 0xFF00) {
-               c = scancodes2high[k & 0xFF][downflag ? 0 : 1];
+               for (i = 0; scancodes2high[i].index; i++) {
+                       if ((k & 0xff) == scancodes2high[i].index) {
+                               ks = &scancodes2high[i].data;
+                               break;
+                       }
+               }
        } else {
                return;
        }
 
-       if (!c) return;
+       if (!ks) return;
 
-       if (kbd_mode == 1) {
-               while (*c) {
-                       char cconv = sc_convert_1(*c);
-                       if (cconv) kbd_inject_scancode(cconv);
-                       c++;
-               }
-       } else {
-               while (*c) {
-                       kbd_inject_scancode(*c);
-                       c++;
-               }
+       if (downflag)
+               c = ks->press;
+       else
+               c = ks->release;
+
+       i = 0;
+
+       if (ks->press[0] == '\xe0' && !downflag)
+               kbd_inject_scancode('\xe0');
+
+       while (*c && i < 2) {
+               kbd_inject_scancode(*c);
+               c++;
+               i++;
+       }
+
+       if (ks->press[0] == '\x12' && !downflag) {
+               kbd_inject_scancode('\xf0');
+               kbd_inject_scancode('\x12');
        }
 }
 
index 5ba1857cf4f73e1b745d2e399162c6211dace9d5..4041bdc7b3a29bdf4d634cc3db7500f2c90b1d9e 100644 (file)
@@ -54,6 +54,7 @@ void ps_switch_stack (void (*call)(), int stack);
 
 #define        CR0_PG  0x80000000
 #define CR4_PSE        0x00000010
+#define CR4_OSFXSR 0x00000200
 
 #define MAP_FLAGS      (PTE_PRESENT | PTE_READ_WRITE)
 
@@ -183,54 +184,66 @@ static void pt_setup(int tseg_start, int tseg_size) {
 
 void init_and_run(void)
 {
+       DBG(0x0A);
+
        if (!initialized)
        {
+               DBG(0x0B);
                smi_init();
                initialized = 1;
        }
        
+       DBG(0x0C);
        smi_entry();
+
+       DBG(0xCC);
 }
 
 void c_entry(void)
 {
        paging_enb = 0;
 
-       outb(0x80, 0x01);       
+       DBG(0x01);
+
        if (!initialized)
                pt_setup(0x1FF80000, 0x80000);
-       outb(0x80, 0x02);
-               
+
+       DBG(0x02);
+
        /* Enable paging. */
        set_cr3((unsigned long)pd);
-       set_cr4(get_cr4() | CR4_PSE);   /* ITT, we 4MByte page. */ 
+       set_cr4(get_cr4() | CR4_PSE | CR4_OSFXSR);      /* ITT, we 4MByte page. */ 
        set_cr0(get_cr0() | CR0_PG);
-       outb(0x80, 0x03);
+
+       DBG(0x03);
        paging_enb = 1;
 
        /* If this is the first goround, copy in data. */
        if (!initialized)
        {
                unsigned char *p;
-               
-               outb(0x80, 0x04);
+
+               DBG(0x04);
+
                for (p = (void *)0x200000; (void *)p < (void *)&_bss; p++)
                        *p = *(p + 0x100000);
                for (p = (void *)&_bss; (void *)p < (void *)&_bssend; p++)
                        *p = 0;
-               outb(0x80, 0x05);
+
+               DBG(0x05);
                
                /* Only now is it safe to call other functions. */
                serial_init();
+               DBG(0x06);
                dolog("Evacuation to TSEG complete.");
+               DBG(0x07);
        }
-       
-       outb(0x80, 0x06);
 
+       DBG(0x08);
        traps_install();
        
-       outb(0x80, 0x07);
+       DBG(0x09);
+       ps_switch_stack(init_and_run, 0xa2000);
 
-       ps_switch_stack(init_and_run, 0x270000);
-       outb(0x80, 0xFA);
+       DBG(0xFA);
 }
index bf5ca803b221ef2968fb9dee73ee0be0a47345d1..25a404c6a5fe58bf24275f8ab40c454ce8c5e6e5 100644 (file)
 
 #include "traps.h"
 
-#define CS_SEGSEL      0x8
+#define CS_SEGSEL      0x10
+
+asm (
+       "fault_wrapper_common:\n"
+       "push %eax\n"
+        "mov %cr2, %eax\n"
+        "push %eax\n"
+        "push %esp\n"
+        "call die\n"
+);
+
+#define FAULT_WRAPPER(func_name, code)        asm (    \
+        ".global " #func_name "_wrapper\n"              \
+        #func_name "_wrapper:\n"                        \
+       "mov $" #code ", %eax\n"                        \
+       "jmp fault_wrapper_common\n"                    \
+); void func_name##_wrapper(void);
 
-#define FAULT_WRAPPER(func_name)        asm (           \
+#define FAULT_WRAPPER1(func_name, code)        asm (           \
         ".global " #func_name "_wrapper\n"              \
         #func_name "_wrapper:\n"                        \
-        "mov %cr2, %eax\n"                              \
+       "mov $0, %eax\n"                                \
         "push %eax\n"                                   \
-        "push %esp\n"                                   \
-        "call " #func_name "\n"                         \
+       "mov $" #code ", %eax\n"                        \
+       "jmp fault_wrapper_common\n"                    \
 ); void func_name##_wrapper(void);
 
 #define WRAPPER_INSTALL(idt, idt4_value, func_name, int_number) {      \
 /* The 16 bits at offset 4 from the start of an interrupt gate are a
  * bitfield, according to the Intel spec:
  * 15           P - Segment Present - set to 1
- * 14-13        DPL - Descriptor privilege level - set to 11 for trap/int, 00 for IPI
+ * 14-13        DPL - Descriptor privilege level - set to 00, since we're always in ring 0
  * 12-8         01111 for 32-bit trap gates, 01110 for 32-bit interrupt gates
  * 7-0          Set to 0
- * Trap:      binary 11101111 0000000, hex EF00.
- * Interrupt: binary 11101110 0000000, hex EE00.
  */
-#define TRAP           0xEF00
-#define INTERRUPT      0xEE00
+#define TRAP           0x8F00
 
 typedef struct trap_t {
        int cr2;
+       int fault_code;
         int error_code;
         int eip;
         int cs;
         int eflags;
-        int esp;
-        int ss;
 } trap_t;
 
+static const char const * trapcodes[20] = {
+       "Divide by Zero",
+       "Debug Trap",
+       "NMI",
+       "Breakpoint Trap",
+       "Overflow Trap",
+       "Bound Range Fault",
+       "Invalid Opcode",
+       "Device Not Available",
+       "Double Fault",
+       "Coprocessor Overrun",
+       "Invalid TSS",
+       "Segmnet Not Present",
+       "Stack Fault",
+       "GPF",
+       "Page Fault",
+       "Reserved Trap",
+       "x87 FPE Pending",
+       "Alignment Check",
+       "Machine Check",
+       "SIMD FPE Fault"
+};
+
 void die(struct trap_t * trap) {
-       outputf("Error %08x %%eip %08x", trap->error_code, trap->eip);
-       outputf("%%esp %08x %%eflags %08x", trap->esp, trap->eflags);
-       while(1) asm("hlt");
-}
 
-void fault_gp(struct trap_t * trap) {
-       outputf("GENERAL PROTECTION FAULT");
-       die(trap);
-}
+       DBG(0x40 + trap->fault_code);
 
-void fault_page(struct trap_t * trap) {
-       outputf("PAGE FAULT: %08x", trap->cr2);
-       die(trap);
-}
-void fault_divide(struct trap_t * trap) {
-       outputf("DIVISION FAULT");
-       die(trap);
-}
-void double_fault(struct trap_t * trap) {
-       outputf("DOUBLE FAULT");
-       die(trap);
+       if (trap->fault_code < 20) {
+               outputf("---\n%s", trapcodes[trap->fault_code]);
+       } else {
+               outputf("---\nUNKNOWN FAULT");
+       }
+
+       outputf("Error %08x %%eip %08x", trap->error_code, trap->eip);
+       outputf("%%cr2 %08x %%eflags %08x", trap->cr2, trap->eflags);
+       while(1) asm("hlt");
 }
 
-FAULT_WRAPPER(fault_gp);
-FAULT_WRAPPER(fault_page);
-FAULT_WRAPPER(fault_divide);
-FAULT_WRAPPER(double_fault);
+FAULT_WRAPPER1(fault_divide, 0);
+FAULT_WRAPPER1(fault_db, 1);
+FAULT_WRAPPER1(fault_nmi, 2);
+FAULT_WRAPPER1(fault_3, 3);
+FAULT_WRAPPER1(fault_overflow, 4);
+FAULT_WRAPPER1(fault_oob, 5);
+FAULT_WRAPPER1(fault_opcode, 6);
+FAULT_WRAPPER1(fault_enofpu, 7);
+FAULT_WRAPPER(double_fault, 8);
+FAULT_WRAPPER1(fault_fpu, 9);
+FAULT_WRAPPER(fault_invalid_tss, 10);
+FAULT_WRAPPER(fault_noseg, 11);
+FAULT_WRAPPER(fault_stack, 12);
+FAULT_WRAPPER(fault_gp, 13);
+FAULT_WRAPPER(fault_page, 14);
+FAULT_WRAPPER1(fault_fpe, 16);
+FAULT_WRAPPER(fault_ac, 17);
+FAULT_WRAPPER1(fault_machine, 18);
+FAULT_WRAPPER1(fault_other, 19);
 
 /* pseudo_descriptor and x86_gate structs from 15-410 basis code. */
 
 struct x86_gate {
-unsigned int filler[2]; //64 bits; or 8 bytes.
+       unsigned int filler[2];         //64 bits, or 8 bytes.
 };
 
 static struct x86_gate idt[64];
@@ -99,17 +140,38 @@ struct pseudo_descriptor {
 } __attribute__((packed));
 
 void traps_install(void) {
+        DBG(0xCA);
+       int i;
 
         struct pseudo_descriptor pdesc;
        pdesc.limit = sizeof(idt) - 1;
-       pdesc.linear_base = v2p(&idt);
+       pdesc.linear_base = (int)&idt; //v2p(&idt);
+
+               DBG(0xCB);
+
+       for (i = 0; i < 32; i++)
+               WRAPPER_INSTALL(idt, TRAP, fault_other, i);
 
        WRAPPER_INSTALL(idt, TRAP, fault_divide, T_DIVIDE_ERROR);
+       WRAPPER_INSTALL(idt, TRAP, fault_db, T_DEBUG);
+       WRAPPER_INSTALL(idt, TRAP, fault_nmi, T_NMI);
+       WRAPPER_INSTALL(idt, TRAP, fault_3, T_INT3);
+       WRAPPER_INSTALL(idt, TRAP, fault_overflow, T_OVERFLOW);
+       WRAPPER_INSTALL(idt, TRAP, fault_oob, T_OUT_OF_BOUNDS);
+       WRAPPER_INSTALL(idt, TRAP, fault_opcode, T_INVALID_OPCODE);
+       WRAPPER_INSTALL(idt, TRAP, fault_enofpu, T_NO_FPU);
+       WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT);
+       WRAPPER_INSTALL(idt, TRAP, fault_fpu, T_FPU_FAULT);
+       WRAPPER_INSTALL(idt, TRAP, fault_invalid_tss, T_INVALID_TSS);
+       WRAPPER_INSTALL(idt, TRAP, fault_noseg, T_SEGMENT_NOT_PRESENT);
+       WRAPPER_INSTALL(idt, TRAP, fault_stack, T_STACK_FAULT);
        WRAPPER_INSTALL(idt, TRAP, fault_gp, T_GENERAL_PROTECTION);
        WRAPPER_INSTALL(idt, TRAP, fault_page, T_PAGE_FAULT);
-       WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT);
+       WRAPPER_INSTALL(idt, TRAP, fault_fpe, T_FLOATING_POINT_ERROR);
+       WRAPPER_INSTALL(idt, TRAP, fault_ac, T_ALIGNMENT_CHECK);
+       WRAPPER_INSTALL(idt, TRAP, fault_machine, T_MACHINE_CHECK);
 
-        outb(0x80, 0xCC);
+        DBG(0xCC);
        asm volatile("lidt %0" : : "m" (pdesc.limit));
-        outb(0x80, 0xCD);
+        DBG(0xCE);
 }
This page took 0.069155 seconds and 4 git commands to generate.