531a027122
We cannot be certain that the CR8 register will be zeroed by the time we have control passed to us, therefore it is wise to set it ourselves. Signed-off-by: Chloe M. <chloe@mensia.org>
134 lines
2.9 KiB
C
134 lines
2.9 KiB
C
/*
|
|
* Copyright (c) 2026, Chloe M.
|
|
* Provided under the BSD-3 clause.
|
|
*
|
|
* Description: Kernel processor control region
|
|
* Author: Chloe M.
|
|
*/
|
|
|
|
#include <hal/kpcr.h>
|
|
#include <hal/intr.h>
|
|
#include <ex/trace.h>
|
|
#include <machine/cpuid.h>
|
|
#include <machine/idt.h>
|
|
#include <stdef.h>
|
|
|
|
#define DTRACE(Fmt, ...) \
|
|
TRACE("[ CPU ]: " Fmt, ##__VA_ARGS__)
|
|
|
|
/* Processor types */
|
|
#define PROCESSOR_OEM 0
|
|
#define PROCESSOR_OVERDRIVE 1
|
|
#define PROCESSOR_DUAL 2
|
|
|
|
#define PROCESSOR_TYPE(TYPE) \
|
|
((TYPE) >= NELEM(ProcessorType)) \
|
|
? "unknown" \
|
|
: ProcessorType[(Type)]
|
|
|
|
/* Processor type lookup table */
|
|
static const CHAR *ProcessorType[] = {
|
|
[PROCESSOR_OEM] = "OEM processor",
|
|
[PROCESSOR_OVERDRIVE] = "Intel overdrive processor",
|
|
[PROCESSOR_DUAL] = "Intel P5 dual processor"
|
|
};
|
|
|
|
/* From cpu/vector.S */
|
|
extern VOID MdVectorInit(VOID);
|
|
|
|
/*
|
|
* Called by ProcessorIdentify()
|
|
*/
|
|
static VOID
|
|
ProcessorIdentify1(MCB *Mcb)
|
|
{
|
|
UCHAR ManufactId[13];
|
|
ULONG Ebx, Edx, Ecx, Unused;
|
|
|
|
if (Mcb == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* Grab the manufacturer ID */
|
|
ManufactId[12] = '\0';
|
|
CPUID(0, Unused, Ebx, Ecx, Edx);
|
|
|
|
/* DWORD 0 */
|
|
ManufactId[0] = Ebx & 0xFF;
|
|
ManufactId[1] = (Ebx >> 8) & 0xFF;
|
|
ManufactId[2] = (Ebx >> 16) & 0xFF;
|
|
ManufactId[3] = (Ebx >> 24) & 0xFF;
|
|
|
|
/* DWORD 1 */
|
|
ManufactId[4] = Edx & 0xFF;
|
|
ManufactId[5] = (Edx >> 8) & 0xFF;
|
|
ManufactId[6] = (Edx >> 16) & 0xFF;
|
|
ManufactId[7] = (Edx >> 24) & 0xFF;
|
|
|
|
/* DWORD 2 */
|
|
ManufactId[8] = Ecx & 0xFF;
|
|
ManufactId[9] = (Ecx >> 8) & 0xFF;
|
|
ManufactId[10] = (Ecx >> 16) & 0xFF;
|
|
ManufactId[11] = (Ecx >> 24) & 0xFF;
|
|
DTRACE("vendor : %s\n", ManufactId);
|
|
}
|
|
|
|
static VOID
|
|
ProcessorIdentify(MCB *Mcb)
|
|
{
|
|
ULONG Eax, Unused;
|
|
UCHAR ModelLow, ModelHigh;
|
|
UCHAR FamilyLow, FamilyHigh;
|
|
UCHAR Type;
|
|
|
|
if (Mcb == NULL) {
|
|
return;
|
|
}
|
|
|
|
CPUID(1, Eax, Unused, Unused, Unused);
|
|
|
|
/* Extarct the model ID */
|
|
ModelLow = (Eax >> 4) & 0xF;
|
|
ModelHigh = (Eax >> 16) & 0xF;
|
|
Mcb->ModelId = (ModelHigh << 4) | ModelLow;
|
|
|
|
/* Extract the family ID */
|
|
FamilyLow = (Eax >> 8) & 0xF;
|
|
FamilyHigh = (Eax >> 20) & 0xFF;
|
|
Mcb->FamilyId = (FamilyHigh << 4) | FamilyLow;
|
|
|
|
/* Extract the processor type */
|
|
Type = (Eax >> 12) & 3;
|
|
|
|
/* Informational logging */
|
|
DTRACE("model : %X\n", Mcb->ModelId);
|
|
DTRACE("family : %X\n", Mcb->FamilyId);
|
|
DTRACE("type : %s\n", PROCESSOR_TYPE(Type));
|
|
ProcessorIdentify1(Mcb);
|
|
}
|
|
|
|
VOID
|
|
HalKpcrP1Init(KPCR *Kpcr)
|
|
{
|
|
MCB *Mcb;
|
|
|
|
if (Kpcr == NULL) {
|
|
return;
|
|
}
|
|
|
|
Mcb = &Kpcr->Mcb;
|
|
ProcessorIdentify(Mcb);
|
|
|
|
/* Load the IDT */
|
|
MdVectorInit();
|
|
MdIdtLoad();
|
|
|
|
/* Default to IRQL_PASSIVE */
|
|
ASMV(
|
|
"mov %0, %%cr8"
|
|
:
|
|
: "r" ((UQUAD)IRQL_PASSIVE)
|
|
: "memory"
|
|
);
|
|
}
|