Fixed up error codes to all have a positive 'defined' value and a -negative return...
authorKevin Klues <klueska@eecs.berkeley.edu>
Wed, 1 Jul 2009 19:23:06 +0000 (12:23 -0700)
committerKevin Klues <klueska@eecs.berkeley.edu>
Wed, 1 Jul 2009 19:23:06 +0000 (12:23 -0700)
12 files changed:
include/arch/mmu.h
include/ros/error.h
kern/src/atomic.c
kern/src/env.c
kern/src/pmap.c
kern/src/printfmt.c
kern/src/smp.c
kern/src/syscall.c
user/parlib/src/debugfmt.c
user/roslib/src/asynccall.c
user/roslib/src/printfmt.c
user/roslib/src/syscall.c

index b2fe3c7..bc85efc 100644 (file)
@@ -72,6 +72,9 @@
 #define PTE_PAT                0x080   // PAT (only applies to second layer PTEs)
 #define PTE_G          0x100   // Global Page
 
+#define VALID_USER_PERMS(perm) \
+       (((perm) == PTE_U) || ((perm) == (PTE_U | PTE_W))) 
+
 // The PTE_AVAIL bits aren't used by the kernel or interpreted by the
 // hardware, so user processes are allowed to set them arbitrarily.
 #define PTE_AVAIL      0xE00   // Available for software use
index 28fa1f9..ed0ec3a 100644 (file)
@@ -3,22 +3,43 @@
 #ifndef ROS_INC_ERROR_H
 #define ROS_INC_ERROR_H
 
+#define DECLARE_ERROR_CODE(e, s)
+
 typedef enum {
-       E_DEADLOCK      =       -3,
-       E_BUSY          =       -2,
-       E_FAIL          =       -1,
-       E_SUCCESS       =       0,
+       ESUCCESS = 0,            // Success
+       EFAIL,                   // Generic Failure
+       EPERM,                   // Wrong permissions
+       EDEADLOCK,               // Would cause deadlock
+       EBUSY,                   // Currently busy, try again later
+       ENOMEM,                  // No memory available
+       EINVAL,                  // Invalid arguments
+       EFAULT,                  // Segmentation fault
+       EBADENV,                 // Bad environment 
+       ENOFREEENV,              // No free environment
+       EUNSPECIFIED,            // Unspecified
+       NUMERRORS,               // Total number of error codes
 } error_t;
 
-// Kernel error codes -- keep in sync with list in lib/printfmt.c.
-#define E_UNSPECIFIED  1       // Unspecified or unknown problem
-#define E_BAD_ENV              2       // Environment doesn't exist or otherwise
-                                                       // cannot be used in requested action
-#define E_INVAL                        3       // Invalid parameter
-#define E_NO_MEM               4       // Request failed due to memory shortage
-#define E_NO_FREE_ENV  5       // Attempt to create a new environment beyond
-                                                       // the maximum allowed
-#define E_FAULT                        6       // Memory fault
-#define        MAXERROR                6
+/* 
+ * The special format for printk %e takes an integer 
+ * error code and prints a string describing the error.
+ * The integer may be positive or negative,
+ * so that -ENOMEM and ENOMEM are equivalent.
+ */
+
+static const char * const error_string[NUMERRORS] =
+{
+       "Success",
+       "Generic Failure",
+       "Wrong permissions",
+       "Would cause deadlock",
+       "Currently busy, try again later",
+       "No memory available",
+       "Invalid arguments"
+       "Segmentation fault"
+       "Bad environment"
+       "No free environment"
+       "Unspecified"
+};
 
 #endif // !ROS_INC_ERROR_H */
index 1135416..e823ec3 100644 (file)
@@ -15,7 +15,7 @@ int commit_checklist_wait(checklist_t* list, checklist_mask_t* mask)
        // Or, bail out if we can see the list is already in use.  This check is
        // just an optimization before we try to use the list for real.
        if ((checklist_is_locked(list)) || !checklist_is_clear(list))
-               return E_BUSY;
+               return -EBUSY;
 
        // possession of this lock means you can wait on it and set it
        spin_lock_irqsave(&list->lock);
index 1260481..a683d38 100644 (file)
@@ -37,7 +37,7 @@ static env_list_t env_free_list;      // Free list
 // Converts an envid to an env pointer.
 //
 // RETURNS
