Changeset 96e01fbc in mainline for kernel


Ignore:
Timestamp:
2012-08-31T17:30:29Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2be2506a
Parents:
e0d5bc5 (diff), 0d57c3e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
kernel
Files:
1 added
28 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/asm.S

    re0d5bc5 r96e01fbc  
    362362         */
    363363        call syscall_handler
    364        
     364
     365        /*
     366         * Test if the saved return address is canonical and not-kernel.
     367         * We do this by looking at the 16 most significant bits
     368         * of the saved return address (two bytes at offset 6).
     369         */
     370        testw $0xffff, ISTATE_OFFSET_RIP+6(%rsp)
     371        jnz bad_rip
     372
    365373        cli
    366374       
     
    388396        sysretq
    389397
     398bad_rip:
     399        movq %rsp, %rdi
     400        movabs $bad_rip_msg, %rsi
     401        xorb %al, %al
     402        callq fault_from_uspace
     403        /* not reached */
     404       
     405bad_rip_msg:
     406        .asciz "Invalid instruction pointer."
     407
    390408/** Print Unicode character to EGA display.
    391409 *
  • kernel/arch/amd64/src/boot/multiboot.S

    re0d5bc5 r96e01fbc  
    7676
    7777multiboot_image_start:
     78        cli
    7879        cld
    7980       
     
    8182        movl $START_STACK, %esp
    8283       
    83         /* Initialize Global Descriptor Table register */
     84        /*
     85         * Initialize Global Descriptor Table and
     86         * Interrupt Descriptor Table registers
     87         */
    8488        lgdtl bootstrap_gdtr
     89        lidtl bootstrap_idtr
    8590       
    8691        /* Kernel data + stack */
     
    645650.section K_DATA_START, "aw", @progbits
    646651
     652.global bootstrap_idtr
     653bootstrap_idtr:
     654        .word 0
     655        .long 0
     656
    647657.global bootstrap_gdtr
    648658bootstrap_gdtr:
  • kernel/arch/amd64/src/boot/multiboot2.S

    re0d5bc5 r96e01fbc  
    116116
    117117multiboot2_image_start:
     118        cli
    118119        cld
    119120       
     
    121122        movl $START_STACK, %esp
    122123       
    123         /* Initialize Global Descriptor Table register */
     124        /*
     125         * Initialize Global Descriptor Table and
     126         * Interrupt Descriptor Table registers
     127         */
    124128        lgdtl bootstrap_gdtr
     129        lidtl bootstrap_idtr
    125130       
    126131        /* Kernel data + stack */
  • kernel/arch/amd64/src/boot/vesa_ret.inc

    re0d5bc5 r96e01fbc  
    11.code32
    22vesa_init_protected:
     3        cli
    34        cld
    45       
  • kernel/arch/ia32/src/boot/multiboot.S

    re0d5bc5 r96e01fbc  
    7373
    7474multiboot_image_start:
     75        cli
    7576        cld
    7677       
     
    7879        movl $START_STACK, %esp
    7980       
    80         /* Initialize Global Descriptor Table register */
     81        /*
     82         * Initialize Global Descriptor Table and
     83         * Interrupt Descriptor Table registers
     84         */
    8185        lgdtl bootstrap_gdtr
     86        lidtl bootstrap_idtr
    8287       
    8388        /* Kernel data + stack */
     
    701706page_directory:
    702707        .space 4096, 0
     708
     709.global bootstrap_idtr
     710bootstrap_idtr:
     711        .word 0
     712        .long 0
    703713
    704714.global bootstrap_gdtr
  • kernel/arch/ia32/src/boot/multiboot2.S

    re0d5bc5 r96e01fbc  
    114114
    115115multiboot2_image_start:
     116        cli
    116117        cld
    117118       
     
    119120        movl $START_STACK, %esp
    120121       
    121         /* Initialize Global Descriptor Table register */
     122        /*
     123         * Initialize Global Descriptor Table and
     124         * Interrupt Descriptor Table registers
     125         */
    122126        lgdtl bootstrap_gdtr
     127        lidtl bootstrap_idtr
    123128       
    124129        /* Kernel data + stack */
  • kernel/arch/ia32/src/boot/vesa_prot.inc

    re0d5bc5 r96e01fbc  
    8888                /* Returned back to protected mode */
    8989               
     90                /*
     91                 * Initialize Global Descriptor Table and
     92                 * Interrupt Descriptor Table registers
     93                 */
     94                lgdtl bootstrap_gdtr
     95                lidtl bootstrap_idtr
     96               
    9097                movzx %ax, %ecx
    9198                mov %ecx, KA2PA(bfb_scanline)
  • kernel/arch/ia32/src/boot/vesa_real.inc

    re0d5bc5 r96e01fbc  
    3030.code32
    3131vesa_init:
     32        lidtl vesa_idtr
    3233        jmp $GDT_SELECTOR(VESA_INIT_DES), $vesa_init_real - vesa_init
     34
     35vesa_idtr:
     36        .word 0x3ff
     37        .long 0
    3338
    3439.code16
  • kernel/arch/ia32/src/boot/vesa_ret.inc

    re0d5bc5 r96e01fbc  
    11.code32
    22vesa_init_protected:
     3        cli
    34        cld
    45       
  • kernel/arch/ia64/Makefile.inc

    re0d5bc5 r96e01fbc  
    3030BFD_ARCH = ia64-elf64
    3131
    32 CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127
     32#
     33# FIXME:
     34#
     35# The -fno-selective-scheduling and -fno-selective-scheduling2 options
     36# should be removed as soon as a bug in GCC concerning unchecked
     37# speculative loads is fixed.
     38#
     39# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53975 for reference.
     40#
     41
     42CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127 -fno-selective-scheduling -fno-selective-scheduling2
    3343GCC_CFLAGS += $(CMN1)
    3444ICC_CFLAGS += $(CMN1)
  • kernel/arch/mips32/Makefile.inc

    re0d5bc5 r96e01fbc  
    2929BFD_ARCH = mips
    3030BFD = binary
    31 GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=32
     31GCC_CFLAGS += -msoft-float -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=32
    3232
    3333BITS = 32
     
    4848        BFD_NAME = elf32-tradlittlemips
    4949        ENDIANESS = LE
    50         GCC_CFLAGS += -mhard-float
    5150endif
    5251
  • kernel/arch/mips64/Makefile.inc

    re0d5bc5 r96e01fbc  
    2929BFD_ARCH = mips:4000
    3030BFD = binary
    31 GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=64
     31GCC_CFLAGS += -msoft-float -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=64
    3232AFLAGS = -64
    3333
     
    4040        BFD_NAME = elf64-tradlittlemips
    4141        ENDIANESS = LE
    42         GCC_CFLAGS += -mhard-float
    4342endif
    4443
  • kernel/generic/include/interrupt.h

    re0d5bc5 r96e01fbc  
    3838#include <arch/interrupt.h>
    3939#include <print.h>
     40#include <stdarg.h>
    4041#include <typedefs.h>
    4142#include <proc/task.h>
     
    5859extern exc_table_t exc_table[];
    5960
     61extern void fault_from_uspace(istate_t *, const char *, ...)
     62    PRINTF_ATTRIBUTE(2, 3);
    6063extern void fault_if_from_uspace(istate_t *, const char *, ...)
    6164    PRINTF_ATTRIBUTE(2, 3);
  • kernel/generic/include/ipc/ipc.h

    re0d5bc5 r96e01fbc  
    7777        waitq_t wq;
    7878       
    79         /** Linkage for the list of task's synchronous answerboxes. */
    80         link_t sync_box_link;
    81        
    8279        /** Phones connected to this answerbox. */
    8380        list_t connected_phones;
     
    116113        struct task *sender;
    117114       
    118         /*
    119          * The caller box is different from sender->answerbox
    120          * for synchronous calls.
    121          */
    122         answerbox_t *callerbox;
    123        
    124115        /** Private data to internal IPC. */
    125116        sysarg_t priv;
     
    147138
    148139extern int ipc_call(phone_t *, call_t *);
    149 extern int ipc_call_sync(phone_t *, call_t *);
    150140extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int);
    151141extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int);
  • kernel/generic/include/ipc/irq.h

    re0d5bc5 r96e01fbc  
    3737
    3838/** Maximum number of IPC IRQ programmed I/O ranges. */
    39 #define IRQ_MAX_RANGE_COUNT     8
     39#define IRQ_MAX_RANGE_COUNT  8
    4040
    4141/** Maximum length of IPC IRQ program. */
    42 #define IRQ_MAX_PROG_SIZE  20
     42#define IRQ_MAX_PROG_SIZE  256
    4343
    4444#include <ipc/ipc.h>
  • kernel/generic/include/ipc/sysipc.h

    re0d5bc5 r96e01fbc  
    4040#include <typedefs.h>
    4141
    42 extern sysarg_t sys_ipc_call_sync_fast(sysarg_t, sysarg_t, sysarg_t,
    43     sysarg_t, sysarg_t, ipc_data_t *);
    44 extern sysarg_t sys_ipc_call_sync_slow(sysarg_t, ipc_data_t *, ipc_data_t *);
    4542extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t,
    4643    sysarg_t, sysarg_t, sysarg_t);
  • kernel/generic/include/print.h

    re0d5bc5 r96e01fbc  
    3838#include <typedefs.h>
    3939#include <stdarg.h>
    40 
    41 #ifndef NVERIFY_PRINTF
    42 
    43 #define PRINTF_ATTRIBUTE(start, end) \
    44         __attribute__((format(gnu_printf, start, end)))
    45 
    46 #else /* NVERIFY_PRINTF */
    47 
    48 #define PRINTF_ATTRIBUTE(start, end)
    49 
    50 #endif /* NVERIFY_PRINTF */
     40#include <printf/verify.h>
    5141
    5242#define EOF  (-1)
  • kernel/generic/include/proc/task.h

    re0d5bc5 r96e01fbc  
    9494        phone_t phones[IPC_MAX_PHONES];
    9595        stats_ipc_t ipc_info;   /**< IPC statistics */
    96         list_t sync_boxes;      /**< List of synchronous answerboxes. */
    9796        event_t events[EVENT_TASK_END - EVENT_END];
    9897       
  • kernel/generic/src/console/kconsole.c

    re0d5bc5 r96e01fbc  
    202202 *
    203203 */
    204 NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t * indev)
     204NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev)
    205205{
    206206        const char *name = input;
    207207       
    208208        size_t found = 0;
    209         /* Maximum Match Length : Length of longest matching common substring in
    210            case more than one match is found */
     209       
     210        /*
     211         * Maximum Match Length: Length of longest matching common
     212         * substring in case more than one match is found.
     213         */
    211214        size_t max_match_len = size;
    212215        size_t max_match_len_tmp = size;
     
    229232        }
    230233       
    231         /* If possible completions are more than MAX_TAB_HINTS, ask user whether to display them or not. */
     234        /*
     235         * If the number of possible completions is more than MAX_TAB_HINTS,
     236         * ask the user whether to display them or not.
     237         */
    232238        if (found > MAX_TAB_HINTS) {
    233239                printf("\n");
    234                 continue_showing_hints = console_prompt_display_all_hints(indev, found);
     240                continue_showing_hints =
     241                    console_prompt_display_all_hints(indev, found);
    235242        }
    236243       
     
    240247                while (cmdtab_search_one(name, &pos)) {
    241248                        cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
    242 
     249                       
    243250                        if (continue_showing_hints) {
    244251                                printf("%s (%s)\n", hlp->name, hlp->description);
    245252                                --hints_to_show;
    246253                                ++total_hints_shown;
    247 
    248                                 if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
    249                                         continue_showing_hints = console_prompt_more_hints(indev, &hints_to_show);
     254                               
     255                                if ((hints_to_show == 0) && (total_hints_shown != found)) {
     256                                        /* Ask user to continue */
     257                                        continue_showing_hints =
     258                                            console_prompt_more_hints(indev, &hints_to_show);
    250259                                }
    251260                        }
    252 
     261                       
    253262                        pos = pos->next;
    254                         for(max_match_len_tmp = 0; output[max_match_len_tmp] == hlp->name[input_len + max_match_len_tmp]
    255                                         && max_match_len_tmp < max_match_len; ++max_match_len_tmp);
     263                       
     264                        for (max_match_len_tmp = 0;
     265                            (output[max_match_len_tmp] ==
     266                            hlp->name[input_len + max_match_len_tmp]) &&
     267                            (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
     268                       
    256269                        max_match_len = max_match_len_tmp;
    257270                }
    258                 /* keep only the characters common in all completions */
     271               
     272                /* Keep only the characters common in all completions */
    259273                output[max_match_len] = 0;
    260274        }
     
    310324                                continue;
    311325                       
    312                         /* Find the beginning of the word
    313                            and copy it to tmp */
     326                        /*
     327                         * Find the beginning of the word
     328                         * and copy it to tmp
     329                         */
    314330                        size_t beg;
    315331                        for (beg = position - 1; (beg > 0) && (!isspace(current[beg]));
     
    333349                                continue;
    334350
    335                         /* We have hints, may be many. In case of more than one hint,
    336                            tmp will contain the common prefix. */
     351                        /*
     352                         * We have hints, possibly many. In case of more than one hint,
     353                         * tmp will contain the common prefix.
     354                         */
    337355                        size_t off = 0;
    338356                        size_t i = 0;
     
    340358                                if (!wstr_linsert(current, ch, position + i, MAX_CMDLINE))
    341359                                        break;
     360                               
    342361                                i++;
    343362                        }
  • kernel/generic/src/console/prompt.c

    re0d5bc5 r96e01fbc  
    4343 * @param indev Where to read characters from.
    4444 * @param hints Number of hints that would be displayed.
     45 *
    4546 * @return Whether to print all hints.
     47 *
    4648 */
    4749bool console_prompt_display_all_hints(indev_t *indev, size_t hints)
     
    4951        ASSERT(indev);
    5052        ASSERT(hints > 0);
    51 
    52         printf("Display all %zu possibilities? (y or n)", hints);
    53 
     53       
     54        printf("Display all %zu possibilities? (y or n) ", hints);
     55       
    5456        while (true) {
    5557                wchar_t answer = indev_pop_character(indev);
    56 
    57                 if (answer == 'y' || answer == 'Y') {
    58                         printf(" y");
     58               
     59                if ((answer == 'y') || (answer == 'Y')) {
     60                        printf("y");
    5961                        return true;
    6062                }
    61 
    62                 if (answer == 'n' || answer == 'N') {
    63                         printf(" n");
     63               
     64                if ((answer == 'n') || (answer == 'N')) {
     65                        printf("n");
    6466                        return false;
    6567                }
     
    7173 * When the function returns false, @p display_hints is set to zero.
    7274 *
    73  * @param[in] indev Where to read characters from.
     75 * @param[in]  indev        Where to read characters from.
    7476 * @param[out] display_hints How many hints to display.
     77 *
    7578 * @return Whether to display more hints.
     79 *
    7680 */
    7781bool console_prompt_more_hints(indev_t *indev, size_t *display_hints)
     
    7983        ASSERT(indev);
    8084        ASSERT(display_hints != NULL);
    81 
     85       
    8286        printf("--More--");
    8387        while (true) {
    8488                wchar_t continue_showing_hints = indev_pop_character(indev);
    8589                /* Display a full page again? */
    86                 if (continue_showing_hints == 'y'
    87                     || continue_showing_hints == 'Y'
    88                     || continue_showing_hints == ' ') {
     90                if ((continue_showing_hints == 'y') ||
     91                    (continue_showing_hints == 'Y') ||
     92                    (continue_showing_hints == ' ')) {
    8993                        *display_hints = MAX_TAB_HINTS - 1;
    9094                        break;
    9195                }
    92 
     96               
    9397                /* Stop displaying hints? */
    94                 if (continue_showing_hints == 'n'
    95                     || continue_showing_hints == 'N'
    96                     || continue_showing_hints == 'q'
    97                     || continue_showing_hints == 'Q') {
     98                if ((continue_showing_hints == 'n') ||
     99                    (continue_showing_hints == 'N') ||
     100                    (continue_showing_hints == 'q') ||
     101                    (continue_showing_hints == 'Q')) {
    98102                        *display_hints = 0;
    99103                        break;
    100104                }
    101 
     105               
    102106                /* Show one more hint? */
    103107                if (continue_showing_hints == '\n') {
     
    106110                }
    107111        }
    108 
     112       
    109113        /* Delete the --More-- option */
    110114        printf("\r         \r");
    111 
     115       
    112116        return *display_hints > 0;
    113117}
  • kernel/generic/src/debug/symtab.c

    re0d5bc5 r96e01fbc  
    210210 *
    211211 */
    212 int symtab_compl(char *input, size_t size, indev_t * indev)
     212int symtab_compl(char *input, size_t size, indev_t *indev)
    213213{
    214214#ifdef CONFIG_SYMTAB
     
    227227        const char *hint;
    228228        char output[MAX_SYMBOL_NAME];
    229         /* Maximum Match Length : Length of longest matching common substring in
    230            case more than one match is found */
     229       
     230        /*
     231         * Maximum Match Length: Length of longest matching common substring in
     232         * case more than one match is found.
     233         */
    231234        size_t max_match_len = size;
    232235        size_t max_match_len_tmp = size;
     
    238241       
    239242        output[0] = 0;
    240 
    241         while ((hint = symtab_search_one(name, &pos))) {
    242                 ++pos;
    243         }
    244 
     243       
     244        while ((hint = symtab_search_one(name, &pos)))
     245                pos++;
     246       
    245247        pos = 0;
    246248       
     
    253255        }
    254256       
    255         /* If possible completions are more than MAX_TAB_HINTS, ask user whether to display them or not. */
     257        /*
     258         * If the number of possible completions is more than MAX_TAB_HINTS,
     259         * ask the user whether to display them or not.
     260         */
    256261        if (found > MAX_TAB_HINTS) {
    257262                printf("\n");
    258                 continue_showing_hints = console_prompt_display_all_hints(indev, found);
     263                continue_showing_hints =
     264                    console_prompt_display_all_hints(indev, found);
    259265        }
    260266       
     
    265271                        sym_name = symbol_table[pos].symbol_name;
    266272                        pos++;
    267 
    268                         if (continue_showing_hints) { /* We are still showing hints */
     273                       
     274                        if (continue_showing_hints) {
     275                                /* We are still showing hints */
    269276                                printf("%s\n", sym_name);
    270277                                --hints_to_show;
    271278                                ++total_hints_shown;
    272 
    273                                 if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
    274                                         continue_showing_hints = console_prompt_more_hints(indev, &hints_to_show);
     279                               
     280                                if ((hints_to_show == 0) && (total_hints_shown != found)) {
     281                                        /* Ask the user to continue */
     282                                        continue_showing_hints =
     283                                            console_prompt_more_hints(indev, &hints_to_show);
    275284                                }
    276285                        }
    277 
    278                         for(max_match_len_tmp = 0; output[max_match_len_tmp] == sym_name[input_len + max_match_len_tmp]
    279                                         && max_match_len_tmp < max_match_len; ++max_match_len_tmp);
     286                       
     287                        for (max_match_len_tmp = 0;
     288                            (output[max_match_len_tmp] ==
     289                            sym_name[input_len + max_match_len_tmp]) &&
     290                            (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
     291                       
    280292                        max_match_len = max_match_len_tmp;
    281293                }
    282                 /* keep only the characters common in all completions */
     294               
     295                /* Keep only the characters common in all completions */
    283296                output[max_match_len] = 0;
    284297        }
  • kernel/generic/src/interrupt/interrupt.c

    re0d5bc5 r96e01fbc  
    5050#include <panic.h>
    5151#include <print.h>
     52#include <stdarg.h>
    5253#include <symtab.h>
    5354#include <proc/thread.h>
     
    165166}
    166167
    167 /** Terminate thread and task if exception came from userspace.
    168  *
    169  */
    170 NO_TRACE void fault_if_from_uspace(istate_t *istate, const char *fmt, ...)
    171 {
    172         if (!istate_from_uspace(istate))
    173                 return;
    174        
     168static NO_TRACE void fault_from_uspace_core(istate_t *istate, const char *fmt, va_list args)
     169{
    175170        printf("Task %s (%" PRIu64 ") killed due to an exception at "
    176171            "program counter %p.\n", TASK->name, TASK->taskid,
     
    181176       
    182177        printf("Kill message: ");
     178        vprintf(fmt, args);
     179        printf("\n");
     180       
     181        task_kill_self(true);
     182}
     183
     184/** Terminate thread and task after the exception came from userspace.
     185 *
     186 */
     187NO_TRACE void fault_from_uspace(istate_t *istate, const char *fmt, ...)
     188{
     189        va_list args;
     190
     191        va_start(args, fmt);
     192        fault_from_uspace_core(istate, fmt, args);
     193        va_end(args);
     194}
     195
     196/** Terminate thread and task if exception came from userspace.
     197 *
     198 */
     199NO_TRACE void fault_if_from_uspace(istate_t *istate, const char *fmt, ...)
     200{
     201        if (!istate_from_uspace(istate))
     202                return;
    183203       
    184204        va_list args;
    185205        va_start(args, fmt);
    186         vprintf(fmt, args);
     206        fault_from_uspace_core(istate, fmt, args);
    187207        va_end(args);
    188         printf("\n");
    189        
    190         task_kill_self(true);
    191208}
    192209
  • kernel/generic/src/ipc/ipc.c

    re0d5bc5 r96e01fbc  
    7171{
    7272        memsetb(call, sizeof(*call), 0);
    73         call->callerbox = &TASK->answerbox;
    7473        call->sender = TASK;
    7574        call->buffer = NULL;
     
    120119        irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
    121120        waitq_initialize(&box->wq);
    122         link_initialize(&box->sync_box_link);
    123121        list_initialize(&box->connected_phones);
    124122        list_initialize(&box->calls);
     
    163161}
    164162
    165 /** Helper function to facilitate synchronous calls.
    166  *
    167  * @param phone   Destination kernel phone structure.
    168  * @param request Call structure with request.
    169  *
    170  * @return EOK on success or EINTR if the sleep was interrupted.
    171  *
    172  */
    173 int ipc_call_sync(phone_t *phone, call_t *request)
    174 {
    175         answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);
    176         ipc_answerbox_init(sync_box, TASK);
    177        
    178         /*
    179          * Put the answerbox on the TASK's list of synchronous answerboxes so
    180          * that it can be cleaned up if the call is interrupted.
    181          */
    182         irq_spinlock_lock(&TASK->lock, true);
    183         list_append(&sync_box->sync_box_link, &TASK->sync_boxes);
    184         irq_spinlock_unlock(&TASK->lock, true);
    185        
    186         /* We will receive data in a special box. */
    187         request->callerbox = sync_box;
    188        
    189         ipc_call(phone, request);
    190         if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
    191             SYNCH_FLAGS_INTERRUPTIBLE)) {
    192                 /* The answerbox and the call will be freed by ipc_cleanup(). */
    193                 return EINTR;
    194         }
    195        
    196         /*
    197          * The answer arrived without interruption so we can remove the
    198          * answerbox from the TASK's list of synchronous answerboxes.
    199          */
    200         irq_spinlock_lock(&TASK->lock, true);
    201         list_remove(&sync_box->sync_box_link);
    202         irq_spinlock_unlock(&TASK->lock, true);
    203        
    204         slab_free(ipc_answerbox_slab, sync_box);
    205         return EOK;
    206 }
    207 
    208163/** Answer a message which was not dispatched and is not listed in any queue.
    209164 *
     
    214169static void _ipc_answer_free_call(call_t *call, bool selflocked)
    215170{
    216         answerbox_t *callerbox = call->callerbox;
     171        answerbox_t *callerbox = &call->sender->answerbox;
    217172        bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
    218173       
     
    606561        ipc_cleanup_call_list(&TASK->answerbox.calls);
    607562        irq_spinlock_unlock(&TASK->answerbox.lock, true);
    608        
    609         /* Wait for all answers to interrupted synchronous calls to arrive */
    610         ipl_t ipl = interrupts_disable();
    611         while (!list_empty(&TASK->sync_boxes)) {
    612                 answerbox_t *box = list_get_instance(
    613                     list_first(&TASK->sync_boxes), answerbox_t, sync_box_link);
    614                
    615                 list_remove(&box->sync_box_link);
    616                 call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
    617                     SYNCH_FLAGS_NONE);
    618                 ipc_call_free(call);
    619                 slab_free(ipc_answerbox_slab, box);
    620         }
    621         interrupts_restore(ipl);
    622563       
    623564        /* Wait for all answers to asynchronous calls to arrive */
  • kernel/generic/src/ipc/irq.c

    re0d5bc5 r96e01fbc  
    3939 * when interrupt is detected. The application may provide a simple 'top-half'
    4040 * handler as part of its registration, which can perform simple operations
    41  * (read/write port/memory, add information to notification ipc message).
     41 * (read/write port/memory, add information to notification IPC message).
    4242 *
    4343 * The structure of a notification message is as follows:
    4444 * - IMETHOD: interface and method as registered by
    4545 *            the SYS_IRQ_REGISTER syscall
    46  * - ARG1: payload modified by a 'top-half' handler
    47  * - ARG2: payload modified by a 'top-half' handler
    48  * - ARG3: payload modified by a 'top-half' handler
    49  * - ARG4: payload modified by a 'top-half' handler
    50  * - ARG5: payload modified by a 'top-half' handler
     46 * - ARG1: payload modified by a 'top-half' handler (scratch[1])
     47 * - ARG2: payload modified by a 'top-half' handler (scratch[2])
     48 * - ARG3: payload modified by a 'top-half' handler (scratch[3])
     49 * - ARG4: payload modified by a 'top-half' handler (scratch[4])
     50 * - ARG5: payload modified by a 'top-half' handler (scratch[5])
    5151 * - in_phone_hash: interrupt counter (may be needed to assure correct order
    5252 *                  in multithreaded drivers)
     
    8787static void ranges_unmap(irq_pio_range_t *ranges, size_t rangecount)
    8888{
    89         size_t i;
    90 
    91         for (i = 0; i < rangecount; i++) {
     89        for (size_t i = 0; i < rangecount; i++) {
    9290#ifdef IO_SPACE_BOUNDARY
    9391                if ((void *) ranges[i].base >= IO_SPACE_BOUNDARY)
     
    10098    irq_cmd_t *cmds, size_t cmdcount)
    10199{
    102         uintptr_t *pbase;
    103         size_t i, j;
    104 
    105100        /* Copy the physical base addresses aside. */
    106         pbase = malloc(rangecount * sizeof(uintptr_t), 0);
    107         for (i = 0; i < rangecount; i++)
     101        uintptr_t *pbase = malloc(rangecount * sizeof(uintptr_t), 0);
     102        for (size_t i = 0; i < rangecount; i++)
    108103                pbase[i] = ranges[i].base;
    109 
     104       
    110105        /* Map the PIO ranges into the kernel virtual address space. */
    111         for (i = 0; i < rangecount; i++) {
     106        for (size_t i = 0; i < rangecount; i++) {
    112107#ifdef IO_SPACE_BOUNDARY
    113108                if ((void *) ranges[i].base < IO_SPACE_BOUNDARY)
     
    122117                }
    123118        }
    124 
     119       
    125120        /* Rewrite the pseudocode addresses from physical to kernel virtual. */
    126         for (i = 0; i < cmdcount; i++) {
     121        for (size_t i = 0; i < cmdcount; i++) {
    127122                uintptr_t addr;
    128123                size_t size;
    129 
     124               
    130125                /* Process only commands that use an address. */
    131126                switch (cmds[i].cmd) {
    132127                case CMD_PIO_READ_8:
    133                 case CMD_PIO_WRITE_8:
    134                 case CMD_PIO_WRITE_A_8:
     128                case CMD_PIO_WRITE_8:
     129                case CMD_PIO_WRITE_A_8:
    135130                        size = 1;
    136131                        break;
    137                 case CMD_PIO_READ_16:
    138                 case CMD_PIO_WRITE_16:
    139                 case CMD_PIO_WRITE_A_16:
     132                case CMD_PIO_READ_16:
     133                case CMD_PIO_WRITE_16:
     134                case CMD_PIO_WRITE_A_16:
    140135                        size = 2;
    141136                        break;
    142                 case CMD_PIO_READ_32:
    143                 case CMD_PIO_WRITE_32:
    144                 case CMD_PIO_WRITE_A_32:
     137                case CMD_PIO_READ_32:
     138                case CMD_PIO_WRITE_32:
     139                case CMD_PIO_WRITE_A_32:
    145140                        size = 4;
    146141                        break;
     
    149144                        continue;
    150145                }
    151 
     146               
    152147                addr = (uintptr_t) cmds[i].addr;
    153148               
     149                size_t j;
    154150                for (j = 0; j < rangecount; j++) {
    155 
    156151                        /* Find the matching range. */
    157152                        if (!iswithin(pbase[j], ranges[j].size, addr, size))
    158153                                continue;
    159 
     154                       
    160155                        /* Switch the command to a kernel virtual address. */
    161156                        addr -= pbase[j];
    162157                        addr += ranges[j].base;
    163 
     158                       
    164159                        cmds[i].addr = (void *) addr;
    165160                        break;
    166161                }
    167 
     162               
    168163                if (j == rangecount) {
    169164                        /*
     
    176171                }
    177172        }
    178 
     173       
    179174        free(pbase);
     175        return EOK;
     176}
     177
     178/** Statically check the top-half pseudocode
     179 *
     180 * Check the top-half pseudocode for invalid or unsafe
     181 * constructs.
     182 *
     183 */
     184static int code_check(irq_cmd_t *cmds, size_t cmdcount)
     185{
     186        for (size_t i = 0; i < cmdcount; i++) {
     187                /*
     188                 * Check for accepted ranges.
     189                 */
     190                if (cmds[i].cmd >= CMD_LAST)
     191                        return EINVAL;
     192               
     193                if (cmds[i].srcarg >= IPC_CALL_LEN)
     194                        return EINVAL;
     195               
     196                if (cmds[i].dstarg >= IPC_CALL_LEN)
     197                        return EINVAL;
     198               
     199                switch (cmds[i].cmd) {
     200                case CMD_PREDICATE:
     201                        /*
     202                         * Check for control flow overflow.
     203                         * Note that jumping just beyond the last
     204                         * command is a correct behaviour.
     205                         */
     206                        if (i + cmds[i].value > cmdcount)
     207                                return EINVAL;
     208                       
     209                        break;
     210                default:
     211                        break;
     212                }
     213        }
     214       
    180215        return EOK;
    181216}
     
    207242        irq_pio_range_t *ranges = NULL;
    208243        irq_cmd_t *cmds = NULL;
    209 
     244       
    210245        irq_code_t *code = malloc(sizeof(*code), 0);
    211246        int rc = copy_from_uspace(code, ucode, sizeof(*code));
     
    222257        if (rc != EOK)
    223258                goto error;
    224 
     259       
    225260        cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0);
    226261        rc = copy_from_uspace(cmds, code->cmds,
     
    228263        if (rc != EOK)
    229264                goto error;
    230 
     265       
     266        rc = code_check(cmds, code->cmdcount);
     267        if (rc != EOK)
     268                goto error;
     269       
    231270        rc = ranges_map_and_apply(ranges, code->rangecount, cmds,
    232271            code->cmdcount);
    233272        if (rc != EOK)
    234273                goto error;
    235 
     274       
    236275        code->ranges = ranges;
    237276        code->cmds = cmds;
    238 
     277       
    239278        return code;
    240 
     279       
    241280error:
    242281        if (cmds)
    243282                free(cmds);
     283       
    244284        if (ranges)
    245285                free(ranges);
     286       
    246287        free(code);
    247288        return NULL;
     
    250291/** Register an answerbox as a receiving end for IRQ notifications.
    251292 *
    252  * @param box           Receiving answerbox.
    253  * @param inr           IRQ number.
    254  * @param devno         Device number.
    255  * @param imethod       Interface and method to be associated with the
    256  *                      notification.
    257  * @param ucode         Uspace pointer to top-half pseudocode.
    258  * @return              EOK on success or a negative error code.
     293 * @param box     Receiving answerbox.
     294 * @param inr     IRQ number.
     295 * @param devno   Device number.
     296 * @param imethod Interface and method to be associated with the
     297 *                notification.
     298 * @param ucode   Uspace pointer to top-half pseudocode.
     299 *
     300 * @return EOK on success or a negative error code.
    259301 *
    260302 */
     
    266308                (sysarg_t) devno
    267309        };
    268 
     310       
    269311        if ((inr < 0) || (inr > last_inr))
    270312                return ELIMIT;
     
    329371/** Unregister task from IRQ notification.
    330372 *
    331  * @param box           Answerbox associated with the notification.
    332  * @param inr           IRQ number.
    333  * @param devno         Device number.
    334  * @return              EOK on success or a negative error code.
     373 * @param box   Answerbox associated with the notification.
     374 * @param inr   IRQ number.
     375 * @param devno Device number.
     376 *
     377 * @return EOK on success or a negative error code.
     378 *
    335379 */
    336380int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
     
    340384                (sysarg_t) devno
    341385        };
    342 
     386       
    343387        if ((inr < 0) || (inr > last_inr))
    344388                return ELIMIT;
     
    436480                /* Remove from the hash table. */
    437481                hash_table_remove(&irq_uspace_hash_table, key, 2);
    438 
     482               
    439483                /*
    440484                 * Release both locks so that we can free the pseudo code.
     
    442486                irq_spinlock_unlock(&box->irq_lock, false);
    443487                irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    444 
     488               
    445489                code_free(irq->notif_cfg.code);
    446490                free(irq);
     
    492536       
    493537        for (size_t i = 0; i < code->cmdcount; i++) {
    494                 uint32_t dstval;
    495                
    496538                uintptr_t srcarg = code->cmds[i].srcarg;
    497539                uintptr_t dstarg = code->cmds[i].dstarg;
    498540               
    499                 if (srcarg >= IPC_CALL_LEN)
    500                         break;
    501                
    502                 if (dstarg >= IPC_CALL_LEN)
    503                         break;
    504        
    505541                switch (code->cmds[i].cmd) {
    506542                case CMD_PIO_READ_8:
    507                         dstval = pio_read_8((ioport8_t *) code->cmds[i].addr);
    508                         if (dstarg)
    509                                 scratch[dstarg] = dstval;
     543                        scratch[dstarg] =
     544                            pio_read_8((ioport8_t *) code->cmds[i].addr);
    510545                        break;
    511546                case CMD_PIO_READ_16:
    512                         dstval = pio_read_16((ioport16_t *) code->cmds[i].addr);
    513                         if (dstarg)
    514                                 scratch[dstarg] = dstval;
     547                        scratch[dstarg] =
     548                            pio_read_16((ioport16_t *) code->cmds[i].addr);
    515549                        break;
    516550                case CMD_PIO_READ_32:
    517                         dstval = pio_read_32((ioport32_t *) code->cmds[i].addr);
    518                         if (dstarg)
    519                                 scratch[dstarg] = dstval;
     551                        scratch[dstarg] =
     552                            pio_read_32((ioport32_t *) code->cmds[i].addr);
    520553                        break;
    521554                case CMD_PIO_WRITE_8:
     
    532565                        break;
    533566                case CMD_PIO_WRITE_A_8:
    534                         if (srcarg) {
    535                                 pio_write_8((ioport8_t *) code->cmds[i].addr,
    536                                     (uint8_t) scratch[srcarg]);
    537                         }
     567                        pio_write_8((ioport8_t *) code->cmds[i].addr,
     568                            (uint8_t) scratch[srcarg]);
    538569                        break;
    539570                case CMD_PIO_WRITE_A_16:
    540                         if (srcarg) {
    541                                 pio_write_16((ioport16_t *) code->cmds[i].addr,
    542                                     (uint16_t) scratch[srcarg]);
    543                         }
     571                        pio_write_16((ioport16_t *) code->cmds[i].addr,
     572                            (uint16_t) scratch[srcarg]);
    544573                        break;
    545574                case CMD_PIO_WRITE_A_32:
    546                         if (srcarg) {
    547                                 pio_write_32((ioport32_t *) code->cmds[i].addr,
    548                                     (uint32_t) scratch[srcarg]);
    549                         }
    550                         break;
    551                 case CMD_BTEST:
    552                         if ((srcarg) && (dstarg)) {
    553                                 dstval = scratch[srcarg] & code->cmds[i].value;
    554                                 scratch[dstarg] = dstval;
    555                         }
     575                        pio_write_32((ioport32_t *) code->cmds[i].addr,
     576                            (uint32_t) scratch[srcarg]);
     577                        break;
     578                case CMD_LOAD:
     579                        scratch[dstarg] = code->cmds[i].value;
     580                        break;
     581                case CMD_AND:
     582                        scratch[dstarg] = scratch[srcarg] &
     583                            code->cmds[i].value;
    556584                        break;
    557585                case CMD_PREDICATE:
    558                         if ((srcarg) && (!scratch[srcarg])) {
     586                        if (scratch[srcarg] == 0)
    559587                                i += code->cmds[i].value;
    560                                 continue;
    561                         }
     588                       
    562589                        break;
    563590                case CMD_ACCEPT:
     
    582609{
    583610        ASSERT(irq);
    584 
     611       
    585612        ASSERT(interrupts_disabled());
    586613        ASSERT(irq_spinlock_locked(&irq->lock));
  • kernel/generic/src/ipc/sysipc.c

    re0d5bc5 r96e01fbc  
    612612                break;
    613613        }
    614        
    615         return 0;
    616 }
    617 
    618 /** Make a fast call over IPC, wait for reply and return to user.
    619  *
    620  * This function can handle only three arguments of payload, but is faster than
    621  * the generic function (i.e. sys_ipc_call_sync_slow()).
    622  *
    623  * @param phoneid Phone handle for the call.
    624  * @param imethod Interface and method of the call.
    625  * @param arg1    Service-defined payload argument.
    626  * @param arg2    Service-defined payload argument.
    627  * @param arg3    Service-defined payload argument.
    628  * @param data    Address of user-space structure where the reply call will
    629  *                be stored.
    630  *
    631  * @return 0 on success.
    632  * @return ENOENT if there is no such phone handle.
    633  *
    634  */
    635 sysarg_t sys_ipc_call_sync_fast(sysarg_t phoneid, sysarg_t imethod,
    636     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_data_t *data)
    637 {
    638         phone_t *phone;
    639         if (phone_get(phoneid, &phone) != EOK)
    640                 return ENOENT;
    641        
    642         call_t *call = ipc_call_alloc(0);
    643         IPC_SET_IMETHOD(call->data, imethod);
    644         IPC_SET_ARG1(call->data, arg1);
    645         IPC_SET_ARG2(call->data, arg2);
    646         IPC_SET_ARG3(call->data, arg3);
    647        
    648         /*
    649          * To achieve deterministic behavior, zero out arguments that are beyond
    650          * the limits of the fast version.
    651          */
    652         IPC_SET_ARG4(call->data, 0);
    653         IPC_SET_ARG5(call->data, 0);
    654        
    655         int res = request_preprocess(call, phone);
    656         int rc;
    657        
    658         if (!res) {
    659 #ifdef CONFIG_UDEBUG
    660                 udebug_stoppable_begin();
    661 #endif
    662                 rc = ipc_call_sync(phone, call);
    663 #ifdef CONFIG_UDEBUG
    664                 udebug_stoppable_end();
    665 #endif
    666                
    667                 if (rc != EOK) {
    668                         /* The call will be freed by ipc_cleanup(). */
    669                         return rc;
    670                 }
    671                
    672                 process_answer(call);
    673         } else
    674                 IPC_SET_RETVAL(call->data, res);
    675        
    676         rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
    677         ipc_call_free(call);
    678         if (rc != 0)
    679                 return rc;
    680        
    681         return 0;
    682 }
    683 
    684 /** Make a synchronous IPC call allowing to transmit the entire payload.
    685  *
    686  * @param phoneid Phone handle for the call.
    687  * @param request User-space address of call data with the request.
    688  * @param reply   User-space address of call data where to store the
    689  *                answer.
    690  *
    691  * @return Zero on success or an error code.
    692  *
    693  */
    694 sysarg_t sys_ipc_call_sync_slow(sysarg_t phoneid, ipc_data_t *request,
    695     ipc_data_t *reply)
    696 {
    697         phone_t *phone;
    698         if (phone_get(phoneid, &phone) != EOK)
    699                 return ENOENT;
    700        
    701         call_t *call = ipc_call_alloc(0);
    702         int rc = copy_from_uspace(&call->data.args, &request->args,
    703             sizeof(call->data.args));
    704         if (rc != 0) {
    705                 ipc_call_free(call);
    706                 return (sysarg_t) rc;
    707         }
    708        
    709         int res = request_preprocess(call, phone);
    710        
    711         if (!res) {
    712 #ifdef CONFIG_UDEBUG
    713                 udebug_stoppable_begin();
    714 #endif
    715                 rc = ipc_call_sync(phone, call);
    716 #ifdef CONFIG_UDEBUG
    717                 udebug_stoppable_end();
    718 #endif
    719                
    720                 if (rc != EOK) {
    721                         /* The call will be freed by ipc_cleanup(). */
    722                         return rc;
    723                 }
    724                
    725                 process_answer(call);
    726         } else
    727                 IPC_SET_RETVAL(call->data, res);
    728        
    729         rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
    730         ipc_call_free(call);
    731         if (rc != 0)
    732                 return rc;
    733614       
    734615        return 0;
  • kernel/generic/src/lib/str.c

    re0d5bc5 r96e01fbc  
    456456 *
    457457 * Do a char-by-char comparison of two NULL-terminated strings.
    458  * The strings are considered equal iff they consist of the same
    459  * characters on the minimum of their lengths.
     458 * The strings are considered equal iff their length is equal
     459 * and both strings consist of the same sequence of characters.
     460 *
     461 * A string S1 is less than another string S2 if it has a character with
     462 * lower value at the first character position where the strings differ.
     463 * If the strings differ in length, the shorter one is treated as if
     464 * padded by characters with a value of zero.
    460465 *
    461466 * @param s1 First string to compare.
    462467 * @param s2 Second string to compare.
    463468 *
    464  * @return 0 if the strings are equal, -1 if first is smaller,
    465  *         1 if second smaller.
     469 * @return 0 if the strings are equal, -1 if the first is less than the second,
     470 *         1 if the second is less than the first.
    466471 *
    467472 */
     
    494499 *
    495500 * Do a char-by-char comparison of two NULL-terminated strings.
    496  * The strings are considered equal iff they consist of the same
    497  * characters on the minimum of their lengths and the length limit.
     501 * The strings are considered equal iff
     502 * min(str_length(s1), max_len) == min(str_length(s2), max_len)
     503 * and both strings consist of the same sequence of characters,
     504 * up to max_len characters.
     505 *
     506 * A string S1 is less than another string S2 if it has a character with
     507 * lower value at the first character position where the strings differ.
     508 * If the strings differ in length, the shorter one is treated as if
     509 * padded by characters with a value of zero. Only the first max_len
     510 * characters are considered.
    498511 *
    499512 * @param s1      First string to compare.
     
    501514 * @param max_len Maximum number of characters to consider.
    502515 *
    503  * @return 0 if the strings are equal, -1 if first is smaller,
    504  *         1 if second smaller.
     516 * @return 0 if the strings are equal, -1 if the first is less than the second,
     517 *         1 if the second is less than the first.
    505518 *
    506519 */
  • kernel/generic/src/proc/task.c

    re0d5bc5 r96e01fbc  
    156156       
    157157        list_initialize(&task->threads);
    158         list_initialize(&task->sync_boxes);
    159158       
    160159        ipc_answerbox_init(&task->answerbox, task);
  • kernel/generic/src/syscall/syscall.c

    re0d5bc5 r96e01fbc  
    151151       
    152152        /* IPC related syscalls. */
    153         (syshandler_t) sys_ipc_call_sync_fast,
    154         (syshandler_t) sys_ipc_call_sync_slow,
    155153        (syshandler_t) sys_ipc_call_async_fast,
    156154        (syshandler_t) sys_ipc_call_async_slow,
Note: See TracChangeset for help on using the changeset viewer.