Use clang-format
This commit is contained in:
37
.editorconfig
Normal file
37
.editorconfig
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
# Default for all files
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
# C / header files
|
||||||
|
[*.{c,h}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
tab_width = 2
|
||||||
|
max_line_length = 80
|
||||||
|
|
||||||
|
# Assembly (if present; usually tab-sensitive)
|
||||||
|
[*.S]
|
||||||
|
indent_style = tab
|
||||||
|
tab_width = 8
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
# Makefiles (MUST use tabs)
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
tab_width = 8
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.mk]
|
||||||
|
indent_style = tab
|
||||||
|
tab_width = 8
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
# Markdown (avoid wrapping conflicts)
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
max_line_length = off
|
||||||
5
Makefile
5
Makefile
@@ -6,4 +6,7 @@ all_kernel:
|
|||||||
clean_kernel:
|
clean_kernel:
|
||||||
make -C kernel platform=$(platform) clean
|
make -C kernel platform=$(platform) clean
|
||||||
|
|
||||||
.PHONY: all_kernel clean_kernel
|
format_kernel:
|
||||||
|
make -C kernel platform=$(platform) format
|
||||||
|
|
||||||
|
.PHONY: all_kernel clean_kernel format_kernel
|
||||||
|
|||||||
57
kernel/.clang-format
Normal file
57
kernel/.clang-format
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
BasedOnStyle: LLVM
|
||||||
|
Language: C
|
||||||
|
|
||||||
|
# Indentation
|
||||||
|
IndentWidth: 2
|
||||||
|
TabWidth: 2
|
||||||
|
UseTab: Never
|
||||||
|
|
||||||
|
# Braces and blocks
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BraceWrapping:
|
||||||
|
AfterFunction: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeElse: false
|
||||||
|
|
||||||
|
# Control statements
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
|
||||||
|
# Line breaking
|
||||||
|
ColumnLimit: 80
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakStringLiterals: false
|
||||||
|
|
||||||
|
# Spacing
|
||||||
|
SpaceBeforeParens: Always
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
|
||||||
|
# Pointer alignment
|
||||||
|
PointerAlignment: Left
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
|
||||||
|
# Alignment
|
||||||
|
AlignAfterOpenBracket: DontAlign
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignOperands: false
|
||||||
|
|
||||||
|
# Includes
|
||||||
|
SortIncludes: true
|
||||||
|
|
||||||
|
# Comments
|
||||||
|
ReflowComments: false
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
@@ -23,4 +23,13 @@ build/kernel.elf: $(o)
|
|||||||
clean:
|
clean:
|
||||||
rm -f $(o) build/kernel.elf
|
rm -f $(o) build/kernel.elf
|
||||||
|
|
||||||
.PHONY: all clean
|
format:
|
||||||
|
clang-format -i $$(git ls-files '*.c' '*.h' \
|
||||||
|
':!limine/limine.h' \
|
||||||
|
':!c_headers/include/**' \
|
||||||
|
':!uACPI/source/**' \
|
||||||
|
':!uACPI/include/**' \
|
||||||
|
':!uACPI/tests/**' \
|
||||||
|
':!libk/printf*')
|
||||||
|
|
||||||
|
.PHONY: all clean format
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
#include <limine/limine.h>
|
|
||||||
#include <amd64/init.h>
|
#include <amd64/init.h>
|
||||||
#include <sys/debug.h>
|
#include <limine/limine.h>
|
||||||
#include <mm/pmm.h>
|
|
||||||
#include <mm/liballoc.h>
|
#include <mm/liballoc.h>
|
||||||
|
#include <mm/pmm.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
#include <uacpi/uacpi.h>
|
#include <uacpi/uacpi.h>
|
||||||
|
|
||||||
#define UACPI_MEMORY_BUFFER_MAX 4096
|
#define UACPI_MEMORY_BUFFER_MAX 4096
|
||||||
|
|
||||||
__attribute__((aligned(16))) static uint8_t uacpi_memory_buffer[UACPI_MEMORY_BUFFER_MAX];
|
__attribute__ ((
|
||||||
|
aligned (16))) static uint8_t uacpi_memory_buffer[UACPI_MEMORY_BUFFER_MAX];
|
||||||
|
|
||||||
void bootmain(void) {
|
void bootmain (void) {
|
||||||
amd64_init();
|
amd64_init ();
|
||||||
pmm_init();
|
pmm_init ();
|
||||||
|
|
||||||
uacpi_setup_early_table_access((void *)uacpi_memory_buffer, sizeof(uacpi_memory_buffer));
|
|
||||||
|
|
||||||
int *a = malloc(sizeof(int));
|
uacpi_setup_early_table_access (
|
||||||
|
(void*)uacpi_memory_buffer, sizeof (uacpi_memory_buffer));
|
||||||
|
|
||||||
|
int* a = malloc (sizeof (int));
|
||||||
*a = 6969;
|
*a = 6969;
|
||||||
DEBUG("a=%p, *a=%d\n", a, *a);
|
DEBUG ("a=%p, *a=%d\n", a, *a);
|
||||||
|
|
||||||
for (;;);
|
for (;;)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,47 @@
|
|||||||
#include <libk/std.h>
|
|
||||||
#include <libk/string.h>
|
|
||||||
#include <libk/printf.h>
|
|
||||||
#include <sys/debug.h>
|
|
||||||
#include <amd64/debug.h>
|
#include <amd64/debug.h>
|
||||||
#include <amd64/io.h>
|
#include <amd64/io.h>
|
||||||
|
#include <libk/printf.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
#include <libk/string.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
|
|
||||||
#define PORT_COM1 0x03F8
|
#define PORT_COM1 0x03F8
|
||||||
#define BUFFER_SIZE 1024
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
static bool amd64_debug_serial_tx_empty(void) {
|
static bool amd64_debug_serial_tx_empty (void) {
|
||||||
return (bool)(amd64_io_inb(PORT_COM1 + 5) & 0x20);
|
return (bool)(amd64_io_inb (PORT_COM1 + 5) & 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amd64_debug_serial_write(char x) {
|
static void amd64_debug_serial_write (char x) {
|
||||||
while (!amd64_debug_serial_tx_empty());
|
while (!amd64_debug_serial_tx_empty ())
|
||||||
amd64_io_outb(PORT_COM1, (uint8_t)x);
|
;
|
||||||
|
amd64_io_outb (PORT_COM1, (uint8_t)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void debugprintf(const char *fmt, ...) {
|
void debugprintf (const char* fmt, ...) {
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset (buffer, 0, sizeof (buffer));
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start (ap, fmt);
|
||||||
vsnprintf(buffer, sizeof(buffer), fmt, ap);
|
vsnprintf (buffer, sizeof (buffer), fmt, ap);
|
||||||
va_end(ap);
|
va_end (ap);
|
||||||
|
|
||||||
buffer[sizeof(buffer) - 1] = '\0';
|
buffer[sizeof (buffer) - 1] = '\0';
|
||||||
|
|
||||||
const char *p = buffer;
|
const char* p = buffer;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
amd64_debug_serial_write(*p);
|
amd64_debug_serial_write (*p);
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_debug_init(void) {
|
void amd64_debug_init (void) {
|
||||||
amd64_io_outb(PORT_COM1 + 1, 0x00);
|
amd64_io_outb (PORT_COM1 + 1, 0x00);
|
||||||
amd64_io_outb(PORT_COM1 + 3, 0x80);
|
amd64_io_outb (PORT_COM1 + 3, 0x80);
|
||||||
amd64_io_outb(PORT_COM1 + 0, 0x03);
|
amd64_io_outb (PORT_COM1 + 0, 0x03);
|
||||||
amd64_io_outb(PORT_COM1 + 1, 0x00);
|
amd64_io_outb (PORT_COM1 + 1, 0x00);
|
||||||
amd64_io_outb(PORT_COM1 + 3, 0x03);
|
amd64_io_outb (PORT_COM1 + 3, 0x03);
|
||||||
amd64_io_outb(PORT_COM1 + 2, 0xC7);
|
amd64_io_outb (PORT_COM1 + 2, 0xC7);
|
||||||
amd64_io_outb(PORT_COM1 + 4, 0x0B);
|
amd64_io_outb (PORT_COM1 + 4, 0x0B);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef _KERNEL_AMD64_DEBUG_H
|
#ifndef _KERNEL_AMD64_DEBUG_H
|
||||||
#define _KERNEL_AMD64_DEBUG_H
|
#define _KERNEL_AMD64_DEBUG_H
|
||||||
|
|
||||||
void amd64_debug_init(void);
|
void amd64_debug_init (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_DEBUG_H
|
#endif // _KERNEL_AMD64_DEBUG_H
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
|
#include <amd64/debug.h>
|
||||||
|
#include <amd64/init.h>
|
||||||
|
#include <amd64/intr.h>
|
||||||
|
#include <amd64/tss.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
#include <amd64/init.h>
|
|
||||||
#include <amd64/tss.h>
|
|
||||||
#include <amd64/debug.h>
|
|
||||||
#include <amd64/intr.h>
|
|
||||||
|
|
||||||
#define GDT_KCODE 0x08
|
#define GDT_KCODE 0x08
|
||||||
#define GDT_KDATA 0x10
|
#define GDT_KDATA 0x10
|
||||||
#define GDT_UCODE 0x18
|
#define GDT_UCODE 0x18
|
||||||
#define GDT_UDATA 0x20
|
#define GDT_UDATA 0x20
|
||||||
#define GDT_TSS 0x28
|
#define GDT_TSS 0x28
|
||||||
|
|
||||||
#define TSS 0x80
|
#define TSS 0x80
|
||||||
#define TSS_PRESENT 0x89
|
#define TSS_PRESENT 0x89
|
||||||
|
|
||||||
#define KSTACK_SIZE (8*1024)
|
#define KSTACK_SIZE (8 * 1024)
|
||||||
|
|
||||||
struct gdt_entry {
|
struct gdt_entry {
|
||||||
uint16_t limitlow;
|
uint16_t limitlow;
|
||||||
@@ -23,24 +23,26 @@ struct gdt_entry {
|
|||||||
uint8_t access;
|
uint8_t access;
|
||||||
uint8_t gran;
|
uint8_t gran;
|
||||||
uint8_t basehigh;
|
uint8_t basehigh;
|
||||||
} __attribute__((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct gdt_ptr {
|
struct gdt_ptr {
|
||||||
uint16_t limit;
|
uint16_t limit;
|
||||||
uint64_t base;
|
uint64_t base;
|
||||||
} __attribute__((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct gdt_extended {
|
struct gdt_extended {
|
||||||
struct gdt_entry old[5];
|
struct gdt_entry old[5];
|
||||||
struct gdt_entry tsslow;
|
struct gdt_entry tsslow;
|
||||||
struct gdt_entry tsshigh;
|
struct gdt_entry tsshigh;
|
||||||
} __attribute__((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
__attribute__((aligned(16))) static volatile uint8_t kernel_stack[KSTACK_SIZE];
|
/* clang-format off */
|
||||||
__attribute__((aligned(16))) static volatile struct gdt_extended gdt;
|
__attribute__ ((aligned (16))) static volatile uint8_t kernel_stack[KSTACK_SIZE];
|
||||||
|
__attribute__ ((aligned (16))) static volatile struct gdt_extended gdt;
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
static void amd64_gdt_set(volatile struct gdt_entry *ent, uint32_t base,
|
static void amd64_gdt_set (volatile struct gdt_entry* ent, uint32_t base,
|
||||||
uint32_t limit, uint8_t acc, uint8_t gran) {
|
uint32_t limit, uint8_t acc, uint8_t gran) {
|
||||||
ent->baselow = (base & 0xFFFF);
|
ent->baselow = (base & 0xFFFF);
|
||||||
ent->basemid = (base >> 16) & 0xFF;
|
ent->basemid = (base >> 16) & 0xFF;
|
||||||
ent->basehigh = (base >> 24) & 0xFF;
|
ent->basehigh = (base >> 24) & 0xFF;
|
||||||
@@ -49,25 +51,26 @@ static void amd64_gdt_set(volatile struct gdt_entry *ent, uint32_t base,
|
|||||||
ent->access = acc;
|
ent->access = acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amd64_gdt_init(void) {
|
static void amd64_gdt_init (void) {
|
||||||
volatile struct tss *tss = amd64_get_tss();
|
volatile struct tss* tss = amd64_get_tss ();
|
||||||
|
|
||||||
memset((void *)&gdt, 0, sizeof(gdt));
|
memset ((void*)&gdt, 0, sizeof (gdt));
|
||||||
memset((void *)kernel_stack, 0, sizeof(kernel_stack));
|
memset ((void*)kernel_stack, 0, sizeof (kernel_stack));
|
||||||
memset((void *)tss, 0, sizeof(*tss));
|
memset ((void*)tss, 0, sizeof (*tss));
|
||||||
|
|
||||||
tss->iopb_off = sizeof(*tss);
|
tss->iopb_off = sizeof (*tss);
|
||||||
tss->rsp0 = (uint64_t)((uintptr_t)kernel_stack + sizeof(kernel_stack));
|
tss->rsp0 = (uint64_t)((uintptr_t)kernel_stack + sizeof (kernel_stack));
|
||||||
|
|
||||||
uint64_t tssbase = (uint64_t)&tss;
|
uint64_t tssbase = (uint64_t)&tss;
|
||||||
uint64_t tsslimit = sizeof(*tss) - 1;
|
uint64_t tsslimit = sizeof (*tss) - 1;
|
||||||
|
|
||||||
amd64_gdt_set(&gdt.old[0], 0, 0, 0, 0);
|
amd64_gdt_set (&gdt.old[0], 0, 0, 0, 0);
|
||||||
amd64_gdt_set(&gdt.old[1], 0, 0xFFFFF, 0x9A, 0xA0);
|
amd64_gdt_set (&gdt.old[1], 0, 0xFFFFF, 0x9A, 0xA0);
|
||||||
amd64_gdt_set(&gdt.old[2], 0, 0xFFFFF, 0x92, 0xC0);
|
amd64_gdt_set (&gdt.old[2], 0, 0xFFFFF, 0x92, 0xC0);
|
||||||
amd64_gdt_set(&gdt.old[3], 0, 0xFFFFF, 0xFA, 0xA0);
|
amd64_gdt_set (&gdt.old[3], 0, 0xFFFFF, 0xFA, 0xA0);
|
||||||
amd64_gdt_set(&gdt.old[4], 0, 0xFFFFF, 0xF2, 0xC0);
|
amd64_gdt_set (&gdt.old[4], 0, 0xFFFFF, 0xF2, 0xC0);
|
||||||
amd64_gdt_set(&gdt.tsslow, (tssbase & 0xFFFFFFFF), tsslimit, TSS_PRESENT | TSS, 0);
|
amd64_gdt_set (
|
||||||
|
&gdt.tsslow, (tssbase & 0xFFFFFFFF), tsslimit, TSS_PRESENT | TSS, 0);
|
||||||
|
|
||||||
uint32_t tssbasehigh = (tssbase >> 32);
|
uint32_t tssbasehigh = (tssbase >> 32);
|
||||||
gdt.tsshigh.limitlow = (tssbasehigh & 0xFFFF);
|
gdt.tsshigh.limitlow = (tssbasehigh & 0xFFFF);
|
||||||
@@ -78,30 +81,28 @@ static void amd64_gdt_init(void) {
|
|||||||
gdt.tsshigh.gran = 0;
|
gdt.tsshigh.gran = 0;
|
||||||
|
|
||||||
struct gdt_ptr gdtr;
|
struct gdt_ptr gdtr;
|
||||||
gdtr.limit = sizeof(gdt) - 1;
|
gdtr.limit = sizeof (gdt) - 1;
|
||||||
gdtr.base = (uint64_t)&gdt;
|
gdtr.base = (uint64_t)&gdt;
|
||||||
__asm__ volatile("lgdt %0" :: "m"(gdtr) : "memory");
|
__asm__ volatile ("lgdt %0" ::"m"(gdtr) : "memory");
|
||||||
|
|
||||||
__asm__ volatile(
|
__asm__ volatile ("pushq %[kcode]\n"
|
||||||
"pushq %[kcode]\n"
|
"lea 1f(%%rip), %%rax\n"
|
||||||
"lea 1f(%%rip), %%rax\n"
|
"pushq %%rax\n"
|
||||||
"pushq %%rax\n"
|
"lretq\n"
|
||||||
"lretq\n"
|
"1:\n"
|
||||||
"1:\n"
|
"movw %[kdata], %%ax\n"
|
||||||
"movw %[kdata], %%ax\n"
|
"movw %%ax, %%ds\n"
|
||||||
"movw %%ax, %%ds\n"
|
"movw %%ax, %%es\n"
|
||||||
"movw %%ax, %%es\n"
|
"movw %%ax, %%ss\n"
|
||||||
"movw %%ax, %%ss\n"
|
:
|
||||||
:
|
: [kcode] "i"(GDT_KCODE), [kdata] "i"(GDT_KDATA)
|
||||||
: [kcode] "i"(GDT_KCODE), [kdata] "i"(GDT_KDATA)
|
: "rax", "memory");
|
||||||
: "rax", "memory"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm__ volatile("ltr %0" :: "r"((uint16_t)GDT_TSS));
|
__asm__ volatile ("ltr %0" ::"r"((uint16_t)GDT_TSS));
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_init(void) {
|
void amd64_init (void) {
|
||||||
amd64_gdt_init();
|
amd64_gdt_init ();
|
||||||
amd64_debug_init();
|
amd64_debug_init ();
|
||||||
amd64_intr_init();
|
amd64_intr_init ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef _KERNEL_AMD64_INIT_H
|
#ifndef _KERNEL_AMD64_INIT_H
|
||||||
#define _KERNEL_AMD64_INIT_H
|
#define _KERNEL_AMD64_INIT_H
|
||||||
|
|
||||||
void amd64_init(void);
|
void amd64_init (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_INIT_H
|
#endif // _KERNEL_AMD64_INIT_H
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
|
#include <amd64/intr.h>
|
||||||
|
#include <amd64/io.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
#include <amd64/intr.h>
|
|
||||||
#include <amd64/io.h>
|
|
||||||
|
|
||||||
/* 8259 PIC defs. */
|
/* 8259 PIC defs. */
|
||||||
#define PIC1 0x20
|
#define PIC1 0x20
|
||||||
#define PIC2 0xA0
|
#define PIC2 0xA0
|
||||||
#define PIC1_CMD PIC1
|
#define PIC1_CMD PIC1
|
||||||
#define PIC1_DATA (PIC1 + 1)
|
#define PIC1_DATA (PIC1 + 1)
|
||||||
#define PIC2_CMD PIC2
|
#define PIC2_CMD PIC2
|
||||||
#define PIC2_DATA (PIC2 + 1)
|
#define PIC2_DATA (PIC2 + 1)
|
||||||
#define PIC_EOI 0x20
|
#define PIC_EOI 0x20
|
||||||
|
|
||||||
#define ICW1_ICW4 0x01
|
#define ICW1_ICW4 0x01
|
||||||
#define ICW1_SINGLE 0x02
|
#define ICW1_SINGLE 0x02
|
||||||
#define ICW1_INTVL4 0x04
|
#define ICW1_INTVL4 0x04
|
||||||
#define ICW1_LEVEL 0x08
|
#define ICW1_LEVEL 0x08
|
||||||
#define ICW1_INIT 0x10
|
#define ICW1_INIT 0x10
|
||||||
|
|
||||||
#define ICW4_8086 0x01
|
#define ICW4_8086 0x01
|
||||||
#define ICW4_AUTO 0x02
|
#define ICW4_AUTO 0x02
|
||||||
#define ICW4_BUFSLAVE 0x08
|
#define ICW4_BUFSLAVE 0x08
|
||||||
#define ICW4_BUFMASER 0x0C
|
#define ICW4_BUFMASER 0x0C
|
||||||
#define ICW4_SFNM 0x10
|
#define ICW4_SFNM 0x10
|
||||||
|
|
||||||
#define CASCADE_IRQ 2
|
#define CASCADE_IRQ 2
|
||||||
|
|
||||||
/* IDT defs. */
|
/* IDT defs. */
|
||||||
|
|
||||||
@@ -39,42 +39,46 @@ struct idt_entry {
|
|||||||
uint16_t intrmid;
|
uint16_t intrmid;
|
||||||
uint32_t intrhigh;
|
uint32_t intrhigh;
|
||||||
uint32_t resv;
|
uint32_t resv;
|
||||||
} __attribute__((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct idt {
|
struct idt {
|
||||||
uint16_t limit;
|
uint16_t limit;
|
||||||
uint64_t base;
|
uint64_t base;
|
||||||
} __attribute__((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
__attribute__((aligned(16))) static volatile struct idt_entry idt_entries[IDT_ENTRIES_MAX];
|
__attribute__ ((aligned (
|
||||||
|
16))) static volatile struct idt_entry idt_entries[IDT_ENTRIES_MAX];
|
||||||
static volatile struct idt idt;
|
static volatile struct idt idt;
|
||||||
|
|
||||||
extern void amd64_spin(void);
|
extern void amd64_spin (void);
|
||||||
|
|
||||||
/* Remaps and disables old 8259 PIC, since we'll be using APIC. */
|
/* Remaps and disables old 8259 PIC, since we'll be using APIC. */
|
||||||
static void amd64_init_pic(void) {
|
static void amd64_init_pic (void) {
|
||||||
#define IO_OP(fn, ...) fn(__VA_ARGS__); amd64_io_wait()
|
#define IO_OP(fn, ...) \
|
||||||
|
fn (__VA_ARGS__); \
|
||||||
|
amd64_io_wait ()
|
||||||
|
|
||||||
IO_OP(amd64_io_outb, PIC1_CMD, (ICW1_INIT | ICW1_ICW4));
|
IO_OP (amd64_io_outb, PIC1_CMD, (ICW1_INIT | ICW1_ICW4));
|
||||||
IO_OP(amd64_io_outb, PIC2_CMD, (ICW1_INIT | ICW1_ICW4));
|
IO_OP (amd64_io_outb, PIC2_CMD, (ICW1_INIT | ICW1_ICW4));
|
||||||
|
|
||||||
IO_OP(amd64_io_outb, PIC1_DATA, 0x20);
|
IO_OP (amd64_io_outb, PIC1_DATA, 0x20);
|
||||||
IO_OP(amd64_io_outb, PIC2_DATA, 0x28);
|
IO_OP (amd64_io_outb, PIC2_DATA, 0x28);
|
||||||
|
|
||||||
IO_OP(amd64_io_outb, PIC1_DATA, (1 << CASCADE_IRQ));
|
IO_OP (amd64_io_outb, PIC1_DATA, (1 << CASCADE_IRQ));
|
||||||
IO_OP(amd64_io_outb, PIC2_DATA, 2);
|
IO_OP (amd64_io_outb, PIC2_DATA, 2);
|
||||||
|
|
||||||
IO_OP(amd64_io_outb, PIC1_DATA, ICW4_8086);
|
IO_OP (amd64_io_outb, PIC1_DATA, ICW4_8086);
|
||||||
IO_OP(amd64_io_outb, PIC2_DATA, ICW4_8086);
|
IO_OP (amd64_io_outb, PIC2_DATA, ICW4_8086);
|
||||||
|
|
||||||
/* Disable */
|
/* Disable */
|
||||||
IO_OP(amd64_io_outb, PIC1_DATA, 0xFF);
|
IO_OP (amd64_io_outb, PIC1_DATA, 0xFF);
|
||||||
IO_OP(amd64_io_outb, PIC2_DATA, 0xFF);
|
IO_OP (amd64_io_outb, PIC2_DATA, 0xFF);
|
||||||
|
|
||||||
#undef IO_OP
|
#undef IO_OP
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amd64_idt_set(volatile struct idt_entry *ent, uint64_t handler, uint8_t flags) {
|
static void amd64_idt_set (
|
||||||
|
volatile struct idt_entry* ent, uint64_t handler, uint8_t flags) {
|
||||||
ent->intrlow = (handler & 0xFFFF);
|
ent->intrlow = (handler & 0xFFFF);
|
||||||
ent->kernel_cs = 0x08; // GDT_KCODE (init.c)
|
ent->kernel_cs = 0x08; // GDT_KCODE (init.c)
|
||||||
ent->ist = 0;
|
ent->ist = 0;
|
||||||
@@ -84,74 +88,104 @@ static void amd64_idt_set(volatile struct idt_entry *ent, uint64_t handler, uint
|
|||||||
ent->resv = 0;
|
ent->resv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amd64_idt_init(void) {
|
static void amd64_idt_init (void) {
|
||||||
memset((void *)idt_entries, 0, sizeof(idt_entries));
|
memset ((void*)idt_entries, 0, sizeof (idt_entries));
|
||||||
|
|
||||||
#define IDT_ENTRY(n) \
|
#define IDT_ENTRY(n) \
|
||||||
extern void amd64_intr ## n(void); \
|
extern void amd64_intr##n (void); \
|
||||||
amd64_idt_set(&idt_entries[(n)], (uint64_t)&amd64_intr ## n, 0x8E)
|
amd64_idt_set (&idt_entries[(n)], (uint64_t)&amd64_intr##n, 0x8E)
|
||||||
IDT_ENTRY(0); IDT_ENTRY(1); IDT_ENTRY(2); IDT_ENTRY(3);
|
IDT_ENTRY (0);
|
||||||
IDT_ENTRY(4); IDT_ENTRY(5); IDT_ENTRY(6); IDT_ENTRY(7);
|
IDT_ENTRY (1);
|
||||||
IDT_ENTRY(8); IDT_ENTRY(9); IDT_ENTRY(10); IDT_ENTRY(11);
|
IDT_ENTRY (2);
|
||||||
IDT_ENTRY(12); IDT_ENTRY(13); IDT_ENTRY(14); IDT_ENTRY(15);
|
IDT_ENTRY (3);
|
||||||
IDT_ENTRY(16); IDT_ENTRY(17); IDT_ENTRY(18); IDT_ENTRY(19);
|
IDT_ENTRY (4);
|
||||||
IDT_ENTRY(20); IDT_ENTRY(21); IDT_ENTRY(22); IDT_ENTRY(23);
|
IDT_ENTRY (5);
|
||||||
IDT_ENTRY(24); IDT_ENTRY(25); IDT_ENTRY(26); IDT_ENTRY(27);
|
IDT_ENTRY (6);
|
||||||
IDT_ENTRY(28); IDT_ENTRY(29); IDT_ENTRY(30); IDT_ENTRY(31);
|
IDT_ENTRY (7);
|
||||||
IDT_ENTRY(32); IDT_ENTRY(33); IDT_ENTRY(34); IDT_ENTRY(35);
|
IDT_ENTRY (8);
|
||||||
IDT_ENTRY(36); IDT_ENTRY(37); IDT_ENTRY(38); IDT_ENTRY(39);
|
IDT_ENTRY (9);
|
||||||
IDT_ENTRY(40); IDT_ENTRY(41); IDT_ENTRY(42); IDT_ENTRY(43);
|
IDT_ENTRY (10);
|
||||||
IDT_ENTRY(44); IDT_ENTRY(45); IDT_ENTRY(46); IDT_ENTRY(47);
|
IDT_ENTRY (11);
|
||||||
|
IDT_ENTRY (12);
|
||||||
|
IDT_ENTRY (13);
|
||||||
|
IDT_ENTRY (14);
|
||||||
|
IDT_ENTRY (15);
|
||||||
|
IDT_ENTRY (16);
|
||||||
|
IDT_ENTRY (17);
|
||||||
|
IDT_ENTRY (18);
|
||||||
|
IDT_ENTRY (19);
|
||||||
|
IDT_ENTRY (20);
|
||||||
|
IDT_ENTRY (21);
|
||||||
|
IDT_ENTRY (22);
|
||||||
|
IDT_ENTRY (23);
|
||||||
|
IDT_ENTRY (24);
|
||||||
|
IDT_ENTRY (25);
|
||||||
|
IDT_ENTRY (26);
|
||||||
|
IDT_ENTRY (27);
|
||||||
|
IDT_ENTRY (28);
|
||||||
|
IDT_ENTRY (29);
|
||||||
|
IDT_ENTRY (30);
|
||||||
|
IDT_ENTRY (31);
|
||||||
|
IDT_ENTRY (32);
|
||||||
|
IDT_ENTRY (33);
|
||||||
|
IDT_ENTRY (34);
|
||||||
|
IDT_ENTRY (35);
|
||||||
|
IDT_ENTRY (36);
|
||||||
|
IDT_ENTRY (37);
|
||||||
|
IDT_ENTRY (38);
|
||||||
|
IDT_ENTRY (39);
|
||||||
|
IDT_ENTRY (40);
|
||||||
|
IDT_ENTRY (41);
|
||||||
|
IDT_ENTRY (42);
|
||||||
|
IDT_ENTRY (43);
|
||||||
|
IDT_ENTRY (44);
|
||||||
|
IDT_ENTRY (45);
|
||||||
|
IDT_ENTRY (46);
|
||||||
|
IDT_ENTRY (47);
|
||||||
#undef IDT_ENTRY
|
#undef IDT_ENTRY
|
||||||
|
|
||||||
idt.limit = sizeof(idt_entries) - 1;
|
idt.limit = sizeof (idt_entries) - 1;
|
||||||
idt.base = (uint64_t)idt_entries;
|
idt.base = (uint64_t)idt_entries;
|
||||||
|
|
||||||
__asm__ volatile("lidt %0" :: "m"(idt));
|
__asm__ volatile ("lidt %0" ::"m"(idt));
|
||||||
__asm__ volatile("sti");
|
__asm__ volatile ("sti");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amd64_intr_exception(struct saved_regs *regs) {
|
static void amd64_intr_exception (struct saved_regs* regs) {
|
||||||
DEBUG("cpu exception %lu (%lu)\n", regs->trap, regs->error);
|
DEBUG ("cpu exception %lu (%lu)\n", regs->trap, regs->error);
|
||||||
|
|
||||||
uint64_t cr2;
|
uint64_t cr2;
|
||||||
__asm__ volatile("movq %%cr2, %0" : "=r"(cr2));
|
__asm__ volatile ("movq %%cr2, %0" : "=r"(cr2));
|
||||||
uint64_t cr3;
|
uint64_t cr3;
|
||||||
__asm__ volatile("movq %%cr3, %0" : "=r"(cr3));
|
__asm__ volatile ("movq %%cr3, %0" : "=r"(cr3));
|
||||||
|
|
||||||
debugprintf(
|
debugprintf ("r15=%016lx r14=%016lx r13=%016lx\n"
|
||||||
"r15=%016lx r14=%016lx r13=%016lx\n"
|
"r12=%016lx r11=%016lx r10=%016lx\n"
|
||||||
"r12=%016lx r11=%016lx r10=%016lx\n"
|
"r9 =%016lx r8 =%016lx rbp=%016lx\n"
|
||||||
"r9 =%016lx r8 =%016lx rbp=%016lx\n"
|
"rdi=%016lx rsi=%016lx rdx=%016lx\n"
|
||||||
"rdi=%016lx rsi=%016lx rdx=%016lx\n"
|
"rcx=%016lx rax=%016lx trp=%016lx\n"
|
||||||
"rcx=%016lx rax=%016lx trp=%016lx\n"
|
"err=%016lx rip=%016lx cs =%016lx\n"
|
||||||
"err=%016lx rip=%016lx cs =%016lx\n"
|
"rfl=%016lx rsp=%016lx ss =%016lx\n"
|
||||||
"rfl=%016lx rsp=%016lx ss =%016lx\n"
|
"cr2=%016lx cr3=%016lx rbx=%016lx\n",
|
||||||
"cr2=%016lx cr3=%016lx rbx=%016lx\n",
|
regs->r15, regs->r14, regs->r13, regs->r12, regs->r11, regs->r10,
|
||||||
regs->r15, regs->r14, regs->r13,
|
regs->r9, regs->r8, regs->rbp, regs->rdi, regs->rsi, regs->rdx, regs->rcx,
|
||||||
regs->r12, regs->r11, regs->r10,
|
regs->rax, regs->trap, regs->error, regs->rip, regs->cs, regs->rflags,
|
||||||
regs->r9, regs->r8, regs->rbp,
|
regs->rsp, regs->ss, cr2, cr3, regs->rbx);
|
||||||
regs->rdi, regs->rsi, regs->rdx,
|
|
||||||
regs->rcx, regs->rax, regs->trap,
|
|
||||||
regs->error, regs->rip, regs->cs,
|
|
||||||
regs->rflags, regs->rsp, regs->ss,
|
|
||||||
cr2, cr3, regs->rbx
|
|
||||||
);
|
|
||||||
|
|
||||||
amd64_spin();
|
amd64_spin ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_intr_handler(void *stack_ptr) {
|
void amd64_intr_handler (void* stack_ptr) {
|
||||||
struct saved_regs *regs = stack_ptr;
|
struct saved_regs* regs = stack_ptr;
|
||||||
|
|
||||||
if (regs->trap <= 31) {
|
if (regs->trap <= 31) {
|
||||||
amd64_intr_exception(regs);
|
amd64_intr_exception (regs);
|
||||||
} else {
|
} else {
|
||||||
DEBUG("unknown trap %lu\n", regs->trap);
|
DEBUG ("unknown trap %lu\n", regs->trap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_intr_init(void) {
|
void amd64_intr_init (void) {
|
||||||
amd64_init_pic();
|
amd64_init_pic ();
|
||||||
amd64_idt_init();
|
amd64_idt_init ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ struct saved_regs {
|
|||||||
uint64_t rflags;
|
uint64_t rflags;
|
||||||
uint64_t rsp;
|
uint64_t rsp;
|
||||||
uint64_t ss;
|
uint64_t ss;
|
||||||
} __attribute__((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
void amd64_intr_init(void);
|
void amd64_intr_init (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_INTR_H
|
#endif // _KERNEL_AMD64_INTR_H
|
||||||
|
|||||||
@@ -1,54 +1,48 @@
|
|||||||
#include <libk/std.h>
|
|
||||||
#include <amd64/io.h>
|
#include <amd64/io.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
|
||||||
void amd64_io_outb(uint16_t port, uint8_t v) {
|
void amd64_io_outb (uint16_t port, uint8_t v) {
|
||||||
__asm__ volatile("outb %1, %0" :: "dN"(port), "a"(v));
|
__asm__ volatile ("outb %1, %0" ::"dN"(port), "a"(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_io_outw(uint16_t port, uint16_t v) {
|
void amd64_io_outw (uint16_t port, uint16_t v) {
|
||||||
__asm__ volatile("outw %%ax, %%dx" :: "a"(v), "d"(port));
|
__asm__ volatile ("outw %%ax, %%dx" ::"a"(v), "d"(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_io_outl(uint16_t port, uint32_t v) {
|
void amd64_io_outl (uint16_t port, uint32_t v) {
|
||||||
__asm__ volatile("outl %%eax, %%dx" :: "d"(port), "a"(v));
|
__asm__ volatile ("outl %%eax, %%dx" ::"d"(port), "a"(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_io_outsw(uint16_t port, const void *addr, int cnt) {
|
void amd64_io_outsw (uint16_t port, const void* addr, int cnt) {
|
||||||
__asm__ volatile(
|
__asm__ volatile ("cld; rep outsw"
|
||||||
"cld; rep outsw"
|
: "+S"(addr), "+c"(cnt)
|
||||||
: "+S"(addr), "+c"(cnt)
|
: "d"(port)
|
||||||
: "d"(port)
|
: "memory", "cc");
|
||||||
: "memory", "cc"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t amd64_io_inb(uint16_t port) {
|
uint8_t amd64_io_inb (uint16_t port) {
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
__asm__ volatile("inb %1, %0" : "=a"(r) : "dN"(port));
|
__asm__ volatile ("inb %1, %0" : "=a"(r) : "dN"(port));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t amd64_io_inw(uint16_t port) {
|
uint16_t amd64_io_inw (uint16_t port) {
|
||||||
uint16_t r;
|
uint16_t r;
|
||||||
__asm__ volatile("inw %%dx, %%ax" : "=a"(r) : "d"(port));
|
__asm__ volatile ("inw %%dx, %%ax" : "=a"(r) : "d"(port));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t amd64_io_inl(uint16_t port) {
|
uint32_t amd64_io_inl (uint16_t port) {
|
||||||
uint32_t r;
|
uint32_t r;
|
||||||
__asm__ volatile("inl %%dx, %%eax" : "=a"(r) : "d"(port));
|
__asm__ volatile ("inl %%dx, %%eax" : "=a"(r) : "d"(port));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_io_insw(uint16_t port, void *addr, int cnt) {
|
void amd64_io_insw (uint16_t port, void* addr, int cnt) {
|
||||||
__asm__ volatile(
|
__asm__ volatile ("cld; rep insw"
|
||||||
"cld; rep insw"
|
: "+D"(addr), "+c"(cnt)
|
||||||
: "+D"(addr), "+c"(cnt)
|
: "d"(port)
|
||||||
: "d"(port)
|
: "memory", "cc");
|
||||||
: "memory", "cc"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_io_wait(void) {
|
void amd64_io_wait (void) { amd64_io_outb (0x80, 0); }
|
||||||
amd64_io_outb(0x80, 0);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
void amd64_io_outb(uint16_t port, uint8_t v);
|
void amd64_io_outb (uint16_t port, uint8_t v);
|
||||||
void amd64_io_outw(uint16_t port, uint16_t v);
|
void amd64_io_outw (uint16_t port, uint16_t v);
|
||||||
void amd64_io_outl(uint16_t port, uint32_t v);
|
void amd64_io_outl (uint16_t port, uint32_t v);
|
||||||
void amd64_io_outsw(uint16_t port, const void *addr, int cnt);
|
void amd64_io_outsw (uint16_t port, const void* addr, int cnt);
|
||||||
uint8_t amd64_io_inb(uint16_t port);
|
uint8_t amd64_io_inb (uint16_t port);
|
||||||
uint16_t amd64_io_inw(uint16_t port);
|
uint16_t amd64_io_inw (uint16_t port);
|
||||||
uint32_t amd64_io_inl(uint16_t port);
|
uint32_t amd64_io_inl (uint16_t port);
|
||||||
void amd64_io_insw(uint16_t port, void *addr, int cnt);
|
void amd64_io_insw (uint16_t port, void* addr, int cnt);
|
||||||
void amd64_io_wait(void);
|
void amd64_io_wait (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_IO_H
|
#endif // _KERNEL_AMD64_IO_H
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef _KERNEL_AMD64_MM_H
|
#ifndef _KERNEL_AMD64_MM_H
|
||||||
#define _KERNEL_AMD64_MM_H
|
#define _KERNEL_AMD64_MM_H
|
||||||
|
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_MM_H
|
#endif // _KERNEL_AMD64_MM_H
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#include <sys/spin_lock.h>
|
#include <sys/spin_lock.h>
|
||||||
|
|
||||||
void spin_lock_relax(void) {
|
void spin_lock_relax (void) { __asm__ volatile ("pause"); }
|
||||||
__asm__ volatile("pause");
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include <libk/std.h>
|
|
||||||
#include <amd64/tss.h>
|
#include <amd64/tss.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
|
||||||
__attribute__((aligned(16))) static volatile struct tss tss;
|
__attribute__ ((aligned (16))) static volatile struct tss tss;
|
||||||
|
|
||||||
volatile struct tss *amd64_get_tss(void) {
|
volatile struct tss* amd64_get_tss (void) { return &tss; }
|
||||||
return &tss;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ struct tss {
|
|||||||
uint64_t resv2;
|
uint64_t resv2;
|
||||||
uint16_t resv3;
|
uint16_t resv3;
|
||||||
uint16_t iopb_off;
|
uint16_t iopb_off;
|
||||||
} __attribute__((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
volatile struct tss *amd64_get_tss(void);
|
volatile struct tss* amd64_get_tss (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_TSS_H
|
#endif // _KERNEL_AMD64_TSS_H
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define _KERNEL_LIBK_ALIGN_H
|
#define _KERNEL_LIBK_ALIGN_H
|
||||||
|
|
||||||
#define div_align_up(x, div) (((x) + (div) - 1) / (div))
|
#define div_align_up(x, div) (((x) + (div) - 1) / (div))
|
||||||
#define align_down(x, a) ((x) & ~((a) - 1))
|
#define align_down(x, a) ((x) & ~((a) - 1))
|
||||||
#define align_up(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
#define align_up(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||||
|
|
||||||
#endif // _KERNEL_LIBK_ALIGN_H
|
#endif // _KERNEL_LIBK_ALIGN_H
|
||||||
|
|||||||
@@ -1,74 +1,74 @@
|
|||||||
#include <libk/std.h>
|
|
||||||
#include <libk/bm.h>
|
#include <libk/bm.h>
|
||||||
|
#include <libk/std.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
|
|
||||||
void bm_init(struct bm *bm, uint8_t *base, size_t nbits) {
|
void bm_init (struct bm* bm, uint8_t* base, size_t nbits) {
|
||||||
bm->base = base;
|
bm->base = base;
|
||||||
bm->nbits = nbits;
|
bm->nbits = nbits;
|
||||||
memset(bm->base, 0, (nbits + 7) / 8);
|
memset (bm->base, 0, (nbits + 7) / 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set a bit in a bitmap.
|
* Set a bit in a bitmap.
|
||||||
*/
|
*/
|
||||||
void bm_set(struct bm *bm, size_t k) {
|
void bm_set (struct bm* bm, size_t k) {
|
||||||
if (k >= bm->nbits)
|
if (k >= bm->nbits)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8_t *b = (uint8_t *)((uintptr_t)bm->base + (k / 8));
|
uint8_t* b = (uint8_t*)((uintptr_t)bm->base + (k / 8));
|
||||||
*b = ((*b) | (1 << (k % 8)));
|
*b = ((*b) | (1 << (k % 8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear a bit in a bitmap.
|
* Clear a bit in a bitmap.
|
||||||
*/
|
*/
|
||||||
void bm_clear(struct bm *bm, size_t k) {
|
void bm_clear (struct bm* bm, size_t k) {
|
||||||
if (k >= bm->nbits)
|
if (k >= bm->nbits)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8_t *b = (uint8_t *)((uintptr_t)bm->base + (k / 8));
|
uint8_t* b = (uint8_t*)((uintptr_t)bm->base + (k / 8));
|
||||||
*b = ((*b) & ~(1 << (k % 8)));
|
*b = ((*b) & ~(1 << (k % 8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test (true/false) a bit in a bitmap.
|
* Test (true/false) a bit in a bitmap.
|
||||||
*/
|
*/
|
||||||
bool bm_test(struct bm *bm, size_t k) {
|
bool bm_test (struct bm* bm, size_t k) {
|
||||||
if (k >= bm->nbits)
|
if (k >= bm->nbits)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint8_t *b = (uint8_t *)((uintptr_t)bm->base + (k / 8));
|
uint8_t* b = (uint8_t*)((uintptr_t)bm->base + (k / 8));
|
||||||
return (*b) & (1 << (k % 8));
|
return (*b) & (1 << (k % 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set a range of bits in a bitmap. if starting bit is out of range, we fail.
|
* Set a range of bits in a bitmap. if starting bit is out of range, we fail.
|
||||||
*/
|
*/
|
||||||
bool bm_set_region(struct bm *bm, size_t k, size_t m) {
|
bool bm_set_region (struct bm* bm, size_t k, size_t m) {
|
||||||
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (size_t i = k; i < m; i++) {
|
for (size_t i = k; i < m; i++) {
|
||||||
bool taken = bm_test(bm, i);
|
bool taken = bm_test (bm, i);
|
||||||
if (taken)
|
if (taken)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = k; i < m; i++)
|
for (size_t i = k; i < m; i++)
|
||||||
bm_set(bm, i);
|
bm_set (bm, i);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear a range of bits in a bitmap. starting bit must be in range.
|
* Clear a range of bits in a bitmap. starting bit must be in range.
|
||||||
*/
|
*/
|
||||||
void bm_clear_region(struct bm *bm, size_t k, size_t m) {
|
void bm_clear_region (struct bm* bm, size_t k, size_t m) {
|
||||||
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (size_t i = k; i < m; i++)
|
for (size_t i = k; i < m; i++)
|
||||||
bm_clear(bm, i);
|
bm_clear (bm, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -77,12 +77,12 @@ void bm_clear_region(struct bm *bm, size_t k, size_t m) {
|
|||||||
* are out of range, act as if the bits are set / bitmap is full - this is
|
* are out of range, act as if the bits are set / bitmap is full - this is
|
||||||
* useful for implementing the physical memory manager algorithm.
|
* useful for implementing the physical memory manager algorithm.
|
||||||
*/
|
*/
|
||||||
bool bm_test_region(struct bm *bm, size_t k, size_t m) {
|
bool bm_test_region (struct bm* bm, size_t k, size_t m) {
|
||||||
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (size_t i = k; i < m; i++) {
|
for (size_t i = k; i < m; i++) {
|
||||||
bool test = bm_test(bm, i);
|
bool test = bm_test (bm, i);
|
||||||
if (test)
|
if (test)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
struct bm {
|
struct bm {
|
||||||
uint8_t *base;
|
uint8_t* base;
|
||||||
size_t nbits;
|
size_t nbits;
|
||||||
};
|
};
|
||||||
|
|
||||||
void bm_init(struct bm *bm, uint8_t *base, size_t nbits);
|
void bm_init (struct bm* bm, uint8_t* base, size_t nbits);
|
||||||
void bm_set(struct bm *bm, size_t k);
|
void bm_set (struct bm* bm, size_t k);
|
||||||
bool bm_set_region(struct bm *bm, size_t k, size_t m);
|
bool bm_set_region (struct bm* bm, size_t k, size_t m);
|
||||||
void bm_clear(struct bm *bm, size_t k);
|
void bm_clear (struct bm* bm, size_t k);
|
||||||
void bm_clear_region(struct bm *bm, size_t k, size_t m);
|
void bm_clear_region (struct bm* bm, size_t k, size_t m);
|
||||||
bool bm_test(struct bm *bm, size_t k);
|
bool bm_test (struct bm* bm, size_t k);
|
||||||
bool bm_test_region(struct bm *bm, size_t k, size_t m);
|
bool bm_test_region (struct bm* bm, size_t k, size_t m);
|
||||||
|
|
||||||
#endif // _KERNEL_LIBK_BM_H
|
#endif // _KERNEL_LIBK_BM_H
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
|
|
||||||
void putchar_(char x) { (void)x; }
|
void putchar_ (char x) { (void)x; }
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdalign.h>
|
#include <stdalign.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdnoreturn.h>
|
#include <stdnoreturn.h>
|
||||||
#include <stdatomic.h>
|
|
||||||
|
|
||||||
#endif // _KERNEL_LIBK_STD_H
|
#endif // _KERNEL_LIBK_STD_H
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
|
|
||||||
size_t memset(void *dst, uint8_t b, size_t n) {
|
size_t memset (void* dst, uint8_t b, size_t n) {
|
||||||
uint8_t *dst1 = dst;
|
uint8_t* dst1 = dst;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
dst1[i] = b;
|
dst1[i] = b;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t memcpy(void *dst, const void *src, size_t n) {
|
size_t memcpy (void* dst, const void* src, size_t n) {
|
||||||
uint8_t *dst1 = dst;
|
uint8_t* dst1 = dst;
|
||||||
const uint8_t *src1 = src;
|
const uint8_t* src1 = src;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
dst1[i] = src1[i];
|
dst1[i] = src1[i];
|
||||||
@@ -19,20 +19,22 @@ size_t memcpy(void *dst, const void *src, size_t n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SOURCE: https://stackoverflow.com/a/48967408
|
// SOURCE: https://stackoverflow.com/a/48967408
|
||||||
void strncpy(char* dst, const char* src, size_t n) {
|
void strncpy (char* dst, const char* src, size_t n) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while(i++ != n && (*dst++ = *src++));
|
while (i++ != n && (*dst++ = *src++))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t strlen(const char *str) {
|
size_t strlen (const char* str) {
|
||||||
const char *s;
|
const char* s;
|
||||||
for (s = str; *s; ++s);
|
for (s = str; *s; ++s)
|
||||||
|
;
|
||||||
return (s - str);
|
return (s - str);
|
||||||
}
|
}
|
||||||
|
|
||||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
int memcmp (const void* s1, const void* s2, size_t n) {
|
||||||
unsigned char *p = (unsigned char *)s1;
|
unsigned char* p = (unsigned char*)s1;
|
||||||
unsigned char *q = (unsigned char *)s2;
|
unsigned char* q = (unsigned char*)s2;
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
if (*p != *q) {
|
if (*p != *q) {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#ifndef _KERNEL_LIBK_STRING_H
|
#ifndef _KERNEL_LIBK_STRING_H
|
||||||
#define _KERNEL_LIBK_STRING_H
|
#define _KERNEL_LIBK_STRING_H
|
||||||
|
|
||||||
size_t memset(void *dst, uint8_t b, size_t n);
|
size_t memset (void* dst, uint8_t b, size_t n);
|
||||||
size_t memcpy(void *dst, const void *src, size_t n);
|
size_t memcpy (void* dst, const void* src, size_t n);
|
||||||
void strncpy(char* dst, const char* src, size_t n);
|
void strncpy (char* dst, const char* src, size_t n);
|
||||||
size_t strlen(const char *str);
|
size_t strlen (const char* str);
|
||||||
int memcmp(const void *s1, const void *s2, size_t n);
|
int memcmp (const void* s1, const void* s2, size_t n);
|
||||||
|
|
||||||
#endif // _KERNEL_LIBK_STRING_H
|
#endif // _KERNEL_LIBK_STRING_H
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
#include <limine/limine.h>
|
#include <limine/limine.h>
|
||||||
|
|
||||||
#define DECL_REQ(small, big) \
|
#define DECL_REQ(small, big) \
|
||||||
__attribute__((used, section(".limine_requests"))) \
|
__attribute__ (( \
|
||||||
struct limine_ ## small ## _request limine_ ## small ## _request = { \
|
used, section (".limine_requests"))) struct limine_##small##_request \
|
||||||
.id = LIMINE_ ## big ## _REQUEST_ID, \
|
limine_##small##_request = { \
|
||||||
.revision = 4 \
|
.id = LIMINE_##big##_REQUEST_ID, .revision = 4}
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((used, section(".limine_requests")))
|
__attribute__ ((used,
|
||||||
volatile uint64_t limine_base_revision[] = LIMINE_BASE_REVISION(4);
|
section (".limine_requests"))) volatile uint64_t limine_base_revision[] =
|
||||||
|
LIMINE_BASE_REVISION (4);
|
||||||
|
|
||||||
__attribute__((used, section(".limine_requests_start")))
|
__attribute__ ((used, section (".limine_requests_start"))) volatile uint64_t
|
||||||
volatile uint64_t limine_requests_start_marker[] = LIMINE_REQUESTS_START_MARKER;
|
limine_requests_start_marker[] = LIMINE_REQUESTS_START_MARKER;
|
||||||
|
|
||||||
__attribute__((used, section(".limine_requests_end")))
|
__attribute__ ((used, section (".limine_requests_end"))) volatile uint64_t
|
||||||
volatile uint64_t limine_requests_end_marker[] = LIMINE_REQUESTS_END_MARKER;
|
limine_requests_end_marker[] = LIMINE_REQUESTS_END_MARKER;
|
||||||
|
|
||||||
DECL_REQ(hhdm, HHDM);
|
DECL_REQ (hhdm, HHDM);
|
||||||
DECL_REQ(memmap, MEMMAP);
|
DECL_REQ (memmap, MEMMAP);
|
||||||
DECL_REQ(rsdp, RSDP);
|
DECL_REQ (rsdp, RSDP);
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
#include <limine/limine.h>
|
#include <limine/limine.h>
|
||||||
|
|
||||||
#define EXTERN_REQ(small) \
|
#define EXTERN_REQ(small) \
|
||||||
extern struct limine_ ## small ## _request limine_ ## small ## _request
|
extern struct limine_##small##_request limine_##small##_request
|
||||||
|
|
||||||
EXTERN_REQ(hhdm);
|
EXTERN_REQ (hhdm);
|
||||||
EXTERN_REQ(memmap);
|
EXTERN_REQ (memmap);
|
||||||
EXTERN_REQ(rsdp);
|
EXTERN_REQ (rsdp);
|
||||||
|
|
||||||
#endif // _KERNEL_LIMINE_REQUESTS_H
|
#endif // _KERNEL_LIMINE_REQUESTS_H
|
||||||
|
|||||||
@@ -1,79 +1,75 @@
|
|||||||
/* liballoc breaks when optimized too aggressively, for eg. clang's -Oz */
|
/* liballoc breaks when optimized too aggressively, for eg. clang's -Oz */
|
||||||
#pragma clang optimize off
|
#pragma clang optimize off
|
||||||
|
|
||||||
|
#include <limine/requests.h>
|
||||||
#include <mm/liballoc.h>
|
#include <mm/liballoc.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <mm/types.h>
|
#include <mm/types.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
#include <limine/requests.h>
|
|
||||||
|
|
||||||
/* Porting */
|
/* Porting */
|
||||||
spin_lock_t _liballoc_lock = SPIN_LOCK_INIT;
|
spin_lock_t _liballoc_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
int liballoc_lock(void) {
|
int liballoc_lock (void) {
|
||||||
spin_lock(&_liballoc_lock);
|
spin_lock (&_liballoc_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int liballoc_unlock(void) {
|
int liballoc_unlock (void) {
|
||||||
spin_unlock(&_liballoc_lock);
|
spin_unlock (&_liballoc_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *liballoc_alloc(int pages) {
|
void* liballoc_alloc (int pages) {
|
||||||
physaddr_t p_addr = pmm_alloc(pages);
|
physaddr_t p_addr = pmm_alloc (pages);
|
||||||
|
|
||||||
if (p_addr == PMM_ALLOC_ERR)
|
if (p_addr == PMM_ALLOC_ERR)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
struct limine_hhdm_response *hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
uintptr_t addr = (uintptr_t)(p_addr + hhdm->offset);
|
uintptr_t addr = (uintptr_t)(p_addr + hhdm->offset);
|
||||||
return (void *)addr;
|
return (void*)addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int liballoc_free(void *ptr, int pages) {
|
int liballoc_free (void* ptr, int pages) {
|
||||||
struct limine_hhdm_response *hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
physaddr_t p_addr = (uintptr_t)ptr - hhdm->offset;
|
physaddr_t p_addr = (uintptr_t)ptr - hhdm->offset;
|
||||||
|
|
||||||
pmm_free(p_addr, pages);
|
pmm_free (p_addr, pages);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Durand's Ridiculously Amazing Super Duper Memory functions. */
|
/** Durand's Ridiculously Amazing Super Duper Memory functions. */
|
||||||
|
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
|
|
||||||
#define LIBALLOC_MAGIC 0xc001c0de
|
#define LIBALLOC_MAGIC 0xc001c0de
|
||||||
#define MAXCOMPLETE 5
|
#define MAXCOMPLETE 5
|
||||||
#define MAXEXP 32
|
#define MAXEXP 32
|
||||||
#define MINEXP 8
|
#define MINEXP 8
|
||||||
|
|
||||||
#define MODE_BEST 0
|
#define MODE_BEST 0
|
||||||
#define MODE_INSTANT 1
|
#define MODE_INSTANT 1
|
||||||
|
|
||||||
#define MODE MODE_BEST
|
#define MODE MODE_BEST
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
|
||||||
struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
|
int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
|
||||||
int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
unsigned int l_allocated = 0; //< The real amount of memory allocated.
|
unsigned int l_allocated = 0; //< The real amount of memory allocated.
|
||||||
unsigned int l_inuse = 0; //< The amount of memory in use (malloc'ed).
|
unsigned int l_inuse = 0; //< The amount of memory in use (malloc'ed).
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int l_initialized = 0; //< Flag to indicate initialization.
|
||||||
static int l_initialized = 0; //< Flag to indicate initialization.
|
static int l_pageSize = 4096; //< Individual page size
|
||||||
static int l_pageSize = 4096; //< Individual page size
|
static int l_pageCount = 16; //< Minimum number of pages to allocate.
|
||||||
static int l_pageCount = 16; //< Minimum number of pages to allocate.
|
|
||||||
|
|
||||||
|
|
||||||
// *********** HELPER FUNCTIONS *******************************
|
// *********** HELPER FUNCTIONS *******************************
|
||||||
|
|
||||||
@@ -81,495 +77,456 @@ static int l_pageCount = 16; //< Minimum number of pages to allocate.
|
|||||||
*
|
*
|
||||||
* Returns n where 2^n <= size < 2^(n+1)
|
* Returns n where 2^n <= size < 2^(n+1)
|
||||||
*/
|
*/
|
||||||
static inline int getexp( unsigned int size )
|
static inline int getexp (unsigned int size) {
|
||||||
{
|
if (size < (1 << MINEXP)) {
|
||||||
if ( size < (1<<MINEXP) )
|
#ifdef DEBUG
|
||||||
{
|
printf ("getexp returns -1 for %i less than MINEXP\n", size);
|
||||||
#ifdef DEBUG
|
#endif
|
||||||
printf("getexp returns -1 for %i less than MINEXP\n", size );
|
return -1; // Smaller than the quantum.
|
||||||
#endif
|
}
|
||||||
return -1; // Smaller than the quantum.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int shift = MINEXP;
|
|
||||||
|
|
||||||
while ( shift < MAXEXP )
|
int shift = MINEXP;
|
||||||
{
|
|
||||||
if ( (1<<shift) > size ) break;
|
|
||||||
shift += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
while (shift < MAXEXP) {
|
||||||
printf("getexp returns %i (%i bytes) for %i size\n", shift - 1, (1<<(shift -1)), size );
|
if ((1 << shift) > size)
|
||||||
#endif
|
break;
|
||||||
|
shift += 1;
|
||||||
|
}
|
||||||
|
|
||||||
return shift - 1;
|
#ifdef DEBUG
|
||||||
|
printf ("getexp returns %i (%i bytes) for %i size\n", shift - 1,
|
||||||
|
(1 << (shift - 1)), size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return shift - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void* liballoc_memset (void* s, int c, size_t n) {
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
((char*)s)[i] = c;
|
||||||
|
|
||||||
static void* liballoc_memset(void* s, int c, size_t n)
|
return s;
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for ( i = 0; i < n ; i++)
|
|
||||||
((char*)s)[i] = c;
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* liballoc_memcpy(void* s1, const void* s2, size_t n)
|
static void* liballoc_memcpy (void* s1, const void* s2, size_t n) {
|
||||||
{
|
char* cdest;
|
||||||
char *cdest;
|
char* csrc;
|
||||||
char *csrc;
|
unsigned int* ldest = (unsigned int*)s1;
|
||||||
unsigned int *ldest = (unsigned int*)s1;
|
unsigned int* lsrc = (unsigned int*)s2;
|
||||||
unsigned int *lsrc = (unsigned int*)s2;
|
|
||||||
|
|
||||||
while ( n >= sizeof(unsigned int) )
|
while (n >= sizeof (unsigned int)) {
|
||||||
{
|
*ldest++ = *lsrc++;
|
||||||
*ldest++ = *lsrc++;
|
n -= sizeof (unsigned int);
|
||||||
n -= sizeof(unsigned int);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cdest = (char*)ldest;
|
cdest = (char*)ldest;
|
||||||
csrc = (char*)lsrc;
|
csrc = (char*)lsrc;
|
||||||
|
|
||||||
while ( n > 0 )
|
while (n > 0) {
|
||||||
{
|
*cdest++ = *csrc++;
|
||||||
*cdest++ = *csrc++;
|
n -= 1;
|
||||||
n -= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s1;
|
return s1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void dump_array()
|
static void dump_array () {
|
||||||
{
|
int i = 0;
|
||||||
int i = 0;
|
struct boundary_tag* tag = NULL;
|
||||||
struct boundary_tag *tag = NULL;
|
|
||||||
|
|
||||||
printf("------ Free pages array ---------\n");
|
printf ("------ Free pages array ---------\n");
|
||||||
printf("System memory allocated: %i\n", l_allocated );
|
printf ("System memory allocated: %i\n", l_allocated);
|
||||||
printf("Memory in used (malloc'ed): %i\n", l_inuse );
|
printf ("Memory in used (malloc'ed): %i\n", l_inuse);
|
||||||
|
|
||||||
for ( i = 0; i < MAXEXP; i++ )
|
for (i = 0; i < MAXEXP; i++) {
|
||||||
{
|
printf ("%.2i(%i): ", i, l_completePages[i]);
|
||||||
printf("%.2i(%i): ",i, l_completePages[i] );
|
|
||||||
|
|
||||||
tag = l_freePages[ i ];
|
|
||||||
while ( tag != NULL )
|
|
||||||
{
|
|
||||||
if ( tag->split_left != NULL ) printf("*");
|
|
||||||
printf("%i", tag->real_size );
|
|
||||||
if ( tag->split_right != NULL ) printf("*");
|
|
||||||
|
|
||||||
printf(" ");
|
|
||||||
tag = tag->next;
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("'*' denotes a split to the left/right of a tag\n");
|
tag = l_freePages[i];
|
||||||
fflush( stdout );
|
while (tag != NULL) {
|
||||||
|
if (tag->split_left != NULL)
|
||||||
|
printf ("*");
|
||||||
|
printf ("%i", tag->real_size);
|
||||||
|
if (tag->split_right != NULL)
|
||||||
|
printf ("*");
|
||||||
|
|
||||||
|
printf (" ");
|
||||||
|
tag = tag->next;
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("'*' denotes a split to the left/right of a tag\n");
|
||||||
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void insert_tag (struct boundary_tag* tag, int index) {
|
||||||
|
int realIndex;
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
realIndex = getexp (tag->real_size - sizeof (struct boundary_tag));
|
||||||
|
if (realIndex < MINEXP)
|
||||||
|
realIndex = MINEXP;
|
||||||
|
} else
|
||||||
|
realIndex = index;
|
||||||
|
|
||||||
static inline void insert_tag( struct boundary_tag *tag, int index )
|
tag->index = realIndex;
|
||||||
{
|
|
||||||
int realIndex;
|
|
||||||
|
|
||||||
if ( index < 0 )
|
|
||||||
{
|
|
||||||
realIndex = getexp( tag->real_size - sizeof(struct boundary_tag) );
|
|
||||||
if ( realIndex < MINEXP ) realIndex = MINEXP;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
realIndex = index;
|
|
||||||
|
|
||||||
tag->index = realIndex;
|
|
||||||
|
|
||||||
if ( l_freePages[ realIndex ] != NULL )
|
|
||||||
{
|
|
||||||
l_freePages[ realIndex ]->prev = tag;
|
|
||||||
tag->next = l_freePages[ realIndex ];
|
|
||||||
}
|
|
||||||
|
|
||||||
l_freePages[ realIndex ] = tag;
|
if (l_freePages[realIndex] != NULL) {
|
||||||
|
l_freePages[realIndex]->prev = tag;
|
||||||
|
tag->next = l_freePages[realIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
l_freePages[realIndex] = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void remove_tag( struct boundary_tag *tag )
|
static inline void remove_tag (struct boundary_tag* tag) {
|
||||||
{
|
if (l_freePages[tag->index] == tag)
|
||||||
if ( l_freePages[ tag->index ] == tag ) l_freePages[ tag->index ] = tag->next;
|
l_freePages[tag->index] = tag->next;
|
||||||
|
|
||||||
if ( tag->prev != NULL ) tag->prev->next = tag->next;
|
if (tag->prev != NULL)
|
||||||
if ( tag->next != NULL ) tag->next->prev = tag->prev;
|
tag->prev->next = tag->next;
|
||||||
|
if (tag->next != NULL)
|
||||||
|
tag->next->prev = tag->prev;
|
||||||
|
|
||||||
tag->next = NULL;
|
tag->next = NULL;
|
||||||
tag->prev = NULL;
|
tag->prev = NULL;
|
||||||
tag->index = -1;
|
tag->index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct boundary_tag* melt_left (struct boundary_tag* tag) {
|
||||||
|
struct boundary_tag* left = tag->split_left;
|
||||||
|
|
||||||
static inline struct boundary_tag* melt_left( struct boundary_tag *tag )
|
left->real_size += tag->real_size;
|
||||||
{
|
left->split_right = tag->split_right;
|
||||||
struct boundary_tag *left = tag->split_left;
|
|
||||||
|
|
||||||
left->real_size += tag->real_size;
|
|
||||||
left->split_right = tag->split_right;
|
|
||||||
|
|
||||||
if ( tag->split_right != NULL ) tag->split_right->split_left = left;
|
|
||||||
|
|
||||||
return left;
|
if (tag->split_right != NULL)
|
||||||
|
tag->split_right->split_left = left;
|
||||||
|
|
||||||
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct boundary_tag* absorb_right (struct boundary_tag* tag) {
|
||||||
|
struct boundary_tag* right = tag->split_right;
|
||||||
|
|
||||||
static inline struct boundary_tag* absorb_right( struct boundary_tag *tag )
|
remove_tag (right); // Remove right from free pages.
|
||||||
{
|
|
||||||
struct boundary_tag *right = tag->split_right;
|
|
||||||
|
|
||||||
remove_tag( right ); // Remove right from free pages.
|
tag->real_size += right->real_size;
|
||||||
|
|
||||||
tag->real_size += right->real_size;
|
tag->split_right = right->split_right;
|
||||||
|
if (right->split_right != NULL)
|
||||||
|
right->split_right->split_left = tag;
|
||||||
|
|
||||||
tag->split_right = right->split_right;
|
return tag;
|
||||||
if ( right->split_right != NULL )
|
|
||||||
right->split_right->split_left = tag;
|
|
||||||
|
|
||||||
return tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct boundary_tag* split_tag( struct boundary_tag* tag )
|
static inline struct boundary_tag* split_tag (struct boundary_tag* tag) {
|
||||||
{
|
unsigned int remainder =
|
||||||
unsigned int remainder = tag->real_size - sizeof(struct boundary_tag) - tag->size;
|
tag->real_size - sizeof (struct boundary_tag) - tag->size;
|
||||||
|
|
||||||
struct boundary_tag *new_tag =
|
|
||||||
(struct boundary_tag*)((uintptr_t)tag + sizeof(struct boundary_tag) + tag->size);
|
|
||||||
|
|
||||||
new_tag->magic = LIBALLOC_MAGIC;
|
|
||||||
new_tag->real_size = remainder;
|
|
||||||
|
|
||||||
new_tag->next = NULL;
|
struct boundary_tag* new_tag = (struct boundary_tag*)((uintptr_t)tag +
|
||||||
new_tag->prev = NULL;
|
sizeof (struct boundary_tag) + tag->size);
|
||||||
|
|
||||||
new_tag->split_left = tag;
|
new_tag->magic = LIBALLOC_MAGIC;
|
||||||
new_tag->split_right = tag->split_right;
|
new_tag->real_size = remainder;
|
||||||
|
|
||||||
if (new_tag->split_right != NULL) new_tag->split_right->split_left = new_tag;
|
new_tag->next = NULL;
|
||||||
tag->split_right = new_tag;
|
new_tag->prev = NULL;
|
||||||
|
|
||||||
tag->real_size -= new_tag->real_size;
|
new_tag->split_left = tag;
|
||||||
|
new_tag->split_right = tag->split_right;
|
||||||
insert_tag( new_tag, -1 );
|
|
||||||
|
if (new_tag->split_right != NULL)
|
||||||
return new_tag;
|
new_tag->split_right->split_left = new_tag;
|
||||||
|
tag->split_right = new_tag;
|
||||||
|
|
||||||
|
tag->real_size -= new_tag->real_size;
|
||||||
|
|
||||||
|
insert_tag (new_tag, -1);
|
||||||
|
|
||||||
|
return new_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************
|
// ***************************************************************
|
||||||
|
|
||||||
|
static struct boundary_tag* allocate_new_tag (unsigned int size) {
|
||||||
|
unsigned int pages;
|
||||||
|
unsigned int usage;
|
||||||
|
struct boundary_tag* tag;
|
||||||
|
|
||||||
|
// This is how much space is required.
|
||||||
|
usage = size + sizeof (struct boundary_tag);
|
||||||
|
|
||||||
|
// Perfect amount of space
|
||||||
|
pages = usage / l_pageSize;
|
||||||
|
if ((usage % l_pageSize) != 0)
|
||||||
|
pages += 1;
|
||||||
|
|
||||||
static struct boundary_tag* allocate_new_tag( unsigned int size )
|
// Make sure it's >= the minimum size.
|
||||||
{
|
if (pages < (unsigned int)l_pageCount)
|
||||||
unsigned int pages;
|
pages = l_pageCount;
|
||||||
unsigned int usage;
|
|
||||||
struct boundary_tag *tag;
|
|
||||||
|
|
||||||
// This is how much space is required.
|
tag = (struct boundary_tag*)liballoc_alloc (pages);
|
||||||
usage = size + sizeof(struct boundary_tag);
|
|
||||||
|
|
||||||
// Perfect amount of space
|
if (tag == NULL)
|
||||||
pages = usage / l_pageSize;
|
return NULL; // uh oh, we ran out of memory.
|
||||||
if ( (usage % l_pageSize) != 0 ) pages += 1;
|
|
||||||
|
|
||||||
// Make sure it's >= the minimum size.
|
tag->magic = LIBALLOC_MAGIC;
|
||||||
if ( pages < (unsigned int)l_pageCount ) pages = l_pageCount;
|
tag->size = size;
|
||||||
|
tag->real_size = pages * l_pageSize;
|
||||||
|
tag->index = -1;
|
||||||
|
|
||||||
tag = (struct boundary_tag*)liballoc_alloc( pages );
|
tag->next = NULL;
|
||||||
|
tag->prev = NULL;
|
||||||
|
tag->split_left = NULL;
|
||||||
|
tag->split_right = NULL;
|
||||||
|
|
||||||
if ( tag == NULL ) return NULL; // uh oh, we ran out of memory.
|
#ifdef DEBUG
|
||||||
|
printf ("Resource allocated %x of %i pages (%i bytes) for %i size.\n", tag,
|
||||||
tag->magic = LIBALLOC_MAGIC;
|
pages, pages * l_pageSize, size);
|
||||||
tag->size = size;
|
|
||||||
tag->real_size = pages * l_pageSize;
|
|
||||||
tag->index = -1;
|
|
||||||
|
|
||||||
tag->next = NULL;
|
l_allocated += pages * l_pageSize;
|
||||||
tag->prev = NULL;
|
|
||||||
tag->split_left = NULL;
|
|
||||||
tag->split_right = NULL;
|
|
||||||
|
|
||||||
|
printf ("Total memory usage = %i KB\n", (int)((l_allocated / (1024))));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
return tag;
|
||||||
printf("Resource allocated %x of %i pages (%i bytes) for %i size.\n", tag, pages, pages * l_pageSize, size );
|
|
||||||
|
|
||||||
l_allocated += pages * l_pageSize;
|
|
||||||
|
|
||||||
printf("Total memory usage = %i KB\n", (int)((l_allocated / (1024))) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* malloc (size_t size) {
|
||||||
|
int index;
|
||||||
|
void* ptr;
|
||||||
|
struct boundary_tag* tag = NULL;
|
||||||
|
|
||||||
|
liballoc_lock ();
|
||||||
|
|
||||||
void *malloc(size_t size)
|
if (l_initialized == 0) {
|
||||||
{
|
#ifdef DEBUG
|
||||||
int index;
|
printf ("%s\n", "liballoc initializing.");
|
||||||
void *ptr;
|
#endif
|
||||||
struct boundary_tag *tag = NULL;
|
for (index = 0; index < MAXEXP; index++) {
|
||||||
|
l_freePages[index] = NULL;
|
||||||
|
l_completePages[index] = 0;
|
||||||
|
}
|
||||||
|
l_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
liballoc_lock();
|
index = getexp (size) + MODE;
|
||||||
|
if (index < MINEXP)
|
||||||
|
index = MINEXP;
|
||||||
|
|
||||||
if ( l_initialized == 0 )
|
// Find one big enough.
|
||||||
{
|
tag = l_freePages[index]; // Start at the front of the list.
|
||||||
#ifdef DEBUG
|
while (tag != NULL) {
|
||||||
printf("%s\n","liballoc initializing.");
|
// If there's enough space in this tag.
|
||||||
#endif
|
if ((tag->real_size - sizeof (struct boundary_tag)) >=
|
||||||
for ( index = 0; index < MAXEXP; index++ )
|
(size + sizeof (struct boundary_tag))) {
|
||||||
{
|
#ifdef DEBUG
|
||||||
l_freePages[index] = NULL;
|
printf ("Tag search found %i >= %i\n",
|
||||||
l_completePages[index] = 0;
|
(tag->real_size - sizeof (struct boundary_tag)),
|
||||||
}
|
(size + sizeof (struct boundary_tag)));
|
||||||
l_initialized = 1;
|
#endif
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
index = getexp( size ) + MODE;
|
tag = tag->next;
|
||||||
if ( index < MINEXP ) index = MINEXP;
|
}
|
||||||
|
|
||||||
|
|
||||||
// Find one big enough.
|
// No page found. Make one.
|
||||||
tag = l_freePages[ index ]; // Start at the front of the list.
|
if (tag == NULL) {
|
||||||
while ( tag != NULL )
|
if ((tag = allocate_new_tag (size)) == NULL) {
|
||||||
{
|
liballoc_unlock ();
|
||||||
// If there's enough space in this tag.
|
return NULL;
|
||||||
if ( (tag->real_size - sizeof(struct boundary_tag))
|
}
|
||||||
>= (size + sizeof(struct boundary_tag) ) )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("Tag search found %i >= %i\n",(tag->real_size - sizeof(struct boundary_tag)), (size + sizeof(struct boundary_tag) ) );
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tag = tag->next;
|
index = getexp (tag->real_size - sizeof (struct boundary_tag));
|
||||||
}
|
} else {
|
||||||
|
remove_tag (tag);
|
||||||
|
|
||||||
|
if ((tag->split_left == NULL) && (tag->split_right == NULL))
|
||||||
// No page found. Make one.
|
l_completePages[index] -= 1;
|
||||||
if ( tag == NULL )
|
}
|
||||||
{
|
|
||||||
if ( (tag = allocate_new_tag( size )) == NULL )
|
|
||||||
{
|
|
||||||
liballoc_unlock();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = getexp( tag->real_size - sizeof(struct boundary_tag) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
remove_tag( tag );
|
|
||||||
|
|
||||||
if ( (tag->split_left == NULL) && (tag->split_right == NULL) )
|
// We have a free page. Remove it from the free pages list.
|
||||||
l_completePages[ index ] -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have a free page. Remove it from the free pages list.
|
|
||||||
|
|
||||||
tag->size = size;
|
|
||||||
|
|
||||||
// Removed... see if we can re-use the excess space.
|
tag->size = size;
|
||||||
|
|
||||||
#ifdef DEBUG
|
// Removed... see if we can re-use the excess space.
|
||||||
printf("Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n", tag->real_size - sizeof(struct boundary_tag), size, tag->real_size - size - sizeof(struct boundary_tag), index, 1<<index );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned int remainder = tag->real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder
|
|
||||||
|
|
||||||
if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/ )
|
#ifdef DEBUG
|
||||||
{
|
printf (
|
||||||
int childIndex = getexp( remainder );
|
"Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n",
|
||||||
|
tag->real_size - sizeof (struct boundary_tag), size,
|
||||||
if ( childIndex >= 0 )
|
tag->real_size - size - sizeof (struct boundary_tag), index, 1 << index);
|
||||||
{
|
#endif
|
||||||
#ifdef DEBUG
|
|
||||||
printf("Seems to be splittable: %i >= 2^%i .. %i\n", remainder, childIndex, (1<<childIndex) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct boundary_tag *new_tag = split_tag( tag );
|
unsigned int remainder = tag->real_size - size -
|
||||||
|
sizeof (struct boundary_tag) * 2; // Support a new tag + remainder
|
||||||
|
|
||||||
(void)new_tag;
|
if (((int)(remainder) >
|
||||||
|
0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/) {
|
||||||
|
int childIndex = getexp (remainder);
|
||||||
|
|
||||||
#ifdef DEBUG
|
if (childIndex >= 0) {
|
||||||
printf("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n", tag->real_size, new_tag->real_size, new_tag->index );
|
#ifdef DEBUG
|
||||||
#endif
|
printf ("Seems to be splittable: %i >= 2^%i .. %i\n", remainder,
|
||||||
}
|
childIndex, (1 << childIndex));
|
||||||
}
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ptr = (void*)((uintptr_t)tag + sizeof( struct boundary_tag ) );
|
struct boundary_tag* new_tag = split_tag (tag);
|
||||||
|
|
||||||
|
(void)new_tag;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
#ifdef DEBUG
|
printf ("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n",
|
||||||
l_inuse += size;
|
tag->real_size, new_tag->real_size, new_tag->index);
|
||||||
printf("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 );
|
#endif
|
||||||
dump_array();
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
ptr = (void*)((uintptr_t)tag + sizeof (struct boundary_tag));
|
||||||
|
|
||||||
liballoc_unlock();
|
#ifdef DEBUG
|
||||||
return ptr;
|
l_inuse += size;
|
||||||
|
printf ("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024,
|
||||||
|
(int)l_allocated / 1024);
|
||||||
|
dump_array ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
liballoc_unlock ();
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free (void* ptr) {
|
||||||
|
int index;
|
||||||
|
struct boundary_tag* tag;
|
||||||
|
|
||||||
|
if (ptr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
liballoc_lock ();
|
||||||
|
|
||||||
|
tag = (struct boundary_tag*)((uintptr_t)ptr - sizeof (struct boundary_tag));
|
||||||
|
|
||||||
void free(void *ptr)
|
if (tag->magic != LIBALLOC_MAGIC) {
|
||||||
{
|
liballoc_unlock (); // release the lock
|
||||||
int index;
|
return;
|
||||||
struct boundary_tag *tag;
|
}
|
||||||
|
|
||||||
if ( ptr == NULL ) return;
|
#ifdef DEBUG
|
||||||
|
l_inuse -= tag->size;
|
||||||
|
printf (
|
||||||
|
"free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024);
|
||||||
|
#endif
|
||||||
|
|
||||||
liballoc_lock();
|
// MELT LEFT...
|
||||||
|
while ((tag->split_left != NULL) && (tag->split_left->index >= 0)) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf (
|
||||||
|
"Melting tag left into available memory. Left was %i, becomes %i (%i)\n",
|
||||||
|
tag->split_left->real_size, tag->split_left->real_size + tag->real_size,
|
||||||
|
tag->split_left->real_size);
|
||||||
|
#endif
|
||||||
|
tag = melt_left (tag);
|
||||||
|
remove_tag (tag);
|
||||||
|
}
|
||||||
|
|
||||||
tag = (struct boundary_tag*)((uintptr_t)ptr - sizeof( struct boundary_tag ));
|
// MELT RIGHT...
|
||||||
|
while ((tag->split_right != NULL) && (tag->split_right->index >= 0)) {
|
||||||
if ( tag->magic != LIBALLOC_MAGIC )
|
#ifdef DEBUG
|
||||||
{
|
printf (
|
||||||
liballoc_unlock(); // release the lock
|
"Melting tag right into available memory. This was was %i, becomes %i (%i)\n",
|
||||||
return;
|
tag->real_size, tag->split_right->real_size + tag->real_size,
|
||||||
}
|
tag->split_right->real_size);
|
||||||
|
#endif
|
||||||
|
tag = absorb_right (tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where is it going back to?
|
||||||
|
index = getexp (tag->real_size - sizeof (struct boundary_tag));
|
||||||
|
if (index < MINEXP)
|
||||||
|
index = MINEXP;
|
||||||
|
|
||||||
|
// A whole, empty block?
|
||||||
|
if ((tag->split_left == NULL) && (tag->split_right == NULL)) {
|
||||||
|
if (l_completePages[index] == MAXCOMPLETE) {
|
||||||
|
// Too many standing by to keep. Free this one.
|
||||||
|
unsigned int pages = tag->real_size / l_pageSize;
|
||||||
|
|
||||||
#ifdef DEBUG
|
if ((tag->real_size % l_pageSize) != 0)
|
||||||
l_inuse -= tag->size;
|
pages += 1;
|
||||||
printf("free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 );
|
if (pages < (unsigned int)l_pageCount)
|
||||||
#endif
|
pages = l_pageCount;
|
||||||
|
|
||||||
|
|
||||||
// MELT LEFT...
|
liballoc_free (tag, pages);
|
||||||
while ( (tag->split_left != NULL) && (tag->split_left->index >= 0) )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("Melting tag left into available memory. Left was %i, becomes %i (%i)\n", tag->split_left->real_size, tag->split_left->real_size + tag->real_size, tag->split_left->real_size );
|
|
||||||
#endif
|
|
||||||
tag = melt_left( tag );
|
|
||||||
remove_tag( tag );
|
|
||||||
}
|
|
||||||
|
|
||||||
// MELT RIGHT...
|
#ifdef DEBUG
|
||||||
while ( (tag->split_right != NULL) && (tag->split_right->index >= 0) )
|
l_allocated -= pages * l_pageSize;
|
||||||
{
|
printf ("Resource freeing %x of %i pages\n", tag, pages);
|
||||||
#ifdef DEBUG
|
dump_array ();
|
||||||
printf("Melting tag right into available memory. This was was %i, becomes %i (%i)\n", tag->real_size, tag->split_right->real_size + tag->real_size, tag->split_right->real_size );
|
#endif
|
||||||
#endif
|
|
||||||
tag = absorb_right( tag );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
liballoc_unlock ();
|
||||||
// Where is it going back to?
|
return;
|
||||||
index = getexp( tag->real_size - sizeof(struct boundary_tag) );
|
}
|
||||||
if ( index < MINEXP ) index = MINEXP;
|
|
||||||
|
|
||||||
// A whole, empty block?
|
|
||||||
if ( (tag->split_left == NULL) && (tag->split_right == NULL) )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( l_completePages[ index ] == MAXCOMPLETE )
|
l_completePages[index] += 1; // Increase the count of complete pages.
|
||||||
{
|
}
|
||||||
// Too many standing by to keep. Free this one.
|
|
||||||
unsigned int pages = tag->real_size / l_pageSize;
|
|
||||||
|
|
||||||
if ( (tag->real_size % l_pageSize) != 0 ) pages += 1;
|
// ..........
|
||||||
if ( pages < (unsigned int)l_pageCount ) pages = l_pageCount;
|
|
||||||
|
|
||||||
liballoc_free( tag, pages );
|
insert_tag (tag, index);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
l_allocated -= pages * l_pageSize;
|
printf (
|
||||||
printf("Resource freeing %x of %i pages\n", tag, pages );
|
"Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n",
|
||||||
dump_array();
|
tag->real_size, tag->size, index);
|
||||||
#endif
|
dump_array ();
|
||||||
|
#endif
|
||||||
|
|
||||||
liballoc_unlock();
|
liballoc_unlock ();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
l_completePages[ index ] += 1; // Increase the count of complete pages.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ..........
|
|
||||||
|
|
||||||
|
|
||||||
insert_tag( tag, index );
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n", tag->real_size, tag->size, index );
|
|
||||||
dump_array();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
liballoc_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* calloc (size_t nobj, size_t size) {
|
||||||
|
int real_size;
|
||||||
|
void* p;
|
||||||
|
|
||||||
|
real_size = nobj * size;
|
||||||
|
|
||||||
|
p = malloc (real_size);
|
||||||
|
|
||||||
void* calloc(size_t nobj, size_t size)
|
liballoc_memset (p, 0, real_size);
|
||||||
{
|
|
||||||
int real_size;
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
real_size = nobj * size;
|
return p;
|
||||||
|
|
||||||
p = malloc( real_size );
|
|
||||||
|
|
||||||
liballoc_memset( p, 0, real_size );
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* realloc (void* p, size_t size) {
|
||||||
|
void* ptr;
|
||||||
|
struct boundary_tag* tag;
|
||||||
|
int real_size;
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
free (p);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (p == NULL)
|
||||||
|
return malloc (size);
|
||||||
|
|
||||||
void* realloc(void *p, size_t size)
|
if (&liballoc_lock != NULL)
|
||||||
{
|
liballoc_lock (); // lockit
|
||||||
void *ptr;
|
tag = (struct boundary_tag*)((uintptr_t)p - sizeof (struct boundary_tag));
|
||||||
struct boundary_tag *tag;
|
real_size = tag->size;
|
||||||
int real_size;
|
if (&liballoc_unlock != NULL)
|
||||||
|
liballoc_unlock ();
|
||||||
if ( size == 0 )
|
|
||||||
{
|
|
||||||
free( p );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if ( p == NULL ) return malloc( size );
|
|
||||||
|
|
||||||
if ( &liballoc_lock != NULL ) liballoc_lock(); // lockit
|
if ((size_t)real_size > size)
|
||||||
tag = (struct boundary_tag*)((uintptr_t)p - sizeof( struct boundary_tag ));
|
real_size = size;
|
||||||
real_size = tag->size;
|
|
||||||
if ( &liballoc_unlock != NULL ) liballoc_unlock();
|
|
||||||
|
|
||||||
if ( (size_t)real_size > size ) real_size = size;
|
ptr = malloc (size);
|
||||||
|
liballoc_memcpy (ptr, p, real_size);
|
||||||
|
free (p);
|
||||||
|
|
||||||
ptr = malloc( size );
|
return ptr;
|
||||||
liballoc_memcpy( ptr, p, real_size );
|
|
||||||
free( p );
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,11 @@
|
|||||||
|
|
||||||
#ifndef _HAVE_SIZE_T
|
#ifndef _HAVE_SIZE_T
|
||||||
#define _HAVE_SIZE_T
|
#define _HAVE_SIZE_T
|
||||||
typedef unsigned int size_t;
|
typedef unsigned int size_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
#ifndef NULL
|
#define NULL 0
|
||||||
#define NULL 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -23,29 +22,24 @@ typedef unsigned int size_t;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** This is a boundary tag which is prepended to the
|
/** This is a boundary tag which is prepended to the
|
||||||
* page or section of a page which we have allocated. It is
|
* page or section of a page which we have allocated. It is
|
||||||
* used to identify valid memory blocks that the
|
* used to identify valid memory blocks that the
|
||||||
* application is trying to free.
|
* application is trying to free.
|
||||||
*/
|
*/
|
||||||
struct boundary_tag
|
struct boundary_tag {
|
||||||
{
|
unsigned int magic; //< It's a kind of ...
|
||||||
unsigned int magic; //< It's a kind of ...
|
unsigned int size; //< Requested size.
|
||||||
unsigned int size; //< Requested size.
|
unsigned int real_size; //< Actual size.
|
||||||
unsigned int real_size; //< Actual size.
|
int index; //< Location in the page table.
|
||||||
int index; //< Location in the page table.
|
|
||||||
|
|
||||||
struct boundary_tag *split_left; //< Linked-list info for broken pages.
|
struct boundary_tag* split_left; //< Linked-list info for broken pages.
|
||||||
struct boundary_tag *split_right; //< The same.
|
struct boundary_tag* split_right; //< The same.
|
||||||
|
|
||||||
struct boundary_tag *next; //< Linked list info.
|
struct boundary_tag* next; //< Linked list info.
|
||||||
struct boundary_tag *prev; //< Linked list info.
|
struct boundary_tag* prev; //< Linked list info.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** This function is supposed to lock the memory data structures. It
|
/** This function is supposed to lock the memory data structures. It
|
||||||
* could be as simple as disabling interrupts or acquiring a spinlock.
|
* could be as simple as disabling interrupts or acquiring a spinlock.
|
||||||
* It's up to you to decide.
|
* It's up to you to decide.
|
||||||
@@ -53,7 +47,7 @@ struct boundary_tag
|
|||||||
* \return 0 if the lock was acquired successfully. Anything else is
|
* \return 0 if the lock was acquired successfully. Anything else is
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
extern int liballoc_lock();
|
extern int liballoc_lock ();
|
||||||
|
|
||||||
/** This function unlocks what was previously locked by the liballoc_lock
|
/** This function unlocks what was previously locked by the liballoc_lock
|
||||||
* function. If it disabled interrupts, it enables interrupts. If it
|
* function. If it disabled interrupts, it enables interrupts. If it
|
||||||
@@ -61,7 +55,7 @@ extern int liballoc_lock();
|
|||||||
*
|
*
|
||||||
* \return 0 if the lock was successfully released.
|
* \return 0 if the lock was successfully released.
|
||||||
*/
|
*/
|
||||||
extern int liballoc_unlock();
|
extern int liballoc_unlock ();
|
||||||
|
|
||||||
/** This is the hook into the local system which allocates pages. It
|
/** This is the hook into the local system which allocates pages. It
|
||||||
* accepts an integer parameter which is the number of pages
|
* accepts an integer parameter which is the number of pages
|
||||||
@@ -70,7 +64,7 @@ extern int liballoc_unlock();
|
|||||||
* \return NULL if the pages were not allocated.
|
* \return NULL if the pages were not allocated.
|
||||||
* \return A pointer to the allocated memory.
|
* \return A pointer to the allocated memory.
|
||||||
*/
|
*/
|
||||||
extern void* liballoc_alloc(int);
|
extern void* liballoc_alloc (int);
|
||||||
|
|
||||||
/** This frees previously allocated memory. The void* parameter passed
|
/** This frees previously allocated memory. The void* parameter passed
|
||||||
* to the function is the exact same value returned from a previous
|
* to the function is the exact same value returned from a previous
|
||||||
@@ -80,20 +74,15 @@ extern void* liballoc_alloc(int);
|
|||||||
*
|
*
|
||||||
* \return 0 if the memory was successfully freed.
|
* \return 0 if the memory was successfully freed.
|
||||||
*/
|
*/
|
||||||
extern int liballoc_free(void*,int);
|
extern int liballoc_free (void*, int);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void *malloc(size_t); //< The standard function.
|
|
||||||
void *realloc(void *, size_t); //< The standard function.
|
|
||||||
void *calloc(size_t, size_t); //< The standard function.
|
|
||||||
void free(void *); //< The standard function.
|
|
||||||
|
|
||||||
|
void* malloc (size_t); //< The standard function.
|
||||||
|
void* realloc (void*, size_t); //< The standard function.
|
||||||
|
void* calloc (size_t, size_t); //< The standard function.
|
||||||
|
void free (void*); //< The standard function.
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +1,51 @@
|
|||||||
#include <libk/std.h>
|
|
||||||
#include <libk/bm.h>
|
|
||||||
#include <libk/string.h>
|
|
||||||
#include <libk/align.h>
|
#include <libk/align.h>
|
||||||
#include <sys/mm.h>
|
#include <libk/bm.h>
|
||||||
#include <sys/debug.h>
|
#include <libk/std.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <libk/string.h>
|
||||||
#include <mm/types.h>
|
|
||||||
#include <mm/pmm.h>
|
|
||||||
#include <limine/limine.h>
|
#include <limine/limine.h>
|
||||||
#include <limine/requests.h>
|
#include <limine/requests.h>
|
||||||
|
#include <mm/pmm.h>
|
||||||
|
#include <mm/types.h>
|
||||||
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
|
#include <sys/mm.h>
|
||||||
|
|
||||||
static struct pmm pmm;
|
static struct pmm pmm;
|
||||||
|
|
||||||
void pmm_init(void) {
|
void pmm_init (void) {
|
||||||
memset(&pmm, 0, sizeof(pmm));
|
memset (&pmm, 0, sizeof (pmm));
|
||||||
|
|
||||||
struct limine_memmap_response *memmap = limine_memmap_request.response;
|
struct limine_memmap_response* memmap = limine_memmap_request.response;
|
||||||
struct limine_hhdm_response *hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
size_t region = 0;
|
size_t region = 0;
|
||||||
for (size_t i = 0; i < memmap->entry_count; i++) {
|
for (size_t i = 0; i < memmap->entry_count; i++) {
|
||||||
struct limine_memmap_entry *entry = memmap->entries[i];
|
struct limine_memmap_entry* entry = memmap->entries[i];
|
||||||
static const char *entry_strings[] = {
|
static const char* entry_strings[] = {"usable", "reserved",
|
||||||
"usable", "reserved", "acpi reclaimable", "acpi nvs",
|
"acpi reclaimable", "acpi nvs", "bad memory", "bootloader reclaimable",
|
||||||
"bad memory", "bootloader reclaimable", "executable and modules",
|
"executable and modules", "framebuffer", "acpi tables"};
|
||||||
"framebuffer", "acpi tables"
|
|
||||||
};
|
|
||||||
|
|
||||||
DEBUG("memmap entry: %-25s %p (%zu bytes)\n", entry_strings[entry->type], entry->base, entry->length);
|
DEBUG ("memmap entry: %-25s %p (%zu bytes)\n", entry_strings[entry->type],
|
||||||
|
entry->base, entry->length);
|
||||||
|
|
||||||
if (entry->type == LIMINE_MEMMAP_USABLE && region < PMM_REGIONS_MAX) {
|
if (entry->type == LIMINE_MEMMAP_USABLE && region < PMM_REGIONS_MAX) {
|
||||||
struct pmm_region *pmm_region = &pmm.regions[region];
|
struct pmm_region* pmm_region = &pmm.regions[region];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to calculate sizes for the pmm region and the bitmap. The bitmap MUSTN'T include it's
|
* We need to calculate sizes for the pmm region and the bitmap. The bitmap MUSTN'T include it's
|
||||||
* own region within the bit range.
|
* own region within the bit range.
|
||||||
* */
|
* */
|
||||||
|
|
||||||
size_t size = align_down(entry->length, PAGE_SIZE);
|
size_t size = align_down (entry->length, PAGE_SIZE);
|
||||||
physaddr_t start = align_up(entry->base, PAGE_SIZE);
|
physaddr_t start = align_up (entry->base, PAGE_SIZE);
|
||||||
|
|
||||||
size_t max_pages = (size * 8) / (PAGE_SIZE * 8 + 1);
|
size_t max_pages = (size * 8) / (PAGE_SIZE * 8 + 1);
|
||||||
|
|
||||||
size_t bm_nbits = max_pages;
|
size_t bm_nbits = max_pages;
|
||||||
size_t bm_size = align_up(bm_nbits, 8) / 8;
|
size_t bm_size = align_up (bm_nbits, 8) / 8;
|
||||||
|
|
||||||
physaddr_t bm_base = start;
|
physaddr_t bm_base = start;
|
||||||
physaddr_t data_base = align_up(bm_base + bm_size, PAGE_SIZE);
|
physaddr_t data_base = align_up (bm_base + bm_size, PAGE_SIZE);
|
||||||
|
|
||||||
if (bm_base + bm_size >= start + size)
|
if (bm_base + bm_size >= start + size)
|
||||||
continue;
|
continue;
|
||||||
@@ -57,22 +56,22 @@ void pmm_init(void) {
|
|||||||
|
|
||||||
if (final_pages < max_pages) {
|
if (final_pages < max_pages) {
|
||||||
bm_nbits = final_pages;
|
bm_nbits = final_pages;
|
||||||
bm_size = align_up(bm_nbits, 8) / 8;
|
bm_size = align_up (bm_nbits, 8) / 8;
|
||||||
data_base = align_up(bm_base + bm_size, PAGE_SIZE);
|
data_base = align_up (bm_base + bm_size, PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t managed_size = final_pages * PAGE_SIZE;
|
size_t managed_size = final_pages * PAGE_SIZE;
|
||||||
|
|
||||||
uint8_t *bm_base1 = (uint8_t *)(bm_base + hhdm->offset);
|
uint8_t* bm_base1 = (uint8_t*)(bm_base + hhdm->offset);
|
||||||
|
|
||||||
/* Init the pm region. */
|
/* Init the pm region. */
|
||||||
pmm_region->lock = SPIN_LOCK_INIT;
|
pmm_region->lock = SPIN_LOCK_INIT;
|
||||||
pmm_region->membase = data_base;
|
pmm_region->membase = data_base;
|
||||||
pmm_region->size = managed_size;
|
pmm_region->size = managed_size;
|
||||||
bm_init(&pmm_region->bm, bm_base1, bm_nbits);
|
bm_init (&pmm_region->bm, bm_base1, bm_nbits);
|
||||||
bm_clear_region(&pmm_region->bm, 0, bm_nbits);
|
bm_clear_region (&pmm_region->bm, 0, bm_nbits);
|
||||||
pmm_region->flags |= PMM_REGION_ACTIVE; /* mark as active */
|
pmm_region->flags |= PMM_REGION_ACTIVE; /* mark as active */
|
||||||
|
|
||||||
region++;
|
region++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,9 +81,10 @@ void pmm_init(void) {
|
|||||||
* Find free space for a block range. For every bit of the bitmap, we test nblks bits forward.
|
* Find free space for a block range. For every bit of the bitmap, we test nblks bits forward.
|
||||||
* bm_test_region helps us out, because it automatically does range checks. See comments there.
|
* bm_test_region helps us out, because it automatically does range checks. See comments there.
|
||||||
*/
|
*/
|
||||||
static size_t pmm_find_free_space(struct pmm_region *pmm_region, size_t nblks) {
|
static size_t pmm_find_free_space (
|
||||||
|
struct pmm_region* pmm_region, size_t nblks) {
|
||||||
for (size_t bit = 0; bit < pmm_region->bm.nbits; bit++) {
|
for (size_t bit = 0; bit < pmm_region->bm.nbits; bit++) {
|
||||||
if (bm_test_region(&pmm_region->bm, bit, nblks)) {
|
if (bm_test_region (&pmm_region->bm, bit, nblks)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,56 +94,57 @@ static size_t pmm_find_free_space(struct pmm_region *pmm_region, size_t nblks) {
|
|||||||
return (size_t)-1;
|
return (size_t)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
physaddr_t pmm_alloc(size_t nblks) {
|
physaddr_t pmm_alloc (size_t nblks) {
|
||||||
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
|
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
|
||||||
struct pmm_region *pmm_region = &pmm.regions[region];
|
struct pmm_region* pmm_region = &pmm.regions[region];
|
||||||
|
|
||||||
/* Inactive region, so don't bother with it. */
|
/* Inactive region, so don't bother with it. */
|
||||||
if (!(pmm_region->flags & PMM_REGION_ACTIVE))
|
if (!(pmm_region->flags & PMM_REGION_ACTIVE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
spin_lock(&pmm_region->lock);
|
spin_lock (&pmm_region->lock);
|
||||||
|
|
||||||
/* Find starting bit of the free bit range */
|
/* Find starting bit of the free bit range */
|
||||||
size_t bit = pmm_find_free_space(pmm_region, nblks);
|
size_t bit = pmm_find_free_space (pmm_region, nblks);
|
||||||
|
|
||||||
/* Found a free range? */
|
/* Found a free range? */
|
||||||
if (bit != (size_t)-1) {
|
if (bit != (size_t)-1) {
|
||||||
/* Mark it */
|
/* Mark it */
|
||||||
bm_set_region(&pmm_region->bm, bit, nblks);
|
bm_set_region (&pmm_region->bm, bit, nblks);
|
||||||
spin_unlock(&pmm_region->lock);
|
spin_unlock (&pmm_region->lock);
|
||||||
|
|
||||||
return pmm_region->membase + bit * PAGE_SIZE;
|
return pmm_region->membase + bit * PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&pmm_region->lock);
|
spin_unlock (&pmm_region->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PMM_ALLOC_ERR;
|
return PMM_ALLOC_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pmm_free(physaddr_t p_addr, size_t nblks) {
|
void pmm_free (physaddr_t p_addr, size_t nblks) {
|
||||||
/* Round down to nearest page boundary */
|
/* Round down to nearest page boundary */
|
||||||
physaddr_t aligned_p_addr = align_down(p_addr, PAGE_SIZE);
|
physaddr_t aligned_p_addr = align_down (p_addr, PAGE_SIZE);
|
||||||
|
|
||||||
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
|
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
|
||||||
struct pmm_region *pmm_region = &pmm.regions[region];
|
struct pmm_region* pmm_region = &pmm.regions[region];
|
||||||
|
|
||||||
/* Inactive region, so don't bother with it. */
|
/* Inactive region, so don't bother with it. */
|
||||||
if (!(pmm_region->flags & PMM_REGION_ACTIVE))
|
if (!(pmm_region->flags & PMM_REGION_ACTIVE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If aligned_p_addr is within the range if this region, it belongs to it. */
|
/* If aligned_p_addr is within the range if this region, it belongs to it. */
|
||||||
if (aligned_p_addr >= pmm_region->membase && aligned_p_addr < pmm_region->size) {
|
if (aligned_p_addr >= pmm_region->membase &&
|
||||||
|
aligned_p_addr < pmm_region->size) {
|
||||||
physaddr_t addr = aligned_p_addr - pmm_region->membase;
|
physaddr_t addr = aligned_p_addr - pmm_region->membase;
|
||||||
|
|
||||||
size_t bit = div_align_up(addr, PAGE_SIZE);
|
size_t bit = div_align_up (addr, PAGE_SIZE);
|
||||||
|
|
||||||
spin_lock(&pmm_region->lock);
|
spin_lock (&pmm_region->lock);
|
||||||
|
|
||||||
bm_clear_region(&pmm_region->bm, bit, nblks);
|
|
||||||
|
|
||||||
spin_unlock(&pmm_region->lock);
|
bm_clear_region (&pmm_region->bm, bit, nblks);
|
||||||
|
|
||||||
|
spin_unlock (&pmm_region->lock);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
#ifndef _KERNEL_MM_PMM_H
|
#ifndef _KERNEL_MM_PMM_H
|
||||||
#define _KERNEL_MM_PMM_H
|
#define _KERNEL_MM_PMM_H
|
||||||
|
|
||||||
#include <libk/std.h>
|
|
||||||
#include <libk/bm.h>
|
#include <libk/bm.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <libk/std.h>
|
||||||
#include <mm/types.h>
|
#include <mm/types.h>
|
||||||
|
#include <sync/spin_lock.h>
|
||||||
|
|
||||||
#define PMM_ALLOC_ERR ((physaddr_t)-1)
|
#define PMM_ALLOC_ERR ((physaddr_t) - 1)
|
||||||
|
|
||||||
#define PMM_REGIONS_MAX 32
|
#define PMM_REGIONS_MAX 32
|
||||||
|
|
||||||
#define PMM_REGION_ACTIVE (1 << 0)
|
#define PMM_REGION_ACTIVE (1 << 0)
|
||||||
|
|
||||||
struct pmm_region {
|
struct pmm_region {
|
||||||
spin_lock_t lock;
|
spin_lock_t lock;
|
||||||
@@ -24,8 +24,8 @@ struct pmm {
|
|||||||
struct pmm_region regions[PMM_REGIONS_MAX];
|
struct pmm_region regions[PMM_REGIONS_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
void pmm_init(void);
|
void pmm_init (void);
|
||||||
physaddr_t pmm_alloc(size_t nblks);
|
physaddr_t pmm_alloc (size_t nblks);
|
||||||
void pmm_free(physaddr_t p_addr, size_t nblks);
|
void pmm_free (physaddr_t p_addr, size_t nblks);
|
||||||
|
|
||||||
#endif // _KERNEL_MM_PMM_H
|
#endif // _KERNEL_MM_PMM_H
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <sys/spin_lock.h>
|
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/spin_lock.h>
|
||||||
|
|
||||||
void spin_lock(spin_lock_t *sl) {
|
void spin_lock (spin_lock_t* sl) {
|
||||||
while (atomic_flag_test_and_set_explicit(sl, memory_order_acquire))
|
while (atomic_flag_test_and_set_explicit (sl, memory_order_acquire))
|
||||||
spin_lock_relax();
|
spin_lock_relax ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void spin_unlock(spin_lock_t *sl) {
|
void spin_unlock (spin_lock_t* sl) {
|
||||||
atomic_flag_clear_explicit(sl, memory_order_release);
|
atomic_flag_clear_explicit (sl, memory_order_release);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
#define SPIN_LOCK_INIT ATOMIC_FLAG_INIT
|
#define SPIN_LOCK_INIT ATOMIC_FLAG_INIT
|
||||||
|
|
||||||
typedef atomic_flag spin_lock_t;
|
typedef atomic_flag spin_lock_t;
|
||||||
|
|
||||||
void spin_lock(spin_lock_t *sl);
|
void spin_lock (spin_lock_t* sl);
|
||||||
void spin_unlock(spin_lock_t *sl);
|
void spin_unlock (spin_lock_t* sl);
|
||||||
|
|
||||||
#endif // _KERNEL_SYNC_SPIN_LOCK_H
|
#endif // _KERNEL_SYNC_SPIN_LOCK_H
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#ifndef _KERNEL_SYS_DEBUG_H
|
#ifndef _KERNEL_SYS_DEBUG_H
|
||||||
#define _KERNEL_SYS_DEBUG_H
|
#define _KERNEL_SYS_DEBUG_H
|
||||||
|
|
||||||
void debugprintf(const char *fmt, ...);
|
void debugprintf (const char* fmt, ...);
|
||||||
|
|
||||||
#define DEBUG(fmt, ...) do { \
|
#define DEBUG(fmt, ...) \
|
||||||
debugprintf("%s: " fmt, __func__, ##__VA_ARGS__); \
|
do { \
|
||||||
} while(0)
|
debugprintf ("%s: " fmt, __func__, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif // _KERNEL_SYS_DEBUG_H
|
#endif // _KERNEL_SYS_DEBUG_H
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define _KERNEL_SYS_MM_H
|
#define _KERNEL_SYS_MM_H
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
#include <amd64/mm.h>
|
#include <amd64/mm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _KERNEL_SYS_MM_H
|
#endif // _KERNEL_SYS_MM_H
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef _KERNEL_SYS_SPIN_LOCK_H
|
#ifndef _KERNEL_SYS_SPIN_LOCK_H
|
||||||
#define _KERNEL_SYS_SPIN_LOCK_H
|
#define _KERNEL_SYS_SPIN_LOCK_H
|
||||||
|
|
||||||
void spin_lock_relax(void);
|
void spin_lock_relax (void);
|
||||||
|
|
||||||
#endif // _KERNEL_SYS_SPIN_LOCK_H
|
#endif // _KERNEL_SYS_SPIN_LOCK_H
|
||||||
|
|||||||
@@ -1,49 +1,48 @@
|
|||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <sys/debug.h>
|
|
||||||
#include <mm/liballoc.h>
|
|
||||||
#include <limine/requests.h>
|
#include <limine/requests.h>
|
||||||
|
#include <mm/liballoc.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
#include <uacpi/kernel_api.h>
|
#include <uacpi/kernel_api.h>
|
||||||
#include <uacpi/status.h>
|
#include <uacpi/status.h>
|
||||||
|
|
||||||
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address) {
|
uacpi_status uacpi_kernel_get_rsdp (uacpi_phys_addr* out_rsdp_address) {
|
||||||
struct limine_hhdm_response *hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
struct limine_rsdp_response *rsdp = limine_rsdp_request.response;
|
struct limine_rsdp_response* rsdp = limine_rsdp_request.response;
|
||||||
|
|
||||||
*out_rsdp_address = (uacpi_phys_addr)((uintptr_t)rsdp->address - (uintptr_t)hhdm->offset);
|
*out_rsdp_address =
|
||||||
|
(uacpi_phys_addr)((uintptr_t)rsdp->address - (uintptr_t)hhdm->offset);
|
||||||
|
|
||||||
return UACPI_STATUS_OK;
|
return UACPI_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) {
|
void* uacpi_kernel_map (uacpi_phys_addr addr, uacpi_size len) {
|
||||||
(void)len;
|
(void)len;
|
||||||
struct limine_hhdm_response *hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
return (void *)((uintptr_t)hhdm->offset + (uintptr_t)addr);
|
return (void*)((uintptr_t)hhdm->offset + (uintptr_t)addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uacpi_kernel_unmap(void *addr, uacpi_size len) {
|
void uacpi_kernel_unmap (void* addr, uacpi_size len) { (void)addr, (void)len; }
|
||||||
(void)addr, (void)len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uacpi_kernel_log(uacpi_log_level level, const uacpi_char* msg) {
|
void uacpi_kernel_log (uacpi_log_level level, const uacpi_char* msg) {
|
||||||
const char *prefix = NULL;
|
const char* prefix = NULL;
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case UACPI_LOG_DEBUG:
|
case UACPI_LOG_DEBUG:
|
||||||
prefix = "Debug";
|
prefix = "Debug";
|
||||||
break;
|
break;
|
||||||
case UACPI_LOG_TRACE:
|
case UACPI_LOG_TRACE:
|
||||||
prefix = "Trace";
|
prefix = "Trace";
|
||||||
break;
|
break;
|
||||||
case UACPI_LOG_INFO:
|
case UACPI_LOG_INFO:
|
||||||
prefix = "Info";
|
prefix = "Info";
|
||||||
break;
|
break;
|
||||||
case UACPI_LOG_WARN:
|
case UACPI_LOG_WARN:
|
||||||
prefix = "Warning";
|
prefix = "Warning";
|
||||||
break;
|
break;
|
||||||
case UACPI_LOG_ERROR:
|
case UACPI_LOG_ERROR:
|
||||||
prefix = "Error";
|
prefix = "Error";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("%s %s", prefix, msg);
|
DEBUG ("%s %s", prefix, msg);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user