Formating tweaks overall

This commit is contained in:
Thomas Lovén 2022-01-18 13:42:01 +01:00
parent 8dd5e81399
commit ba85d9337d
30 changed files with 930 additions and 825 deletions

View File

@ -10,6 +10,6 @@
"**/*.d": true, "**/*.d": true,
}, },
"C_Cpp.default.includePath": ["src/kernel/include"], "C_Cpp.default.includePath": ["src/kernel/include", "sysroot/usr/include"],
"C_Cpp.default.cStandard": "c2x", "C_Cpp.default.cStandard": "c17",
} }

View File

@ -9,42 +9,51 @@ extern gfx_context kernel_fb;
int *position = (void *)0x20000; int *position = (void *)0x20000;
void thread1() { void thread1() {
int a = 1; int a = 1;
gfx_context *ctx = framebuffer_make_subcontext(&kernel_fb, 700, 300, 100, 100); gfx_context *ctx =
while(1) { framebuffer_make_subcontext(&kernel_fb, 700, 300, 100, 100);
putCharacter(term_fb, *position, *position, RGB(255,255,0), RGB(0,0,0), '0'+(a++%10)); while(1) {
flip(term_fb); putCharacter(term_fb,
draw_line(ctx, 0, 100, 50, ((a-1)%100), RGB(0,0,0)); *position, *position,
draw_line(ctx, 0, 100, 50, (a%100), RGB(255,0,0)); RGB(255,255,0), RGB(0,0,0),
flip(ctx); '0'+(a++%10)
sched_yield(); );
} flip(term_fb);
draw_line(ctx, 0, 100, 50, ((a-1)%100), RGB(0,0,0));
draw_line(ctx, 0, 100, 50, (a%100), RGB(255,0,0));
flip(ctx);
sched_yield();
}
} }
void thread2() { void thread2() {
int a = 0; int a = 0;
while(1) { while(1) {
putCharacter(term_fb, *position, *position, RGB(0,255,255), RGB(0,0,0), 'A'+(a++%10)); putCharacter(term_fb,
flip(term_fb); *position, *position,
sched_yield(); RGB(0,255,255), RGB(0,0,0),
} 'A'+(a++%10)
);
flip(term_fb);
sched_yield();
}
} }
void TEMP_test_scheduler() { void TEMP_test_scheduler() {
struct process *th1 = new_process(thread1); struct process *th1 = new_process(thread1);
scheduler_insert(th1); scheduler_insert(th1);
struct process *th2 = new_process(thread2); struct process *th2 = new_process(thread2);
scheduler_insert(th2); scheduler_insert(th2);
uint64_t p1 = pmm_alloc(); uint64_t p1 = pmm_alloc();
uint64_t p2 = pmm_alloc(); uint64_t p2 = pmm_alloc();
vmm_set_page(th1->P4, 0x20000, p1, PAGE_PRESENT); vmm_set_page(th1->P4, 0x20000, p1, PAGE_PRESENT);
vmm_set_page(th2->P4, 0x20000, p2, PAGE_PRESENT); vmm_set_page(th2->P4, 0x20000, p2, PAGE_PRESENT);
// Write different values into the position variable for the two processes // Write different values into the position variable for the two processes
int *a = P2V(p1); int *a = P2V(p1);
*a = 20; *a = 20;
a = P2V(p2); a = P2V(p2);
*a = 70; *a = 70;
} }

View File

@ -15,45 +15,46 @@ struct kernel_boot_data_st kernel_boot_data;
registers *kbd_handler(registers *r) registers *kbd_handler(registers *r)
{ {
while(inb(0x64) & 0x2); while(inb(0x64) & 0x2);
uint8_t scancode = inb(0x60); uint8_t scancode = inb(0x60);
debug("Keyboard: %x\n", scancode); debug("Keyboard: %x\n", scancode);
irq_ack(); irq_ack();
return r; return r;
} }
void kmain(uint64_t multiboot_magic, void *multiboot_data) { void kmain(uint64_t multiboot_magic, void *multiboot_data) {
musl_init(); musl_init();
debug_info("Started kernel\n"); debug_info("Started kernel\n");
multiboot_init(multiboot_magic, P2V(multiboot_data)); multiboot_init(multiboot_magic, P2V(multiboot_data));
debug_info("Kernel loaded with command line: \"%s\" by <%s>\n", debug_info("Kernel loaded with command line: \"%s\" by <%s>\n",
kernel_boot_data.commandline, kernel_boot_data.commandline,
kernel_boot_data.bootloader); kernel_boot_data.bootloader
);
early_cpu_init(); early_cpu_init();
debug_info("Set up boot CPU\n"); debug_info("Set up boot CPU\n");
memory_init(); memory_init();
debug_info("Set up memory management\n"); debug_info("Set up memory management\n");
terminal_init(); terminal_init();
debug_info("Set up debug terminal\n"); debug_info("Set up debug terminal\n");
cpu_init(); cpu_init();
__asm__("sti"); __asm__("sti");
debug_info("Boot complete\n"); debug_info("Boot complete\n");
bind_interrupt(IRQ_INTERRUPT(IRQ_PS2_KBD), kbd_handler); bind_interrupt(IRQ_INTERRUPT(IRQ_PS2_KBD), kbd_handler);
irq_unmask(IRQ_PS2_KBD); irq_unmask(IRQ_PS2_KBD);
TEMP_test_scheduler(); TEMP_test_scheduler();
start_scheduler(); start_scheduler();
PANIC("End of kernel function!"); PANIC("End of kernel function!");
debug_info("Broke out of panic"); debug_info("Broke out of panic");
for(;;); for(;;);
} }

View File

@ -8,106 +8,119 @@
// https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html // https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html
struct taglist { struct taglist {
uint32_t total_size; uint32_t total_size;
uint32_t reserved; uint32_t reserved;
}__attribute__((packed)); }__attribute__((packed));
struct tag { struct tag {
uint32_t type; uint32_t type;
uint32_t size; uint32_t size;
uint8_t data[]; uint8_t data[];
}__attribute__((packed)); }__attribute__((packed));
struct mmap_entry { struct mmap_entry {
uint64_t base; uint64_t base;
uint64_t len; uint64_t len;
uint32_t type; uint32_t type;
uint32_t reserved; uint32_t reserved;
}__attribute__((packed)); }__attribute__((packed));
struct mmap { struct mmap {
uint32_t entry_size; uint32_t entry_size;
uint32_t entry_version; uint32_t entry_version;
struct mmap_entry entries[]; struct mmap_entry entries[];
}__attribute__((packed)); }__attribute__((packed));
static int parse_multiboot2(struct taglist *tags) { static int parse_multiboot2(struct taglist *tags) {
struct mmap *mmap; struct mmap *mmap;
struct tag *tag = incptr(tags, sizeof(struct taglist)); struct tag *tag = incptr(tags, sizeof(struct taglist));
kernel_boot_data.mboot_tags = tag; kernel_boot_data.mboot_tags = tag;
kernel_boot_data.tags_length = tags->total_size; kernel_boot_data.tags_length = tags->total_size;
while(tag->type) { while(tag->type) {
switch(tag->type) { switch(tag->type) {
case MBOOT2_TAG_BOOTLOADER: case MBOOT2_TAG_BOOTLOADER:
kernel_boot_data.bootloader = (char *)tag->data; kernel_boot_data.bootloader = (char *)tag->data;
break; break;
case MBOOT2_TAG_CMDLINE: case MBOOT2_TAG_CMDLINE:
kernel_boot_data.commandline = (char *)tag->data; kernel_boot_data.commandline = (char *)tag->data;
break; break;
case MBOOT2_TAG_MMAP: case MBOOT2_TAG_MMAP:
mmap = kernel_boot_data.mmap = (void *)tag->data; mmap = kernel_boot_data.mmap = (void *)tag->data;
kernel_boot_data.mmap_len = (tag->size - 8)/mmap->entry_size; kernel_boot_data.mmap_len = (tag->size - 8)/mmap->entry_size;
kernel_boot_data.mmap_size = (tag->size - 8); kernel_boot_data.mmap_size = (tag->size - 8);
break; break;
case MBOOT2_TAG_FBINFO: case MBOOT2_TAG_FBINFO:
kernel_boot_data.fbinfo = (void *)tag->data; kernel_boot_data.fbinfo = (void *)tag->data;
break; break;
case MBOOT2_TAG_OLD_RSDP: case MBOOT2_TAG_OLD_RSDP:
case MBOOT2_TAG_NEW_RSDP: case MBOOT2_TAG_NEW_RSDP:
kernel_boot_data.rsdp = (void *)tag->data; kernel_boot_data.rsdp = (void *)tag->data;
break; break;
}
// Tags are 8 byte alligned, so make sure we look for the next one in the right place
int padded_size = tag->size + ((tag->size % 8)?(8-(tag->size%8)):0);
tag = incptr(tag, padded_size);
} }
return 0;
// Tags are 8 byte alligned, so make sure we look for the next one
// in the right place
int padded_size = tag->size + ((tag->size % 8)?(8-(tag->size%8)):0);
tag = incptr(tag, padded_size);
}
return 0;
} }
int multiboot_init(uint64_t magic, void *mboot_info) { int multiboot_init(uint64_t magic, void *mboot_info) {
if(magic == MBOOT2_REPLY) { if(magic == MBOOT2_REPLY) {
kernel_boot_data.multiboot_version = 2; kernel_boot_data.multiboot_version = 2;
parse_multiboot2(mboot_info); parse_multiboot2(mboot_info);
} else { } else {
return 1; return 1;
} }
return 0; return 0;
} }
int multiboot_get_memory_area(size_t index, uintptr_t *start, uintptr_t *end, uint32_t *type) { int multiboot_get_memory_area(
if(index >= kernel_boot_data.mmap_len) return 1; size_t index,
uintptr_t *start,
uintptr_t *end,
uint32_t *type
) {
if(index >= kernel_boot_data.mmap_len) return 1;
struct mmap *mmap = kernel_boot_data.mmap; struct mmap *mmap = kernel_boot_data.mmap;
struct mmap_entry *entry = mmap->entries; struct mmap_entry *entry = mmap->entries;
entry = incptr(entry, index*mmap->entry_size); entry = incptr(entry, index*mmap->entry_size);
*start = entry->base; *start = entry->base;
*end = entry->base + entry->len; *end = entry->base + entry->len;
*type = entry->type; *type = entry->type;
return 0; return 0;
} }
int multiboot_page_used(uintptr_t page) { int multiboot_page_used(uintptr_t page) {
#define within_page(st, l) (((uintptr_t)st + l) > page && (uintptr_t)st < (page + PAGE_SIZE)) #define within_page(st, l) (((uintptr_t)st + l) > page && \
(uintptr_t)st < (page + PAGE_SIZE))
size_t fb_size = 0; size_t fb_size = 0;
uintptr_t fb_start = 0; uintptr_t fb_start = 0;
if(kernel_boot_data.fbinfo) { if(kernel_boot_data.fbinfo) {
fb_start = kernel_boot_data.fbinfo->framebuffer_addr; fb_start = kernel_boot_data.fbinfo->framebuffer_addr;
fb_size = kernel_boot_data.fbinfo->framebuffer_pitch*(kernel_boot_data.fbinfo->framebuffer_height + 1); fb_size = kernel_boot_data.fbinfo->framebuffer_pitch *
} (kernel_boot_data.fbinfo->framebuffer_height + 1);
if( }
within_page(kernel_boot_data.mboot_tags, kernel_boot_data.tags_length) || if(
within_page(kernel_boot_data.bootloader, strlen(kernel_boot_data.bootloader)) || within_page(kernel_boot_data.mboot_tags,
within_page(kernel_boot_data.commandline, strlen(kernel_boot_data.commandline)) || kernel_boot_data.tags_length
within_page(kernel_boot_data.mmap, kernel_boot_data.mmap_size) || ) ||
within_page(fb_start, fb_size) || within_page(kernel_boot_data.bootloader,
0 strlen(kernel_boot_data.bootloader)
) { ) ||
return 1; within_page(kernel_boot_data.commandline,
} strlen(kernel_boot_data.commandline)
return 0; ) ||
within_page(kernel_boot_data.mmap, kernel_boot_data.mmap_size) ||
within_page(fb_start, fb_size) ||
0) {
return 1;
}
return 0;
} }

