github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/kernel/isyscall/syscall.go (about)

     1  package isyscall
     2  
     3  import (
     4  	"syscall"
     5  	_ "unsafe"
     6  )
     7  
     8  const (
     9  	EPANIC syscall.Errno = 0xfffff
    10  )
    11  
    12  var (
    13  	handlers [512]Handler
    14  )
    15  
    16  //go:linkname wakeup github.com/icexin/eggos/kernel.wakeup
    17  func wakeup(lock *uintptr, n int)
    18  
    19  type Handler func(req *Request)
    20  
    21  type Request struct {
    22  	tf *trapFrame
    23  
    24  	Lock uintptr
    25  }
    26  
    27  //go:nosplit
    28  func (r *Request) NO() uintptr {
    29  	return r.tf.NO()
    30  }
    31  
    32  //go:nosplit
    33  func (r *Request) Arg(n int) uintptr {
    34  	return r.tf.Arg(n)
    35  }
    36  
    37  //go:nosplit
    38  func (r *Request) SetRet(v uintptr) {
    39  	r.tf.SetRet(v)
    40  }
    41  
    42  //go:nosplit
    43  func (r *Request) Ret() uintptr {
    44  	return r.tf.Ret()
    45  }
    46  
    47  //go:nosplit
    48  func (r *Request) SetErrorNO(errno syscall.Errno) {
    49  	r.SetRet(Errno(errno))
    50  }
    51  
    52  //go:nosplit
    53  func (r *Request) SetError(err error) {
    54  	if err == nil {
    55  		r.SetRet(0)
    56  		return
    57  	}
    58  	r.SetRet(Error(err))
    59  }
    60  
    61  func (r *Request) Done() {
    62  	wakeup(&r.Lock, 1)
    63  }
    64  
    65  func GetHandler(no uintptr) Handler {
    66  	return handlers[no]
    67  }
    68  
    69  func Register(no uintptr, handler Handler) {
    70  	handlers[no] = handler
    71  }
    72  
    73  func Errno(code syscall.Errno) uintptr {
    74  	return uintptr(-code)
    75  }
    76  
    77  func Error(err error) uintptr {
    78  	if err == nil {
    79  		return 0
    80  	}
    81  	if code, ok := err.(syscall.Errno); ok {
    82  		return Errno(code)
    83  	}
    84  	ret := uintptr(syscall.EINVAL)
    85  	return -ret
    86  }