github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/runtime/os_linux_arm.c (about)

     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  #include "runtime.h"
     6  #include "defs_GOOS_GOARCH.h"
     7  #include "os_GOOS.h"
     8  
     9  #define AT_NULL		0
    10  #define AT_PLATFORM	15 // introduced in at least 2.6.11
    11  #define AT_HWCAP	16 // introduced in at least 2.6.11
    12  #define AT_RANDOM	25 // introduced in 2.6.29
    13  #define HWCAP_VFP	(1 << 6) // introduced in at least 2.6.11
    14  #define HWCAP_VFPv3	(1 << 13) // introduced in 2.6.30
    15  static uint32 runtime·randomNumber;
    16  uint8  runtime·armArch = 6;	// we default to ARMv6
    17  uint32 runtime·hwcap;	// set by setup_auxv
    18  uint8  runtime·goarm;	// set by 5l
    19  
    20  void
    21  runtime·checkgoarm(void)
    22  {
    23  	if(runtime·goarm > 5 && !(runtime·hwcap & HWCAP_VFP)) {
    24  		runtime·printf("runtime: this CPU has no floating point hardware, so it cannot run\n");
    25  		runtime·printf("this GOARM=%d binary. Recompile using GOARM=5.\n", runtime·goarm);
    26  		runtime·exit(1);
    27  	}
    28  	if(runtime·goarm > 6 && !(runtime·hwcap & HWCAP_VFPv3)) {
    29  		runtime·printf("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n");
    30  		runtime·printf("this GOARM=%d binary. Recompile using GOARM=6.\n", runtime·goarm);
    31  		runtime·exit(1);
    32  	}
    33  }
    34  
    35  #pragma textflag 7
    36  void
    37  runtime·setup_auxv(int32 argc, void *argv_list)
    38  {
    39  	byte **argv;
    40  	byte **envp;
    41  	byte *rnd;
    42  	uint32 *auxv;
    43  	uint32 t;
    44  
    45  	argv = &argv_list;
    46  
    47  	// skip envp to get to ELF auxiliary vector.
    48  	for(envp = &argv[argc+1]; *envp != nil; envp++)
    49  		;
    50  	envp++;
    51  	
    52  	for(auxv=(uint32*)envp; auxv[0] != AT_NULL; auxv += 2) {
    53  		switch(auxv[0]) {
    54  		case AT_RANDOM: // kernel provided 16-byte worth of random data
    55  			if(auxv[1]) {
    56  				rnd = (byte*)auxv[1];
    57  				runtime·randomNumber = rnd[4] | rnd[5]<<8 | rnd[6]<<16 | rnd[7]<<24;
    58  			}
    59  			break;
    60  		case AT_PLATFORM: // v5l, v6l, v7l
    61  			if(auxv[1]) {
    62  				t = *(uint8*)(auxv[1]+1);
    63  				if(t >= '5' && t <= '7')
    64  					runtime·armArch = t - '0';
    65  			}
    66  			break;
    67  		case AT_HWCAP: // CPU capability bit flags
    68  			runtime·hwcap = auxv[1];
    69  			break;
    70  		}
    71  	}
    72  }
    73  
    74  #pragma textflag 7
    75  int64
    76  runtime·cputicks(void)
    77  {
    78  	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
    79  	// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
    80  	// runtime·randomNumber provides better seeding of fastrand1.
    81  	return runtime·nanotime() + runtime·randomNumber;
    82  }