View File

@ -4,22 +4,23 @@
#include <string.h> #include <string.h>
#include <debug.h> #include <debug.h>
// ACPI Specification https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf // ACPI Specification:
// https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
struct rsdp { // 5.2.5.3 struct rsdp { // 5.2.5.3
char signature[8]; char signature[8];
uint8_t checksum; uint8_t checksum;
char OEMID[6]; char OEMID[6];
uint8_t revision; uint8_t revision;
uint32_t rsdt_p; uint32_t rsdt_p;
uint8_t _[14]; // Fields for revision >= 2 uint8_t _[14]; // Fields for revision >= 2
}__attribute__((packed)); }__attribute__((packed));
struct sdt { struct sdt {
char signature[4]; char signature[4];
uint32_t length; uint32_t length;
uint8_t _[28]; uint8_t _[28];
uint32_t data[]; uint32_t data[];
}__attribute__((packed)); }__attribute__((packed));
@ -29,83 +30,79 @@ struct sdt {
#define MADT_TYPE_ISO 2 #define MADT_TYPE_ISO 2
struct madt_field { struct madt_field {
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
union { union {
// Processor Local APIC (5.2.12.2) struct { // Processor Local APIC (5.2.12.2)
struct { uint8_t id;
uint8_t id; uint8_t apic;
uint8_t apic; uint32_t flags;
uint32_t flags; }__attribute__((packed)) lapic;
}__attribute__((packed)) lapic; struct { // I/O APIC (5.2.12.3)
// I/O APIC (5.2.12.3) uint8_t id;
struct { uint8_t reserved;
uint8_t id; uint32_t address;
uint8_t reserved; uint32_t base;
uint32_t address; }__attribute__((packed)) ioapic;
uint32_t base; struct { // Interrupt source override (5.2.12.5)
}__attribute__((packed)) ioapic; uint8_t bus;
// Interrupt source override (5.2.12.5) uint8_t source;
struct { uint32_t interrupt;
uint8_t bus; uint16_t flags;
uint8_t source; }__attribute__((packed)) iso;
uint32_t interrupt; };
uint16_t flags;
}__attribute__((packed)) iso;
};
}__attribute__((packed)); }__attribute__((packed));
struct madt_header { struct madt_header {
uint32_t controllerAddress; uint32_t controllerAddress;
uint32_t flags; uint32_t flags;
struct madt_field fields[]; struct madt_field fields[];
}__attribute__((packed)); }__attribute__((packed));
static void madt_parse(struct madt_header *madt, size_t length) static void madt_parse(struct madt_header *madt, size_t length)
{ {
int cpu_i=0; int cpu_i=0;
for( for(struct madt_field *f = madt->fields;
struct madt_field *f = madt->fields; (size_t)f <= (size_t)madt + length;
(size_t)f <= (size_t)madt + length; f = incptr(f, f->length)
f = incptr(f, f->length) ) {
) { switch(f->type) {
switch(f->type) { case MADT_TYPE_LAPIC: {
case MADT_TYPE_LAPIC: { struct cpu *cpu = P2V(pmm_alloc());
struct cpu *cpu = P2V(pmm_alloc()); cpus[cpu_i++] = cpu;
cpus[cpu_i++] = cpu; cpu->id = f->lapic.id;
cpu->id = f->lapic.id; cpu->apic_id = f->lapic.apic;
cpu->apic_id = f->lapic.apic; cpu->flags = f->lapic.flags;
cpu->flags = f->lapic.flags; break;
break; }
} case MADT_TYPE_IOAPIC: {
case MADT_TYPE_IOAPIC: { ioapic.id = f->ioapic.id;
ioapic.id = f->ioapic.id; ioapic.addr = f->ioapic.address;
ioapic.addr = f->ioapic.address; ioapic.base = f->ioapic.base;
ioapic.base = f->ioapic.base; break;
break; }
} case MADT_TYPE_ISO: {
case MADT_TYPE_ISO: { irq_redirects[f->iso.source] = f->iso.interrupt;
irq_redirects[f->iso.source] = f->iso.interrupt; break;
break; }
} default:
default:
}
} }
}
} }
void acpi_parse(void *_rsdp) { void acpi_parse(void *_rsdp) {
struct rsdp *rsdp = _rsdp; struct rsdp *rsdp = _rsdp;
struct sdt *rsdt = P2V(rsdp->rsdt_p); struct sdt *rsdt = P2V(rsdp->rsdt_p);
int rsdt_entries = (rsdt->length - sizeof(struct sdt))/sizeof(uint32_t); int rsdt_entries = (rsdt->length - sizeof(struct sdt))/sizeof(uint32_t);
for(int i = 0; i < rsdt_entries; i++) { for(int i = 0; i < rsdt_entries; i++) {
struct sdt *h = P2V(rsdt->data[i]); struct sdt *h = P2V(rsdt->data[i]);
if(h->length == 0) continue; if(h->length == 0) continue;
if(!strncmp(h->signature, "APIC", 4)) { // 5.2.12 if(!strncmp(h->signature, "APIC", 4)) { // 5.2.12
madt_parse(P2V(h->data), h->length - sizeof(struct sdt)); madt_parse(P2V(h->data), h->length - sizeof(struct sdt));
}
} }
}
} }

View File

