1
/* Re-written from scratch 4 March 2001 */
2
/* Handles sparc chips on Linux architecture */
3
/* by Vince Weaver <vince@deater.net> */
7
#include <stdlib.h> /* atof */
10
#include "../sysinfo.h"
11
#include "../include/generic.h"
15
int get_cpu_info(struct cpu_info_type *cpu_info) {
18
char temp_string[BUFSIZ],temp[BUFSIZ];
19
char vendor_string[BUFSIZ],model_string[BUFSIZ];
21
float megahertz=0.0,bogomips=0.0;
23
vendor_string[0]=model_string[0]=0;
25
/* We get all of our info here from /proc/cpuinfo */
26
if ((fff=fopen(get_cpuinfo_file(),"r") )!=NULL) {
28
while ( (fgets(temp_string,BUFSIZ,fff)!=NULL) ) {
30
if ( !(strncmp(temp_string,"cpu",3))) {
31
strncpy(model_string,parse_line(temp_string),BUFSIZ);
32
clip_lf(model_string,BUFSIZ);
35
if ( !(strncmp(temp_string,"ncpus active",12))) {
36
cpu_count=atoi(parse_line(temp_string));
39
/* Suggested change by Ben Collins <bmc@visi.net> */
40
if ( !(strncasecmp(temp_string,"bogomips",8)) ||
41
!(fnmatch("Cpu[0-9]*Bogo*",temp_string,0))) {
44
/* Ugh why must people play with capitalization */
45
if ( !(strncmp(temp_string,"bogomips",8)) ||
46
!(strncmp(temp_string,"BogoMips",8)) ||
47
!(strncmp(temp_string,"BogoMIPS",8)) ||
48
!(strncmp(temp_string,"Cpu",3))) {
50
bogomips+=atof(parse_line(temp_string));
56
strncpy(cpu_info->chip_vendor,"Sparc",SYSINFO_CHIP_VENDOR_SIZE);
57
strncpy(cpu_info->chip_type,model_string,SYSINFO_CHIP_TYPE_SIZE);
59
/* Fix up cpuinfo some */
61
if (!strncmp(model_string,"Cypress",7)) {
62
strncpy(cpu_info->chip_vendor,"Cypress",8);
63
sscanf(model_string,"%*s %s",temp);
64
strncpy(cpu_info->chip_type,temp,SYSINFO_CHIP_TYPE_SIZE);
67
if (!strncmp(model_string,"ROSS",4)) {
68
strncpy(cpu_info->chip_vendor,"ROSS",5);
69
sscanf(model_string,"%*s %s",temp);
70
strncpy(cpu_info->chip_type,temp,SYSINFO_CHIP_TYPE_SIZE);
73
if (!strncmp(model_string,"Texas",5)) {
74
strncpy(cpu_info->chip_vendor,"TI",3);
75
sscanf(model_string,"%*s %*s %*s %*s %s",temp);
76
strncpy(cpu_info->chip_type,temp,SYSINFO_CHIP_TYPE_SIZE);
78
if (strstr(model_string,"UltraSparc II ")!=NULL) {
79
strncpy(cpu_info->chip_type,"UltraSparc II",14);
84
if (strstr(model_string,"SpitFire")!=NULL) {
85
strncpy(cpu_info->chip_type,"SpitFire",9);
87
if (strstr(model_string,"Power-UP")!=NULL) {
88
strncpy(cpu_info->chip_type,"Power-UP",9);
90
if (strstr(model_string,"UltraSparc II ")!=NULL) {
91
strncpy(cpu_info->chip_type,"UltraSparc II",14);
93
if (strstr(model_string,"UltraSparc III+")!=NULL) {
94
strncpy(cpu_info->chip_type,"UltraSparc III+",16);
99
cpu_info->num_cpus=cpu_count;
100
cpu_info->megahertz=megahertz;
101
cpu_info->bogomips=bogomips;
107
int get_hardware(char *hardware_string) {
109
char temp_string[BUFSIZ];
112
if ((fff=fopen(get_cpuinfo_file(),"r") )!=NULL) {
114
while ( (fgets(temp_string,BUFSIZ,fff)!=NULL) ) {
116
if (!(strncmp(temp_string,"type",4))) {
117
strncpy(hardware_string,parse_line(temp_string),
118
SYSINFO_HARDWARE_STRING_SIZE);
126
/* I don't have a machine to test the below code on. I have */
127
/* had multiple reports that the PROM code DOESN'T work, so */
128
/* until someone sends me a patch that fixes it, I have turned */
129
/* off the PROM code */
131
#define CROSS_DEBUGGING 1
133
/* Following routine provided by Ben Collins <bmc@visi.net> */
134
/* Ripped from prtconf: Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) */
137
#if (CROSS_DEBUGGING==1)
139
long long get_arch_specific_mem_size(void) {
141
/* /proc/kcore does not reflect memsize on sparc */
142
return MEM_USE_MEMINFO;
147
#include <sys/ioctl.h>
148
#include <sys/types.h>
149
#include <sys/stat.h>
151
#include <sys/utsname.h>
153
#include <asm/openpromio.h>
156
static char buf[4096];
157
static int prom_root_node, prom_current_node;
158
#define DECL_OP(size) struct openpromio *op = (struct openpromio *)buf; op->oprom_size = (size)
160
static int prom_getsibling(int node) {
162
DECL_OP(sizeof(int));
164
if (node == -1) return 0;
165
*(int *)op->oprom_array = node;
166
if (ioctl (promfd, OPROMNEXT, op) < 0)
168
prom_current_node = *(int *)op->oprom_array;
169
return *(int *)op->oprom_array;
172
static int prom_getchild(int node) {
174
DECL_OP(sizeof(int));
176
if (!node || node == -1) return 0;
177
*(int *)op->oprom_array = node;
178
if (ioctl (promfd, OPROMCHILD, op) < 0)
180
prom_current_node = *(int *)op->oprom_array;
181
return *(int *)op->oprom_array;
184
static char *prom_getproperty(char *prop, int *lenp) {
188
strcpy (op->oprom_array, prop);
189
if (ioctl (promfd, OPROMGETPROP, op) < 0)
191
if (lenp) *lenp = op->oprom_size;
192
return op->oprom_array;
195
static int prom_searchsiblings(char *name) {
201
if (!(prop = prom_getproperty("name", &len)))
204
if (!strcmp(prop, name))
205
return prom_current_node;
206
if (!prom_getsibling(prom_current_node))
211
static inline int is_sparc64(void) {
213
struct utsname uts_info;
217
if (!strcmp(uts_info.machine, "sparc64"))
224
/* On sparc, the best method of memory detection is the prom. We use
225
* sparse memory, so /proc/kcore is almost never right, and we all know
226
* that /proc/meminfo never reports physical ram accurately. */
228
long long get_arch_specific_mem_size(void) {
230
long long memory_size = 0;
234
promfd = open("/dev/openprom", O_RDONLY);
236
memory_size=MEM_USE_MEMINFO;
240
prom_root_node = prom_getsibling(0);
241
if (!prom_root_node) {
242
memory_size=MEM_USE_MEMINFO;
246
prom_getchild(prom_getsibling(0));
247
if (!prom_searchsiblings("memory")) {
248
memory_size=MEM_USE_MEMINFO;
252
prop = (unsigned int *)prom_getproperty("reg", &len);
254
if (!prop || (len % sizeof(int)))
263
for (i = 0; i < len; i+=4) {
264
memory_size += ((unsigned long long)prop[i + 2] << 32);
265
memory_size += prop[i + 3];
272
for (i = 0; i < len; i+=3)
273
memory_size += prop[i + 2];
281
/* Memory size is megabytes */