Finally got KFS stuff sorted out on the new setup
authorKevin Klues <klueska@ros-dev.(none)>
Sat, 3 Apr 2010 02:45:18 +0000 (19:45 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:39 +0000 (17:35 -0700)
We also touched up a few issues relating to the last commit
with the configuration options.  Specifically, with the SINGLE_CORE option.
Incidentally, this option seems to be broken at the moment, but at least
we fixed the logic as to when it should be turned on.

13 files changed:
Makeconfig
Makelocal.template
kern/arch/i686/init.c
kern/src/Makefrag
kern/src/kfs.c
kern/src/manager.c
kern/src/syscall.c
tests/tlstest.c [new file with mode: 0644]
user/include/debug.h [new file with mode: 0644]
user/include/stdio.h [new file with mode: 0644]
user/parlib/Makefrag
user/parlib/debug.c [new file with mode: 0644]
user/parlib/debugfmt.c [new file with mode: 0644]

index 4e1c9f4..cbef09c 100644 (file)
@@ -1,3 +1,9 @@
+# General Purpose configuration parameters
+# By default, each of these options will be turned off
+# To enable any of these options, add a line like the following to your Makelocal
+# CFLAGS += $(CONFIG_APPSERVER)
+CONFIG_APPSERVER:=                 -D__CONFIG_APPSERVER__
+
 # Kernel configuration parameters
 # By default, each of these options will be turned off
 # To enable any of these options, add a line like the following to your Makelocal
@@ -9,7 +15,6 @@ CONFIG_SERIAL_IO:=                 -D__CONFIG_SERIAL_IO__
 CONFIG_BSD_ON_CORE0:=              -D__CONFIG_BSD_ON_CORE0__
 CONFIG_SPINLOCK_DEBUG:=            -D__CONFIG_SPINLOCK_DEBUG__
 CONFIG_PAGE_COLORING:=             -D__CONFIG_PAGE_COLORING__
-CONFIG_APPSERVER:=                 -D__CONFIG_APPSERVER__
 CONFIG_DEMAND_PAGING:=             -D__CONFIG_DEMAND_PAGING__
 
 # Userspace configuration parameters
@@ -23,3 +28,4 @@ CONFIG_SYSCALL_TRAP:=              -D__CONFIG_SYSCALL_TRAP__
 # To enable any of these options, add a line like the following to your Makelocal
 # TESTS_CFLAGS += $(CONFIG_STATIC_APPS)
 CONFIG_STATIC_APPS:=               -static
+
index 81ea6f3..d712689 100644 (file)
@@ -1,3 +1,6 @@
+# General Purpose configuration parameters
+#CFLAGS += $(CONFIG_APPSERVER)
+
 # Kernel configuration parameters
 #KERN_CFLAGS += $(CONFIG_KFS)
 #KERN_CFLAGS += $(CONFIG_SINGLE_CORE)
index 4c21c5c..7b0ec3f 100644 (file)
@@ -22,9 +22,9 @@ void arch_init()
        // __CONFIG_NETWORKING__ inits to not need multiple cores running.
        // this returns when all other cores are done and ready to receive IPIs
        #ifdef __CONFIG_SINGLE_CORE__
-               smp_boot();
-       #else
                smp_percpu_init();
+       #else
+               smp_boot();
        #endif
        proc_init();
 
@@ -40,7 +40,12 @@ void arch_init()
         * Additionally, you should have a look at the syscall server in the tools directory
         */
        #ifdef __CONFIG_NETWORKING__
-       rl8168_init();          
-       ne2k_init();
+       #ifdef __CONFIG_SINGLE_CORE__
+               warn("You currently can't have networking if you boot into single core mode!!\n");
+       #else
+               rl8168_init();          
+               ne2k_init();
+       #endif // __CONFIG_SINGLE_CORE__
        #endif // __CONFIG_NETWORKING__
 }
+
index 8412d36..1eeebc1 100644 (file)
@@ -47,26 +47,21 @@ KERN_SRCFILES := $(wildcard $(KERN_SRCFILES))
 
 KERN_APPFILES := \
 
-ifeq ($(TARGET_ARCH),i386)
+
+ifneq ($(findstring CONFIG_KFS,$(KERN_CFLAGS)),)
+$(OBJDIR)/$(KERN_DIR)/kernel: tests
+
 KERN_APPFILES += \