@ -14,82 +14,90 @@
#define IOREDTBL(irq) (0x10 + (irq)*2) #define IOREDTBL(irq) (0x10 + (irq)*2)
union iored { union iored {
struct { struct {
uint8_t vector; uint8_t vector;
uint8_t flags; uint8_t flags;
uint8_t mask; uint8_t mask;
uint32_t reserved; uint32_t reserved;
uint8_t target; uint8_t target;
}__attribute__((packed)); }__attribute__((packed));
struct { struct {
uint32_t l; uint32_t l;
uint32_t h; uint32_t h;
}__attribute__((packed)); }__attribute__((packed));
uint64_t val; uint64_t val;
}; };
static uint32_t ioapic_read(int reg) { static uint32_t ioapic_read(int reg) {
uint32_t volatile *ioregsel = P2V(ioapic.addr); uint32_t volatile *ioregsel = P2V(ioapic.addr);
uint32_t volatile *iowin = P2V(ioapic.addr + 0x10); uint32_t volatile *iowin = P2V(ioapic.addr + 0x10);
*ioregsel = reg; *ioregsel = reg;
return *iowin; return *iowin;
} }
static void ioapic_write(int reg, uint32_t value) { static void ioapic_write(int reg, uint32_t value) {
uint32_t volatile *ioregsel = P2V(ioapic.addr); uint32_t volatile *ioregsel = P2V(ioapic.addr);
uint32_t volatile *iowin = P2V(ioapic.addr + 0x10); uint32_t volatile *iowin = P2V(ioapic.addr + 0x10);
*ioregsel = reg; *ioregsel = reg;
*iowin = value; *iowin = value;
} }
static uint64_t ioapic_read_redirection(int irq) { static uint64_t ioapic_read_redirection(int irq) {
union iored retval; union iored retval;
retval.l = ioapic_read(IOREDTBL(irq)); retval.l = ioapic_read(IOREDTBL(irq));
retval.h = ioapic_read(IOREDTBL(irq)+1); retval.h = ioapic_read(IOREDTBL(irq)+1);
return retval.val; return retval.val;
} }
static void ioapic_write_redirection(int irq, uint64_t val) { static void ioapic_write_redirection(int irq, uint64_t val) {
union iored value; union iored value;
value.val = val; value.val = val;
ioapic_write(IOREDTBL(irq), value.l); ioapic_write(IOREDTBL(irq), value.l);
ioapic_write(IOREDTBL(irq) + 1, value.h); ioapic_write(IOREDTBL(irq) + 1, value.h);
} }
void irq_ack() { void irq_ack() {
APIC_REG(APIC_EOI) = 0; APIC_REG(APIC_EOI) = 0;
} }
void irq_mask(int irq) { void irq_mask(int irq) {
union iored iored; union iored iored;
iored.val = ioapic_read_redirection(irq_redirects[irq]); iored.val = ioapic_read_redirection(irq_redirects[irq]);
iored.mask |= 0x1; iored.mask |= 0x1;
ioapic_write_redirection(irq_redirects[irq], iored.val); ioapic_write_redirection(irq_redirects[irq], iored.val);
} }
void irq_unmask(int irq) { void irq_unmask(int irq) {
union iored iored; union iored iored;
iored.val = ioapic_read_redirection(irq_redirects[irq]); iored.val = ioapic_read_redirection(irq_redirects[irq]);
iored.mask &= ~0x1; iored.mask &= ~0x1;
ioapic_write_redirection(irq_redirects[irq], iored.val); ioapic_write_redirection(irq_redirects[irq], iored.val);
} }
void ioapic_init() { void ioapic_init() {
// Map ioapic offset into kernel memory // Map ioapic offset into kernel memory
vmm_set_page(kernel_P4, (uintptr_t)P2V(ioapic.addr), ioapic.addr, PAGE_PRESENT | PAGE_WRITE | PAGE_GLOBAL); vmm_set_page(kernel_P4,
(uintptr_t)P2V(ioapic.addr),
ioapic.addr,
PAGE_PRESENT | PAGE_WRITE | PAGE_GLOBAL
);
union iored iored; union iored iored;
for(int i = 0; i < 24; i++) { for(int i = 0; i < 24; i++) {
iored.val = ioapic_read_redirection(i); iored.val = ioapic_read_redirection(i);
iored.vector = IRQ_BASE+i; iored.vector = IRQ_BASE+i;
iored.flags = 0x0; iored.flags = 0x0;
iored.mask |= 1; iored.mask |= 1;
iored.target = 0x0; iored.target = 0x0;
ioapic_write_redirection(i, iored.val); ioapic_write_redirection(i, iored.val);
} }
} }
void apic_init() { void apic_init() {
// Map apic offset into kernel memory // Map apic offset into kernel memory
vmm_set_page(kernel_P4, (uintptr_t)P2V(APIC_BASE), APIC_BASE, PAGE_PRESENT | PAGE_WRITE | PAGE_GLOBAL); vmm_set_page(kernel_P4,
(uintptr_t)P2V(APIC_BASE),
APIC_BASE,
PAGE_PRESENT | PAGE_WRITE | PAGE_GLOBAL
);
// Allow LAPIC to receive interrupts // Allow LAPIC to receive interrupts
APIC_REG(APIC_SPURIOUS) = APIC_REG(APIC_SPURIOUS) | 0x100 | IRQ_SPURIOUS; APIC_REG(APIC_SPURIOUS) = APIC_REG(APIC_SPURIOUS) | 0x100 | IRQ_SPURIOUS;
} }

View File

@ -4,24 +4,26 @@
struct cpu *cpus[16]; struct cpu *cpus[16];
struct ioapic ioapic = {0,0,0}; struct ioapic ioapic = {0,0,0};
uint8_t irq_redirects[MAX_IRQS] = \ uint8_t irq_redirects[MAX_IRQS] = {
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
};
#define PIC1_ADDR 0x20 #define PIC1_ADDR 0x20
#define PIC2_ADDR 0xA0 #define PIC2_ADDR 0xA0
static void pic_disable() { static void pic_disable() {
// Mask all interrupts // Mask all interrupts
outb(PIC1_ADDR | 1, 0xFF); outb(PIC1_ADDR | 1, 0xFF);
outb(PIC2_ADDR | 1, 0xFF); outb(PIC2_ADDR | 1, 0xFF);
} }
void early_cpu_init() { void early_cpu_init() {
interrupt_init(); interrupt_init();
} }
void cpu_init() { void cpu_init() {
acpi_parse(kernel_boot_data.rsdp); acpi_parse(kernel_boot_data.rsdp);
pic_disable(); pic_disable();
apic_init(); apic_init();
ioapic_init(); ioapic_init();
} }

View File

@ -6,18 +6,18 @@
#define GDT_LONG (1<<21) #define GDT_LONG (1<<21)
struct gdt { struct gdt {
uint32_t _; uint32_t _;
uint32_t flags; uint32_t flags;
}__attribute__((packed)); }__attribute__((packed));
struct gdtp { struct gdtp {
uint16_t len; uint16_t len;
struct gdt *gdt; struct gdt *gdt;
}__attribute__((packed)); }__attribute__((packed));
struct gdt BootGDT[] = { struct gdt BootGDT[] = {
{0, 0}, {0, 0},
{0, GDT_PRESENT | GDT_DPL(0) | GDT_CODE | GDT_LONG} {0, GDT_PRESENT | GDT_DPL(0) | GDT_CODE | GDT_LONG}
}; };
struct gdtp GDTp = {2*8-1, BootGDT}; struct gdtp GDTp = {2*8-1, BootGDT};

View File

@ -11,67 +11,70 @@
#define NUM_INTERRUPTS 256 #define NUM_INTERRUPTS 256
struct idt { struct idt {
uint16_t base_l; uint16_t base_l;
uint16_t cs; uint16_t cs;
uint8_t ist; uint8_t ist;
uint8_t flags; uint8_t flags;
uint16_t base_m; uint16_t base_m;
uint32_t base_h; uint32_t base_h;
uint32_t _; uint32_t _;
}__attribute__((packed)) idt[NUM_INTERRUPTS]; }__attribute__((packed)) idt[NUM_INTERRUPTS];
struct { struct {
uint16_t len; uint16_t len;
struct idt *addr; struct idt *addr;
}__attribute__((packed)) idtr; }__attribute__((packed)) idtr;
extern uintptr_t isr_table[]; extern uintptr_t isr_table[];
int_handler_t int_handlers[NUM_INTERRUPTS]; int_handler_t int_handlers[NUM_INTERRUPTS];
void interrupt_init() { void interrupt_init() {
memset(idt, 0, sizeof(idt)); memset(idt, 0, sizeof(idt));
for(int i=0; i < NUM_INTERRUPTS; i++) { for(int i=0; i < NUM_INTERRUPTS; i++) {
idt[i].base_l = isr_table[i] & 0xFFFF; idt[i].base_l = isr_table[i] & 0xFFFF;
idt[i].base_m = (isr_table[i] >> 16) & 0xFFFF; idt[i].base_m = (isr_table[i] >> 16) & 0xFFFF;
idt[i].base_h = (isr_table[i] >> 32) & 0xFFFFFFFF; idt[i].base_h = (isr_table[i] >> 32) & 0xFFFFFFFF;
idt[i].cs = 0x8; idt[i].cs = 0x8;
idt[i].ist = 0; idt[i].ist = 0;
idt[i].flags = IDT_PRESENT | IDT_DPL0 | IDT_INTERRUPT; idt[i].flags = IDT_PRESENT | IDT_DPL0 | IDT_INTERRUPT;
} }
idtr.addr = idt; idtr.addr = idt;
idtr.len = sizeof(idt)-1; idtr.len = sizeof(idt)-1;
load_idt(&idtr); // cpu/registers.S load_idt(&idtr); // cpu/registers.S
} }
int_handler_t bind_interrupt(uint32_t num, int_handler_t fn) { int_handler_t bind_interrupt(uint32_t num, int_handler_t fn) {
int_handler_t old = int_handlers[num]; int_handler_t old = int_handlers[num];
int_handlers[num] = fn; int_handlers[num] = fn;
return old; return old;
} }
registers *int_handler(registers *r) { registers *int_handler(registers *r) {
if(int_handlers[r->int_no]) if(int_handlers[r->int_no])
return int_handlers[r->int_no](r); return int_handlers[r->int_no](r);
if(r->int_no < IRQ_BASE) { if(r->int_no < IRQ_BASE) {
debug_error("UNHANDLED EXCEPTION\n"); debug_error("UNHANDLED EXCEPTION\n");
switch(r->int_no) { switch(r->int_no) {
case 14: case 14:
debug_error("Page fault\n"); debug_error("Page fault\n");
break; break;
case 6: case 6:
debug_error("Invalid opcode\n"); debug_error("Invalid opcode\n");
}
debug_error("Interrupt number: %d, Error code: %d\n", r->int_no, r->err_code);
PANIC("Unhandled interrupt\n");
} else if(r->int_no < IRQ_BASE + MAX_IRQS) {
debug_error("UNHANDLED IRQ\n");
debug_error("IRQ: %d", r->int_no - IRQ_BASE);
PANIC("Unhandled IRQ\n");
} else {
debug_error("UNKNOWN INTERRUPT\n");
debug_error("Interrupt number: %d\n", r->int_no);
PANIC("Unknown interrupt\n");
} }
return r; debug_error("Interrupt number: %d, Error code: %d\n",
r->int_no,
r->err_code
);
PANIC("Unhandled interrupt\n");
} else if(r->int_no < IRQ_BASE + MAX_IRQS) {
debug_error("UNHANDLED IRQ\n");
debug_error("IRQ: %d", r->int_no - IRQ_BASE);
PANIC("Unhandled IRQ\n");
} else {
debug_error("UNKNOWN INTERRUPT\n");
debug_error("Interrupt number: %d\n", r->int_no);
PANIC("Unknown interrupt\n");
}
return r;
} }