-//   0 on success, -E_BAD_ENV on error.
+//   0 on success, -EBADENV on error.
 //   On success, sets *env_store to the environment.
 //   On error, sets *env_store to NULL.
 //
@@ -61,7 +61,7 @@ envid2env(envid_t envid, env_t **env_store, bool checkperm)
        e = &envs[ENVX(envid)];
        if (e->env_status == ENV_FREE || e->env_id != envid) {
                *env_store = 0;
-               return -E_BAD_ENV;
+               return -EBADENV;
        }
 
        // Check that the calling environment has legitimate permission
@@ -71,7 +71,7 @@ envid2env(envid_t envid, env_t **env_store, bool checkperm)
        // or an immediate child of the current environment.
        if (checkperm && e != curenv && e->env_parent_id != curenv->env_id) {
                *env_store = 0;
-               return -E_BAD_ENV;
+               return -EBADENV;
        }
 
        *env_store = e;
@@ -105,7 +105,7 @@ env_init(void)
 // of the environment's virtual address space.
 //
 // Returns 0 on success, < 0 on error.  Errors include:
-//     -E_NO_MEM if page directory or table could not be allocated.
+//     -ENOMEM if page directory or table could not be allocated.
 //
 static int
 env_setup_vm(env_t *e)
@@ -212,8 +212,8 @@ WRITES(e->env_pgdir, e->env_cr3, e->env_procinfo, e->env_procdata,
 // On success, the new environment is stored in *newenv_store.
 //
 // Returns 0 on success, < 0 on failure.  Errors include:
-//     -E_NO_FREE_ENV if all NENVS environments are allocated
-//     -E_NO_MEM on memory exhaustion
+//     -ENOFREEENV if all NENVS environments are allocated
+//     -ENOMEM on memory exhaustion
 //
 int
 env_alloc(env_t **newenv_store, envid_t parent_id)
@@ -223,7 +223,7 @@ env_alloc(env_t **newenv_store, envid_t parent_id)
        env_t *e;
 
        if (!(e = LIST_FIRST(&env_free_list)))
-               return -E_NO_FREE_ENV;
+               return -ENOFREEENV;
        
        //memset((void*)e + sizeof(e->env_link), 0, sizeof(*e) - sizeof(e->env_link));
 
@@ -497,7 +497,7 @@ error_t env_incref(env_t* e)
        if (e->env_refcnt)
                e->env_refcnt++;
        else
-               retval = E_BAD_ENV;
+               retval = -EBADENV;
        spin_unlock(&e->lock);
        return retval;
 }
index 3d944e5..632f5ae 100644 (file)
@@ -755,12 +755,12 @@ page_initpp(page_t *pp)
  *
  * RETURNS 
  *   0         -- on success