-                 $(USER_APPS_PARLIB_DIR)/matrix \
-                 $(USER_APPS_ROSLIB_DIR)/proctests \
-                 $(USER_APPS_ROSLIB_DIR)/fptest \
-                 $(USER_APPS_ROSLIB_DIR)/null \
-                 $(USER_APPS_ROSLIB_DIR)/spawn \
-                 $(USER_APPS_ROSLIB_DIR)/hello \
-                 $(USER_APPS_ROSLIB_DIR)/mhello \
-                 $(USER_APPS_ROSLIB_DIR)/mproctests \
-                 $(USER_APPS_ROSLIB_DIR)/measurements \
-                 $(USER_APPS_PARLIB_DIR)/draw_nanwan_standalone \
-                 $(USER_APPS_PARLIB_DIR)/channel_test_client \
-                 $(USER_APPS_PARLIB_DIR)/channel_test_server \
-                 $(USER_APPS_PARLIB_DIR)/hello \
-                 $(USER_APPS_PARLIB_DIR)/mhello \
-                 $(USER_APPS_PARLIB_DIR)/httpserver \
-                 $(USER_APPS_PARLIB_DIR)/manycore_test \
-                 $(USER_APPS_PARLIB_DIR)/lock_test 
-               
+                 $(TESTS_DIR)/tlstest \
+                 $(TESTS_DIR)/proctests \
+                 $(TESTS_DIR)/fp_test \
+                 $(TESTS_DIR)/null \
+                 $(TESTS_DIR)/spawn \
+                 $(TESTS_DIR)/mproctests \
+                 $(TESTS_DIR)/draw_nanwan \
+                 $(TESTS_DIR)/hello \
+                 $(TESTS_DIR)/mhello \
+                 $(TESTS_DIR)/manycore_test
 endif
 
 KERN_LDFLAGS   := $(KERN_LDFLAGS) -L$(OBJDIR)/$(KERN_DIR) \
index 68f7592..e98ab6f 100644 (file)
 #include <error.h>
 
 #define DECL_PROG(x) \