View File

@ -8,47 +8,63 @@ gfx_context *term_fb;
static int setup = 0; static int setup = 0;
void fbterm_movecursor(unsigned int cursor) { void fbterm_movecursor(unsigned int cursor) {
(void) cursor; (void) cursor;
} }
void fbterm_flush(struct vga_cell *buffer) { void fbterm_flush(struct vga_cell *buffer) {
if(!setup) return; if(!setup) return;
int i = 0; int i = 0;
for(int row = 0; row < VGA_ROWS; row++) { for(int row = 0; row < VGA_ROWS; row++) {
for(int col=0; col < VGA_COLS; col++) { for(int col=0; col < VGA_COLS; col++) {
putCharacter(term_fb, col*8, row*16, 0xebdbb2, 0x282828, (char)buffer[i++].c); putCharacter(term_fb,
} col*8, row*16,
0xebdbb2, 0x282828,
(char)buffer[i++].c
);
} }
flip(term_fb); }
flip(term_fb);
} }
void fbterm_init(struct fbinfo *fbinfo) { void fbterm_init(struct fbinfo *fbinfo) {
kernel_fb.width = fbinfo->framebuffer_width; kernel_fb = (gfx_context){
kernel_fb.height = fbinfo->framebuffer_height; .width = fbinfo->framebuffer_width,
kernel_fb.bpp = fbinfo->framebuffer_bpp/8; .height = fbinfo->framebuffer_height,
kernel_fb.pitch = fbinfo->framebuffer_pitch/kernel_fb.bpp; .bpp = fbinfo->framebuffer_bpp/8,
kernel_fb.addr = P2V(fbinfo->framebuffer_addr); .pitch = fbinfo->framebuffer_pitch/(fbinfo->framebuffer_bpp/8),
kernel_fb.size = fbinfo->framebuffer_pitch * (kernel_fb.height); .addr = P2V(fbinfo->framebuffer_addr),
kernel_fb.buffer = calloc(1, kernel_fb.size); .size = fbinfo->framebuffer_pitch * (fbinfo->framebuffer_height),
};
kernel_fb.buffer = calloc(1, kernel_fb.size);
for( for(uintptr_t p = (uintptr_t)kernel_fb.addr;
uintptr_t p = (uintptr_t)kernel_fb.addr; p < ((uintptr_t)kernel_fb.addr + kernel_fb.size);
p < ((uintptr_t)kernel_fb.addr + kernel_fb.size); p += PAGE_SIZE
p += PAGE_SIZE ) {
) { vmm_set_page(kernel_P4,
vmm_set_page(kernel_P4, p, V2P(p), PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT); p,
} V2P(p),
PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT
);
}
draw_rect(&kernel_fb, 20, 20, 8*VGA_COLS+8, 16*VGA_ROWS+8, RGB(255, 0, 0)); draw_rect(&kernel_fb,
flip(&kernel_fb); 20, 20,
term_fb = framebuffer_make_subcontext(&kernel_fb, 24, 24, 8*VGA_COLS, 16*VGA_ROWS); 8*VGA_COLS+8, 16*VGA_ROWS+8,
flip(term_fb); RGB(255, 0, 0)
setup = 1; );
flip(&kernel_fb);
term_fb = framebuffer_make_subcontext(&kernel_fb,
24, 24,
8*VGA_COLS, 16*VGA_ROWS
);
flip(term_fb);
setup = 1;
draw_line(&kernel_fb, 750, 850, 120, 120, RGB(255,0,0)); draw_line(&kernel_fb, 750, 850, 120, 120, RGB(255,0,0));
draw_line(&kernel_fb, 750, 750, 120, 220, RGB(0,255,0)); draw_line(&kernel_fb, 750, 750, 120, 220, RGB(0,255,0));
draw_line(&kernel_fb, 750, 850, 120, 220, RGB(0,0,255)); draw_line(&kernel_fb, 750, 850, 120, 220, RGB(0,0,255));
draw_line(&kernel_fb, 750, 800, 120, 220, RGB(255,0,255)); draw_line(&kernel_fb, 750, 800, 120, 220, RGB(255,0,255));
draw_line(&kernel_fb, 750, 850, 120, 170, RGB(255,255,0)); draw_line(&kernel_fb, 750, 850, 120, 170, RGB(255,255,0));
flip(&kernel_fb); flip(&kernel_fb);
} }

View File

@ -20,86 +20,91 @@ uint8_t format = 0x7;
static int terminal_type; static int terminal_type;
static void scroll() { static void scroll() {
while(cursor >= VGA_SIZE) { while(cursor >= VGA_SIZE) {
memmove(buffer, &buffer[VGA_POS(1,0)], VGA_COLS*(VGA_ROWS-1)*sizeof(struct vga_cell)); memmove(buffer,
memset(&buffer[VGA_POS(VGA_ROWS-1, 0)], 0, VGA_COLS*sizeof(struct vga_cell)); &buffer[VGA_POS(1,0)],
cursor -= VGA_COLS; VGA_COLS*(VGA_ROWS-1)*sizeof(struct vga_cell)
} );
memset(&buffer[VGA_POS(VGA_ROWS-1, 0)],
0,
VGA_COLS*sizeof(struct vga_cell)
);
cursor -= VGA_COLS;
}
} }
static void terminal_write(char c) { static void terminal_write(char c) {
int doflush = 0; int doflush = 0;
switch(c) { switch(c) {
case '\n': case '\n':
cursor += VGA_COLS - VGA_COL(cursor); cursor += VGA_COLS - VGA_COL(cursor);
doflush = 1; doflush = 1;
break; break;
default: default:
buffer[cursor++] = (struct vga_cell){.c = c, .f = format}; buffer[cursor++] = (struct vga_cell){.c = c, .f = format};
} }
scroll(); scroll();
switch(terminal_type) { switch(terminal_type) {
case FRAMEBUFFER: case FRAMEBUFFER:
if(doflush) if(doflush)
fbterm_flush(buffer); fbterm_flush(buffer);
fbterm_movecursor(cursor); fbterm_movecursor(cursor);
break; break;
case EGA_TEXT: case EGA_TEXT:
if(doflush) if(doflush)
vga_flush(buffer); vga_flush(buffer);
vga_movecursor(cursor); vga_movecursor(cursor);
break; break;
} }
} }
static void terminal_putsn(char *s, size_t n) { static void terminal_putsn(char *s, size_t n) {
while(n--) while(n--)
terminal_write(*s++); terminal_write(*s++);
} }
long k_ioctl(long fd, long cmd, long arg3, long, long, long) { long k_ioctl(long fd, long cmd, long arg3, long, long, long) {
if(fd == 1 && cmd == 0x5413) { if(fd == 1 && cmd == 0x5413) {
struct { struct {
unsigned short ws_row; unsigned short ws_row;
unsigned short ws_col; unsigned short ws_col;
unsigned short ws_xp; unsigned short ws_xp;
unsigned short ws_yp; unsigned short ws_yp;
} *wsz = (void *)arg3; } *wsz = (void *)arg3;
wsz->ws_row = 24; wsz->ws_row = 24;
wsz->ws_col = 80; wsz->ws_col = 80;
return 0; return 0;
} }
long retval = -1; long retval = -1;
PANIC("Unknown IOCTL request: fd: %d, command: %x\n", fd, cmd); PANIC("Unknown IOCTL request: fd: %d, command: %x\n", fd, cmd);
return retval; return retval;
} }
long k_writev(long fd, long iov, long iovcnt, long, long, long) { long k_writev(long fd, long iov, long iovcnt, long, long, long) {
if(fd == 1) if(fd == 1) {
{ size_t len = 0;
size_t len = 0; struct iovec *v = (void *) iov;
struct iovec *v = (void *) iov; for(int i = 0; i < iovcnt; i++) {
for(int i = 0; i < iovcnt; i++) { terminal_putsn(v[i].iov_base, v[i].iov_len);
terminal_putsn(v[i].iov_base, v[i].iov_len); len += v[i].iov_len;
len += v[i].iov_len;
}
return len;
} }
long retval = 0; return len;
PANIC("Unknown writev request: fd: %d\n", fd); }
return retval; long retval = 0;
PANIC("Unknown writev request: fd: %d\n", fd);
return retval;
} }
void terminal_init() { void terminal_init() {
struct fbinfo *fbinfo = kernel_boot_data.fbinfo; struct fbinfo *fbinfo = kernel_boot_data.fbinfo;
terminal_type = fbinfo->framebuffer_type; terminal_type = fbinfo->framebuffer_type;
switch(terminal_type) { switch(terminal_type) {
case FRAMEBUFFER: case FRAMEBUFFER:
fbterm_init(fbinfo); fbterm_init(fbinfo);
break; break;
case EGA_TEXT: case EGA_TEXT:
vga_init(fbinfo); vga_init(fbinfo);
break; break;
} }
} }

