File: archdetect-mips-linux.c

package info (click to toggle)
ddetect 1.14
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 736 kB
  • ctags: 112
  • sloc: sh: 872; ansic: 533; makefile: 93
file content (144 lines) | stat: -rw-r--r-- 3,105 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "archdetect.h"

struct cpu {
	char *cpu;
	char *ret;
};

struct systype {
	char *sys;
	struct cpu *cpu;
};

static struct cpu system_sgi_ind_cpu[] = {
	/* match various R4000 variants */
	{ "R4", "r4k-ip22" },
	{ "R5000", "r5k-ip22" },
	{ "R8000", "r8k-ip26" },
	{ "R10000", "r10k-ip28" },
	{ NULL, "unknown" }
};

static struct cpu system_sgi_origin_cpu[] = {
	{ "R10000", "r10k-ip27" },
	{ "R12000", "r12k-ip27" },
	{ NULL, "unknown" }
};

static struct cpu system_sgi_o2_cpu[] = {
	/* match R5000 and R5500 */
	{ "R5", "r5k-ip32" },
	{ "RM7000", "r5k-ip32" },
	{ "R10000", "r10k-ip32" },
	{ "R12000", "r12k-ip32" },
	{ NULL, "unknown" }
};

static struct cpu system_sibyte_sb1_cpu[] = {
	{ "SiByte SB1", "sb1-swarm-bn" },
	{ NULL, "unknown" }
};

static struct cpu system_sni_rm200c_cpu[] = {
	/* match various R4000 variants */
	{ "R4", "r4k-rm200c" },
	{ NULL, "unknown" }
};

/* add new system types here */

static struct cpu system_unknown_cpu[] = {
	{ NULL, "unknown" }
};

static struct systype system_type[] = {
	/* match "SGI Indy" and "SGI Indigo2" */
	{"SGI Ind", system_sgi_ind_cpu },
	/* SGI Origin (ip27) */
	{"SGI Origin", system_sgi_origin_cpu },
	/* SGI O2 (ip32) */
	{"SGI IP32", system_sgi_o2_cpu },
	{"SGI O2", system_sgi_o2_cpu },
	/* match the Broadcom SWARM development board */
	{"SiByte BCM91250A", system_sibyte_sb1_cpu },
	/* SNI RM200C */
	{"SNI RM200_PCI", system_sni_rm200c_cpu },
	/* add new system types here */
	{ NULL, system_unknown_cpu }
};

#define INVALID_SYS_IDX (sizeof(system_type) / sizeof(struct systype) - 1)
#define INVALID_CPU_IDX (-1)

#define BUFFER_LENGTH (1024)

static int check_system(const char *entry)
{
	int ret;

	for (ret = 0; system_type[ret].sys; ret++) {
		if (!strncmp(system_type[ret].sys, entry,
			     strlen(system_type[ret].sys)))
			break;
	}

	return ret;
}

static int check_cpu(const char *entry, int sys_idx)
{
	int ret;

	if (sys_idx == INVALID_SYS_IDX) {
		/*
		 * This means an unsupported system type, because the
		 * system type is always the first entry in /proc/cpuinfo.
		 */
		return INVALID_CPU_IDX;
	}

	for (ret = 0; system_type[sys_idx].cpu[ret].cpu; ret++) {
		if (!strncmp(system_type[sys_idx].cpu[ret].cpu, entry,
			     strlen(system_type[sys_idx].cpu[ret].cpu)))
			break;
	}

	return ret;
}

const char *subarch_analyze(void)
{
	FILE *file;
	int sys_idx = INVALID_SYS_IDX;
	int cpu_idx = INVALID_CPU_IDX;
	char buf[BUFFER_LENGTH];
        char *pos;
	size_t len;

	if (!(file = fopen("/proc/cpuinfo", "r")))
		return system_type[sys_idx].cpu[0].ret;

	while (fgets(buf, sizeof(buf), file)) {
		if (!(pos = strchr(buf, ':')))
			continue;
		if (!(len = strspn(pos, ": \t")))
			continue;
		if (!strncmp(buf, "system type", strlen("system type")))
			sys_idx = check_system(pos + len);
		else if (!strncmp(buf, "cpu model", strlen("cpu model")))
			cpu_idx = check_cpu(pos + len, sys_idx);
	}

	fclose(file);

	if (cpu_idx == INVALID_CPU_IDX) {
		sys_idx = INVALID_SYS_IDX;
		cpu_idx = 0;
	}

	return system_type[sys_idx].cpu[cpu_idx].ret;
}