xref: /haiku/src/system/kernel/system_info.cpp (revision 2222d0559df303a9846a2fad53741f8b20b14d7c)
1 /*
2  * Copyright (c) 2004-2008, 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.h>
31 #include <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\n", __DATE__, __TIME__);
47 	kprintf("SVN revision: %lu\n\n", sHaikuRevision);
48 
49 	kprintf("cpu count: %ld, active times:\n", smp_get_num_cpus());
50 
51 	for (int32 i = 0; i < smp_get_num_cpus(); i++)
52 		kprintf("  [%ld] %Ld\n", i + 1, cpu_get_active_time(i));
53 
54 	// ToDo: Add page_faults
55 	kprintf("pages:\t\t%ld (%ld max)\n", vm_page_num_pages() - vm_page_num_free_pages(),
56 		vm_page_num_pages());
57 
58 	kprintf("sems:\t\t%ld (%ld max)\n", sem_used_sems(), sem_max_sems());
59 	kprintf("ports:\t\t%ld (%ld max)\n", port_used_ports(), port_max_ports());
60 	kprintf("threads:\t%ld (%ld max)\n", thread_used_threads(), thread_max_threads());
61 	kprintf("teams:\t\t%ld (%ld max)\n", team_used_teams(), team_max_teams());
62 
63 	return 0;
64 }
65 
66 
67 //	#pragma mark -
68 
69 
70 status_t
71 _get_system_info(system_info *info, size_t size)
72 {
73 	if (size != sizeof(system_info))
74 		return B_BAD_VALUE;
75 
76 	memset(info, 0, sizeof(system_info));
77 
78 	info->boot_time = rtc_boot_time();
79 	info->cpu_count = smp_get_num_cpus();
80 
81 	for (int32 i = 0; i < info->cpu_count; i++)
82 		info->cpu_infos[i].active_time = cpu_get_active_time(i);
83 
84 	vm_page_get_stats(info);
85 	// TODO: Add page_faults
86 
87 	info->used_threads = thread_used_threads();
88 	info->max_threads = thread_max_threads();
89 	info->used_teams = team_used_teams();
90 	info->max_teams = team_max_teams();
91 	info->used_ports = port_used_ports();
92 	info->max_ports = port_max_ports();
93 	info->used_sems = sem_used_sems();
94 	info->max_sems = sem_max_sems();
95 
96 	info->kernel_version = kKernelVersion;
97 	strlcpy(info->kernel_name, kKernelName, B_FILE_NAME_LENGTH);
98 	strlcpy(info->kernel_build_date, __DATE__, B_OS_NAME_LENGTH);
99 	strlcpy(info->kernel_build_time, __TIME__, B_OS_NAME_LENGTH);
100 	info->abi = B_HAIKU_ABI;
101 
102 	// all other stuff is architecture specific
103 	return arch_get_system_info(info, size);
104 }
105 
106 
107 status_t
108 system_info_init(struct kernel_args *args)
109 {
110 	add_debugger_command("info", &dump_info, "System info");
111 
112 	return arch_system_info_init(args);
113 }
114 
115 
116 uint32
117 get_haiku_revision(void)
118 {
119 	return sHaikuRevision;
120 }
121 
122 
123 //	#pragma mark -
124 
125 
126 status_t
127 _user_get_system_info(system_info *userInfo, size_t size)
128 {
129 	// The BeBook says get_system_info() always returns B_OK,
130 	// but that ain't true with invalid addresses
131 	if (userInfo == NULL || !IS_USER_ADDRESS(userInfo))
132 		return B_BAD_ADDRESS;
133 
134 	system_info info;
135 	status_t status = _get_system_info(&info, size);
136 	if (status == B_OK) {
137 		if (user_memcpy(userInfo, &info, sizeof(system_info)) < B_OK)
138 			return B_BAD_ADDRESS;
139 
140 		return B_OK;
141 	}
142 
143 	return status;
144 }
145 
146 
147 status_t
148 _user_get_system_info_etc(int32 id, void* userInfo, size_t size)
149 {
150 	if (userInfo == NULL || !IS_USER_ADDRESS(userInfo))
151 		return B_BAD_ADDRESS;
152 
153 	switch (id) {
154 		case B_MEMORY_INFO:
155 		{
156 			if (size < sizeof(system_memory_info))
157 				return B_BAD_VALUE;
158 
159 			system_memory_info info;
160 			vm_get_info(&info);
161 
162 			info.block_cache_memory = block_cache_used_memory();
163 
164 			return user_memcpy(userInfo, &info, sizeof(system_memory_info));
165 		}
166 
167 		default:
168 			return B_BAD_VALUE;
169 	}
170 }
171