Add CPU features and fix CPU vendor #2

Closed
Ghost wants to merge 5 commits from (deleted):prcb-cpu-features into master
First-time contributor

Fixed CPU vendor name code which was bugged, and
Extracted CPU vendor name code to ArpSetCpuVendor

Added CPU features field onto CPU_IDENTIFICATION struct

Added few debugging utilities

Fixed CPU vendor name code which was bugged, and Extracted CPU vendor name code to `ArpSetCpuVendor` Added CPU features field onto `CPU_IDENTIFICATION` struct Added few debugging utilities
belliash requested changes 2023-11-21 20:09:39 +01:00
@ -187,0 +188,4 @@
typedef struct _CPU_FEATURES {
union {
struct {
unsigned int SSE3 : 1;
Owner

UINT, or maybe something smaller if just one bit used.

UINT, or maybe something smaller if just one bit used.
Author
First-time contributor

Using BYTE instead of unsigned int for the bitfield

Using BYTE instead of unsigned int for the bitfield
Ghost marked this conversation as resolved
@ -138,0 +139,4 @@
typedef struct _CPU_FEATURES {
union {
struct {
unsigned int SSE3 : 1;
Owner

UINT, or maybe something smaller if just one bit used.

UINT, or maybe something smaller if just one bit used.
Author
First-time contributor

Using BYTE instead of unsigned int for the bitfield

Using BYTE instead of unsigned int for the bitfield
Ghost marked this conversation as resolved
@ -152,6 +225,7 @@ typedef struct _CPU_IDENTIFICATION
USHORT Stepping;
CPU_VENDOR Vendor;
UCHAR VendorName[13];
CPU_FEATURES Features;
Owner

IMHO this should go to PROCESSOR_CONTROL_BLOCK.

IMHO this should go to PROCESSOR_CONTROL_BLOCK.
Author
First-time contributor

Moved to PROCESSOR_CONTROL_BLOCK

Moved to PROCESSOR_CONTROL_BLOCK
Ghost marked this conversation as resolved
@ -21,9 +21,12 @@
#ifdef DBG
#define DEBUG 1
#define DebugPrint(Format, ...) if(KeDbgPrint) KeDbgPrint(Format, __VA_ARGS__);
#define DebugPrintSeparator() DebugPrint(L"===============================================================================\n");
Owner

Why need this? What would you like to separate?
Only debug messages are printed to serial console.

Why need this? What would you like to separate? Only debug messages are printed to serial console.
Author
First-time contributor

Just being fancy, but pretty much unnecessary.
Being removed now.

Just being fancy, but pretty much unnecessary. Being removed now.
Ghost marked this conversation as resolved
@ -12,6 +12,7 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.c
${XTOSKRNL_SOURCE_DIR}/ar/arcommon.c
Owner

AR is architecture specific library, so I believe it should not contain any common points. Especially, there are architectures different than x86.

AR is architecture specific library, so I believe it should not contain any common points. Especially, there are architectures different than x86.
Author
First-time contributor

Removed

Removed
Ghost marked this conversation as resolved
@ -8,6 +8,11 @@
Owner

xtoskrnl/ar/i686/procsup.c missing in this PR

xtoskrnl/ar/i686/procsup.c missing in this PR
Author
First-time contributor

Implemented on i686

Implemented on i686
Ghost marked this conversation as resolved
@ -9,2 +9,4 @@
#include <xtos.h>
#ifdef DEBUG
WCHAR VendorName[13];
Owner

All global variables should be placed in globals.c and globals.h

All global variables should be placed in globals.c and globals.h
Author
First-time contributor

Removed debug stuff

Removed debug stuff
Ghost marked this conversation as resolved
@ -11,0 +12,4 @@
WCHAR VendorName[13];
#endif
extern const WCHAR ArCpuFeatureNames[64][16];
Owner

All global variables should be placed in globals.c and globals.h

All global variables should be placed in globals.c and globals.h
Author
First-time contributor

Removed debug stuff

Removed debug stuff
Ghost marked this conversation as resolved
@ -110,0 +127,4 @@
*/
XTAPI
VOID
ArpSetCpuVendor(IN PKPROCESSOR_CONTROL_BLOCK Prcb,
Owner

Why this needs to be so over-complicated? It should be possible to simply store data read from EBX, EDX and ECX registers.

Why this needs to be so over-complicated? It should be possible to simply store data read from EBX, EDX and ECX registers.
Author
First-time contributor

Simplified

XTAPI
VOID ArpSetCpuVendor(IN PKPROCESSOR_CONTROL_BLOCK Prcb,
                     IN CPUID_REGISTERS CpuRegisters) 
{
    *((UINT32 *)(Prcb->CpuId.VendorName))     = CpuRegisters.Ebx;
    *((UINT32 *)(Prcb->CpuId.VendorName + 4)) = CpuRegisters.Edx;
    *((UINT32 *)(Prcb->CpuId.VendorName + 8)) = CpuRegisters.Ecx;
    Prcb->CpuId.VendorName[12]                = '\0';
}
Simplified ```c XTAPI VOID ArpSetCpuVendor(IN PKPROCESSOR_CONTROL_BLOCK Prcb, IN CPUID_REGISTERS CpuRegisters) { *((UINT32 *)(Prcb->CpuId.VendorName)) = CpuRegisters.Ebx; *((UINT32 *)(Prcb->CpuId.VendorName + 4)) = CpuRegisters.Edx; *((UINT32 *)(Prcb->CpuId.VendorName + 8)) = CpuRegisters.Ecx; Prcb->CpuId.VendorName[12] = '\0'; } ```
Ghost marked this conversation as resolved
@ -123,8 +168,14 @@ ArpIdentifyProcessor(VOID)
CPUID_REGISTERS CpuRegisters;
CPUID_SIGNATURE CpuSignature;
#ifdef DEBUG
Owner

All these ifdef statements are completely useless, as DebugPrint on non-debug build is just a NOP.

All these `ifdef ` statements are completely useless, as DebugPrint on non-debug build is just a NOP.
Ghost marked this conversation as resolved
@ -0,0 +1,25 @@
/**
Owner

AR is architecture specific library, so I believe it should not contain any common points. Especially, there are architectures different than x86 that might get supported in the future.

AR is architecture specific library, so I believe it should not contain any common points. Especially, there are architectures different than x86 that might get supported in the future.
Ghost marked this conversation as resolved
@ -0,0 +9,4 @@
#include <xtos.h>
/* CPU feature names */
const WCHAR ArCpuFeatureNames[64][16] = {
Owner

What is this needed for?
This is a kernel and it needs information about CPU supported features, for example to check minimal requirements and panic if they are not met. They should be stored somewhere in PROCESSOR_CONTROL_BLOCK probably.

Why WCHAR (wide character) needs to be used here?

What is this needed for? This is a kernel and it needs information about CPU supported features, for example to check minimal requirements and panic if they are not met. They should be stored somewhere in PROCESSOR_CONTROL_BLOCK probably. Why WCHAR (wide character) needs to be used here?
Author
First-time contributor

These are actually debug messages. Stored there temporarily. Removed.

These are actually debug messages. Stored there temporarily. Removed.
Ghost marked this conversation as resolved
Ghost changed title from Add PRCB CPU features and fixes to WIP: Add PRCB CPU features and fixes 2023-11-21 22:37:38 +01:00
Ghost changed title from WIP: Add PRCB CPU features and fixes to Add PRCB CPU features and fixes 2023-11-22 01:13:28 +01:00
Ghost changed title from Add PRCB CPU features and fixes to Add CPU features and fix CPU vendor 2023-11-22 01:14:03 +01:00
Ghost requested review from belliash 2023-11-22 17:11:16 +01:00
Ghost changed title from Add CPU features and fix CPU vendor to WIP: Add CPU features and fix CPU vendor 2023-11-23 16:34:48 +01:00
Ghost force-pushed prcb-cpu-features from 9ae270c241 to a270c08dcf 2023-11-23 23:28:07 +01:00 Compare
Author
First-time contributor

Reopening a clean PR

Reopening a clean PR
Ghost closed this pull request 2023-11-23 23:28:46 +01:00
Ghost reopened this pull request 2023-11-24 00:36:18 +01:00
Ghost changed title from WIP: Add CPU features and fix CPU vendor to Add CPU features and fix CPU vendor 2023-11-24 00:36:23 +01:00
Owner

Could you update your source branch to match the destination?

Could you update your source branch to match the destination?
Ghost added 1 commit 2023-11-26 18:53:30 +01:00
Ghost added 1 commit 2023-11-27 19:12:11 +01:00
Author
First-time contributor

Updated

Updated
belliash requested changes 2023-11-27 19:34:56 +01:00
@ -113,4 +117,3 @@
/* CPU vendor enumeration list */
typedef enum _CPU_VENDOR
{
CPU_VENDOR_AMD = 0x68747541,
Owner

Why do we change the values in CPU_VENDOR enum?

Why do we change the values in CPU_VENDOR enum?
Author
First-time contributor

The modifications were made to enhance code readability and maintainability, I specifically targeted removing magic numbers, and, to introduce a specific value (CPU_VENDOR_INVALID) to handle cases where the CPU vendor is in an invalid state.

The modifications were made to enhance code readability and maintainability, I specifically targeted removing magic numbers, and, to introduce a specific value (CPU_VENDOR_INVALID) to handle cases where the CPU vendor is in an invalid state.
Owner

That magic numbers have some meaning: HEX(68747541) = STR(Auth)

That magic numbers have some meaning: HEX(68747541) = STR(Auth)
Author
First-time contributor

I know. Why shouldn't we change the values in CPU_VENDOR enum?

I know. Why shouldn't we change the values in CPU_VENDOR enum?
@ -187,0 +193,4 @@
typedef struct _CPU_FEATURES {
union {
struct {
BOOLEAN SSE3 : 1;
Owner

It is not guaranteed that enum has unsigned underlying type.

It is not guaranteed that enum has unsigned underlying type.
Author
First-time contributor

You pointed the struct in this case, was this a mis-comment?

You pointed the struct in this case, was this a mis-comment?
Owner

No, it's not a mistake. BOOLEAN is defined as enum.

No, it's not a mistake. BOOLEAN is defined as enum.
Author
First-time contributor
May we define `BOOLEAN as enum : BYTE`? https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
Author
First-time contributor

Swapped all BOOLEAN on the structure with BYTE

Swapped all BOOLEAN on the structure with BYTE
@ -187,0 +263,4 @@
BOOLEAN Reserved4 : 1; // Bit 30 is reserved
BOOLEAN PBE : 1;
};
UINT64 Features;
Owner

Any reason for using UINT64 here?

Any reason for using UINT64 here?
Author
First-time contributor

I've specifically added that to access the whole value AsUINT64, maybe it's unnecesary right now, but added it as a plus. I took some inspiration from this code, that does the same:
xtchain/binaries/x86_64-w64-mingw32/include/winhvplatformdefs.h:29
(look for typedef union WHV_CAPABILITY_FEATURES)

I've specifically added that to access the whole value AsUINT64, maybe it's unnecesary right now, but added it as a plus. I took some inspiration from this code, that does the same: xtchain/binaries/x86_64-w64-mingw32/include/winhvplatformdefs.h:29 (look for typedef union WHV_CAPABILITY_FEATURES)
Author
First-time contributor

Swapped all BOOLEAN on the structure with BYTE

Swapped all BOOLEAN on the structure with BYTE
@ -64,4 +68,3 @@
/* CPU vendor enumeration list */
typedef enum _CPU_VENDOR
{
CPU_VENDOR_AMD = 0x68747541,
Owner

Why do we change the values in CPU_VENDOR enum?

Why do we change the values in CPU_VENDOR enum?
Author
First-time contributor

The modifications were made to enhance code readability and maintainability, I specifically targeted removing magic numbers, and, to introduce a specific value (CPU_VENDOR_INVALID) to handle cases where the CPU vendor is in an invalid state.

The modifications were made to enhance code readability and maintainability, I specifically targeted removing magic numbers, and, to introduce a specific value (CPU_VENDOR_INVALID) to handle cases where the CPU vendor is in an invalid state.
Owner

That magic numbers have some meaning, eg: HEX(68747541) = STR(Auth)

That magic numbers have some meaning, eg: HEX(68747541) = STR(Auth)
Author
First-time contributor

I know. Why shouldn't we change the values in CPU_VENDOR enum?

I know. Why shouldn't we change the values in CPU_VENDOR enum?
@ -138,0 +144,4 @@
typedef struct _CPU_FEATURES {
union {
struct {
BOOLEAN SSE3 : 1;
Owner

It is not guaranteed that enum has unsigned underlying type.

It is not guaranteed that enum has unsigned underlying type.
Author
First-time contributor

You pointed the struct in this case, was this a mis-comment?

You pointed the struct in this case, was this a mis-comment?
@ -138,0 +209,4 @@
BOOLEAN Reserved4 : 1; // Bit 30 is reserved
BOOLEAN PBE : 1;
};
UINT64 AsUINT64;
Owner

Any reason for using UINT64 here?

Any reason for using UINT64 here?
Author
First-time contributor

I've specifically added that to access the whole value AsUINT64, maybe it's unnecesary right now, but added it as a plus. I took some inspiration from this code, that does the same:
xtchain/binaries/x86_64-w64-mingw32/include/winhvplatformdefs.h:29
(look for typedef union WHV_CAPABILITY_FEATURES)

I've specifically added that to access the whole value `AsUINT64`, maybe it's unnecesary right now, but added it as a plus. I took some inspiration from this code, that does the same: xtchain/binaries/x86_64-w64-mingw32/include/winhvplatformdefs.h:29 (look for `typedef union WHV_CAPABILITY_FEATURES`)
Owner

I didn't notice the difference between i686 and amd64. In one case it is a structure containing 2 unions. Here we got 1 bit structure. Does it mean, that CPUID returns different data across archs?

I didn't notice the difference between i686 and amd64. In one case it is a structure containing 2 unions. Here we got 1 bit structure. Does it mean, that CPUID returns different data across archs?
Author
First-time contributor

This is a small regression on local commits, I'll push the final structure.

This is a small regression on local commits, I'll push the final structure.
Author
First-time contributor

Fixed on last commit.

Fixed on last commit.
@ -154,3 +186,3 @@
/* CPU vendor specific quirks */
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
if (Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
Owner

Please don't mix code changes with formatting.

Please don't mix code changes with formatting.
Author
First-time contributor

Do you expect to just copy and paste the code from one side to another without giving it proper format? Notice it's placed on another function (Diff does not help here)

Do you expect to just copy and paste the code from one side to another without giving it proper format? Notice it's placed on another function (Diff does not help here)
Owner

It does not look like copied from one place into another. There is additional space between if and parenthesis. If it gets removed, git won't see any change in this place.

It is placed in another function, because ArpIdentifyProcessor() got divided.

It does not look like copied from one place into another. There is additional space between if and parenthesis. If it gets removed, git won't see any change in this place. It is placed in another function, because ArpIdentifyProcessor() got divided.
Author
First-time contributor

In the process of moving the code from ArpIdentifyProcessor to ArpSetCpuVendor I formatted the whole function, as it makes sense to tidy up and reformat the function I've touched.

In the process of moving the code from `ArpIdentifyProcessor` to `ArpSetCpuVendor` I formatted the whole function, as it makes sense to tidy up and reformat the function I've touched.
@ -163,3 +199,3 @@
{
/* Intel CPU */
if(Prcb->CpuId.Family == 0xF)
if (Prcb->CpuId.Family == 0xF)
Owner

Please don't mix code changes with formatting.

Please don't mix code changes with formatting.
Author
First-time contributor

Do you expect to just copy and paste the code from one side to another without giving it proper format? Notice it's placed on another function (Diff does not help here)

Do you expect to just copy and paste the code from one side to another without giving it proper format? Notice it's placed on another function (Diff does not help here)
Owner

It does not look like copied from one place into another. There is additional space between if and parenthesis. If it gets removed, git won't see any change in this place.

It is placed in another function, because ArpIdentifyProcessor() got divided.

It does not look like copied from one place into another. There is additional space between if and parenthesis. If it gets removed, git won't see any change in this place. It is placed in another function, because ArpIdentifyProcessor() got divided.
Author
First-time contributor

In the process of moving the code from ArpIdentifyProcessor to ArpSetCpuVendor I formatted the whole function, as it makes sense to tidy up and reformat the function I've touched.

In the process of moving the code from `ArpIdentifyProcessor` to `ArpSetCpuVendor` I formatted the whole function, as it makes sense to tidy up and reformat the function I've touched.
Ghost added 1 commit 2023-11-27 22:06:49 +01:00
Ghost closed this pull request 2023-11-27 22:51:01 +01:00

Pull request closed

Sign in to join this conversation.
No description provided.