View File

@ -16,21 +16,21 @@ static void *vidmem;
static int setup = 0; static int setup = 0;
void vga_init(struct fbinfo *fbinfo) { void vga_init(struct fbinfo *fbinfo) {
(void) fbinfo; (void) fbinfo;
vidmem = VGA_MEMORY; vidmem = VGA_MEMORY;
memset(vidmem, 0, VGA_SIZE*sizeof(struct vga_cell)); memset(vidmem, 0, VGA_SIZE*sizeof(struct vga_cell));
setup = 1; setup = 1;
} }
void vga_movecursor(unsigned int cursor) { void vga_movecursor(unsigned int cursor) {
if(!setup) return; if(!setup) return;
outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_LOW); outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_LOW);
outb(VGA_DATA_PORT, (uint8_t)(cursor & 0xFF)); outb(VGA_DATA_PORT, (uint8_t)(cursor & 0xFF));
outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_HIGH); outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_HIGH);
outb(VGA_DATA_PORT, (uint8_t)((cursor >> 8) & 0xFF)); outb(VGA_DATA_PORT, (uint8_t)((cursor >> 8) & 0xFF));
} }
void vga_flush(struct vga_cell *buffer) { void vga_flush(struct vga_cell *buffer) {
if(!setup) return; if(!setup) return;
memcpy(vidmem, buffer, VGA_SIZE*2); memcpy(vidmem, buffer, VGA_SIZE*2);
} }

View File

@ -13,43 +13,43 @@
#define IRQ_SPURIOUS 0xFF #define IRQ_SPURIOUS 0xFF
typedef struct { typedef struct {
uint64_t rax; uint64_t rax;
uint64_t rbx; uint64_t rbx;
uint64_t rcx; uint64_t rcx;
uint64_t rdx; uint64_t rdx;
uint64_t rsi; uint64_t rsi;
uint64_t rdi; uint64_t rdi;
uint64_t rbp; uint64_t rbp;
uint64_t r8; uint64_t r8;
uint64_t r9; uint64_t r9;
uint64_t r10; uint64_t r10;
uint64_t r11; uint64_t r11;
uint64_t r12; uint64_t r12;
uint64_t r13; uint64_t r13;
uint64_t r14; uint64_t r14;
uint64_t r15; uint64_t r15;
uint64_t int_no; uint64_t int_no;
uint64_t err_code; uint64_t err_code;
uint64_t rip; uint64_t rip;
uint64_t cs; uint64_t cs;
uint64_t rflags; uint64_t rflags;
uint64_t rsp; uint64_t rsp;
uint64_t ss; uint64_t ss;
} registers; } registers;
typedef registers *(*int_handler_t)(registers *); typedef registers *(*int_handler_t)(registers *);
struct cpu { struct cpu {
uint8_t id; uint8_t id;
uint8_t apic_id; uint8_t apic_id;
uint32_t flags; uint32_t flags;
}; };
struct ioapic { struct ioapic {
uint8_t id; uint8_t id;
uint32_t addr; uint32_t addr;
uint32_t base; uint32_t base;
}; };
extern struct cpu *cpus[MAX_CPUS]; extern struct cpu *cpus[MAX_CPUS];

View File

@ -26,12 +26,12 @@
#define PANIC(...) \ #define PANIC(...) \
do { \ do { \
debug("\n\nKERNEL PANIC!\n%s:%d\n", __FILE__, __LINE__); \ debug("\n\nKERNEL PANIC!\n%s:%d\n", __FILE__, __LINE__); \
debug(__VA_ARGS__); \ debug(__VA_ARGS__); \
debug("\n"); \ debug("\n"); \
volatile int _override = 0; \ volatile int _override = 0; \
while(1) { \ while(1) { \
__asm__("panic_breakpoint_" S__LINE__ ":"); \ __asm__("panic_breakpoint_" S__LINE__ ":"); \
if(_override) break; \ if(_override) break; \
} \ } \
}while(0) }while(0)

View File

@ -12,40 +12,40 @@
#define ENTRIES_PER_PT 512 #define ENTRIES_PER_PT 512
#ifdef __ASSEMBLER__ #ifdef __ASSEMBLER__
#define V2P(a) ((a) - KERNEL_OFFSET) #define V2P(a) ((a) - KERNEL_OFFSET)
#define P2V(a) ((a) + KERNEL_OFFSET) #define P2V(a) ((a) + KERNEL_OFFSET)
#else #else
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#define V2P(a) ((uintptr_t)(a) &~KERNEL_OFFSET) #define V2P(a) ((uintptr_t)(a) &~KERNEL_OFFSET)
#define P2V(a) ((void *)((uintptr_t)(a) | KERNEL_OFFSET)) #define P2V(a) ((void *)((uintptr_t)(a) | KERNEL_OFFSET))
#define incptr(p, n) ((void *)(((uintptr_t)(p)) + (n))) #define incptr(p, n) ((void *)(((uintptr_t)(p)) + (n)))
#define P1_OFFSET(a) (((a)>>12) & 0x1FF) #define P1_OFFSET(a) (((a)>>12) & 0x1FF)
#define P2_OFFSET(a) (((a)>>21) & 0x1FF) #define P2_OFFSET(a) (((a)>>21) & 0x1FF)
#define P3_OFFSET(a) (((a)>>30) & 0x1FF) #define P3_OFFSET(a) (((a)>>30) & 0x1FF)
#define P4_OFFSET(a) (((a)>>39) & 0x1FF) #define P4_OFFSET(a) (((a)>>39) & 0x1FF)
// memory/memory.c // memory/memory.c
void memory_init(); void memory_init();
extern uint64_t kernel_P4; extern uint64_t kernel_P4;
// memory/vmm.c // memory/vmm.c
uint64_t new_P4(); uint64_t new_P4();
uint64_t vmm_get_page(uint64_t P4, uint64_t addr); uint64_t vmm_get_page(uint64_t P4, uint64_t addr);
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags); int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags);
void vmm_clear_page(uint64_t P4, uint64_t addr, int free); void vmm_clear_page(uint64_t P4, uint64_t addr, int free);
// memory/pmm.c // memory/pmm.c
void pmm_free(uint64_t page); void pmm_free(uint64_t page);
uint64_t pmm_alloc(); uint64_t pmm_alloc();
uint64_t pmm_calloc(); uint64_t pmm_calloc();
// Link.ld // Link.ld
extern int kernel_start, kernel_end; extern int kernel_start, kernel_end;
// boot/boot_PT.s // boot/boot_PT.s
extern uint64_t BootP4; extern uint64_t BootP4;
#endif #endif

View File

@ -18,27 +18,27 @@
#include <stdint.h> #include <stdint.h>
struct fbinfo { struct fbinfo {
uint64_t framebuffer_addr; uint64_t framebuffer_addr;
uint32_t framebuffer_pitch; uint32_t framebuffer_pitch;
uint32_t framebuffer_width; uint32_t framebuffer_width;
uint32_t framebuffer_height; uint32_t framebuffer_height;
uint8_t framebuffer_bpp; uint8_t framebuffer_bpp;
uint8_t framebuffer_type; uint8_t framebuffer_type;
uint8_t reserved; uint8_t reserved;
uint8_t color_info[]; uint8_t color_info[];
}__attribute__((packed)); }__attribute__((packed));
struct kernel_boot_data_st { struct kernel_boot_data_st {
int multiboot_version; int multiboot_version;
void *mboot_tags; void *mboot_tags;
size_t tags_length; size_t tags_length;
char *bootloader; char *bootloader;
char *commandline; char *commandline;
size_t mmap_size; size_t mmap_size;
unsigned int mmap_len; unsigned int mmap_len;
void *mmap; void *mmap;
struct fbinfo *fbinfo; struct fbinfo *fbinfo;
void *rsdp; void *rsdp;
}; };
#define MMAP_FREE 1 #define MMAP_FREE 1

View File

@ -26,23 +26,23 @@ long k_sched_yield(long, long, long, long, long, long);
struct __locale_struct { struct __locale_struct {
const struct __locale_map *cat[6]; const struct __locale_map *cat[6];
}; };
struct tls_module { struct tls_module {
struct tls_module *next; struct tls_module *next;
void *image; void *image;
size_t len, size, align, offset; size_t len, size, align, offset;
}; };
struct __libc { struct __libc {
char can_do_threads; char can_do_threads;
char threaded; char threaded;
char secure; char secure;
volatile signed char need_locks; volatile signed char need_locks;
int threads_minus_1; int threads_minus_1;
size_t *auxv; size_t *auxv;
struct tls_module *tls_head; struct tls_module *tls_head;
size_t tls_size, tls_align, tls_cnt; size_t tls_size, tls_align, tls_cnt;
size_t page_size; size_t page_size;
struct __locale_struct global_locale; struct __locale_struct global_locale;
}; };
extern struct __libc __libc; extern struct __libc __libc;

View File

@ -2,13 +2,13 @@
#include <stdint.h> #include <stdint.h>
static __inline void _outb(uint16_t port, uint8_t value) { static __inline void _outb(uint16_t port, uint8_t value) {
__asm__ volatile("outb %1, %0" : : "dN" (port), "a" (value)); __asm__ volatile("outb %1, %0" : : "dN" (port), "a" (value));
} }
static __inline uint8_t _inb(uint16_t port) { static __inline uint8_t _inb(uint16_t port) {
uint8_t ret; uint8_t ret;
__asm__ volatile("inb %1, %0" : "=a" (ret) : "dN" (port)); __asm__ volatile("inb %1, %0" : "=a" (ret) : "dN" (port));
return ret; return ret;
} }
#define outb _outb #define outb _outb