- *   -E_NO_MEM -- otherwise 
+ *   -ENOMEM   -- otherwise 
  */
 int page_alloc(page_t **pp_store)
 {
        if (LIST_EMPTY(&page_free_list))
-               return -E_NO_MEM;
+               return -ENOMEM;
        *pp_store = LIST_FIRST(&page_free_list);
        LIST_REMOVE(*pp_store, pp_link);
        page_initpp(*pp_store);
@@ -777,13 +777,13 @@ int page_alloc(page_t **pp_store)
  *
  * RETURNS 
  *   0         -- on success
- *   -E_NO_MEM -- otherwise 
+ *   -ENOMEM   -- otherwise 
  */
 int page_alloc_specific(page_t **pp_store, size_t ppn)
 {
        page_t* page = ppn2page(ppn);
        if( page->pp_ref != 0 )
-               return -E_NO_MEM;
+               return -ENOMEM;
        *pp_store = page;
        LIST_REMOVE(*pp_store, pp_link);
        page_initpp(*pp_store);
@@ -824,7 +824,7 @@ error_t     pagetable_remove(pde_t *pgdir, void *va)
        pde_t* the_pde = &pgdir[PDX(va)];
 
        if (!(*the_pde & PTE_P) || (*the_pde & PTE_PS))
-               return -E_FAULT;
+               return -EFAULT;
        pte_t* page_table = (pde_t*)KADDR(PTE_ADDR(*the_pde));
        for (int i = 0; i < NPTENTRIES; i++) 
                if (page_table[i] & PTE_P)
@@ -903,7 +903,7 @@ pgdir_walk(pde_t *pgdir, const void *SNT va, int create)
 //
 // RETURNS: 
 //   0 on success
-//   -E_NO_MEM, if page table couldn't be allocated
+//   -ENOMEM, if page table couldn't be allocated
 //
 // Hint: The TA solution is implemented using pgdir_walk, page_remove,
 // and page2pa.
@@ -916,7 +916,7 @@ page_insert(pde_t *pgdir, page_t *pp, void *va, int perm)
 {
        pte_t* pte = pgdir_walk(pgdir, va, 1);
        if (!pte)
-               return -E_NO_MEM;
+               return -ENOMEM;
        // need to up the ref count in case pp is already mapped at va
        // and we don't want to page_remove (which could free pp) and then 
        // continue as if pp wasn't freed.  moral = up the ref asap
@@ -1031,7 +1031,7 @@ static void *DANGEROUS user_mem_check_addr;
 // check that user pointers aren't dereferenced. User pointers get the
 // DANGEROUS qualifier. After validation, these functions return a
 // COUNT(len) pointer. user_mem_check now returns NULL on error instead of
-// -E_FAULT.
+// -EFAULT.
 
 void *COUNT(len)
 user_mem_check(env_t *env, const void *DANGEROUS va, size_t len, int perm)
@@ -1112,7 +1112,7 @@ page_check(void)
        LIST_INIT(&page_free_list);
 
        // should be no free memory
-       assert(page_alloc(&pp) == -E_NO_MEM);
+       assert(page_alloc(&pp) == -ENOMEM);
 
        // Fill pp1 with bogus data and check for invalid tlb entries
        memset(page2kva(pp1), 0xFFFFFFFF, PGSIZE);
@@ -1150,7 +1150,7 @@ page_check(void)
        }
 
        // should be no free memory
-       assert(page_alloc(&pp) == -E_NO_MEM);
+       assert(page_alloc(&pp) == -ENOMEM);
 
        // should be able to map pp2 at PGSIZE because it's already there
        assert(page_insert(boot_pgdir, pp2, (void*) PGSIZE, PTE_U) == 0);
@@ -1165,7 +1165,7 @@ page_check(void)
 
        // pp2 should NOT be on the free list
        // could happen in ref counts are handled sloppily in page_insert
-       assert(page_alloc(&pp) == -E_NO_MEM);
+       assert(page_alloc(&pp) == -ENOMEM);
 
        // should not be able to map at PTSIZE because need free page for page table
        assert(page_insert(boot_pgdir, pp0, (void*) PTSIZE, 0) < 0);
@@ -1201,7 +1201,7 @@ page_check(void)
        assert(page_alloc(&pp) == 0 && pp == pp1);
 
        // should be no free memory
-       assert(page_alloc(&pp) == -E_NO_MEM);
+       assert(page_alloc(&pp) == -ENOMEM);
 
        // forcibly take pp0 back
        assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
index 9a0fd09..c0bb169 100644 (file)
 #include <stdarg.h>
 
 /*
- * Space or zero padding and a field width are supported for the numeric
- * formats only. 
- * 
- * The special format %e takes an integer error code
- * and prints a string describing the error.
- * The integer may be positive or negative,
- * so that -E_NO_MEM and E_NO_MEM are equivalent.
- */
-
-static const char * const error_string[MAXERROR + 1] =
-{
-       NULL,
-       "unspecified error",
-       "bad environment",
-       "invalid parameter",
-       "out of memory",
-       "out of environments",
-       "segmentation fault",
-};
-
-/*
  * Print a number (base <= 16) in reverse order,
  * using specified putch function and associated pointer putdat.
  */
@@ -166,10 +145,10 @@ void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_li
                        err = va_arg(ap, int);
                        if (err < 0)
                                err = -err;
-                       if (err > MAXERROR || (p = error_string[err]) == NULL)
+                       if (err >= NUMERRORS)
                                printfmt(putch, putdat, "error %d", err);
                        else
-                               printfmt(putch, putdat, "%s", p);
+                               printfmt(putch, putdat, "%s", error_string[err]);
                        break;
 
                // string
@@ -271,7 +250,7 @@ int vsnprintf(char *buf, int n, const char *fmt, va_list ap)
        sprintbuf_t *bp = &b;
 
        if (buf == NULL || n < 1)
-               return -E_INVAL;
+               return -EINVAL;
 
        // print the string to the buffer
        vprintfmt((void*)sprintputch, (void**)&bp, fmt, ap);
index 0932120..d9052da 100644 (file)
@@ -243,7 +243,7 @@ static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler, void* da
        atomic_inc(&outstanding_calls);
        if (outstanding_calls > NUM_HANDLER_WRAPPERS) {
                atomic_dec(&outstanding_calls);
-               return E_BUSY;
+               return -EBUSY;
        }
        
        // assumes our cores are numbered in order
@@ -299,7 +299,7 @@ static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler, void* da
                // to use (have to check your return value).  consider putting a delay
                // here too (like if wrapper_num == initial_wrapper_num)
                if (count++ > NUM_HANDLER_WRAPPERS * 1000) // note 1000 isn't enough...
-                       return E_BUSY;
+                       return -EBUSY;
                */
        }
 
@@ -373,7 +373,7 @@ int smp_call_wait(handler_wrapper_t* wrapper)
                return 0;
        } else {
                warn("Attempting to wait on null wrapper!  Check your return values!");
-               return E_FAIL;
+               return -EFAIL;
        }
 }
 
