From 0dbeb6af86010aa37b415f9bf94d2abed3fb277a Mon Sep 17 00:00:00 2001 From: lolo859 Date: Tue, 3 Feb 2026 17:15:04 +0100 Subject: [PATCH] a new version + a bunch of crap (temp) --- ccc.cpp | 3 + ccc.cpp.ccomp | 260 ++++++++++++++++++ hello.c | 5 + hello.c.ccomp | Bin 0 -> 51 bytes log.c | 409 ++++++++++++++++++++++++++++ log.c.ccomp | 412 ++++++++++++++++++++++++++++ page.c | 721 +++++++++++++++++++++++++++++++++++++++++++++++++ page.c.ccomp | 726 ++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 2536 insertions(+) create mode 100644 ccc.cpp.ccomp create mode 100644 hello.c create mode 100644 hello.c.ccomp create mode 100644 log.c create mode 100644 log.c.ccomp create mode 100644 page.c create mode 100644 page.c.ccomp diff --git a/ccc.cpp b/ccc.cpp index c8f8cbe..3de91d2 100644 --- a/ccc.cpp +++ b/ccc.cpp @@ -251,5 +251,8 @@ int main(int argc,char **argv) { } } } + ofstream out_file(filepath+".ccomp",ios::binary); + out_file.write(reinterpret_cast(output.data()),output.size()); + out_file.close(); return 0; } diff --git a/ccc.cpp.ccomp b/ccc.cpp.ccomp new file mode 100644 index 0000000..e4bd41a --- /dev/null +++ b/ccc.cpp.ccomp @@ -0,0 +1,260 @@ +CCC@ push_backunsignedoutput bytes_to_skip codepointchar leaderboardstringincludecodechildrensourcecurrsizein_comment_singlein_comment_multisregex_iteratorreturnelse root_nodeintnamefilepathtoken_idcontinuevectorconstsymbolfortop64nodebest_idistreambuf_iteratorfalse in_stringsize_tlengthout_filebest_lenscore symbol_regextokenscleancinsert words_begincountsx3F +clean_code +filesystemautocleancount words_endmatch namespacecoutboolfileendlbinarystructmapstrregexcstddef> +c> +ioeam> +> +feam> +> +> +> +iterator> +> +using std; + fs=; + <> ={ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "# \"", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" +}; + { + ; + ; +}; + { + <,*> ; + =-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 "<<; + -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++; + } { + u32_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++; + } + } + } + } + ofeam (+".ccomp",ios::); + .write(reerpret_cast<>(.data()),.()); + .close(); + 0; +} diff --git a/hello.c b/hello.c new file mode 100644 index 0000000..a9b074e --- /dev/null +++ b/hello.c @@ -0,0 +1,5 @@ +#include +int main() { + printf("hello"); + return 0; +} diff --git a/hello.c.ccomp b/hello.c.ccomp new file mode 100644 index 0000000000000000000000000000000000000000..dce2ab5b9d971bcf854e1b1857967bd5629f111f GIT binary patch literal 51 zcmZ>Ec4k;xT#}NRua{xRHBBKmF*8p?Q=ytmL7|{%TAGGZMruw@zLKUjP++!#fi+hx F7XX~m4$J@m literal 0 HcmV?d00001 diff --git a/log.c b/log.c new file mode 100644 index 0000000..54df5d6 --- /dev/null +++ b/log.c @@ -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_typeoutput_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; +} diff --git a/log.c.ccomp b/log.c.ccomp new file mode 100644 index 0000000..ebd5d4e --- /dev/null +++ b/log.c.ccomp @@ -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_SOURCE output_typemessage_pointersh_log_send_uintnsh_status_error mem_stats +SH_NULLPTRsh_log_send_byte sh_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_bytes SH_LOG_DEBUG SH_LOG_ERROR SH_LOG_FATAL integer_partSH_LOG_SERIAL_PORT_COM1 SH_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"); + } + ; +} diff --git a/page.c b/page.c new file mode 100644 index 0000000..48fe7ea --- /dev/null +++ b/page.c @@ -0,0 +1,721 @@ +#include "../include/page.h" +#include +__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;ientry_count;++i) { + sh_log_send_string("Entry number "); + sh_log_send_uintn(i); + sh_log_send_string(" : "); + for (sh_uint64 y=0;y=page_count) { + return 0; + } + if ((value & (1ULL<page_count_in_bitmap) { + return SH_STATUS_INVALID_PARAMETER; + } + for (sh_uint64 i=0;ipage_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;iptp_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;wordptp_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<ptp_alloc_bitmap[word]|=(1ULL<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>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>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;ientry_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;ientry_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>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<>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; +} diff --git a/page.c.ccomp b/page.c.ccomp new file mode 100644 index 0000000..f57d548 --- /dev/null +++ b/page.c.ccomp @@ -0,0 +1,726 @@ +CCC@ sh_uint64SH_STATUS_INVALID_PARAMETERreturn SH_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_HEADER pages_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_count sh_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_MEMORY candidate_pa candidate_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=) { + 0; + } + ((value & (1ULL<_in_bitmap) { + ; + } + ( i=0;i<;++i) { + page=+i; + byte_index=page/8; + bit_index=page%8; + (state) { + bitmap[byte_index]|=()(1u<page_table_pa=_pa; + ->page_table_va=_va; + ->_pages_count=SH_PAGE_PTP_ALLOCATOR_PAGES_COUNT; + ->_u64_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<->_u64_count;++i) { + (" 0x"); + (->[i]); + } + ("\n"); + ; +} + ( *pt_pool) { + (pt_pool==) { + ; + } + =pt_pool->_pages_count; + bitmap_word_count=(+63)/64; + ( word=0;word[word]; + (value==0xFFFFFFFFFFFFFFFFULL) { + ; + } + ( bit=0;bit<64;bit++) { + =(word*64)+bit; + (>=) { + 0; + } + ((value & (1ULL<[word]|=(1ULL<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>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>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;ientry_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_u64_count=/64; + remaining_bits=%64; + *bitmap64=(*); + ( i=0;i>b) & 1; + (bit_set) { + ++; + () { + ++; + (>) { + =; + } + =0; + } + } { + ++; + () { + ++; + (>) { + =; + } + =0; + } + } + } + } + (remaining_bits) { + val=bitmap64[full_u64_count] & ((1ULL<>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; + ; +}