View File

@ -2,12 +2,12 @@
#include <stdint.h> #include <stdint.h>
struct process { struct process {
uint64_t pid; uint64_t pid;
void *stack_ptr; void *stack_ptr;
uint64_t state; uint64_t state;
uint64_t P4; uint64_t P4;
struct process *q_next; struct process *q_next;
uint8_t stack[]; uint8_t stack[];
}; };
// proc/process.c // proc/process.c

View File

@ -8,8 +8,8 @@
#define VGA_MEMORY P2V(0xB8000) #define VGA_MEMORY P2V(0xB8000)
struct vga_cell { struct vga_cell {
uint8_t c; uint8_t c;
uint8_t f; uint8_t f;
}__attribute__((packed)); }__attribute__((packed));

View File

@ -2,85 +2,89 @@
#include <debug.h> #include <debug.h>
syscall_handler syscall_handlers[440] = { syscall_handler syscall_handlers[440] = {
[SYSCALL_BRK] = k_brk, [SYSCALL_BRK] = k_brk,
[SYSCALL_IOCTL] = k_ioctl, [SYSCALL_IOCTL] = k_ioctl,
[SYSCALL_WRITEV] = k_writev, [SYSCALL_WRITEV] = k_writev,
[SYSCALL_SCHED_YIELD] = k_sched_yield, [SYSCALL_SCHED_YIELD] = k_sched_yield,
[SYSCALL_MMAP] = k_mmap, [SYSCALL_MMAP] = k_mmap,
}; };
syscall_handler set_syscall_handler(long num, syscall_handler handler) { syscall_handler set_syscall_handler(long num, syscall_handler handler) {
syscall_handler old = syscall_handlers[num]; syscall_handler old = syscall_handlers[num];
syscall_handlers[num] = handler; syscall_handlers[num] = handler;
return old; return old;
} }
long syscall0(long num) { long syscall0(long num) {
long retval = 0; long retval = 0;
if(syscall_handlers[num]) if(syscall_handlers[num])
retval = syscall_handlers[num](0, 0, 0, 0, 0, 0); retval = syscall_handlers[num](0, 0, 0, 0, 0, 0);
else else
PANIC("Unknown syscall: %d()\n", num); PANIC("Unknown syscall: %d()\n", num);
return retval; return retval;
} }
long syscall1(long num, long a1) { long syscall1(long num, long a1) {
long retval = 0; long retval = 0;
if(syscall_handlers[num]) if(syscall_handlers[num])
retval = syscall_handlers[num](a1, 0, 0, 0, 0, 0); retval = syscall_handlers[num](a1, 0, 0, 0, 0, 0);
else else
PANIC("Unknown syscall: %d(%x)\n", num, a1); PANIC("Unknown syscall: %d(%x)\n", num, a1);
return retval; return retval;
} }
long syscall2(long num, long a1, long a2) { long syscall2(long num, long a1, long a2) {
long retval = 0; long retval = 0;
if(syscall_handlers[num]) if(syscall_handlers[num])
retval = syscall_handlers[num](a1, a2, 0, 0, 0, 0); retval = syscall_handlers[num](a1, a2, 0, 0, 0, 0);
else else
PANIC("Unknown syscall: %d(%x, %x)\n", num, a1, a2); PANIC("Unknown syscall: %d(%x, %x)\n", num, a1, a2);
return retval; return retval;
} }
long syscall3(long num, long a1, long a2, long a3) { long syscall3(long num, long a1, long a2, long a3) {
long retval = 0; long retval = 0;
if(syscall_handlers[num]) if(syscall_handlers[num])
retval = syscall_handlers[num](a1, a2, a3, 0, 0, 0); retval = syscall_handlers[num](a1, a2, a3, 0, 0, 0);
else else
PANIC("Unknown syscall: %d(%x, %x, %x)\n", num, a1, a2, a3); PANIC("Unknown syscall: %d(%x, %x, %x)\n", num, a1, a2, a3);
return retval; return retval;
} }
long syscall4(long num, long a1, long a2, long a3, long a4) { long syscall4(long num, long a1, long a2, long a3, long a4) {
long retval = 0; long retval = 0;
if(syscall_handlers[num]) if(syscall_handlers[num])
retval = syscall_handlers[num](a1, a2, a3, a4, 0, 0); retval = syscall_handlers[num](a1, a2, a3, a4, 0, 0);
else else
PANIC("Unknown syscall: %d(%x, %x, %x, %x)\n", num, a1, a2, a3, a4); PANIC("Unknown syscall: %d(%x, %x, %x, %x)\n", num, a1, a2, a3, a4);
return retval; return retval;
} }
long syscall5(long num, long a1, long a2, long a3, long a4, long a5) { long syscall5(long num, long a1, long a2, long a3, long a4, long a5) {
long retval = 0; long retval = 0;
if(syscall_handlers[num]) if(syscall_handlers[num])
retval = syscall_handlers[num](a1, a2, a3, a4, a5, 0); retval = syscall_handlers[num](a1, a2, a3, a4, a5, 0);
else else
PANIC("Unknown syscall: %d(%x, %x, %x, %x, %x)\n", num, a1, a2, a3, a4, a5); PANIC("Unknown syscall: %d(%x, %x, %x, %x, %x)\n",
return retval; num, a1, a2, a3, a4, a5
);
return retval;
} }
long syscall6(long num, long a1, long a2, long a3, long a4, long a5, long a6) { long syscall6(long num, long a1, long a2, long a3, long a4, long a5, long a6) {
long retval = 0; long retval = 0;
if(syscall_handlers[num]) if(syscall_handlers[num])
retval = syscall_handlers[num](a1, a2, a3, a4, a5, a6); retval = syscall_handlers[num](a1, a2, a3, a4, a5, a6);
else else
PANIC("Unknown syscall: %d(%x, %x, %x, %x, %x, %x)\n", num, a1, a2, a3, a4, a5, a6); PANIC("Unknown syscall: %d(%x, %x, %x, %x, %x, %x)\n",
return retval; num, a1, a2, a3, a4, a5, a6
);
return retval;
} }
size_t auxv[] = {0}; size_t auxv[] = {0};
void musl_init() { void musl_init() {
__libc.auxv = auxv; __libc.auxv = auxv;
} }

View File

@ -5,27 +5,42 @@ static long _brk = KERNEL_BRK0;
static long _mmap = KERNEL_MMAP; static long _mmap = KERNEL_MMAP;
long k_brk(long brk, long, long, long, long, long) { long k_brk(long brk, long, long, long, long, long) {
if(brk) { if(brk) {
while(_brk < brk) { while(_brk < brk) {
vmm_set_page(kernel_P4, _brk, pmm_alloc(), PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT); vmm_set_page(kernel_P4,
_brk += PAGE_SIZE; _brk,
} pmm_alloc(),
PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT
);
_brk += PAGE_SIZE;
} }
return _brk; }
return _brk;
} }
long k_mmap(long addr, long length, long prot, long flags, long fd, long offset) { long k_mmap(
(void)addr; long addr,
(void)prot; long length,
(void)flags; long prot,
(void)offset; long flags,
if(fd != -1) long fd,
PANIC("Unknown mmap request\n"); long offset
long retval = _mmap; ) {
while(length > 0) { (void)addr;
vmm_set_page(kernel_P4, _mmap, pmm_alloc(), PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT); (void)prot;
_mmap += PAGE_SIZE; (void)flags;
length -= PAGE_SIZE; (void)offset;
}
return retval; if(fd != -1)
PANIC("Unknown mmap request\n");
long retval = _mmap;
while(length > 0) {
vmm_set_page(kernel_P4,
_mmap, pmm_alloc(),
PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT
);
_mmap += PAGE_SIZE;
length -= PAGE_SIZE;
}
return retval;
} }

View File

@ -7,27 +7,27 @@
uint64_t kernel_P4; uint64_t kernel_P4;
void memory_init() { void memory_init() {
kernel_P4 = (uint64_t)&BootP4; kernel_P4 = (uint64_t)&BootP4;
uint64_t start, end; uint64_t start, end;
uint32_t type, i = 0; uint32_t type, i = 0;
while(!multiboot_get_memory_area(i++, &start, &end, &type)) { while(!multiboot_get_memory_area(i++, &start, &end, &type)) {
for(uint64_t p = start; p < end; p += PAGE_SIZE) { for(uint64_t p = start; p < end; p += PAGE_SIZE) {
uint64_t vaddr = (uint64_t)P2V(p); uint64_t vaddr = (uint64_t)P2V(p);
uint64_t page = vmm_get_page(kernel_P4, vaddr); uint64_t page = vmm_get_page(kernel_P4, vaddr);
if(page == (uint64_t)-1 || !(page & PAGE_PRESENT)) { if(page == (uint64_t)-1 || !(page & PAGE_PRESENT)) {
uint16_t flags = PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT; uint16_t flags = PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT;
vmm_set_page(kernel_P4, vaddr, p, flags); vmm_set_page(kernel_P4, vaddr, p, flags);
} }
if(type != MMAP_FREE) if(type != MMAP_FREE)
continue; continue;
if(p >= V2P(&kernel_start) && p < V2P(&kernel_end)) if(p >= V2P(&kernel_start) && p < V2P(&kernel_end))
continue; continue;
if(multiboot_page_used((uintptr_t)P2V(p))) if(multiboot_page_used((uintptr_t)P2V(p)))
continue; continue;
pmm_free(p); pmm_free(p);
}
} }
}
} }

