xref: /haiku/src/system/libroot/os/system_info.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 /*
2  * Copyright 2013, Paweł Dziepak, pdziepak@quarnos.org.
3  * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include <OS.h>
9 
10 #include <string.h>
11 
12 #include <algorithm>
13 
14 #include <syscalls.h>
15 #include <system_info.h>
16 
17 
18 #if _BEOS_R5_COMPATIBLE_
19 
20 
21 #define LEGACY_B_CPU_X86			15
22 
23 #define LEGACY_B_AT_CLONE_PLATFORM	2
24 
25 typedef struct {
26 	bigtime_t	active_time;	/* usec of doing useful work since boot */
27 } legacy_cpu_info;
28 
29 typedef struct {
30 	int32			id[2];				/* unique machine ID */
31 	bigtime_t		boot_time;			/* time of boot (usecs since 1/1/1970) */
32 
33 	int32			cpu_count;			/* number of cpus */
34 	int32			cpu_type;			/* type of cpu */
35 	int32			cpu_revision;		/* revision # of cpu */
36 	legacy_cpu_info	cpu_infos[8];		/* info about individual cpus */
37 	int64			cpu_clock_speed;	/* processor clock speed (Hz) */
38 	int64			bus_clock_speed;	/* bus clock speed (Hz) */
39 	int32			platform_type;	/* type of machine we're on */
40 
41 	int32			max_pages;			/* total # of accessible pages */
42 	int32			used_pages;			/* # of accessible pages in use */
43 	int32			page_faults;		/* # of page faults */
44 	int32			max_sems;
45 	int32			used_sems;
46 	int32			max_ports;
47 	int32			used_ports;
48 	int32			max_threads;
49 	int32			used_threads;
50 	int32			max_teams;
51 	int32			used_teams;
52 
53 	char			kernel_name[256];
54 	char			kernel_build_date[32];
55 	char			kernel_build_time[32];
56 	int64			kernel_version;
57 
58 	bigtime_t		_busy_wait_time;	/* reserved for whatever */
59 
60 	int32			cached_pages;
61 	uint32			abi;				/* the system API */
62 	int32			ignored_pages;		/* # of ignored/inaccessible pages */
63 	int32			pad;
64 } legacy_system_info;
65 
66 
67 extern "C" status_t
68 _get_system_info(legacy_system_info* info, size_t size)
69 {
70 	if (info == NULL || size != sizeof(legacy_system_info))
71 		return B_BAD_VALUE;
72 	memset(info, 0, sizeof(legacy_system_info));
73 
74 	system_info systemInfo;
75 	status_t error = _kern_get_system_info(&systemInfo);
76 	if (error != B_OK)
77 		return error;
78 
79 	cpu_info cpuInfos[8];
80 	error = _kern_get_cpu_info(0, std::min(systemInfo.cpu_count, uint32(8)),
81 			cpuInfos);
82 	if (error != B_OK)
83 		return error;
84 
85 	info->boot_time = systemInfo.boot_time;
86 	info->cpu_count = std::min(systemInfo.cpu_count, uint32(8));
87 	for (int32 i = 0; i < info->cpu_count; i++)
88 		info->cpu_infos[i].active_time = cpuInfos[i].active_time;
89 
90 	info->platform_type = LEGACY_B_AT_CLONE_PLATFORM;
91 	info->cpu_type = LEGACY_B_CPU_X86;
92 
93 	uint32 topologyNodeCount = 0;
94 	cpu_topology_node_info* topology = NULL;
95 	error = get_cpu_topology_info(NULL, &topologyNodeCount);
96 	if (error != B_OK)
97 		return B_OK;
98 	if (topologyNodeCount != 0) {
99 		topology = new(std::nothrow) cpu_topology_node_info[topologyNodeCount];
100 		if (topology == NULL)
101 			return B_NO_MEMORY;
102 	}
103 	error = get_cpu_topology_info(topology, &topologyNodeCount);
104 	if (error != B_OK) {
105 		delete[] topology;
106 		return error;
107 	}
108 
109 	for (uint32 i = 0; i < topologyNodeCount; i++) {
110 		if (topology[i].type == B_TOPOLOGY_CORE) {
111 			info->cpu_clock_speed = topology[i].data.core.default_frequency;
112 			break;
113 		}
114 	}
115 	info->bus_clock_speed = info->cpu_clock_speed;
116 	delete[] topology;
117 
118 	info->max_pages = std::min(systemInfo.max_pages, uint64(INT32_MAX));
119 	info->used_pages = std::min(systemInfo.used_pages, uint64(INT32_MAX));
120 	info->cached_pages = std::min(systemInfo.cached_pages, uint64(INT32_MAX));
121 	info->ignored_pages = std::min(systemInfo.ignored_pages, uint64(INT32_MAX));
122 	info->page_faults = std::min(systemInfo.page_faults, uint32(INT32_MAX));
123 	info->max_sems = std::min(systemInfo.max_sems, uint32(INT32_MAX));
124 	info->used_sems = std::min(systemInfo.used_sems, uint32(INT32_MAX));
125 	info->max_ports = std::min(systemInfo.max_ports, uint32(INT32_MAX));
126 	info->used_ports = std::min(systemInfo.used_ports, uint32(INT32_MAX));
127 	info->max_threads = std::min(systemInfo.max_threads, uint32(INT32_MAX));
128 	info->used_threads = std::min(systemInfo.used_threads, uint32(INT32_MAX));
129 	info->max_teams = std::min(systemInfo.max_teams, uint32(INT32_MAX));
130 	info->used_teams = std::min(systemInfo.used_teams, uint32(INT32_MAX));
131 
132 	strlcpy(info->kernel_name, systemInfo.kernel_name,
133 		sizeof(info->kernel_name));
134 	strlcpy(info->kernel_build_date, systemInfo.kernel_build_date,
135 		sizeof(info->kernel_build_date));
136 	strlcpy(info->kernel_build_time, systemInfo.kernel_build_time,
137 		sizeof(info->kernel_build_time));
138 	info->kernel_version = systemInfo.kernel_version;
139 
140 	info->abi = systemInfo.abi;
141 
142 	return B_OK;
143 }
144 
145 
146 #endif	// _BEOS_R5_COMPATIBLE_
147 
148 
149 status_t
150 __get_system_info(system_info* info)
151 {
152 	return _kern_get_system_info(info);
153 }
154 
155 
156 typedef struct {
157 	bigtime_t	active_time;
158 	bool		enabled;
159 } beta2_cpu_info;
160 
161 
162 extern "C" status_t
163 __get_cpu_info(uint32 firstCPU, uint32 cpuCount, beta2_cpu_info* beta2_info)
164 {
165 	cpu_info info;
166 	status_t err = _get_cpu_info_etc(firstCPU, cpuCount, &info, sizeof(info));
167 	if (err == B_OK) {
168 		beta2_info->active_time = info.active_time;
169 		beta2_info->enabled = info.enabled;
170 	}
171 	return err;
172 }
173 
174 
175 status_t
176 _get_cpu_info_etc(uint32 firstCPU, uint32 cpuCount, cpu_info* info,
177 	size_t size)
178 {
179 	if (info == NULL || size != sizeof(cpu_info))
180 		return B_BAD_VALUE;
181 	return _kern_get_cpu_info(firstCPU, cpuCount, info);
182 }
183 
184 
185 status_t
186 __get_cpu_topology_info(cpu_topology_node_info* topologyInfos,
187 	uint32* topologyInfoCount)
188 {
189 	return _kern_get_cpu_topology_info(topologyInfos, topologyInfoCount);
190 }
191 
192 
193 status_t
194 __start_watching_system(int32 object, uint32 flags, port_id port, int32 token)
195 {
196 	return _kern_start_watching_system(object, flags, port, token);
197 }
198 
199 
200 status_t
201 __stop_watching_system(int32 object, uint32 flags, port_id port, int32 token)
202 {
203 	return _kern_stop_watching_system(object, flags, port, token);
204 }
205 
206 
207 int32
208 is_computer_on(void)
209 {
210 	return _kern_is_computer_on();
211 }
212 
213 
214 double
215 is_computer_on_fire(void)
216 {
217 	return 0.63739;
218 }
219 
220 
221 B_DEFINE_WEAK_ALIAS(__get_system_info, get_system_info);
222 B_DEFINE_WEAK_ALIAS(__get_cpu_info, get_cpu_info);
223 B_DEFINE_WEAK_ALIAS(__get_cpu_topology_info, get_cpu_topology_info);
224 
225