Merge branch 'master' into proc-work
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 4 Aug 2009 02:44:41 +0000 (19:44 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 4 Aug 2009 02:44:41 +0000 (19:44 -0700)
Conflicts:
kern/src/Makefrag
kern/src/manager.c

1  2 
GNUmakefile
kern/arch/i386/atomic.h
kern/include/smp.h
kern/src/Makefrag
kern/src/env.c
kern/src/init.c
kern/src/kfs.c
kern/src/manager.c
kern/src/syscall.c
kern/src/testing.c

diff --cc GNUmakefile
@@@ -113,7 -111,9 +111,10 @@@ $(OBJDIR)/.deps: $(foreach dir, $(OBJDI
  
  # For deleting the build
  clean:
--      rm -rf $(OBJDIR)
 -      rm -f kern/boot
 -      rm -f kern/include/arch
++      @rm -rf $(OBJDIR)
++      @rm -f kern/boot
++      @rm -f kern/include/arch
++      @echo All clean and pretty!
  
  always:
        @:
@@@ -7,33 -7,33 +7,47 @@@
  #define rmb() ({ asm volatile("lfence"); })
  #define wmb() 
  
--//linux style atomic ops
--typedef struct {volatile uint32_t real_num;} atomic_t;
--#define atomic_read(atom) ((atom)->real_num)
--#define atomic_set(atom, val) (((atom)->real_num) = (val))
--#define atomic_init(i) {(i)}
--//and the atomic incs, etc take an atomic_t ptr, deref inside
--
--static inline void atomic_inc(atomic_t* number);
--static inline void atomic_dec(atomic_t* number);
++typedef void* atomic_t;
++
++static inline void atomic_init(atomic_t *number, int32_t val);
++static inline int32_t atomic_read(atomic_t *number);
++static inline void atomic_set(atomic_t *number, int32_t val);
++static inline void atomic_inc(atomic_t *number);
++static inline void atomic_dec(atomic_t *number);
  static inline void atomic_andb(volatile uint8_t* number, uint8_t mask);
  static inline void spin_lock(volatile uint32_t* lock);
  static inline void spin_unlock(volatile uint32_t* lock);
  
  /* Inlined functions declared above */
++static inline void atomic_init(atomic_t *number, int32_t val)
++{
++      asm volatile("movl %1,%0" : "=m"(*number) : "r"(val));
++}
++
++static inline int32_t atomic_read(atomic_t *number)
++{
++      int32_t val;
++      asm volatile("movl %1,%0" : "=r"(val) : "m"(*number));
++      return val;
++}
++
++static inline void atomic_set(atomic_t *number, int32_t val)
++{
++      asm volatile("movl %1,%0" : "=m"(*number) : "r"(val));
++}
  
  // need to do this with pointers and deref.  %0 needs to be the memory address
--static inline void atomic_inc(atomic_tnumber)
++static inline void atomic_inc(atomic_t *number)
  {
--      asm volatile("lock incl %0" : "=m"(number->real_num) : : "cc");
++      asm volatile("lock incl %0" : "=m"(*number) : : "cc");
  }
  
--static inline void atomic_dec(atomic_tnumber)
++static inline void atomic_dec(atomic_t *number)
  {
--      asm volatile("lock decl %0" : "=m"(number->real_num) : : "cc");
++      asm volatile("lock decl %0" : "=m"(*number) : : "cc");
  }
  
--static inline void atomic_andb(uint8_t* number, uint8_t mask)
++static inline void atomic_andb(volatile uint8_t *number, uint8_t mask)
  {
        asm volatile("lock andb %1,%0" : "=m"(*number) : "r"(mask) : "cc");
  }
  #include <atomic.h>
  #include <workqueue.h>
  
- // be careful changing this, esp if you go over 16
- #define NUM_HANDLER_WRAPPERS          5
- typedef struct HandlerWrapper {
-       checklist_t* cpu_list;
-       uint8_t vector;
- } handler_wrapper_t;
 -#ifdef __BOCHS__
 -#define SMP_CALL_FUNCTION_TIMEOUT    0x00ffffff
 -#define SMP_BOOT_TIMEOUT             0x0000ffff
 -#else
 -#define SMP_CALL_FUNCTION_TIMEOUT    0x7ffffff0
 -#define SMP_BOOT_TIMEOUT             0x002fffff
 -#endif
--
 -typedef struct per_cpu_info {
 +// will want this padded out to cacheline alignment
 +struct per_cpu_info {
        uint32_t lock;
 -      // Once we have a real kmalloc, we can make this dynamic.  Want a queue.
 -      work_t delayed_work;
 -      // will want it padded out to an even cacheline
 -} per_cpu_info_t;
 -
 -extern per_cpu_info_t per_cpu_info[MAX_NUM_CPUS];
 +      struct workqueue workqueue;
 +};
 +extern struct per_cpu_info  per_cpu_info[MAX_NUM_CPUS];
  extern volatile uint8_t num_cpus;
  
  /* SMP bootup functions */
@@@ -36,17 -34,20 +36,21 @@@ KERN_SRCFILES := $(KERN_ARCH_SRCFILES) 
  KERN_SRCFILES := $(wildcard $(KERN_SRCFILES))
  
  KERN_APPFILES := \
--                    $(USER_APPS_ROSLIB_DIR)/proctests \
--                    $(USER_APPS_ROSLIB_DIR)/fptest \
--                    $(USER_APPS_ROSLIB_DIR)/null \
-                     $(USER_APPS_ROSLIB_DIR)/hello \
-                     $(USER_APPS_ROSLIB_DIR)/spawn \
-                     $(USER_APPS_PARLIB_DIR)/channel_test_client \
-                     $(USER_APPS_PARLIB_DIR)/channel_test_server \
-                     $(USER_APPS_ROSLIB_DIR)/measurements
- #                    $(USER_APPS_PARLIB_DIR)/draw_nanwan
- #                    $(USER_APPS_PARLIB_DIR)/open_read \
- #                    $(USER_APPS_PARLIB_DIR)/hello
 -                    $(USER_APPS_ROSLIB_DIR)/hello
++                 $(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
+ ifeq ($(TARGET_ARCH),i386)
+       KERN_APPFILES += \
 -                          $(USER_APPS_PARLIB_DIR)/channel_test_client \
 -                          $(USER_APPS_PARLIB_DIR)/channel_test_server \
 -                          $(USER_APPS_ROSLIB_DIR)/measurements
 -      #                    $(USER_APPS_PARLIB_DIR)/draw_nanwan
 -      #                    $(USER_APPS_PARLIB_DIR)/open_read \
 -      #                    $(USER_APPS_PARLIB_DIR)/hello
++                       $(USER_APPS_PARLIB_DIR)/channel_test_client \
++                       $(USER_APPS_PARLIB_DIR)/channel_test_server \
++                       $(USER_APPS_ROSLIB_DIR)/measurements
++#                      $(USER_APPS_PARLIB_DIR)/draw_nanwan \
++#                      $(USER_APPS_PARLIB_DIR)/open_read \
++#                      $(USER_APPS_PARLIB_DIR)/hello
+ endif
  
  KERN_LDFLAGS   := $(KERN_LDFLAGS) -L$(OBJDIR)/$(KERN_DIR) \
                    -T $(ARCH_DIR)/$(TARGET_ARCH)/kernel.ld
diff --cc kern/src/env.c
@@@ -22,7 -22,7 +22,7 @@@
  #include <ros/error.h>
  
  env_t *envs = NULL;           // All environments
--atomic_t num_envs = atomic_init(0);
++atomic_t num_envs;
  // TODO: make this a struct of info including the pointer and cacheline-align it
  // This lets the kernel know what process is running on the core it traps into.
  // A lot of the Env business, including this and its usage, will change when we
@@@ -88,6 -87,6 +88,8 @@@ voi
  env_init(void)
  {
        int i;
++
++      atomic_init(&num_envs, 0);
        LIST_INIT(&env_free_list);
        assert(envs != NULL);
        for (i = NENV-1; i >= 0; i--) { TRUSTEDBLOCK // asw ivy workaround
diff --cc kern/src/init.c
@@@ -20,9 -20,8 +20,8 @@@
  #include <assert.h>
  #include <monitor.h>
  #include <pmap.h>
 -#include <env.h>
 -#include <testing.h>
 +#include <process.h>
 +#include <trap.h>
- #include <testing.h>
  #include <syscall.h>
  #include <kclock.h>
  #include <manager.h>
@@@ -58,15 -57,15 +57,6 @@@ void kernel_init(multiboot_info_t *mboo
  
        // this returns when all other cores are done and ready to receive IPIs
        smp_boot();
--      test_smp_call_functions();
--      test_checklists();
--      test_barrier();
--      test_print_info();
--      /*
--      test_lapic_status_bit();
--      test_ipi_sending();
--      test_pit();
--      */
  
        manager();
  }
diff --cc kern/src/kfs.c
index 819c8c4,0000000..df853fb
mode 100644,000000..100644
--- /dev/null
@@@ -1,60 -1,0 +1,65 @@@
- DECL_PROG(roslib_hello);
 +/*
 + * Copyright (c) 2009 The Regents of the University of California
 + * Barret Rhoden <brho@cs.berkeley.edu>
 + * See LICENSE for details.
 + */
 +
 +#include <kfs.h>
 +#include <string.h>
 +#include <assert.h>
 +#include <ros/error.h>
 +
 +#define DECL_PROG(x) extern uint8_t _binary_obj_user_apps_##x##_start[], _binary_obj_user_apps_##x##_size[];      
 +
 +#define KFS_ENTRY(x) {#x, _binary_obj_user_apps_##x##_start, (size_t) _binary_obj_user_apps_##x##_size},
 +
 +/*
 + * Hardcode the files included in the KFS.  This needs to be in sync with the
 + * userapps in kern/src/Makefrag.
 + * Make sure to declare it, and add an entry.  Keep MAX_KFS_FILES big enough too
 + */
 +DECL_PROG(roslib_proctests);
 +DECL_PROG(roslib_fptest);
 +DECL_PROG(roslib_null);
-       KFS_ENTRY(roslib_hello)
 +DECL_PROG(roslib_spawn);
++DECL_PROG(roslib_hello);
++
++#ifdef __i386__
 +DECL_PROG(parlib_channel_test_client);
 +DECL_PROG(parlib_channel_test_server);
 +DECL_PROG(roslib_measurements);
++#endif
 +
 +struct kfs_entry kfs[MAX_KFS_FILES] = {
 +      KFS_ENTRY(roslib_proctests)
 +      KFS_ENTRY(roslib_fptest)
 +      KFS_ENTRY(roslib_null)
 +      KFS_ENTRY(roslib_spawn)
++      KFS_ENTRY(roslib_hello)
++      #ifdef __i386__
 +      KFS_ENTRY(parlib_channel_test_client)
 +      KFS_ENTRY(parlib_channel_test_server)
 +      KFS_ENTRY(roslib_measurements)
++      #endif
 +};
 +
 +ssize_t kfs_lookup_path(char* path)
 +{
 +      for (int i = 0; i < MAX_KFS_FILES; i++)
 +              // need to think about how to copy-in something of unknown length
 +              if (!strncmp(kfs[i].name, path, strlen(path)))
 +                      return i;
 +      return -EINVAL;
 +}
 +
 +/*
 + * Creates a process from the file pointed to by the KFS inode (index)
 + * This should take a real inode or something to point to the real location,
 + * and env_create shouldn't assume everything is contiguous
 + */
 +struct proc *kfs_proc_create(size_t kfs_inode)
 +{
 +      if (kfs_inode < 0 || kfs_inode >= MAX_KFS_FILES)
 +              panic("Invalid kfs_inode.  Check you error codes!");
 +      return env_create(kfs[kfs_inode].start, kfs[kfs_inode].size);
 +}
@@@ -30,13 -28,28 +30,24 @@@ void manager(void
        env_t *envs[256];
  
        switch (progress++) {
 -      
 -      #ifdef __i386__
 -
                case 0:
 -
 -      #if 0
 -              case 0:
 -                      printk("Beginning Tests\n");
 -                      test_run_measurements(progress-1);  // should never return
 +                      envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
 +                      proc_set_state(envs[0], PROC_RUNNABLE_S);
 +                      env_run(envs[0]);
 +                      break;
++      #ifdef __i386__
++              case 1:
++                      panic("Do not panic");
+                       envs[0] = ENV_CREATE(parlib_channel_test_client);
+                       envs[1] = ENV_CREATE(parlib_channel_test_server);
+                       smp_call_function_single(1, run_env_handler, envs[0], 0);
+                       smp_call_function_single(2, run_env_handler, envs[1], 0);
 -      #endif
 -
 -              case 1:
+                       break;
 -      #else
 -
 -              case 0:
+               case 2:
+               case 3:
++      #else // sparc
 +              case 1:
 +                      panic("Do not panic");
                        envs[0] = ENV_CREATE(roslib_proctests);
                        envs[1] = ENV_CREATE(roslib_proctests);
                        envs[2] = ENV_CREATE(roslib_proctests);
                        envs[4] = ENV_CREATE(roslib_fptest);
                        envs[5] = ENV_CREATE(roslib_hello);
                        envs[6] = ENV_CREATE(roslib_null);
--                      //envs[6] = ENV_CREATE(roslib_measurements);
                        env_run(envs[0]);
                        break;
-                       #if 0
-                       #endif
 -              case 1:
                case 2:
 +                      #if 0
 +                      // reminder of how to spawn remotely
 +                      for (int i = 0; i < 8; i++) {
 +                              envs[i] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
 +                              proc_set_state(envs[i], PROC_RUNNABLE_S);
 +                              smp_call_function_single(i, run_env_handler, envs[i], 0);
 +                      }
 +                      process_workqueue();
 +                      #endif
                case 3:
 -
+       #endif
 +              #if 0
-               case 0:
++              case 4:
 +                      printk("Beginning Tests\n");
 +                      test_run_measurements(progress-1);  // should never return
 +                      break;
-               case 1:
++              case 5:
 +                      envs[0] = ENV_CREATE(parlib_channel_test_client);
 +                      envs[1] = ENV_CREATE(parlib_channel_test_server);
 +                      smp_call_function_single(1, run_env_handler, envs[0], 0);
 +                      smp_call_function_single(2, run_env_handler, envs[1], 0);
-               case 2:
-               case 3:
++              case 6:
++              #endif
                case 4:
++                      /*
++                      test_smp_call_functions();
++                      test_checklists();
++                      test_barrier();
++                      test_print_info();
++                      test_lapic_status_bit();
++                      test_ipi_sending();
++                      test_pit();
++                      */
                case 5:
                case 6:
                case 7:
                case 12:
                case 13:
                case 14:
-                       test_run_measurements(progress-1);
-                       break;
-               #endif
+                       //test_run_measurements(progress-1);
 -                      break;
                default:
                        printk("Manager Progress: %d\n", progress);
                        schedule();
Simple merge
@@@ -74,7 -74,7 +74,7 @@@ void test_pic_reception(void
        while(1);
  }
  
--#endif
++#endif // __i386__
  
  void test_print_info(void)
  {
@@@ -268,7 -269,7 +268,7 @@@ void test_checklists(void
  
  }
  
--atomic_t a = atomic_init(0), b = atomic_init(0), c = atomic_init(0);
++atomic_t a, b, c;
  
  void test_incrementer_handler(trapframe_t *tf, void* data)
  {
@@@ -284,6 -285,6 +284,9 @@@ void test_null_handler(trapframe_t *tf
  void test_smp_call_functions(void)
  {
        int i;
++      atomic_init(&a, 0);
++      atomic_init(&b, 0);
++      atomic_init(&c, 0);
        handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
                          *waiter4 = 0, *waiter5 = 0;
        uint8_t me = core_id();
@@@ -401,7 -402,7 +404,7 @@@ void test_lapic_status_bit(void
        printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
        // hopefully that handler never fires again.  leaving it registered for now.
  }
--#endif
++#endif // __i386__
  
  /******************************************************************************/
  /*            Test Measurements: Couples with measurement.c                   */
@@@ -533,6 -536,8 +538,8 @@@ void test_run_measurements(uint32_t job
        panic("Error in test setup!!");
  }
  
 -#endif
++#endif // __i386__
  /************************************************************/
  /* ISR Handler Functions */
  
@@@ -576,7 -581,7 +583,7 @@@ void test_print_info_handler(trapframe_
                read_msr(0x20c), read_msr(0x20d));
        cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
                read_msr(0x20e), read_msr(0x20f));
--#endif
++#endif // __i386__
        cprintf("----------------------------\n");
        spin_unlock_irqsave(&print_info_lock);
  }
@@@ -616,11 -621,11 +623,12 @@@ void test_pit(void
        enable_irq();
        lapic_set_timer(10000000, FALSE);
  
--      atomic_t waiting = atomic_init(1);
++      atomic_t waiting;
++      atomic_init(&waiting, 1);
        register_interrupt_handler(interrupt_handlers, test_vector,
                                   test_waiting_handler, &waiting);
        while(atomic_read(&waiting))
                cpu_relax();
        cprintf("End now\n");
  }
--#endif
++#endif // __i386__