View File

@ -6,19 +6,19 @@
uint64_t next = 0; uint64_t next = 0;
void pmm_free(uint64_t page) { void pmm_free(uint64_t page) {
*(uint64_t *)P2V(page) = next; *(uint64_t *)P2V(page) = next;
next = page; next = page;
} }
uint64_t pmm_alloc() { uint64_t pmm_alloc() {
if(!next) return 0; if(!next) return 0;
uint64_t page = next; uint64_t page = next;
next = *(uint64_t *)P2V(page); next = *(uint64_t *)P2V(page);
return page; return page;
} }
uint64_t pmm_calloc() { uint64_t pmm_calloc() {
uint64_t page = pmm_alloc(); uint64_t page = pmm_alloc();
memset(P2V(page), 0, PAGE_SIZE); memset(P2V(page), 0, PAGE_SIZE);
return page; return page;
} }

View File

@ -17,80 +17,79 @@
static int P1_exists(uint64_t P4, uint64_t addr) { static int P1_exists(uint64_t P4, uint64_t addr) {
if (P4 && PRESENT(P4E(P4, addr)) && PRESENT(P3E(P4, addr)) && PRESENT(P2E(P4, addr)))
if (P4 && PRESENT(P4E(P4, addr)) && PRESENT(P3E(P4, addr)) && PRESENT(P2E(P4, addr))) return 1;
return 1; return 0;
return 0;
} }
static int touch_P1(uint64_t P4, uint64_t addr, uint16_t flags) { static int touch_P1(uint64_t P4, uint64_t addr, uint16_t flags) {
if (!P4) return -1; if (!P4) return -1;
if(!PRESENT(P4E(P4, addr)) && (!(P4E(P4,addr) = pmm_calloc()))) if(!PRESENT(P4E(P4, addr)) && (!(P4E(P4,addr) = pmm_calloc())))
return -1; return -1;
P4E(P4, addr) |= flags | PAGE_PRESENT; P4E(P4, addr) |= flags | PAGE_PRESENT;
if(!PRESENT(P3E(P4, addr)) && (!(P3E(P4, addr) = pmm_calloc()))) if(!PRESENT(P3E(P4, addr)) && (!(P3E(P4, addr) = pmm_calloc())))
return -1; return -1;
P3E(P4, addr) |= flags | PAGE_PRESENT; P3E(P4, addr) |= flags | PAGE_PRESENT;
if(!PRESENT(P2E(P4, addr)) && (!(P2E(P4, addr) = pmm_calloc()))) if(!PRESENT(P2E(P4, addr)) && (!(P2E(P4, addr) = pmm_calloc())))
return -1; return -1;
P2E(P4, addr) |= flags | PAGE_PRESENT; P2E(P4, addr) |= flags | PAGE_PRESENT;
return 0; return 0;
} }
uint64_t new_P4() { uint64_t new_P4() {
uint64_t p4 = pmm_alloc(); uint64_t p4 = pmm_alloc();
memcpy(P2V(p4), (void *)kernel_P4, PAGE_SIZE); memcpy(P2V(p4), (void *)kernel_P4, PAGE_SIZE);
return p4; return p4;
} }
uint64_t vmm_get_page(uint64_t P4, uint64_t addr) { uint64_t vmm_get_page(uint64_t P4, uint64_t addr) {
if(P1_exists(P4, addr)) if(P1_exists(P4, addr))
return P1E(P4, addr); return P1E(P4, addr);
return -1; return -1;
} }
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags) { int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags) {
if(!P1_exists(P4, addr)) if(!P1_exists(P4, addr))
if(touch_P1(P4, addr, flags)) if(touch_P1(P4, addr, flags))
return -1; return -1;
P1E(P4, addr) = page | flags; P1E(P4, addr) = page | flags;
return 0; return 0;
} }
void vmm_clear_page(uint64_t P4, uint64_t addr, int free) { void vmm_clear_page(uint64_t P4, uint64_t addr, int free) {
if(!P1_exists(P4, addr)) if(!P1_exists(P4, addr))
return; return;
uint64_t *pt; uint64_t *pt;
P1E(P4, addr) = 0; P1E(P4, addr) = 0;
if(!free) if(!free)
return; return;
pt = PT(P2E(P4, addr)); pt = PT(P2E(P4, addr));
for(int i = 0; i < ENTRIES_PER_PT; i++) for(int i = 0; i < ENTRIES_PER_PT; i++)
if(pt[i]) if(pt[i])
return; return;
pmm_free(MASK_FLAGS(P2E(P4, addr))); pmm_free(MASK_FLAGS(P2E(P4, addr)));
P2E(P4, addr) = 0; P2E(P4, addr) = 0;
pt = PT(P3E(P4, addr)); pt = PT(P3E(P4, addr));
for(int i = 0; i < ENTRIES_PER_PT; i++) for(int i = 0; i < ENTRIES_PER_PT; i++)
if(pt[i]) if(pt[i])
return; return;
pmm_free(MASK_FLAGS(P3E(P4, addr))); pmm_free(MASK_FLAGS(P3E(P4, addr)));
P3E(P4, addr) = 0; P3E(P4, addr) = 0;
pt = PT(P4E(P4, addr)); pt = PT(P4E(P4, addr));
for(int i = 0; i < ENTRIES_PER_PT; i++) for(int i = 0; i < ENTRIES_PER_PT; i++)
if(pt[i]) if(pt[i])
return; return;
pmm_free(MASK_FLAGS(P4E(P4, addr))); pmm_free(MASK_FLAGS(P4E(P4, addr)));
P4E(P4, addr) = 0; P4E(P4, addr) = 0;
} }

View File

@ -3,14 +3,14 @@
#include <memory.h> #include <memory.h>
struct swtch_stack { struct swtch_stack {
uint64_t RBP; uint64_t RBP;
uint64_t RBX; uint64_t RBX;
uint64_t R12; uint64_t R12;
uint64_t R13; uint64_t R13;
uint64_t R14; uint64_t R14;
uint64_t R15; uint64_t R15;
uint64_t RBP2; uint64_t RBP2;
uint64_t ret; uint64_t ret;
}; };
static uint64_t next_pid = 1; static uint64_t next_pid = 1;
@ -18,19 +18,19 @@ static uint64_t next_pid = 1;
struct process *current_proc; struct process *current_proc;
struct process *new_process(void (*function)(void)) { struct process *new_process(void (*function)(void)) {
struct process *p = P2V(pmm_calloc()); struct process *p = P2V(pmm_calloc());
p->pid = next_pid++; p->pid = next_pid++;
p->stack_ptr = incptr(p, PAGE_SIZE - sizeof(struct swtch_stack)); p->stack_ptr = incptr(p, PAGE_SIZE - sizeof(struct swtch_stack));
p->q_next = 0; p->q_next = 0;
p->P4 = new_P4(); p->P4 = new_P4();
struct swtch_stack *stck = p->stack_ptr; struct swtch_stack *stck = p->stack_ptr;
stck->RBP = (uint64_t)&stck->RBP2; stck->RBP = (uint64_t)&stck->RBP2;
stck->ret = (uint64_t)function; stck->ret = (uint64_t)function;
return p; return p;
} }
struct process *proc() { struct process *proc() {
return current_proc; return current_proc;
} }

View File

@ -2,52 +2,52 @@
#include <cpu.h> #include <cpu.h>
static struct { static struct {
struct process *first; struct process *first;
struct process *last; struct process *last;
} run_q = {0,0}; } run_q = {0,0};
static struct process *scheduler_proc; static struct process *scheduler_proc;
static struct process *scheduler_next() { static struct process *scheduler_next() {
struct process *ret = run_q.first; struct process *ret = run_q.first;
if(run_q.first && !(run_q.first = run_q.first->q_next)) if(run_q.first && !(run_q.first = run_q.first->q_next))
run_q.last = 0; run_q.last = 0;
return ret; return ret;
} }
void scheduler_insert(struct process *new) { void scheduler_insert(struct process *new) {
if(run_q.last) { if(run_q.last) {
run_q.last->q_next = new; run_q.last->q_next = new;
run_q.last = new; run_q.last = new;
} else { } else {
run_q.first = run_q.last = new; run_q.first = run_q.last = new;
} }
new->q_next = 0; new->q_next = 0;
} }
void scheduler() { void scheduler() {
while(1) { while(1) {
struct process *new = 0; struct process *new = 0;
while(!(new = scheduler_next())); while(!(new = scheduler_next()));
current_proc = new; current_proc = new;
write_cr3(new->P4); write_cr3(new->P4);
switch_stack(&scheduler_proc->stack_ptr, &new->stack_ptr); switch_stack(&scheduler_proc->stack_ptr, &new->stack_ptr);
scheduler_insert(current_proc); scheduler_insert(current_proc);
current_proc = 0; current_proc = 0;
} }
} }
long k_sched_yield(long, long, long, long, long, long) { long k_sched_yield(long, long, long, long, long, long) {
switch_stack(&current_proc->stack_ptr, &scheduler_proc->stack_ptr); switch_stack(&current_proc->stack_ptr, &scheduler_proc->stack_ptr);
return 0; return 0;
} }
void start_scheduler() { void start_scheduler() {
scheduler_proc = new_process(scheduler); scheduler_proc = new_process(scheduler);
scheduler_proc->pid = (uint64_t)-1; scheduler_proc->pid = (uint64_t)-1;
uint64_t stack; uint64_t stack;
switch_stack(&stack, &scheduler_proc->stack_ptr); switch_stack(&stack, &scheduler_proc->stack_ptr);
} }

View File

