Espresso 0.0.0e
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
|
||||
#include <mm/paging.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/heap.h>
|
||||
|
||||
#define PAGE_DIRECTORY_ENTRIES 1024
|
||||
#define PAGE_TABLE_ENTRIES 1024
|
||||
@ -11,7 +12,7 @@
|
||||
typedef uint32_t page_directory_entry_t;
|
||||
typedef uint32_t page_table_entry_t;
|
||||
|
||||
static page_directory_entry_t* page_directory = (page_directory_entry_t*)0x9C000; /* Must be page-aligned */
|
||||
static page_directory_entry_t* page_directory = NULL; /* Will be allocated */
|
||||
static page_table_entry_t* page_tables[PAGE_DIRECTORY_ENTRIES];
|
||||
|
||||
extern void _enable_paging_asm(void);
|
||||
@ -19,37 +20,37 @@ extern void _enable_paging_asm(void);
|
||||
void paging_init(void)
|
||||
{
|
||||
/* Allocate and clear the page directory */
|
||||
page_directory = (uint32_t*)alloc_page();
|
||||
memset(page_directory, 0, 4096);
|
||||
page_directory = (page_directory_entry_t*)alloc_page();
|
||||
memset(page_directory, 0, PAGE_SIZE);
|
||||
|
||||
/* Allocate and set up the first identity-mapped page table (0–4MB) */
|
||||
uint32_t* first_table = (uint32_t*)alloc_page();
|
||||
memset(first_table, 0, 4096);
|
||||
for (uint32_t i = 0; i < 1024; i++)
|
||||
page_tables[0] = (page_table_entry_t*)alloc_page();
|
||||
memset(page_tables[0], 0, PAGE_SIZE);
|
||||
for (uint32_t i = 0; i < PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
first_table[i] = (i * 0x1000) | 3; /* Present | RW */
|
||||
page_tables[0][i] = (i * PAGE_SIZE) | 3; /* Present | RW */
|
||||
}
|
||||
page_directory[0] = ((uint32_t)first_table) | 3;
|
||||
page_directory[0] = ((uint32_t)page_tables[0]) | 3;
|
||||
|
||||
/* --- Map 4MB heap at 0xC0000000 --- */
|
||||
uint32_t* heap_table = (uint32_t*)alloc_page();
|
||||
memset(heap_table, 0, 4096);
|
||||
|
||||
for (uint32_t i = 0; i < 1024; i++) /* 256 pages = 1MB */
|
||||
/* Allocate and clear the heap page table */
|
||||
uint32_t heap_pd_index = HEAP_START >> 22; /* 0xC0000000 >> 22 = 768 */
|
||||
page_tables[heap_pd_index] = (page_table_entry_t*)alloc_page();
|
||||
memset(page_tables[heap_pd_index], 0, PAGE_SIZE);
|
||||
|
||||
/* Map 4MB heap pages */
|
||||
for (uint32_t i = 0; i < PAGE_TABLE_ENTRIES; i++) /* 1024 pages = 4MB */
|
||||
{
|
||||
uint32_t phys = (uint32_t)alloc_page();
|
||||
void* phys = alloc_page();
|
||||
if (phys == 0)
|
||||
{
|
||||
printf("Out of physical memory during heap mapping!\n");
|
||||
while (1);
|
||||
}
|
||||
heap_table[i] = phys | 3; /* Present | RW */
|
||||
page_tables[heap_pd_index][i] = ((uint32_t)phys & 0xFFFFF000) | 3; /* Present | RW */
|
||||
}
|
||||
page_directory[heap_pd_index] = ((uint32_t)page_tables[heap_pd_index]) | 3;
|
||||
|
||||
/* 0xC0000000 >> 22 == 768 */
|
||||
page_directory[768] = ((uint32_t)heap_table) | 3;
|
||||
|
||||
// Load page directory
|
||||
/* Load page directory */
|
||||
asm volatile ("mov %0, %%cr3" : : "r"(page_directory));
|
||||
|
||||
/* Enable paging */
|
||||
@ -67,16 +68,14 @@ void map_page(void* phys_addr, void* virt_addr)
|
||||
void* pt_phys = alloc_page();
|
||||
page_tables[pd_index] = (page_table_entry_t*)((uint32_t)pt_phys + 0xC0000000); /* Map it higher */
|
||||
|
||||
for (int i = 0; i < PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
page_tables[pd_index][i] = 0x00000002; /* Not present */
|
||||
}
|
||||
memset(page_tables[pd_index], 0, PAGE_SIZE);
|
||||
|
||||
page_directory[pd_index] = ((uint32_t)pt_phys) | 0x3; /* Present, R/W */
|
||||
}
|
||||
|
||||
page_table_entry_t* page_table = (page_table_entry_t*)((page_directory[pd_index] & 0xFFFFF000) | 0xC0000000);
|
||||
page_table_entry_t* page_table = (page_table_entry_t*)((page_directory[pd_index] & 0xFFFFF000) + 0xC0000000);
|
||||
page_table[pt_index] = ((uint32_t)phys_addr & 0xFFFFF000) | 0x3; /* Present, R/W */
|
||||
|
||||
asm volatile ("invlpg (%0)" :: "r" (virt_addr) : "memory");
|
||||
}
|
||||
|
||||
|
120
lib/printf.c
120
lib/printf.c
@ -34,7 +34,7 @@ void printf(const char* format, ...) {
|
||||
if (format[i] == '%' && format[i + 1] != '\0') {
|
||||
++i;
|
||||
|
||||
// Parse width (only supports zero-padding like %04x)
|
||||
// Check for width (like %016llx)
|
||||
int width = 0;
|
||||
if (format[i] == '0') {
|
||||
++i;
|
||||
@ -44,6 +44,13 @@ void printf(const char* format, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for 'll' prefix
|
||||
bool is_ll = false;
|
||||
if (format[i] == 'l' && format[i + 1] == 'l') {
|
||||
is_ll = true;
|
||||
i += 2;
|
||||
}
|
||||
|
||||
switch (format[i]) {
|
||||
case 's': {
|
||||
const char* str = va_arg(args, const char*);
|
||||
@ -67,13 +74,23 @@ void printf(const char* format, ...) {
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
uint32_t val = va_arg(args, uint32_t);
|
||||
print_hex(val, width, false);
|
||||
if (is_ll) {
|
||||
uint64_t val = va_arg(args, uint64_t);
|
||||
print_hex64(val, width ? width : 16, false);
|
||||
} else {
|
||||
uint32_t val = va_arg(args, uint32_t);
|
||||
print_hex(val, width ? width : 8, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'X': {
|
||||
uint32_t val = va_arg(args, uint32_t);
|
||||
print_hex(val, width, true);
|
||||
if (is_ll) {
|
||||
uint64_t val = va_arg(args, uint64_t);
|
||||
print_hex64(val, width ? width : 16, true);
|
||||
} else {
|
||||
uint32_t val = va_arg(args, uint32_t);
|
||||
print_hex(val, width ? width : 8, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'p': {
|
||||
@ -84,8 +101,8 @@ void printf(const char* format, ...) {
|
||||
}
|
||||
case 'f':
|
||||
case 'F': {
|
||||
double val = va_arg(args, double); // double is promoted from float
|
||||
print_double(val, 2); // 2 decimal places
|
||||
double val = va_arg(args, double);
|
||||
print_double(val, 2);
|
||||
break;
|
||||
}
|
||||
case '%': {
|
||||
@ -106,41 +123,6 @@ void printf(const char* format, ...) {
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void print_double(double value, int precision)
|
||||
{
|
||||
// Handle the integer part
|
||||
int32_t integer_part = (int32_t)value;
|
||||
double fractional_part = value - integer_part;
|
||||
|
||||
// Print the integer part
|
||||
print_int(integer_part);
|
||||
|
||||
// Print the decimal point
|
||||
terminal_putchar('.');
|
||||
|
||||
// Print the fractional part (scaled up)
|
||||
fractional_part *= 1;
|
||||
for (int i = 0; i < precision; i++) {
|
||||
fractional_part *= 10;
|
||||
}
|
||||
|
||||
int32_t frac_int = (int32_t)fractional_part;
|
||||
print_int(frac_int);
|
||||
}
|
||||
|
||||
void print_uint(uint32_t value) {
|
||||
char buffer[11]; // Enough for 32-bit unsigned int
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
buffer[i++] = '0' + (value % 10);
|
||||
value /= 10;
|
||||
} while (value > 0);
|
||||
|
||||
while (i--) {
|
||||
terminal_putchar(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void print_int(int32_t value) {
|
||||
char buffer[12]; // Enough for 32-bit signed int (-2147483648)
|
||||
@ -181,3 +163,57 @@ void print_hex(uint32_t value, int width, bool uppercase)
|
||||
terminal_putchar(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void print_double(double value, int precision)
|
||||
{
|
||||
// Handle the integer part
|
||||
int32_t integer_part = (int32_t)value;
|
||||
double fractional_part = value - integer_part;
|
||||
|
||||
// Print the integer part
|
||||
print_int(integer_part);
|
||||
|
||||
// Print the decimal point
|
||||
terminal_putchar('.');
|
||||
|
||||
// Print the fractional part (scaled up)
|
||||
fractional_part *= 1;
|
||||
for (int i = 0; i < precision; i++) {
|
||||
fractional_part *= 10;
|
||||
}
|
||||
|
||||
int32_t frac_int = (int32_t)fractional_part;
|
||||
print_int(frac_int);
|
||||
}
|
||||
|
||||
void print_uint(uint32_t value) {
|
||||
char buffer[11]; // Enough for 32-bit unsigned int
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
buffer[i++] = '0' + (value % 10);
|
||||
value /= 10;
|
||||
} while (value > 0);
|
||||
|
||||
while (i--) {
|
||||
terminal_putchar(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void print_hex64(uint64_t value, int width, bool uppercase) {
|
||||
char buffer[17] = {0};
|
||||
const char* digits = uppercase ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
buffer[i++] = digits[value % 16];
|
||||
value /= 16;
|
||||
} while (value > 0);
|
||||
|
||||
while (i < width)
|
||||
buffer[i++] = '0';
|
||||
|
||||
while (i--)
|
||||
terminal_putchar(buffer[i]);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user