Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPU Information class #545

Closed
fanoI opened this issue Dec 23, 2016 · 15 comments
Closed

CPU Information class #545

fanoI opened this issue Dec 23, 2016 · 15 comments

Comments

@fanoI
Copy link
Contributor

fanoI commented Dec 23, 2016

A class that give information regarding the CPU used similarly to Linux /proc/cpuinfo (but without "strange" virtual filesystems).

@xmine64
Copy link

xmine64 commented Dec 24, 2016

@jp2masa
Copy link
Member

jp2masa commented Dec 24, 2016

There's already an implementation for CPU Information: https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.Core/ProcessorInformation.cs
I don't know if it needs improvements, but I think the essential things are there.

@fanoI
Copy link
Contributor Author

fanoI commented Dec 24, 2016

Yes but it is exposed at the user level? That is there is something usable from System that does "proxy" of the class in HAL?

@jp2masa
Copy link
Member

jp2masa commented Dec 24, 2016

You're right, we need a "proxy" class to let the user level access that informations, a CPU Information class in Cosmos.System would be important.

@fanoI
Copy link
Contributor Author

fanoI commented Dec 24, 2016

The class ProcessorInformation could be augmented for example adding the processor frequency, the bogomips, the number of cores, if SSE / AVX is supported and so on...

@xmine64
Copy link

xmine64 commented Dec 27, 2016

This problem will solve by using Smbios.
http://wiki.osdev.org/System_Management_BIOS

@ERamaM
Copy link

ERamaM commented Jan 25, 2017

I'm working on it (i don't know if i will be able to do all, though). Currently i have parsed the SMBIOS Entry Point Table.

@fanoI
Copy link
Contributor Author

fanoI commented Jan 26, 2017

But we want information on the CPU not on the rest of the machine, do you have familiarity with /proc/cpuinfo or the windows application CPUZ? I think the first pass would be to create a class in system that does as "proxy" for ProcessorInformation...

This is what cpuinfo returns on Linux:

cat /proc/cpuinfo 
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 60
model name	: Intel(R) Pentium(R) CPU G3240 @ 3.10GHz
stepping	: 3
microcode	: 0x1a
cpu MHz		: 3096.246
cache size	: 3072 KB
physical id	: 0
siblings	: 2
core id		: 0
cpu cores	: 2
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer xsave rdrand lahf_lm abm arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust erms invpcid xsaveopt
bugs		:
bogomips	: 6185.80
clflush size	: 64
cache_alignment	: 64
address sizes	: 39 bits physical, 48 bits virtual
power management:

processor	: 1
vendor_id	: GenuineIntel
cpu family	: 6
model		: 60
model name	: Intel(R) Pentium(R) CPU G3240 @ 3.10GHz
stepping	: 3
microcode	: 0x1a
cpu MHz		: 3100.121
cache size	: 3072 KB
physical id	: 0
siblings	: 2
core id		: 1
cpu cores	: 2
apicid		: 2
initial apicid	: 2
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer xsave rdrand lahf_lm abm arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust erms invpcid xsaveopt
bugs		:
bogomips	: 6185.80
clflush size	: 64
cache_alignment	: 64
address sizes	: 39 bits physical, 48 bits virtual
power management:

we can start "little" for now the things really useful are vendor_id, model name and flags (you will need to know if the CPU supports SSE / AVX or not in future to do CPU dispatching).

@ERamaM
Copy link

ERamaM commented Jan 26, 2017

The proxy classes, as I understand the problem, only will act as a facade of the processor information class (only need 2 classes, one in Cosmos.System and another in Cosmos.HAL to make the ring system happy). They are already almost implemented (well, they only have the GetVendorName of the ProcessorInformation class but the idea is there). This clases are called CPUHALInfo and CPUInfo (bad name, should change it later)