@ -11,96 +11,125 @@
#define STEP_X(ctx) 1 #define STEP_X(ctx) 1
#define STEP_Y(ctx) (ctx)->pitch #define STEP_Y(ctx) (ctx)->pitch
void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr) { void putpixel(
if(x >= ctx->width || y >= ctx->height) return; gfx_context *ctx,
uint32_t *fb = (uint32_t *)ctx->buffer; uint64_t x, uint64_t y,
uint32_t clr
) {
if(x >= ctx->width || y >= ctx->height) return;
uint32_t *fb = (uint32_t *)ctx->buffer;
fb[PXL(ctx, x, y)] = clr;
}
void draw_line(
gfx_context *ctx,
uint64_t x0, uint64_t x1,
uint64_t y0, uint64_t y1,
uint32_t clr
) {
int64_t dx = x1 > x0 ? x1 - x0 : x0 - x1;
int64_t dy = y1 > y0 ? y1 - y0 : y0 - y1;
int sx = x1 > x0 ? 1 : -1;
int sy = y1 > y0 ? 1 : -1;
uint64_t x = x0, y = y0;
int64_t diff = dx - dy;
uint32_t *fb = (uint32_t *)ctx->buffer;
while(1) {
fb[PXL(ctx, x, y)] = clr; fb[PXL(ctx, x, y)] = clr;
if(x == x1 && y == y1) break;
if((2*diff) > -dy) {
diff -= dy;
x += sx;
} else {
diff += dx;
y += sy;
}
}
} }
void draw_line(gfx_context *ctx, uint64_t x0, uint64_t x1, uint64_t y0, uint64_t y1, uint32_t clr) { void draw_rect(
int64_t dx = x1 > x0 ? x1 - x0 : x0 - x1; gfx_context *ctx,
int64_t dy = y1 > y0 ? y1 - y0 : y0 - y1; uint64_t x, uint64_t y,
int sx = x1 > x0 ? 1 : -1; uint64_t width, uint64_t height,
int sy = y1 > y0 ? 1 : -1; uint32_t clr
uint64_t x = x0, y = y0; ) {
int64_t diff = dx - dy; uint32_t *fb = (uint32_t *)ctx->buffer;
uint32_t *fb = (uint32_t *)ctx->buffer; uint64_t l1 = PXL(ctx, x, y);
while(1) { uint64_t l2 = PXL(ctx, x, y + height);
fb[PXL(ctx, x, y)] = clr; for(uint64_t _x = 0; _x <= width; _x++) {
if(x == x1 && y == y1) break; fb[l1] = fb[l2] = clr;
l1 += STEP_X(ctx);
if((2*diff) > -dy) { l2 += STEP_X(ctx);
diff -= dy; }
x += sx; l1 = PXL(ctx, x, y);
} else { l2 = PXL(ctx, x + width, y);
diff += dx; for(uint64_t _y = 0; _y <= height; _y++) {
y += sy; fb[l1] = fb[l2] = clr;
} l1 += STEP_Y(ctx);
} l2 += STEP_Y(ctx);
}
} }
void draw_rect(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height, uint32_t clr) { void fill_rect(
uint32_t *fb = (uint32_t *)ctx->buffer; gfx_context *ctx,
uint64_t l1 = PXL(ctx, x, y); uint64_t x, uint64_t y,
uint64_t l2 = PXL(ctx, x, y + height); uint64_t width, uint64_t height,
for(uint64_t _x = 0; _x <= width; _x++) { uint32_t clr
fb[l1] = fb[l2] = clr; ) {
l1 += STEP_X(ctx); uint32_t *fb = (uint32_t *)ctx->buffer;
l2 += STEP_X(ctx); uint64_t loc = PXL(ctx, x, y);
} for(uint64_t _y = 0; _y <= height; _y++) {
l1 = PXL(ctx, x, y); for(uint64_t _x = 0; _x <= width; _x += STEP_X(ctx)) {
l2 = PXL(ctx, x + width, y); fb[loc + _x] = clr;
for(uint64_t _y = 0; _y <= height; _y++) {
fb[l1] = fb[l2] = clr;
l1 += STEP_Y(ctx);
l2 += STEP_Y(ctx);
} }
loc += STEP_Y(ctx);
}
} }
void fill_rect(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height, uint32_t clr) { void putCharacter(
uint32_t *fb = (uint32_t *)ctx->buffer; gfx_context *ctx,
uint64_t loc = PXL(ctx, x, y); uint64_t x, uint64_t y,
for(uint64_t _y = 0; _y <= height; _y++) { uint32_t clr_fg, uint32_t clr_bg,
for(uint64_t _x = 0; _x <= width; _x += STEP_X(ctx)) { char c
fb[loc + _x] = clr; ) {
} unsigned char *chr = c ? font[(int)c-0x20]: font[0];
loc += STEP_Y(ctx); if(x >= ctx->width || y >= ctx->height) return;
} uint32_t *fb = (uint32_t *)ctx->buffer;
} uint64_t loc = y * ctx->pitch + x;
for(int row = 0; row < 16; row++) {
void putCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr_fg, uint32_t clr_bg, char c) { for(int col = 0; col < 8; col++) {
unsigned char *chr = c ? font[(int)c-0x20]: font[0]; fb[loc+col] = ((chr[row]>>(7-col))&0x1) ? clr_fg : clr_bg;
if(x >= ctx->width || y >= ctx->height) return;
uint32_t *fb = (uint32_t *)ctx->buffer;
uint64_t loc = y * ctx->pitch + x;
for(int row = 0; row < 16; row++) {
for(int col = 0; col < 8; col++) {
fb[loc+col] = ((chr[row]>>(7-col))&0x1) ? clr_fg : clr_bg;
}
loc += ctx->pitch;
} }
loc += ctx->pitch;
}
} }
void flip(gfx_context *ctx) { void flip(gfx_context *ctx) {
for(uint64_t y = 0; y < ctx->height; y++) { for(uint64_t y = 0; y < ctx->height; y++) {
memcpy( memcpy(
incptr(ctx->addr, y*ctx->pitch*ctx->bpp), incptr(ctx->addr, y*ctx->pitch*ctx->bpp),
incptr(ctx->buffer, y*ctx->pitch*ctx->bpp), incptr(ctx->buffer, y*ctx->pitch*ctx->bpp),
ctx->width*ctx->bpp); ctx->width*ctx->bpp
} );
}
} }
gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height) { gfx_context *framebuffer_make_subcontext(
gfx_context *out = malloc(sizeof(gfx_context)); gfx_context *ctx,
uint64_t loc = y * ctx->pitch + x; uint64_t x, uint64_t y,
uint64_t width, uint64_t height
) {
gfx_context *out = malloc(sizeof(gfx_context));
uint64_t loc = y * ctx->pitch + x;
out->width = width; out->width = width;
out->height = height; out->height = height;
out->bpp = ctx->bpp; out->bpp = ctx->bpp;
out->pitch = ctx->pitch; out->pitch = ctx->pitch;
out->addr = incptr(ctx->addr, loc*ctx->bpp); out->addr = incptr(ctx->addr, loc*ctx->bpp);
out->size = ctx->pitch * height * ctx->bpp; out->size = ctx->pitch * height * ctx->bpp;
out->buffer = calloc(1, out->size); out->buffer = calloc(1, out->size);
return out; return out;
} }

View File

@ -2,13 +2,13 @@
#include <stdlib.h> #include <stdlib.h>
typedef struct { typedef struct {
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
uint32_t bpp; uint32_t bpp;
uint32_t pitch; uint32_t pitch;
void *addr; void *addr;
void *buffer; void *buffer;
size_t size; size_t size;
} gfx_context; } gfx_context;
#define RGB(r, g, b) (((uint32_t) (r<<16) + (g<<8) + (b))) #define RGB(r, g, b) (((uint32_t) (r<<16) + (g<<8) + (b)))

View File

@ -10,25 +10,29 @@ extern long syscall5(long, long, long, long, long, long);
extern long syscall6(long, long, long, long, long, long, long); extern long syscall6(long, long, long, long, long, long, long);
static __inline long __syscall0(long n) { static __inline long __syscall0(long n) {
return syscall0(n); return syscall0(n);
} }
static __inline long __syscall1(long n, long a1) { static __inline long __syscall1(long n, long a1) {
return syscall1(n, a1); return syscall1(n, a1);
} }
static __inline long __syscall2(long n, long a1, long a2) { static __inline long __syscall2(long n, long a1, long a2) {
return syscall2(n, a1, a2); return syscall2(n, a1, a2);
} }
static __inline long __syscall3(long n, long a1, long a2, long a3) { static __inline long __syscall3(long n, long a1, long a2, long a3) {
return syscall3(n, a1, a2, a3); return syscall3(n, a1, a2, a3);
} }
static __inline long __syscall4(long n, long a1, long a2, long a3, long a4) { static __inline long __syscall4(long n, long a1, long a2, long a3, long a4) {
return syscall4(n, a1, a2, a3, a4); return syscall4(n, a1, a2, a3, a4);
} }
static __inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5) { static __inline long __syscall5(long n, long a1, long a2, long a3, long a4,
return syscall5(n, a1, a2, a3, a4, a5); long a5
) {
return syscall5(n, a1, a2, a3, a4, a5);
} }
static __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6) { static __inline long __syscall6(long n, long a1, long a2, long a3, long a4,
return syscall6(n, a1, a2, a3, a4, a5, a6); long a5, long a6
) {
return syscall6(n, a1, a2, a3, a4, a5, a6);
} }
#define VDSO_USEFUL #define VDSO_USEFUL