blob: 5edb1207d574c00fbb4f9cb33f985868df8a09b6 [file] [log] [blame]
petarj0432cfe2013-09-15 22:49:01 +00001// This file determines MIPS features a processor supports.
dejanjbf68e982013-08-02 15:39:58 +00002//
3// We return:
4// - 0 if the machine matches the asked-for feature.
5// - 1 if the machine does not.
6// - 2 if the asked-for feature isn't recognised (this will be the case for
petarj0432cfe2013-09-15 22:49:01 +00007// any feature if run on a non-MIPS machine).
dejanjbf68e982013-08-02 15:39:58 +00008// - 3 if there was a usage error (it also prints an error message).
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <assert.h>
13
14#define FEATURE_PRESENT 0
15#define FEATURE_NOT_PRESENT 1
16#define UNRECOGNISED_FEATURE 2
17#define USAGE_ERROR 3
18
petarj0432cfe2013-09-15 22:49:01 +000019#if defined(VGA_mips32) || defined(VGA_mips64)
dejanjbf68e982013-08-02 15:39:58 +000020static int mipsCPUInfo(const char *search_string) {
21 const char *file_name = "/proc/cpuinfo";
22 /* Simple detection of MIPS DSP ASE at runtime for Linux.
23 * It is based on /proc/cpuinfo, which reveals hardware configuration
24 * to user-space applications. */
25
26 char cpuinfo_line[256];
27
28 FILE *f = NULL;
29 if ((f = fopen (file_name, "r")) == NULL)
30 return 0;
31
32 while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL)
33 {
34 if (strstr (cpuinfo_line, search_string) != NULL)
35 {
36 fclose (f);
37 return 1;
38 }
39 }
40
41 fclose (f);
42
43 /* Did not find string in the /proc/cpuinfo file. */
44 return 0;
45}
46
47static int go(char *feature)
48{
49 int cpuinfo;
petarj4110f6a2014-09-27 05:33:07 +000050 if (strcmp(feature, "fpu") == 0) {
petarj88cd1622014-09-27 05:18:21 +000051#if defined(__mips_hard_float)
52 /* This is not a runtime detection.
53 If mips_features is built as hard-float, the assumption is that
54 the target MIPS platform has a floating-point unit. */
55 return FEATURE_PRESENT;
56#else
57 return FEATURE_NOT_PRESENT;
58#endif
59 }
60 else if (strcmp(feature, "mips32-dsp") == 0) {
dejanjbf68e982013-08-02 15:39:58 +000061 const char *dsp = "dsp";
62 cpuinfo = mipsCPUInfo(dsp);
63 if (cpuinfo == 1) {
64 return FEATURE_PRESENT;
65 } else{
66 return FEATURE_NOT_PRESENT;
67 }
petarj55e7f192014-01-29 15:58:09 +000068 } else if (strcmp(feature, "mips32-dspr2") == 0) {
dejanjbf68e982013-08-02 15:39:58 +000069 const char *dsp2 = "dsp2";
70 cpuinfo = mipsCPUInfo(dsp2);
71 if (cpuinfo == 1) {
72 return FEATURE_PRESENT;
73 } else{
74 return FEATURE_NOT_PRESENT;
75 }
petarj55e7f192014-01-29 15:58:09 +000076 } else if (strcmp(feature, "cavium-octeon") == 0) {
petarj0432cfe2013-09-15 22:49:01 +000077 const char *cavium = "Cavium Octeon";
78 cpuinfo = mipsCPUInfo(cavium);
79 if (cpuinfo == 1) {
80 return FEATURE_PRESENT;
81 } else{
82 return FEATURE_NOT_PRESENT;
83 }
petarj55e7f192014-01-29 15:58:09 +000084 } else if (strcmp(feature, "cavium-octeon2") == 0) {
85 const char *cavium2 = "Cavium Octeon II";
86 cpuinfo = mipsCPUInfo(cavium2);
87 if (cpuinfo == 1) {
88 return FEATURE_PRESENT;
89 } else{
90 return FEATURE_NOT_PRESENT;
91 }
dejanjb3eae3e2014-03-19 15:44:19 +000092 } else if (strcmp(feature, "mips-be") == 0) {
93#if defined (_MIPSEB)
94 return FEATURE_PRESENT;
95#else
96 return FEATURE_NOT_PRESENT;
97#endif
dejanjbf68e982013-08-02 15:39:58 +000098 } else {
99 return UNRECOGNISED_FEATURE;
100 }
101
102}
103
104#else
105
106static int go(char *feature)
107{
petarj0432cfe2013-09-15 22:49:01 +0000108 /* Feature is not recognised. (non-MIPS machine!) */
dejanjbf68e982013-08-02 15:39:58 +0000109 return UNRECOGNISED_FEATURE;
110}
111
112#endif
113
114
115//---------------------------------------------------------------------------
116// main
117//---------------------------------------------------------------------------
118int main(int argc, char **argv)
119{
120 if (argc != 2) {
petarj0432cfe2013-09-15 22:49:01 +0000121 fprintf( stderr, "usage: mips_features <feature>\n" );
dejanjbf68e982013-08-02 15:39:58 +0000122 exit(USAGE_ERROR);
123 }
124 return go(argv[1]);
125}