Changeset 3fcea34 in mainline


Ignore:
Timestamp:
2024-09-20T12:16:28Z (2 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
d3109ff
Parents:
2cf8f994
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-20 11:42:13)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-20 12:16:28)
Message:

Simplify the SYS_THREAD_CREATE syscall interface

Removed the beefy uarg structure. Instead, the syscall gets two
parameters: %pc (program counter) and %sp (stack pointer). It starts
a thread with those values in corresponding registers, with no other
fuss whatsoever.

libc initializes threads by storing any other needed arguments on
the stack and retrieving them in thread_entry. Importantly, this
includes the address of the
thread_main function which is now
called indirectly to fix dynamic linking issues on some archs.

There's a bit of weirdness on SPARC and IA-64, because of their
stacked register handling. The current solution is that we require
some space *above* the stack pointer to be available for those
architectures. I think for SPARC, it can be made more normal.

For the remaining ones, we can (probably) just set the initial
%sp to the top edge of the stack. There's some lingering offsets
on some archs just because I didn't want to accidentally break
anything. The initial thread bringup should be functionally
unchanged from the previous state, and no binaries are currently
multithreaded except thread1 test, so there should be minimal
risk of breakage. Naturally, I tested all available emulator
builds, save for msim.

Files:
1 deleted
49 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/abs32le/src/userspace.c

    r2cf8f994 r3fcea34  
    3636#include <stdbool.h>
    3737#include <arch.h>
    38 #include <abi/proc/uarg.h>
    3938#include <mm/as.h>
    4039
    41 void userspace(uspace_arg_t *kernel_uarg)
     40uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     41{
     42        return stack_base + stack_size;
     43}
     44
     45void userspace(uintptr_t pc, uintptr_t sp)
    4246{
    4347        /*
  • kernel/arch/amd64/src/userspace.c

    r2cf8f994 r3fcea34  
    3939#include <stdint.h>
    4040#include <arch.h>
    41 #include <abi/proc/uarg.h>
    4241#include <mm/as.h>
     42
     43uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     44{
     45        return stack_base + stack_size;
     46}
    4347
    4448/** Enter userspace
     
    4751 *
    4852 */
    49 void userspace(uspace_arg_t *kernel_uarg)
     53void userspace(uintptr_t pc, uintptr_t sp)
    5054{
    5155        uint64_t rflags = read_rflags();
     
    6064            "pushq %[utext_des]\n"
    6165            "pushq %[entry]\n"
    62             "movq %[uarg], %%rax\n"
    6366
    6467            /* %rdi is defined to hold pcb_ptr - set it to 0 */
     
    6669            "iretq\n"
    6770            :: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
    68               [stack_top] "r" (kernel_uarg->uspace_stack +
    69               kernel_uarg->uspace_stack_size),
     71              [stack_top] "r" (sp),
    7072              [rflags] "r" (rflags),
    7173              [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
    72               [entry] "r" (kernel_uarg->uspace_entry),
    73               [uarg] "r" (kernel_uarg->uspace_uarg)
    74             : "rax"
     74              [entry] "r" (pc)
    7575        );
    7676
  • kernel/arch/arm32/src/userspace.c

    r2cf8f994 r3fcea34  
    6161} ustate_t;
    6262
     63uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     64{
     65        return stack_base + stack_size;
     66}
     67
    6368/** Change processor mode
    6469 *
     
    6671 *
    6772 */
    68 void userspace(uspace_arg_t *kernel_uarg)
     73void userspace(uintptr_t pc, uintptr_t sp)
    6974{
    70         volatile ustate_t ustate;
    71 
    72         /* set first parameter */
    73         ustate.r0 = kernel_uarg->uspace_uarg;
    74 
    75         /* %r1 is defined to hold pcb_ptr - set it to 0 */
    76         ustate.r1 = 0;
     75        volatile ustate_t ustate = { };
    7776
    7877        /* pass the RAS page address in %r2 */
    7978        ustate.r2 = (uintptr_t) ras_page;
    8079
    81         /* clear other registers */
    82         ustate.r3 = 0;
    83         ustate.r4 = 0;
    84         ustate.r5 = 0;
    85         ustate.r6 = 0;
    86         ustate.r7 = 0;
    87         ustate.r8 = 0;
    88         ustate.r9 = 0;
    89         ustate.r10 = 0;
    90         ustate.r11 = 0;
    91         ustate.r12 = 0;
    92         ustate.lr = 0;
    93 
    94         /* set user stack */
    95         ustate.sp = kernel_uarg->uspace_stack +
    96             kernel_uarg->uspace_stack_size;
    97 
    98         /* set where uspace execution starts */
    99         ustate.pc = kernel_uarg->uspace_entry;
     80        ustate.sp = sp;
     81        ustate.pc = pc;
    10082
    10183        /* status register in user mode */
  • kernel/arch/arm64/src/arm64.c

    r2cf8f994 r3fcea34  
    146146}
    147147
     148uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     149{
     150        return stack_base + stack_size;
     151}
     152
    148153/** Change processor mode.
    149154 *
    150155 * @param kernel_uarg Userspace settings (entry point, stack, ...).
    151156 */
    152 void userspace(uspace_arg_t *kernel_uarg)
     157void userspace(uintptr_t pc, uintptr_t sp)
    153158{
    154159        /* Prepare return to EL0. */
     
    157162
    158163        /* Set program entry. */
    159         ELR_EL1_write(kernel_uarg->uspace_entry);
     164        ELR_EL1_write(pc);
    160165
    161166        /* Set user stack. */
    162         SP_EL0_write(kernel_uarg->uspace_stack +
    163             kernel_uarg->uspace_stack_size);
     167        SP_EL0_write(sp);
    164168
    165169        /* Clear Thread ID register. */
     
    170174             * Reset the kernel stack to its base value.
    171175             *
    172              * Clear all general-purpose registers,
    173              * except x0 that holds an argument for
    174              * the user space.
     176             * Clear all general-purpose registers.
    175177             */
    176178            "mov sp, %[kstack]\n"
    177             "mov x0, %[uspace_uarg]\n"
     179            "mov x0, #0\n"
    178180            "mov x1, #0\n"
    179181            "mov x2, #0\n"
     
    207209            "mov x30, #0\n"
    208210            "eret\n"
    209             :: [uspace_uarg] "r" (kernel_uarg->uspace_uarg),
    210               [kstack] "r" (((uint64_t) (THREAD->kstack)) +
     211            :: [kstack] "r" (((uint64_t) (THREAD->kstack)) +
    211212              MEM_STACK_SIZE - SP_DELTA)
    212213        );
  • kernel/arch/ia32/src/userspace.c

    r2cf8f994 r3fcea34  
    3838#include <stdint.h>
    3939#include <arch.h>
    40 #include <abi/proc/uarg.h>
    4140#include <mm/as.h>
    4241#include <arch/cpu.h>
    4342#include <arch/asm.h>
     43
     44uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     45{
     46        return stack_base + stack_size;
     47}
    4448
    4549/** Enter userspace
     
    4852 *
    4953 */
    50 void userspace(uspace_arg_t *kernel_uarg)
     54void userspace(uintptr_t pc, uintptr_t sp)
    5155{
    5256        uint32_t eflags = read_eflags();
     
    6165            "pushl %[utext_des]\n"
    6266            "pushl %[entry]\n"
    63             "movl %[uarg], %%eax\n"
    6467
    6568            /* %edi is defined to hold pcb_ptr - set it to 0 */
     
    7073            : [eflags_mask] "i" (~EFLAGS_NT),
    7174              [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
    72               [stack_top] "r" (kernel_uarg->uspace_stack +
    73               kernel_uarg->uspace_stack_size),
     75              [stack_top] "r" (sp),
    7476              [eflags] "r" ((eflags & ~(EFLAGS_NT)) | EFLAGS_IF),
    7577              [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
    76               [entry] "r" (kernel_uarg->uspace_entry),
    77               [uarg] "r" (kernel_uarg->uspace_uarg),
     78              [entry] "r" (pc),
    7879              [vreg_des] "r" (GDT_SELECTOR(VREG_DES))
    7980            : "eax");
  • kernel/arch/ia64/src/ia64.c

    r2cf8f994 r3fcea34  
    218218}
    219219
     220uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     221{
     222        return ALIGN_DOWN(stack_base + stack_size / 2, STACK_ALIGNMENT);
     223}
     224
    220225/** Enter userspace and never return. */
    221 void userspace(uspace_arg_t *kernel_uarg)
     226void userspace(uintptr_t pc, uintptr_t sp)
    222227{
    223228        psr_t psr;
     
    241246         *
    242247         * When calculating stack addresses, mind the stack split between the
    243          * memory stack and the RSE stack. Each occuppies
    244          * uspace_stack_size / 2 bytes.
     248         * memory stack and the RSE stack.
     249         * Memory stack occupies area under sp, while RSE stack occupies area above.
    245250         */
    246         switch_to_userspace(kernel_uarg->uspace_entry,
    247             kernel_uarg->uspace_stack +
    248             kernel_uarg->uspace_stack_size / 2 -
    249             ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
    250             kernel_uarg->uspace_stack +
    251             kernel_uarg->uspace_stack_size / 2,
    252             kernel_uarg->uspace_uarg, psr.value, rsc.value);
     251        switch_to_userspace(pc,
     252            sp, sp + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
     253            0, psr.value, rsc.value);
    253254
    254255        while (true)
  • kernel/arch/mips32/include/arch/asm.h

    r2cf8f994 r3fcea34  
    8181extern void cpu_halt(void) __attribute__((noreturn));
    8282extern void asm_delay_loop(uint32_t);
    83 extern void userspace_asm(uintptr_t, uintptr_t, uintptr_t);
     83extern void userspace_asm(uintptr_t, uintptr_t);
    8484
    8585extern ipl_t interrupts_disable(void);
  • kernel/arch/mips32/src/mips32.c

    r2cf8f994 r3fcea34  
    163163}
    164164
    165 void userspace(uspace_arg_t *kernel_uarg)
     165uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     166{
     167        return stack_base + stack_size;
     168}
     169
     170void userspace(uintptr_t pc, uintptr_t sp)
    166171{
    167172        /* EXL = 1, UM = 1, IE = 1 */
    168173        cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit |
    169174            cp0_status_um_bit | cp0_status_ie_enabled_bit));
    170         cp0_epc_write(kernel_uarg->uspace_entry);
    171         userspace_asm(kernel_uarg->uspace_stack +
    172             kernel_uarg->uspace_stack_size,
    173             kernel_uarg->uspace_uarg,
    174             kernel_uarg->uspace_entry);
     175        cp0_epc_write(pc);
     176        userspace_asm(sp, pc);
    175177
    176178        while (true)
  • kernel/arch/mips32/src/start.S

    r2cf8f994 r3fcea34  
    339339FUNCTION_BEGIN(userspace_asm)
    340340        move $sp, $a0
    341         move $v0, $a1
    342         move $t9, $a2      /* set up correct entry into PIC code */
    343         xor $a0, $a0, $a0  /* $a0 is defined to hold pcb_ptr */
    344                            /* set it to 0 */
     341        xor $a0, $a0, $a0  /* $a0 is defined to hold pcb_ptr, set it to 0 */
     342        xor $fp, $fp, $fp  // FIXME: wipe all userspace-accessible registers
     343        xor $ra, $ra, $ra
    345344        eret
    346345FUNCTION_END(userspace_asm)
  • kernel/arch/ppc32/src/ppc32.c

    r2cf8f994 r3fcea34  
    4949#include <mm/km.h>
    5050#include <time/clock.h>
    51 #include <abi/proc/uarg.h>
    5251#include <console/console.h>
    5352#include <sysinfo/sysinfo.h>
     
    290289}
    291290
    292 void userspace(uspace_arg_t *kernel_uarg)
    293 {
    294         userspace_asm(kernel_uarg->uspace_uarg,
    295             kernel_uarg->uspace_stack +
    296             kernel_uarg->uspace_stack_size - SP_DELTA,
    297             kernel_uarg->uspace_entry);
    298 
     291uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     292{
     293        return stack_base + stack_size - SP_DELTA;
     294}
     295
     296void userspace(uintptr_t pc, uintptr_t sp)
     297{
     298        userspace_asm(0, sp, pc);
    299299        unreachable();
    300300}
  • kernel/arch/riscv64/src/userspace.c

    r2cf8f994 r3fcea34  
    3333 */
    3434
    35 #include <abi/proc/uarg.h>
    3635#include <userspace.h>
    3736
    38 void userspace(uspace_arg_t *kernel_uarg)
     37uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     38{
     39        return stack_base + stack_size;
     40}
     41
     42void userspace(uintptr_t pc, uintptr_t sp)
    3943{
    4044        // FIXME
  • kernel/arch/sparc64/src/sun4u/asm.S

    r2cf8f994 r3fcea34  
    8383 */
    8484FUNCTION_BEGIN(switch_to_userspace)
    85         save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
     85        save %o1, 0, %sp
    8686        flushw
    8787        wrpr %g0, 0, %cleanwin          ! avoid information leak
  • kernel/arch/sparc64/src/sun4u/sparc64.c

    r2cf8f994 r3fcea34  
    159159}
    160160
     161uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     162{
     163        return ALIGN_DOWN(stack_base + stack_size - STACK_WINDOW_SAVE_AREA_SIZE - STACK_ARG_SAVE_AREA_SIZE, 16) - STACK_BIAS;
     164}
     165
    161166/** Switch to userspace. */
    162 void userspace(uspace_arg_t *kernel_uarg)
     167void userspace(uintptr_t pc, uintptr_t sp)
    163168{
    164169        (void) interrupts_disable();
    165         switch_to_userspace(kernel_uarg->uspace_entry,
    166             kernel_uarg->uspace_stack +
    167             kernel_uarg->uspace_stack_size -
    168             (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
    169             kernel_uarg->uspace_uarg);
     170        switch_to_userspace(pc, sp, 0);
    170171
    171172        /* Not reached */
  • kernel/arch/sparc64/src/sun4v/asm.S

    r2cf8f994 r3fcea34  
    4141 */
    4242FUNCTION_BEGIN(switch_to_userspace)
    43         save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
     43        save %o1, 0, %sp
    4444        flushw
    4545        wrpr %g0, 0, %cleanwin          ! avoid information leak
  • kernel/arch/sparc64/src/sun4v/sparc64.c

    r2cf8f994 r3fcea34  
    157157}
    158158
     159uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
     160{
     161        return ALIGN_DOWN(stack_base + stack_size - STACK_WINDOW_SAVE_AREA_SIZE - STACK_ARG_SAVE_AREA_SIZE, 16) - STACK_BIAS;
     162}
     163
    159164/** Switch to userspace. */
    160 void userspace(uspace_arg_t *kernel_uarg)
     165void userspace(uintptr_t pc, uintptr_t sp)
    161166{
    162167        (void) interrupts_disable();
    163         switch_to_userspace(kernel_uarg->uspace_entry,
    164             kernel_uarg->uspace_stack +
    165             kernel_uarg->uspace_stack_size -
    166             (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
    167             kernel_uarg->uspace_uarg);
     168        switch_to_userspace(pc, sp, 0);
    168169
    169170        /* Not reached */
  • kernel/generic/include/main/uinit.h

    r2cf8f994 r3fcea34  
    3636#define KERN_UINIT_H_
    3737
     38#include <stdint.h>
     39
     40typedef struct {
     41        uintptr_t pc;
     42        uintptr_t sp;
     43} uinit_arg_t;
     44
    3845extern void uinit(void *arg);
    3946
  • kernel/generic/include/proc/thread.h

    r2cf8f994 r3fcea34  
    4545#include <arch/cpu.h>
    4646#include <mm/tlb.h>
    47 #include <abi/proc/uarg.h>
    4847#include <udebug/udebug.h>
    4948#include <abi/proc/thread.h>
  • kernel/generic/include/userspace.h

    r2cf8f994 r3fcea34  
    3939#include <typedefs.h>
    4040
     41extern uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size);
     42
    4143/** Switch to user-space (CPU user priviledge level) */
    42 extern void userspace(uspace_arg_t *uarg) __attribute__((noreturn));
     44extern void userspace(sysarg_t pc, sysarg_t sp) __attribute__((noreturn));
    4345
    4446#endif
  • kernel/generic/src/main/uinit.c

    r2cf8f994 r3fcea34  
    6060#endif
    6161
    62         uspace_arg_t *uarg = arg;
    63         uspace_arg_t local_uarg;
    64 
    65         local_uarg.uspace_entry = uarg->uspace_entry;
    66         local_uarg.uspace_stack = uarg->uspace_stack;
    67         local_uarg.uspace_stack_size = uarg->uspace_stack_size;
    68         local_uarg.uspace_uarg = uarg->uspace_uarg;
    69         local_uarg.uspace_thread_function = USPACE_NULL;
    70         local_uarg.uspace_thread_arg = USPACE_NULL;
    71 
     62        uinit_arg_t *uarg = arg;
     63        sysarg_t pc = uarg->pc;
     64        sysarg_t sp = uarg->sp;
    7265        free(uarg);
    7366
    74         userspace(&local_uarg);
     67        userspace(pc, sp);
    7568}
    7669
  • kernel/generic/src/proc/program.c

    r2cf8f994 r3fcea34  
    5353#include <syscall/copy.h>
    5454#include <proc/program.h>
     55#include <userspace.h>
    5556
    5657/**
     
    7273errno_t program_create(as_t *as, uspace_addr_t entry_addr, char *name, program_t *prg)
    7374{
    74         uspace_arg_t *kernel_uarg = (uspace_arg_t *)
    75             malloc(sizeof(uspace_arg_t));
     75        uinit_arg_t *kernel_uarg = malloc(sizeof(uinit_arg_t));
    7676        if (!kernel_uarg)
    7777                return ENOMEM;
     
    104104        }
    105105
    106         kernel_uarg->uspace_entry = entry_addr;
    107         kernel_uarg->uspace_stack = virt;
    108         kernel_uarg->uspace_stack_size = STACK_SIZE_USER;
    109         kernel_uarg->uspace_thread_function = USPACE_NULL;
    110         kernel_uarg->uspace_thread_arg = USPACE_NULL;
    111         kernel_uarg->uspace_uarg = USPACE_NULL;
     106        kernel_uarg->pc = entry_addr;
     107        kernel_uarg->sp = arch_get_initial_sp(virt, STACK_SIZE_USER);
    112108
    113109        /*
  • kernel/generic/src/proc/thread.c

    r2cf8f994 r3fcea34  
    944944
    945945/** Process syscall to create new thread.
    946  *
    947  */
    948 sys_errno_t sys_thread_create(uspace_ptr_uspace_arg_t uspace_uarg, uspace_ptr_char uspace_name,
    949     size_t name_len, uspace_ptr_thread_id_t uspace_thread_id)
     946 * The started thread will have initial pc and sp set to the exact values passed
     947 * to the syscall. The kernel will not touch any stack data below the stack
     948 * pointer, but some architectures may require some space to be available
     949 * for use above it. See userspace() in kernel, and <libarch/thread.h> in libc.
     950 *
     951 */
     952sys_errno_t sys_thread_create(sysarg_t pc, sysarg_t sp,
     953    uspace_ptr_char uspace_name, size_t name_len)
    950954{
    951955        if (name_len > THREAD_NAME_BUFLEN - 1)
     
    963967         * In case of success, kernel_uarg will be freed in uinit().
    964968         */
    965         uspace_arg_t *kernel_uarg =
    966             (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
     969        uinit_arg_t *kernel_uarg = malloc(sizeof(uinit_arg_t));
    967970        if (!kernel_uarg)
    968971                return (sys_errno_t) ENOMEM;
    969972
    970         rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
    971         if (rc != EOK) {
    972                 free(kernel_uarg);
    973                 return (sys_errno_t) rc;
    974         }
     973        kernel_uarg->pc = pc;
     974        kernel_uarg->sp = sp;
     975
     976        // TODO: fix some unnecessary inconsistencies between architectures
    975977
    976978        thread_t *thread = thread_create(uinit, kernel_uarg, TASK,
    977979            THREAD_FLAG_USPACE | THREAD_FLAG_NOATTACH, namebuf);
    978         if (thread) {
    979                 if (uspace_thread_id) {
    980                         rc = copy_to_uspace(uspace_thread_id, &thread->tid,
    981                             sizeof(thread->tid));
    982                         if (rc != EOK) {
    983                                 /*
    984                                  * We have encountered a failure, but the thread
    985                                  * has already been created. We need to undo its
    986                                  * creation now.
    987                                  */
    988 
    989                                 /*
    990                                  * The new thread structure is initialized, but
    991                                  * is still not visible to the system.
    992                                  * We can safely deallocate it.
    993                                  */
    994                                 slab_free(thread_cache, thread);
    995                                 free(kernel_uarg);
    996 
    997                                 return (sys_errno_t) rc;
    998                         }
    999                 }
     980        if (!thread) {
     981                free(kernel_uarg);
     982                return (sys_errno_t) ENOMEM;
     983        }
    1000984
    1001985#ifdef CONFIG_UDEBUG
    1002                 /*
    1003                 * Generate udebug THREAD_B event and attach the thread.
    1004                 * This must be done atomically (with the debug locks held),
    1005                 * otherwise we would either miss some thread or receive
    1006                 * THREAD_B events for threads that already existed
    1007                 * and could be detected with THREAD_READ before.
    1008                 */
    1009                 udebug_thread_b_event_attach(thread, TASK);
     986        /*
     987        * Generate udebug THREAD_B event and attach the thread.
     988        * This must be done atomically (with the debug locks held),
     989        * otherwise we would either miss some thread or receive
     990        * THREAD_B events for threads that already existed
     991        * and could be detected with THREAD_READ before.
     992        */
     993        udebug_thread_b_event_attach(thread, TASK);
    1010994#else
    1011                 thread_attach(thread, TASK);
     995        thread_attach(thread, TASK);
    1012996#endif
    1013                 thread_start(thread);
    1014                 thread_put(thread);
    1015 
    1016                 return 0;
    1017         } else
    1018                 free(kernel_uarg);
    1019 
    1020         return (sys_errno_t) ENOMEM;
     997        thread_start(thread);
     998        thread_put(thread);
     999
     1000        return (sys_errno_t) EOK;
    10211001}
    10221002
  • meson/arch/ppc32/meson.build

    r2cf8f994 r3fcea34  
    3535arch_kernel_link_args = [ '-nostdlib', '-Wl,-z,max-page-size=0x1000' ]
    3636arch_uspace_link_args = [ '-nostdlib', '-lgcc', '-Wl,-z,max-page-size=0x1000' ]
    37 arch_uspace_link_args += ldflags_ignore_rwx_segments
    3837arch_boot_link_args = ldflags_ignore_rwx_segments
    3938
  • meson/part/compiler_args/meson.build

    r2cf8f994 r3fcea34  
    4242        '-Wl,--warn-common',
    4343        '-Wl,--fatal-warnings',
     44        '-Wl,-z,text',
    4445        language : [ 'c', 'cpp' ],
    4546)
     
    5758
    5859        '-Wa,--fatal-warnings',
     60        '-Wl,-z,text',
    5961
    6062        '-Wall',
  • meson/part/initrd_manifest/meson.build

    r2cf8f994 r3fcea34  
    4949        'app/getterm',
    5050        'app/kio',
     51        'app/tester',
    5152
    5253        'srv/devman',
  • uspace/lib/c/arch/abs32le/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3636#define _LIBC_abs32le_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     44
     45        sp[-1] = (uintptr_t) arg;
     46        sp[-2] = (uintptr_t) main;
     47
     48        return (uintptr_t) sp;
     49}
     50
    3851#endif
    3952
  • uspace/lib/c/arch/abs32le/src/thread_entry.c

    r2cf8f994 r3fcea34  
    3030 */
    3131
     32#include <stdbool.h>
    3233#include <stddef.h>
    3334#include "../../../generic/private/thread.h"
     
    3536void __thread_entry(void)
    3637{
    37         __thread_main(NULL);
     38        while (true)
     39                ;
    3840}
    3941
  • uspace/lib/c/arch/amd64/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3636#define _LIBC_amd64_THREAD_H_
    3737
     38#include <align.h>
     39#include <stddef.h>
     40#include <stdint.h>
     41
     42static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     43    void (*main)(void *), void *arg)
     44{
     45        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     46
     47        *--sp = (uintptr_t) arg;
     48        *--sp = (uintptr_t) main;
     49
     50        return (uintptr_t) sp;
     51}
     52
    3853#endif
    3954
  • uspace/lib/c/arch/amd64/src/thread_entry.S

    r2cf8f994 r3fcea34  
    3535#
    3636SYMBOL_BEGIN(__thread_entry)
     37        # Pop libc thread entry function and argument
     38        popq %rax
     39        popq %rdi
     40
    3741        #
    3842        # Create the first stack frame.
     
    4246        movq %rsp, %rbp
    4347
    44         #
    45         # RAX contains address of uarg
    46         #
    47         movq %rax, %rdi
    48         call FUNCTION_REF(__thread_main)
     48        call *%rax
    4949SYMBOL_END(__thread_entry)
  • uspace/lib/c/arch/arm32/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3737#define _LIBC_arm32_THREAD_H_
    3838
     39#include <align.h>
     40
     41static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     42    void (*main)(void *), void *arg)
     43{
     44        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     45
     46        *--sp = (uintptr_t) main;
     47        *--sp = (uintptr_t) arg;
     48
     49        return (uintptr_t) sp;
     50}
     51
    3952#endif
    4053
  • uspace/lib/c/arch/arm32/src/thread_entry.S

    r2cf8f994 r3fcea34  
    3535#
    3636SYMBOL(__thread_entry)
     37        # Pop libc entry function and its argument.
     38        pop { r0, r4 }
     39
    3740        #
    3841        # Create the first stack frame.
     
    4346        sub fp, ip, #4
    4447
    45         b __thread_main
     48        bx r4
  • uspace/lib/c/arch/arm64/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3636#define _LIBC_arm64_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     44
     45        *--sp = (uintptr_t) arg;
     46        *--sp = (uintptr_t) main;
     47
     48        return (uintptr_t) sp;
     49}
     50
    3851#endif
    3952
  • uspace/lib/c/arch/arm64/src/thread_entry.S

    r2cf8f994 r3fcea34  
    3535#
    3636SYMBOL(__thread_entry)
    37         #
     37        # Load entry function and argument from stack.
     38        ldp x1, x0, [sp], #16
     39
    3840        # Create the first stack frame.
    39         #
    4041        mov x29, #0
    4142        stp x29, x30, [sp, #-16]!
    4243        mov x29, sp
    4344
    44         b __thread_main
     45        br x1
  • uspace/lib/c/arch/ia32/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3636#define _LIBC_ia32_THREAD_H_
    3737
     38#include <align.h>
     39#include <stddef.h>
     40#include <stdint.h>
     41
     42static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     43    void (*main)(void *), void *arg)
     44{
     45        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     46
     47        *--sp = (uintptr_t) arg;
     48        *--sp = (uintptr_t) main;
     49
     50        return (uintptr_t) sp;
     51}
     52
    3853#endif
    3954
  • uspace/lib/c/arch/ia32/src/syscall.S

    r2cf8f994 r3fcea34  
    7777        pushl %ebp
    7878        mov %esp, %ebp
    79         lea ra, %edi
    8079        movl 20(%esp), %edx     # First argument.
    8180        movl 24(%esp), %ecx     # Second argument.
     
    8382        movl 32(%esp), %esi     # Fourth argument.
    8483        movl 44(%esp), %eax     # Syscall number.
    85         sysenter
    86 ra:
     84        call 1f
    8785        movw %cs, %cx
    8886        addw $8, %cx
     
    9593        popl %ebx
    9694        ret
     95
     96        /* Trampoline for entering kernel */
     971:
     98        pop %edi
     99        sysenter
    97100FUNCTION_END(__syscall_fast)
  • uspace/lib/c/arch/ia32/src/thread_entry.S

    r2cf8f994 r3fcea34  
    4141        # Do not set %gs, it contains descriptor that can see TLS
    4242
     43        # Pop libc thread main function.
     44        popl %eax
     45        # Pop argument.
     46        popl %ebx
     47
    4348        #
    4449        # Create the first stack frame.
     
    4853        mov %esp, %ebp
    4954
    50         #
    51         # EAX contains address of uarg.
    52         #
    53         pushl %eax
    54         call __thread_main
     55        pushl %ebx
     56        call *%eax
    5557
    5658        #
  • uspace/lib/c/arch/ia64/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3636#define _LIBC_ia64_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) (ALIGN_DOWN((uintptr_t) stack + stack_size / 2, 16));
     44
     45        /* Store data under stack pointer */
     46        sp[-1] = (uintptr_t) arg;
     47        sp[-2] = (uintptr_t) main;
     48
     49        return (uintptr_t) sp;
     50}
     51
    3852#endif
    3953
  • uspace/lib/c/arch/ia64/src/thread_entry.S

    r2cf8f994 r3fcea34  
    3737        alloc loc0 = ar.pfs, 0, 1, 1, 0
    3838
    39 #ifndef CONFIG_RTLD
    40         # XXX This does not work in a shared library
    41         movl gp = __gp
    42 #endif
     39        add r8 = -8, sp ;;
     40        # Entry function argument
     41        ld8 out0 = [r8], -8 ;;
    4342
    44         #
    45         # r8 contains address of uarg structure.
    46         #
     43        # Entry function descriptor
     44        ld8 r8 = [r8] ;;
     45        # Entry function address
     46        ld8 r9 = [r8], 8 ;;
     47        # Entry function global pointer
     48        ld8 gp = [r8] ;;
    4749
    48         mov out0 = r8 ;;
    49         # XXX br.call.sptk.many b0 = FUNCTION_REF(__thread_main)
    50         br.call.sptk.many b0 = __thread_main
     50        mov b1 = r9 ;;
     51
     52        br.call.sptk.many b0 = b1 ;;
    5153
    5254        #
  • uspace/lib/c/arch/mips32/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3737#define _LIBC_mips32_THREAD_H_
    3838
     39#include <align.h>
     40
     41static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     42    void (*main)(void *), void *arg)
     43{
     44        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     45
     46        sp[-1] = (uintptr_t) arg;
     47        sp[-2] = (uintptr_t) main;
     48
     49        return (uintptr_t) sp;
     50}
     51
    3952#endif
    4053
  • uspace/lib/c/arch/mips32/src/thread_entry.S

    r2cf8f994 r3fcea34  
    4040#
    4141SYMBOL(__thread_entry)
    42         .ent __thread_entry
    43         .frame $sp, ABI_STACK_FRAME, $ra
    44         .cpload $t9
     42        # All registers should be zero, including $fp and $ra.
     43        # Instead of setting up a stack frame here, we leave it for __thread_main.
    4544
    46         #
    47         # v0 contains address of uarg.
    48         #
    49         add $a0, $v0, 0
     45        # Function argument.
     46        lw $a0, -4($sp)
     47        # Function pointer.
     48        lw $t0, -8($sp)
    5049
    51         # Allocate the stack frame.
    52         addiu $sp, -ABI_STACK_FRAME
    53 
    54         # Allow PIC code
    55         .cprestore 16
    56 
    57         jal __thread_main
     50        j $t0
    5851        nop
    59 
    60         #
    61         # Not reached.
    62         #
    63         addiu $sp, ABI_STACK_FRAME
    64         .end __thread_entry
  • uspace/lib/c/arch/ppc32/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3636#define _LIBC_ppc32_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size - sizeof(void *), 16);
     44
     45        sp[0] = 0;
     46        sp[-1] = (uintptr_t) arg;
     47        sp[-2] = (uintptr_t) main;
     48
     49        return (uintptr_t) sp;
     50}
     51
    3852#endif
    3953
  • uspace/lib/c/arch/ppc32/src/thread_entry.S

    r2cf8f994 r3fcea34  
    3535#
    3636SYMBOL(__thread_entry)
    37         #
    38         # Create the first stack frame.
    39         #
    40         li %r4, 0
    41         stw %r4, 0(%r1)
    42         stwu %r1, -16(%r1)
     37        # Load function and argument.
     38        lwz %r3, -4(%r1)
     39        lwz %r4, -8(%r1)
    4340
    44         b __thread_main
     41        # Clear LR
     42        li %r0, 0
     43        mtlr %r0
    4544
     45        mtctr %r4
     46        bctr
  • uspace/lib/c/arch/riscv64/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3636#define _LIBC_riscv64_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     44
     45        sp[-1] = (uintptr_t) arg;
     46        sp[-2] = (uintptr_t) main;
     47
     48        return (uintptr_t) sp;
     49}
     50
    3851#endif
    3952
  • uspace/lib/c/arch/riscv64/src/thread_entry.c

    r2cf8f994 r3fcea34  
    3535void __thread_entry(void)
    3636{
    37         __thread_main((void *) 0);
     37        // TODO
     38        while (true)
     39                ;
    3840}
    3941
  • uspace/lib/c/arch/sparc64/include/libarch/thread.h

    r2cf8f994 r3fcea34  
    3535#define _LIBC_sparc64_THREAD_H_
    3636
     37#include <assert.h>
     38#include <align.h>
     39#include <libarch/stack.h>
     40
     41static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     42    void (*main)(void *), void *arg)
     43{
     44        /* We must leave space above the stack pointer for initial register spill area. */
     45        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size - STACK_WINDOW_SAVE_AREA_SIZE - STACK_ARG_SAVE_AREA_SIZE, 16);
     46
     47        sp[-1] = (uintptr_t) arg;
     48        sp[-2] = (uintptr_t) main;
     49
     50        return ((uintptr_t) sp) - STACK_BIAS;
     51}
     52
    3753#endif
    3854
  • uspace/lib/c/arch/sparc64/src/thread_entry.S

    r2cf8f994 r3fcea34  
    3535#
    3636SYMBOL(__thread_entry)
     37        add %sp, 0x7ff, %g1
     38
    3739        #
    3840        # Create the first stack frame.
     
    4345
    4446        #
    45         # Propagate the input arguments to the new window.
     47        # Load libc entry point address and argument from stack
    4648        #
     49        ldn [%g1 - 8], %o0
     50        ldn [%g1 - 16], %g1
    4751
    48         call __thread_main              ! %o0 contains address of uarg
    49         mov %i0, %o0
     52        jmpl %g1, %r0
     53        # Wipe link register
     54        xor %o7, %o7, %o7
    5055
    5156        ! not reached
  • uspace/lib/c/generic/private/fibril.h

    r2cf8f994 r3fcea34  
    3333#include <context.h>
    3434#include <tls.h>
    35 #include <abi/proc/uarg.h>
    3635#include <fibril.h>
    3736#include <ipc/common.h>
     
    5049        context_t ctx;
    5150
    52         uspace_arg_t uarg;
    5351        link_t link;
    5452        void *stack;
  • uspace/lib/c/generic/private/thread.h

    r2cf8f994 r3fcea34  
    3737
    3838#include <time.h>
    39 #include <abi/proc/uarg.h>
    4039#include <libarch/thread.h>
    4140#include <abi/proc/thread.h>
    4241
    4342extern void __thread_entry(void);
    44 extern void __thread_main(uspace_arg_t *);
    4543
    46 extern errno_t thread_create(void (*)(void *), void *, const char *,
    47     thread_id_t *);
     44extern errno_t thread_create(errno_t (*)(void *), void *, const char *);
    4845extern void thread_exit(int) __attribute__((noreturn));
    49 extern void thread_detach(thread_id_t);
    5046extern thread_id_t thread_get_id(void);
    5147extern void thread_usleep(usec_t);
  • uspace/lib/c/generic/thread/fibril.c

    r2cf8f994 r3fcea34  
    781781}
    782782
    783 static void _runner_fn(void *arg)
     783static errno_t _runner_fn(void *arg)
    784784{
    785785        _helper_fibril_fn(arg);
     786        return EOK;
    786787}
    787788
     
    808809
    809810        for (int i = 0; i < n; i++) {
    810                 thread_id_t tid;
    811                 rc = thread_create(_runner_fn, NULL, "fibril runner", &tid);
     811                rc = thread_create(_runner_fn, NULL, "fibril runner");
    812812                if (rc != EOK)
    813813                        return i;
    814                 thread_detach(tid);
    815814        }
    816815
  • uspace/lib/c/generic/thread/thread.c

    r2cf8f994 r3fcea34  
    3737#include <stdlib.h>
    3838#include <libarch/faddr.h>
    39 #include <abi/proc/uarg.h>
    4039#include <fibril.h>
    4140#include <stack.h>
     
    5453 * and exit when thread returns back.
    5554 *
    56  * @param uarg Pointer to userspace argument structure.
     55 * @param arg Fibril pointer.
    5756 *
    5857 */
    59 void __thread_main(uspace_arg_t *uarg)
     58static void __thread_main(void *arg)
    6059{
     60        fibril_t *fibril = arg;
     61
    6162        assert(!__tcb_is_set());
    62 
    63         fibril_t *fibril = uarg->uspace_thread_arg;
    6463        assert(fibril);
    6564
    6665        __tcb_set(fibril->tcb);
    6766
    68         uarg->uspace_thread_function(fibril->arg);
     67        fibril->func(fibril->arg);
    6968        /*
    7069         * XXX: we cannot free the userspace stack while running on it
     
    9089 * @return Zero on success or a code from @ref errno.h on failure.
    9190 */
    92 errno_t thread_create(void (*function)(void *), void *arg, const char *name,
    93     thread_id_t *tid)
     91errno_t thread_create(errno_t (*func)(void *), void *arg, const char *name)
    9492{
    95         uspace_arg_t *uarg = calloc(1, sizeof(uspace_arg_t));
    96         if (!uarg)
     93        fibril_t *fibril = fibril_alloc();
     94        if (!fibril)
    9795                return ENOMEM;
    9896
    99         fibril_t *fibril = fibril_alloc();
    100         if (!fibril) {
    101                 free(uarg);
    102                 return ENOMEM;
    103         }
     97        fibril->func = func;
     98        fibril->arg = arg;
    10499
    105100        size_t stack_size = stack_size_get();
     
    109104        if (stack == AS_MAP_FAILED) {
    110105                fibril_teardown(fibril);
    111                 free(uarg);
    112106                return ENOMEM;
    113107        }
    114108
    115         fibril->arg = arg;
    116         uarg->uspace_entry = (void *) FADDR(__thread_entry);
    117         uarg->uspace_stack = stack;
    118         uarg->uspace_stack_size = stack_size;
    119         uarg->uspace_thread_function = function;
    120         uarg->uspace_thread_arg = fibril;
    121         uarg->uspace_uarg = uarg;
     109        uintptr_t sp = arch_thread_prepare(stack, stack_size, __thread_main,
     110            fibril);
    122111
    123         errno_t rc = (errno_t) __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg,
    124             (sysarg_t) name, (sysarg_t) str_size(name), (sysarg_t) tid);
     112        errno_t rc = (errno_t) __SYSCALL4(SYS_THREAD_CREATE,
     113            (sysarg_t) FADDR(__thread_entry), sp,
     114            (sysarg_t) name, (sysarg_t) str_size(name));
    125115
    126116        if (rc != EOK) {
     
    130120                 */
    131121                as_area_destroy(stack);
    132                 free(uarg);
    133122        }
    134123
     
    148137        while (true)
    149138                ;
    150 }
    151 
    152 /** Detach thread.
    153  *
    154  * Currently not implemented.
    155  *
    156  * @param thread TID.
    157  */
    158 void thread_detach(thread_id_t thread)
    159 {
    160139}
    161140
Note: See TracChangeset for help on using the changeset viewer.