index 068a94e..b8de0a9 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <arch/types.h>
 #include <arch/x86.h>
+#include <arch/mmu.h>
 #include <arch/console.h>
 #include <arch/apic.h>
 #include <arch/timer.h>
@@ -50,7 +51,7 @@ static ssize_t sys_serial_write(env_t* e, const char *DANGEROUS buf, size_t len)
                        serial_send_byte(buf[i]);       
                return (ssize_t)len;
        #else
-               return -E_INVAL;
+               return -EINVAL;
        #endif
 }
 
@@ -67,7 +68,7 @@ static ssize_t sys_serial_read(env_t* e, char *DANGEROUS buf, size_t len)
                }
                return (ssize_t)bytes_read;
        #else
-               return -E_INVAL;
+               return -EINVAL;
        #endif
 }
 
@@ -194,7 +195,7 @@ static envid_t sys_getcpuid(void)
 // Destroy a given environment (possibly the currently running environment).
 //
 // Returns 0 on success, < 0 on error.  Errors are:
-//     -E_BAD_ENV if environment envid doesn't currently exist,
+//     -EBADENV if environment envid doesn't currently exist,
 //             or the caller doesn't have permission to change envid.
 static error_t sys_env_destroy(env_t* e, envid_t envid)
 {
@@ -239,8 +240,8 @@ intreg_t syscall(env_t* e, uint32_t syscallno, uint32_t a1, uint32_t a2,
        assert(e); // should always have an env for every syscall
        //printk("Running syscall: %d\n", syscallno);
        if (INVALID_SYSCALL(syscallno))
-               return -E_INVAL;
-       
+               return -EINVAL;
+
        switch (syscallno) {
                case SYS_null:
                        sys_null();
@@ -272,7 +273,7 @@ intreg_t syscall(env_t* e, uint32_t syscallno, uint32_t a1, uint32_t a2,
                case SYS_proc_run:
                        panic("Not implemented");
                default:
-                       // or just return -E_INVAL
+                       // or just return -EINVAL
                        panic("Invalid syscall number %d for env %x!", syscallno, *e);
        }
        return 0xdeadbeef;
index 121d1fe..a71b839 100644 (file)
@@ -7,27 +7,6 @@
 #include <debug.h>
 
 /*
- * Space or zero padding and a field width are supported for the numeric
- * formats only. 
- * 
- * The special format %e takes an integer error code
- * and prints a string describing the error.
- * The integer may be positive or negative,
- * so that -E_NO_MEM and E_NO_MEM are equivalent.
- */
-
-static const char * const error_string[MAXERROR + 1] =
-{
-       NULL,
-       "unspecified error",
-       "bad environment",
-       "invalid parameter",
-       "out of memory",
-       "out of environments",
-       "segmentation fault",
-};
-
-/*
  * Print a number (base <= 16) in reverse order,
  * using specified putch function and associated pointer putdat.
  */
@@ -159,10 +138,10 @@ void vdebugfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_li
                        err = va_arg(ap, int);
                        if (err < 0)
                                err = -err;
-                       if (err > MAXERROR || (p = error_string[err]) == NULL)
+                       if (err >= NUMERRORS)
                                debugfmt(putch, putdat, "error %d", err);
                        else
-                               debugfmt(putch, putdat, "%s", p);
+                               debugfmt(putch, putdat, "%s", error_string[err]);
                        break;
 
                // string
index 688c70f..23a7a9b 100644 (file)
@@ -12,7 +12,7 @@ error_t waiton_async_call(async_desc_t* desc, async_rsp_t* rsp)
        syscall_desc_t* d;
        error_t err = 0;
        if (!desc)
-               return -E_INVAL;
+               return -EINVAL;
        while (!(TAILQ_EMPTY(&desc->syslist))) {
                d = TAILQ_FIRST(&desc->syslist);
                err = MIN(waiton_syscall(d, &syscall_rsp), err);
@@ -67,12 +67,12 @@ error_t get_all_desc(async_desc_t** a_desc, syscall_desc_t** s_desc)
 {
        assert(a_desc && s_desc);
        if ((current_async_desc = get_async_desc()) == NULL)
-               return E_BUSY;
+               return -EBUSY;
        *a_desc = current_async_desc;
        if (*s_desc = get_sys_desc(current_async_desc))
                return 0;
        // in case we could get an async, but not a syscall desc, then clean up.
        POOL_PUT(&async_desc_pool, current_async_desc);
        current_async_desc = NULL;
-       return E_BUSY;
+       return -EBUSY;
 }
index 61deaf9..911ae11 100644 (file)
 #include <stdarg.h>
 
 /*
- * Space or zero padding and a field width are supported for the numeric
- * formats only. 
- * 
- * The special format %e takes an integer error code
- * and prints a string describing the error.
- * The integer may be positive or negative,
- * so that -E_NO_MEM and E_NO_MEM are equivalent.
- */
-
-static const char * const error_string[MAXERROR + 1] =
-{
-       NULL,
-       "unspecified error",
-       "bad environment",
-       "invalid parameter",
-       "out of memory",
-       "out of environments",
-       "segmentation fault",
-};
-
-/*
  * Print a number (base <= 16) in reverse order,
  * using specified putch function and associated pointer putdat.
  */
@@ -166,10 +145,10 @@ void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_li
                        err = va_arg(ap, int);
                        if (err < 0)
                                err = -err;
-                       if (err > MAXERROR || (p = error_string[err]) == NULL)
+                       if (err >= NUMERRORS)
                                printfmt(putch, putdat, "error %d", err);
                        else
-                               printfmt(putch, putdat, "%s", p);
+                               printfmt(putch, putdat, "%s", error_string[err]);
                        break;
 
                // string
@@ -271,7 +250,7 @@ int vsnprintf(char *buf, int n, const char *fmt, va_list ap)
        sprintbuf_t *bp = &b;
 
        if (buf == NULL || n < 1)
-               return -E_INVAL;
+               return -EINVAL;
 
        // print the string to the buffer
        vprintfmt((void*)sprintputch, (void**)&bp, fmt, ap);
index 7a60785..ed0284f 100644 (file)
@@ -81,7 +81,7 @@ static error_t async_syscall(syscall_req_t* req, syscall_desc_t* desc)
        // we could spin til it's free, but that could deadlock if this same thread
        // is supposed to consume the requests it is waiting on later.
        if (RING_FULL(&sysfrontring))
-               return E_BUSY;
+               return -EBUSY;
        // req_prod_pvt comes in as the previously produced item.  need to
        // increment to the next available spot, which is the one we'll work on.
        // at some point, we need to listen for the responses.
@@ -102,10 +102,10 @@ error_t waiton_syscall(syscall_desc_t* desc, syscall_rsp_t* rsp)
        // Make sure we were given a desc with a non-NULL frontring.  This could
        // happen if someone forgot to check the error code on the paired syscall.
        if (!desc->sysfr)
-               return E_FAIL;
+               return -EFAIL;
        // this forces us to call wait in the order in which the syscalls are made.
        if (desc->idx != desc->sysfr->rsp_cons + 1)
-               return E_DEADLOCK;
+               return -EDEADLOCK;
        while (!(RING_HAS_UNCONSUMED_RESPONSES(desc->sysfr)))
                cpu_relax();
        memcpy(rsp, RING_GET_RESPONSE(desc->sysfr, desc->idx), sizeof(*rsp));