Removed beep on boot.
That stuff hurts, man. Also moved all the ASM port wrappers into their own file.
This commit is contained in:
parent
d830acbbd4
commit
f33b63d1fb
|
@ -79,7 +79,8 @@ __attribute__((aligned(4096))) static size_t FirstPageTable[512] = {0};
|
|||
void timer_wait(int ticks){
|
||||
uint64_t FinalTick = time + ticks;
|
||||
|
||||
while(time < FinalTick);
|
||||
int i = 0;
|
||||
while(i < ticks * 1000) { i++; };
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,7 +100,15 @@ void PrepareSystem(FILELOADER_PARAMS* FLOP) {
|
|||
InstallGDT();
|
||||
InstallIDT();
|
||||
|
||||
beep();
|
||||
// WARNING!
|
||||
// W A R N I N G !
|
||||
// This is L O U D!
|
||||
// Turn your volume down!
|
||||
// Seriously!
|
||||
// LOWER!
|
||||
// IT'S LOUD!
|
||||
|
||||
//beep();
|
||||
|
||||
if(SetIdentityMap(FLOP->RTServices) == NULL) {
|
||||
Memory_Info.MemoryMap = FLOP->MemoryMap;
|
||||
|
@ -570,209 +579,6 @@ size_t ReadCPUFrequency(size_t* Perfs, uint8_t AverageOrDirect) {
|
|||
return Frequency;
|
||||
}
|
||||
|
||||
uint32_t ReadPort(uint16_t Port, int Length) {
|
||||
uint32_t Data;
|
||||
if(Length == 1) { // Read a byte
|
||||
__asm__ __volatile__("inb %[address], %[value]" : : [value] "a" ((uint8_t) Data), [address] "d" (Port) :);
|
||||
} else if (Length == 2) { // Read a word
|
||||
__asm__ __volatile__("inw %[address], %[value]" : : [value] "a" ((uint16_t) Data), [address] "d" (Port) :);
|
||||
} else if (Length == 4) { // Read a long (dword)
|
||||
__asm__ __volatile__("inl %[address], %[value]" : : [value] "a" (Data), [address] "d" (Port) :);
|
||||
} else {
|
||||
printf("ReadPort: Invalid Read Length.\r\n");
|
||||
}
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
uint32_t WritePort(uint16_t Port, uint32_t Data, int Length) {
|
||||
if(Length == 1) { // Write a byte
|
||||
__asm__ __volatile__("outb %[value], %[address]" : : [value] "a" ((uint8_t) Data), [address] "d" (Port) :);
|
||||
} else if (Length == 2) { // Write a word
|
||||
__asm__ __volatile__("outw %[value], %[address]" : : [value] "a" ((uint16_t) Data), [address] "d" (Port) :);
|
||||
} else if (Length == 4) { // Write a long (dword)
|
||||
__asm__ __volatile__("outl %[value], %[address]" : : [value] "a" (Data), [address] "d" (Port) :);
|
||||
} else {
|
||||
printf("WritePort: Invalid Write Length.\r\n");
|
||||
}
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
size_t ReadModelSpecificRegister(size_t MSR) {
|
||||
size_t RegHigh = 0, RegLow = 0;
|
||||
__asm__ __volatile__("rdmsr" : "=a" (RegLow), "=d" (RegHigh) : "c" (MSR) :);
|
||||
return (RegHigh << 32 | RegLow);
|
||||
}
|
||||
|
||||
size_t WriteModelSpecificRegister(size_t MSR, size_t Data) {
|
||||
size_t DataLow = 0, DataHigh = 0;
|
||||
|
||||
DataLow = ((uint32_t* )&Data)[0];
|
||||
DataHigh = ((uint32_t* )&Data)[1];
|
||||
__asm__ __volatile__("wrmsr" : : "a" (DataLow), "c" (MSR), "d" (DataHigh) : );
|
||||
return Data;
|
||||
}
|
||||
|
||||
// VMXCSR - Vex-Encoded MXCSR. These are preferred when AVX is available.
|
||||
uint32_t ReadVexMXCSR() {
|
||||
uint32_t Data;
|
||||
__asm__ __volatile__("vstmxcsr %[dest]" : [dest] "=m" (Data) : :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
uint32_t WriteVexMXCSR(uint32_t Data) {
|
||||
__asm__ __volatile__("vldmxcsr %[src]" : : [src] "m" (Data) :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
// MXCSR - SSE Control Register.
|
||||
uint32_t ReadMXCSR() {
|
||||
uint32_t Data;
|
||||
__asm__ __volatile__("stmxcsr %[dest]" : [dest] "=m" (Data) : :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
uint32_t WriteMXCSR(uint32_t Data) {
|
||||
__asm__ __volatile__("ldmxcsr %[src]" : : [src] "m" (Data) :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
// Control Register : CRX + RFLAGS. Specify 'f' for RFLAGS, X for CRX.
|
||||
|
||||
size_t ReadControlRegister(int CRX) {
|
||||
size_t Data;
|
||||
switch(CRX) {
|
||||
case 0:
|
||||
__asm__ __volatile__("mov %%cr0, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 1:
|
||||
__asm__ __volatile__("mov %%cr1, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 2:
|
||||
__asm__ __volatile__("mov %%cr2, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 3:
|
||||
__asm__ __volatile__("mov %%cr3, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 4:
|
||||
__asm__ __volatile__("mov %%cr4, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 8:
|
||||
__asm__ __volatile__("mov %%cr8, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 'f':
|
||||
// Push flags and pop them into our buffer
|
||||
__asm__ __volatile__("pushfq\n\t" "popq %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
size_t WriteControlRegister(int CRX, size_t Data) {
|
||||
switch(CRX) {
|
||||
case 0:
|
||||
__asm__ __volatile__("mov %[dest], %%cr0" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 1:
|
||||
__asm__ __volatile__("mov %[dest], %%cr1" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 2:
|
||||
__asm__ __volatile__("mov %[dest], %%cr2" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 3:
|
||||
__asm__ __volatile__("mov %[dest], %%cr3" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 4:
|
||||
__asm__ __volatile__("mov %[dest], %%cr4" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 8:
|
||||
__asm__ __volatile__("mov %[dest], %%cr8" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 'f':
|
||||
__asm__ __volatile__("pushq %[dest]\n\t" "popfq" : : [dest] "r" (Data) : "cc");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Data;
|
||||
|
||||
}
|
||||
|
||||
// XCR = eXtended Control Register.
|
||||
// XCR0 is used to enable AVX/SSE.
|
||||
|
||||
size_t ReadExtendedControlRegister(size_t XCRX) {
|
||||
size_t RegHigh = 0, RegLow = 0;
|
||||
|
||||
__asm__ __volatile__("xgetbv" : "=a" (RegLow), "=d" (RegHigh) : "c" (XCRX) :);
|
||||
return (RegHigh << 32 | RegLow);
|
||||
}
|
||||
|
||||
size_t WriteExtendedControlRegister(size_t XCRX, size_t Data) {
|
||||
__asm__ __volatile__("xsetbv" : : "a" ( ((uint32_t*)&Data)[0]), "c" (XCRX), "d" ( ((uint32_t*)&Data)[1] ) :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
// The following two functions are utility - for determining whether we're operating in Long Mode.
|
||||
// TODO: Move into DescriptorTables.c
|
||||
|
||||
size_t ReadXCS() {
|
||||
size_t Data = 0;
|
||||
__asm__ __volatile__("mov %%cs, %[dest]" : [dest] "=r" (Data) : :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
DESCRIPTOR_TABLE_POINTER FetchGDT() {
|
||||
DESCRIPTOR_TABLE_POINTER GDTrData = {0};
|
||||
|
||||
__asm__ __volatile__("sgdt %[dest]" : [dest] "=m" (GDTrData) : :);
|
||||
return GDTrData;
|
||||
}
|
||||
|
||||
void SetGDT(DESCRIPTOR_TABLE_POINTER GDTrData) {
|
||||
__asm__ __volatile__("lgdt %[src]" : : [src] "m" (GDTrData) :);
|
||||
}
|
||||
|
||||
DESCRIPTOR_TABLE_POINTER FetchIDT() {
|
||||
DESCRIPTOR_TABLE_POINTER IDTrData = {0};
|
||||
__asm__ __volatile__("sidt %[dest]" : [dest] "=m" (IDTrData) : :);
|
||||
return IDTrData;
|
||||
}
|
||||
|
||||
void SetIDT(DESCRIPTOR_TABLE_POINTER IDTrData) {
|
||||
__asm__ __volatile__("lidt %[src]" : : [src] "m" (IDTrData) :);
|
||||
}
|
||||
|
||||
// LDT = Local Descriptor Table (= GDT entry for current segment)
|
||||
|
||||
uint16_t FetchLDT() {
|
||||
uint16_t LDTrData = 0;
|
||||
__asm__ __volatile__("sldt %[dest]" : [dest] "=m" (LDTrData) : :);
|
||||
return LDTrData;
|
||||
}
|
||||
|
||||
void SetLDT(uint16_t LDTrData) {
|
||||
__asm__ __volatile__("lldt %[src]" : : [src] "m" (LDTrData) :);
|
||||
}
|
||||
|
||||
// TSR - Tast State Register
|
||||
|
||||
uint16_t FetchTSR() {
|
||||
uint16_t TSRData = 0;
|
||||
__asm__ __volatile__ ("str %[dest]" : [dest] "=m" (TSRData) : :);
|
||||
return TSRData;
|
||||
}
|
||||
|
||||
void SetTSR(uint16_t TSRData) {
|
||||
__asm__ __volatile__("ltr %[src]" : : [src] "m" (TSRData) :);
|
||||
}
|
||||
|
||||
void InstallGDT() {
|
||||
DESCRIPTOR_TABLE_POINTER GDTData = {0};
|
||||
|
||||
|
|
216
kernel/ports.c
Normal file
216
kernel/ports.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
|
||||
/************************
|
||||
*** Team Kitty, 2019 ***
|
||||
*** Sync ***
|
||||
***********************/
|
||||
|
||||
/* This file contains code required for directly communicating with hardware.
|
||||
* This means ASM, most of the time. These are just wrapper functions that make ASM a little bit less daunting.
|
||||
*/
|
||||
|
||||
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
uint32_t ReadPort(uint16_t Port, int Length) {
|
||||
uint32_t Data;
|
||||
if(Length == 1) { // Read a byte
|
||||
__asm__ __volatile__("inb %[address], %[value]" : : [value] "a" ((uint8_t) Data), [address] "d" (Port) :);
|
||||
} else if (Length == 2) { // Read a word
|
||||
__asm__ __volatile__("inw %[address], %[value]" : : [value] "a" ((uint16_t) Data), [address] "d" (Port) :);
|
||||
} else if (Length == 4) { // Read a long (dword)
|
||||
__asm__ __volatile__("inl %[address], %[value]" : : [value] "a" (Data), [address] "d" (Port) :);
|
||||
} else {
|
||||
printf("ReadPort: Invalid Read Length.\r\n");
|
||||
}
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
uint32_t WritePort(uint16_t Port, uint32_t Data, int Length) {
|
||||
if(Length == 1) { // Write a byte
|
||||
__asm__ __volatile__("outb %[value], %[address]" : : [value] "a" ((uint8_t) Data), [address] "d" (Port) :);
|
||||
} else if (Length == 2) { // Write a word
|
||||
__asm__ __volatile__("outw %[value], %[address]" : : [value] "a" ((uint16_t) Data), [address] "d" (Port) :);
|
||||
} else if (Length == 4) { // Write a long (dword)
|
||||
__asm__ __volatile__("outl %[value], %[address]" : : [value] "a" (Data), [address] "d" (Port) :);
|
||||
} else {
|
||||
printf("WritePort: Invalid Write Length.\r\n");
|
||||
}
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
size_t ReadModelSpecificRegister(size_t MSR) {
|
||||
size_t RegHigh = 0, RegLow = 0;
|
||||
__asm__ __volatile__("rdmsr" : "=a" (RegLow), "=d" (RegHigh) : "c" (MSR) :);
|
||||
return (RegHigh << 32 | RegLow);
|
||||
}
|
||||
|
||||
size_t WriteModelSpecificRegister(size_t MSR, size_t Data) {
|
||||
size_t DataLow = 0, DataHigh = 0;
|
||||
|
||||
DataLow = ((uint32_t* )&Data)[0];
|
||||
DataHigh = ((uint32_t* )&Data)[1];
|
||||
__asm__ __volatile__("wrmsr" : : "a" (DataLow), "c" (MSR), "d" (DataHigh) : );
|
||||
return Data;
|
||||
}
|
||||
|
||||
// VMXCSR - Vex-Encoded MXCSR. These are preferred when AVX is available.
|
||||
uint32_t ReadVexMXCSR() {
|
||||
uint32_t Data;
|
||||
__asm__ __volatile__("vstmxcsr %[dest]" : [dest] "=m" (Data) : :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
uint32_t WriteVexMXCSR(uint32_t Data) {
|
||||
__asm__ __volatile__("vldmxcsr %[src]" : : [src] "m" (Data) :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
// MXCSR - SSE Control Register.
|
||||
uint32_t ReadMXCSR() {
|
||||
uint32_t Data;
|
||||
__asm__ __volatile__("stmxcsr %[dest]" : [dest] "=m" (Data) : :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
uint32_t WriteMXCSR(uint32_t Data) {
|
||||
__asm__ __volatile__("ldmxcsr %[src]" : : [src] "m" (Data) :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
// Control Register : CRX + RFLAGS. Specify 'f' for RFLAGS, X for CRX.
|
||||
|
||||
size_t ReadControlRegister(int CRX) {
|
||||
size_t Data;
|
||||
switch(CRX) {
|
||||
case 0:
|
||||
__asm__ __volatile__("mov %%cr0, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 1:
|
||||
__asm__ __volatile__("mov %%cr1, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 2:
|
||||
__asm__ __volatile__("mov %%cr2, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 3:
|
||||
__asm__ __volatile__("mov %%cr3, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 4:
|
||||
__asm__ __volatile__("mov %%cr4, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 8:
|
||||
__asm__ __volatile__("mov %%cr8, %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
case 'f':
|
||||
// Push flags and pop them into our buffer
|
||||
__asm__ __volatile__("pushfq\n\t" "popq %[dest]" : [dest] "=r" (Data) : :);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
size_t WriteControlRegister(int CRX, size_t Data) {
|
||||
switch(CRX) {
|
||||
case 0:
|
||||
__asm__ __volatile__("mov %[dest], %%cr0" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 1:
|
||||
__asm__ __volatile__("mov %[dest], %%cr1" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 2:
|
||||
__asm__ __volatile__("mov %[dest], %%cr2" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 3:
|
||||
__asm__ __volatile__("mov %[dest], %%cr3" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 4:
|
||||
__asm__ __volatile__("mov %[dest], %%cr4" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 8:
|
||||
__asm__ __volatile__("mov %[dest], %%cr8" : : [dest] "r" (Data) :);
|
||||
break;
|
||||
case 'f':
|
||||
__asm__ __volatile__("pushq %[dest]\n\t" "popfq" : : [dest] "r" (Data) : "cc");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Data;
|
||||
|
||||
}
|
||||
|
||||
// XCR = eXtended Control Register.
|
||||
// XCR0 is used to enable AVX/SSE.
|
||||
|
||||
size_t ReadExtendedControlRegister(size_t XCRX) {
|
||||
size_t RegHigh = 0, RegLow = 0;
|
||||
|
||||
__asm__ __volatile__("xgetbv" : "=a" (RegLow), "=d" (RegHigh) : "c" (XCRX) :);
|
||||
return (RegHigh << 32 | RegLow);
|
||||
}
|
||||
|
||||
size_t WriteExtendedControlRegister(size_t XCRX, size_t Data) {
|
||||
__asm__ __volatile__("xsetbv" : : "a" ( ((uint32_t*)&Data)[0]), "c" (XCRX), "d" ( ((uint32_t*)&Data)[1] ) :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
// The following two functions are utility - for determining whether we're operating in Long Mode.
|
||||
// TODO: Move into DescriptorTables.c
|
||||
|
||||
size_t ReadXCS() {
|
||||
size_t Data = 0;
|
||||
__asm__ __volatile__("mov %%cs, %[dest]" : [dest] "=r" (Data) : :);
|
||||
return Data;
|
||||
}
|
||||
|
||||
DESCRIPTOR_TABLE_POINTER FetchGDT() {
|
||||
DESCRIPTOR_TABLE_POINTER GDTrData = {0};
|
||||
|
||||
__asm__ __volatile__("sgdt %[dest]" : [dest] "=m" (GDTrData) : :);
|
||||
return GDTrData;
|
||||
}
|
||||
|
||||
void SetGDT(DESCRIPTOR_TABLE_POINTER GDTrData) {
|
||||
__asm__ __volatile__("lgdt %[src]" : : [src] "m" (GDTrData) :);
|
||||
}
|
||||
|
||||
DESCRIPTOR_TABLE_POINTER FetchIDT() {
|
||||
DESCRIPTOR_TABLE_POINTER IDTrData = {0};
|
||||
__asm__ __volatile__("sidt %[dest]" : [dest] "=m" (IDTrData) : :);
|
||||
return IDTrData;
|
||||
}
|
||||
|
||||
void SetIDT(DESCRIPTOR_TABLE_POINTER IDTrData) {
|
||||
__asm__ __volatile__("lidt %[src]" : : [src] "m" (IDTrData) :);
|
||||
}
|
||||
|
||||
// LDT = Local Descriptor Table (= GDT entry for current segment)
|
||||
|
||||
uint16_t FetchLDT() {
|
||||
uint16_t LDTrData = 0;
|
||||
__asm__ __volatile__("sldt %[dest]" : [dest] "=m" (LDTrData) : :);
|
||||
return LDTrData;
|
||||
}
|
||||
|
||||
void SetLDT(uint16_t LDTrData) {
|
||||
__asm__ __volatile__("lldt %[src]" : : [src] "m" (LDTrData) :);
|
||||
}
|
||||
|
||||
// TSR - Tast State Register
|
||||
|
||||
uint16_t FetchTSR() {
|
||||
uint16_t TSRData = 0;
|
||||
__asm__ __volatile__ ("str %[dest]" : [dest] "=m" (TSRData) : :);
|
||||
return TSRData;
|
||||
}
|
||||
|
||||
void SetTSR(uint16_t TSRData) {
|
||||
__asm__ __volatile__("ltr %[src]" : : [src] "m" (TSRData) :);
|
||||
}
|
Loading…
Reference in New Issue
Block a user