Changeset 3fcea34 in mainline
- Timestamp:
- 2024-09-20T12:16:28Z (2 months ago)
- 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)
- Files:
-
- 1 deleted
- 49 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/abs32le/src/userspace.c
r2cf8f994 r3fcea34 36 36 #include <stdbool.h> 37 37 #include <arch.h> 38 #include <abi/proc/uarg.h>39 38 #include <mm/as.h> 40 39 41 void userspace(uspace_arg_t *kernel_uarg) 40 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 41 { 42 return stack_base + stack_size; 43 } 44 45 void userspace(uintptr_t pc, uintptr_t sp) 42 46 { 43 47 /* -
kernel/arch/amd64/src/userspace.c
r2cf8f994 r3fcea34 39 39 #include <stdint.h> 40 40 #include <arch.h> 41 #include <abi/proc/uarg.h>42 41 #include <mm/as.h> 42 43 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 44 { 45 return stack_base + stack_size; 46 } 43 47 44 48 /** Enter userspace … … 47 51 * 48 52 */ 49 void userspace(u space_arg_t *kernel_uarg)53 void userspace(uintptr_t pc, uintptr_t sp) 50 54 { 51 55 uint64_t rflags = read_rflags(); … … 60 64 "pushq %[utext_des]\n" 61 65 "pushq %[entry]\n" 62 "movq %[uarg], %%rax\n"63 66 64 67 /* %rdi is defined to hold pcb_ptr - set it to 0 */ … … 66 69 "iretq\n" 67 70 :: [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), 70 72 [rflags] "r" (rflags), 71 73 [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) 75 75 ); 76 76 -
kernel/arch/arm32/src/userspace.c
r2cf8f994 r3fcea34 61 61 } ustate_t; 62 62 63 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 64 { 65 return stack_base + stack_size; 66 } 67 63 68 /** Change processor mode 64 69 * … … 66 71 * 67 72 */ 68 void userspace(u space_arg_t *kernel_uarg)73 void userspace(uintptr_t pc, uintptr_t sp) 69 74 { 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 = { }; 77 76 78 77 /* pass the RAS page address in %r2 */ 79 78 ustate.r2 = (uintptr_t) ras_page; 80 79 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; 100 82 101 83 /* status register in user mode */ -
kernel/arch/arm64/src/arm64.c
r2cf8f994 r3fcea34 146 146 } 147 147 148 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 149 { 150 return stack_base + stack_size; 151 } 152 148 153 /** Change processor mode. 149 154 * 150 155 * @param kernel_uarg Userspace settings (entry point, stack, ...). 151 156 */ 152 void userspace(u space_arg_t *kernel_uarg)157 void userspace(uintptr_t pc, uintptr_t sp) 153 158 { 154 159 /* Prepare return to EL0. */ … … 157 162 158 163 /* Set program entry. */ 159 ELR_EL1_write( kernel_uarg->uspace_entry);164 ELR_EL1_write(pc); 160 165 161 166 /* Set user stack. */ 162 SP_EL0_write(kernel_uarg->uspace_stack + 163 kernel_uarg->uspace_stack_size); 167 SP_EL0_write(sp); 164 168 165 169 /* Clear Thread ID register. */ … … 170 174 * Reset the kernel stack to its base value. 171 175 * 172 * Clear all general-purpose registers, 173 * except x0 that holds an argument for 174 * the user space. 176 * Clear all general-purpose registers. 175 177 */ 176 178 "mov sp, %[kstack]\n" 177 "mov x0, %[uspace_uarg]\n"179 "mov x0, #0\n" 178 180 "mov x1, #0\n" 179 181 "mov x2, #0\n" … … 207 209 "mov x30, #0\n" 208 210 "eret\n" 209 :: [uspace_uarg] "r" (kernel_uarg->uspace_uarg), 210 [kstack] "r" (((uint64_t) (THREAD->kstack)) + 211 :: [kstack] "r" (((uint64_t) (THREAD->kstack)) + 211 212 MEM_STACK_SIZE - SP_DELTA) 212 213 ); -
kernel/arch/ia32/src/userspace.c
r2cf8f994 r3fcea34 38 38 #include <stdint.h> 39 39 #include <arch.h> 40 #include <abi/proc/uarg.h>41 40 #include <mm/as.h> 42 41 #include <arch/cpu.h> 43 42 #include <arch/asm.h> 43 44 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 45 { 46 return stack_base + stack_size; 47 } 44 48 45 49 /** Enter userspace … … 48 52 * 49 53 */ 50 void userspace(u space_arg_t *kernel_uarg)54 void userspace(uintptr_t pc, uintptr_t sp) 51 55 { 52 56 uint32_t eflags = read_eflags(); … … 61 65 "pushl %[utext_des]\n" 62 66 "pushl %[entry]\n" 63 "movl %[uarg], %%eax\n"64 67 65 68 /* %edi is defined to hold pcb_ptr - set it to 0 */ … … 70 73 : [eflags_mask] "i" (~EFLAGS_NT), 71 74 [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), 74 76 [eflags] "r" ((eflags & ~(EFLAGS_NT)) | EFLAGS_IF), 75 77 [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), 78 79 [vreg_des] "r" (GDT_SELECTOR(VREG_DES)) 79 80 : "eax"); -
kernel/arch/ia64/src/ia64.c
r2cf8f994 r3fcea34 218 218 } 219 219 220 uintptr_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 220 225 /** Enter userspace and never return. */ 221 void userspace(u space_arg_t *kernel_uarg)226 void userspace(uintptr_t pc, uintptr_t sp) 222 227 { 223 228 psr_t psr; … … 241 246 * 242 247 * When calculating stack addresses, mind the stack split between the 243 * memory stack and the RSE stack. Each occuppies244 * 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. 245 250 */ 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); 253 254 254 255 while (true) -
kernel/arch/mips32/include/arch/asm.h
r2cf8f994 r3fcea34 81 81 extern void cpu_halt(void) __attribute__((noreturn)); 82 82 extern void asm_delay_loop(uint32_t); 83 extern void userspace_asm(uintptr_t, uintptr_t , uintptr_t);83 extern void userspace_asm(uintptr_t, uintptr_t); 84 84 85 85 extern ipl_t interrupts_disable(void); -
kernel/arch/mips32/src/mips32.c
r2cf8f994 r3fcea34 163 163 } 164 164 165 void userspace(uspace_arg_t *kernel_uarg) 165 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 166 { 167 return stack_base + stack_size; 168 } 169 170 void userspace(uintptr_t pc, uintptr_t sp) 166 171 { 167 172 /* EXL = 1, UM = 1, IE = 1 */ 168 173 cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit | 169 174 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); 175 177 176 178 while (true) -
kernel/arch/mips32/src/start.S
r2cf8f994 r3fcea34 339 339 FUNCTION_BEGIN(userspace_asm) 340 340 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 345 344 eret 346 345 FUNCTION_END(userspace_asm) -
kernel/arch/ppc32/src/ppc32.c
r2cf8f994 r3fcea34 49 49 #include <mm/km.h> 50 50 #include <time/clock.h> 51 #include <abi/proc/uarg.h>52 51 #include <console/console.h> 53 52 #include <sysinfo/sysinfo.h> … … 290 289 } 291 290 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 291 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 292 { 293 return stack_base + stack_size - SP_DELTA; 294 } 295 296 void userspace(uintptr_t pc, uintptr_t sp) 297 { 298 userspace_asm(0, sp, pc); 299 299 unreachable(); 300 300 } -
kernel/arch/riscv64/src/userspace.c
r2cf8f994 r3fcea34 33 33 */ 34 34 35 #include <abi/proc/uarg.h>36 35 #include <userspace.h> 37 36 38 void userspace(uspace_arg_t *kernel_uarg) 37 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 38 { 39 return stack_base + stack_size; 40 } 41 42 void userspace(uintptr_t pc, uintptr_t sp) 39 43 { 40 44 // FIXME -
kernel/arch/sparc64/src/sun4u/asm.S
r2cf8f994 r3fcea34 83 83 */ 84 84 FUNCTION_BEGIN(switch_to_userspace) 85 save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp85 save %o1, 0, %sp 86 86 flushw 87 87 wrpr %g0, 0, %cleanwin ! avoid information leak -
kernel/arch/sparc64/src/sun4u/sparc64.c
r2cf8f994 r3fcea34 159 159 } 160 160 161 uintptr_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 161 166 /** Switch to userspace. */ 162 void userspace(u space_arg_t *kernel_uarg)167 void userspace(uintptr_t pc, uintptr_t sp) 163 168 { 164 169 (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); 170 171 171 172 /* Not reached */ -
kernel/arch/sparc64/src/sun4v/asm.S
r2cf8f994 r3fcea34 41 41 */ 42 42 FUNCTION_BEGIN(switch_to_userspace) 43 save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp43 save %o1, 0, %sp 44 44 flushw 45 45 wrpr %g0, 0, %cleanwin ! avoid information leak -
kernel/arch/sparc64/src/sun4v/sparc64.c
r2cf8f994 r3fcea34 157 157 } 158 158 159 uintptr_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 159 164 /** Switch to userspace. */ 160 void userspace(u space_arg_t *kernel_uarg)165 void userspace(uintptr_t pc, uintptr_t sp) 161 166 { 162 167 (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); 168 169 169 170 /* Not reached */ -
kernel/generic/include/main/uinit.h
r2cf8f994 r3fcea34 36 36 #define KERN_UINIT_H_ 37 37 38 #include <stdint.h> 39 40 typedef struct { 41 uintptr_t pc; 42 uintptr_t sp; 43 } uinit_arg_t; 44 38 45 extern void uinit(void *arg); 39 46 -
kernel/generic/include/proc/thread.h
r2cf8f994 r3fcea34 45 45 #include <arch/cpu.h> 46 46 #include <mm/tlb.h> 47 #include <abi/proc/uarg.h>48 47 #include <udebug/udebug.h> 49 48 #include <abi/proc/thread.h> -
kernel/generic/include/userspace.h
r2cf8f994 r3fcea34 39 39 #include <typedefs.h> 40 40 41 extern uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size); 42 41 43 /** Switch to user-space (CPU user priviledge level) */ 42 extern void userspace( uspace_arg_t *uarg) __attribute__((noreturn));44 extern void userspace(sysarg_t pc, sysarg_t sp) __attribute__((noreturn)); 43 45 44 46 #endif -
kernel/generic/src/main/uinit.c
r2cf8f994 r3fcea34 60 60 #endif 61 61 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; 72 65 free(uarg); 73 66 74 userspace( &local_uarg);67 userspace(pc, sp); 75 68 } 76 69 -
kernel/generic/src/proc/program.c
r2cf8f994 r3fcea34 53 53 #include <syscall/copy.h> 54 54 #include <proc/program.h> 55 #include <userspace.h> 55 56 56 57 /** … … 72 73 errno_t program_create(as_t *as, uspace_addr_t entry_addr, char *name, program_t *prg) 73 74 { 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)); 76 76 if (!kernel_uarg) 77 77 return ENOMEM; … … 104 104 } 105 105 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); 112 108 113 109 /* -
kernel/generic/src/proc/thread.c
r2cf8f994 r3fcea34 944 944 945 945 /** 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 */ 952 sys_errno_t sys_thread_create(sysarg_t pc, sysarg_t sp, 953 uspace_ptr_char uspace_name, size_t name_len) 950 954 { 951 955 if (name_len > THREAD_NAME_BUFLEN - 1) … … 963 967 * In case of success, kernel_uarg will be freed in uinit(). 964 968 */ 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)); 967 970 if (!kernel_uarg) 968 971 return (sys_errno_t) ENOMEM; 969 972 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 975 977 976 978 thread_t *thread = thread_create(uinit, kernel_uarg, TASK, 977 979 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 } 1000 984 1001 985 #ifdef CONFIG_UDEBUG 1002 1003 1004 1005 1006 1007 1008 1009 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); 1010 994 #else 1011 995 thread_attach(thread, TASK); 1012 996 #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; 1021 1001 } 1022 1002 -
meson/arch/ppc32/meson.build
r2cf8f994 r3fcea34 35 35 arch_kernel_link_args = [ '-nostdlib', '-Wl,-z,max-page-size=0x1000' ] 36 36 arch_uspace_link_args = [ '-nostdlib', '-lgcc', '-Wl,-z,max-page-size=0x1000' ] 37 arch_uspace_link_args += ldflags_ignore_rwx_segments38 37 arch_boot_link_args = ldflags_ignore_rwx_segments 39 38 -
meson/part/compiler_args/meson.build
r2cf8f994 r3fcea34 42 42 '-Wl,--warn-common', 43 43 '-Wl,--fatal-warnings', 44 '-Wl,-z,text', 44 45 language : [ 'c', 'cpp' ], 45 46 ) … … 57 58 58 59 '-Wa,--fatal-warnings', 60 '-Wl,-z,text', 59 61 60 62 '-Wall', -
meson/part/initrd_manifest/meson.build
r2cf8f994 r3fcea34 49 49 'app/getterm', 50 50 'app/kio', 51 'app/tester', 51 52 52 53 'srv/devman', -
uspace/lib/c/arch/abs32le/include/libarch/thread.h
r2cf8f994 r3fcea34 36 36 #define _LIBC_abs32le_THREAD_H_ 37 37 38 #include <align.h> 39 40 static 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 38 51 #endif 39 52 -
uspace/lib/c/arch/abs32le/src/thread_entry.c
r2cf8f994 r3fcea34 30 30 */ 31 31 32 #include <stdbool.h> 32 33 #include <stddef.h> 33 34 #include "../../../generic/private/thread.h" … … 35 36 void __thread_entry(void) 36 37 { 37 __thread_main(NULL); 38 while (true) 39 ; 38 40 } 39 41 -
uspace/lib/c/arch/amd64/include/libarch/thread.h
r2cf8f994 r3fcea34 36 36 #define _LIBC_amd64_THREAD_H_ 37 37 38 #include <align.h> 39 #include <stddef.h> 40 #include <stdint.h> 41 42 static 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 38 53 #endif 39 54 -
uspace/lib/c/arch/amd64/src/thread_entry.S
r2cf8f994 r3fcea34 35 35 # 36 36 SYMBOL_BEGIN(__thread_entry) 37 # Pop libc thread entry function and argument 38 popq %rax 39 popq %rdi 40 37 41 # 38 42 # Create the first stack frame. … … 42 46 movq %rsp, %rbp 43 47 44 # 45 # RAX contains address of uarg 46 # 47 movq %rax, %rdi 48 call FUNCTION_REF(__thread_main) 48 call *%rax 49 49 SYMBOL_END(__thread_entry) -
uspace/lib/c/arch/arm32/include/libarch/thread.h
r2cf8f994 r3fcea34 37 37 #define _LIBC_arm32_THREAD_H_ 38 38 39 #include <align.h> 40 41 static 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 39 52 #endif 40 53 -
uspace/lib/c/arch/arm32/src/thread_entry.S
r2cf8f994 r3fcea34 35 35 # 36 36 SYMBOL(__thread_entry) 37 # Pop libc entry function and its argument. 38 pop { r0, r4 } 39 37 40 # 38 41 # Create the first stack frame. … … 43 46 sub fp, ip, #4 44 47 45 b __thread_main48 bx r4 -
uspace/lib/c/arch/arm64/include/libarch/thread.h
r2cf8f994 r3fcea34 36 36 #define _LIBC_arm64_THREAD_H_ 37 37 38 #include <align.h> 39 40 static 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 38 51 #endif 39 52 -
uspace/lib/c/arch/arm64/src/thread_entry.S
r2cf8f994 r3fcea34 35 35 # 36 36 SYMBOL(__thread_entry) 37 # 37 # Load entry function and argument from stack. 38 ldp x1, x0, [sp], #16 39 38 40 # Create the first stack frame. 39 #40 41 mov x29, #0 41 42 stp x29, x30, [sp, #-16]! 42 43 mov x29, sp 43 44 44 b __thread_main45 br x1 -
uspace/lib/c/arch/ia32/include/libarch/thread.h
r2cf8f994 r3fcea34 36 36 #define _LIBC_ia32_THREAD_H_ 37 37 38 #include <align.h> 39 #include <stddef.h> 40 #include <stdint.h> 41 42 static 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 38 53 #endif 39 54 -
uspace/lib/c/arch/ia32/src/syscall.S
r2cf8f994 r3fcea34 77 77 pushl %ebp 78 78 mov %esp, %ebp 79 lea ra, %edi80 79 movl 20(%esp), %edx # First argument. 81 80 movl 24(%esp), %ecx # Second argument. … … 83 82 movl 32(%esp), %esi # Fourth argument. 84 83 movl 44(%esp), %eax # Syscall number. 85 sysenter 86 ra: 84 call 1f 87 85 movw %cs, %cx 88 86 addw $8, %cx … … 95 93 popl %ebx 96 94 ret 95 96 /* Trampoline for entering kernel */ 97 1: 98 pop %edi 99 sysenter 97 100 FUNCTION_END(__syscall_fast) -
uspace/lib/c/arch/ia32/src/thread_entry.S
r2cf8f994 r3fcea34 41 41 # Do not set %gs, it contains descriptor that can see TLS 42 42 43 # Pop libc thread main function. 44 popl %eax 45 # Pop argument. 46 popl %ebx 47 43 48 # 44 49 # Create the first stack frame. … … 48 53 mov %esp, %ebp 49 54 50 # 51 # EAX contains address of uarg. 52 # 53 pushl %eax 54 call __thread_main 55 pushl %ebx 56 call *%eax 55 57 56 58 # -
uspace/lib/c/arch/ia64/include/libarch/thread.h
r2cf8f994 r3fcea34 36 36 #define _LIBC_ia64_THREAD_H_ 37 37 38 #include <align.h> 39 40 static 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 38 52 #endif 39 53 -
uspace/lib/c/arch/ia64/src/thread_entry.S
r2cf8f994 r3fcea34 37 37 alloc loc0 = ar.pfs, 0, 1, 1, 0 38 38 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 ;; 43 42 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] ;; 47 49 48 mov out0 = r8;;49 # XXX br.call.sptk.many b0 = FUNCTION_REF(__thread_main) 50 br.call.sptk.many b0 = __thread_main50 mov b1 = r9 ;; 51 52 br.call.sptk.many b0 = b1 ;; 51 53 52 54 # -
uspace/lib/c/arch/mips32/include/libarch/thread.h
r2cf8f994 r3fcea34 37 37 #define _LIBC_mips32_THREAD_H_ 38 38 39 #include <align.h> 40 41 static 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 39 52 #endif 40 53 -
uspace/lib/c/arch/mips32/src/thread_entry.S
r2cf8f994 r3fcea34 40 40 # 41 41 SYMBOL(__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. 45 44 46 # 47 # v0 contains address of uarg.48 # 49 add $a0, $v0, 045 # Function argument. 46 lw $a0, -4($sp) 47 # Function pointer. 48 lw $t0, -8($sp) 50 49 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 58 51 nop 59 60 #61 # Not reached.62 #63 addiu $sp, ABI_STACK_FRAME64 .end __thread_entry -
uspace/lib/c/arch/ppc32/include/libarch/thread.h
r2cf8f994 r3fcea34 36 36 #define _LIBC_ppc32_THREAD_H_ 37 37 38 #include <align.h> 39 40 static 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 38 52 #endif 39 53 -
uspace/lib/c/arch/ppc32/src/thread_entry.S
r2cf8f994 r3fcea34 35 35 # 36 36 SYMBOL(__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) 43 40 44 b __thread_main 41 # Clear LR 42 li %r0, 0 43 mtlr %r0 45 44 45 mtctr %r4 46 bctr -
uspace/lib/c/arch/riscv64/include/libarch/thread.h
r2cf8f994 r3fcea34 36 36 #define _LIBC_riscv64_THREAD_H_ 37 37 38 #include <align.h> 39 40 static 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 38 51 #endif 39 52 -
uspace/lib/c/arch/riscv64/src/thread_entry.c
r2cf8f994 r3fcea34 35 35 void __thread_entry(void) 36 36 { 37 __thread_main((void *) 0); 37 // TODO 38 while (true) 39 ; 38 40 } 39 41 -
uspace/lib/c/arch/sparc64/include/libarch/thread.h
r2cf8f994 r3fcea34 35 35 #define _LIBC_sparc64_THREAD_H_ 36 36 37 #include <assert.h> 38 #include <align.h> 39 #include <libarch/stack.h> 40 41 static 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 37 53 #endif 38 54 -
uspace/lib/c/arch/sparc64/src/thread_entry.S
r2cf8f994 r3fcea34 35 35 # 36 36 SYMBOL(__thread_entry) 37 add %sp, 0x7ff, %g1 38 37 39 # 38 40 # Create the first stack frame. … … 43 45 44 46 # 45 # Propagate the input arguments to the new window.47 # Load libc entry point address and argument from stack 46 48 # 49 ldn [%g1 - 8], %o0 50 ldn [%g1 - 16], %g1 47 51 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 50 55 51 56 ! not reached -
uspace/lib/c/generic/private/fibril.h
r2cf8f994 r3fcea34 33 33 #include <context.h> 34 34 #include <tls.h> 35 #include <abi/proc/uarg.h>36 35 #include <fibril.h> 37 36 #include <ipc/common.h> … … 50 49 context_t ctx; 51 50 52 uspace_arg_t uarg;53 51 link_t link; 54 52 void *stack; -
uspace/lib/c/generic/private/thread.h
r2cf8f994 r3fcea34 37 37 38 38 #include <time.h> 39 #include <abi/proc/uarg.h>40 39 #include <libarch/thread.h> 41 40 #include <abi/proc/thread.h> 42 41 43 42 extern void __thread_entry(void); 44 extern void __thread_main(uspace_arg_t *);45 43 46 extern errno_t thread_create(void (*)(void *), void *, const char *, 47 thread_id_t *); 44 extern errno_t thread_create(errno_t (*)(void *), void *, const char *); 48 45 extern void thread_exit(int) __attribute__((noreturn)); 49 extern void thread_detach(thread_id_t);50 46 extern thread_id_t thread_get_id(void); 51 47 extern void thread_usleep(usec_t); -
uspace/lib/c/generic/thread/fibril.c
r2cf8f994 r3fcea34 781 781 } 782 782 783 static void_runner_fn(void *arg)783 static errno_t _runner_fn(void *arg) 784 784 { 785 785 _helper_fibril_fn(arg); 786 return EOK; 786 787 } 787 788 … … 808 809 809 810 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"); 812 812 if (rc != EOK) 813 813 return i; 814 thread_detach(tid);815 814 } 816 815 -
uspace/lib/c/generic/thread/thread.c
r2cf8f994 r3fcea34 37 37 #include <stdlib.h> 38 38 #include <libarch/faddr.h> 39 #include <abi/proc/uarg.h>40 39 #include <fibril.h> 41 40 #include <stack.h> … … 54 53 * and exit when thread returns back. 55 54 * 56 * @param uarg Pointer to userspace argument structure.55 * @param arg Fibril pointer. 57 56 * 58 57 */ 59 void __thread_main(uspace_arg_t *uarg)58 static void __thread_main(void *arg) 60 59 { 60 fibril_t *fibril = arg; 61 61 62 assert(!__tcb_is_set()); 62 63 fibril_t *fibril = uarg->uspace_thread_arg;64 63 assert(fibril); 65 64 66 65 __tcb_set(fibril->tcb); 67 66 68 uarg->uspace_thread_function(fibril->arg);67 fibril->func(fibril->arg); 69 68 /* 70 69 * XXX: we cannot free the userspace stack while running on it … … 90 89 * @return Zero on success or a code from @ref errno.h on failure. 91 90 */ 92 errno_t thread_create(void (*function)(void *), void *arg, const char *name, 93 thread_id_t *tid) 91 errno_t thread_create(errno_t (*func)(void *), void *arg, const char *name) 94 92 { 95 uspace_arg_t *uarg = calloc(1, sizeof(uspace_arg_t));96 if (! uarg)93 fibril_t *fibril = fibril_alloc(); 94 if (!fibril) 97 95 return ENOMEM; 98 96 99 fibril_t *fibril = fibril_alloc(); 100 if (!fibril) { 101 free(uarg); 102 return ENOMEM; 103 } 97 fibril->func = func; 98 fibril->arg = arg; 104 99 105 100 size_t stack_size = stack_size_get(); … … 109 104 if (stack == AS_MAP_FAILED) { 110 105 fibril_teardown(fibril); 111 free(uarg);112 106 return ENOMEM; 113 107 } 114 108 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); 122 111 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)); 125 115 126 116 if (rc != EOK) { … … 130 120 */ 131 121 as_area_destroy(stack); 132 free(uarg);133 122 } 134 123 … … 148 137 while (true) 149 138 ; 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 {160 139 } 161 140
Note:
See TracChangeset
for help on using the changeset viewer.