I know the file /proc/cpuinfo but the matter is that the approach used currently to get the vendor name is just raw x86 (i will be sincere: i don't have any idea how it works since my knoledge of x86 is very limited) and thus, dependant on the architecture. In fact, the function GetVendorName doesn't work in my machine (i call it and i receive nothing as a response but probably is my fault).

The SMBIOS approach uses just a bunch of tables in memory to store information regarding BIOS, System, Processor, Memory... However, the parsing is a bit difficult: some information strings are stored just after a formatted table (i.e, a table with predefined size) so accessing a specific table is a bit complicated. Besides, the tables must not be in any specific order (or, at least, i found nothing in the dmtf specification) but i suspect that the bios table (type 0) is always first (as i found in my tests). Almost all the fields in the SMBIOS table are present in /proc/cpuinfo (i think even the flags in the SMBIOS "Processor ID field")

As far the implementation is concerned, you must parse the Entry Point Table so as to find the pointer to the list of tables (and, thus, find the CPU table).

You can check the current state of the implementation in my fork (branch cpuinfo): https://github.com/ERamaM/Cosmos (i know it needs big refactoring). I think the entry point table is well parsed but the first bios table (i assume it is always first, for now) it's not since the pointer is displaced ~8 bytes further (but i think the table is well parsed until the ROMSize, since it report 64K in vmware and 128K in BOCHS, reasonable numbers).

I used the dmtf specification for this: https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf (the juicy points are 5, 6 and 7).

I wil try to continue implementing soon.

@fanoI
Copy link
Contributor Author

fanoI commented Jan 26, 2017

The fact that the code written in Core is x86 only (is probably calling the assembler CPUID instruction) is not a problem and well actually is normal as is there where specific architecture code should be written... when we do ARM there will be another "Core" in which specific code will be for ARM and in case of the ProcessorInformation Class whatever is needed for ARM to get this information.
If instead the code in HAL and worst yet in System is doing assumption on X86 this is bad... try to not see the code in HAL and System as only "facades" try to reason in this way:

  1. In core you write the low engine could be unsafe C# code that sometimes resemble C or directly assembler. Usually very little part of the code is written in Core.
  2. In HAL here you write the class properly you are yet at low level but you can already factory the things in more a C# way. Code in HAL is hardware specific so for an X86 CPU probably is correct that it talks of SSE for example
  3. What to do in System is more difficult you should think in this way what it the less common denominator between any existing CPU? Well sure all CPUs have a vendor id, a name, a frequency, they could have more that one core. The part to how expose specific instruction support in a universal way is already more difficult.

You find some guidance on rings here: https://github.com/CosmosOS/Cosmos/blob/master/Docs/Kernel/Levels.md

This said please note that SMBIOS is x86 only too (that is it will not work on ARM for example) but if it permits to have a totally managed solution it will be better in any case... it has the plus that it we could have other informations on the system too!

@jp2masa
Copy link
Member

jp2masa commented Jan 26, 2017

In https://www.dmtf.org/standards/smbios it has this:

Originally designed for Intel® processor architecture systems, SMBIOS now includes support for IA-32 (x86), x64 (x86-64, Intel64, AMD64, EM64T), Intel® Itanium® architecture, 32-bit ARM (Aarch32) and 64-bit ARM (Aarch64).

@fanoI
Copy link
Contributor Author

fanoI commented Jan 26, 2017

So it seems a sort of universal solution! We could expect a RasperryPI or a "random" smart phone to have this then....

@jp2masa jp2masa added this to the vNext milestone Feb 25, 2018
@Arawn-Davies
Copy link
Member

Work on this has been started in pull request #573. A fair lot of it still needs to be done but 10/13 things still need doing. Documentation on implementation and links on this is included in the discussion.

@fanoI
Copy link
Contributor Author

fanoI commented Mar 19, 2018

I think would be better to re-start less ambitiously this time, without being put "out of road" by SMBIOS, the first objective is to read CPUInfo in the really reliable way this works: using ASM to read the values directly from the CPU.

After this is done and is surface in a proper system class we could the rest.

We will need CPUInfo if we want to do something similar to Net Core 2.1 CPU Intrisics in Cosmos.

@jp2masa jp2masa modified the milestones: User Kit 20181010, vNext Oct 11, 2018
@charlesbetros
Copy link
Member

PR merged to master. Closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants