a new version + a bunch of crap (temp)
This commit is contained in:
3
ccc.cpp
3
ccc.cpp
@@ -251,5 +251,8 @@ int main(int argc,char **argv) {
|
||||
}
|
||||
}
|
||||
}
|
||||
ofstream out_file(filepath+".ccomp",ios::binary);
|
||||
out_file.write(reinterpret_cast<const char*>(output.data()),output.size());
|
||||
out_file.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
260
ccc.cpp.ccomp
Normal file
260
ccc.cpp.ccomp
Normal file
@@ -0,0 +1,260 @@
|
||||
CCC@ push_backunsignedoutput
|
||||
bytes_to_skip codepointcharleaderboardstringincludecodechildrensourcecurrsizein_comment_singlein_comment_multisregex_iteratorreturnelse root_nodeintnamefilepathtoken_idcontinuevectorconstsymbolfortop64nodebest_idistreambuf_iteratorfalse in_stringsize_tlengthout_filebest_lenscoresymbol_regextokenscleancinsertwords_begincountsx3F
|
||||
clean_code
|
||||
filesystemautocleancount words_endmatch namespacecoutboolfileendlbinarystructmapstrregexcstddef>
|
||||
cÇ>
|
||||
ioþeam>
|
||||
ð>
|
||||
fþeam>
|
||||
Ç>
|
||||
ý>
|
||||
Ù>
|
||||
iterator>
|
||||
ÿ>
|
||||
using ö std;
|
||||
ö fs=ð;
|
||||
Ú Ù<Ç> é={
|
||||
"€",
|
||||
"<22>",
|
||||
"ñ",
|
||||
"ø",
|
||||
"„",
|
||||
"…",
|
||||
"Å",
|
||||
"Ú",
|
||||
"ˆ",
|
||||
"Ø",
|
||||
"Š",
|
||||
"‹",
|
||||
"Œ",
|
||||
"Ò",
|
||||
"Ž",
|
||||
"<22>",
|
||||
"á",
|
||||
"‘",
|
||||
"Ü",
|
||||
"“",
|
||||
"”",
|
||||
"•",
|
||||
"Ô",
|
||||
"—",
|
||||
"˜",
|
||||
"™",
|
||||
"š",
|
||||
"Ñ",
|
||||
"œ",
|
||||
"<22>",
|
||||
"ž",
|
||||
"Ÿ",
|
||||
" ",
|
||||
"ü",
|
||||
"¢",
|
||||
"£",
|
||||
"¤",
|
||||
"¥",
|
||||
"¦",
|
||||
"§",
|
||||
"¨",
|
||||
"Á",
|
||||
"ª",
|
||||
"«",
|
||||
"¬",
|
||||
"",
|
||||
"#È \"",
|
||||
"¯",
|
||||
"°",
|
||||
"±",
|
||||
"²",
|
||||
"³",
|
||||
"´",
|
||||
"µ",
|
||||
"¶",
|
||||
"·",
|
||||
"¸",
|
||||
"¹",
|
||||
"º",
|
||||
"»",
|
||||
"¼",
|
||||
"½",
|
||||
"¾",
|
||||
"¿"
|
||||
};
|
||||
ü Û {
|
||||
Ç Õ;
|
||||
Ô ç;
|
||||
};
|
||||
ü Þ {
|
||||
ý<·,Þ*> Ê;
|
||||
Ô ×=-1;
|
||||
};
|
||||
ª ë(Þ* root,Ç þ,Ô id) {
|
||||
Þ* Ì=root;
|
||||
Ü (Å c:þ) {
|
||||
” (Ì->Ê.find(c)==Ì->Ê.end()) {
|
||||
Ì->Ê[c]=new Þ();
|
||||
}
|
||||
Ì=Ì->Ê[c];
|
||||
}
|
||||
Ì->×=id;
|
||||
}
|
||||
Ç ï(Ç Ë) {
|
||||
Ç ò;
|
||||
ø â=á;
|
||||
ø Î=á;
|
||||
ø Ï=á;
|
||||
Ü (ã i=0;i<Ë.Í();++i) {
|
||||
” (Ï) {
|
||||
” (Ë[i]=='*' && i+1<Ë.Í() && Ë[i+1]=='/') {
|
||||
Ï=á;
|
||||
i++;
|
||||
}
|
||||
Ø;
|
||||
}
|
||||
” (Î) {
|
||||
” (Ë[i]=='\n') {
|
||||
Î=á;
|
||||
} Ò {
|
||||
Ø;
|
||||
}
|
||||
}
|
||||
” (â) {
|
||||
” (Ë[i]=='\\') {i++;Ø;}
|
||||
” (Ë[i]=='"') â=á;
|
||||
Ø;
|
||||
}
|
||||
” (Ë[i]=='/' && i+1<Ë.Í()) {
|
||||
” (Ë[i+1]=='/') {Î=¤;i++;Ø;}
|
||||
” (Ë[i+1]=='*') {Ï=¤;i++;Ø;}
|
||||
}
|
||||
” (Ë[i]=='"') {
|
||||
â=¤;
|
||||
Ø;
|
||||
}
|
||||
ò+=Ë[i];
|
||||
}
|
||||
Ñ ò;
|
||||
}
|
||||
Ô main(Ô argc,Å **argv) {
|
||||
” (argc!=2) {
|
||||
÷<<"Usage: ccc <c ù>"<<ú;
|
||||
Ñ -1;
|
||||
}
|
||||
Ç Ö=Ç(argv[1]);
|
||||
” (!fs::exists(Ö)) {
|
||||
÷<<"Error: provided ù ‹esn't exist."<<ú;
|
||||
Ñ -1;
|
||||
}
|
||||
”þeam ù(Ö,ios::û);
|
||||
” (!ù) {
|
||||
÷<<"Error: couldn't open provided ù."<<ú;
|
||||
Ñ -1;
|
||||
}
|
||||
Ç É((à<Å>(ù)),à<Å>());
|
||||
Ç ê=ï(É);
|
||||
ý<Ç,Ô> í;
|
||||
ÿ è("[a-zA-Z_][a-zA-Z0-9_]*");
|
||||
ñ ì=Ð(ê.begin(),ê.end(),è);
|
||||
ñ ô=Ð();
|
||||
Ü (Ð i=ì;i!=ô;i++) {
|
||||
Ç õ=i->þ();
|
||||
” (õ.ä()>2) {
|
||||
í[õ]++;
|
||||
}
|
||||
}
|
||||
Ù<Û> Æ;
|
||||
Ü (ñ Ú& [Õ,ó]:í) {
|
||||
Æ.À({Õ,(Ô)((Õ.ä()-1)*ó-(Õ.ä()+1))});
|
||||
}
|
||||
sort(Æ.begin(),Æ.end(),[](Ú Û& a,Ú Û& b) {
|
||||
Ñ a.ç>b.ç;
|
||||
});
|
||||
Ù<Û> Ý;
|
||||
Ü (Ô i=0;i<64 && i<Æ.Í();i++) {
|
||||
” (!(Æ[i].ç<=0)) Ý.À(Æ[i]);
|
||||
}
|
||||
Þ Ó;
|
||||
Ü (Ô i=0;i<é.Í() && i<64;i++) {
|
||||
ë(&Ó,é[i],0x80+i);
|
||||
}
|
||||
Ü (Ô i=0;i<Ý.Í();i++) {
|
||||
ë(&Ó,Ý[i].Õ,0xC0+i);
|
||||
}
|
||||
Ù<·> Â;
|
||||
Â.À('C');
|
||||
Â.À('C');
|
||||
Â.À('C');
|
||||
Â.À((·)Ý.Í());
|
||||
Ü (Ú ñ& s:Ý) {
|
||||
Â.À((·)s.Õ.ä());
|
||||
Ü (Å c:s.Õ) Â.À(c);
|
||||
}
|
||||
Ü (ã i=0;i<É.Í();) {
|
||||
Þ* Ì=&Ó;
|
||||
Ô ß=-1;
|
||||
ã æ=0;
|
||||
Ü (ã j=i;j<É.Í();j++) {
|
||||
· c=(·)É[j];
|
||||
” (Ì->Ê.ó(c)) {
|
||||
Ì=Ì->Ê[c];
|
||||
” (Ì->×!=-1) {
|
||||
ß=Ì->×;
|
||||
æ=(j-i)+1;
|
||||
}
|
||||
} Ò {
|
||||
„;
|
||||
}
|
||||
}
|
||||
” (ß!=-1) {
|
||||
Â.À((·)ß);
|
||||
i+=æ;
|
||||
} Ò {
|
||||
· c=(·)É[i];
|
||||
” (c<128) {
|
||||
Â.À(c);
|
||||
i++;
|
||||
} Ò {
|
||||
uÔ32_t Ä=0;
|
||||
Ô Ã=0;
|
||||
” ((c & 0xE0)==0xC0) {
|
||||
” (i+1<É.Í()) {
|
||||
Ä=((É[i]&0x1F)<<6) | (É[i+1]&0î);
|
||||
Â.À(12);
|
||||
Ã=2;
|
||||
}
|
||||
} Ò ” ((c & 0xF0)==0xE0) {
|
||||
” (i+2<É.Í()) {
|
||||
Ä=((É[i]&0x0F)<<12) | ((É[i+1]&0î)<<6) | (É[i+2]&0î);
|
||||
Â.À(13);
|
||||
Ã=3;
|
||||
}
|
||||
} Ò ” ((c & 0xF8)==0xF0) {
|
||||
” (i+3<É.Í()) {
|
||||
Ä=((É[i]&0x07)<<18) | ((É[i+1]&0î)<<12) | ((É[i+2]&0î)<<6) | (É[i+3]&0î);
|
||||
Â.À(14);
|
||||
Ã=4;
|
||||
}
|
||||
}
|
||||
” (Ã>0) {
|
||||
” (Ã==2) {
|
||||
Â.À((·)(Ä>>8));
|
||||
Â.À((·)(Ä));
|
||||
} Ò ” (Ã==3) {
|
||||
Â.À((·)(Ä>>8));
|
||||
Â.À((·)(Ä));
|
||||
} Ò ” (Ã==4) {
|
||||
Â.À((·)(Ä>>16));
|
||||
Â.À((·)(Ä>>8));
|
||||
Â.À((·)(Ä));
|
||||
}
|
||||
i+=Ã;
|
||||
} Ò {
|
||||
Â.À(c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ofþeam å(Ö+".ccomp",ios::û);
|
||||
å.write(reÔerpret_cast<¾>(Â.data()),Â.Í());
|
||||
å.close();
|
||||
Ñ 0;
|
||||
5
hello.c
Normal file
5
hello.c
Normal file
@@ -0,0 +1,5 @@
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
printf("hello");
|
||||
return 0;
|
||||
}
|
||||
BIN
hello.c.ccomp
Normal file
BIN
hello.c.ccomp
Normal file
Binary file not shown.
409
log.c
Normal file
409
log.c
Normal file
@@ -0,0 +1,409 @@
|
||||
#include "../include/log.h"
|
||||
#include "../include/page.h"
|
||||
sh_uint8 kernel_log_level=0;
|
||||
static inline sh_uint8 inb(sh_uint16 port) {
|
||||
sh_uint8 val;
|
||||
__asm__ volatile ("inb %1, %0":"=a"(val):"Nd"(port));
|
||||
return val;
|
||||
}
|
||||
static inline void outb(sh_uint16 port,sh_uint8 val) {
|
||||
__asm__ volatile ("outb %0, %1"::"a"(val),"Nd"(port));
|
||||
}
|
||||
SH_STATUS sh_log_send_byte(sh_uint8 b) {
|
||||
while (!(inb(SH_LOG_SERIAL_PORT_COM1+5) & 0x20));
|
||||
outb(SH_LOG_SERIAL_PORT_COM1,b);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_send_string(const char* str) {
|
||||
while (*str) {
|
||||
sh_log_send_byte(*str++);
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_send_uintn(sh_uint64 n) {
|
||||
char buf[20];
|
||||
sh_uint32 i=0;
|
||||
if (n==0) {
|
||||
sh_log_send_byte('0');
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
while (n>0) {
|
||||
buf[i++]='0'+(n%10);
|
||||
n/=10;
|
||||
}
|
||||
while (i--) {
|
||||
sh_log_send_byte(buf[i]);
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_send_uintn_hex(sh_uint64 n) {
|
||||
char buf[16];
|
||||
sh_uint32 i=0;
|
||||
const char hex_digits[]="0123456789ABCDEF";
|
||||
if (n==0) {
|
||||
sh_log_send_byte('0');
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
while (n>0) {
|
||||
buf[i++]=hex_digits[n & 0xF];
|
||||
n>>=4;
|
||||
}
|
||||
while (i--) {
|
||||
sh_log_send_byte(buf[i]);
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_send_double(double value) {
|
||||
if (value<0) {
|
||||
sh_log_send_byte('-');
|
||||
value=-value;
|
||||
}
|
||||
sh_uint64 integer_part=(sh_uint64)value;
|
||||
double fractional_part=value-(double)integer_part;
|
||||
SH_STATUS status=sh_log_send_uintn(integer_part);
|
||||
if (status!=SH_STATUS_SUCCESS) return status;
|
||||
status=sh_log_send_byte('.');
|
||||
if (status!=SH_STATUS_SUCCESS) return status;
|
||||
for (int i=0;i<6;i++) {
|
||||
fractional_part*=10.0;
|
||||
sh_uint64 digit=(sh_uint64)fractional_part;
|
||||
status=sh_log_send_byte('0'+(sh_uint8)digit);
|
||||
if (status!=SH_STATUS_SUCCESS) return status;
|
||||
fractional_part-=(double)digit;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_send_payload(sh_log_OUTPUT_PAYLOAD *payload) {
|
||||
if (payload==SH_NULLPTR) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (!(sh_log_output_type_valid(payload->output_type))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (!(sh_log_output_source_valid(payload->output_source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (payload->output_source!=SH_LOG_SOURCE_TEST && payload->output_type<kernel_log_level) {
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
sh_log_send_string("[Shelter:");
|
||||
if (payload->output_source==SH_LOG_SOURCE_MAIN) {
|
||||
sh_log_send_string("Main@");
|
||||
} else if (payload->output_source==SH_LOG_SOURCE_CONF) {
|
||||
sh_log_send_string("Conf@");
|
||||
} else if (payload->output_source==SH_LOG_SOURCE_PAGE) {
|
||||
sh_log_send_string("Page@");
|
||||
} else if (payload->output_source==SH_LOG_SOURCE_SLAB) {
|
||||
sh_log_send_string("Slab@");
|
||||
} else if (payload->output_source==SH_LOG_SOURCE_TEST) {
|
||||
sh_log_send_string("Test@");
|
||||
}
|
||||
if (payload->output_type==SH_LOG_DEBUG) {
|
||||
sh_log_send_string("Debug] ");
|
||||
} else if (payload->output_type==SH_LOG_LOG) {
|
||||
sh_log_send_string("Log] ");
|
||||
} else if (payload->output_type==SH_LOG_WARNING) {
|
||||
sh_log_send_string("Warning] ");
|
||||
} else if (payload->output_type==SH_LOG_ERROR) {
|
||||
sh_log_send_string("Error] ");
|
||||
} else if (payload->output_type==SH_LOG_CRITICAL) {
|
||||
sh_log_send_string("Critical] ");
|
||||
} else if (payload->output_type==SH_LOG_FATAL) {
|
||||
sh_log_send_string("Fatal] ");
|
||||
} else if (payload->output_type==SH_LOG_TEST) {
|
||||
sh_log_send_string("Test] ");
|
||||
}
|
||||
sh_log_send_uintn(payload->tsc_value);
|
||||
sh_log_send_string(" : ");
|
||||
sh_log_send_string(payload->message_pointer);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_load_log_level(sh_uint8 log_level) {
|
||||
kernel_log_level=log_level;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
sh_uint8 sh_log_get_log_level() {
|
||||
return kernel_log_level;
|
||||
}
|
||||
SH_STATUS sh_log_test(const char* str) {
|
||||
if (str==SH_NULLPTR) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_TEST,
|
||||
.output_source=SH_LOG_SOURCE_TEST,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_debug(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_DEBUG,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_log(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_LOG,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_warning(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_WARNING,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_error(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_ERROR,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_critical(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_CRITICAL,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_fatal(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_FATAL,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_ltest(const char* str) {
|
||||
if (str==SH_NULLPTR) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_TEST,
|
||||
.output_source=SH_LOG_SOURCE_TEST,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_ldebug(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_DEBUG,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_llog(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_LOG,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_lwarning(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_WARNING,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_lerror(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_ERROR,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_lcritical(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_CRITICAL,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_lfatal(const char* str,sh_log_OUTPUT_SOURCE source) {
|
||||
if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_log_OUTPUT_PAYLOAD payload={
|
||||
.output_type=SH_LOG_FATAL,
|
||||
.output_source=source,
|
||||
.tsc_value=sh_tsc_get_kernel_current_tsc(),
|
||||
.message_pointer=str
|
||||
};
|
||||
SH_STATUS status=sh_log_send_payload(&payload);
|
||||
if (sh_status_error(status)) {
|
||||
return status;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_log_mem_stats(sh_log_OUTPUT_SOURCE source) {
|
||||
sh_page_MEM_STATS mem_stats;
|
||||
sh_page_get_memory_stats(&mem_stats);
|
||||
if (sh_log_get_log_level()<=1) {
|
||||
sh_log_llog("Total memory installed (bytes) : ",source);
|
||||
sh_log_send_uintn(mem_stats.memory_total_bytes);
|
||||
sh_log_send_string(" / 0x");
|
||||
sh_log_send_uintn_hex(mem_stats.memory_total_bytes);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Total memory installed (pages) : ",source);
|
||||
sh_log_send_uintn(mem_stats.memory_total_pages);
|
||||
sh_log_send_string(" / 0x");
|
||||
sh_log_send_uintn_hex(mem_stats.memory_total_pages);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Free memory : ",source);
|
||||
sh_log_send_double(mem_stats.free_ratio*100);
|
||||
sh_log_send_string("%\n");
|
||||
sh_log_llog("Used memory : ",source);
|
||||
sh_log_send_double(mem_stats.used_ratio*100);
|
||||
sh_log_send_string("%\n");
|
||||
sh_log_llog("Free pages : ",source);
|
||||
sh_log_send_uintn(mem_stats.free_pages);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Used pages : ",source);
|
||||
sh_log_send_uintn(mem_stats.used_pages);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Largest free block (pages) : ",source);
|
||||
sh_log_send_uintn(mem_stats.largest_free_block);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Largest used block (pages) : ",source);
|
||||
sh_log_send_uintn(mem_stats.largest_used_block);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Free block count : ",source);
|
||||
sh_log_send_uintn(mem_stats.free_blocks_count);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Used block count : ",source);
|
||||
sh_log_send_uintn(mem_stats.used_blocks_count);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Total memory taken by physical bitmap (bytes) : ",source);
|
||||
sh_log_send_uintn(mem_stats.physical_bitmap_size_bytes);
|
||||
sh_log_send_string(" / 0x");
|
||||
sh_log_send_uintn_hex(mem_stats.physical_bitmap_size_bytes);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_llog("Total memory taken by physical bitmap (pages) : ",source);
|
||||
sh_log_send_uintn(mem_stats.physical_bitmap_size_pages);
|
||||
sh_log_send_string(" / 0x");
|
||||
sh_log_send_uintn_hex(mem_stats.physical_bitmap_size_pages);
|
||||
sh_log_send_string("\n");
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
412
log.c.ccomp
Normal file
412
log.c.ccomp
Normal file
@@ -0,0 +1,412 @@
|
||||
CCC@sh_log_send_stringSH_STATUS_SUCCESSSH_STATUS_INVALID_PARAMETERsh_tsc_get_kernel_current_tscsh_log_output_source_validreturn SH_STATUSpayloadsh_log_OUTPUT_PAYLOADsh_log_send_payloadstatus
|
||||
output_sourcesourcesh_log_OUTPUT_SOURCEoutput_typemessage_pointersh_log_send_uintnsh_status_error mem_stats
|
||||
SH_NULLPTRsh_log_send_bytesh_log_llog tsc_valuestrsh_log_send_uintn_hexconstcharSH_LOG_SOURCE_TESTsh_uint8kernel_log_levelfractional_part sh_uint64sh_log_send_doubleSH_LOG_CRITICALelseSH_LOG_WARNINGphysical_bitmap_size_pagesphysical_bitmap_size_bytesSH_LOG_DEBUGSH_LOG_ERRORSH_LOG_FATALinteger_partSH_LOG_SERIAL_PORT_COM1SH_LOG_TESTvaluewhilesh_log_get_log_level
|
||||
SH_LOG_LOGmemory_total_pagesmemory_total_bytesdoublebufport
|
||||
hex_digitsdigit sh_uint32 sh_uint16val log_levelvolatile__asm__includestaticinline®../ý/log.h"
|
||||
®../ý/page.h"
|
||||
Ü Ý=0;
|
||||
þ ÿ Ü inb(ø ô) {
|
||||
Ü ù;
|
||||
ü û ("inb %1, %0":"=a"(ù):"Nd"(ô));
|
||||
Å ù;
|
||||
}
|
||||
þ ÿ ª outb(ø ô,Ü ù) {
|
||||
ü û ("outb %0, %1"::"a"(ù),"Nd"(ô));
|
||||
}
|
||||
Æ Ô(Ü b) {
|
||||
í (!(inb(ê+5) & 0x20));
|
||||
outb(ê,b);
|
||||
Å Á;
|
||||
}
|
||||
Æ À(¾ ×) {
|
||||
í (*×) {
|
||||
Ô(*×++);
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ Ð(ß n) {
|
||||
Ú ó[20];
|
||||
÷ i=0;
|
||||
” (n==0) {
|
||||
Ô('0');
|
||||
Å Á;
|
||||
}
|
||||
í (n>0) {
|
||||
ó[i++]='0'+(n%10);
|
||||
n/=10;
|
||||
}
|
||||
í (i--) {
|
||||
Ô(ó[i]);
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ Ø(ß n) {
|
||||
Ú ó[16];
|
||||
÷ i=0;
|
||||
Ù Ú õ[]="0123456789ABCDEF";
|
||||
” (n==0) {
|
||||
Ô('0');
|
||||
Å Á;
|
||||
}
|
||||
í (n>0) {
|
||||
ó[i++]=õ[n & 0xF];
|
||||
n>>=4;
|
||||
}
|
||||
í (i--) {
|
||||
Ô(ó[i]);
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ à(ò ì) {
|
||||
” (ì<0) {
|
||||
Ô('-');
|
||||
ì=-ì;
|
||||
}
|
||||
ß é=(ß)ì;
|
||||
ò Þ=ì-(ò)é;
|
||||
Æ Ê=Ð(é);
|
||||
” (Ê!=Á) Å Ê;
|
||||
Ê=Ô('.');
|
||||
” (Ê!=Á) Å Ê;
|
||||
’ (– i=0;i<6;i++) {
|
||||
Þ*=10.0;
|
||||
ß ö=(ß)Þ;
|
||||
Ê=Ô('0'+(Ü)ö);
|
||||
” (Ê!=Á) Å Ê;
|
||||
Þ-=(ò)ö;
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ É(È *Ç) {
|
||||
” (Ç==Ó) {
|
||||
Å Â;
|
||||
}
|
||||
” (!(sh_log_Î_ùid(Ç->Î))) {
|
||||
Å Â;
|
||||
}
|
||||
” (!(Ä(Ç->Ë))) {
|
||||
Å Â;
|
||||
}
|
||||
” (Ç->Ë!=Û && Ç->Î<Ý) {
|
||||
Å Á;
|
||||
}
|
||||
À("[Shelter:");
|
||||
” (Ç->Ë==SH_LOG_SOURCE_MAIN) {
|
||||
À("Main@");
|
||||
} â ” (Ç->Ë==SH_LOG_SOURCE_CONF) {
|
||||
À("Conf@");
|
||||
} â ” (Ç->Ë==SH_LOG_SOURCE_PAGE) {
|
||||
À("Page@");
|
||||
} â ” (Ç->Ë==SH_LOG_SOURCE_SLAB) {
|
||||
À("Slab@");
|
||||
} â ” (Ç->Ë==Û) {
|
||||
À("Test@");
|
||||
}
|
||||
” (Ç->Î==æ) {
|
||||
À("Debug] ");
|
||||
} â ” (Ç->Î==ï) {
|
||||
À("Log] ");
|
||||
} â ” (Ç->Î==ã) {
|
||||
À("Warning] ");
|
||||
} â ” (Ç->Î==ç) {
|
||||
À("Error] ");
|
||||
} â ” (Ç->Î==á) {
|
||||
À("Critical] ");
|
||||
} â ” (Ç->Î==è) {
|
||||
À("Fatal] ");
|
||||
} â ” (Ç->Î==ë) {
|
||||
À("Test] ");
|
||||
}
|
||||
Ð(Ç->Ö);
|
||||
À(" : ");
|
||||
À(Ç->Ï);
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_load_ú(Ü ú) {
|
||||
Ý=ú;
|
||||
Å Á;
|
||||
}
|
||||
Ü î() {
|
||||
Å Ý;
|
||||
}
|
||||
Æ sh_log_test(¾ ×) {
|
||||
” (×==Ó) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=ë,
|
||||
.Ë=Û,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
À("\n");
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_debug(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=æ,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
À("\n");
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_log(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=ï,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
À("\n");
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_warning(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=ã,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
À("\n");
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_error(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=ç,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
À("\n");
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_critical(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=á,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
À("\n");
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_fatal(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=è,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
À("\n");
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_ltest(¾ ×) {
|
||||
” (×==Ó) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=ë,
|
||||
.Ë=Û,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_ldebug(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=æ,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ Õ(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=ï,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_lwarning(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=ã,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_lerror(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=ç,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_lcritical(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=á,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_lfatal(¾ ×,Í Ì) {
|
||||
” (×==Ó || !(Ä(Ì))) {
|
||||
Å Â;
|
||||
}
|
||||
È Ç={
|
||||
.Î=è,
|
||||
.Ë=Ì,
|
||||
.Ö=Ã(),
|
||||
.Ï=×
|
||||
};
|
||||
Æ Ê=É(&Ç);
|
||||
” (Ñ(Ê)) {
|
||||
Å Ê;
|
||||
}
|
||||
Å Á;
|
||||
}
|
||||
Æ sh_log_Ò(Í Ì) {
|
||||
sh_page_MEM_STATS Ò;
|
||||
sh_page_get_memory_stats(&Ò);
|
||||
” (î()<=1) {
|
||||
Õ("Total memory installed (bytes) : ",Ì);
|
||||
Ð(Ò.ñ);
|
||||
À(" / 0x");
|
||||
Ø(Ò.ñ);
|
||||
À("\n");
|
||||
Õ("Total memory installed (pages) : ",Ì);
|
||||
Ð(Ò.ð);
|
||||
À(" / 0x");
|
||||
Ø(Ò.ð);
|
||||
À("\n");
|
||||
Õ("Free memory : ",Ì);
|
||||
à(Ò.free_ratio*100);
|
||||
À("%\n");
|
||||
Õ("Used memory : ",Ì);
|
||||
à(Ò.used_ratio*100);
|
||||
À("%\n");
|
||||
Õ("Free pages : ",Ì);
|
||||
Ð(Ò.free_pages);
|
||||
À("\n");
|
||||
Õ("Used pages : ",Ì);
|
||||
Ð(Ò.used_pages);
|
||||
À("\n");
|
||||
Õ("Largest free block (pages) : ",Ì);
|
||||
Ð(Ò.largest_free_block);
|
||||
À("\n");
|
||||
Õ("Largest used block (pages) : ",Ì);
|
||||
Ð(Ò.largest_used_block);
|
||||
À("\n");
|
||||
Õ("Free block count : ",Ì);
|
||||
Ð(Ò.free_blocks_count);
|
||||
À("\n");
|
||||
Õ("Used block count : ",Ì);
|
||||
Ð(Ò.used_blocks_count);
|
||||
À("\n");
|
||||
Õ("Total memory taken by physical bitmap (bytes) : ",Ì);
|
||||
Ð(Ò.å);
|
||||
À(" / 0x");
|
||||
Ø(Ò.å);
|
||||
À("\n");
|
||||
Õ("Total memory taken by physical bitmap (pages) : ",Ì);
|
||||
Ð(Ò.ä);
|
||||
À(" / 0x");
|
||||
Ø(Ò.ä);
|
||||
À("\n");
|
||||
}
|
||||
Å Á;
|
||||
721
page.c
Normal file
721
page.c
Normal file
@@ -0,0 +1,721 @@
|
||||
#include "../include/page.h"
|
||||
#include <stdint.h>
|
||||
__attribute__((section(".bss")))
|
||||
static sh_uint8 memory_map_buffer[64*1024];
|
||||
static sh_uint8 *physical_bitmap;
|
||||
__attribute__((section(".bss")))
|
||||
static sh_uint64 physical_memory_pages_count=0;
|
||||
__attribute__((section(".bss")))
|
||||
static sh_uint64 physical_memory_bytes_count=0;
|
||||
__attribute__((section(".bss")))
|
||||
static sh_uint64 physical_bitmap_size_bytes=0;
|
||||
__attribute__((section(".bss")))
|
||||
static sh_uint64 physical_bitmap_size_pages=0;
|
||||
static sh_page_VIRTUAL_ADRESS page_table_pool_va_ptr=SH_PAGE_NULL_VA;
|
||||
SH_STATUS sh_page_load_boot_ptp_va(sh_page_VIRTUAL_ADRESS pt_pool_va) {
|
||||
page_table_pool_va_ptr=pt_pool_va;
|
||||
sh_log_ldebug("Page table pool VA: 0x",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn_hex((sh_uint64)page_table_pool_va_ptr);
|
||||
sh_log_send_string("\n");
|
||||
sh_uint8 first_byte=*(sh_uint8*)(page_table_pool_va_ptr);
|
||||
sh_log_debug("If you can see this message, no fault happened.",SH_LOG_SOURCE_PAGE);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
sh_page_VIRTUAL_ADRESS sh_page_get_boot_ptp_va() {
|
||||
return page_table_pool_va_ptr;
|
||||
}
|
||||
SH_STATUS sh_page_copy_memory_map() {
|
||||
return sh_mem_copy(memory_map_buffer,(void*)SH_PAGE_MEMORY_MAP_VA,sizeof(memory_map_buffer));
|
||||
}
|
||||
SH_STATUS sh_page_check_memory_map() {
|
||||
static const sh_uint8 memory_map_sig[8]={'S','h','e','M','m','a','p','B'};
|
||||
if (sh_mem_compare(memory_map_sig,memory_map_buffer,sizeof(memory_map_sig))==SH_STATUS_MEM_NOT_EQUAL) {
|
||||
sh_log_critical("Memory map doesn't have signature on.",SH_LOG_SOURCE_PAGE);
|
||||
return SH_STATUS_INVALID_SIGNATURE;
|
||||
}
|
||||
sh_page_MEMORY_MAP_HEADER *memory_map_header=(sh_page_MEMORY_MAP_HEADER *)memory_map_buffer;
|
||||
sh_log_ldebug("Memory map entry count: ",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn((sh_uint64)memory_map_header->entry_count);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_ldebug("Memory map entry size: ",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn((sh_uint64)memory_map_header->entry_size);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_ldebug("Memory map syntax version: ",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn((sh_uint64)memory_map_header->mmap_syntax_version);
|
||||
sh_log_send_string("\n");
|
||||
if (memory_map_header->entry_count*memory_map_header->entry_size+sizeof(sh_page_MEMORY_MAP_HEADER)>sizeof(memory_map_buffer)) {
|
||||
sh_log_error("Memory map overflow allocated buffer.",SH_LOG_SOURCE_PAGE);
|
||||
return SH_STATUS_MMAP_BUFFER_OVERFLOW;
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
void sh_page_dump_memory_map() {
|
||||
sh_page_MEMORY_MAP_HEADER *memory_map_header=(sh_page_MEMORY_MAP_HEADER *)memory_map_buffer;
|
||||
sh_log_send_string("Memory map dump:\n");
|
||||
sh_log_send_string("Header:\n");
|
||||
for (sh_uint64 i=0;i<sizeof(sh_page_MEMORY_MAP_HEADER);++i) {
|
||||
sh_log_send_uintn((sh_uint64)memory_map_buffer[i]);
|
||||
sh_log_send_string(" ");
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
for (sh_uint64 i=0;i<memory_map_header->entry_count;++i) {
|
||||
sh_log_send_string("Entry number ");
|
||||
sh_log_send_uintn(i);
|
||||
sh_log_send_string(" : ");
|
||||
for (sh_uint64 y=0;y<sizeof(sh_page_MEMORY_MAP_ENTRY);++y) {
|
||||
sh_log_send_uintn((sh_uint64)memory_map_buffer[sizeof(sh_page_MEMORY_MAP_HEADER)+i*sizeof(sh_page_MEMORY_MAP_ENTRY)+y]);
|
||||
sh_log_send_string(" ");
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
}
|
||||
}
|
||||
sh_uint64 sh_page_get_physical_memory_amount_pages() {
|
||||
return physical_memory_pages_count;
|
||||
}
|
||||
sh_uint64 sh_page_get_physical_memory_amount_bytes() {
|
||||
return physical_memory_bytes_count;
|
||||
}
|
||||
sh_uint64 sh_page_get_one_page_na() {
|
||||
sh_uint64 page_count=physical_memory_pages_count;
|
||||
sh_uint64 bitmap_word_count=(page_count+63)/64;
|
||||
for (sh_uint64 word=0;word<bitmap_word_count;word++) {
|
||||
sh_uint64 value=physical_bitmap[word];
|
||||
if (value==0xFFFFFFFFFFFFFFFFULL) {
|
||||
continue;
|
||||
}
|
||||
for (sh_uint64 bit=0;bit<64;bit++) {
|
||||
sh_uint64 page_index=(word*64)+bit;
|
||||
if (page_index>=page_count) {
|
||||
return 0;
|
||||
}
|
||||
if ((value & (1ULL<<bit))==0) {
|
||||
return page_index*SH_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
SH_STATUS sh_page_set_pages_range_bitmap(sh_uint8 *bitmap,sh_uint64 page_count_in_bitmap,sh_uint64 page_index,sh_uint64 page_count,sh_bool state) {
|
||||
if (bitmap==SH_NULLPTR) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (page_index+page_count>page_count_in_bitmap) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
for (sh_uint64 i=0;i<page_count;++i) {
|
||||
sh_uint64 page=page_index+i;
|
||||
sh_uint64 byte_index=page/8;
|
||||
sh_uint8 bit_index=page%8;
|
||||
if (state) {
|
||||
bitmap[byte_index]|=(sh_uint8)(1u<<bit_index);
|
||||
} else {
|
||||
bitmap[byte_index]&=(sh_uint8)~(1u<<bit_index);
|
||||
}
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_init_ptp(sh_page_PHYSICAL_ADRESS ptp_pa,sh_page_VIRTUAL_ADRESS ptp_va,sh_uint64 initial_fill_level,sh_page_PAGE_TABLE_POOL *page_table_pool) {
|
||||
page_table_pool->page_table_pa=ptp_pa;
|
||||
page_table_pool->page_table_va=ptp_va;
|
||||
page_table_pool->ptp_pages_count=SH_PAGE_PTP_ALLOCATOR_PAGES_COUNT;
|
||||
page_table_pool->ptp_alloc_bitmap_uint64_count=SH_PAGE_PTP_ALLOCATOR_BITMAP_UINT64;
|
||||
SH_STATUS status=sh_mem_set_8((sh_uint8*)page_table_pool->ptp_alloc_bitmap,SH_FALSE,sizeof(page_table_pool->ptp_alloc_bitmap));
|
||||
if (sh_status_error(status)) {
|
||||
sh_log_error("Error: couldn't initialize page table pool bitmap.",SH_LOG_SOURCE_PAGE);
|
||||
return SH_STATUS_PT_POOL_NO_BITMAP_INIT;
|
||||
}
|
||||
if (initial_fill_level!=0) {
|
||||
status=sh_page_set_pages_range_bitmap((sh_uint8*)page_table_pool->ptp_alloc_bitmap,page_table_pool->ptp_pages_count,0,initial_fill_level,SH_TRUE);
|
||||
if (sh_status_error(status)) {
|
||||
sh_log_error("Error: couldn't initialize pages tables already alocated.",SH_LOG_SOURCE_PAGE);
|
||||
return SH_STATUS_PT_POOL_NO_PAGE_SET;
|
||||
}
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_dump_ptp_bitmap(sh_page_PAGE_TABLE_POOL *ptp) {
|
||||
for (sh_uint64 i=0;i<ptp->ptp_alloc_bitmap_uint64_count;++i) {
|
||||
sh_log_send_string(" 0x");
|
||||
sh_log_send_uintn_hex(ptp->ptp_alloc_bitmap[i]);
|
||||
}
|
||||
sh_log_send_string("\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
sh_page_PHYSICAL_ADRESS sh_page_ptp_alloc_one_page(sh_page_PAGE_TABLE_POOL *pt_pool) {
|
||||
if (pt_pool==SH_NULLPTR) {
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
sh_uint64 page_count=pt_pool->ptp_pages_count;
|
||||
sh_uint64 bitmap_word_count=(page_count+63)/64;
|
||||
for (sh_uint64 word=0;word<bitmap_word_count;word++) {
|
||||
sh_uint64 value=pt_pool->ptp_alloc_bitmap[word];
|
||||
if (value==0xFFFFFFFFFFFFFFFFULL) {
|
||||
continue;
|
||||
}
|
||||
for (sh_uint64 bit=0;bit<64;bit++) {
|
||||
sh_uint64 page_index=(word*64)+bit;
|
||||
if (page_index>=page_count) {
|
||||
return 0;
|
||||
}
|
||||
if ((value & (1ULL<<bit))==0) {
|
||||
pt_pool->ptp_alloc_bitmap[word]|=(1ULL<<bit);
|
||||
sh_page_PHYSICAL_ADRESS pa=pt_pool->page_table_pa+page_index*SH_PAGE_SIZE;
|
||||
return pa;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
SH_STATUS sh_page_map_one_page_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va,sh_page_PHYSICAL_ADRESS pa,sh_uint64 flags) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (va%SH_PAGE_SIZE!=0 || pa%SH_PAGE_SIZE!=0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 pml4_i=(va>>39) & 0x1FF;
|
||||
sh_uint64 pdpt_i=(va>>30) & 0x1FF;
|
||||
sh_uint64 pd_i=(va>>21) & 0x1FF;
|
||||
sh_uint64 pt_i=(va>>12) & 0x1FF;
|
||||
sh_uint64 *pdpt;
|
||||
sh_uint64 *pd;
|
||||
sh_uint64 *pt;
|
||||
sh_uint64 *pml4=(sh_uint64*)ptp->page_table_va;
|
||||
if (!(pml4[pml4_i] & SH_PAGE_PRESENT)) {
|
||||
sh_page_PHYSICAL_ADRESS pdpt_pa=sh_page_ptp_alloc_one_page(ptp);
|
||||
if (!pdpt_pa) return SH_STATUS_OUT_OF_MEMORY;
|
||||
pdpt=sh_page_ptp_pa_to_va(ptp,pdpt_pa);
|
||||
if (!pdpt) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
sh_mem_set_8((sh_uint8*)pdpt,0,SH_PAGE_SIZE);
|
||||
pml4[pml4_i]=pdpt_pa | SH_PAGE_TABLE_FLAGS | SH_PAGE_PRESENT;
|
||||
} else {
|
||||
pdpt=sh_page_ptp_pa_to_va(ptp,(pml4[pml4_i] & ~0xFFFULL));
|
||||
if (!pdpt) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pdpt[pdpt_i] & SH_PAGE_PRESENT)) {
|
||||
sh_page_PHYSICAL_ADRESS pd_pa=sh_page_ptp_alloc_one_page(ptp);
|
||||
if (!pd_pa) return SH_STATUS_OUT_OF_MEMORY;
|
||||
pd=sh_page_ptp_pa_to_va(ptp,pd_pa);
|
||||
if (!pd) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
sh_mem_set_8((sh_uint8*)pd,0,SH_PAGE_SIZE);
|
||||
pdpt[pdpt_i]=pd_pa | SH_PAGE_TABLE_FLAGS | SH_PAGE_PRESENT;
|
||||
} else {
|
||||
pd=sh_page_ptp_pa_to_va(ptp,(pdpt[pdpt_i] & ~0xFFFULL));
|
||||
if (!pd) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pd[pd_i] & SH_PAGE_PRESENT)) {
|
||||
sh_page_PHYSICAL_ADRESS pt_pa=sh_page_ptp_alloc_one_page(ptp);
|
||||
if (!pt_pa) return SH_STATUS_OUT_OF_MEMORY;
|
||||
pt=sh_page_ptp_pa_to_va(ptp,pt_pa);
|
||||
if (!pt) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
sh_mem_set_8((sh_uint8*)pt,0,SH_PAGE_SIZE);
|
||||
pd[pd_i]=pt_pa | SH_PAGE_TABLE_FLAGS | SH_PAGE_PRESENT;
|
||||
} else {
|
||||
pt=sh_page_ptp_pa_to_va(ptp,pd[pd_i] & ~0xFFFULL);
|
||||
if (!pt) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
pt[pt_i]=(pa & ~0xFFFULL) | flags | SH_PAGE_PRESENT;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_is_va_mapped_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 pml4_i=(va>>39) & 0x1FF;
|
||||
sh_uint64 pdpt_i=(va>>30) & 0x1FF;
|
||||
sh_uint64 pd_i=(va>>21) & 0x1FF;
|
||||
sh_uint64 pt_i=(va>>12) & 0x1FF;
|
||||
sh_uint64 *pdpt;
|
||||
sh_uint64 *pd;
|
||||
sh_uint64 *pt;
|
||||
sh_uint64 *pml4=(sh_uint64*)ptp->page_table_va;
|
||||
if (!(pml4[pml4_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pdpt=sh_page_ptp_pa_to_va(ptp,(pml4[pml4_i] & ~0xFFFULL));
|
||||
if (pdpt==0) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pdpt[pdpt_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pd=sh_page_ptp_pa_to_va(ptp,(pdpt[pdpt_i] & ~0xFFFULL));
|
||||
if (pd==0) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pd[pd_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pt=sh_page_ptp_pa_to_va(ptp,(pd[pd_i] & ~0xFFFULL));
|
||||
if (pt==0) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pt[pt_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_VA_NOT_MAPPED;
|
||||
} else {
|
||||
return SH_STATUS_VA_MAPPED;
|
||||
}
|
||||
}
|
||||
SH_STATUS sh_page_is_va_range_mapped_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va,sh_uint64 size_bytes) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (va%SH_PAGE_SIZE!=0 || size_bytes%SH_PAGE_SIZE!=0 || size_bytes==0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 counter=0;
|
||||
for (sh_uint64 i=0;i<size_bytes/SH_PAGE_SIZE;i++) {
|
||||
if (sh_page_is_va_mapped_ptp(ptp,va+i*SH_PAGE_SIZE)==SH_STATUS_VA_MAPPED) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
if (counter==0) return SH_STATUS_VA_NOT_MAPPED;
|
||||
if (counter==size_bytes/SH_PAGE_SIZE) return SH_STATUS_VA_FULLY_MAPPED;
|
||||
return SH_STATUS_VA_PARTIALLY_MAPPED;
|
||||
}
|
||||
SH_STATUS sh_page_search_available_va_range(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS range_base,sh_page_VIRTUAL_ADRESS range_size_bytes,sh_uint64 size_bytes,sh_page_VIRTUAL_ADRESS *adress_found) {
|
||||
if (ptp==SH_NULLPTR || adress_found==SH_NULLPTR) {
|
||||
sh_log_send_string("1\n");
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (size_bytes==0 || size_bytes%SH_PAGE_SIZE!=0) {
|
||||
sh_log_send_string("2\n");
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
};
|
||||
if (range_base%SH_PAGE_SIZE!=0 || range_size_bytes%4096!=0 || range_size_bytes==0) {
|
||||
sh_log_send_string("3\n");
|
||||
return SH_STATUS_INVALID_PARAMETER;
|
||||
};
|
||||
sh_uint64 pages_needed=size_bytes/SH_PAGE_SIZE;
|
||||
sh_page_VIRTUAL_ADRESS current_va=range_base;
|
||||
sh_uint64 contiguous=0;
|
||||
sh_page_VIRTUAL_ADRESS candidate_start=0;
|
||||
while (current_va<range_base+range_size_bytes) {
|
||||
SH_STATUS status=sh_page_is_va_mapped_ptp(ptp,current_va);
|
||||
if (status==SH_STATUS_VA_NOT_MAPPED) {
|
||||
if (contiguous==0) {
|
||||
candidate_start=current_va;
|
||||
}
|
||||
contiguous++;
|
||||
if (contiguous==pages_needed) {
|
||||
*adress_found=(sh_page_VIRTUAL_ADRESS)candidate_start;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (status==SH_STATUS_VA_MAPPED) {
|
||||
contiguous=0;
|
||||
} else {
|
||||
return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
current_va+=SH_PAGE_SIZE;
|
||||
}
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
SH_STATUS sh_page_map_contiguous_pages_range_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va,sh_page_PHYSICAL_ADRESS pa,sh_uint64 flags,sh_uint64 size_bytes) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (va%SH_PAGE_SIZE!=0 || pa%SH_PAGE_SIZE!=0 || size_bytes==0 || size_bytes%SH_PAGE_SIZE!=0) return SH_STATUS_INVALID_PARAMETER;
|
||||
if ((flags & SH_PAGE_PS)==SH_PAGE_PS) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 pages=size_bytes/SH_PAGE_SIZE;
|
||||
SH_STATUS status=sh_page_is_va_range_mapped_ptp(ptp,va,size_bytes);
|
||||
if (status==SH_STATUS_VA_PARTIALLY_MAPPED) return SH_STATUS_ERROR_VA_PARTIALLY_MAPPED;
|
||||
if (status==SH_STATUS_VA_FULLY_MAPPED) return SH_STATUS_ERROR_VA_FULLY_MAPPED;
|
||||
for (sh_uint64 i=0;i<pages;i++) {
|
||||
status=sh_page_map_one_page_ptp(ptp,va+i*SH_PAGE_SIZE,pa+i*SH_PAGE_SIZE,flags);
|
||||
if (status!=SH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_search_physical_contiguous_block_na(sh_uint64 pages_needed,sh_page_PHYSICAL_ADRESS *pa) {
|
||||
if (pages_needed==0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 page_count=sh_page_get_physical_memory_amount_pages();
|
||||
sh_uint64 contiguous=0;
|
||||
sh_uint64 candidate_start=0;
|
||||
for (sh_uint64 page_index=0;page_index<page_count;page_index++) {
|
||||
if (!sh_page_is_allocated(physical_bitmap,page_index)) {
|
||||
if (contiguous==0) candidate_start=page_index;
|
||||
contiguous++;
|
||||
if (contiguous==pages_needed) {
|
||||
*pa=candidate_start*SH_PAGE_SIZE;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
contiguous=0;
|
||||
}
|
||||
}
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
SH_STATUS sh_page_alloc_contiguous(sh_page_PAGE_TABLE_POOL *ptp,sh_uint64 size_bytes,sh_page_VIRTUAL_ADRESS *va) {
|
||||
if (ptp==SH_NULLPTR || va==SH_NULLPTR || size_bytes==0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 pages_needed=size_bytes/SH_PAGE_SIZE;
|
||||
if (size_bytes%SH_PAGE_SIZE!=0) pages_needed++;
|
||||
sh_page_VIRTUAL_ADRESS candidate_va=0;
|
||||
SH_STATUS status=sh_page_search_available_va_range(ptp,0x0,0x00007FFFFFFFF000,pages_needed*SH_PAGE_SIZE,&candidate_va);
|
||||
if (status==SH_STATUS_OUT_OF_MEMORY) {
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
} else if (status==SH_STATUS_INVALID_INTERNAL_PA) {
|
||||
return SH_STATUS_KERNEL_PANIC;
|
||||
} else if (status==SH_STATUS_INVALID_PARAMETER) {
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
} else if (sh_status_error(status)) {
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
sh_page_PHYSICAL_ADRESS candidate_pa=0;
|
||||
status=sh_page_search_physical_contiguous_block_na(pages_needed,&candidate_pa);
|
||||
if (status!=SH_STATUS_SUCCESS) {
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
status=sh_page_map_contiguous_pages_range_ptp(ptp,candidate_va,candidate_pa,SH_PAGE_PRESENT | SH_PAGE_NX | SH_PAGE_RW,pages_needed*SH_PAGE_SIZE);
|
||||
if (status!=SH_STATUS_SUCCESS) return status;
|
||||
sh_page_set_pages_range_bitmap(physical_bitmap,physical_memory_pages_count,(sh_uint64)candidate_pa/SH_PAGE_SIZE,pages_needed,SH_TRUE);
|
||||
*va=candidate_va;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_alloc_contiguous_extended(sh_page_PAGE_TABLE_POOL *ptp,sh_uint64 size_bytes,sh_page_VIRTUAL_ADRESS* va,DEFAULT sh_uint64 flags,DEFAULT sh_page_VIRTUAL_ADRESS va_range_start,DEFAULT sh_uint64 va_range_size_bytes) {
|
||||
if (ptp==SH_NULLPTR || va==SH_NULLPTR || size_bytes==0) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (flags==SH_DEFVALUE) flags=SH_PAGE_PRESENT | SH_PAGE_NX | SH_PAGE_RW;
|
||||
if (va_range_start==SH_DEFVALUE) va_range_start=0x0;
|
||||
if (va_range_size_bytes==SH_DEFVALUE) va_range_size_bytes=0x00007FFFFFFFF000;
|
||||
if (va_range_start%SH_PAGE_SIZE!=0 || va_range_size_bytes==0 || va_range_size_bytes%SH_PAGE_SIZE!=0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 pages_needed=size_bytes/SH_PAGE_SIZE;
|
||||
if (size_bytes%SH_PAGE_SIZE!=0) pages_needed++;
|
||||
sh_page_VIRTUAL_ADRESS candidate_va=0;
|
||||
SH_STATUS status=sh_page_search_available_va_range(ptp,va_range_start,va_range_size_bytes,pages_needed*SH_PAGE_SIZE,&candidate_va);
|
||||
if (status==SH_STATUS_OUT_OF_MEMORY) {
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
} else if (status==SH_STATUS_INVALID_INTERNAL_PA) {
|
||||
return SH_STATUS_KERNEL_PANIC;
|
||||
} else if (status==SH_STATUS_INVALID_PARAMETER) {
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
} else if (sh_status_error(status)) {
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
sh_page_PHYSICAL_ADRESS candidate_pa=0;
|
||||
status=sh_page_search_physical_contiguous_block_na(pages_needed,&candidate_pa);
|
||||
if (status!=SH_STATUS_SUCCESS) {
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
status=sh_page_map_contiguous_pages_range_ptp(ptp,candidate_va,candidate_pa,flags,pages_needed*SH_PAGE_SIZE);
|
||||
if (status!=SH_STATUS_SUCCESS) return status;
|
||||
sh_page_set_pages_range_bitmap(physical_bitmap,physical_memory_pages_count,(sh_uint64)candidate_pa/SH_PAGE_SIZE,pages_needed,SH_TRUE);
|
||||
*va=candidate_va;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_unmap_one_page_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (va%SH_PAGE_SIZE!=0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 pml4_i=(va>>39) & 0x1FF;
|
||||
sh_uint64 pdpt_i=(va>>30) & 0x1FF;
|
||||
sh_uint64 pd_i=(va>>21) & 0x1FF;
|
||||
sh_uint64 pt_i=(va>>12) & 0x1FF;
|
||||
sh_uint64 *pdpt;
|
||||
sh_uint64 *pd;
|
||||
sh_uint64 *pt;
|
||||
sh_uint64 *pml4=(sh_uint64*)ptp->page_table_va;
|
||||
if (!(pml4[pml4_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pdpt=sh_page_ptp_pa_to_va(ptp,(pml4[pml4_i] & ~0xFFFULL));
|
||||
if (!pdpt) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pdpt[pdpt_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pd=sh_page_ptp_pa_to_va(ptp,(pdpt[pdpt_i] & ~0xFFFULL));
|
||||
if (!pd) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pd[pd_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pt=sh_page_ptp_pa_to_va(ptp,pd[pd_i] & ~0xFFFULL);
|
||||
if (!pt) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
pt[pt_i]=0x0ULL;
|
||||
__asm__ volatile("invlpg (%0)" :: "r"(va) : "memory");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_unmap_contiguous_pages_range_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va,sh_uint64 size_bytes) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (va%SH_PAGE_SIZE!=0 || size_bytes==0 || size_bytes%SH_PAGE_SIZE!=0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 pages=size_bytes/SH_PAGE_SIZE;
|
||||
SH_STATUS status=sh_page_is_va_range_mapped_ptp(ptp,va,size_bytes);
|
||||
if (status==SH_STATUS_VA_PARTIALLY_MAPPED) return SH_STATUS_ERROR_VA_PARTIALLY_MAPPED;
|
||||
if (status==SH_STATUS_VA_NOT_MAPPED) return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
for (sh_uint64 i=0;i<pages;i++) {
|
||||
status=sh_page_unmap_one_page_ptp(ptp,va+i*SH_PAGE_SIZE);
|
||||
if (status!=SH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_ptp_va_to_pa(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va,sh_page_PHYSICAL_ADRESS *pa) {
|
||||
if (ptp==SH_NULLPTR || pa==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (va%SH_PAGE_SIZE!=0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_uint64 pml4_i=(va>>39) & 0x1FF;
|
||||
sh_uint64 pdpt_i=(va>>30) & 0x1FF;
|
||||
sh_uint64 pd_i=(va>>21) & 0x1FF;
|
||||
sh_uint64 pt_i=(va>>12) & 0x1FF;
|
||||
sh_uint64 *pdpt;
|
||||
sh_uint64 *pd;
|
||||
sh_uint64 *pt;
|
||||
sh_uint64 *pml4=(sh_uint64*)ptp->page_table_va;
|
||||
if (!(pml4[pml4_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pdpt=sh_page_ptp_pa_to_va(ptp,(pml4[pml4_i] & ~0xFFFULL));
|
||||
if (!pdpt) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pdpt[pdpt_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pd=sh_page_ptp_pa_to_va(ptp,(pdpt[pdpt_i] & ~0xFFFULL));
|
||||
if (!pd) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pd[pd_i] & SH_PAGE_PRESENT)) {
|
||||
return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
} else {
|
||||
pt=sh_page_ptp_pa_to_va(ptp,pd[pd_i] & ~0xFFFULL);
|
||||
if (!pt) return SH_STATUS_INVALID_INTERNAL_PA;
|
||||
}
|
||||
if (!(pt[pt_i] & SH_PAGE_PRESENT)) return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
*pa=pt[pt_i] & 0x000FFFFFFFFFF000;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_unalloc_one_page(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (va%SH_PAGE_SIZE!=0) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_page_PHYSICAL_ADRESS equivalent_pa;
|
||||
SH_STATUS status=sh_page_ptp_va_to_pa(ptp,va,&equivalent_pa);
|
||||
if (status!=SH_STATUS_SUCCESS) return status;
|
||||
status=sh_page_unmap_one_page_ptp(ptp,va); // If this call return SH_STATUS_ERROR_VA_NOT_MAPPED, there is a severe bug that should cause kernel panic because sh_page_ptp_va_to_pa should already have returned exact same error code.
|
||||
if (status!=SH_STATUS_SUCCESS) return status;
|
||||
status=sh_page_set_pages_range_bitmap(physical_bitmap,physical_memory_pages_count,(sh_uint64)(equivalent_pa/SH_PAGE_SIZE),1,SH_FALSE);
|
||||
if (status!=SH_STATUS_SUCCESS) return status;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_unalloc_contiguous(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADRESS va,sh_uint64 size_bytes) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
if (va%SH_PAGE_SIZE!=0 || size_bytes==0 || size_bytes%SH_PAGE_SIZE!=0) return SH_STATUS_INVALID_PARAMETER;
|
||||
SH_STATUS status=sh_page_is_va_range_mapped_ptp(ptp,va,size_bytes);
|
||||
if (status==SH_STATUS_VA_NOT_MAPPED) return SH_STATUS_ERROR_VA_NOT_MAPPED;
|
||||
if (status==SH_STATUS_VA_PARTIALLY_MAPPED) return SH_STATUS_ERROR_VA_PARTIALLY_MAPPED;
|
||||
sh_uint64 pages=size_bytes/SH_PAGE_SIZE;
|
||||
for (sh_uint64 i=0;i<pages;i++) {
|
||||
status=sh_page_unalloc_one_page(ptp,va+i*SH_PAGE_SIZE);
|
||||
if (status!=SH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_page_analyse_memory_map(sh_page_PAGE_TABLE_POOL *ptp) {
|
||||
if (ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
sh_page_MEMORY_MAP_HEADER *memory_map_header=(sh_page_MEMORY_MAP_HEADER *)memory_map_buffer;
|
||||
sh_page_MEMORY_MAP_ENTRY *memory_map_cursor=(sh_page_MEMORY_MAP_ENTRY *)(memory_map_buffer+sizeof(sh_page_MEMORY_MAP_HEADER));
|
||||
sh_bool verbose=sh_log_get_log_level()==0;
|
||||
sh_bool log=sh_log_get_log_level()<=1;
|
||||
sh_uint64 highest_usable_segment=0;
|
||||
sh_uint64 highest_usable_page=0;
|
||||
sh_uint64 biggest_segment_index=0;
|
||||
sh_uint64 biggest_segment_pages=0;
|
||||
if (log) {
|
||||
sh_log_llog("Max pages count is currently set to 0x",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn_hex(SH_PAGE_MAX_PAGES_COUNT);
|
||||
sh_log_send_string(" pages or 0x");
|
||||
sh_log_send_uintn_hex(SH_PAGE_MAX_PAGES_COUNT*4096);
|
||||
sh_log_send_string(" bytes.\n");
|
||||
}
|
||||
// first loop : identify memory amount and bigest free region
|
||||
for (sh_uint64 i=0;i<memory_map_header->entry_count;i++) {
|
||||
sh_uint64 start_page=memory_map_cursor[i].physical_start/4096;
|
||||
sh_uint64 end_page=start_page+memory_map_cursor[i].pages_count;
|
||||
if (memory_map_cursor[i].type==SH_PAGE_CONVENTIONAL_MEMORY && memory_map_cursor[i].pages_count>biggest_segment_pages) {
|
||||
biggest_segment_pages=memory_map_cursor[i].pages_count;
|
||||
biggest_segment_index=i;
|
||||
}
|
||||
if (verbose) {
|
||||
sh_log_ldebug("Found memory map segment #",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn(i);
|
||||
sh_log_send_string(": [0x");
|
||||
sh_log_send_uintn_hex(start_page*4096);
|
||||
sh_log_send_string(" - 0x");
|
||||
sh_log_send_uintn_hex(end_page*4096);
|
||||
sh_log_send_string("] Memory type: ");
|
||||
sh_log_send_uintn(memory_map_cursor[i].type);
|
||||
if (memory_map_cursor[i].type==SH_PAGE_CONVENTIONAL_MEMORY) {
|
||||
sh_log_send_string(" --> usable\n");
|
||||
} else {
|
||||
sh_log_send_string(" --> not usable\n");
|
||||
}
|
||||
if (!(end_page<=SH_PAGE_MAX_PAGES_COUNT)) {
|
||||
sh_log_lwarning("Memory map segment #",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn(i);
|
||||
sh_log_send_string(" isn't usable because it overflow over max page count. Enable debug log channel to see more.\n");
|
||||
}
|
||||
}
|
||||
if (memory_map_cursor[i].type==SH_PAGE_CONVENTIONAL_MEMORY && end_page<=SH_PAGE_MAX_PAGES_COUNT) {
|
||||
if (end_page>highest_usable_page) {
|
||||
highest_usable_segment=i;
|
||||
highest_usable_page=end_page;
|
||||
}
|
||||
}
|
||||
}
|
||||
physical_memory_pages_count=highest_usable_page;
|
||||
physical_memory_bytes_count=physical_memory_pages_count*SH_PAGE_SIZE;
|
||||
if (verbose) {
|
||||
sh_log_ldebug("Total memory was given by memory map segment #",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn(highest_usable_segment);
|
||||
sh_log_send_string("\n");
|
||||
sh_log_ldebug("Total memory (pages): 0x",SH_LOG_SOURCE_PAGE);
|
||||
sh_log_send_uintn_hex(physical_memory_pages_count);
|
||||
sh_log_send_string(". Total memory (bytes) : 0x");
|
||||
sh_log_send_uintn_hex(physical_memory_bytes_count);
|
||||
sh_log_send_string("\n");
|
||||
}
|
||||
if (biggest_segment_pages==0) {
|
||||
sh_log_error("No suitable conventional memory segment found.",SH_LOG_SOURCE_PAGE);
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
if (memory_map_cursor[biggest_segment_index].pages_count<(physical_memory_pages_count/8)) {
|
||||
sh_log_error("Memory is too low or too fragmented to allocate physical bitmap.",SH_LOG_SOURCE_PAGE);
|
||||
return SH_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
sh_page_PHYSICAL_ADRESS pa=memory_map_cursor[biggest_segment_index].physical_start;
|
||||
sh_page_VIRTUAL_ADRESS va;
|
||||
physical_bitmap_size_bytes=physical_memory_pages_count/8;
|
||||
if (physical_memory_pages_count%8!=0) physical_bitmap_size_bytes++;
|
||||
physical_bitmap_size_pages=physical_bitmap_size_bytes/SH_PAGE_SIZE;
|
||||
if (physical_bitmap_size_bytes%SH_PAGE_SIZE!=0) physical_bitmap_size_pages++;
|
||||
SH_STATUS status=sh_page_search_available_va_range(ptp,SH_PAGE_KERNEL_PERM_VA_BASE,(SH_PAGE_KERNEL_PERM_VA_END-SH_PAGE_KERNEL_PERM_VA_BASE+1-0x1000),physical_bitmap_size_pages*SH_PAGE_SIZE,&va);
|
||||
if (status!=SH_STATUS_SUCCESS) {
|
||||
sh_log_error("Memory is too low or too fragmented to allocate physical bitmap.",SH_LOG_SOURCE_PAGE);
|
||||
return status;
|
||||
}
|
||||
status=sh_page_map_contiguous_pages_range_ptp(ptp,va,pa,SH_PAGE_PRESENT | SH_PAGE_NX | SH_PAGE_RW,physical_bitmap_size_pages*SH_PAGE_SIZE);
|
||||
if (status==SH_STATUS_OUT_OF_MEMORY) {
|
||||
sh_log_error("Memory is too low or too fragmented to allocate physical bitmap.",SH_LOG_SOURCE_PAGE);
|
||||
return status;
|
||||
} else if (status!=SH_STATUS_SUCCESS) {
|
||||
sh_log_error("An unknow error happened during physical bitmap pages mapping. See error below",SH_LOG_SOURCE_PAGE);
|
||||
return status;
|
||||
}
|
||||
physical_bitmap=(sh_uint8*)va;
|
||||
status=sh_mem_set_8(physical_bitmap,0xFF,physical_bitmap_size_bytes);
|
||||
if (sh_status_error(status)) {
|
||||
sh_log_error("An unknow error happened during physical bitmap filling with 0xFF. See error below.",SH_LOG_SOURCE_PAGE);
|
||||
return status;
|
||||
}
|
||||
// second loop : actually set all free regions into physical bitmap
|
||||
for (sh_uint64 i=0;i<memory_map_header->entry_count;i++) {
|
||||
sh_uint64 start_page=memory_map_cursor[i].physical_start/4096;
|
||||
sh_uint64 end_page=start_page+memory_map_cursor[i].pages_count;
|
||||
if (end_page<=SH_PAGE_MAX_PAGES_COUNT) {
|
||||
if (memory_map_cursor[i].type==SH_PAGE_CONVENTIONAL_MEMORY) {
|
||||
SH_STATUS status=sh_page_set_pages_range_bitmap(physical_bitmap,physical_memory_pages_count,memory_map_cursor[i].physical_start/SH_PAGE_SIZE,memory_map_cursor[i].pages_count,SH_FALSE);
|
||||
if (sh_status_error(status)) {
|
||||
sh_log_error("Couldn't set this memory map segment to usable.",SH_LOG_SOURCE_PAGE);
|
||||
return SH_STATUS_PMAP_NO_PAGES_SET;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sh_page_set_pages_range_bitmap(physical_bitmap,physical_memory_pages_count,pa/SH_PAGE_SIZE,physical_bitmap_size_pages,SH_TRUE);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
sh_page_VIRTUAL_ADRESS sh_page_get_physical_bitmap_ptr() {
|
||||
return (sh_page_VIRTUAL_ADRESS)physical_bitmap;
|
||||
}
|
||||
static sh_uint64 popcount64(sh_uint64 x) {
|
||||
x=x-((x>>1) & 0x5555555555555555ULL);
|
||||
x=(x & 0x3333333333333333ULL)+((x>>2) & 0x3333333333333333ULL);
|
||||
x=(x+(x>>4)) & 0x0F0F0F0F0F0F0F0FULL;
|
||||
x=x+(x>>8);
|
||||
x=x+(x>>16);
|
||||
x=x+(x>>32);
|
||||
return x & 0x7F;
|
||||
}
|
||||
SH_STATUS sh_page_get_memory_stats(sh_page_MEM_STATS *mem_stats) {
|
||||
if (mem_stats==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER;
|
||||
mem_stats->memory_total_pages=physical_memory_pages_count;
|
||||
mem_stats->memory_total_bytes=physical_memory_bytes_count;
|
||||
sh_uint64 free_pages=0;
|
||||
sh_uint64 used_pages=0;
|
||||
sh_uint64 largest_free_block=0;
|
||||
sh_uint64 largest_used_block=0;
|
||||
sh_uint64 free_blocks_count=0;
|
||||
sh_uint64 used_blocks_count=0;
|
||||
sh_uint64 current_free_block=0;
|
||||
sh_uint64 current_used_block=0;
|
||||
sh_uint64 full_uint64_count=physical_memory_pages_count/64;
|
||||
sh_uint64 remaining_bits=physical_memory_pages_count%64;
|
||||
sh_uint64 *bitmap64=(sh_uint64*)physical_bitmap;
|
||||
for (sh_uint64 i=0;i<full_uint64_count;i++) {
|
||||
sh_uint64 val=bitmap64[i];
|
||||
unsigned ones=popcount64(val);
|
||||
unsigned zeros=64-ones;
|
||||
used_pages+=ones;
|
||||
free_pages+=zeros;
|
||||
for (int b=0;b<64;b++) {
|
||||
sh_bool bit_set=(val>>b) & 1;
|
||||
if (bit_set) {
|
||||
current_used_block++;
|
||||
if (current_free_block) {
|
||||
free_blocks_count++;
|
||||
if (current_free_block>largest_free_block) {
|
||||
largest_free_block=current_free_block;
|
||||
}
|
||||
current_free_block=0;
|
||||
}
|
||||
} else {
|
||||
current_free_block++;
|
||||
if (current_used_block) {
|
||||
used_blocks_count++;
|
||||
if (current_used_block>largest_used_block) {
|
||||
largest_used_block=current_used_block;
|
||||
}
|
||||
current_used_block=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remaining_bits) {
|
||||
sh_uint64 val=bitmap64[full_uint64_count] & ((1ULL<<remaining_bits)-1);
|
||||
unsigned ones=popcount64(val);
|
||||
unsigned zeros=remaining_bits-ones;
|
||||
used_pages+=ones;
|
||||
free_pages+=zeros;
|
||||
for (sh_uint64 b=0;b<remaining_bits;b++) {
|
||||
sh_bool bit_set=(val>>b) & 1;
|
||||
if (bit_set) {
|
||||
current_used_block++;
|
||||
if (current_free_block) {
|
||||
free_blocks_count++;
|
||||
if (current_free_block>largest_free_block) {
|
||||
largest_free_block=current_free_block;
|
||||
}
|
||||
current_free_block=0;
|
||||
}
|
||||
} else {
|
||||
current_free_block++;
|
||||
if (current_used_block) {
|
||||
used_blocks_count++;
|
||||
if (current_used_block>largest_used_block) {
|
||||
largest_used_block=current_used_block;
|
||||
}
|
||||
current_used_block=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current_free_block) {
|
||||
free_blocks_count++;
|
||||
if (current_free_block>largest_free_block) {
|
||||
largest_free_block=current_free_block;
|
||||
}
|
||||
}
|
||||
if (current_used_block) {
|
||||
used_blocks_count++;
|
||||
if (current_used_block>largest_used_block) {
|
||||
largest_used_block=current_used_block;
|
||||
}
|
||||
}
|
||||
mem_stats->free_pages=free_pages;
|
||||
mem_stats->used_pages=used_pages;
|
||||
mem_stats->free_ratio=(double)free_pages/(double)physical_memory_pages_count;
|
||||
mem_stats->used_ratio=(double)used_pages/(double)physical_memory_pages_count;
|
||||
mem_stats->largest_free_block=largest_free_block;
|
||||
mem_stats->largest_used_block=largest_used_block;
|
||||
mem_stats->free_blocks_count=free_blocks_count;
|
||||
mem_stats->used_blocks_count=used_blocks_count;
|
||||
mem_stats->physical_bitmap_size_bytes=(physical_memory_pages_count+7)/8;
|
||||
mem_stats->physical_bitmap_size_pages=(mem_stats->physical_bitmap_size_bytes+4095)/4096;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
726
page.c.ccomp
Normal file
726
page.c.ccomp
Normal file
@@ -0,0 +1,726 @@
|
||||
CCC@ sh_uint64SH_STATUS_INVALID_PARAMETERreturnSH_PAGE_SIZEsh_page_VIRTUAL_ADRESSphysical_memory_pages_countSH_STATUS_INVALID_INTERNAL_PASH_STATUS_SUCCESSsh_log_send_stringSH_STATUS_OUT_OF_MEMORYSH_LOG_SOURCE_PAGEstatussh_page_PAGE_TABLE_POOLsh_page_PHYSICAL_ADRESSSH_PAGE_PRESENT
|
||||
size_bytessh_page_ptp_pa_to_va SH_STATUSmemory_map_cursorSH_STATUS_ERROR_VA_NOT_MAPPEDcurrent_free_blockcurrent_used_blocksh_page_MEMORY_MAP_HEADERpages_neededphysical_bitmap_size_bytessh_page_set_pages_range_bitmap
|
||||
SH_NULLPTRmemory_map_buffermemory_map_headerSH_STATUS_VA_NOT_MAPPEDphysical_bitmapphysical_bitmap_size_pagessh_log_send_uintnsh_log_send_uintn_hexlargest_free_blocklargest_used_blockptp
|
||||
page_indexpage_table_pool mem_stats&sh_page_map_contiguous_pages_range_ptpphysical_memory_bytes_countsh_log_errorsh_uint8!sh_page_search_available_va_range
|
||||
page_countva_range_size_bytesSH_PAGE_MAX_PAGES_COUNTsh_page_is_va_range_mapped_ptp+sh_page_search_physical_contiguous_block_naSH_STATUS_VA_PARTIALLY_MAPPEDpage_table_pool_va_ptr
|
||||
contiguousfree_blocks_countused_blocks_countelseSH_PAGE_CONVENTIONAL_MEMORYcandidate_pacandidate_vaptp_alloc_bitmapsh_page_ptp_alloc_one_page
|
||||
sh_log_ldebugxFFFULLcandidate_start®../include/page.h"
|
||||
std–.h>
|
||||
__attribute__((section(".bss")))
|
||||
Ÿ ë Û[64*1024];
|
||||
Ÿ ë *Þ;
|
||||
__attribute__((section(".bss")))
|
||||
Ÿ À Å=0;
|
||||
__attribute__((section(".bss")))
|
||||
Ÿ À é=0;
|
||||
__attribute__((section(".bss")))
|
||||
Ÿ À Ø=0;
|
||||
__attribute__((section(".bss")))
|
||||
Ÿ À ß=0;
|
||||
Ÿ Ä ó=SH_PAGE_NULL_VA;
|
||||
Ñ sh_page_load_boot_ä_va(Ä pt_pool_va) {
|
||||
ó=pt_pool_va;
|
||||
ý("Page table pool VA: 0x",Ê);
|
||||
á((À)ó);
|
||||
È("\n");
|
||||
ë first_byte=*(ë*)(ó);
|
||||
sh_log_debug("If you can see this message, no fault happened.",Ê);
|
||||
 Ç;
|
||||
}
|
||||
Ä sh_page_get_boot_ä_va() {
|
||||
 ó;
|
||||
}
|
||||
Ñ sh_page_copy_memory_map() {
|
||||
 sh_mem_copy(Û,(ª*)SH_PAGE_MEMORY_MAP_VA,ž(Û));
|
||||
}
|
||||
Ñ sh_page_check_memory_map() {
|
||||
Ÿ ‡ ë memory_map_sig[8]={'S','h','e','M','m','a','p','B'};
|
||||
” (sh_mem_compare(memory_map_sig,Û,ž(memory_map_sig))==Ñ_MEM_NOT_EQUAL) {
|
||||
sh_log_critical("Memory map ‹esn't have signature on.",Ê);
|
||||
 Ñ_INVALID_SIGNATURE;
|
||||
}
|
||||
Ö *Ü=(Ö *)Û;
|
||||
ý("Memory map entry count: ",Ê);
|
||||
à((À)Ü->entry_count);
|
||||
È("\n");
|
||||
ý("Memory map entry size: ",Ê);
|
||||
à((À)Ü->entry_size);
|
||||
È("\n");
|
||||
ý("Memory map syntax version: ",Ê);
|
||||
à((À)Ü->mmap_syntax_version);
|
||||
È("\n");
|
||||
” (Ü->entry_count*Ü->entry_size+ž(Ö)>ž(Û)) {
|
||||
ê("Memory map overflow allocated buffer.",Ê);
|
||||
 Ñ_MMAP_BUFFER_OVERFLOW;
|
||||
}
|
||||
 Ç;
|
||||
}
|
||||
ª sh_page_dump_memory_map() {
|
||||
Ö *Ü=(Ö *)Û;
|
||||
È("Memory map dump:\n");
|
||||
È("Header:\n");
|
||||
’ (À i=0;i<ž(Ö);++i) {
|
||||
à((À)Û[i]);
|
||||
È(" ");
|
||||
}
|
||||
È("\n");
|
||||
’ (À i=0;i<Ü->entry_count;++i) {
|
||||
È("Entry number ");
|
||||
à(i);
|
||||
È(" : ");
|
||||
’ (À y=0;y<ž(sh_page_MEMORY_MAP_ENTRY);++y) {
|
||||
à((À)Û[ž(Ö)+i*ž(sh_page_MEMORY_MAP_ENTRY)+y]);
|
||||
È(" ");
|
||||
}
|
||||
È("\n");
|
||||
}
|
||||
}
|
||||
À sh_page_get_physical_memory_amount_pages() {
|
||||
 Å;
|
||||
}
|
||||
À sh_page_get_physical_memory_amount_bytes() {
|
||||
 é;
|
||||
}
|
||||
À sh_page_get_one_page_na() {
|
||||
À í=Å;
|
||||
À bitmap_word_count=(í+63)/64;
|
||||
’ (À word=0;word<bitmap_word_count;word++) {
|
||||
À value=Þ[word];
|
||||
” (value==0xFFFFFFFFFFFFFFFFULL) {
|
||||
‰;
|
||||
}
|
||||
’ (À bit=0;bit<64;bit++) {
|
||||
À å=(word*64)+bit;
|
||||
” (å>=í) {
|
||||
 0;
|
||||
}
|
||||
” ((value & (1ULL<<bit))==0) {
|
||||
 å*Ã;
|
||||
}
|
||||
}
|
||||
}
|
||||
 0;
|
||||
}
|
||||
Ñ Ù(ë *bitmap,À í_in_bitmap,À å,À í,sh_ƒ state) {
|
||||
” (bitmap==Ú) {
|
||||
 Á;
|
||||
}
|
||||
” (å+í>í_in_bitmap) {
|
||||
 Á;
|
||||
}
|
||||
’ (À i=0;i<í;++i) {
|
||||
À page=å+i;
|
||||
À byte_index=page/8;
|
||||
ë bit_index=page%8;
|
||||
” (state) {
|
||||
bitmap[byte_index]|=(ë)(1u<<bit_index);
|
||||
} ÷ {
|
||||
bitmap[byte_index]&=(ë)~(1u<<bit_index);
|
||||
}
|
||||
}
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_init_ä(Í ä_pa,Ä ä_va,À initial_fill_level,Ì *æ) {
|
||||
æ->page_table_pa=ä_pa;
|
||||
æ->page_table_va=ä_va;
|
||||
æ->ä_pages_count=SH_PAGE_PTP_ALLOCATOR_PAGES_COUNT;
|
||||
æ->û_u–64_count=SH_PAGE_PTP_ALLOCATOR_BITMAP_UINT64;
|
||||
Ñ Ë=sh_mem_set_8((ë*)æ->û,SH_FALSE,ž(æ->û));
|
||||
” (sh_Ë_error(Ë)) {
|
||||
ê("Error: couldn't initialize page table pool bitmap.",Ê);
|
||||
 Ñ_PT_POOL_NO_BITMAP_INIT;
|
||||
}
|
||||
” (initial_fill_level!=0) {
|
||||
Ë=Ù((ë*)æ->û,æ->ä_pages_count,0,initial_fill_level,SH_TRUE);
|
||||
” (sh_Ë_error(Ë)) {
|
||||
ê("Error: couldn't initialize pages tables already alocated.",Ê);
|
||||
 Ñ_PT_POOL_NO_PAGE_SET;
|
||||
}
|
||||
}
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_dump_ä_bitmap(Ì *ä) {
|
||||
’ (À i=0;i<ä->û_u–64_count;++i) {
|
||||
È(" 0x");
|
||||
á(ä->û[i]);
|
||||
}
|
||||
È("\n");
|
||||
 Ç;
|
||||
}
|
||||
Í ü(Ì *pt_pool) {
|
||||
” (pt_pool==Ú) {
|
||||
 Á;
|
||||
}
|
||||
À í=pt_pool->ä_pages_count;
|
||||
À bitmap_word_count=(í+63)/64;
|
||||
’ (À word=0;word<bitmap_word_count;word++) {
|
||||
À value=pt_pool->û[word];
|
||||
” (value==0xFFFFFFFFFFFFFFFFULL) {
|
||||
‰;
|
||||
}
|
||||
’ (À bit=0;bit<64;bit++) {
|
||||
À å=(word*64)+bit;
|
||||
” (å>=í) {
|
||||
 0;
|
||||
}
|
||||
” ((value & (1ULL<<bit))==0) {
|
||||
pt_pool->û[word]|=(1ULL<<bit);
|
||||
Í pa=pt_pool->page_table_pa+å*Ã;
|
||||
 pa;
|
||||
}
|
||||
}
|
||||
}
|
||||
 0;
|
||||
}
|
||||
Ñ sh_page_map_one_page_ä(Ì *ä,Ä va,Í pa,À flags) {
|
||||
” (ä==Ú) Â Á;
|
||||
” (va%Ã!=0 || pa%Ã!=0) Â Á;
|
||||
À pml4_i=(va>>39) & 0x1FF;
|
||||
À pdpt_i=(va>>30) & 0x1FF;
|
||||
À pd_i=(va>>21) & 0x1FF;
|
||||
À pt_i=(va>>12) & 0x1FF;
|
||||
À *pdpt;
|
||||
À *pd;
|
||||
À *pt;
|
||||
À *pml4=(À*)ä->page_table_va;
|
||||
” (!(pml4[pml4_i] & Î)) {
|
||||
Í pdpt_pa=ü(ä);
|
||||
” (!pdpt_pa) Â É;
|
||||
pdpt=Ð(ä,pdpt_pa);
|
||||
” (!pdpt) Â Æ;
|
||||
sh_mem_set_8((ë*)pdpt,0,Ã);
|
||||
pml4[pml4_i]=pdpt_pa | SH_PAGE_TABLE_FLAGS | Î;
|
||||
} ÷ {
|
||||
pdpt=Ð(ä,(pml4[pml4_i] & ~0þ));
|
||||
” (!pdpt) Â Æ;
|
||||
}
|
||||
” (!(pdpt[pdpt_i] & Î)) {
|
||||
Í pd_pa=ü(ä);
|
||||
” (!pd_pa) Â É;
|
||||
pd=Ð(ä,pd_pa);
|
||||
” (!pd) Â Æ;
|
||||
sh_mem_set_8((ë*)pd,0,Ã);
|
||||
pdpt[pdpt_i]=pd_pa | SH_PAGE_TABLE_FLAGS | Î;
|
||||
} ÷ {
|
||||
pd=Ð(ä,(pdpt[pdpt_i] & ~0þ));
|
||||
” (!pd) Â Æ;
|
||||
}
|
||||
” (!(pd[pd_i] & Î)) {
|
||||
Í pt_pa=ü(ä);
|
||||
” (!pt_pa) Â É;
|
||||
pt=Ð(ä,pt_pa);
|
||||
” (!pt) Â Æ;
|
||||
sh_mem_set_8((ë*)pt,0,Ã);
|
||||
pd[pd_i]=pt_pa | SH_PAGE_TABLE_FLAGS | Î;
|
||||
} ÷ {
|
||||
pt=Ð(ä,pd[pd_i] & ~0þ);
|
||||
” (!pt) Â Æ;
|
||||
}
|
||||
pt[pt_i]=(pa & ~0þ) | flags | Î;
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_is_va_mapped_ä(Ì *ä,Ä va) {
|
||||
” (ä==Ú) Â Á;
|
||||
À pml4_i=(va>>39) & 0x1FF;
|
||||
À pdpt_i=(va>>30) & 0x1FF;
|
||||
À pd_i=(va>>21) & 0x1FF;
|
||||
À pt_i=(va>>12) & 0x1FF;
|
||||
À *pdpt;
|
||||
À *pd;
|
||||
À *pt;
|
||||
À *pml4=(À*)ä->page_table_va;
|
||||
” (!(pml4[pml4_i] & Î)) {
|
||||
 Ý;
|
||||
} ÷ {
|
||||
pdpt=Ð(ä,(pml4[pml4_i] & ~0þ));
|
||||
” (pdpt==0) Â Æ;
|
||||
}
|
||||
” (!(pdpt[pdpt_i] & Î)) {
|
||||
 Ý;
|
||||
} ÷ {
|
||||
pd=Ð(ä,(pdpt[pdpt_i] & ~0þ));
|
||||
” (pd==0) Â Æ;
|
||||
}
|
||||
” (!(pd[pd_i] & Î)) {
|
||||
 Ý;
|
||||
} ÷ {
|
||||
pt=Ð(ä,(pd[pd_i] & ~0þ));
|
||||
” (pt==0) Â Æ;
|
||||
}
|
||||
” (!(pt[pt_i] & Î)) {
|
||||
 Ý;
|
||||
} ÷ {
|
||||
 Ñ_VA_MAPPED;
|
||||
}
|
||||
}
|
||||
Ñ ð(Ì *ä,Ä va,À Ï) {
|
||||
” (ä==Ú) Â Á;
|
||||
” (va%Ã!=0 || Ï%Ã!=0 || Ï==0) Â Á;
|
||||
À counter=0;
|
||||
’ (À i=0;i<Ï/Ã;i++) {
|
||||
” (sh_page_is_va_mapped_ä(ä,va+i*Ã)==Ñ_VA_MAPPED) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
” (counter==0) Â Ý;
|
||||
” (counter==Ï/Ã) Â Ñ_VA_FULLY_MAPPED;
|
||||
 ò;
|
||||
}
|
||||
Ñ ì(Ì *ä,Ä range_base,Ä range_Ï,À Ï,Ä *adress_found) {
|
||||
” (ä==Ú || adress_found==Ú) {
|
||||
È("1\n");
|
||||
 Á;
|
||||
}
|
||||
” (Ï==0 || Ï%Ã!=0) {
|
||||
È("2\n");
|
||||
 Á;
|
||||
};
|
||||
” (range_base%Ã!=0 || range_Ï%4096!=0 || range_Ï==0) {
|
||||
È("3\n");
|
||||
 Á;
|
||||
};
|
||||
À ×=Ï/Ã;
|
||||
Ä current_va=range_base;
|
||||
À ô=0;
|
||||
Ä ÿ=0;
|
||||
¬ (current_va<range_base+range_Ï) {
|
||||
Ñ Ë=sh_page_is_va_mapped_ä(ä,current_va);
|
||||
” (Ë==Ý) {
|
||||
” (ô==0) {
|
||||
ÿ=current_va;
|
||||
}
|
||||
ô++;
|
||||
” (ô==×) {
|
||||
*adress_found=(Ä)ÿ;
|
||||
 Ç;
|
||||
}
|
||||
} ÷ ” (Ë==Ñ_VA_MAPPED) {
|
||||
ô=0;
|
||||
} ÷ {
|
||||
 Æ;
|
||||
}
|
||||
current_va+=Ã;
|
||||
}
|
||||
 É;
|
||||
}
|
||||
Ñ è(Ì *ä,Ä va,Í pa,À flags,À Ï) {
|
||||
” (ä==Ú) Â Á;
|
||||
” (va%Ã!=0 || pa%Ã!=0 || Ï==0 || Ï%Ã!=0) Â Á;
|
||||
” ((flags & SH_PAGE_PS)==SH_PAGE_PS) Â Á;
|
||||
À pages=Ï/Ã;
|
||||
Ñ Ë=ð(ä,va,Ï);
|
||||
” (Ë==ò) Â Ñ_ERROR_VA_PARTIALLY_MAPPED;
|
||||
” (Ë==Ñ_VA_FULLY_MAPPED) Â Ñ_ERROR_VA_FULLY_MAPPED;
|
||||
’ (À i=0;i<pages;i++) {
|
||||
Ë=sh_page_map_one_page_ä(ä,va+i*Ã,pa+i*Ã,flags);
|
||||
” (Ë!=Ç) {
|
||||
 Ë;
|
||||
}
|
||||
}
|
||||
 Ç;
|
||||
}
|
||||
Ñ ñ(À ×,Í *pa) {
|
||||
” (×==0) Â Á;
|
||||
À í=sh_page_get_physical_memory_amount_pages();
|
||||
À ô=0;
|
||||
À ÿ=0;
|
||||
’ (À å=0;å<í;å++) {
|
||||
” (!sh_page_is_allocated(Þ,å)) {
|
||||
” (ô==0) ÿ=å;
|
||||
ô++;
|
||||
” (ô==×) {
|
||||
*pa=ÿ*Ã;
|
||||
 Ç;
|
||||
}
|
||||
} ÷ {
|
||||
ô=0;
|
||||
}
|
||||
}
|
||||
 É;
|
||||
}
|
||||
Ñ sh_page_alloc_ô(Ì *ä,À Ï,Ä *va) {
|
||||
” (ä==Ú || va==Ú || Ï==0) Â Á;
|
||||
À ×=Ï/Ã;
|
||||
” (Ï%Ã!=0) ×++;
|
||||
Ä ú=0;
|
||||
Ñ Ë=ì(ä,0x0,0x00007FFFFFFFF000,×*Ã,&ú);
|
||||
” (Ë==É) {
|
||||
 É;
|
||||
} ÷ ” (Ë==Æ) {
|
||||
 Ñ_KERNEL_PANIC;
|
||||
} ÷ ” (Ë==Á) {
|
||||
 É;
|
||||
} ÷ ” (sh_Ë_error(Ë)) {
|
||||
 É;
|
||||
}
|
||||
Í ù=0;
|
||||
Ë=ñ(×,&ù);
|
||||
” (Ë!=Ç) {
|
||||
 É;
|
||||
}
|
||||
Ë=è(ä,ú,ù,Î | SH_PAGE_NX | SH_PAGE_RW,×*Ã);
|
||||
” (Ë!=Ç) Â Ë;
|
||||
Ù(Þ,Å,(À)ù/Ã,×,SH_TRUE);
|
||||
*va=ú;
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_alloc_ô_extended(Ì *ä,À Ï,Ä* va,DEFAULT À flags,DEFAULT Ä va_range_start,DEFAULT À î) {
|
||||
” (ä==Ú || va==Ú || Ï==0) Â Á;
|
||||
” (flags==SH_DEFVALUE) flags=Î | SH_PAGE_NX | SH_PAGE_RW;
|
||||
” (va_range_start==SH_DEFVALUE) va_range_start=0x0;
|
||||
” (î==SH_DEFVALUE) î=0x00007FFFFFFFF000;
|
||||
” (va_range_start%Ã!=0 || î==0 || î%Ã!=0) Â Á;
|
||||
À ×=Ï/Ã;
|
||||
” (Ï%Ã!=0) ×++;
|
||||
Ä ú=0;
|
||||
Ñ Ë=ì(ä,va_range_start,î,×*Ã,&ú);
|
||||
” (Ë==É) {
|
||||
 É;
|
||||
} ÷ ” (Ë==Æ) {
|
||||
 Ñ_KERNEL_PANIC;
|
||||
} ÷ ” (Ë==Á) {
|
||||
 É;
|
||||
} ÷ ” (sh_Ë_error(Ë)) {
|
||||
 É;
|
||||
}
|
||||
Í ù=0;
|
||||
Ë=ñ(×,&ù);
|
||||
” (Ë!=Ç) {
|
||||
 É;
|
||||
}
|
||||
Ë=è(ä,ú,ù,flags,×*Ã);
|
||||
” (Ë!=Ç) Â Ë;
|
||||
Ù(Þ,Å,(À)ù/Ã,×,SH_TRUE);
|
||||
*va=ú;
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_unmap_one_page_ä(Ì *ä,Ä va) {
|
||||
” (ä==Ú) Â Á;
|
||||
” (va%Ã!=0) Â Á;
|
||||
À pml4_i=(va>>39) & 0x1FF;
|
||||
À pdpt_i=(va>>30) & 0x1FF;
|
||||
À pd_i=(va>>21) & 0x1FF;
|
||||
À pt_i=(va>>12) & 0x1FF;
|
||||
À *pdpt;
|
||||
À *pd;
|
||||
À *pt;
|
||||
À *pml4=(À*)ä->page_table_va;
|
||||
” (!(pml4[pml4_i] & Î)) {
|
||||
 Ó;
|
||||
} ÷ {
|
||||
pdpt=Ð(ä,(pml4[pml4_i] & ~0þ));
|
||||
” (!pdpt) Â Æ;
|
||||
}
|
||||
” (!(pdpt[pdpt_i] & Î)) {
|
||||
 Ó;
|
||||
} ÷ {
|
||||
pd=Ð(ä,(pdpt[pdpt_i] & ~0þ));
|
||||
” (!pd) Â Æ;
|
||||
}
|
||||
” (!(pd[pd_i] & Î)) {
|
||||
 Ó;
|
||||
} ÷ {
|
||||
pt=Ð(ä,pd[pd_i] & ~0þ);
|
||||
” (!pt) Â Æ;
|
||||
}
|
||||
pt[pt_i]=0x0ULL;
|
||||
__asm__ «("invlpg (%0)" :: "r"(va) : "memory");
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_unmap_ô_pages_range_ä(Ì *ä,Ä va,À Ï) {
|
||||
” (ä==Ú) Â Á;
|
||||
” (va%Ã!=0 || Ï==0 || Ï%Ã!=0) Â Á;
|
||||
À pages=Ï/Ã;
|
||||
Ñ Ë=ð(ä,va,Ï);
|
||||
” (Ë==ò) Â Ñ_ERROR_VA_PARTIALLY_MAPPED;
|
||||
” (Ë==Ý) Â Ó;
|
||||
’ (À i=0;i<pages;i++) {
|
||||
Ë=sh_page_unmap_one_page_ä(ä,va+i*Ã);
|
||||
” (Ë!=Ç) {
|
||||
 Ë;
|
||||
}
|
||||
}
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_ä_va_to_pa(Ì *ä,Ä va,Í *pa) {
|
||||
” (ä==Ú || pa==Ú) Â Á;
|
||||
” (va%Ã!=0) Â Á;
|
||||
À pml4_i=(va>>39) & 0x1FF;
|
||||
À pdpt_i=(va>>30) & 0x1FF;
|
||||
À pd_i=(va>>21) & 0x1FF;
|
||||
À pt_i=(va>>12) & 0x1FF;
|
||||
À *pdpt;
|
||||
À *pd;
|
||||
À *pt;
|
||||
À *pml4=(À*)ä->page_table_va;
|
||||
” (!(pml4[pml4_i] & Î)) {
|
||||
 Ó;
|
||||
} ÷ {
|
||||
pdpt=Ð(ä,(pml4[pml4_i] & ~0þ));
|
||||
” (!pdpt) Â Æ;
|
||||
}
|
||||
” (!(pdpt[pdpt_i] & Î)) {
|
||||
 Ó;
|
||||
} ÷ {
|
||||
pd=Ð(ä,(pdpt[pdpt_i] & ~0þ));
|
||||
” (!pd) Â Æ;
|
||||
}
|
||||
” (!(pd[pd_i] & Î)) {
|
||||
 Ó;
|
||||
} ÷ {
|
||||
pt=Ð(ä,pd[pd_i] & ~0þ);
|
||||
” (!pt) Â Æ;
|
||||
}
|
||||
” (!(pt[pt_i] & Î)) Â Ó;
|
||||
*pa=pt[pt_i] & 0x000FFFFFFFFFF000;
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_unalloc_one_page(Ì *ä,Ä va) {
|
||||
” (ä==Ú) Â Á;
|
||||
” (va%Ã!=0) Â Á;
|
||||
Í equivalent_pa;
|
||||
Ñ Ë=sh_page_ä_va_to_pa(ä,va,&equivalent_pa);
|
||||
” (Ë!=Ç) Â Ë;
|
||||
Ë=sh_page_unmap_one_page_ä(ä,va); // If this call  Ó, there is a severe bug that should cause kernel panic because sh_page_ä_va_to_pa should already have Âed exact same error code.
|
||||
” (Ë!=Ç) Â Ë;
|
||||
Ë=Ù(Þ,Å,(À)(equivalent_pa/Ã),1,SH_FALSE);
|
||||
” (Ë!=Ç) Â Ë;
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_unalloc_ô(Ì *ä,Ä va,À Ï) {
|
||||
” (ä==Ú) Â Á;
|
||||
” (va%Ã!=0 || Ï==0 || Ï%Ã!=0) Â Á;
|
||||
Ñ Ë=ð(ä,va,Ï);
|
||||
” (Ë==Ý) Â Ó;
|
||||
” (Ë==ò) Â Ñ_ERROR_VA_PARTIALLY_MAPPED;
|
||||
À pages=Ï/Ã;
|
||||
’ (À i=0;i<pages;i++) {
|
||||
Ë=sh_page_unalloc_one_page(ä,va+i*Ã);
|
||||
” (Ë!=Ç) {
|
||||
 Ë;
|
||||
}
|
||||
}
|
||||
 Ç;
|
||||
}
|
||||
Ñ sh_page_analyse_memory_map(Ì *ä) {
|
||||
” (ä==Ú) Â Á;
|
||||
Ö *Ü=(Ö *)Û;
|
||||
sh_page_MEMORY_MAP_ENTRY *Ò=(sh_page_MEMORY_MAP_ENTRY *)(Û+ž(Ö));
|
||||
sh_ƒ verbose=sh_log_get_log_level()==0;
|
||||
sh_ƒ log=sh_log_get_log_level()<=1;
|
||||
À highest_usable_segment=0;
|
||||
À highest_usable_page=0;
|
||||
À biggest_segment_index=0;
|
||||
À biggest_segment_pages=0;
|
||||
” (log) {
|
||||
sh_log_llog("Max pages count is currently set to 0x",Ê);
|
||||
á(ï);
|
||||
È(" pages or 0x");
|
||||
á(ï*4096);
|
||||
È(" bytes.\n");
|
||||
}
|
||||
// first loop : ident”y memory amount and bigest free region
|
||||
’ (À i=0;i<Ü->entry_count;i++) {
|
||||
À start_page=Ò[i].physical_start/4096;
|
||||
À end_page=start_page+Ò[i].pages_count;
|
||||
” (Ò[i].type==ø && Ò[i].pages_count>biggest_segment_pages) {
|
||||
biggest_segment_pages=Ò[i].pages_count;
|
||||
biggest_segment_index=i;
|
||||
}
|
||||
” (verbose) {
|
||||
ý("Found memory map segment #",Ê);
|
||||
à(i);
|
||||
È(": [0x");
|
||||
á(start_page*4096);
|
||||
È(" - 0x");
|
||||
á(end_page*4096);
|
||||
È("] Memory type: ");
|
||||
à(Ò[i].type);
|
||||
” (Ò[i].type==ø) {
|
||||
È(" --> usable\n");
|
||||
} ÷ {
|
||||
È(" --> not usable\n");
|
||||
}
|
||||
” (!(end_page<=ï)) {
|
||||
sh_log_lwarning("Memory map segment #",Ê);
|
||||
à(i);
|
||||
È(" isn't usable because it overflow over max page count. Enable debug log channel to see more.\n");
|
||||
}
|
||||
}
|
||||
” (Ò[i].type==ø && end_page<=ï) {
|
||||
” (end_page>highest_usable_page) {
|
||||
highest_usable_segment=i;
|
||||
highest_usable_page=end_page;
|
||||
}
|
||||
}
|
||||
}
|
||||
Å=highest_usable_page;
|
||||
é=Å*Ã;
|
||||
” (verbose) {
|
||||
ý("Total memory was given by memory map segment #",Ê);
|
||||
à(highest_usable_segment);
|
||||
È("\n");
|
||||
ý("Total memory (pages): 0x",Ê);
|
||||
á(Å);
|
||||
È(". Total memory (bytes) : 0x");
|
||||
á(é);
|
||||
È("\n");
|
||||
}
|
||||
” (biggest_segment_pages==0) {
|
||||
ê("No suitable conventional memory segment found.",Ê);
|
||||
 É;
|
||||
}
|
||||
” (Ò[biggest_segment_index].pages_count<(Å/8)) {
|
||||
ê("Memory is too low or too fragmented to allocate physical bitmap.",Ê);
|
||||
 É;
|
||||
}
|
||||
Í pa=Ò[biggest_segment_index].physical_start;
|
||||
Ä va;
|
||||
Ø=Å/8;
|
||||
” (Å%8!=0) Ø++;
|
||||
ß=Ø/Ã;
|
||||
” (Ø%Ã!=0) ß++;
|
||||
Ñ Ë=ì(ä,SH_PAGE_KERNEL_PERM_VA_BASE,(SH_PAGE_KERNEL_PERM_VA_END-SH_PAGE_KERNEL_PERM_VA_BASE+1-0x1000),ß*Ã,&va);
|
||||
” (Ë!=Ç) {
|
||||
ê("Memory is too low or too fragmented to allocate physical bitmap.",Ê);
|
||||
 Ë;
|
||||
}
|
||||
Ë=è(ä,va,pa,Î | SH_PAGE_NX | SH_PAGE_RW,ß*Ã);
|
||||
” (Ë==É) {
|
||||
ê("Memory is too low or too fragmented to allocate physical bitmap.",Ê);
|
||||
 Ë;
|
||||
} ÷ ” (Ë!=Ç) {
|
||||
ê("An unknow error happened during physical bitmap pages mapping. See error below",Ê);
|
||||
 Ë;
|
||||
}
|
||||
Þ=(ë*)va;
|
||||
Ë=sh_mem_set_8(Þ,0xFF,Ø);
|
||||
” (sh_Ë_error(Ë)) {
|
||||
ê("An unknow error happened during physical bitmap filling with 0xFF. See error below.",Ê);
|
||||
 Ë;
|
||||
}
|
||||
// second loop : actually set all free regions –o physical bitmap
|
||||
’ (À i=0;i<Ü->entry_count;i++) {
|
||||
À start_page=Ò[i].physical_start/4096;
|
||||
À end_page=start_page+Ò[i].pages_count;
|
||||
” (end_page<=ï) {
|
||||
” (Ò[i].type==ø) {
|
||||
Ñ Ë=Ù(Þ,Å,Ò[i].physical_start/Ã,Ò[i].pages_count,SH_FALSE);
|
||||
” (sh_Ë_error(Ë)) {
|
||||
ê("Couldn't set this memory map segment to usable.",Ê);
|
||||
 Ñ_PMAP_NO_PAGES_SET;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ù(Þ,Å,pa/Ã,ß,SH_TRUE);
|
||||
 Ç;
|
||||
}
|
||||
Ä sh_page_get_Þ_ptr() {
|
||||
 (Ä)Þ;
|
||||
}
|
||||
Ÿ À popcount64(À x) {
|
||||
x=x-((x>>1) & 0x5555555555555555ULL);
|
||||
x=(x & 0x3333333333333333ULL)+((x>>2) & 0x3333333333333333ULL);
|
||||
x=(x+(x>>4)) & 0x0F0F0F0F0F0F0F0FULL;
|
||||
x=x+(x>>8);
|
||||
x=x+(x>>16);
|
||||
x=x+(x>>32);
|
||||
 x & 0x7F;
|
||||
}
|
||||
Ñ sh_page_get_memory_stats(sh_page_MEM_STATS *ç) {
|
||||
” (ç==Ú) Â Á;
|
||||
ç->memory_total_pages=Å;
|
||||
ç->memory_total_bytes=é;
|
||||
À free_pages=0;
|
||||
À used_pages=0;
|
||||
À â=0;
|
||||
À ã=0;
|
||||
À õ=0;
|
||||
À ö=0;
|
||||
À Ô=0;
|
||||
À Õ=0;
|
||||
À full_u–64_count=Å/64;
|
||||
À remaining_bits=Å%64;
|
||||
À *bitmap64=(À*)Þ;
|
||||
’ (À i=0;i<full_u–64_count;i++) {
|
||||
À val=bitmap64[i];
|
||||
© ones=popcount64(val);
|
||||
© zeros=64-ones;
|
||||
used_pages+=ones;
|
||||
free_pages+=zeros;
|
||||
’ (– b=0;b<64;b++) {
|
||||
sh_ƒ bit_set=(val>>b) & 1;
|
||||
” (bit_set) {
|
||||
Õ++;
|
||||
” (Ô) {
|
||||
õ++;
|
||||
” (Ô>â) {
|
||||
â=Ô;
|
||||
}
|
||||
Ô=0;
|
||||
}
|
||||
} ÷ {
|
||||
Ô++;
|
||||
” (Õ) {
|
||||
ö++;
|
||||
” (Õ>ã) {
|
||||
ã=Õ;
|
||||
}
|
||||
Õ=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
” (remaining_bits) {
|
||||
À val=bitmap64[full_u–64_count] & ((1ULL<<remaining_bits)-1);
|
||||
© ones=popcount64(val);
|
||||
© zeros=remaining_bits-ones;
|
||||
used_pages+=ones;
|
||||
free_pages+=zeros;
|
||||
’ (À b=0;b<remaining_bits;b++) {
|
||||
sh_ƒ bit_set=(val>>b) & 1;
|
||||
” (bit_set) {
|
||||
Õ++;
|
||||
” (Ô) {
|
||||
õ++;
|
||||
” (Ô>â) {
|
||||
â=Ô;
|
||||
}
|
||||
Ô=0;
|
||||
}
|
||||
} ÷ {
|
||||
Ô++;
|
||||
” (Õ) {
|
||||
ö++;
|
||||
” (Õ>ã) {
|
||||
ã=Õ;
|
||||
}
|
||||
Õ=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
” (Ô) {
|
||||
õ++;
|
||||
” (Ô>â) {
|
||||
â=Ô;
|
||||
}
|
||||
}
|
||||
” (Õ) {
|
||||
ö++;
|
||||
” (Õ>ã) {
|
||||
ã=Õ;
|
||||
}
|
||||
}
|
||||
ç->free_pages=free_pages;
|
||||
ç->used_pages=used_pages;
|
||||
ç->free_ratio=(Œ)free_pages/(Œ)Å;
|
||||
ç->used_ratio=(Œ)used_pages/(Œ)Å;
|
||||
ç->â=â;
|
||||
ç->ã=ã;
|
||||
ç->õ=õ;
|
||||
ç->ö=ö;
|
||||
ç->Ø=(Å+7)/8;
|
||||
ç->ß=(ç->Ø+4095)/4096;
|
||||
 Ç;
|
||||
Reference in New Issue
Block a user