-    extern uint8_t (COUNT(sizeof(size_t)) _binary_obj_user_apps_##x##_size)[],\
-        (COUNT(_binary_obj_user_apps_##x##_size)_binary_obj_user_apps_##x##_start)[];
+    extern uint8_t (COUNT(sizeof(size_t)) _binary_obj_tests_##x##_size)[],\
+        (COUNT(_binary_obj_user_apps_##x##_size)_binary_obj_tests_##x##_start)[];
 
-#define KFS_ENTRY(x) {#x, _binary_obj_user_apps_##x##_start, (size_t) _binary_obj_user_apps_##x##_size},
+#define KFS_ENTRY(x) {#x, _binary_obj_tests_##x##_start, (size_t) _binary_obj_tests_##x##_size},
 
 /*
  * Hardcode the files included in the KFS.  This needs to be in sync with the
  * Make sure to declare it, and add an entry.  Keep MAX_KFS_FILES big enough too
  */
 #ifdef __CONFIG_KFS__
-DECL_PROG(parlib_matrix);
-DECL_PROG(roslib_proctests);
-DECL_PROG(roslib_fptest);
-DECL_PROG(roslib_null);
-DECL_PROG(roslib_spawn);
-DECL_PROG(roslib_hello);
-DECL_PROG(roslib_mhello);
-DECL_PROG(roslib_mproctests);
-DECL_PROG(roslib_measurements);
-DECL_PROG(parlib_draw_nanwan_standalone);
-DECL_PROG(parlib_channel_test_client);
-DECL_PROG(parlib_channel_test_server);
-DECL_PROG(parlib_hello);
-DECL_PROG(parlib_mhello);
-DECL_PROG(parlib_httpserver);
-DECL_PROG(parlib_manycore_test);
-DECL_PROG(parlib_lock_test);
+DECL_PROG(tlstest);
+DECL_PROG(proctests);
+DECL_PROG(fp_test);
+DECL_PROG(null);
+DECL_PROG(spawn);
+DECL_PROG(mproctests);
+DECL_PROG(draw_nanwan);
+DECL_PROG(hello);
+DECL_PROG(mhello);
+DECL_PROG(manycore_test);
 #endif
 
 struct kfs_entry kfs[MAX_KFS_FILES] = {
 #ifdef __CONFIG_KFS__
-       KFS_ENTRY(parlib_matrix)
-       KFS_ENTRY(roslib_proctests)
-       KFS_ENTRY(roslib_fptest)
-       KFS_ENTRY(roslib_null)
-       KFS_ENTRY(roslib_spawn)
-       KFS_ENTRY(roslib_hello)
-       KFS_ENTRY(roslib_mhello)
-       KFS_ENTRY(roslib_mproctests)
-       KFS_ENTRY(roslib_measurements)
-       KFS_ENTRY(parlib_draw_nanwan_standalone)
-       KFS_ENTRY(parlib_channel_test_client)
-       KFS_ENTRY(parlib_channel_test_server)
-       KFS_ENTRY(parlib_hello)
-       KFS_ENTRY(parlib_mhello)
-       KFS_ENTRY(parlib_httpserver)
-       KFS_ENTRY(parlib_manycore_test)
-       KFS_ENTRY(parlib_lock_test)
+       KFS_ENTRY(tlstest)
+       KFS_ENTRY(proctests)
+       KFS_ENTRY(fp_test)
+       KFS_ENTRY(null)
+       KFS_ENTRY(spawn)
+       KFS_ENTRY(mproctests)
+       KFS_ENTRY(draw_nanwan)
+       KFS_ENTRY(hello)
+       KFS_ENTRY(mhello)
+       KFS_ENTRY(manycore_test)
 #endif
 };
 
index ff60ce8..f2fe313 100644 (file)
@@ -66,7 +66,7 @@ void manager_brho(void)
        switch (progress++) {
                case 0:
                        // TODO: need to store the pid for future manager runs, not the *p
-                       p = kfs_proc_create(kfs_lookup_path("parlib_mhello"));
+                       p = kfs_proc_create(kfs_lookup_path("mhello"));
                        //p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
                        //p = kfs_proc_create(kfs_lookup_path("roslib_mproctests"));
                        //p = kfs_proc_create(kfs_lookup_path("roslib_spawn"));
index 4f4d9cc..86919a1 100644 (file)
@@ -904,7 +904,12 @@ intreg_t sys_gettimeofday(struct proc* p, int* buf)
 
        spin_lock(&gtod_lock);
        if(t0 == 0)
+#ifdef __CONFIG_APPSERVER__
                t0 = ufe(time,0,0,0,0);
+#else
+               // Nanwan's birthday, bitches!!
+               t0 = 1242129600;
+#endif 
        spin_unlock(&gtod_lock);
 
        long long dt = read_tsc();
diff --git a/tests/tlstest.c b/tests/tlstest.c
new file mode 100644 (file)
index 0000000..9e47bd2
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+volatile __thread int foo;
+volatile __thread int bar;
+
+int main()
+{
+       printf("&foo = %p, &bar = %p\n",&foo,&bar);
+       bar = 0xcafebabe;
+       printf("bar = %p\n",bar);
+       return 0;
+}
diff --git a/user/include/debug.h b/user/include/debug.h
new file mode 100644 (file)
index 0000000..632ff4c
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef PARLIB_INC_DEBUG_H
+#define PARLIB_INC_DEBUG_H
+
+#include <ros/noivy.h>
+#include <stdio.h>
+
+#ifndef __va_list__
+typedef __builtin_va_list va_list;
+#endif
+
+#define va_start(v,l)   __builtin_va_start(v,l)
+#define va_end(v)      __builtin_va_end(v)
+#define va_arg(v,l)     __builtin_va_arg(v,l)
+
+size_t strnlen(const char *NTS s, size_t size);
+#ifdef __DEPUTY__
+void debugfmt(void (*putch)(int, TV(t)), TV(t) putdat, const char *NTS fmt, ...);
+void vdebugfmt(void (*putch)(int, TV(t)), TV(t) putdat, const char *NTS fmt, va_list);
+#else
+void debugfmt(void (*putch)(int, void**), void **putdat, const char *NTS fmt, ...);
+void vdebugfmt(void (*putch)(int, void**), void **putdat, const char *NTS fmt, va_list);
+#endif
+
+int    debug(const char * NTS fmt, ...);
+int    vdebug(const char * NTS fmt, va_list);
+
+#endif /* !PARLIB_INC_DEBUG_H */
diff --git a/user/include/stdio.h b/user/include/stdio.h
new file mode 100644 (file)
index 0000000..08fc2f1
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __PARLIB_STDIO_H__
+#define __PARLIB_STDIO_H__
+
+#include_next <stdio.h>
+
+#ifndef __CONFIG_APPSERVER__
+#include <debug.h>
+#define printf(...) debug(__VA_ARGS__)
+#endif
+
+#endif
index 9023b0d..9dca308 100644 (file)
@@ -13,7 +13,9 @@ USER_PARLIB_SRCFILES := \
                  $(USER_PARLIB_DIR)/pthread.c \
                  $(USER_PARLIB_DIR)/hart.c \
                  $(USER_PARLIB_DIR)/panic.c \
-                 $(USER_PARLIB_DIR)/syscall.c 
+                 $(USER_PARLIB_DIR)/syscall.c \
+                 $(USER_PARLIB_DIR)/debugfmt.c \
+                 $(USER_PARLIB_DIR)/debug.c
 
 # Only build files if they exist.
 USER_PARLIB_SRCFILES := $(wildcard $(USER_PARLIB_SRCFILES))
diff --git a/user/parlib/debug.c b/user/parlib/debug.c
new file mode 100644 (file)
index 0000000..e4c2977
--- /dev/null
@@ -0,0 +1,59 @@
+// Implementation of cprintf console output for user processes,
+// based on printfmt() and the sys_cputs() system call.
+//
+// cprintf is a debugging statement, not a generic output statement.
+// It is very important that it always go to the console, especially when
+// debugging file descriptor code!
+
+#include <ros/common.h>
+#include <parlib.h>
+#include <debug.h>
+
+// Collect up to BUF_SIZE characters into a buffer
+// and perform ONE system call to print all of them,
+// in order to make the lines output to the console atomic
+// and prevent interrupts from causing context switches
+// in the middle of a console output line and such.
+#define BUF_SIZE 256
+typedef struct debugbuf {
+       size_t  idx;    // current buffer index
+       size_t  cnt;    // total bytes printed so far
+       uint8_t buf[BUF_SIZE];
+} debugbuf_t;
+
+
+static void putch(int ch, debugbuf_t **b)
+{
+       (*b)->buf[(*b)->idx++] = ch;
+       if ((*b)->idx == BUF_SIZE) {
+               sys_cputs((*b)->buf, (*b)->idx);
+               (*b)->idx = 0;
+       }
+       (*b)->cnt++;
+}
+
+int vdebug(const char *fmt, va_list ap)
+{
+       debugbuf_t b;
+       debugbuf_t *COUNT(1) bp = &b;
+
+       b.idx = 0;
+       b.cnt = 0;
+       vdebugfmt((void*)putch, (void*)&bp, fmt, ap);
+       sys_cputs(b.buf, b.idx);
+
+       return b.cnt;
+}
+
+int debug(const char *fmt, ...)
+{
+       va_list ap;
+       int cnt;
+
+       va_start(ap, fmt);
+       cnt = vdebug(fmt, ap);
+       va_end(ap);
+
+       return cnt;
+}
+
diff --git a/user/parlib/debugfmt.c b/user/parlib/debugfmt.c
new file mode 100644 (file)
index 0000000..ce4e478
--- /dev/null
@@ -0,0 +1,233 @@
+#include <ros/common.h>
+#include <ros/errno.h>
+#include <debug.h>
+
+/*
+ * Print a number (base <= 16) in reverse order,
+ * using specified putch function and associated pointer putdat.
+ */
+#ifdef __DEPUTY__
+static void printnum(void (*putch)(int, TV(t)), TV(t) putdat,
+                        unsigned long long num, unsigned base, int width, int padc)
+#else
+static void printnum(void (*putch)(int, void**), void **putdat,
+                        unsigned long long num, unsigned base, int width, int padc)
+#endif
+{
+       // first recursively print all preceding (more significant) digits
+       if (num >= base) {
+               printnum(putch, putdat, num / base, base, width - 1, padc);
+       } else {
+               // print any needed pad characters before first digit
+               while (--width > 0)
+                       putch(padc, putdat);
+       }
+
+       // then print this (the least significant) digit
+       putch("0123456789abcdef"[num % base], putdat);
+}
+
+// Get an unsigned int of various possible sizes from a varargs list,
+// depending on the lflag parameter.
+static unsigned long long getuint(va_list *ap, int lflag)
+{
+       if (lflag >= 2)
+               return va_arg(*ap, unsigned long long);
+       else if (lflag)
+               return va_arg(*ap, unsigned long);
+       else
+               return va_arg(*ap, unsigned int);
+}
+
+// Same as getuint but signed - can't use getuint
+// because of sign extension
+static long long getint(va_list *ap, int lflag)
+{
+       if (lflag >= 2)
+               return va_arg(*ap, long long);
+       else if (lflag)
+               return va_arg(*ap, long);
+       else
+               return va_arg(*ap, int);
+}
+
+
+// Main function to format and print a string.
+#ifdef __DEPUTY__
+void debugfmt(void (*putch)(int, TV(t)), TV(t) putdat, const char *fmt, ...);
+void vdebugfmt(void (*putch)(int, TV(t)), TV(t) putdat, const char *fmt, va_list ap)
+#else
+void debugfmt(void (*putch)(int, void**), void **putdat, const char *fmt, ...);
+void vdebugfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap)
+#endif
+{
+       register const char *NTS p;
+       const char *NTS last_fmt;
+       register int ch, err;
+       unsigned long long num;
+       int base, lflag, width, precision, altflag;
+       char padc;
+
+       while (1) {
+               while ((ch = *(unsigned char *) fmt) != '%') {
+                       if (ch == '\0')
+                               return;
+                       fmt++;
+                       putch(ch, putdat);
+               }
+               fmt++;
+
+               // Process a %-escape sequence
+               last_fmt = fmt;
+               padc = ' ';
+               width = -1;
+               precision = -1;
+               lflag = 0;
+               altflag = 0;
+       reswitch:
+               switch (ch = *(unsigned char *) fmt++) {
+
+               // flag to pad on the right
+               case '-':
+                       padc = '-';
+                       goto reswitch;
+                       
+               // flag to pad with 0's instead of spaces
+               case '0':
+                       padc = '0';
+                       goto reswitch;
+
+               // width field
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+                       for (precision = 0; ; ++fmt) {
+                               precision = precision * 10 + ch - '0';
+                               ch = *fmt;
+                               if (ch < '0' || ch > '9')
+                                       break;
+                       }
+                       goto process_precision;
+
+               case '*':
+                       precision = va_arg(ap, int);
+                       goto process_precision;
+
+               case '.':
+                       if (width < 0)
+                               width = 0;
+                       goto reswitch;
+
+               case '#':
+                       altflag = 1;
+                       goto reswitch;
+
+               process_precision:
+                       if (width < 0)
+                               width = precision, precision = -1;
+                       goto reswitch;
+
+               // long flag (doubled for long long)
+               case 'l':
+                       lflag++;
+                       goto reswitch;
+
+               // character
+               case 'c':
+                       putch(va_arg(ap, int), putdat);
+                       break;
+
+               // string
+               case 's':
+                       if ((p = va_arg(ap, char *NT)) == NULL)
+                               p = "(null)";
+                       if (width > 0 && padc != '-')
+                               for (width -= strnlen(p, precision); width > 0; width--)
+                                       putch(padc, putdat);
+                       for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) {
+                               if (altflag && (ch < ' ' || ch > '~'))
+                                       putch('?', putdat);
+                               else
+                                       putch(ch, putdat);
+                               // zra: make sure *p isn't '\0' before inc'ing
+                               p++;
+                       }
+                       for (; width > 0; width--)
+                               putch(' ', putdat);
+                       break;
+
+               // (signed) decimal
+               case 'd':
+                       num = getint(&ap, lflag);
+                       if ((long long) num < 0) {
+                               putch('-', putdat);
+                               num = -(long long) num;
+                       }
+                       base = 10;
+                       goto number;
+
+               // unsigned decimal
+               case 'u':
+                       num = getuint(&ap, lflag);
+                       base = 10;
+                       goto number;
+
+               // (unsigned) octal
+               case 'o':
+                       // should do something with padding so it's always 3 octits
+                       num = getuint(&ap, lflag);
+                       base = 8;
+                       goto number;
+
+               // pointer
+               case 'p':
+                       putch('0', putdat);
+                       putch('x', putdat);
+                       num = (unsigned long long)
+                               (uintptr_t) va_arg(ap, void *);
+                       base = 16;
+                       goto number;
+
+               // (unsigned) hexadecimal
+               case 'x':
+                       num = getuint(&ap, lflag);
+                       base = 16;
+               number:
+                       printnum(putch, putdat, num, base, width, padc);
+                       break;
+
+               // escaped '%' character
+               case '%':
+                       putch(ch, putdat);
+                       break;
+                       
+               // unrecognized escape sequence - just print it literally
+               default:
+                       putch('%', putdat);
+                       fmt = last_fmt;
+                       //for (fmt--; fmt[-1] != '%'; fmt--)
+                               /* do nothing */;
+                       break;
+               }
+       }
+}
+
+#ifdef __DEPUTY__
+void debugfmt(void (*putch)(int, TV(t)), TV(t) putdat, const char *fmt, ...)
+#else
+void debugfmt(void (*putch)(int, void**), void **putdat, const char *fmt, ...)
+#endif
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       vdebugfmt(putch, putdat, fmt, ap);
+       va_end(ap);
+}
+