Files
ccc/log.c

410 lines
13 KiB
C

#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;
}