mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-12 14:10:36 -04:00
Update ACPI to implement shutdown
This commit is contained in:
parent
03e21e8b37
commit
92fa122b0f
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace acpi {
|
namespace acpi {
|
||||||
|
|
||||||
void init();
|
bool init();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
} //end of acpi namespace
|
} //end of acpi namespace
|
||||||
|
@ -14,8 +14,11 @@ namespace paging {
|
|||||||
|
|
||||||
const int PAGE_SIZE = 4096;
|
const int PAGE_SIZE = 4096;
|
||||||
|
|
||||||
bool identity_map(void* physical);
|
void* physical_address(void* virt);
|
||||||
bool identity_map(void* physical, size_t pages);
|
bool page_present(void* virt);
|
||||||
|
bool page_free_or_set(void* virt, void* physical);
|
||||||
|
bool identity_map(void* virt);
|
||||||
|
bool identity_map(void* virt, size_t pages);
|
||||||
|
|
||||||
} //end of namespace paging
|
} //end of namespace paging
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ uint64_t str_len(const char* a);
|
|||||||
const char* str_until(char* a, char c);
|
const char* str_until(char* a, char c);
|
||||||
const char* str_from(char* a, char c);
|
const char* str_from(char* a, char c);
|
||||||
|
|
||||||
|
void memset(void * ptr, uint8_t value, size_t num);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void memcopy(T* destination, const T* source, size_t size){
|
void memcopy(T* destination, const T* source, size_t size){
|
||||||
--source;
|
--source;
|
||||||
|
@ -15,37 +15,39 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
uint32_t *SMI_CMD;
|
uint32_t SMI_CMD; //ptr
|
||||||
uint8_t ACPI_ENABLE;
|
uint8_t ACPI_ENABLE;
|
||||||
uint8_t ACPI_DISABLE;
|
uint8_t ACPI_DISABLE;
|
||||||
uint32_t *PM1a_CNT;
|
uint32_t PM1a_CNT; //ptr
|
||||||
uint32_t *PM1b_CNT;
|
uint32_t PM1b_CNT; //ptr
|
||||||
uint16_t SLP_TYPa;
|
uint16_t SLP_TYPa;
|
||||||
uint16_t SLP_TYPb;
|
uint16_t SLP_TYPb;
|
||||||
uint16_t SLP_EN;
|
uint16_t SLP_EN;
|
||||||
uint16_t SCI_EN;
|
uint16_t SCI_EN;
|
||||||
uint8_t PM1_CNT_LEN;
|
uint8_t PM1_CNT_LEN;
|
||||||
|
|
||||||
|
bool version_2 = false;
|
||||||
|
|
||||||
struct RSDPtr {
|
struct RSDPtr {
|
||||||
uint8_t Signature[8];
|
uint8_t Signature[8];
|
||||||
uint8_t CheckSum;
|
uint8_t CheckSum;
|
||||||
uint8_t OemID[6];
|
uint8_t OemID[6];
|
||||||
uint8_t Revision;
|
uint8_t Revision;
|
||||||
uint32_t *RsdtAddress;
|
uint32_t RsdtAddress; //ptr
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FACP {
|
struct FACP {
|
||||||
uint8_t Signature[4];
|
uint8_t Signature[4];
|
||||||
uint32_t Length;
|
uint32_t Length;
|
||||||
uint8_t unneded1[40 - 8];
|
uint8_t unneded1[40 - 8];
|
||||||
uint32_t *DSDT;
|
uint32_t DSDT; //ptr
|
||||||
uint8_t unneded2[48 - 44];
|
uint8_t unneded2[48 - 44];
|
||||||
uint32_t *SMI_CMD;
|
uint32_t SMI_CMD; //ptr
|
||||||
uint8_t ACPI_ENABLE;
|
uint8_t ACPI_ENABLE;
|
||||||
uint8_t ACPI_DISABLE;
|
uint8_t ACPI_DISABLE;
|
||||||
uint8_t unneded3[64 - 54];
|
uint8_t unneded3[64 - 54];
|
||||||
uint32_t *PM1a_CNT_BLK;
|
uint32_t PM1a_CNT_BLK; //ptr
|
||||||
uint32_t *PM1b_CNT_BLK;
|
uint32_t PM1b_CNT_BLK; //ptr
|
||||||
uint8_t unneded4[89 - 72];
|
uint8_t unneded4[89 - 72];
|
||||||
uint8_t PM1_CNT_LEN;
|
uint8_t PM1_CNT_LEN;
|
||||||
};
|
};
|
||||||
@ -83,10 +85,8 @@ unsigned int* check_rsd_ptr(unsigned int *ptr) {
|
|||||||
|
|
||||||
// found valid rsdpd
|
// found valid rsdpd
|
||||||
if (check == 0) {
|
if (check == 0) {
|
||||||
if (rsdp->Revision == 0)
|
version_2 = rsdp->Revision != 0;
|
||||||
k_print_line("ACPI 1");
|
|
||||||
else
|
|
||||||
k_print_line("ACPI 2");
|
|
||||||
return reinterpret_cast<unsigned int *>(rsdp->RsdtAddress);
|
return reinterpret_cast<unsigned int *>(rsdp->RsdtAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,14 +142,14 @@ int check_header(unsigned int *ptr, const char* sig){
|
|||||||
|
|
||||||
int acpiEnable(void){
|
int acpiEnable(void){
|
||||||
// check if acpi is enabled
|
// check if acpi is enabled
|
||||||
if ( (in_word(reinterpret_cast<uint64_t>(PM1a_CNT)) &SCI_EN) == 0 ){
|
if ( (in_word(PM1a_CNT) &SCI_EN) == 0 ){
|
||||||
// check if acpi can be enabled
|
// check if acpi can be enabled
|
||||||
if (SMI_CMD != 0 && ACPI_ENABLE != 0){
|
if (SMI_CMD != 0 && ACPI_ENABLE != 0){
|
||||||
out_byte(reinterpret_cast<uint64_t>(SMI_CMD), ACPI_ENABLE); // send acpi enable command
|
out_byte(SMI_CMD, ACPI_ENABLE); // send acpi enable command
|
||||||
// give 3 seconds time to enable acpi
|
// give 3 seconds time to enable acpi
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<300; i++ ){
|
for (i=0; i<300; i++ ){
|
||||||
if ( (in_word(reinterpret_cast<uint64_t>(PM1a_CNT)) & SCI_EN) == 1 )
|
if ( (in_word(PM1a_CNT) & SCI_EN) == 1 )
|
||||||
break;
|
break;
|
||||||
sleep_ms(10);
|
sleep_ms(10);
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ int acpiEnable(void){
|
|||||||
if (PM1b_CNT != 0)
|
if (PM1b_CNT != 0)
|
||||||
for (; i<300; i++ )
|
for (; i<300; i++ )
|
||||||
{
|
{
|
||||||
if ( (in_word(reinterpret_cast<uint64_t>(PM1b_CNT)) & SCI_EN) == 1 )
|
if ( (in_word(PM1b_CNT) & SCI_EN) == 1 )
|
||||||
break;
|
break;
|
||||||
sleep_ms(10);
|
sleep_ms(10);
|
||||||
}
|
}
|
||||||
@ -199,17 +199,12 @@ int acpiEnable(void){
|
|||||||
int init_acpi(){
|
int init_acpi(){
|
||||||
unsigned int *ptr = get_rsd_ptr();
|
unsigned int *ptr = get_rsd_ptr();
|
||||||
|
|
||||||
k_printf("%h\n", reinterpret_cast<uintptr_t>(ptr));
|
|
||||||
|
|
||||||
if(!paging::identity_map(ptr, 16)){
|
if(!paging::identity_map(ptr, 16)){
|
||||||
k_print_line("Impossible to map the ACPI tables");
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if address is correct ( if acpi is available on this pc )
|
// check if address is correct ( if acpi is available on this pc )
|
||||||
if (ptr && check_header(ptr, "RSDT") == 0){
|
if (ptr && check_header(ptr, "RSDT") == 0){
|
||||||
//k_print_line("2");
|
|
||||||
// the RSDT contains an unknown number of pointers to acpi tables
|
// the RSDT contains an unknown number of pointers to acpi tables
|
||||||
int entrys = *(ptr + 1);
|
int entrys = *(ptr + 1);
|
||||||
entrys = (entrys-36) /4;
|
entrys = (entrys-36) /4;
|
||||||
@ -220,11 +215,12 @@ int init_acpi(){
|
|||||||
if (check_header(reinterpret_cast<unsigned int*>(*ptr), "FACP") == 0){
|
if (check_header(reinterpret_cast<unsigned int*>(*ptr), "FACP") == 0){
|
||||||
entrys = -2;
|
entrys = -2;
|
||||||
|
|
||||||
struct FACP *facp = reinterpret_cast<FACP*>(*ptr);
|
struct FACP* facp = reinterpret_cast<FACP*>(*ptr);
|
||||||
|
|
||||||
if (check_header(reinterpret_cast<unsigned int*>(facp->DSDT), "DSDT") == 0){
|
if (check_header(reinterpret_cast<unsigned int*>(facp->DSDT), "DSDT") == 0){
|
||||||
// search the \_S5 package in the DSDT
|
// search the \_S5 package in the DSDT
|
||||||
char *S5Addr = reinterpret_cast<char *>(facp->DSDT + 36); // skip header
|
char *S5Addr = reinterpret_cast<char *>(facp->DSDT + 36); // skip header
|
||||||
int dsdtLength = *(facp->DSDT+1) -36;
|
int dsdtLength = *(reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(facp->DSDT)+1)) - 36;
|
||||||
while (0 < dsdtLength--){
|
while (0 < dsdtLength--){
|
||||||
if ( memcmp(S5Addr, "_S5_", 4) == 0)
|
if ( memcmp(S5Addr, "_S5_", 4) == 0)
|
||||||
break;
|
break;
|
||||||
@ -287,8 +283,8 @@ int init_acpi(){
|
|||||||
|
|
||||||
} //end of anonymous namespace
|
} //end of anonymous namespace
|
||||||
|
|
||||||
void acpi::init(){
|
bool acpi::init(){
|
||||||
init_acpi();
|
return init_acpi() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void acpi::shutdown(){
|
void acpi::shutdown(){
|
||||||
@ -300,9 +296,9 @@ void acpi::shutdown(){
|
|||||||
acpiEnable();
|
acpiEnable();
|
||||||
|
|
||||||
// send the shutdown command
|
// send the shutdown command
|
||||||
out_word(reinterpret_cast<uint64_t>(PM1a_CNT), SLP_TYPa | SLP_EN );
|
out_word(PM1a_CNT, SLP_TYPa | SLP_EN );
|
||||||
if ( PM1b_CNT != 0 ){
|
if ( PM1b_CNT != 0 ){
|
||||||
out_word(reinterpret_cast<uint64_t>(PM1b_CNT), SLP_TYPb | SLP_EN );
|
out_word(PM1b_CNT, SLP_TYPb | SLP_EN );
|
||||||
}
|
}
|
||||||
|
|
||||||
k_print_line("acpi poweroff failed.");
|
k_print_line("acpi poweroff failed.");
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
#include "paging.hpp"
|
#include "paging.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
|
#include "console.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -16,44 +19,153 @@ typedef pt_t* pdt_t;
|
|||||||
typedef pdt_t* pdpt_t;
|
typedef pdt_t* pdpt_t;
|
||||||
typedef pdpt_t* pml4t_t;
|
typedef pdpt_t* pml4t_t;
|
||||||
|
|
||||||
|
constexpr int PRESENT = 0x1;
|
||||||
|
constexpr int WRITEABLE = 0x2;
|
||||||
|
constexpr int USER = 0x4;
|
||||||
|
|
||||||
|
//Memory from 0x70000 can be used for pages
|
||||||
|
uintptr_t last_page = 0x73000;
|
||||||
|
|
||||||
|
uintptr_t init_new_page(){
|
||||||
|
auto new_page = last_page + paging::PAGE_SIZE;
|
||||||
|
|
||||||
|
memset(reinterpret_cast<void*>(new_page), 0, paging::PAGE_SIZE);
|
||||||
|
|
||||||
|
last_page = new_page;
|
||||||
|
|
||||||
|
return new_page;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool page_aligned(void* addr){
|
||||||
|
return !(reinterpret_cast<uintptr_t>(addr) & (paging::PAGE_SIZE - 1));
|
||||||
|
}
|
||||||
|
|
||||||
} //end of anonymous namespace
|
} //end of anonymous namespace
|
||||||
|
|
||||||
bool paging::identity_map(void* physical){
|
void* paging::physical_address(void* virt){
|
||||||
|
if(!page_present(virt)){
|
||||||
|
//TODO Not a very good value since 0x0 is a valid physical address
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find the correct indexes inside the paging table for the physical address
|
||||||
|
auto table = (reinterpret_cast<uintptr_t>(virt) >> 12) & 0x1FF;
|
||||||
|
auto directory = (reinterpret_cast<uintptr_t>(virt) >> 21) & 0x1FF;
|
||||||
|
auto directory_ptr = (reinterpret_cast<uintptr_t>(virt) >> 30) & 0x1FF;
|
||||||
|
auto pml4 = (reinterpret_cast<uintptr_t>(virt) >> 39) & 0x1FF;
|
||||||
|
|
||||||
|
pml4t_t pml4t = reinterpret_cast<pml4t_t>(0x70000);
|
||||||
|
|
||||||
|
auto pdpt = reinterpret_cast<pdpt_t>(reinterpret_cast<uintptr_t>(pml4t[pml4]) & ~0xFFF);
|
||||||
|
auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||||
|
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[directory]) & ~0xFFF);
|
||||||
|
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(pt[table]) & ~0xFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool paging::page_present(void* virt){
|
||||||
|
//Find the correct indexes inside the paging table for the physical address
|
||||||
|
auto table = (reinterpret_cast<uintptr_t>(virt) >> 12) & 0x1FF;
|
||||||
|
auto directory = (reinterpret_cast<uintptr_t>(virt) >> 21) & 0x1FF;
|
||||||
|
auto directory_ptr = (reinterpret_cast<uintptr_t>(virt) >> 30) & 0x1FF;
|
||||||
|
auto pml4 = (reinterpret_cast<uintptr_t>(virt) >> 39) & 0x1FF;
|
||||||
|
|
||||||
|
pml4t_t pml4t = reinterpret_cast<pml4t_t>(0x70000);
|
||||||
|
if(!(reinterpret_cast<uintptr_t>(pml4t[pml4]) & PRESENT)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pdpt = reinterpret_cast<pdpt_t>(reinterpret_cast<uintptr_t>(pml4t[pml4]) & ~0xFFF);
|
||||||
|
if(!(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & PRESENT)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||||
|
if(!(reinterpret_cast<uintptr_t>(pdt[directory]) & PRESENT)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[directory]) & ~0xFFF);
|
||||||
|
return reinterpret_cast<uintptr_t>(pt[table]) & PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool paging::page_free_or_set(void* virt, void* physical){
|
||||||
|
if(!page_present(virt)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(physical_address(virt) == physical){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool paging::identity_map(void* virt){
|
||||||
//The address must be page-aligned
|
//The address must be page-aligned
|
||||||
if(reinterpret_cast<uintptr_t>(physical) % PAGE_SIZE != 0){
|
if(!page_aligned(virt)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Find the correct indexes inside the paging table for the physical address
|
//Find the correct indexes inside the paging table for the physical address
|
||||||
auto table = (reinterpret_cast<uintptr_t>(physical) >> 12) & 0x1FF;
|
auto table = (reinterpret_cast<uintptr_t>(virt) >> 12) & 0x1FF;
|
||||||
auto directory = (reinterpret_cast<uintptr_t>(physical) >> 21) & 0x1FF;
|
auto directory = (reinterpret_cast<uintptr_t>(virt) >> 21) & 0x1FF;
|
||||||
auto directory_ptr = (reinterpret_cast<uintptr_t>(physical) >> 30) & 0x1FF;
|
auto directory_ptr = (reinterpret_cast<uintptr_t>(virt) >> 30) & 0x1FF;
|
||||||
auto pml4 = (reinterpret_cast<uintptr_t>(physical) >> 39) & 0x1FF;
|
auto pml4 = (reinterpret_cast<uintptr_t>(virt) >> 39) & 0x1FF;
|
||||||
|
|
||||||
//Find the entries
|
|
||||||
pml4t_t pml4t = reinterpret_cast<pml4t_t>(0x70000);
|
pml4t_t pml4t = reinterpret_cast<pml4t_t>(0x70000);
|
||||||
|
|
||||||
|
//Init new page if necessary
|
||||||
|
if(!(reinterpret_cast<uintptr_t>(pml4t[pml4]) & PRESENT)){
|
||||||
|
pml4t[pml4] = reinterpret_cast<pdpt_t>(init_new_page() | (PRESENT | WRITEABLE));
|
||||||
|
}
|
||||||
|
|
||||||
auto pdpt = reinterpret_cast<pdpt_t>(reinterpret_cast<uintptr_t>(pml4t[pml4]) & ~0xFFF);
|
auto pdpt = reinterpret_cast<pdpt_t>(reinterpret_cast<uintptr_t>(pml4t[pml4]) & ~0xFFF);
|
||||||
|
|
||||||
|
//Init new page if necessary
|
||||||
|
if(!(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & PRESENT)){
|
||||||
|
pdpt[directory_ptr] = reinterpret_cast<pdt_t>(init_new_page() | (PRESENT | WRITEABLE));
|
||||||
|
}
|
||||||
|
|
||||||
auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||||
|
|
||||||
|
//Init new page if necessary
|
||||||
|
if(!(reinterpret_cast<uintptr_t>(pdt[directory]) & PRESENT)){
|
||||||
|
pdt[directory] = reinterpret_cast<pt_t>(init_new_page() | (PRESENT | WRITEABLE));
|
||||||
|
}
|
||||||
|
|
||||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[directory]) & ~0xFFF);
|
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[directory]) & ~0xFFF);
|
||||||
|
|
||||||
//Identity map the physical address
|
//Check if the page is already present
|
||||||
pt[table] = reinterpret_cast<page_entry>(reinterpret_cast<uintptr_t>(physical) | 0x3);
|
if(reinterpret_cast<uintptr_t>(pt[table]) & PRESENT){
|
||||||
|
//If the page is already set to the correct value, return true
|
||||||
|
//If the page is set to another value, return false
|
||||||
|
return reinterpret_cast<uintptr_t>(pt[table]) == (reinterpret_cast<uintptr_t>(virt) | (PRESENT | WRITEABLE));
|
||||||
|
}
|
||||||
|
|
||||||
//TODO Check if pt[table] is already used and if so, return false
|
//Identity map the physical address
|
||||||
|
pt[table] = reinterpret_cast<page_entry>(reinterpret_cast<uintptr_t>(virt) | (PRESENT | WRITEABLE));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool paging::identity_map(void* physical, size_t pages){
|
bool paging::identity_map(void* virt, size_t pages){
|
||||||
//The address must be page-aligned
|
//The address must be page-aligned
|
||||||
if(reinterpret_cast<uintptr_t>(physical) % PAGE_SIZE != 0){
|
if(!page_aligned(virt)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO This should first check each page for the present bit
|
//To avoid mapping only a subset of the pages
|
||||||
|
//check if one of the page is already mapped to another value
|
||||||
for(size_t page = 0; page < pages; ++page){
|
for(size_t page = 0; page < pages; ++page){
|
||||||
if(!identity_map(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(physical) + page * PAGE_SIZE))){
|
auto addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(virt) + page * PAGE_SIZE);
|
||||||
|
if(!page_free_or_set(addr, addr)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Identity map each page
|
||||||
|
for(size_t page = 0; page < pages; ++page){
|
||||||
|
if(!identity_map(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(virt) + page * PAGE_SIZE))){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,9 +516,11 @@ void cat_command(const vector<string>& params){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void shutdown_command(const vector<string>&){
|
void shutdown_command(const vector<string>&){
|
||||||
k_print_line("Init ACPI");
|
if(!acpi::init()){
|
||||||
|
k_print_line("Unable to init ACPI");
|
||||||
|
}
|
||||||
|
|
||||||
acpi::init();
|
acpi::shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
} //end of anonymous namespace
|
} //end of anonymous namespace
|
||||||
|
@ -36,7 +36,7 @@ void decode_bytes (int data, int descriptor[16], int *next){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void get_cache_info() {
|
void get_cache_info() {
|
||||||
int next = 0, i = 0;
|
/*int next = 0, i = 0;
|
||||||
int descriptor[256];
|
int descriptor[256];
|
||||||
int mem_count;
|
int mem_count;
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ void get_cache_info() {
|
|||||||
k_print_line(" 64-byte prefetching");
|
k_print_line(" 64-byte prefetching");
|
||||||
if ( descriptor[i] == 0xF1)
|
if ( descriptor[i] == 0xF1)
|
||||||
k_print_line(" 128-byte prefetching");
|
k_print_line(" 128-byte prefetching");
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// EDX Features
|
// EDX Features
|
||||||
|
@ -8,6 +8,16 @@
|
|||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "string.hpp"
|
#include "string.hpp"
|
||||||
|
|
||||||
|
void memset(void* ptr, unsigned char value, size_t num){
|
||||||
|
auto p = static_cast<unsigned char*>(ptr);
|
||||||
|
|
||||||
|
--p;
|
||||||
|
|
||||||
|
while(num--){
|
||||||
|
*++p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool str_equals(const char* a, const char* b){
|
bool str_equals(const char* a, const char* b){
|
||||||
while(*a && *a == *b){
|
while(*a && *a == *b){
|
||||||
++a;
|
++a;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user