xref: /haiku/src/system/kernel/system_info.cpp (revision e0ef64750f3169cd634bb2f7a001e22488b05231)
1 /*
2  * Copyright (c) 2004-2010, Haiku, Inc.
3  * Distributed under the terms of the MIT license.
4  *
5  * Authors:
6  *		Stefano Ceccherini
7  *		Axel Dörfler, axeld@pinc-software.de
8  */
9 
10 
11 #include <ksystem_info.h>
12 #include <system_info.h>
13 #include <arch/system_info.h>
14 
15 #include <string.h>
16 
17 #include <OS.h>
18 #include <KernelExport.h>
19 
20 #include <block_cache.h>
21 #include <cpu.h>
22 #include <debug.h>
23 #include <kernel.h>
24 #include <port.h>
25 #include <real_time_clock.h>
26 #include <sem.h>
27 #include <smp.h>
28 #include <team.h>
29 #include <thread.h>
30 #include <vm/vm.h>
31 #include <vm/vm_page.h>
32 
33 
34 const static int64 kKernelVersion = 0x1;
35 const static char *kKernelName = "kernel_" HAIKU_ARCH;
36 
37 
38 // Haiku SVN revision. Will be set when copying the kernel to the image.
39 // Lives in a separate section so that it can easily be found.
40 static uint32 sHaikuRevision __attribute__((section("_haiku_revision")));
41 
42 
43 static int
44 dump_info(int argc, char **argv)
45 {
46 	kprintf("kernel build: %s %s (gcc%d %s)\n", __DATE__, __TIME__, __GNUC__,
47 		__VERSION__);
48 	kprintf("SVN revision: %lu\n\n", sHaikuRevision);
49 
50 	kprintf("cpu count: %ld, active times:\n", smp_get_num_cpus());
51 
52 	for (int32 i = 0; i < smp_get_num_cpus(); i++)
53 		kprintf("  [%ld] %Ld\n", i + 1, gCPU[i].active_time);
54 
55 	// ToDo: Add page_faults
56 	kprintf("pages:\t\t%" B_PRIuPHYSADDR " (%" B_PRIuPHYSADDR " max)\n",
57 		vm_page_num_pages() - vm_page_num_free_pages(), vm_page_num_pages());
58 
59 	kprintf("sems:\t\t%ld (%ld max)\n", sem_used_sems(), sem_max_sems());
60 	kprintf("ports:\t\t%ld (%ld max)\n", port_used_ports(), port_max_ports());
61 	kprintf("threads:\t%ld (%ld max)\n", thread_used_threads(),
62 		thread_max_threads());
63 	kprintf("teams:\t\t%ld (%ld max)\n", team_used_teams(), team_max_teams());
64 
65 	return 0;
66 }
67 
68 
69 //	#pragma mark -
70 
71 
72 status_t
73 _get_system_info(system_info *info, size_t size)
74 {
75 	if (size != sizeof(system_info))
76 		return B_BAD_VALUE;
77 
78 	memset(info, 0, sizeof(system_info));
79 
80 	info->boot_time = rtc_boot_time();
81 	info->cpu_count = smp_get_num_cpus();
82 
83 	for (int32 i = 0; i < info->cpu_count; i++)
84 		info->cpu_infos[i].active_time = cpu_get_active_time(i);
85 
86 	vm_page_get_stats(info);
87 	// TODO: Add page_faults
88 
89 	info->used_threads = thread_used_threads();
90 	info->max_threads = thread_max_threads();
91 	info->used_teams = team_used_teams();
92 	info->max_teams = team_max_teams();
93 	info->used_ports = port_used_ports();
94 	info->max_ports = port_max_ports();
95 	info->used_sems = sem_used_sems();
96 	info->max_sems = sem_max_sems();
97 
98 	info->kernel_version = kKernelVersion;
99 	strlcpy(info->kernel_name, kKernelName, B_FILE_NAME_LENGTH);
100 	strlcpy(info->kernel_build_date, __DATE__, B_OS_NAME_LENGTH);
101 	strlcpy(info->kernel_build_time, __TIME__, B_OS_NAME_LENGTH);
102 	info->abi = B_HAIKU_ABI;
103 
104 	// all other stuff is architecture specific
105 	return arch_get_system_info(info, size);
106 }
107 
108 
109 status_t
110 system_info_init(struct kernel_args *args)
111 {
112 	add_debugger_command("info", &dump_info, "System info");
113 
114 	return arch_system_info_init(args);
115 }
116 
117 
118 uint32
119 get_haiku_revision(void)
120 {
121 	return sHaikuRevision;
122 }
123 
124 
125 //	#pragma mark -
126 
127 
128 status_t
129 _user_get_system_info(system_info *userInfo, size_t size)
130 {
131 	// The BeBook says get_system_info() always returns B_OK,
132 	// but that ain't true with invalid addresses
133 	if (userInfo == NULL || !IS_USER_ADDRESS(userInfo))
134 		return B_BAD_ADDRESS;
135 
136 	system_info info;
137 	status_t status = _get_system_info(&info, size);
138 	if (status == B_OK) {
139 		if (user_memcpy(userInfo, &info, sizeof(system_info)) < B_OK)
140 			return B_BAD_ADDRESS;
141 
142 		return B_OK;
143 	}
144 
145 	return status;
146 }
147 
148 
149 status_t
150 _user_get_system_info_etc(int32 id, void* userInfo, size_t size)
151 {
152 	if (userInfo == NULL || !IS_USER_ADDRESS(userInfo))
153 		return B_BAD_ADDRESS;
154 
155 	switch (id) {
156 		case B_MEMORY_INFO:
157 		{
158 			if (size < sizeof(system_memory_info))
159 				return B_BAD_VALUE;
160 
161 			system_memory_info info;
162 			vm_get_info(&info);
163 
164 			info.block_cache_memory = block_cache_used_memory();
165 
166 			return user_memcpy(userInfo, &info, sizeof(system_memory_info));
167 		}
168 
169 		default:
170 			return B_BAD_VALUE;
171 	}
172 }
173