Changeset ad7a6c9 in mainline for kernel/generic/src


Ignore:
Timestamp:
2011-03-30T13:10:24Z (15 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4ae90f9
Parents:
6e50466 (diff), d6b81941 (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/generic/src
Files:
25 edited
1 moved

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/adt/avl.c

    r6e50466 rad7a6c9  
    723723void avltree_walk(avltree_t *t, avltree_walker_t walker, void *arg)
    724724{
    725         _avltree_walk(t->root, walker, arg);
     725        if (t->root)
     726                _avltree_walk(t->root, walker, arg);
    726727}
    727728
  • kernel/generic/src/console/cmd.c

    r6e50466 rad7a6c9  
    7878static cmd_info_t help_info = {
    7979        .name = "help",
    80         .description = "List of supported commands.",
     80        .description = "List supported commands.",
    8181        .func = cmd_help,
    8282        .argc = 0
    8383};
    8484
     85/* Data and methods for 'reboot' command. */
    8586static int cmd_reboot(cmd_arg_t *argv);
    8687static cmd_info_t reboot_info = {
    8788        .name = "reboot",
    88         .description = "Reboot.",
     89        .description = "Reboot system.",
    8990        .func = cmd_reboot,
    9091        .argc = 0
    9192};
    9293
     94/* Data and methods for 'uptime' command. */
    9395static int cmd_uptime(cmd_arg_t *argv);
    9496static cmd_info_t uptime_info = {
    9597        .name = "uptime",
    96         .description = "Print uptime information.",
     98        .description = "Show system uptime.",
    9799        .func = cmd_uptime,
    98100        .argc = 0
    99101};
    100102
     103/* Data and methods for 'continue' command. */
    101104static int cmd_continue(cmd_arg_t *argv);
    102105static cmd_info_t continue_info = {
     
    108111
    109112#ifdef CONFIG_TEST
     113
     114/* Data and methods for 'test' command. */
    110115static char test_buf[MAX_CMDLINE + 1];
    111116static int cmd_test(cmd_arg_t *argv);
     
    119124static cmd_info_t test_info = {
    120125        .name = "test",
    121         .description = "Print list of kernel tests or run a test.",
     126        .description = "<test> List kernel tests or run a test.",
    122127        .func = cmd_test,
    123128        .argc = 1,
     
    125130};
    126131
     132/* Data and methods for 'bench' command. */
    127133static int cmd_bench(cmd_arg_t *argv);
    128134static cmd_arg_t bench_argv[] = {
     
    138144static cmd_info_t bench_info = {
    139145        .name = "bench",
    140         .description = "Run kernel test as benchmark.",
     146        .description = "<test> <count> Run kernel test as benchmark.",
    141147        .func = cmd_bench,
    142148        .argc = 2,
    143149        .argv = bench_argv
    144150};
    145 #endif
     151
     152#endif /* CONFIG_TEST */
    146153
    147154/* Data and methods for 'description' command. */
    148155static int cmd_desc(cmd_arg_t *argv);
    149156static void desc_help(void);
    150 static char desc_buf[MAX_CMDLINE+1];
     157static char desc_buf[MAX_CMDLINE + 1];
    151158static cmd_arg_t desc_argv = {
    152159        .type = ARG_TYPE_STRING,
     
    156163static cmd_info_t desc_info = {
    157164        .name = "describe",
    158         .description = "Describe specified command.",
     165        .description = "<command> Describe specified command.",
    159166        .help = desc_help,
    160167        .func = cmd_desc,
     
    165172/* Data and methods for 'symaddr' command. */
    166173static int cmd_symaddr(cmd_arg_t *argv);
    167 static char symaddr_buf[MAX_CMDLINE+1];
     174static char symaddr_buf[MAX_CMDLINE + 1];
    168175static cmd_arg_t symaddr_argv = {
    169176        .type = ARG_TYPE_STRING,
     
    173180static cmd_info_t symaddr_info = {
    174181        .name = "symaddr",
    175         .description = "Return symbol address.",
     182        .description = "<symbol> Return symbol address.",
    176183        .func = cmd_symaddr,
    177184        .argc = 1,
     
    179186};
    180187
    181 static char set_buf[MAX_CMDLINE+1];
     188/* Data and methods for 'set4' command. */
     189static char set_buf[MAX_CMDLINE + 1];
    182190static int cmd_set4(cmd_arg_t *argv);
    183191static cmd_arg_t set4_argv[] = {
     
    193201static cmd_info_t set4_info = {
    194202        .name = "set4",
    195         .description = "set <dest_addr> <value> - 4byte version",
     203        .description = "<addr> <value> Set 4B memory location to a value.",
    196204        .func = cmd_set4,
    197205        .argc = 2,
     
    213221static cmd_info_t call0_info = {
    214222        .name = "call0",
    215         .description = "call0 <function> -> call function().",
     223        .description = "<function> Call function().",
    216224        .func = cmd_call0,
    217225        .argc = 1,
     
    228236static cmd_info_t mcall0_info = {
    229237        .name = "mcall0",
    230         .description = "mcall0 <function> -> call function() on each CPU.",
     238        .description = "<function> Call function() on each CPU.",
    231239        .func = cmd_mcall0,
    232240        .argc = 1,
     
    250258static cmd_info_t call1_info = {
    251259        .name = "call1",
    252         .description = "call1 <function> <arg1> -> call function(arg1).",
     260        .description = "<function> <arg1> Call function(arg1).",
    253261        .func = cmd_call1,
    254262        .argc = 2,
     
    277285static cmd_info_t call2_info = {
    278286        .name = "call2",
    279         .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
     287        .description = "<function> <arg1> <arg2> Call function(arg1, arg2).",
    280288        .func = cmd_call2,
    281289        .argc = 3,
     
    310318static cmd_info_t call3_info = {
    311319        .name = "call3",
    312         .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
     320        .description = "<function> <arg1> <arg2> <arg3> Call function(arg1, arg2, arg3).",
    313321        .func = cmd_call3,
    314322        .argc = 4,
     
    340348cmd_info_t tlb_info = {
    341349        .name = "tlb",
    342         .description = "Print TLB of current processor.",
     350        .description = "Print TLB of the current CPU.",
    343351        .help = NULL,
    344352        .func = cmd_tlb,
     
    377385};
    378386
     387#ifdef CONFIG_UDEBUG
     388
     389/* Data and methods for 'btrace' command */
     390static int cmd_btrace(cmd_arg_t *argv);
     391static cmd_arg_t btrace_argv = {
     392        .type = ARG_TYPE_INT,
     393};
     394static cmd_info_t btrace_info = {
     395        .name = "btrace",
     396        .description = "<threadid> Show thread stack trace.",
     397        .func = cmd_btrace,
     398        .argc = 1,
     399        .argv = &btrace_argv
     400};
     401
     402#endif /* CONFIG_UDEBUG */
    379403
    380404static int cmd_sched(cmd_arg_t *argv);
    381405static cmd_info_t sched_info = {
    382406        .name = "scheduler",
    383         .description = "List all scheduler information.",
     407        .description = "Show scheduler information.",
    384408        .func = cmd_sched,
    385409        .argc = 0
     
    406430static cmd_info_t zones_info = {
    407431        .name = "zones",
    408         .description = "List of memory zones.",
     432        .description = "List memory zones.",
    409433        .func = cmd_zones,
    410434        .argc = 0
     435};
     436
     437/* Data and methods for 'zone' command */
     438static int cmd_zone(cmd_arg_t *argv);
     439static cmd_arg_t zone_argv = {
     440        .type = ARG_TYPE_INT,
     441};
     442
     443static cmd_info_t zone_info = {
     444        .name = "zone",
     445        .description = "<zone> Show memory zone structure.",
     446        .func = cmd_zone,
     447        .argc = 1,
     448        .argv = &zone_argv
    411449};
    412450
     
    418456static cmd_info_t ipc_info = {
    419457        .name = "ipc",
    420         .description = "ipc <taskid> Show IPC information of given task.",
     458        .description = "<taskid> Show IPC information of a task.",
    421459        .func = cmd_ipc,
    422460        .argc = 1,
     
    431469static cmd_info_t kill_info = {
    432470        .name = "kill",
    433         .description = "kill <taskid> Kill a task.",
     471        .description = "<taskid> Kill a task.",
    434472        .func = cmd_kill,
    435473        .argc = 1,
    436474        .argv = &kill_argv
    437 };
    438 
    439 /* Data and methods for 'zone' command */
    440 static int cmd_zone(cmd_arg_t *argv);
    441 static cmd_arg_t zone_argv = {
    442         .type = ARG_TYPE_INT,
    443 };
    444 
    445 static cmd_info_t zone_info = {
    446         .name = "zone",
    447         .description = "Show memory zone structure.",
    448         .func = cmd_zone,
    449         .argc = 1,
    450         .argv = &zone_argv
    451475};
    452476
     
    482506        &cpus_info,
    483507        &desc_info,
    484         &reboot_info,
    485         &uptime_info,
    486508        &halt_info,
    487509        &help_info,
    488510        &ipc_info,
    489511        &kill_info,
     512        &physmem_info,
     513        &reboot_info,
     514        &sched_info,
    490515        &set4_info,
    491516        &slabs_info,
     517        &symaddr_info,
    492518        &sysinfo_info,
    493         &symaddr_info,
    494         &sched_info,
     519        &tasks_info,
    495520        &threads_info,
    496         &tasks_info,
    497         &physmem_info,
    498521        &tlb_info,
     522        &uptime_info,
    499523        &version_info,
    500524        &zones_info,
     
    504528        &bench_info,
    505529#endif
     530#ifdef CONFIG_UDEBUG
     531        &btrace_info,
     532#endif
    506533        NULL
    507534};
     
    526553        for (i = 0; basic_commands[i]; i++) {
    527554                cmd_initialize(basic_commands[i]);
    528                 if (!cmd_register(basic_commands[i]))
    529                         printf("Cannot register command %s\n", basic_commands[i]->name);
    530         }
    531 }
    532 
     555        }
     556
     557        for (i = 0; basic_commands[i]; i++) {
     558                if (!cmd_register(basic_commands[i])) {
     559                        printf("Cannot register command %s\n",
     560                            basic_commands[i]->name);
     561                }
     562        }
     563}
    533564
    534565/** List supported commands.
     
    574605}
    575606
    576 
    577607/** Reboot the system.
    578608 *
     
    588618        return 1;
    589619}
    590 
    591620
    592621/** Print system uptime information.
     
    824853}
    825854
    826 
    827855/** Print detailed description of 'describe' command. */
    828856void desc_help(void)
     
    911939 * @return Always 1
    912940 */
    913 int cmd_slabs(cmd_arg_t * argv)
     941int cmd_slabs(cmd_arg_t *argv)
    914942{
    915943        slab_print_list();
     
    923951 * @return Always 1
    924952 */
    925 int cmd_sysinfo(cmd_arg_t * argv)
     953int cmd_sysinfo(cmd_arg_t *argv)
    926954{
    927955        sysinfo_dump(NULL);
     
    929957}
    930958
    931 
    932 /** Command for listings Thread information
     959/** Command for listing thread information
    933960 *
    934961 * @param argv Ignored
     
    948975}
    949976
    950 /** Command for listings Task information
     977/** Command for listing task information
    951978 *
    952979 * @param argv Ignored
     
    966993}
    967994
    968 /** Command for listings Thread information
     995#ifdef CONFIG_UDEBUG
     996
     997/** Command for printing thread stack trace
     998 *
     999 * @param argv Integer argument from cmdline expected
     1000 *
     1001 * return Always 1
     1002 *
     1003 */
     1004int cmd_btrace(cmd_arg_t *argv)
     1005{
     1006        thread_stack_trace(argv[0].intval);
     1007        return 1;
     1008}
     1009
     1010#endif /* CONFIG_UDEBUG */
     1011
     1012/** Command for printing scheduler information
    9691013 *
    9701014 * @param argv Ignores
     
    9721016 * @return Always 1
    9731017 */
    974 int cmd_sched(cmd_arg_t * argv)
     1018int cmd_sched(cmd_arg_t *argv)
    9751019{
    9761020        sched_print_list();
     
    9841028 * return Always 1
    9851029 */
    986 int cmd_zones(cmd_arg_t * argv)
     1030int cmd_zones(cmd_arg_t *argv)
    9871031{
    9881032        zones_print_list();
     
    9961040 * return Always 1
    9971041 */
    998 int cmd_zone(cmd_arg_t * argv)
     1042int cmd_zone(cmd_arg_t *argv)
    9991043{
    10001044        zone_print_one(argv[0].intval);
     
    10021046}
    10031047
    1004 /** Command for printing task ipc details
     1048/** Command for printing task IPC details
    10051049 *
    10061050 * @param argv Integer argument from cmdline expected
     
    10081052 * return Always 1
    10091053 */
    1010 int cmd_ipc(cmd_arg_t * argv)
     1054int cmd_ipc(cmd_arg_t *argv)
    10111055{
    10121056        ipc_print_task(argv[0].intval);
     
    10201064 * return 0 on failure, 1 on success.
    10211065 */
    1022 int cmd_kill(cmd_arg_t * argv)
     1066int cmd_kill(cmd_arg_t *argv)
    10231067{
    10241068        if (task_kill(argv[0].intval) != EOK)
  • kernel/generic/src/console/console.c

    r6e50466 rad7a6c9  
    160160        klog_parea.pbase = (uintptr_t) faddr;
    161161        klog_parea.frames = SIZE2FRAMES(sizeof(klog));
     162        klog_parea.unpriv = false;
    162163        ddi_parea_register(&klog_parea);
    163164       
  • kernel/generic/src/ddi/ddi.c

    r6e50466 rad7a6c9  
    104104{
    105105        ASSERT(TASK);
    106         ASSERT((pf % FRAME_SIZE) == 0);
    107         ASSERT((vp % PAGE_SIZE) == 0);
    108        
    109         /*
    110          * Make sure the caller is authorised to make this syscall.
    111          */
    112         cap_t caps = cap_get(TASK);
    113         if (!(caps & CAP_MEM_MANAGER))
    114                 return EPERM;
     106       
     107        if ((pf % FRAME_SIZE) != 0)
     108                return EBADMEM;
     109       
     110        if ((vp % PAGE_SIZE) != 0)
     111                return EBADMEM;
     112       
     113        /*
     114         * Unprivileged tasks are only allowed to map pareas
     115         * which are explicitly marked as such.
     116         */
     117        bool priv =
     118            ((cap_get(TASK) & CAP_MEM_MANAGER) == CAP_MEM_MANAGER);
    115119       
    116120        mem_backend_data_t backend_data;
     
    123127       
    124128        if (znum == (size_t) -1) {
    125                 /* Frames not found in any zones
    126                  * -> assume it is hardware device and allow mapping
     129                /*
     130                 * Frames not found in any zone
     131                 * -> assume it is a hardware device and allow mapping
     132                 *    for privileged tasks.
    127133                 */
    128134                irq_spinlock_unlock(&zones.lock, true);
     135               
     136                if (!priv)
     137                        return EPERM;
     138               
    129139                goto map;
    130140        }
    131141       
    132142        if (zones.info[znum].flags & ZONE_FIRMWARE) {
    133                 /* Frames are part of firmware */
     143                /*
     144                 * Frames are part of firmware
     145                 * -> allow mapping for privileged tasks.
     146                 */
    134147                irq_spinlock_unlock(&zones.lock, true);
     148               
     149                if (!priv)
     150                        return EPERM;
     151               
    135152                goto map;
    136153        }
     
    138155        if (zone_flags_available(zones.info[znum].flags)) {
    139156                /*
    140                  * Frames are part of physical memory, check if the memory
    141                  * region is enabled for mapping.
     157                 * Frames are part of physical memory, check
     158                 * if the memory region is enabled for mapping.
    142159                 */
    143160                irq_spinlock_unlock(&zones.lock, true);
     
    150167                if ((!parea) || (parea->frames < pages)) {
    151168                        mutex_unlock(&parea_lock);
    152                         goto err;
     169                        return ENOENT;
     170                }
     171               
     172                if (!priv) {
     173                        if (!parea->unpriv) {
     174                                mutex_unlock(&parea_lock);
     175                                return EPERM;
     176                        }
    153177                }
    154178               
     
    158182       
    159183        irq_spinlock_unlock(&zones.lock, true);
    160        
    161 err:
    162184        return ENOENT;
    163185       
     
    258280}
    259281
    260 /** Disable or enable specified interrupts.
    261  *
    262  * @param irq the interrupt to be enabled/disabled.
    263  * @param enable if true enable the interrupt, disable otherwise.
    264  *
    265  * @retutn Zero on success, error code otherwise.
    266  */
    267 sysarg_t sys_interrupt_enable(int irq, int enable)
    268 {
    269 /* FIXME: this needs to be generic code, or better not be in kernel at all. */
    270 #if 0
    271         cap_t task_cap = cap_get(TASK);
    272         if (!(task_cap & CAP_IRQ_REG))
    273                 return EPERM;
    274                
    275         if (irq < 0 || irq > 16) {
    276                 return EINVAL;
    277         }
    278        
    279         uint16_t irq_mask = (uint16_t)(1 << irq);
    280         if (enable) {
    281                 trap_virtual_enable_irqs(irq_mask);
    282         } else {
    283                 trap_virtual_disable_irqs(irq_mask);
    284         }
    285        
    286 #endif
    287         return 0;
    288 }
    289 
    290282/** @}
    291283 */
  • kernel/generic/src/ddi/irq.c

    r6e50466 rad7a6c9  
    136136static size_t buckets;
    137137
     138/** Last valid INR. */
     139inr_t last_inr = 0;
     140
    138141/** Initialize IRQ subsystem.
    139142 *
     
    145148{
    146149        buckets = chains;
     150        last_inr = inrs - 1;
     151
    147152        /*
    148153         * Be smart about the choice of the hash table operations.
  • kernel/generic/src/interrupt/interrupt.c

    r6e50466 rad7a6c9  
    4545#include <console/console.h>
    4646#include <console/cmd.h>
    47 #include <ipc/event.h>
    4847#include <synch/mutex.h>
    4948#include <time/delay.h>
     
    188187        printf("\n");
    189188       
     189        task_kill_self(true);
     190}
     191
     192/** Get istate structure of a thread.
     193 *
     194 * Get pointer to the istate structure at the bottom of the kernel stack.
     195 *
     196 * This function can be called in interrupt or user context. In interrupt
     197 * context the istate structure is created by the low-level exception
     198 * handler. In user context the istate structure is created by the
     199 * low-level syscall handler.
     200 */
     201istate_t *istate_get(thread_t *thread)
     202{
    190203        /*
    191          * Userspace can subscribe for FAULT events to take action
    192          * whenever a thread faults. (E.g. take a dump, run a debugger).
    193          * The notification is always available, but unless Udebug is enabled,
    194          * that's all you get.
     204         * The istate structure should be right at the bottom of the kernel
     205         * stack.
    195206         */
    196         if (event_is_subscribed(EVENT_FAULT)) {
    197                 /* Notify the subscriber that a fault occurred. */
    198                 event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),
    199                     UPPER32(TASK->taskid), (sysarg_t) THREAD);
    200                
    201 #ifdef CONFIG_UDEBUG
    202                 /* Wait for a debugging session. */
    203                 udebug_thread_fault();
    204 #endif
    205         }
    206        
    207         task_kill(TASK->taskid);
    208         thread_exit();
     207        return (istate_t *) ((uint8_t *) thread->kstack + THREAD_STACK_SIZE -
     208            sizeof(istate_t));
    209209}
    210210
  • kernel/generic/src/ipc/ipc.c

    r6e50466 rad7a6c9  
    295295                atomic_inc(&phone->active_calls);
    296296                call->data.phone = phone;
     297                call->data.task = TASK;
    297298        }
    298299       
     
    406407                        call->caller_phone = call->data.phone;
    407408                call->data.phone = newphone;
     409                call->data.task = TASK;
    408410        }
    409411       
     
    688690        irq_spinlock_exchange(&tasks_lock, &task->lock);
    689691       
    690         /* Print opened phones & details */
    691         printf("PHONE:\n");
     692        printf("[phone id] [calls] [state\n");
    692693       
    693694        size_t i;
    694695        for (i = 0; i < IPC_MAX_PHONES; i++) {
    695696                if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) {
    696                         printf("%zu: mutex busy\n", i);
     697                        printf("%-10zu (mutex busy)\n", i);
    697698                        continue;
    698699                }
    699700               
    700701                if (task->phones[i].state != IPC_PHONE_FREE) {
    701                         printf("%zu: ", i);
     702                        printf("%-10zu %7" PRIun " ", i,
     703                            atomic_get(&task->phones[i].active_calls));
    702704                       
    703705                        switch (task->phones[i].state) {
    704706                        case IPC_PHONE_CONNECTING:
    705                                 printf("connecting ");
     707                                printf("connecting");
    706708                                break;
    707709                        case IPC_PHONE_CONNECTED:
    708                                 printf("connected to: %p ",
    709                                     task->phones[i].callee);
     710                                printf("connected to %" PRIu64 " (%s)",
     711                                    task->phones[i].callee->task->taskid,
     712                                    task->phones[i].callee->task->name);
    710713                                break;
    711714                        case IPC_PHONE_SLAMMED:
    712                                 printf("slammed by: %p ",
     715                                printf("slammed by %p",
    713716                                    task->phones[i].callee);
    714717                                break;
    715718                        case IPC_PHONE_HUNGUP:
    716                                 printf("hung up - was: %p ",
     719                                printf("hung up by %p",
    717720                                    task->phones[i].callee);
    718721                                break;
     
    721724                        }
    722725                       
    723                         printf("active: %" PRIun "\n",
    724                             atomic_get(&task->phones[i].active_calls));
     726                        printf("\n");
    725727                }
    726728               
     
    730732        irq_spinlock_lock(&task->answerbox.lock, false);
    731733       
     734#ifdef __32_BITS__
     735        printf("[call id ] [method] [arg1] [arg2] [arg3] [arg4] [arg5]"
     736            " [flags] [sender\n");
     737#endif
     738       
     739#ifdef __64_BITS__
     740        printf("[call id         ] [method] [arg1] [arg2] [arg3] [arg4]"
     741            " [arg5] [flags] [sender\n");
     742#endif
     743       
    732744        link_t *cur;
    733745       
    734         /* Print answerbox - calls */
    735         printf("ABOX - CALLS:\n");
     746        printf(" --- incomming calls ---\n");
    736747        for (cur = task->answerbox.calls.next; cur != &task->answerbox.calls;
    737748            cur = cur->next) {
    738749                call_t *call = list_get_instance(cur, call_t, link);
    739                 printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
    740                     " A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
    741                     " A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call,
    742                     call->sender->taskid,
     750               
     751#ifdef __32_BITS__
     752                printf("%10p ", call);
     753#endif
     754               
     755#ifdef __64_BITS__
     756                printf("%18p ", call);
     757#endif
     758               
     759                printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
     760                    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
    743761                    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
    744762                    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
    745763                    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
    746                     call->flags);
    747         }
    748        
    749         /* Print answerbox - dispatched calls */
    750         printf("ABOX - DISPATCHED CALLS:\n");
     764                    call->flags, call->sender->taskid, call->sender->name);
     765        }
     766       
     767        printf(" --- dispatched calls ---\n");
    751768        for (cur = task->answerbox.dispatched_calls.next;
    752769            cur != &task->answerbox.dispatched_calls;
    753770            cur = cur->next) {
    754771                call_t *call = list_get_instance(cur, call_t, link);
    755                 printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
    756                     " A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
    757                     " A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call,
    758                     call->sender->taskid,
     772               
     773#ifdef __32_BITS__
     774                printf("%10p ", call);
     775#endif
     776               
     777#ifdef __64_BITS__
     778                printf("%18p ", call);
     779#endif
     780               
     781                printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
     782                    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
    759783                    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
    760784                    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
    761785                    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
    762                     call->flags);
    763         }
    764        
    765         /* Print answerbox - answers */
    766         printf("ABOX - ANSWERS:\n");
     786                    call->flags, call->sender->taskid, call->sender->name);
     787        }
     788       
     789        printf(" --- incoming answers ---\n");
    767790        for (cur = task->answerbox.answers.next;
    768791            cur != &task->answerbox.answers;
    769792            cur = cur->next) {
    770793                call_t *call = list_get_instance(cur, call_t, link);
    771                 printf("Callid:%p M:%" PRIun " A1:%" PRIun " A2:%" PRIun
    772                     " A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n",
    773                     call, IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
     794               
     795#ifdef __32_BITS__
     796                printf("%10p ", call);
     797#endif
     798               
     799#ifdef __64_BITS__
     800                printf("%18p ", call);
     801#endif
     802               
     803                printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
     804                    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
     805                    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
    774806                    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
    775807                    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
    776                     call->flags);
     808                    call->flags, call->sender->taskid, call->sender->name);
    777809        }
    778810       
  • kernel/generic/src/ipc/irq.c

    r6e50466 rad7a6c9  
    4242 *
    4343 * The structure of a notification message is as follows:
    44  * - IMETHOD: interface and method as registered by the SYS_IPC_REGISTER_IRQ
     44 * - IMETHOD: interface and method as registered by the SYS_REGISTER_IRQ
    4545 *            syscall
    4646 * - ARG1: payload modified by a 'top-half' handler
     
    131131/** Register an answerbox as a receiving end for IRQ notifications.
    132132 *
    133  * @param box     Receiving answerbox.
    134  * @param inr     IRQ number.
    135  * @param devno   Device number.
    136  * @param imethod Interface and method to be associated
    137  *                with the notification.
    138  * @param ucode   Uspace pointer to top-half pseudocode.
    139  *
    140  * @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success.
     133 * @param box           Receiving answerbox.
     134 * @param inr           IRQ number.
     135 * @param devno         Device number.
     136 * @param imethod       Interface and method to be associated with the
     137 *                      notification.
     138 * @param ucode         Uspace pointer to top-half pseudocode.
     139 * @return              EOK on success or a negative error code.
    141140 *
    142141 */
     
    148147                (sysarg_t) devno
    149148        };
     149
     150        if ((inr < 0) || (inr > last_inr))
     151                return ELIMIT;
    150152       
    151153        irq_code_t *code;
     
    208210/** Unregister task from IRQ notification.
    209211 *
    210  * @param box   Answerbox associated with the notification.
    211  * @param inr   IRQ number.
    212  * @param devno Device number.
    213  *
     212 * @param box           Answerbox associated with the notification.
     213 * @param inr           IRQ number.
     214 * @param devno         Device number.
     215 * @return              EOK on success or a negative error code.
    214216 */
    215217int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
     
    219221                (sysarg_t) devno
    220222        };
     223
     224        if ((inr < 0) || (inr > last_inr))
     225                return ELIMIT;
    221226       
    222227        irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
     
    399404                            (uint32_t) code->cmds[i].value);
    400405                        break;
     406                case CMD_PIO_WRITE_A_8:
     407                        if (srcarg) {
     408                                pio_write_8((ioport8_t *) code->cmds[i].addr,
     409                                    (uint8_t) scratch[srcarg]);
     410                        }
     411                        break;
     412                case CMD_PIO_WRITE_A_16:
     413                        if (srcarg) {
     414                                pio_write_16((ioport16_t *) code->cmds[i].addr,
     415                                    (uint16_t) scratch[srcarg]);
     416                        }
     417                        break;
     418                case CMD_PIO_WRITE_A_32:
     419                        if (srcarg) {
     420                                pio_write_32((ioport32_t *) code->cmds[i].addr,
     421                                    (uint32_t) scratch[srcarg]);
     422                        }
     423                        break;
    401424                case CMD_BTEST:
    402425                        if ((srcarg) && (dstarg)) {
  • kernel/generic/src/ipc/sysipc.c

    r6e50466 rad7a6c9  
    248248                        /* The connection was accepted */
    249249                        phone_connect(phoneid, &answer->sender->answerbox);
     250                        /* Set 'task hash' as arg4 of response */
     251                        IPC_SET_ARG4(answer->data, (sysarg_t) TASK);
    250252                        /* Set 'phone hash' as arg5 of response */
    251253                        IPC_SET_ARG5(answer->data,
     
    11031105 *
    11041106 */
    1105 sysarg_t sys_ipc_register_irq(inr_t inr, devno_t devno, sysarg_t imethod,
     1107sysarg_t sys_register_irq(inr_t inr, devno_t devno, sysarg_t imethod,
    11061108    irq_code_t *ucode)
    11071109{
     
    11201122 *
    11211123 */
    1122 sysarg_t sys_ipc_unregister_irq(inr_t inr, devno_t devno)
     1124sysarg_t sys_unregister_irq(inr_t inr, devno_t devno)
    11231125{
    11241126        if (!(cap_get(TASK) & CAP_IRQ_REG))
  • kernel/generic/src/lib/elf.c

    r6e50466 rad7a6c9  
    157157        case PT_NULL:
    158158        case PT_PHDR:
     159        case PT_NOTE:
    159160                break;
    160161        case PT_LOAD:
     
    173174                break;
    174175        case PT_SHLIB:
    175         case PT_NOTE:
    176176        case PT_LOPROC:
    177177        case PT_HIPROC:
  • kernel/generic/src/lib/memfnc.c

    r6e50466 rad7a6c9  
    1 /*
    2  * Copyright (c) 2009 Lukas Mejdrech
     1        /*
     2 * Copyright (c) 2011 Martin Decky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup ip
     29/** @addtogroup generic
    3030 * @{
    3131 */
    3232
    33 /** @file
    34  * IP standalone module implementation.
    35  * Contains skeleton module functions mapping.
    36  * The functions are used by the module skeleton as module specific entry
    37  * points.
     33/**
     34 * @file
     35 * @brief Memory string functions.
    3836 *
    39  * @see module.c
     37 * This file provides architecture independent functions to manipulate blocks
     38 * of memory. These functions are optimized as much as generic functions of
     39 * this type can be.
    4040 */
    4141
    42 #include <async.h>
    43 #include <stdio.h>
    44 #include <ipc/ipc.h>
    45 #include <ipc/services.h>
    46 #include <errno.h>
     42#include <lib/memfnc.h>
     43#include <typedefs.h>
    4744
    48 #include <net/modules.h>
    49 #include <net_interface.h>
    50 #include <net/packet.h>
    51 #include <il_local.h>
    52 
    53 #include "ip.h"
    54 #include "ip_module.h"
    55 
    56 /** IP module global data. */
    57 extern ip_globals_t ip_globals;
    58 
    59 int
    60 il_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    61     ipc_call_t *answer, int *answer_count)
     45/** Fill block of memory.
     46 *
     47 * Fill cnt bytes at dst address with the value val.
     48 *
     49 * @param dst Destination address to fill.
     50 * @param val Value to fill.
     51 * @param cnt Number of bytes to fill.
     52 *
     53 * @return Destination address.
     54 *
     55 */
     56void *memset(void *dst, int val, size_t cnt)
    6257{
    63         return ip_message_standalone(callid, call, answer, answer_count);
     58        size_t i;
     59        uint8_t *ptr = (uint8_t *) dst;
     60       
     61        for (i = 0; i < cnt; i++)
     62                ptr[i] = val;
     63       
     64        return dst;
    6465}
    6566
    66 int il_module_start_standalone(async_client_conn_t client_connection)
     67/** Move memory block without overlapping.
     68 *
     69 * Copy cnt bytes from src address to dst address. The source
     70 * and destination memory areas cannot overlap.
     71 *
     72 * @param dst Destination address to copy to.
     73 * @param src Source address to copy from.
     74 * @param cnt Number of bytes to copy.
     75 *
     76 * @return Destination address.
     77 *
     78 */
     79void *memcpy(void *dst, const void *src, size_t cnt)
    6780{
    68         sysarg_t phonehash;
    69         int rc;
     81        uint8_t *dp = (uint8_t *) dst;
     82        const uint8_t *sp = (uint8_t *) src;
    7083       
    71         async_set_client_connection(client_connection);
    72         ip_globals.net_phone = net_connect_module();
    73 
    74         rc = pm_init();
    75         if (rc != EOK)
    76                 return rc;
     84        while (cnt-- != 0)
     85                        *dp++ = *sp++;
    7786       
    78         rc = ip_initialize(client_connection);
    79         if (rc != EOK)
    80                 goto out;
    81        
    82         rc = ipc_connect_to_me(PHONE_NS, SERVICE_IP, 0, 0, &phonehash);
    83         if (rc != EOK)
    84                 goto out;
    85        
    86         async_manager();
    87 
    88 out:
    89         pm_destroy();
    90         return rc;
     87        return dst;
    9188}
    9289
  • kernel/generic/src/lib/memstr.c

    r6e50466 rad7a6c9  
    2828 */
    2929
    30 /** @addtogroup generic 
     30/** @addtogroup generic
    3131 * @{
    3232 */
     
    3434/**
    3535 * @file
    36  * @brief       Memory string operations.
     36 * @brief Memory string operations.
    3737 *
    38  * This file provides architecture independent functions to manipulate blocks of
    39  * memory. These functions are optimized as much as generic functions of this
    40  * type can be. However, architectures are free to provide even more optimized
    41  * versions of these functions.
     38 * This file provides architecture independent functions to manipulate blocks
     39 * of memory. These functions are optimized as much as generic functions of
     40 * this type can be.
    4241 */
    4342
    4443#include <memstr.h>
    4544#include <typedefs.h>
    46 #include <align.h>
    4745
    48 /** Copy block of memory.
     46/** Fill block of memory.
    4947 *
    50  * Copy cnt bytes from src address to dst address.  The copying is done
    51  * word-by-word and then byte-by-byte.  The source and destination memory areas
    52  * cannot overlap.
     48 * Fill cnt bytes at dst address with the value val.
    5349 *
    54  * @param src           Source address to copy from.
    55  * @param dst           Destination address to copy to.
    56  * @param cnt           Number of bytes to copy.
     50 * @param dst Destination address to fill.
     51 * @param cnt Number of bytes to fill.
     52 * @param val Value to fill.
    5753 *
    58  * @return              Destination address.
    5954 */
    60 void *_memcpy(void *dst, const void *src, size_t cnt)
     55void memsetb(void *dst, size_t cnt, uint8_t val)
    6156{
    62         unsigned int i, j;
     57        memset(dst, val, cnt);
     58}
     59
     60/** Fill block of memory.
     61 *
     62 * Fill cnt words at dst address with the value val. The filling
     63 * is done word-by-word.
     64 *
     65 * @param dst Destination address to fill.
     66 * @param cnt Number of words to fill.
     67 * @param val Value to fill.
     68 *
     69 */
     70void memsetw(void *dst, size_t cnt, uint16_t val)
     71{
     72        size_t i;
     73        uint16_t *ptr = (uint16_t *) dst;
    6374       
    64         if (ALIGN_UP((uintptr_t) src, sizeof(sysarg_t)) != (uintptr_t) src ||
    65             ALIGN_UP((uintptr_t) dst, sizeof(sysarg_t)) != (uintptr_t) dst) {
    66                 for (i = 0; i < cnt; i++)
    67                         ((uint8_t *) dst)[i] = ((uint8_t *) src)[i];
    68         } else {
    69                 for (i = 0; i < cnt / sizeof(sysarg_t); i++)
    70                         ((sysarg_t *) dst)[i] = ((sysarg_t *) src)[i];
    71                
    72                 for (j = 0; j < cnt % sizeof(sysarg_t); j++)
    73                         ((uint8_t *)(((sysarg_t *) dst) + i))[j] =
    74                             ((uint8_t *)(((sysarg_t *) src) + i))[j];
    75         }
    76                
    77         return (char *) dst;
     75        for (i = 0; i < cnt; i++)
     76                ptr[i] = val;
    7877}
    7978
    8079/** Move memory block with possible overlapping.
    8180 *
    82  * Copy cnt bytes from src address to dst address. The source and destination
    83  * memory areas may overlap.
     81 * Copy cnt bytes from src address to dst address. The source
     82 * and destination memory areas may overlap.
    8483 *
    85  * @param src           Source address to copy from.
    86  * @param dst           Destination address to copy to.
    87  * @param cnt           Number of bytes to copy.
     84 * @param dst Destination address to copy to.
     85 * @param src Source address to copy from.
     86 * @param cnt Number of bytes to copy.
    8887 *
    89  * @return              Destination address.
     88 * @return Destination address.
     89 *
    9090 */
    91 void *memmove(void *dst, const void *src, size_t n)
     91void *memmove(void *dst, const void *src, size_t cnt)
    9292{
    93         const uint8_t *sp;
    94         uint8_t *dp;
    95 
    9693        /* Nothing to do? */
    9794        if (src == dst)
    9895                return dst;
    99 
     96       
    10097        /* Non-overlapping? */
    101         if (dst >= src + n || src >= dst + n) {
    102                 return memcpy(dst, src, n);
    103         }
    104 
     98        if ((dst >= src + cnt) || (src >= dst + cnt))
     99                return memcpy(dst, src, cnt);
     100       
     101        uint8_t *dp;
     102        const uint8_t *sp;
     103       
    105104        /* Which direction? */
    106105        if (src > dst) {
    107106                /* Forwards. */
     107                dp = dst;
    108108                sp = src;
    109                 dp = dst;
    110 
    111                 while (n-- != 0)
     109               
     110                while (cnt-- != 0)
    112111                        *dp++ = *sp++;
    113112        } else {
    114113                /* Backwards. */
    115                 sp = src + (n - 1);
    116                 dp = dst + (n - 1);
    117 
    118                 while (n-- != 0)
     114                dp = dst + (cnt - 1);
     115                sp = src + (cnt - 1);
     116               
     117                while (cnt-- != 0)
    119118                        *dp-- = *sp--;
    120119        }
    121 
     120       
    122121        return dst;
    123 }
    124 
    125 /** Fill block of memory
    126  *
    127  * Fill cnt bytes at dst address with the value x.  The filling is done
    128  * byte-by-byte.
    129  *
    130  * @param dst           Destination address to fill.
    131  * @param cnt           Number of bytes to fill.
    132  * @param x             Value to fill.
    133  *
    134  */
    135 void _memsetb(void *dst, size_t cnt, uint8_t x)
    136 {
    137         unsigned int i;
    138         uint8_t *p = (uint8_t *) dst;
    139        
    140         for (i = 0; i < cnt; i++)
    141                 p[i] = x;
    142 }
    143 
    144 /** Fill block of memory.
    145  *
    146  * Fill cnt words at dst address with the value x.  The filling is done
    147  * word-by-word.
    148  *
    149  * @param dst           Destination address to fill.
    150  * @param cnt           Number of words to fill.
    151  * @param x             Value to fill.
    152  *
    153  */
    154 void _memsetw(void *dst, size_t cnt, uint16_t x)
    155 {
    156         unsigned int i;
    157         uint16_t *p = (uint16_t *) dst;
    158        
    159         for (i = 0; i < cnt; i++)
    160                 p[i] = x;       
    161122}
    162123
  • kernel/generic/src/lib/rd.c

    r6e50466 rad7a6c9  
    9090            FRAME_SIZE);
    9191        rd_parea.frames = SIZE2FRAMES(dsize);
     92        rd_parea.unpriv = false;
    9293        ddi_parea_register(&rd_parea);
    9394
  • kernel/generic/src/main/main.c

    r6e50466 rad7a6c9  
    185185        LOG("\nconfig.base=%p config.kernel_size=%zu"
    186186            "\nconfig.stack_base=%p config.stack_size=%zu",
    187             config.base, config.kernel_size, config.stack_base,
    188             config.stack_size);
     187            (void *) config.base, config.kernel_size,
     188            (void *) config.stack_base, config.stack_size);
    189189       
    190190#ifdef CONFIG_KCONSOLE
     
    242242                for (i = 0; i < init.cnt; i++)
    243243                        LOG("init[%zu].addr=%p, init[%zu].size=%zu",
    244                             i, init.tasks[i].addr, i, init.tasks[i].size);
     244                            i, (void *) init.tasks[i].addr, i, init.tasks[i].size);
    245245        } else
    246246                printf("No init binaries found.\n");
  • kernel/generic/src/mm/as.c

    r6e50466 rad7a6c9  
    7171#include <memstr.h>
    7272#include <macros.h>
     73#include <bitops.h>
    7374#include <arch.h>
    7475#include <errno.h>
     
    8687 * Each architecture decides what functions will be used to carry out
    8788 * address space operations such as creating or locking page tables.
    88  *
    8989 */
    9090as_operations_t *as_operations = NULL;
    9191
    92 /**
    93  * Slab for as_t objects.
     92/** Slab for as_t objects.
    9493 *
    9594 */
    9695static slab_cache_t *as_slab;
    9796
    98 /**
    99  * This lock serializes access to the ASID subsystem.
    100  * It protects:
     97/** ASID subsystem lock.
     98 *
     99 * This lock protects:
    101100 * - inactive_as_with_asid_head list
    102101 * - as->asid for each as of the as_t type
     
    107106
    108107/**
    109  * This list contains address spaces that are not active on any
    110  * processor and that have valid ASID.
    111  *
     108 * Inactive address spaces (on all processors)
     109 * that have valid ASID.
    112110 */
    113111LIST_INITIALIZE(inactive_as_with_asid_head);
     
    123121        mutex_initialize(&as->lock, MUTEX_PASSIVE);
    124122       
    125         int rc = as_constructor_arch(as, flags);
    126        
    127         return rc;
     123        return as_constructor_arch(as, flags);
    128124}
    129125
    130126NO_TRACE static size_t as_destructor(void *obj)
    131127{
    132         as_t *as = (as_t *) obj;
    133         return as_destructor_arch(as);
     128        return as_destructor_arch((as_t *) obj);
    134129}
    135130
     
    146141                panic("Cannot create kernel address space.");
    147142       
    148         /* Make sure the kernel address space
     143        /*
     144         * Make sure the kernel address space
    149145         * reference count never drops to zero.
    150146         */
     
    195191{
    196192        DEADLOCK_PROBE_INIT(p_asidlock);
    197 
     193       
    198194        ASSERT(as != AS);
    199195        ASSERT(atomic_get(&as->refcount) == 0);
     
    203199         * lock its mutex.
    204200         */
    205 
     201       
    206202        /*
    207203         * We need to avoid deadlock between TLB shootdown and asidlock.
     
    210206         * disabled to prevent nested context switches. We also depend on the
    211207         * fact that so far no spinlocks are held.
    212          *
    213208         */
    214209        preemption_disable();
     
    235230        spinlock_unlock(&asidlock);
    236231        interrupts_restore(ipl);
    237 
     232       
    238233       
    239234        /*
     
    241236         * The B+tree must be walked carefully because it is
    242237         * also being destroyed.
    243          *
    244238         */
    245239        bool cond = true;
     
    268262/** Hold a reference to an address space.
    269263 *
    270  * Holding a reference to an address space prevents destruction of that address
    271  * space.
     264 * Holding a reference to an address space prevents destruction
     265 * of that address space.
    272266 *
    273267 * @param as Address space to be held.
     
    281275/** Release a reference to an address space.
    282276 *
    283  * The last one to release a reference to an address space destroys the address
    284  * space.
     277 * The last one to release a reference to an address space
     278 * destroys the address space.
    285279 *
    286280 * @param asAddress space to be released.
     
    295289/** Check area conflicts with other areas.
    296290 *
    297  * @param as         Address space.
    298  * @param va         Starting virtual address of the area being tested.
    299  * @param size       Size of the area being tested.
    300  * @param avoid_area Do not touch this area.
     291 * @param as    Address space.
     292 * @param addr  Starting virtual address of the area being tested.
     293 * @param count Number of pages in the area being tested.
     294 * @param avoid Do not touch this area.
    301295 *
    302296 * @return True if there is no conflict, false otherwise.
    303297 *
    304298 */
    305 NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
    306     as_area_t *avoid_area)
    307 {
     299NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr,
     300    size_t count, as_area_t *avoid)
     301{
     302        ASSERT((addr % PAGE_SIZE) == 0);
    308303        ASSERT(mutex_locked(&as->lock));
    309304       
    310305        /*
    311306         * We don't want any area to have conflicts with NULL page.
    312          *
    313          */
    314         if (overlaps(va, size, (uintptr_t) NULL, PAGE_SIZE))
     307         */
     308        if (overlaps(addr, count << PAGE_WIDTH, (uintptr_t) NULL, PAGE_SIZE))
    315309                return false;
    316310       
     
    321315         * record in the left neighbour, the leftmost record in the right
    322316         * neighbour and all records in the leaf node itself.
    323          *
    324317         */
    325318        btree_node_t *leaf;
    326319        as_area_t *area =
    327             (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     320            (as_area_t *) btree_search(&as->as_area_btree, addr, &leaf);
    328321        if (area) {
    329                 if (area != avoid_area)
     322                if (area != avoid)
    330323                        return false;
    331324        }
     
    337330                area = (as_area_t *) node->value[node->keys - 1];
    338331               
    339                 mutex_lock(&area->lock);
    340                
    341                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     332                if (area != avoid) {
     333                        mutex_lock(&area->lock);
     334                       
     335                        if (overlaps(addr, count << PAGE_WIDTH,
     336                            area->base, area->pages << PAGE_WIDTH)) {
     337                                mutex_unlock(&area->lock);
     338                                return false;
     339                        }
     340                       
    342341                        mutex_unlock(&area->lock);
    343                         return false;
    344                 }
    345                
    346                 mutex_unlock(&area->lock);
     342                }
    347343        }
    348344       
     
    351347                area = (as_area_t *) node->value[0];
    352348               
    353                 mutex_lock(&area->lock);
    354                
    355                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     349                if (area != avoid) {
     350                        mutex_lock(&area->lock);
     351                       
     352                        if (overlaps(addr, count << PAGE_WIDTH,
     353                            area->base, area->pages << PAGE_WIDTH)) {
     354                                mutex_unlock(&area->lock);
     355                                return false;
     356                        }
     357                       
    356358                        mutex_unlock(&area->lock);
    357                         return false;
    358                 }
    359                
    360                 mutex_unlock(&area->lock);
     359                }
    361360        }
    362361       
     
    366365                area = (as_area_t *) leaf->value[i];
    367366               
    368                 if (area == avoid_area)
     367                if (area == avoid)
    369368                        continue;
    370369               
    371370                mutex_lock(&area->lock);
    372371               
    373                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     372                if (overlaps(addr, count << PAGE_WIDTH,
     373                    area->base, area->pages << PAGE_WIDTH)) {
    374374                        mutex_unlock(&area->lock);
    375375                        return false;
     
    382382         * So far, the area does not conflict with other areas.
    383383         * Check if it doesn't conflict with kernel address space.
    384          *
    385384         */
    386385        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    387                 return !overlaps(va, size,
     386                return !overlaps(addr, count << PAGE_WIDTH,
    388387                    KERNEL_ADDRESS_SPACE_START,
    389388                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
     
    412411    mem_backend_data_t *backend_data)
    413412{
    414         if (base % PAGE_SIZE)
     413        if ((base % PAGE_SIZE) != 0)
    415414                return NULL;
    416415       
    417         if (!size)
     416        if (size == 0)
    418417                return NULL;
     418       
     419        size_t pages = SIZE2FRAMES(size);
    419420       
    420421        /* Writeable executable areas are not supported. */
     
    424425        mutex_lock(&as->lock);
    425426       
    426         if (!check_area_conflicts(as, base, size, NULL)) {
     427        if (!check_area_conflicts(as, base, pages, NULL)) {
    427428                mutex_unlock(&as->lock);
    428429                return NULL;
     
    436437        area->flags = flags;
    437438        area->attributes = attrs;
    438         area->pages = SIZE2FRAMES(size);
     439        area->pages = pages;
     440        area->resident = 0;
    439441        area->base = base;
    440442        area->sh_info = NULL;
     
    479481         * to find out whether this is a miss or va belongs to an address
    480482         * space area found there.
    481          *
    482483         */
    483484       
     
    490491                mutex_lock(&area->lock);
    491492               
    492                 if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
     493                if ((area->base <= va) &&
     494                    (va < area->base + (area->pages << PAGE_WIDTH)))
    493495                        return area;
    494496               
     
    499501         * Second, locate the left neighbour and test its last record.
    500502         * Because of its position in the B+tree, it must have base < va.
    501          *
    502503         */
    503504        btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     
    507508                mutex_lock(&area->lock);
    508509               
    509                 if (va < area->base + area->pages * PAGE_SIZE)
     510                if (va < area->base + (area->pages << PAGE_WIDTH))
    510511                        return area;
    511512               
     
    534535        /*
    535536         * Locate the area.
    536          *
    537537         */
    538538        as_area_t *area = find_area_and_lock(as, address);
     
    546546                 * Remapping of address space areas associated
    547547                 * with memory mapped devices is not supported.
    548                  *
    549548                 */
    550549                mutex_unlock(&area->lock);
     
    557556                 * Remapping of shared address space areas
    558557                 * is not supported.
    559                  *
    560558                 */
    561559                mutex_unlock(&area->lock);
     
    568566                /*
    569567                 * Zero size address space areas are not allowed.
    570                  *
    571568                 */
    572569                mutex_unlock(&area->lock);
     
    576573       
    577574        if (pages < area->pages) {
    578                 uintptr_t start_free = area->base + pages * PAGE_SIZE;
     575                uintptr_t start_free = area->base + (pages << PAGE_WIDTH);
    579576               
    580577                /*
    581578                 * Shrinking the area.
    582579                 * No need to check for overlaps.
    583                  *
    584580                 */
    585581               
     
    588584                /*
    589585                 * Start TLB shootdown sequence.
    590                  *
    591586                 */
    592587                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
    593                     area->base + pages * PAGE_SIZE, area->pages - pages);
     588                    area->base + (pages << PAGE_WIDTH), area->pages - pages);
    594589               
    595590                /*
     
    599594                 * is also the right way to remove part of the used_space
    600595                 * B+tree leaf list.
    601                  *
    602596                 */
    603597                bool cond = true;
     
    615609                                size_t i = 0;
    616610                               
    617                                 if (overlaps(ptr, size * PAGE_SIZE, area->base,
    618                                     pages * PAGE_SIZE)) {
     611                                if (overlaps(ptr, size << PAGE_WIDTH, area->base,
     612                                    pages << PAGE_WIDTH)) {
    619613                                       
    620                                         if (ptr + size * PAGE_SIZE <= start_free) {
     614                                        if (ptr + (size << PAGE_WIDTH) <= start_free) {
    621615                                                /*
    622616                                                 * The whole interval fits
    623617                                                 * completely in the resized
    624618                                                 * address space area.
    625                                                  *
    626619                                                 */
    627620                                                break;
     
    632625                                         * to b and c overlaps with the resized
    633626                                         * address space area.
    634                                          *
    635627                                         */
    636628                                       
     
    652644                                for (; i < size; i++) {
    653645                                        pte_t *pte = page_mapping_find(as, ptr +
    654                                             i * PAGE_SIZE);
     646                                            (i << PAGE_WIDTH));
    655647                                       
    656648                                        ASSERT(pte);
     
    661653                                            (area->backend->frame_free)) {
    662654                                                area->backend->frame_free(area,
    663                                                     ptr + i * PAGE_SIZE,
     655                                                    ptr + (i << PAGE_WIDTH),
    664656                                                    PTE_GET_FRAME(pte));
    665657                                        }
    666658                                       
    667659                                        page_mapping_remove(as, ptr +
    668                                             i * PAGE_SIZE);
     660                                            (i << PAGE_WIDTH));
    669661                                }
    670662                        }
     
    673665                /*
    674666                 * Finish TLB shootdown sequence.
    675                  *
    676                  */
    677                
    678                 tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
     667                 */
     668               
     669                tlb_invalidate_pages(as->asid, area->base + (pages << PAGE_WIDTH),
    679670                    area->pages - pages);
    680671               
    681672                /*
    682673                 * Invalidate software translation caches (e.g. TSB on sparc64).
    683                  *
    684674                 */
    685675                as_invalidate_translation_cache(as, area->base +
    686                     pages * PAGE_SIZE, area->pages - pages);
     676                    (pages << PAGE_WIDTH), area->pages - pages);
    687677                tlb_shootdown_finalize(ipl);
    688678               
     
    692682                 * Growing the area.
    693683                 * Check for overlaps with other address space areas.
    694                  *
    695                  */
    696                 if (!check_area_conflicts(as, address, pages * PAGE_SIZE,
    697                     area)) {
     684                 */
     685                if (!check_area_conflicts(as, address, pages, area)) {
    698686                        mutex_unlock(&area->lock);
    699687                        mutex_unlock(&as->lock);
     
    794782                       
    795783                        for (size = 0; size < (size_t) node->value[i]; size++) {
    796                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
     784                                pte_t *pte =
     785                                    page_mapping_find(as, ptr + (size << PAGE_WIDTH));
    797786                               
    798787                                ASSERT(pte);
     
    803792                                    (area->backend->frame_free)) {
    804793                                        area->backend->frame_free(area,
    805                                             ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte));
     794                                            ptr + (size << PAGE_WIDTH), PTE_GET_FRAME(pte));
    806795                                }
    807796                               
    808                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     797                                page_mapping_remove(as, ptr + (size << PAGE_WIDTH));
    809798                        }
    810799                }
     
    813802        /*
    814803         * Finish TLB shootdown sequence.
    815          *
    816804         */
    817805       
     
    821809         * Invalidate potential software translation caches (e.g. TSB on
    822810         * sparc64).
    823          *
    824811         */
    825812        as_invalidate_translation_cache(as, area->base, area->pages);
     
    839826        /*
    840827         * Remove the empty area from address space.
    841          *
    842828         */
    843829        btree_remove(&as->as_area_btree, base, NULL);
     
    881867                /*
    882868                 * Could not find the source address space area.
    883                  *
    884869                 */
    885870                mutex_unlock(&src_as->lock);
     
    891876                 * There is no backend or the backend does not
    892877                 * know how to share the area.
    893                  *
    894878                 */
    895879                mutex_unlock(&src_area->lock);
     
    898882        }
    899883       
    900         size_t src_size = src_area->pages * PAGE_SIZE;
     884        size_t src_size = src_area->pages << PAGE_WIDTH;
    901885        unsigned int src_flags = src_area->flags;
    902886        mem_backend_t *src_backend = src_area->backend;
     
    918902         * First, prepare the area for sharing.
    919903         * Then it will be safe to unlock it.
    920          *
    921904         */
    922905        share_info_t *sh_info = src_area->sh_info;
     
    930913                /*
    931914                 * Call the backend to setup sharing.
    932                  *
    933915                 */
    934916                src_area->backend->share(src_area);
     
    949931         * The flags of the source area are masked against dst_flags_mask
    950932         * to support sharing in less privileged mode.
    951          *
    952933         */
    953934        as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask, src_size,
     
    966947         * fully initialized. Clear the AS_AREA_ATTR_PARTIAL
    967948         * attribute and set the sh_info.
    968          *
    969949         */
    970950        mutex_lock(&dst_as->lock);
     
    989969NO_TRACE bool as_area_check_access(as_area_t *area, pf_access_t access)
    990970{
     971        ASSERT(mutex_locked(&area->lock));
     972       
    991973        int flagmap[] = {
    992974                [PF_ACCESS_READ] = AS_AREA_READ,
     
    994976                [PF_ACCESS_EXEC] = AS_AREA_EXEC
    995977        };
    996 
    997         ASSERT(mutex_locked(&area->lock));
    998978       
    999979        if (!(area->flags & flagmap[access]))
     
    10661046        /*
    10671047         * Compute total number of used pages in the used_space B+tree
    1068          *
    10691048         */
    10701049        size_t used_pages = 0;
     
    10881067        /*
    10891068         * Start TLB shootdown sequence.
    1090          *
    10911069         */
    10921070        ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
     
    10961074         * Remove used pages from page tables and remember their frame
    10971075         * numbers.
    1098          *
    10991076         */
    11001077        size_t frame_idx = 0;
     
    11111088                       
    11121089                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1113                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
     1090                                pte_t *pte =
     1091                                    page_mapping_find(as, ptr + (size << PAGE_WIDTH));
    11141092                               
    11151093                                ASSERT(pte);
     
    11201098                               
    11211099                                /* Remove old mapping */
    1122                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     1100                                page_mapping_remove(as, ptr + (size << PAGE_WIDTH));
    11231101                        }
    11241102                }
     
    11271105        /*
    11281106         * Finish TLB shootdown sequence.
    1129          *
    11301107         */
    11311108       
     
    11351112         * Invalidate potential software translation caches (e.g. TSB on
    11361113         * sparc64).
    1137          *
    11381114         */
    11391115        as_invalidate_translation_cache(as, area->base, area->pages);
     
    11681144                               
    11691145                                /* Insert the new mapping */
    1170                                 page_mapping_insert(as, ptr + size * PAGE_SIZE,
     1146                                page_mapping_insert(as, ptr + (size << PAGE_WIDTH),
    11711147                                    old_frame[frame_idx++], page_flags);
    11721148                               
     
    12171193                 * No area contained mapping for 'page'.
    12181194                 * Signal page fault to low-level handler.
    1219                  *
    12201195                 */
    12211196                mutex_unlock(&AS->lock);
     
    12371212                 * The address space area is not backed by any backend
    12381213                 * or the backend cannot handle page faults.
    1239                  *
    12401214                 */
    12411215                mutex_unlock(&area->lock);
     
    12491223         * To avoid race condition between two page faults on the same address,
    12501224         * we need to make sure the mapping has not been already inserted.
    1251          *
    12521225         */
    12531226        pte_t *pte;
     
    12671240        /*
    12681241         * Resort to the backend page fault handler.
    1269          *
    12701242         */
    12711243        if (area->backend->page_fault(area, page, access) != AS_PF_OK) {
     
    13221294                 * preemption is disabled. We should not be
    13231295                 * holding any other lock.
    1324                  *
    13251296                 */
    13261297                (void) interrupts_enable();
     
    13421313                         * list of inactive address spaces with assigned
    13431314                         * ASID.
    1344                          *
    13451315                         */
    13461316                        ASSERT(old_as->asid != ASID_INVALID);
     
    13531323                 * Perform architecture-specific tasks when the address space
    13541324                 * is being removed from the CPU.
    1355                  *
    13561325                 */
    13571326                as_deinstall_arch(old_as);
     
    13601329        /*
    13611330         * Second, prepare the new address space.
    1362          *
    13631331         */
    13641332        if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) {
     
    13761344         * Perform architecture-specific steps.
    13771345         * (e.g. write ASID to hardware register etc.)
    1378          *
    13791346         */
    13801347        as_install_arch(new_as);
     
    13951362{
    13961363        ASSERT(mutex_locked(&area->lock));
    1397 
     1364       
    13981365        return area_flags_to_page_flags(area->flags);
    13991366}
     
    14991466       
    15001467        if (src_area) {
    1501                 size = src_area->pages * PAGE_SIZE;
     1468                size = src_area->pages << PAGE_WIDTH;
    15021469                mutex_unlock(&src_area->lock);
    15031470        } else
     
    15161483 * @param count Number of page to be marked.
    15171484 *
    1518  * @return Zero on failure and non-zero on success.
    1519  *
    1520  */
    1521 int used_space_insert(as_area_t *area, uintptr_t page, size_t count)
     1485 * @return False on failure or true on success.
     1486 *
     1487 */
     1488bool used_space_insert(as_area_t *area, uintptr_t page, size_t count)
    15221489{
    15231490        ASSERT(mutex_locked(&area->lock));
     
    15301497                /*
    15311498                 * We hit the beginning of some used space.
    1532                  *
    1533                  */
    1534                 return 0;
     1499                 */
     1500                return false;
    15351501        }
    15361502       
    15371503        if (!leaf->keys) {
    15381504                btree_insert(&area->used_space, page, (void *) count, leaf);
    1539                 return 1;
     1505                goto success;
    15401506        }
    15411507       
     
    15511517                 * somewhere between the rightmost interval of
    15521518                 * the left neigbour and the first interval of the leaf.
    1553                  *
    15541519                 */
    15551520               
    15561521                if (page >= right_pg) {
    15571522                        /* Do nothing. */
    1558                 } else if (overlaps(page, count * PAGE_SIZE, left_pg,
    1559                     left_cnt * PAGE_SIZE)) {
     1523                } else if (overlaps(page, count << PAGE_WIDTH, left_pg,
     1524                    left_cnt << PAGE_WIDTH)) {
    15601525                        /* The interval intersects with the left interval. */
    1561                         return 0;
    1562                 } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1563                     right_cnt * PAGE_SIZE)) {
     1526                        return false;
     1527                } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
     1528                    right_cnt << PAGE_WIDTH)) {
    15641529                        /* The interval intersects with the right interval. */
    1565                         return 0;
    1566                 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1567                     (page + count * PAGE_SIZE == right_pg)) {
     1530                        return false;
     1531                } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
     1532                    (page + (count << PAGE_WIDTH) == right_pg)) {
    15681533                        /*
    15691534                         * The interval can be added by merging the two already
    15701535                         * present intervals.
    1571                          *
    15721536                         */
    15731537                        node->value[node->keys - 1] += count + right_cnt;
    15741538                        btree_remove(&area->used_space, right_pg, leaf);
    1575                         return 1;
    1576                 } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1539                        goto success;
     1540                } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
    15771541                        /*
    15781542                         * The interval can be added by simply growing the left
    15791543                         * interval.
    1580                          *
    15811544                         */
    15821545                        node->value[node->keys - 1] += count;
    1583                         return 1;
    1584                 } else if (page + count * PAGE_SIZE == right_pg) {
     1546                        goto success;
     1547                } else if (page + (count << PAGE_WIDTH) == right_pg) {
    15851548                        /*
    15861549                         * The interval can be addded by simply moving base of
    15871550                         * the right interval down and increasing its size
    15881551                         * accordingly.
    1589                          *
    15901552                         */
    15911553                        leaf->value[0] += count;
    15921554                        leaf->key[0] = page;
    1593                         return 1;
     1555                        goto success;
    15941556                } else {
    15951557                        /*
    15961558                         * The interval is between both neigbouring intervals,
    15971559                         * but cannot be merged with any of them.
    1598                          *
    15991560                         */
    16001561                        btree_insert(&area->used_space, page, (void *) count,
    16011562                            leaf);
    1602                         return 1;
     1563                        goto success;
    16031564                }
    16041565        } else if (page < leaf->key[0]) {
     
    16091570                 * Investigate the border case in which the left neighbour does
    16101571                 * not exist but the interval fits from the left.
    1611                  *
    1612                  */
    1613                
    1614                 if (overlaps(page, count * PAGE_SIZE, right_pg,
    1615                     right_cnt * PAGE_SIZE)) {
     1572                 */
     1573               
     1574                if (overlaps(page, count << PAGE_WIDTH, right_pg,
     1575                    right_cnt << PAGE_WIDTH)) {
    16161576                        /* The interval intersects with the right interval. */
    1617                         return 0;
    1618                 } else if (page + count * PAGE_SIZE == right_pg) {
     1577                        return false;
     1578                } else if (page + (count << PAGE_WIDTH) == right_pg) {
    16191579                        /*
    16201580                         * The interval can be added by moving the base of the
    16211581                         * right interval down and increasing its size
    16221582                         * accordingly.
    1623                          *
    16241583                         */
    16251584                        leaf->key[0] = page;
    16261585                        leaf->value[0] += count;
    1627                         return 1;
     1586                        goto success;
    16281587                } else {
    16291588                        /*
    16301589                         * The interval doesn't adjoin with the right interval.
    16311590                         * It must be added individually.
    1632                          *
    16331591                         */
    16341592                        btree_insert(&area->used_space, page, (void *) count,
    16351593                            leaf);
    1636                         return 1;
     1594                        goto success;
    16371595                }
    16381596        }
     
    16491607                 * somewhere between the leftmost interval of
    16501608                 * the right neigbour and the last interval of the leaf.
    1651                  *
    16521609                 */
    16531610               
    16541611                if (page < left_pg) {
    16551612                        /* Do nothing. */
    1656                 } else if (overlaps(page, count * PAGE_SIZE, left_pg,
    1657                     left_cnt * PAGE_SIZE)) {
     1613                } else if (overlaps(page, count << PAGE_WIDTH, left_pg,
     1614                    left_cnt << PAGE_WIDTH)) {
    16581615                        /* The interval intersects with the left interval. */
    1659                         return 0;
    1660                 } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1661                     right_cnt * PAGE_SIZE)) {
     1616                        return false;
     1617                } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
     1618                    right_cnt << PAGE_WIDTH)) {
    16621619                        /* The interval intersects with the right interval. */
    1663                         return 0;
    1664                 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1665                     (page + count * PAGE_SIZE == right_pg)) {
     1620                        return false;
     1621                } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
     1622                    (page + (count << PAGE_WIDTH) == right_pg)) {
    16661623                        /*
    16671624                         * The interval can be added by merging the two already
    16681625                         * present intervals.
    1669                          *
    16701626                         */
    16711627                        leaf->value[leaf->keys - 1] += count + right_cnt;
    16721628                        btree_remove(&area->used_space, right_pg, node);
    1673                         return 1;
    1674                 } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1629                        goto success;
     1630                } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
    16751631                        /*
    16761632                         * The interval can be added by simply growing the left
    16771633                         * interval.
    1678                          *
    16791634                         */
    1680                         leaf->value[leaf->keys - 1] +=  count;
    1681                         return 1;
    1682                 } else if (page + count * PAGE_SIZE == right_pg) {
     1635                        leaf->value[leaf->keys - 1] += count;
     1636                        goto success;
     1637                } else if (page + (count << PAGE_WIDTH) == right_pg) {
    16831638                        /*
    16841639                         * The interval can be addded by simply moving base of
    16851640                         * the right interval down and increasing its size
    16861641                         * accordingly.
    1687                          *
    16881642                         */
    16891643                        node->value[0] += count;
    16901644                        node->key[0] = page;
    1691                         return 1;
     1645                        goto success;
    16921646                } else {
    16931647                        /*
    16941648                         * The interval is between both neigbouring intervals,
    16951649                         * but cannot be merged with any of them.
    1696                          *
    16971650                         */
    16981651                        btree_insert(&area->used_space, page, (void *) count,
    16991652                            leaf);
    1700                         return 1;
     1653                        goto success;
    17011654                }
    17021655        } else if (page >= leaf->key[leaf->keys - 1]) {
     
    17071660                 * Investigate the border case in which the right neighbour
    17081661                 * does not exist but the interval fits from the right.
    1709                  *
    1710                  */
    1711                
    1712                 if (overlaps(page, count * PAGE_SIZE, left_pg,
    1713                     left_cnt * PAGE_SIZE)) {
     1662                 */
     1663               
     1664                if (overlaps(page, count << PAGE_WIDTH, left_pg,
     1665                    left_cnt << PAGE_WIDTH)) {
    17141666                        /* The interval intersects with the left interval. */
    1715                         return 0;
    1716                 } else if (left_pg + left_cnt * PAGE_SIZE == page) {
     1667                        return false;
     1668                } else if (left_pg + (left_cnt << PAGE_WIDTH) == page) {
    17171669                        /*
    17181670                         * The interval can be added by growing the left
    17191671                         * interval.
    1720                          *
    17211672                         */
    17221673                        leaf->value[leaf->keys - 1] += count;
    1723                         return 1;
     1674                        goto success;
    17241675                } else {
    17251676                        /*
    17261677                         * The interval doesn't adjoin with the left interval.
    17271678                         * It must be added individually.
    1728                          *
    17291679                         */
    17301680                        btree_insert(&area->used_space, page, (void *) count,
    17311681                            leaf);
    1732                         return 1;
     1682                        goto success;
    17331683                }
    17341684        }
     
    17381688         * only between two other intervals of the leaf. The two border cases
    17391689         * were already resolved.
    1740          *
    17411690         */
    17421691        btree_key_t i;
     
    17501699                        /*
    17511700                         * The interval fits between left_pg and right_pg.
    1752                          *
    17531701                         */
    17541702                       
    1755                         if (overlaps(page, count * PAGE_SIZE, left_pg,
    1756                             left_cnt * PAGE_SIZE)) {
     1703                        if (overlaps(page, count << PAGE_WIDTH, left_pg,
     1704                            left_cnt << PAGE_WIDTH)) {
    17571705                                /*
    17581706                                 * The interval intersects with the left
    17591707                                 * interval.
    1760                                  *
    17611708                                 */
    1762                                 return 0;
    1763                         } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1764                             right_cnt * PAGE_SIZE)) {
     1709                                return false;
     1710                        } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
     1711                            right_cnt << PAGE_WIDTH)) {
    17651712                                /*
    17661713                                 * The interval intersects with the right
    17671714                                 * interval.
    1768                                  *
    17691715                                 */
    1770                                 return 0;
    1771                         } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1772                             (page + count * PAGE_SIZE == right_pg)) {
     1716                                return false;
     1717                        } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
     1718                            (page + (count << PAGE_WIDTH) == right_pg)) {
    17731719                                /*
    17741720                                 * The interval can be added by merging the two
    17751721                                 * already present intervals.
    1776                                  *
    17771722                                 */
    17781723                                leaf->value[i - 1] += count + right_cnt;
    17791724                                btree_remove(&area->used_space, right_pg, leaf);
    1780                                 return 1;
    1781                         } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1725                                goto success;
     1726                        } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
    17821727                                /*
    17831728                                 * The interval can be added by simply growing
    17841729                                 * the left interval.
    1785                                  *
    17861730                                 */
    17871731                                leaf->value[i - 1] += count;
    1788                                 return 1;
    1789                         } else if (page + count * PAGE_SIZE == right_pg) {
     1732                                goto success;
     1733                        } else if (page + (count << PAGE_WIDTH) == right_pg) {
    17901734                                /*
    17911735                                 * The interval can be addded by simply moving
    17921736                                 * base of the right interval down and
    17931737                                 * increasing its size accordingly.
    1794                                  *
    17951738                                 */
    17961739                                leaf->value[i] += count;
    17971740                                leaf->key[i] = page;
    1798                                 return 1;
     1741                                goto success;
    17991742                        } else {
    18001743                                /*
     
    18021745                                 * intervals, but cannot be merged with any of
    18031746                                 * them.
    1804                                  *
    18051747                                 */
    18061748                                btree_insert(&area->used_space, page,
    18071749                                    (void *) count, leaf);
    1808                                 return 1;
     1750                                goto success;
    18091751                        }
    18101752                }
     
    18131755        panic("Inconsistency detected while adding %zu pages of used "
    18141756            "space at %p.", count, (void *) page);
     1757       
     1758success:
     1759        area->resident += count;
     1760        return true;
    18151761}
    18161762
     
    18231769 * @param count Number of page to be marked.
    18241770 *
    1825  * @return Zero on failure and non-zero on success.
    1826  *
    1827  */
    1828 int used_space_remove(as_area_t *area, uintptr_t page, size_t count)
     1771 * @return False on failure or true on success.
     1772 *
     1773 */
     1774bool used_space_remove(as_area_t *area, uintptr_t page, size_t count)
    18291775{
    18301776        ASSERT(mutex_locked(&area->lock));
     
    18371783                /*
    18381784                 * We are lucky, page is the beginning of some interval.
    1839                  *
    18401785                 */
    18411786                if (count > pages) {
    1842                         return 0;
     1787                        return false;
    18431788                } else if (count == pages) {
    18441789                        btree_remove(&area->used_space, page, leaf);
    1845                         return 1;
     1790                        goto success;
    18461791                } else {
    18471792                        /*
    18481793                         * Find the respective interval.
    18491794                         * Decrease its size and relocate its start address.
    1850                          *
    18511795                         */
    18521796                        btree_key_t i;
    18531797                        for (i = 0; i < leaf->keys; i++) {
    18541798                                if (leaf->key[i] == page) {
    1855                                         leaf->key[i] += count * PAGE_SIZE;
     1799                                        leaf->key[i] += count << PAGE_WIDTH;
    18561800                                        leaf->value[i] -= count;
    1857                                         return 1;
     1801                                        goto success;
    18581802                                }
    18591803                        }
     1804                       
    18601805                        goto error;
    18611806                }
     
    18671812                size_t left_cnt = (size_t) node->value[node->keys - 1];
    18681813               
    1869                 if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    1870                     count * PAGE_SIZE)) {
    1871                         if (page + count * PAGE_SIZE ==
    1872                             left_pg + left_cnt * PAGE_SIZE) {
     1814                if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
     1815                    count << PAGE_WIDTH)) {
     1816                        if (page + (count << PAGE_WIDTH) ==
     1817                            left_pg + (left_cnt << PAGE_WIDTH)) {
    18731818                                /*
    18741819                                 * The interval is contained in the rightmost
     
    18761821                                 * removed by updating the size of the bigger
    18771822                                 * interval.
    1878                                  *
    18791823                                 */
    18801824                                node->value[node->keys - 1] -= count;
    1881                                 return 1;
    1882                         } else if (page + count * PAGE_SIZE <
    1883                             left_pg + left_cnt*PAGE_SIZE) {
     1825                                goto success;
     1826                        } else if (page + (count << PAGE_WIDTH) <
     1827                            left_pg + (left_cnt << PAGE_WIDTH)) {
    18841828                                /*
    18851829                                 * The interval is contained in the rightmost
     
    18881832                                 * the original interval and also inserting a
    18891833                                 * new interval.
    1890                                  *
    18911834                                 */
    1892                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    1893                                     (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
     1835                                size_t new_cnt = ((left_pg + (left_cnt << PAGE_WIDTH)) -
     1836                                    (page + (count << PAGE_WIDTH))) >> PAGE_WIDTH;
    18941837                                node->value[node->keys - 1] -= count + new_cnt;
    18951838                                btree_insert(&area->used_space, page +
    1896                                     count * PAGE_SIZE, (void *) new_cnt, leaf);
    1897                                 return 1;
     1839                                    (count << PAGE_WIDTH), (void *) new_cnt, leaf);
     1840                                goto success;
    18981841                        }
    18991842                }
    1900                 return 0;
     1843               
     1844                return false;
    19011845        } else if (page < leaf->key[0])
    1902                 return 0;
     1846                return false;
    19031847       
    19041848        if (page > leaf->key[leaf->keys - 1]) {
     
    19061850                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    19071851               
    1908                 if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    1909                     count * PAGE_SIZE)) {
    1910                         if (page + count * PAGE_SIZE ==
    1911                             left_pg + left_cnt * PAGE_SIZE) {
     1852                if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
     1853                    count << PAGE_WIDTH)) {
     1854                        if (page + (count << PAGE_WIDTH) ==
     1855                            left_pg + (left_cnt << PAGE_WIDTH)) {
    19121856                                /*
    19131857                                 * The interval is contained in the rightmost
    19141858                                 * interval of the leaf and can be removed by
    19151859                                 * updating the size of the bigger interval.
    1916                                  *
    19171860                                 */
    19181861                                leaf->value[leaf->keys - 1] -= count;
    1919                                 return 1;
    1920                         } else if (page + count * PAGE_SIZE < left_pg +
    1921                             left_cnt * PAGE_SIZE) {
     1862                                goto success;
     1863                        } else if (page + (count << PAGE_WIDTH) < left_pg +
     1864                            (left_cnt << PAGE_WIDTH)) {
    19221865                                /*
    19231866                                 * The interval is contained in the rightmost
     
    19261869                                 * original interval and also inserting a new
    19271870                                 * interval.
    1928                                  *
    19291871                                 */
    1930                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    1931                                     (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
     1872                                size_t new_cnt = ((left_pg + (left_cnt << PAGE_WIDTH)) -
     1873                                    (page + (count << PAGE_WIDTH))) >> PAGE_WIDTH;
    19321874                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    19331875                                btree_insert(&area->used_space, page +
    1934                                     count * PAGE_SIZE, (void *) new_cnt, leaf);
    1935                                 return 1;
     1876                                    (count << PAGE_WIDTH), (void *) new_cnt, leaf);
     1877                                goto success;
    19361878                        }
    19371879                }
    1938                 return 0;
     1880               
     1881                return false;
    19391882        }
    19401883       
    19411884        /*
    19421885         * The border cases have been already resolved.
    1943          * Now the interval can be only between intervals of the leaf. 
     1886         * Now the interval can be only between intervals of the leaf.
    19441887         */
    19451888        btree_key_t i;
     
    19531896                         * to (i - 1) and i.
    19541897                         */
    1955                         if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    1956                             count * PAGE_SIZE)) {
    1957                                 if (page + count * PAGE_SIZE ==
    1958                                     left_pg + left_cnt*PAGE_SIZE) {
     1898                        if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
     1899                            count << PAGE_WIDTH)) {
     1900                                if (page + (count << PAGE_WIDTH) ==
     1901                                    left_pg + (left_cnt << PAGE_WIDTH)) {
    19591902                                        /*
    19601903                                         * The interval is contained in the
     
    19621905                                         * be removed by updating the size of
    19631906                                         * the bigger interval.
    1964                                          *
    19651907                                         */
    19661908                                        leaf->value[i - 1] -= count;
    1967                                         return 1;
    1968                                 } else if (page + count * PAGE_SIZE <
    1969                                     left_pg + left_cnt * PAGE_SIZE) {
     1909                                        goto success;
     1910                                } else if (page + (count << PAGE_WIDTH) <
     1911                                    left_pg + (left_cnt << PAGE_WIDTH)) {
    19701912                                        /*
    19711913                                         * The interval is contained in the
     
    19761918                                         */
    19771919                                        size_t new_cnt = ((left_pg +
    1978                                             left_cnt * PAGE_SIZE) -
    1979                                             (page + count * PAGE_SIZE)) >>
     1920                                            (left_cnt << PAGE_WIDTH)) -
     1921                                            (page + (count << PAGE_WIDTH))) >>
    19801922                                            PAGE_WIDTH;
    19811923                                        leaf->value[i - 1] -= count + new_cnt;
    19821924                                        btree_insert(&area->used_space, page +
    1983                                             count * PAGE_SIZE, (void *) new_cnt,
     1925                                            (count << PAGE_WIDTH), (void *) new_cnt,
    19841926                                            leaf);
    1985                                         return 1;
     1927                                        goto success;
    19861928                                }
    19871929                        }
    1988                         return 0;
     1930                       
     1931                        return false;
    19891932                }
    19901933        }
     
    19931936        panic("Inconsistency detected while removing %zu pages of used "
    19941937            "space from %p.", count, (void *) page);
     1938       
     1939success:
     1940        area->resident -= count;
     1941        return true;
    19951942}
    19961943
     
    20271974}
    20281975
     1976/** Return pointer to unmapped address space area
     1977 *
     1978 * @param base Lowest address bound.
     1979 * @param size Requested size of the allocation.
     1980 *
     1981 * @return Pointer to the beginning of unmapped address space area.
     1982 *
     1983 */
     1984sysarg_t sys_as_get_unmapped_area(uintptr_t base, size_t size)
     1985{
     1986        if (size == 0)
     1987                return 0;
     1988       
     1989        /*
     1990         * Make sure we allocate from page-aligned
     1991         * address. Check for possible overflow in
     1992         * each step.
     1993         */
     1994       
     1995        size_t pages = SIZE2FRAMES(size);
     1996        uintptr_t ret = 0;
     1997       
     1998        /*
     1999         * Find the lowest unmapped address aligned on the sz
     2000         * boundary, not smaller than base and of the required size.
     2001         */
     2002       
     2003        mutex_lock(&AS->lock);
     2004       
     2005        /* First check the base address itself */
     2006        uintptr_t addr = ALIGN_UP(base, PAGE_SIZE);
     2007        if ((addr >= base) &&
     2008            (check_area_conflicts(AS, addr, pages, NULL)))
     2009                ret = addr;
     2010       
     2011        /* Eventually check the addresses behind each area */
     2012        link_t *cur;
     2013        for (cur = AS->as_area_btree.leaf_head.next;
     2014            (ret == 0) && (cur != &AS->as_area_btree.leaf_head);
     2015            cur = cur->next) {
     2016                btree_node_t *node =
     2017                    list_get_instance(cur, btree_node_t, leaf_link);
     2018               
     2019                btree_key_t i;
     2020                for (i = 0; (ret == 0) && (i < node->keys); i++) {
     2021                        as_area_t *area = (as_area_t *) node->value[i];
     2022                       
     2023                        mutex_lock(&area->lock);
     2024                       
     2025                        uintptr_t addr =
     2026                            ALIGN_UP(area->base + (area->pages << PAGE_WIDTH),
     2027                            PAGE_SIZE);
     2028                       
     2029                        if ((addr >= base) && (addr >= area->base) &&
     2030                            (check_area_conflicts(AS, addr, pages, area)))
     2031                                ret = addr;
     2032                       
     2033                        mutex_unlock(&area->lock);
     2034                }
     2035        }
     2036       
     2037        mutex_unlock(&AS->lock);
     2038       
     2039        return (sysarg_t) ret;
     2040}
     2041
    20292042/** Get list of adress space areas.
    20302043 *
     
    20932106        mutex_lock(&as->lock);
    20942107       
    2095         /* print out info about address space areas */
     2108        /* Print out info about address space areas */
    20962109        link_t *cur;
    20972110        for (cur = as->as_area_btree.leaf_head.next;
  • kernel/generic/src/mm/backend_phys.c

    r6e50466 rad7a6c9  
    8181        page_mapping_insert(AS, addr, base + (addr - area->base),
    8282            as_area_get_flags(area));
    83         if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
    84                 panic("Cannot insert used space.");
     83       
     84        if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
     85                panic("Cannot insert used space.");
    8586
    8687        return AS_PF_OK;
  • kernel/generic/src/mm/slab.c

    r6e50466 rad7a6c9  
    806806}
    807807
    808 /** Go through all caches and reclaim what is possible
    809  *
    810  * Interrupts must be disabled before calling this function,
    811  * otherwise  memory allocation from interrupts can deadlock.
    812  *
    813  */
     808/** Go through all caches and reclaim what is possible */
    814809size_t slab_reclaim(unsigned int flags)
    815810{
    816         irq_spinlock_lock(&slab_cache_lock, false);
     811        irq_spinlock_lock(&slab_cache_lock, true);
    817812       
    818813        size_t frames = 0;
     
    824819        }
    825820       
    826         irq_spinlock_unlock(&slab_cache_lock, false);
     821        irq_spinlock_unlock(&slab_cache_lock, true);
    827822       
    828823        return frames;
  • kernel/generic/src/proc/program.c

    r6e50466 rad7a6c9  
    171171        void *loader = program_loader;
    172172        if (!loader) {
     173                as_destroy(as);
    173174                printf("Cannot spawn loader as none was registered\n");
    174175                return ENOENT;
     
    179180        if (rc != EE_OK) {
    180181                as_destroy(as);
     182                printf("Cannot spawn loader (%s)\n", elf_error(rc));
    181183                return ENOENT;
    182184        }
  • kernel/generic/src/proc/scheduler.c

    r6e50466 rad7a6c9  
    6262#include <print.h>
    6363#include <debug.h>
    64 
    65 static void before_task_runs(void);
    66 static void before_thread_runs(void);
    67 static void after_thread_ran(void);
     64#include <stacktrace.h>
     65
    6866static void scheduler_separated_stack(void);
    6967
     
    7169
    7270/** Carry out actions before new task runs. */
    73 void before_task_runs(void)
     71static void before_task_runs(void)
    7472{
    7573        before_task_runs_arch();
     
    8078 * Perform actions that need to be
    8179 * taken before the newly selected
    82  * tread is passed control.
     80 * thread is passed control.
    8381 *
    8482 * THREAD->lock is locked on entry
    8583 *
    8684 */
    87 void before_thread_runs(void)
     85static void before_thread_runs(void)
    8886{
    8987        before_thread_runs_arch();
     88       
    9089#ifdef CONFIG_FPU_LAZY
    91         if(THREAD == CPU->fpu_owner)
     90        if (THREAD == CPU->fpu_owner)
    9291                fpu_enable();
    9392        else
     
    102101        }
    103102#endif
     103       
     104#ifdef CONFIG_UDEBUG
     105        if (THREAD->btrace) {
     106                istate_t *istate = THREAD->udebug.uspace_state;
     107                if (istate != NULL) {
     108                        printf("Thread %" PRIu64 " stack trace:\n", THREAD->tid);
     109                        stack_trace_istate(istate);
     110                }
     111               
     112                THREAD->btrace = false;
     113        }
     114#endif
    104115}
    105116
     
    113124 *
    114125 */
    115 void after_thread_ran(void)
     126static void after_thread_ran(void)
    116127{
    117128        after_thread_ran_arch();
     
    391402         * possible destruction should thread_destroy() be called on this or any
    392403         * other processor while the scheduler is still using them.
    393          *
    394404         */
    395405        if (old_task)
     
    417427                                 * The thread structure is kept allocated until
    418428                                 * somebody calls thread_detach() on it.
    419                                  *
    420429                                 */
    421430                                if (!irq_spinlock_trylock(&THREAD->join_wq.lock)) {
    422431                                        /*
    423432                                         * Avoid deadlock.
    424                                          *
    425433                                         */
    426434                                        irq_spinlock_unlock(&THREAD->lock, false);
     
    443451                        /*
    444452                         * Prefer the thread after it's woken up.
    445                          *
    446453                         */
    447454                        THREAD->priority = -1;
     
    451458                         * waitq_sleep(). Address of wq->lock is kept in
    452459                         * THREAD->sleep_queue.
    453                          *
    454460                         */
    455461                        irq_spinlock_unlock(&THREAD->sleep_queue->lock, false);
     
    461467                        /*
    462468                         * Entering state is unexpected.
    463                          *
    464469                         */
    465470                        panic("tid%" PRIu64 ": unexpected state %s.",
     
    480485       
    481486        /*
    482          * If both the old and the new task are the same, lots of work is
    483          * avoided.
    484          *
     487         * If both the old and the new task are the same,
     488         * lots of work is avoided.
    485489         */
    486490        if (TASK != THREAD->task) {
     
    488492               
    489493                /*
    490                  * Note that it is possible for two tasks to share one address
    491                  * space.
    492                  (
     494                 * Note that it is possible for two tasks
     495                 * to share one address space.
    493496                 */
    494497                if (old_as != new_as) {
     
    496499                         * Both tasks and address spaces are different.
    497500                         * Replace the old one with the new one.
    498                          *
    499501                         */
    500502                        as_switch(old_as, new_as);
     
    527529         * necessary, is to be mapped in before_thread_runs(). This
    528530         * function must be executed before the switch to the new stack.
    529          *
    530531         */
    531532        before_thread_runs();
     
    534535         * Copy the knowledge of CPU, TASK, THREAD and preemption counter to
    535536         * thread's stack.
    536          *
    537537         */
    538538        the_copy(THE, (the_t *) THREAD->kstack);
     
    658658                                /*
    659659                                 * Ready thread on local CPU
    660                                  *
    661660                                 */
    662661                               
  • kernel/generic/src/proc/task.c

    r6e50466 rad7a6c9  
    342342sysarg_t sys_task_set_name(const char *uspace_name, size_t name_len)
    343343{
    344         int rc;
    345344        char namebuf[TASK_NAME_BUFLEN];
    346345       
    347346        /* Cap length of name and copy it from userspace. */
    348        
    349347        if (name_len > TASK_NAME_BUFLEN - 1)
    350348                name_len = TASK_NAME_BUFLEN - 1;
    351349       
    352         rc = copy_from_uspace(namebuf, uspace_name, name_len);
     350        int rc = copy_from_uspace(namebuf, uspace_name, name_len);
    353351        if (rc != 0)
    354352                return (sysarg_t) rc;
    355353       
    356354        namebuf[name_len] = '\0';
     355       
     356        /*
     357         * As the task name is referenced also from the
     358         * threads, lock the threads' lock for the course
     359         * of the update.
     360         */
     361       
     362        irq_spinlock_lock(&tasks_lock, true);
     363        irq_spinlock_lock(&TASK->lock, false);
     364        irq_spinlock_lock(&threads_lock, false);
     365       
     366        /* Set task name */
    357367        str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
    358368       
     369        irq_spinlock_unlock(&threads_lock, false);
     370        irq_spinlock_unlock(&TASK->lock, false);
     371        irq_spinlock_unlock(&tasks_lock, true);
     372       
    359373        return EOK;
     374}
     375
     376/** Syscall to forcefully terminate a task
     377 *
     378 * @param uspace_taskid Pointer to task ID in user space.
     379 *
     380 * @return 0 on success or an error code from @ref errno.h.
     381 *
     382 */
     383sysarg_t sys_task_kill(task_id_t *uspace_taskid)
     384{
     385        task_id_t taskid;
     386        int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(taskid));
     387        if (rc != 0)
     388                return (sysarg_t) rc;
     389       
     390        return (sysarg_t) task_kill(taskid);
    360391}
    361392
     
    430461static void task_kill_internal(task_t *task)
    431462{
     463        irq_spinlock_lock(&task->lock, false);
     464        irq_spinlock_lock(&threads_lock, false);
     465       
     466        /*
     467         * Interrupt all threads.
     468         */
     469       
    432470        link_t *cur;
    433        
    434         /*
    435          * Interrupt all threads.
    436          */
    437         irq_spinlock_lock(&task->lock, false);
    438471        for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
    439472                thread_t *thread = list_get_instance(cur, thread_t, th_link);
     
    452485        }
    453486       
     487        irq_spinlock_unlock(&threads_lock, false);
    454488        irq_spinlock_unlock(&task->lock, false);
    455489}
     
    481515        irq_spinlock_unlock(&tasks_lock, true);
    482516       
     517        return EOK;
     518}
     519
     520/** Kill the currently running task.
     521 *
     522 * @param notify Send out fault notifications.
     523 *
     524 * @return Zero on success or an error code from errno.h.
     525 *
     526 */
     527void task_kill_self(bool notify)
     528{
     529        /*
     530         * User space can subscribe for FAULT events to take action
     531         * whenever a task faults (to take a dump, run a debugger, etc.).
     532         * The notification is always available, but unless udebug is enabled,
     533         * that's all you get.
     534        */
     535        if (notify) {
     536                if (event_is_subscribed(EVENT_FAULT)) {
     537                        /* Notify the subscriber that a fault occurred. */
     538                        event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),
     539                            UPPER32(TASK->taskid), (sysarg_t) THREAD);
     540               
     541#ifdef CONFIG_UDEBUG
     542                        /* Wait for a debugging session. */
     543                        udebug_thread_fault();
     544#endif
     545                }
     546        }
     547       
     548        irq_spinlock_lock(&tasks_lock, true);
     549        task_kill_internal(TASK);
     550        irq_spinlock_unlock(&tasks_lock, true);
     551       
     552        thread_exit();
     553}
     554
     555/** Process syscall to terminate the current task.
     556 *
     557 * @param notify Send out fault notifications.
     558 *
     559 */
     560sysarg_t sys_task_exit(sysarg_t notify)
     561{
     562        task_kill_self(notify);
     563       
     564        /* Unreachable */
    483565        return EOK;
    484566}
  • kernel/generic/src/proc/thread.c

    r6e50466 rad7a6c9  
    239239 * Switch thread to the ready state.
    240240 *
    241  * @param t Thread to make ready.
     241 * @param thread Thread to make ready.
    242242 *
    243243 */
     
    246246        irq_spinlock_lock(&thread->lock, true);
    247247       
    248         ASSERT(!(thread->state == Ready));
     248        ASSERT(thread->state != Ready);
    249249       
    250250        int i = (thread->priority < RQ_COUNT - 1)
     
    350350       
    351351#ifdef CONFIG_UDEBUG
    352         /* Init debugging stuff */
     352        /* Initialize debugging stuff */
     353        thread->btrace = false;
    353354        udebug_thread_initialize(&thread->udebug);
    354355#endif
     
    535536/** Detach thread.
    536537 *
    537  * Mark the thread as detached, if the thread is already in the Lingering
    538  * state, deallocate its resources.
     538 * Mark the thread as detached. If the thread is already
     539 * in the Lingering state, deallocate its resources.
    539540 *
    540541 * @param thread Thread to be detached.
     
    590591        order_suffix(thread->kcycles, &kcycles, &ksuffix);
    591592       
     593        char *name;
     594        if (str_cmp(thread->name, "uinit") == 0)
     595                name = thread->task->name;
     596        else
     597                name = thread->name;
     598       
    592599#ifdef __32_BITS__
    593600        if (*additional)
    594                 printf("%-8" PRIu64" %10p %9" PRIu64 "%c %9" PRIu64 "%c ",
    595                     thread->tid, thread->kstack, ucycles, usuffix,
    596                     kcycles, ksuffix);
     601                printf("%-8" PRIu64 " %10p %10p %9" PRIu64 "%c %9" PRIu64 "%c ",
     602                    thread->tid, thread->thread_code, thread->kstack,
     603                    ucycles, usuffix, kcycles, ksuffix);
    597604        else
    598                 printf("%-8" PRIu64" %-14s %10p %-8s %10p %-5" PRIu32 " %10p\n",
    599                     thread->tid, thread->name, thread, thread_states[thread->state],
    600                     thread->task, thread->task->context, thread->thread_code);
     605                printf("%-8" PRIu64 " %-14s %10p %-8s %10p %-5" PRIu32 "\n",
     606                    thread->tid, name, thread, thread_states[thread->state],
     607                    thread->task, thread->task->context);
    601608#endif
    602609       
    603610#ifdef __64_BITS__
    604611        if (*additional)
    605                 printf("%-8" PRIu64" %18p %18p\n"
     612                printf("%-8" PRIu64 " %18p %18p\n"
    606613                    "         %9" PRIu64 "%c %9" PRIu64 "%c ",
    607614                    thread->tid, thread->thread_code, thread->kstack,
    608615                    ucycles, usuffix, kcycles, ksuffix);
    609616        else
    610                 printf("%-8" PRIu64" %-14s %18p %-8s %18p %-5" PRIu32 "\n",
    611                     thread->tid, thread->name, thread, thread_states[thread->state],
     617                printf("%-8" PRIu64 " %-14s %18p %-8s %18p %-5" PRIu32 "\n",
     618                    thread->tid, name, thread, thread_states[thread->state],
    612619                    thread->task, thread->task->context);
    613620#endif
     
    647654#ifdef __32_BITS__
    648655        if (additional)
    649                 printf("[id    ] [stack   ] [ucycles ] [kcycles ] [cpu]"
    650                     " [waitqueue]\n");
     656                printf("[id    ] [code    ] [stack   ] [ucycles ] [kcycles ]"
     657                    " [cpu] [waitqueue]\n");
    651658        else
    652659                printf("[id    ] [name        ] [address ] [state ] [task    ]"
    653                     " [ctx] [code    ]\n");
     660                    " [ctx]\n");
    654661#endif
    655662       
     
    740747        ASSERT(interrupts_disabled());
    741748        ASSERT(irq_spinlock_locked(&threads_lock));
    742 
     749       
    743750        thread_iterator_t iterator;
    744751       
     
    751758}
    752759
     760#ifdef CONFIG_UDEBUG
     761
     762void thread_stack_trace(thread_id_t thread_id)
     763{
     764        irq_spinlock_lock(&threads_lock, true);
     765       
     766        thread_t *thread = thread_find_by_id(thread_id);
     767        if (thread == NULL) {
     768                printf("No such thread.\n");
     769                irq_spinlock_unlock(&threads_lock, true);
     770                return;
     771        }
     772       
     773        irq_spinlock_lock(&thread->lock, false);
     774       
     775        /*
     776         * Schedule a stack trace to be printed
     777         * just before the thread is scheduled next.
     778         *
     779         * If the thread is sleeping then try to interrupt
     780         * the sleep. Any request for printing an uspace stack
     781         * trace from within the kernel should be always
     782         * considered a last resort debugging means, therefore
     783         * forcing the thread's sleep to be interrupted
     784         * is probably justifiable.
     785         */
     786       
     787        bool sleeping = false;
     788        istate_t *istate = thread->udebug.uspace_state;
     789        if (istate != NULL) {
     790                printf("Scheduling thread stack trace.\n");
     791                thread->btrace = true;
     792                if (thread->state == Sleeping)
     793                        sleeping = true;
     794        } else
     795                printf("Thread interrupt state not available.\n");
     796       
     797        irq_spinlock_unlock(&thread->lock, false);
     798       
     799        if (sleeping)
     800                waitq_interrupt_sleep(thread);
     801       
     802        irq_spinlock_unlock(&threads_lock, true);
     803}
     804
     805#endif /* CONFIG_UDEBUG */
    753806
    754807/** Process syscall to create new thread.
     
    793846                                 * has already been created. We need to undo its
    794847                                 * creation now.
    795                                  *
    796848                                 */
    797849                               
     
    815867                 * THREAD_B events for threads that already existed
    816868                 * and could be detected with THREAD_READ before.
    817                  *
    818869                 */
    819870                udebug_thread_b_event_attach(thread, TASK);
  • kernel/generic/src/synch/waitq.c

    r6e50466 rad7a6c9  
    127127/** Interrupt sleeping thread.
    128128 *
    129  * This routine attempts to interrupt a thread from its sleep in a waitqueue.
    130  * If the thread is not found sleeping, no action is taken.
     129 * This routine attempts to interrupt a thread from its sleep in
     130 * a waitqueue. If the thread is not found sleeping, no action
     131 * is taken.
     132 *
     133 * The threads_lock must be already held and interrupts must be
     134 * disabled upon calling this function.
    131135 *
    132136 * @param thread Thread to be interrupted.
     
    138142        DEADLOCK_PROBE_INIT(p_wqlock);
    139143       
    140         irq_spinlock_lock(&threads_lock, true);
    141         if (!thread_exists(thread))
    142                 goto out;
     144        /*
     145         * The thread is quaranteed to exist because
     146         * threads_lock is held.
     147         */
    143148       
    144149grab_locks:
     
    150155                        /*
    151156                         * The sleep cannot be interrupted.
    152                          *
    153157                         */
    154158                        irq_spinlock_unlock(&thread->lock, false);
    155                         goto out;
     159                        return;
    156160                }
    157161               
    158162                if (!irq_spinlock_trylock(&wq->lock)) {
     163                        /* Avoid deadlock */
    159164                        irq_spinlock_unlock(&thread->lock, false);
    160165                        DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD);
    161                         /* Avoid deadlock */
    162166                        goto grab_locks;
    163167                }
     
    173177                irq_spinlock_unlock(&wq->lock, false);
    174178        }
     179       
    175180        irq_spinlock_unlock(&thread->lock, false);
    176181       
    177182        if (do_wakeup)
    178183                thread_ready(thread);
    179        
    180 out:
    181         irq_spinlock_unlock(&threads_lock, true);
    182184}
    183185
     
    370372                 * If the thread was already interrupted,
    371373                 * don't go to sleep at all.
    372                  *
    373374                 */
    374375                if (THREAD->interrupted) {
     
    381382                 * Set context that will be restored if the sleep
    382383                 * of this thread is ever interrupted.
    383                  *
    384384                 */
    385385                THREAD->sleep_interruptible = true;
  • kernel/generic/src/syscall/syscall.c

    r6e50466 rad7a6c9  
    4545#include <debug.h>
    4646#include <ddi/device.h>
     47#include <interrupt.h>
    4748#include <ipc/sysipc.h>
    4849#include <synch/futex.h>
     
    6667#ifdef CONFIG_UDEBUG
    6768        /*
     69         * An istate_t-compatible record was created on the stack by the
     70         * low-level syscall handler. This is the userspace space state
     71         * structure.
     72         */
     73        THREAD->udebug.uspace_state = istate_get(THREAD);
     74
     75        /*
    6876         * Early check for undebugged tasks. We do not lock anything as this
    6977         * test need not be precise in either direction.
    70          *
    7178         */
    7279        if (THREAD->udebug.active)
     
    7986        } else {
    8087                printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
    81                 task_kill(TASK->taskid);
    82                 thread_exit();
     88                task_kill_self(true);
    8389        }
    8490       
     
    98104                udebug_stoppable_end();
    99105        }
     106
     107        /* Clear userspace state pointer */
     108        THREAD->udebug.uspace_state = NULL;
    100109#endif
    101110       
     
    120129        (syshandler_t) sys_task_get_id,
    121130        (syshandler_t) sys_task_set_name,
     131        (syshandler_t) sys_task_kill,
     132        (syshandler_t) sys_task_exit,
    122133        (syshandler_t) sys_program_spawn_loader,
    123134       
     
    132143        (syshandler_t) sys_as_area_change_flags,
    133144        (syshandler_t) sys_as_area_destroy,
     145        (syshandler_t) sys_as_get_unmapped_area,
    134146       
    135147        /* IPC related syscalls. */
     
    145157        (syshandler_t) sys_ipc_poke,
    146158        (syshandler_t) sys_ipc_hangup,
    147         (syshandler_t) sys_ipc_register_irq,
    148         (syshandler_t) sys_ipc_unregister_irq,
    149159        (syshandler_t) sys_ipc_connect_kbox,
    150160       
     
    160170        (syshandler_t) sys_physmem_map,
    161171        (syshandler_t) sys_iospace_enable,
    162         (syshandler_t) sys_interrupt_enable,
     172        (syshandler_t) sys_register_irq,
     173        (syshandler_t) sys_unregister_irq,
    163174       
    164175        /* Sysinfo syscalls */
  • kernel/generic/src/sysinfo/stats.c

    r6e50466 rad7a6c9  
    160160static size_t get_task_virtmem(as_t *as)
    161161{
    162         size_t result = 0;
    163 
    164162        /*
    165          * We are holding some spinlocks here and therefore are not allowed to
    166          * block. Only attempt to lock the address space and address space area
    167          * mutexes conditionally. If it is not possible to lock either object,
    168          * allow the statistics to be inexact by skipping the respective object.
    169          *
    170          * Note that it may be infinitely better to let the address space
    171          * management code compute these statistics as it proceeds instead of
    172          * having them calculated here over and over again here.
     163         * We are holding spinlocks here and therefore are not allowed to
     164         * block. Only attempt to lock the address space and address space
     165         * area mutexes conditionally. If it is not possible to lock either
     166         * object, return inexact statistics by skipping the respective object.
    173167         */
    174 
     168       
    175169        if (SYNCH_FAILED(mutex_trylock(&as->lock)))
    176                 return result * PAGE_SIZE;
     170                return 0;
     171       
     172        size_t pages = 0;
    177173       
    178174        /* Walk the B+ tree and count pages */
     
    189185                        if (SYNCH_FAILED(mutex_trylock(&area->lock)))
    190186                                continue;
    191                         result += area->pages;
     187                       
     188                        pages += area->pages;
    192189                        mutex_unlock(&area->lock);
    193190                }
     
    196193        mutex_unlock(&as->lock);
    197194       
    198         return result * PAGE_SIZE;
     195        return (pages << PAGE_WIDTH);
     196}
     197
     198/** Get the resident (used) size of a virtual address space
     199 *
     200 * @param as Address space.
     201 *
     202 * @return Size of the resident (used) virtual address space (bytes).
     203 *
     204 */
     205static size_t get_task_resmem(as_t *as)
     206{
     207        /*
     208         * We are holding spinlocks here and therefore are not allowed to
     209         * block. Only attempt to lock the address space and address space
     210         * area mutexes conditionally. If it is not possible to lock either
     211         * object, return inexact statistics by skipping the respective object.
     212         */
     213       
     214        if (SYNCH_FAILED(mutex_trylock(&as->lock)))
     215                return 0;
     216       
     217        size_t pages = 0;
     218       
     219        /* Walk the B+ tree and count pages */
     220        link_t *cur;
     221        for (cur = as->as_area_btree.leaf_head.next;
     222            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
     223                btree_node_t *node =
     224                    list_get_instance(cur, btree_node_t, leaf_link);
     225               
     226                unsigned int i;
     227                for (i = 0; i < node->keys; i++) {
     228                        as_area_t *area = node->value[i];
     229                       
     230                        if (SYNCH_FAILED(mutex_trylock(&area->lock)))
     231                                continue;
     232                       
     233                        pages += area->resident;
     234                        mutex_unlock(&area->lock);
     235                }
     236        }
     237       
     238        mutex_unlock(&as->lock);
     239       
     240        return (pages << PAGE_WIDTH);
    199241}
    200242
     
    215257        str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name);
    216258        stats_task->virtmem = get_task_virtmem(task->as);
     259        stats_task->resmem = get_task_resmem(task->as);
    217260        stats_task->threads = atomic_get(&task->refcount);
    218261        task_get_accounting(task, &(stats_task->ucycles),
  • kernel/generic/src/sysinfo/sysinfo.c

    r6e50466 rad7a6c9  
    4040#include <arch/asm.h>
    4141#include <errno.h>
     42#include <macros.h>
    4243
    4344/** Maximal sysinfo path length */
     
    761762 * character must be null).
    762763 *
    763  * The user space buffer must be sized exactly according
    764  * to the size of the binary data, otherwise the request
    765  * fails.
     764 * If the user space buffer size does not equal
     765 * the actual size of the returned data, the data
     766 * is truncated. Whether this is actually a fatal
     767 * error or the data can be still interpreted as valid
     768 * depends on the nature of the data and has to be
     769 * decided by the user space.
     770 *
     771 * The actual size of data returned is stored to
     772 * size_ptr.
    766773 *
    767774 * @param path_ptr    Sysinfo path in the user address space.
     
    770777 *                    to store the binary data.
    771778 * @param buffer_size User space buffer size.
     779 * @param size_ptr    User space pointer where to store the
     780 *                    binary data size.
    772781 *
    773782 * @return Error code (EOK in case of no error).
     
    775784 */
    776785sysarg_t sys_sysinfo_get_data(void *path_ptr, size_t path_size,
    777     void *buffer_ptr, size_t buffer_size)
     786    void *buffer_ptr, size_t buffer_size, size_t *size_ptr)
    778787{
    779788        int rc;
    780789       
    781790        /* Get the item */
    782         sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, false);
    783 
     791        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size,
     792            false);
     793       
    784794        /* Only constant or generated binary data is considered */
    785         if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) {
    786                 /* Check destination buffer size */
    787                 if (ret.data.size == buffer_size)
    788                         rc = copy_to_uspace(buffer_ptr, ret.data.data,
    789                             ret.data.size);
    790                 else
    791                         rc = ENOMEM;
     795        if ((ret.tag == SYSINFO_VAL_DATA) ||
     796            (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) {
     797                size_t size = min(ret.data.size, buffer_size);
     798                rc = copy_to_uspace(buffer_ptr, ret.data.data, size);
     799                if (rc == EOK)
     800                        rc = copy_to_uspace(size_ptr, &size, sizeof(size));
    792801        } else
    793802                rc = EINVAL;
  • kernel/generic/src/time/clock.c

    r6e50466 rad7a6c9  
    9393        clock_parea.pbase = (uintptr_t) faddr;
    9494        clock_parea.frames = 1;
     95        clock_parea.unpriv = true;
    9596        ddi_parea_register(&clock_parea);
    9697       
     
    100101         *
    101102         */
    102         sysinfo_set_item_val("clock.cacheable", NULL, (sysarg_t) true);
    103103        sysinfo_set_item_val("clock.faddr", NULL, (sysarg_t) faddr);
    104104}
Note: See TracChangeset for help on using the changeset viewer.