2 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 #include <arch/system_info.h>
11 #include <KernelExport.h>
14 #include <boot/kernel_args.h>
20 enum cpu_vendor sCPUVendor
;
26 get_cpuid_for(cpuid_info
*info
, uint32 currentCPU
, uint32 eaxRegister
,
29 if (currentCPU
!= forCPU
)
32 get_current_cpuid(info
, eaxRegister
, 0);
38 get_cpuid(cpuid_info
*info
, uint32 eaxRegister
, uint32 forCPU
)
40 uint32 numCPUs
= (uint32
)smp_get_num_cpus();
43 if (forCPU
>= numCPUs
)
46 // prevent us from being rescheduled
47 state
= disable_interrupts();
49 // ToDo: as long as we only run on pentium-class systems, we can assume
50 // that the CPU supports cpuid.
52 if (!get_cpuid_for(info
, smp_get_current_cpu(), eaxRegister
, forCPU
)) {
53 smp_send_broadcast_ici(SMP_MSG_CALL_FUNCTION
, (addr_t
)info
,
54 eaxRegister
, forCPU
, (void *)get_cpuid_for
, SMP_MSG_FLAG_SYNC
);
57 restore_interrupts(state
);
63 arch_system_info_init(struct kernel_args
*args
)
65 // So far we don't have to care about heterogeneous x86 platforms.
66 cpu_ent
* cpu
= get_cpu_struct();
68 switch (cpu
->arch
.vendor
) {
70 sCPUVendor
= B_CPU_VENDOR_AMD
;
73 sCPUVendor
= B_CPU_VENDOR_VIA
;
76 sCPUVendor
= B_CPU_VENDOR_CYRIX
;
79 sCPUVendor
= B_CPU_VENDOR_INTEL
;
82 sCPUVendor
= B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR
;
85 sCPUVendor
= B_CPU_VENDOR_RISE
;
87 case VENDOR_TRANSMETA
:
88 sCPUVendor
= B_CPU_VENDOR_TRANSMETA
;
91 sCPUVendor
= B_CPU_VENDOR_UNKNOWN
;
95 sCPUModel
= (cpu
->arch
.extended_family
<< 20)
96 | (cpu
->arch
.extended_model
<< 16) | (cpu
->arch
.type
<< 12)
97 | (cpu
->arch
.family
<< 8) | (cpu
->arch
.model
<< 4) | cpu
->arch
.stepping
;
99 sCPUClockSpeed
= args
->arch_args
.cpu_clock_speed
;
105 arch_fill_topology_node(cpu_topology_node_info
* node
, int32 cpu
)
107 switch (node
->type
) {
108 case B_TOPOLOGY_ROOT
:
110 node
->data
.root
.platform
= B_CPU_x86
;
112 node
->data
.root
.platform
= B_CPU_x86_64
;
114 node
->data
.root
.platform
= B_CPU_UNKNOWN
;
118 case B_TOPOLOGY_PACKAGE
:
119 node
->data
.package
.vendor
= sCPUVendor
;
120 node
->data
.package
.cache_line_size
= CACHE_LINE_SIZE
;
123 case B_TOPOLOGY_CORE
:
124 node
->data
.core
.model
= sCPUModel
;
125 node
->data
.core
.default_frequency
= sCPUClockSpeed
;
138 _user_get_cpuid(cpuid_info
*userInfo
, uint32 eaxRegister
, uint32 cpuNum
)
143 if (!IS_USER_ADDRESS(userInfo
))
144 return B_BAD_ADDRESS
;
146 status
= get_cpuid(&info
, eaxRegister
, cpuNum
);
149 && user_memcpy(userInfo
, &info
, sizeof(cpuid_info
)) < B_OK
)
150 return B_BAD_ADDRESS
;