Fix PMM for real HW + serial lock
This commit is contained in:
@@ -31,7 +31,7 @@
|
|||||||
#define KERNEL_IDT_ENTRIES 33
|
#define KERNEL_IDT_ENTRIES 33
|
||||||
|
|
||||||
/* paging */
|
/* paging */
|
||||||
#define PAGING_MAX_PHYS 0x100000000
|
#define PAGING_MAX_PHYS 0x200000000
|
||||||
|
|
||||||
/* heap */
|
/* heap */
|
||||||
#define KHEAP_SIZE (32*1024*1024)
|
#define KHEAP_SIZE (32*1024*1024)
|
||||||
|
|||||||
@@ -36,27 +36,6 @@ void read_rflags(uint64_t rflags)
|
|||||||
CHECK_BIT(rflags, 19) ? "VIF " : "", /*virtual interrupt flag*/
|
CHECK_BIT(rflags, 19) ? "VIF " : "", /*virtual interrupt flag*/
|
||||||
CHECK_BIT(rflags, 20) ? "VIP " : "", /*virtual interrupt pending*/
|
CHECK_BIT(rflags, 20) ? "VIP " : "", /*virtual interrupt pending*/
|
||||||
CHECK_BIT(rflags, 21) ? "ID " : ""); /*id flag*/
|
CHECK_BIT(rflags, 21) ? "ID " : ""); /*id flag*/
|
||||||
|
|
||||||
if (init.terminal) {
|
|
||||||
printf("\x1b[38;5;226m%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\x1b[38;5;231m\r\n",
|
|
||||||
CHECK_BIT(rflags, 0) ? "CF " : "",
|
|
||||||
CHECK_BIT(rflags, 2) ? "PF " : "",
|
|
||||||
CHECK_BIT(rflags, 4) ? "AF " : "",
|
|
||||||
CHECK_BIT(rflags, 6) ? "ZF " : "",
|
|
||||||
CHECK_BIT(rflags, 7) ? "SF " : "",
|
|
||||||
CHECK_BIT(rflags, 8) ? "TF " : "",
|
|
||||||
CHECK_BIT(rflags, 9) ? "IF " : "",
|
|
||||||
CHECK_BIT(rflags, 10) ? "DF " : "",
|
|
||||||
CHECK_BIT(rflags, 11) ? "OF " : "",
|
|
||||||
(CHECK_BIT(rflags, 12) && CHECK_BIT(rflags, 13)) ? "IOPL3 " : "IOPL0 ",
|
|
||||||
CHECK_BIT(rflags, 14) ? "NT " : "",
|
|
||||||
CHECK_BIT(rflags, 16) ? "RF " : "",
|
|
||||||
CHECK_BIT(rflags, 17) ? "VM " : "",
|
|
||||||
CHECK_BIT(rflags, 18) ? "AC " : "",
|
|
||||||
CHECK_BIT(rflags, 19) ? "VIF " : "",
|
|
||||||
CHECK_BIT(rflags, 20) ? "VIP " : "",
|
|
||||||
CHECK_BIT(rflags, 21) ? "ID " : "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
|||||||
|
|
||||||
case 33: // Keyboard Interrupt
|
case 33: // Keyboard Interrupt
|
||||||
keyboard_handler();
|
keyboard_handler();
|
||||||
//process_create("keyboard-initiated", kbdproc_main, NULL); // DEBUG
|
process_create("keyboard-initiated", kbdproc_main, NULL); // DEBUG
|
||||||
outb(0x20, 0x20);
|
outb(0x20, 0x20);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,13 @@
|
|||||||
|
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <io/serial/serial.h>
|
#include <io/serial/serial.h>
|
||||||
|
#include <sched/spinlock.h>
|
||||||
|
|
||||||
extern struct init_status init;
|
extern struct init_status init;
|
||||||
|
|
||||||
|
extern int panic_count;
|
||||||
|
struct spinlock_t serial_lock = {0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* outb - Writes a byte to a CPU port
|
* outb - Writes a byte to a CPU port
|
||||||
* @port: CPU port to write to
|
* @port: CPU port to write to
|
||||||
@@ -85,9 +89,15 @@ static int is_transmit_empty()
|
|||||||
*/
|
*/
|
||||||
void skputc(char c)
|
void skputc(char c)
|
||||||
{
|
{
|
||||||
// TODO: Spinlock here (serial access)
|
if (panic_count == 0) {
|
||||||
while (!is_transmit_empty()); // wait for free spot
|
spinlock_acquire(&serial_lock);
|
||||||
outb(PORT, c);
|
while (!is_transmit_empty()); // wait for free spot
|
||||||
|
outb(PORT, c);
|
||||||
|
spinlock_release(&serial_lock);
|
||||||
|
} else {
|
||||||
|
while (!is_transmit_empty());
|
||||||
|
outb(PORT, c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ extern struct flanterm_context* ft_ctx;
|
|||||||
extern struct boot_context boot_ctx;
|
extern struct boot_context boot_ctx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flanterm_free_wrapper - free() wrapper for Flanterm
|
* flanterm_free_wrapper - free() wrapper for Flanterm (DEPRECATED)
|
||||||
* @ptr: pointer to free
|
* @ptr: pointer to free
|
||||||
* @size: amount of bytes to free
|
* @size: amount of bytes to free
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -80,10 +80,11 @@ void idle_main(void* arg)
|
|||||||
|
|
||||||
void thing_main(void* arg)
|
void thing_main(void* arg)
|
||||||
{
|
{
|
||||||
printf("What's your name, pal? ");
|
/* printf("What's your name, pal? ");
|
||||||
char name[10];
|
char name[10];
|
||||||
keyboard_getline(name, 10);
|
keyboard_getline(name, 10);
|
||||||
printf("\r\n{%s} is such a nice name!\r\n", name);
|
printf("\r\n{%s} is such a nice name!\r\n", name); */
|
||||||
|
while (ticks < 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uintptr_t kheap_start;
|
extern uintptr_t kheap_start;
|
||||||
|
|||||||
@@ -173,9 +173,9 @@ void paging_init(struct boot_context boot_ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4GB
|
// 8GB
|
||||||
if (max_phys > PAGING_MAX_PHYS) {
|
if (max_phys > PAGING_MAX_PHYS) {
|
||||||
DEBUG("WARNING: max_phys capped to 4GB (%x) (from max_phys=%p)", PAGING_MAX_PHYS, max_phys);
|
DEBUG("WARNING: max_phys capped to PAGING_MAX_PHYS (from max_phys=%p)", max_phys);
|
||||||
max_phys = PAGING_MAX_PHYS;
|
max_phys = PAGING_MAX_PHYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ it will probably need to get some info from Limine,
|
|||||||
to see which pages are used by kernel/bootloader/mmio/fb etc.
|
to see which pages are used by kernel/bootloader/mmio/fb etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <mem/paging.h>
|
#include <mem/paging.h>
|
||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -24,10 +25,11 @@ First we'll have to discover the physical memory layout,
|
|||||||
and for that we can use a Limine request.
|
and for that we can use a Limine request.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
struct limine_memmap_entry* biggest_entry;
|
struct limine_memmap_entry* biggest_entry;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pmm_find_biggest_usable_region - Finding the biggest free memory region
|
* pmm_find_biggest_usable_region - Finding the biggest free memory region (DEPRECATED)
|
||||||
* @memmap: Limine memory map
|
* @memmap: Limine memory map
|
||||||
* @hhdm: Limine HHDM offset
|
* @hhdm: Limine HHDM offset
|
||||||
*
|
*
|
||||||
@@ -99,19 +101,32 @@ void pmm_free(uintptr_t addr)
|
|||||||
* This function marks the biggest memory region as
|
* This function marks the biggest memory region as
|
||||||
* free, so we can use it in pmm_alloc.
|
* free, so we can use it in pmm_alloc.
|
||||||
*/
|
*/
|
||||||
static void pmm_init_freelist()
|
static void pmm_init_freelist(struct limine_memmap_response* memmap)
|
||||||
{
|
{
|
||||||
// We simply call pmm_free() on each page that is marked USABLE
|
uint64_t total_pages = 0;
|
||||||
// in our big memory region.
|
|
||||||
uint64_t base = ALIGN_UP(biggest_entry->base, PAGE_SIZE);
|
|
||||||
uint64_t end = ALIGN_DOWN(biggest_entry->base + biggest_entry->length, PAGE_SIZE);
|
|
||||||
|
|
||||||
uint64_t page_count=0;
|
for (size_t i=0; i<memmap->entry_count; i++) {
|
||||||
for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) {
|
struct limine_memmap_entry* entry = memmap->entries[i];
|
||||||
pmm_free(addr);
|
|
||||||
page_count++;
|
if (entry->type == LIMINE_MEMMAP_USABLE) {
|
||||||
|
uint64_t base = ALIGN_UP(entry->base, PAGE_SIZE);
|
||||||
|
uint64_t end = ALIGN_DOWN(entry->base + entry->length, PAGE_SIZE);
|
||||||
|
|
||||||
|
if (end > PAGING_MAX_PHYS) {
|
||||||
|
end = PAGING_MAX_PHYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Region above PAGING_MAX_PHYS
|
||||||
|
if (base >= end) continue;
|
||||||
|
|
||||||
|
for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) {
|
||||||
|
pmm_free(addr);
|
||||||
|
total_pages++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DEBUG("%u frames in freelist, available for use (%u bytes)", page_count, page_count*PAGE_SIZE);
|
|
||||||
|
DEBUG("%u frames in freelist, %u bytes available (%u MB)", total_pages, total_pages*PAGE_SIZE, total_pages*PAGE_SIZE/1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -124,9 +139,9 @@ static void pmm_init_freelist()
|
|||||||
void pmm_init(struct boot_context boot_ctx)
|
void pmm_init(struct boot_context boot_ctx)
|
||||||
{
|
{
|
||||||
hhdm_off = boot_ctx.hhdm->offset;
|
hhdm_off = boot_ctx.hhdm->offset;
|
||||||
pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm);
|
//pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm);
|
||||||
|
|
||||||
// Now we have biggest USABLE region,
|
// Now we have biggest USABLE region,
|
||||||
// so to populate the free list we just iterate through it
|
// so to populate the free list we just iterate through it
|
||||||
pmm_init_freelist();
|
pmm_init_freelist(boot_ctx.mmap);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
current_process->context = context;
|
current_process->context = context;
|
||||||
//current_process->status = READY;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
struct process_t* prev_process = current_process;
|
struct process_t* prev_process = current_process;
|
||||||
@@ -65,6 +64,9 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
|
|||||||
return idle_proc->context;
|
return idle_proc->context;
|
||||||
} else {
|
} else {
|
||||||
current_process->status = RUNNING;
|
current_process->status = RUNNING;
|
||||||
|
if (prev_process != current_process) {
|
||||||
|
DEBUG("Changed from {pid=%u, name=%s} to {pid=%u, name=%s}", prev_process->pid, prev_process->name, current_process->pid, current_process->name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user