Home | History | Annotate | Download | only in runtime
      1 // Copyright 2009 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package runtime
      6 
      7 import "unsafe"
      8 
      9 const (
     10 	_AT_NULL     = 0
     11 	_AT_PLATFORM = 15 //  introduced in at least 2.6.11
     12 	_AT_HWCAP    = 16 // introduced in at least 2.6.11
     13 	_AT_RANDOM   = 25 // introduced in 2.6.29
     14 
     15 	_HWCAP_VFP   = 1 << 6  // introduced in at least 2.6.11
     16 	_HWCAP_VFPv3 = 1 << 13 // introduced in 2.6.30
     17 )
     18 
     19 var randomNumber uint32
     20 var armArch uint8 = 6 // we default to ARMv6
     21 var hwcap uint32      // set by setup_auxv
     22 
     23 func checkgoarm() {
     24 	if goarm > 5 && hwcap&_HWCAP_VFP == 0 {
     25 		print("runtime: this CPU has no floating point hardware, so it cannot run\n")
     26 		print("this GOARM=", goarm, " binary. Recompile using GOARM=5.\n")
     27 		exit(1)
     28 	}
     29 	if goarm > 6 && hwcap&_HWCAP_VFPv3 == 0 {
     30 		print("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n")
     31 		print("this GOARM=", goarm, " binary. Recompile using GOARM=5.\n")
     32 		exit(1)
     33 	}
     34 }
     35 
     36 func sysargs(argc int32, argv **byte) {
     37 	// skip over argv, envv to get to auxv
     38 	n := argc + 1
     39 	for argv_index(argv, n) != nil {
     40 		n++
     41 	}
     42 	n++
     43 	auxv := (*[1 << 28]uint32)(add(unsafe.Pointer(argv), uintptr(n)*ptrSize))
     44 
     45 	for i := 0; auxv[i] != _AT_NULL; i += 2 {
     46 		switch auxv[i] {
     47 		case _AT_RANDOM: // kernel provides a pointer to 16-bytes worth of random data
     48 			startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
     49 			// the pointer provided may not be word aligned, so we must treat it
     50 			// as a byte array.
     51 			randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
     52 				uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
     53 
     54 		case _AT_PLATFORM: // v5l, v6l, v7l
     55 			t := *(*uint8)(unsafe.Pointer(uintptr(auxv[i+1] + 1)))
     56 			if '5' <= t && t <= '7' {
     57 				armArch = t - '0'
     58 			}
     59 
     60 		case _AT_HWCAP: // CPU capability bit flags
     61 			hwcap = auxv[i+1]
     62 		}
     63 	}
     64 }
     65 
     66 //go:nosplit
     67 func cputicks() int64 {
     68 	// Currently cputicks() is used in blocking profiler and to seed fastrand1().
     69 	// nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
     70 	// randomNumber provides better seeding of fastrand1.
     71 	return nanotime() + int64(randomNumber)
     72 }
     73