real-hw-fix #16
4
Makefile
4
Makefile
@@ -12,13 +12,13 @@ CC_PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable
|
|||||||
LD := x86_64-elf-ld
|
LD := x86_64-elf-ld
|
||||||
|
|
||||||
$(ELFFILE): $(BUILDDIR) $(OBJFILES)
|
$(ELFFILE): $(BUILDDIR) $(OBJFILES)
|
||||||
nasm -f elf64 src/idt/idt.S -o $(BUILDDIR)/idt_stub.o
|
nasm -f elf64 src/arch/x86/idt.S -o $(BUILDDIR)/idt_stub.o
|
||||||
$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o
|
$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o
|
||||||
# Get the symbols for debugging
|
# Get the symbols for debugging
|
||||||
nm -n $(ELFFILE) | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
|
nm -n $(ELFFILE) | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
|
||||||
python3 symbols.py
|
python3 symbols.py
|
||||||
nasm -f elf64 symbols.S -o $(BUILDDIR)/symbols.o
|
nasm -f elf64 symbols.S -o $(BUILDDIR)/symbols.o
|
||||||
$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o
|
$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o $(BUILDDIR)/symbols.o
|
||||||
|
|
||||||
$(BUILDDIR):
|
$(BUILDDIR):
|
||||||
@mkdir -p $(BUILDDIR)
|
@mkdir -p $(BUILDDIR)
|
||||||
|
|||||||
@@ -10,4 +10,53 @@ void wrmsr(uint32_t msr, uint64_t value);
|
|||||||
bool x86_has_msr();
|
bool x86_has_msr();
|
||||||
void x86_arch_init();
|
void x86_arch_init();
|
||||||
|
|
||||||
|
/* Interrupt Descriptor Table */
|
||||||
|
|
||||||
|
void idt_init(void);
|
||||||
|
|
||||||
|
struct interrupt_descriptor {
|
||||||
|
uint16_t address_low;
|
||||||
|
uint16_t selector;
|
||||||
|
uint8_t ist;
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t address_mid;
|
||||||
|
uint32_t address_high;
|
||||||
|
uint32_t reserved;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct idtr {
|
||||||
|
uint16_t limit;
|
||||||
|
uint64_t base;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
// All general-purpose registers (except rsp) as stored on the stack,
|
||||||
|
// plus the values we pushed (vector number, error code) and the iret frame
|
||||||
|
// In reverse order because the stack grows downwards.
|
||||||
|
struct cpu_status_t {
|
||||||
|
uint64_t r15;
|
||||||
|
uint64_t r14;
|
||||||
|
uint64_t r13;
|
||||||
|
uint64_t r12;
|
||||||
|
uint64_t r11;
|
||||||
|
uint64_t r10;
|
||||||
|
uint64_t r9;
|
||||||
|
uint64_t r8;
|
||||||
|
uint64_t rbp;
|
||||||
|
uint64_t rdi;
|
||||||
|
uint64_t rsi;
|
||||||
|
uint64_t rdx;
|
||||||
|
uint64_t rcx;
|
||||||
|
uint64_t rbx;
|
||||||
|
uint64_t rax;
|
||||||
|
|
||||||
|
uint64_t vector_number;
|
||||||
|
uint64_t error_code;
|
||||||
|
|
||||||
|
uint64_t iret_rip;
|
||||||
|
uint64_t iret_cs;
|
||||||
|
uint64_t iret_flags;
|
||||||
|
uint64_t iret_rsp;
|
||||||
|
uint64_t iret_ss;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* @author xamidev <xamidev@riseup.net>
|
|
||||||
* @brief Interrupt Descriptor Table setup and dispatching
|
|
||||||
* @license GPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IDT_H
|
|
||||||
#define IDT_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void idt_init(void);
|
|
||||||
|
|
||||||
struct interrupt_descriptor {
|
|
||||||
uint16_t address_low;
|
|
||||||
uint16_t selector;
|
|
||||||
uint8_t ist;
|
|
||||||
uint8_t flags;
|
|
||||||
uint16_t address_mid;
|
|
||||||
uint32_t address_high;
|
|
||||||
uint32_t reserved;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct idtr {
|
|
||||||
uint16_t limit;
|
|
||||||
uint64_t base;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
// All general-purpose registers (except rsp) as stored on the stack,
|
|
||||||
// plus the values we pushed (vector number, error code) and the iret frame
|
|
||||||
// In reverse order because the stack grows downwards.
|
|
||||||
struct cpu_status_t {
|
|
||||||
uint64_t r15;
|
|
||||||
uint64_t r14;
|
|
||||||
uint64_t r13;
|
|
||||||
uint64_t r12;
|
|
||||||
uint64_t r11;
|
|
||||||
uint64_t r10;
|
|
||||||
uint64_t r9;
|
|
||||||
uint64_t r8;
|
|
||||||
uint64_t rbp;
|
|
||||||
uint64_t rdi;
|
|
||||||
uint64_t rsi;
|
|
||||||
uint64_t rdx;
|
|
||||||
uint64_t rcx;
|
|
||||||
uint64_t rbx;
|
|
||||||
uint64_t rax;
|
|
||||||
|
|
||||||
uint64_t vector_number;
|
|
||||||
uint64_t error_code;
|
|
||||||
|
|
||||||
uint64_t iret_rip;
|
|
||||||
uint64_t iret_cs;
|
|
||||||
uint64_t iret_flags;
|
|
||||||
uint64_t iret_rsp;
|
|
||||||
uint64_t iret_ss;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
#define TERM_H
|
#define TERM_H
|
||||||
|
|
||||||
void kputs(const char* str);
|
void kputs(const char* str);
|
||||||
void _putchar(char character);
|
|
||||||
void term_init(void);
|
void term_init(void);
|
||||||
int printf(const char* fmt, ...);
|
int printf(const char* fmt, ...);
|
||||||
|
void internal_putc(int c, void *_);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ enum ErrorCodes {
|
|||||||
|
|
||||||
#include <io/serial/serial.h>
|
#include <io/serial/serial.h>
|
||||||
#include <io/term/term.h>
|
#include <io/term/term.h>
|
||||||
#include <idt/idt.h>
|
#include <arch/x86.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
extern volatile uint64_t ticks;
|
extern volatile uint64_t ticks;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* @license GPL-3.0-only
|
* @license GPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <idt/idt.h>
|
#include <arch/x86.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <io/serial/serial.h>
|
#include <io/serial/serial.h>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <idt/idt.h>
|
#include <arch/x86.h>
|
||||||
#include <io/serial/serial.h>
|
#include <io/serial/serial.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
|
||||||
|
|||||||
@@ -216,10 +216,10 @@ void keyboard_handler()
|
|||||||
|
|
||||||
if (c) {
|
if (c) {
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
_putchar('\r');
|
internal_putc('\r', NULL);
|
||||||
}
|
}
|
||||||
// Should probably have a keyboard buffer here... instead of this
|
|
||||||
_putchar(c);
|
internal_putc(c, NULL);
|
||||||
keyboard_putchar(c);
|
keyboard_putchar(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,19 +30,10 @@ extern struct flanterm_context* ft_ctx;
|
|||||||
extern struct init_status init;
|
extern struct init_status init;
|
||||||
|
|
||||||
struct spinlock_t term_lock = {0};
|
struct spinlock_t term_lock = {0};
|
||||||
|
struct spinlock_t printf_lock = {0};
|
||||||
|
|
||||||
extern int panic_count;
|
extern int panic_count;
|
||||||
|
|
||||||
/*
|
|
||||||
* _putchar - Writes a character to terminal (DEPRECATED)
|
|
||||||
* @character: character to write
|
|
||||||
*/
|
|
||||||
void _putchar(char character)
|
|
||||||
{
|
|
||||||
// TODO: Spinlock here (terminal access)
|
|
||||||
flanterm_write(ft_ctx, &character, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* internal_putc - Internal putchar function
|
* internal_putc - Internal putchar function
|
||||||
* @c: char to print
|
* @c: char to print
|
||||||
@@ -83,14 +74,26 @@ void internal_putc(int c, void *_)
|
|||||||
*
|
*
|
||||||
* Return:
|
* Return:
|
||||||
* <ret> - number of characters sent to the callback
|
* <ret> - number of characters sent to the callback
|
||||||
|
* %-1 - error
|
||||||
*/
|
*/
|
||||||
int printf(const char* fmt, ...)
|
int printf(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
|
if (panic_count == 0) {
|
||||||
|
spinlock_acquire(&printf_lock);
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
spinlock_release(&printf_lock);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
|
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -103,30 +106,14 @@ void kputs(const char* str)
|
|||||||
{
|
{
|
||||||
size_t i=0;
|
size_t i=0;
|
||||||
while (str[i] != 0) {
|
while (str[i] != 0) {
|
||||||
_putchar(str[i]);
|
internal_putc(str[i], NULL);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
_putchar('\r');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern struct flanterm_context* ft_ctx;
|
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 (DEPRECATED)
|
|
||||||
* @ptr: pointer to free
|
|
||||||
* @size: amount of bytes to free
|
|
||||||
*
|
|
||||||
* This function exists solely because the Flanterm initialization
|
|
||||||
* function only accepts a free() function with a size parameter,
|
|
||||||
* and the default one doesn't have it.
|
|
||||||
*/
|
|
||||||
void flanterm_free_wrapper(void* ptr, size_t size)
|
|
||||||
{
|
|
||||||
(void)size;
|
|
||||||
kfree(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* term_init - Video output/terminal initialization
|
* term_init - Video output/terminal initialization
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <io/serial/serial.h>
|
#include <io/serial/serial.h>
|
||||||
#include <mem/gdt.h>
|
#include <mem/gdt.h>
|
||||||
#include <mem/utils.h>
|
#include <mem/utils.h>
|
||||||
#include <idt/idt.h>
|
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <time/timer.h>
|
#include <time/timer.h>
|
||||||
#include <io/kbd/ps2.h>
|
#include <io/kbd/ps2.h>
|
||||||
|
|||||||
@@ -25,43 +25,6 @@ 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;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pmm_find_biggest_usable_region - Finding the biggest free memory region (DEPRECATED)
|
|
||||||
* @memmap: Limine memory map
|
|
||||||
* @hhdm: Limine HHDM offset
|
|
||||||
*
|
|
||||||
* This function uses the memory map provided by the bootloader
|
|
||||||
* to find the single biggest free memory region we can use.
|
|
||||||
*/
|
|
||||||
static void pmm_find_biggest_usable_region(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm)
|
|
||||||
{
|
|
||||||
// Max length of a usable memory region
|
|
||||||
uint64_t length_max = 0;
|
|
||||||
uint64_t offset = hhdm->offset;
|
|
||||||
|
|
||||||
DEBUG("Usable Memory:");
|
|
||||||
for (size_t i=0; i<memmap->entry_count; i++) {
|
|
||||||
struct limine_memmap_entry* entry = memmap->entries[i];
|
|
||||||
|
|
||||||
if (entry->type == LIMINE_MEMMAP_USABLE) {
|
|
||||||
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", entry->base, entry->base+entry->length,
|
|
||||||
entry->base+offset, entry->base+entry->length+offset);
|
|
||||||
if (entry->length > length_max)
|
|
||||||
{
|
|
||||||
length_max = entry->length;
|
|
||||||
biggest_entry = entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG("Biggest usable memory region:");
|
|
||||||
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", biggest_entry->base, biggest_entry->base + biggest_entry->length,
|
|
||||||
biggest_entry->base+offset, biggest_entry->base+biggest_entry->length+offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset from Higher Half Direct Map
|
// Offset from Higher Half Direct Map
|
||||||
uint64_t hhdm_off;
|
uint64_t hhdm_off;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user