~ubuntu-branches/debian/sid/botan/sid

« back to all changes in this revision

Viewing changes to src/lib/utils/cpuid/cpuid_ppc.cpp

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2018-03-01 22:23:25 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20180301222325-7p7vc45gu3hta34d
Tags: 2.4.0-2
* Don't remove .doctrees from the manual if it doesn't exist.
* Don't specify parallel to debhelper.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* Runtime CPU detection for POWER/PowerPC
 
3
* (C) 2009,2010,2013,2017 Jack Lloyd
 
4
*
 
5
* Botan is released under the Simplified BSD License (see license.txt)
 
6
*/
 
7
 
 
8
#include <botan/cpuid.h>
 
9
#include <botan/internal/os_utils.h>
 
10
 
 
11
#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
 
12
 
 
13
/*
 
14
* On Darwin and OpenBSD ppc, use sysctl to detect AltiVec
 
15
*/
 
16
#if defined(BOTAN_TARGET_OS_IS_DARWIN)
 
17
  #include <sys/sysctl.h>
 
18
#elif defined(BOTAN_TARGET_OS_IS_OPENBSD)
 
19
  #include <sys/param.h>
 
20
  #include <sys/sysctl.h>
 
21
  #include <machine/cpu.h>
 
22
#endif
 
23
 
 
24
#endif
 
25
 
 
26
namespace Botan {
 
27
 
 
28
#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
 
29
 
 
30
/*
 
31
* PowerPC specific block: check for AltiVec using either
 
32
* sysctl or by reading processor version number register.
 
33
*/
 
34
uint64_t CPUID::detect_cpu_features(size_t* cache_line_size)
 
35
   {
 
36
#if defined(BOTAN_TARGET_OS_IS_DARWIN) || defined(BOTAN_TARGET_OS_IS_OPENBSD)
 
37
   // On Darwin/OS X and OpenBSD, use sysctl
 
38
 
 
39
   int sels[2] = {
 
40
#if defined(BOTAN_TARGET_OS_IS_OPENBSD)
 
41
      CTL_MACHDEP, CPU_ALTIVEC
 
42
#else
 
43
      CTL_HW, HW_VECTORUNIT
 
44
#endif
 
45
   };
 
46
 
 
47
   int vector_type = 0;
 
48
   size_t length = sizeof(vector_type);
 
49
   int error = ::sysctl(sels, 2, &vector_type, &length, NULL, 0);
 
50
 
 
51
   if(error == 0 && vector_type > 0)
 
52
      return CPUID::CPUID_ALTIVEC_BIT;
 
53
 
 
54
#else
 
55
 
 
56
   /*
 
57
   On PowerPC, MSR 287 is PVR, the Processor Version Number
 
58
   Normally it is only accessible to ring 0, but Linux and NetBSD
 
59
   (others, too, maybe?) will trap and emulate it for us.
 
60
   */
 
61
 
 
62
   int pvr = OS::run_cpu_instruction_probe([]() -> int {
 
63
      uint32_t pvr = 0;
 
64
      asm volatile("mfspr %0, 287" : "=r" (pvr));
 
65
      // Top 16 bits suffice to identify the model
 
66
      return static_cast<int>(pvr >> 16);
 
67
      });
 
68
 
 
69
   if(pvr > 0)
 
70
      {
 
71
      const uint16_t ALTIVEC_PVR[] = {
 
72
         0x003E, // IBM POWER6
 
73
         0x003F, // IBM POWER7
 
74
         0x004A, // IBM POWER7p
 
75
         0x004D, // IBM POWER8
 
76
         0x004B, // IBM POWER8E
 
77
         0x000C, // G4-7400
 
78
         0x0039, // G5 970
 
79
         0x003C, // G5 970FX
 
80
         0x0044, // G5 970MP
 
81
         0x0070, // Cell PPU
 
82
         0, // end
 
83
      };
 
84
 
 
85
      for(size_t i = 0; ALTIVEC_PVR[i]; ++i)
 
86
         {
 
87
         if(pvr == ALTIVEC_PVR[i])
 
88
            return CPUID::CPUID_ALTIVEC_BIT;
 
89
         }
 
90
 
 
91
      return 0;
 
92
      }
 
93
 
 
94
   // TODO try direct instruction probing
 
95
 
 
96
#endif
 
97
 
 
98
   return 0;
 
99
   }
 
100
 
 
101
#endif
 
102
 
 
103
}