;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; This file is part of 'M', a MIPS system emulator. ;; ;; ;; ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;; ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;; ;; ;; ;; You do not have, nor can you ever acquire the right to use, copy or ;; ;; distribute this software ; Should you use this software for any purpose, ;; ;; or copy and distribute it to anyone or in any manner, you are breaking ;; ;; the laws of whatever soi-disant jurisdiction, and you promise to ;; ;; continue doing so for the indefinite future. In any case, please ;; ;; always : read and understand any software ; verify any PGP signatures ;; ;; that you use - for any purpose. ;; ;; ;; ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;----------------------------------------------------------------------------- %macro PUSHA 0 push rax push rbx push rcx push rdx push rbp push rdi push rsi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 ; lea rsp,[rsp-16*4] ; movdqu [rsp+16*0], xmm0 ; movdqu [rsp+16*1], xmm1 ; movdqu [rsp+16*2], xmm2 ; movdqu [rsp+16*3], xmm2 %endmacro ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- %macro POPA 0 ; movdqu xmm1,[rsp+16*3] ; movdqu xmm1,[rsp+16*2] ; movdqu xmm1,[rsp+16*1] ; movdqu xmm0,[rsp+16*0] ; lea rsp,[rsp+16*4] pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rsi pop rdi pop rbp pop rdx pop rcx pop rbx pop rax %endmacro ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; x64 sys calls %define SYS_BRK 12 %define SYS_EXIT 60 %define SYS_EXIT_GROUP 231 %define SYS_READ 0 %define SYS_WRITE 1 %define SYS_OPEN 2 %define SYS_CLOSE 3 %define SYS_FSTAT 5 %define SYS_MMAP 9 %define SYS_MUNMAP 11 %define SYS_NANOSLEEP 35 %define SYS_TIME 201 ; For threadism: %define SYS_CLONE 56 ; For tty cure: %define SYS_IOCTL 16 ; For sys_mmap %define PROT_READ 1 %define PROT_WRITE 2 %define MAP_PRIVATE 2 ; Output fd's: %define STDOUT 1 %define STDERR 2 ;----------------------------------------------------------------------------- ; For threadism: ;; sched.h %define CLONE_VM 0x00000100 %define CLONE_FS 0x00000200 %define CLONE_FILES 0x00000400 %define CLONE_SIGHAND 0x00000800 %define CLONE_PARENT 0x00008000 %define CLONE_THREAD 0x00010000 %define CLONE_IO 0x80000000 ;; sys/mman.h %define MAP_GROWSDOWN 0x0100 %define MAP_ANONYMOUS 0x0020 %define MAP_PRIVATE 0x0002 %define PROT_READ 0x1 %define PROT_WRITE 0x2 %define PROT_EXEC 0x4 %define THREAD_FLAGS \ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_PARENT | \ CLONE_THREAD | CLONE_IO ;----------------------------------------------------------------------------- ; Pill for linux's tty buffering retardation %define ICANON 2 %define ECHO 8 %define TCGETS 21505 ; to read back the termios config %define TCPUTS 21508 ; to set the termios config ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; For output of sys_fstat struc statbuf .st_dev resq 1 .st_ino resq 1 .st_nlink resq 1 .st_mode resd 1 .st_uid resd 1 .st_gid resd 1 .__pad0 resd 1 .st_rdev resq 1 .st_size resq 1 ; file size in bytes .st_blksize resq 1 .st_blocks resq 1 .st_atime resq 1 .st_atime_nsec resq 1 .st_mtime resq 1 .st_mtime_nsec resq 1 .st_ctime resq 1 .st_ctime_nsec resq 1 .__unused resq 3 .size endstruc ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ;; State ;----------------------------------------------------------------------------- section .bss linux_epoch resq 1 ; for _Get_Epoch_Time ;----------------------------------------------------------------------------- section .text ;----------------------------------------------------------------------------- ; For spawning slave threads: ;----------------------------------------------------------------------------- _Create_Thread: push rdi ;; Allocate stack for the new thread: mov rdi, 0 mov rsi, SLAVE_STACK_SIZE mov rdx, PROT_WRITE | PROT_READ mov r10, MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN mov rax, SYS_MMAP syscall ; invoke mmap ;; Verify whether we actually got our memory: cmp rax, 0 jg .ok ;; ... if not: EGGOG "Could not allocate memory for slave stack!" .ok: ;; we got the memory; ;; Actually spawn the thread: lea rsi, [rax + SLAVE_STACK_SIZE - 8] pop qword [rsi] mov rdi, THREAD_FLAGS mov rax, SYS_CLONE syscall ret ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Get Epoch Time from OS. Return in RDX. ;----------------------------------------------------------------------------- _Get_Epoch_Time: PUSHA mov rax, SYS_TIME ; sys_time mov rdi, linux_epoch ; where it will be written syscall ; invoke the call POPA mov rdx, qword [linux_epoch] ; return all 64 bits of epoch time ret ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; 'NanoSleep' (rax : pointer to TS structure) ;----------------------------------------------------------------------------- _Nano_Sleep: mov rdi, rax mov rax, SYS_NANOSLEEP ; nanosleep xor rsi, rsi syscall ; Invoke sleep ret ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Terminate Current Thread Only ;----------------------------------------------------------------------------- _Stop: mov rax, SYS_EXIT ; Terminate (current thread only) mov rdi, 0 ; exit code (always 0, for now) syscall ;; no more after this, we're through ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Hard Stop (kill self and all child threads) ;----------------------------------------------------------------------------- _Hard_Stop: mov rax, SYS_EXIT_GROUP ; Terminate Master and all slaves mov rdi, 0 ; exit code (always 0, for now) syscall ;; no more after this, we're through ;-----------------------------------------------------------------------------