From 050aa3ab70dd69d1ca8ffe94fd146039a0885550 Mon Sep 17 00:00:00 2001 From: aqua Date: Wed, 24 May 2023 21:29:00 +0300 Subject: Make code ANSI C compatible --- i686/Makefile | 2 +- i686/boot.S | 89 --------------------------------------- i686/boot.s | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++ i686/gdt.c | 6 +-- i686/gdt.h | 72 ++++++++++++++++---------------- i686/idt.h | 8 ++-- i686/isr.c | 2 +- i686/lgdt.c | 26 ++++-------- i686/lidt.c | 28 +++++++------ i686/macros.s | 25 ----------- i686/paging.h | 86 +++++++++++++++++++------------------- i686/sys/control.h | 15 ++++--- i686/sys/cpuid.h | 2 +- i686/sys/io.h | 50 +++++++++++----------- i686/test_gdt.cc | 1 - i686/toolchain.mk | 4 +- 16 files changed, 266 insertions(+), 270 deletions(-) delete mode 100644 i686/boot.S create mode 100644 i686/boot.s delete mode 100644 i686/macros.s (limited to 'i686') diff --git a/i686/Makefile b/i686/Makefile index 93f9a63..3702bef 100644 --- a/i686/Makefile +++ b/i686/Makefile @@ -5,7 +5,7 @@ ${ARCH}_CFLAGS += ${INCLUDES} ${ARCH}_CXXFLAGS += ${INCLUDES} TARGETLIB += arch -arch.SRCS = boot.S init.s \ +arch.SRCS = boot.s init.s \ gdt.c lgdt.c \ lidt.c isr.c diff --git a/i686/boot.S b/i686/boot.S deleted file mode 100644 index 1eea9a3..0000000 --- a/i686/boot.S +++ /dev/null @@ -1,89 +0,0 @@ -#define ASM_FILE -#include -#include "macros.s" - -/* Declare a multiboot header that marks this program as a kernel */ -.section .multiboot.header, "a" -header_begin: -.align 8 - .int MULTIBOOT2_HEADER_MAGIC - .int MULTIBOOT_ARCHITECTURE_I386 - .int header_end - header_begin - .int -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (header_end - header_begin)) - -.align 8 -header_info_begin: - .short MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST - .short 0 # flags - .int header_info_end - header_info_begin - .int MULTIBOOT_TAG_TYPE_MMAP -header_info_end: - -.align 8 - .short MULTIBOOT_HEADER_TAG_END - .short 0 - .int 8 -header_end: - -.section .multiboot.pages, "aw", @nobits -.align 4096 -bootstrap_page0: - .skip 1024 * 4 - -.section .multiboot.text, "ax" -.extern k_pagedir -.extern k_stack -.extern k_init - -#.global __vaddr_base -#.set __vaddr_base, 0xc0000000 -#.global __vaddr_offset -.set __vaddr_offset, 0xc0000000 - 0x2000 - -.global _start -.type _start, @function -_start: - cli - - # check multiboot header - cmp $MULTIBOOT2_BOOTLOADER_MAGIC, %eax - jz c - hlt - -c: mov $k_stack - __vaddr_offset, %esp - - push %ebx # pointer to multiboot structure - call __multiboot2 - - # mmap multiboot section into bootstrap page - movl $bootstrap_page0, %edi - movl $1024, %ecx - mmap_section __multiboot_begin, __multiboot_end, PAGE_RW - mmap_section (__text_begin - __vaddr_offset), (__text_end - __vaddr_offset), PAGE_RO - mmap_section (__rodata_begin - __vaddr_offset), (__rodata_end - __vaddr_offset), PAGE_RO - mmap_section (__bss_begin - __vaddr_offset), (__bss_end - __vaddr_offset), PAGE_RW - mmap_section (__data_begin - __vaddr_offset), (__data_end - __vaddr_offset), PAGE_RW - - # mmap all the other section into k_ptable0x300 - movl $(k_ptable0x300 - __vaddr_offset), %edi - movl $1024, %ecx - mmap_section (__text_begin - __vaddr_offset), (__text_end - __vaddr_offset), PAGE_RO - mmap_section (__rodata_begin - __vaddr_offset), (__rodata_end - __vaddr_offset), PAGE_RO - mmap_section (__bss_begin - __vaddr_offset), (__bss_end - __vaddr_offset), PAGE_RW - mmap_section (__data_begin - __vaddr_offset), (__data_end - __vaddr_offset), PAGE_RW - - movl $(bootstrap_page0 + PAGE_RW), k_pagedir - __vaddr_offset + 0 * 4 - movl $(k_ptable0x300 - __vaddr_offset + PAGE_RW), k_pagedir - __vaddr_offset + 768 * 4 - - movl $(k_pagedir - __vaddr_offset), %ecx - movl %ecx, %cr3 - - # enable paging and the write-protect bit - movl %cr0, %ecx - orl $0x80010000, %ecx - movl %ecx, %cr0 - - # jump to higher half with an absolute jump - lea (k_init), %ecx - jmp *%ecx - diff --git a/i686/boot.s b/i686/boot.s new file mode 100644 index 0000000..40b0389 --- /dev/null +++ b/i686/boot.s @@ -0,0 +1,120 @@ +/* The magic field should contain this. */ +.set MULTIBOOT2_HEADER_MAGIC, 0xe85250d6 +/* This should be in %eax. */ +.set MULTIBOOT2_BOOTLOADER_MAGIC, 0x36d76289 +.set MULTIBOOT_ARCHITECTURE_I386, 0 +.set MULTIBOOT_HEADER_TAG_END, 0 +.set MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST, 1 +.set MULTIBOOT_TAG_TYPE_MMAP, 6 + +.set PAGE_RO, 0x001 +.set PAGE_RW, 0x003 + +/* write section to page table macro + * + * Registers used: + * %ecx: loop counter [ set to $1024 ] + * %edx: temporary + * %esi: current page being mapped + * %edi: page entry [ set to $page_addr ] + */ +.macro mmap_section begin, end, access + mov $\begin, %esi # from $begin +1: cmpl $\end, %esi # until $end + jge 2f + + movl %esi, %edx + orl $\access, %edx + movl %edx, (%edi) + + addl $4096, %esi # move to next page + addl $4, %edi # size of page entry is 4 bytes + loop 1b # loop according to %ecx +2: +.endm + +/* Declare a multiboot header that marks this program as a kernel */ +.section .multiboot.header, "a" +header_begin: +.align 8 + .int MULTIBOOT2_HEADER_MAGIC + .int MULTIBOOT_ARCHITECTURE_I386 + .int header_end - header_begin + .int -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (header_end - header_begin)) + +.align 8 +header_info_begin: + .short MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST + .short 0 # flags + .int header_info_end - header_info_begin + .int MULTIBOOT_TAG_TYPE_MMAP +header_info_end: + +.align 8 + .short MULTIBOOT_HEADER_TAG_END + .short 0 + .int 8 +header_end: + +.section .multiboot.pages, "aw", @nobits +.align 4096 +bootstrap_page0: + .skip 1024 * 4 + +.section .multiboot.text, "ax" +.extern k_pagedir +.extern k_stack +.extern k_init + +#.global __vaddr_base +#.set __vaddr_base, 0xc0000000 +#.global __vaddr_offset +.set __vaddr_offset, 0xc0000000 - 0x2000 + +.global _start +.type _start, @function +_start: + cli + + # check multiboot header + cmp $MULTIBOOT2_BOOTLOADER_MAGIC, %eax + jz c + hlt + +c: mov $k_stack - __vaddr_offset, %esp + + push %ebx # pointer to multiboot structure + call __multiboot2 + + # mmap multiboot section into bootstrap page + movl $bootstrap_page0, %edi + movl $1024, %ecx + mmap_section __multiboot_begin, __multiboot_end, PAGE_RW + mmap_section (__text_begin - __vaddr_offset), (__text_end - __vaddr_offset), PAGE_RO + mmap_section (__rodata_begin - __vaddr_offset), (__rodata_end - __vaddr_offset), PAGE_RO + mmap_section (__bss_begin - __vaddr_offset), (__bss_end - __vaddr_offset), PAGE_RW + mmap_section (__data_begin - __vaddr_offset), (__data_end - __vaddr_offset), PAGE_RW + + # mmap all the other section into k_ptable0x300 + movl $(k_ptable0x300 - __vaddr_offset), %edi + movl $1024, %ecx + mmap_section (__text_begin - __vaddr_offset), (__text_end - __vaddr_offset), PAGE_RO + mmap_section (__rodata_begin - __vaddr_offset), (__rodata_end - __vaddr_offset), PAGE_RO + mmap_section (__bss_begin - __vaddr_offset), (__bss_end - __vaddr_offset), PAGE_RW + mmap_section (__data_begin - __vaddr_offset), (__data_end - __vaddr_offset), PAGE_RW + + movl $(bootstrap_page0 + PAGE_RW), k_pagedir - __vaddr_offset + 0 * 4 + movl $(k_ptable0x300 - __vaddr_offset + PAGE_RW), k_pagedir - __vaddr_offset + 768 * 4 + + movl $(k_pagedir - __vaddr_offset), %ecx + movl %ecx, %cr3 + + # enable paging and the write-protect bit + movl %cr0, %ecx + orl $0x80010000, %ecx + movl %ecx, %cr0 + + # jump to higher half with an absolute jump + lea (k_init), %ecx + jmp *%ecx + diff --git a/i686/gdt.c b/i686/gdt.c index c0898f3..3148096 100644 --- a/i686/gdt.c +++ b/i686/gdt.c @@ -4,11 +4,11 @@ void SegmentDescriptor(struct SegmentDescriptor_t *self, unsigned base, unsigned limit, uint8_t access) { self->base_15_0 = base & 0xffff; - self->base_23_16 = (base >> 16) & 0xff; - self->base_31_24 = (base >> 24) & 0xff; + self->base_23_16 = (uint8_t)(base >> 16); + self->base_31_24 = (uint8_t)(base >> 24); self->limit_15_0 = (limit <= 0xffff) ? (limit & 0xffff) : ((limit >> 12) & 0xffff); - self->limit_19_16 = (limit <= 0xffff) ? 0 : ((limit >> 28) & 0xf); + self->limit_19_16 = 0xfu & (uint8_t)((limit <= 0xffff) ? 0 : (limit >> 28)); self->access = access; diff --git a/i686/gdt.h b/i686/gdt.h index 91de365..2bdfb22 100644 --- a/i686/gdt.h +++ b/i686/gdt.h @@ -6,44 +6,44 @@ enum Ring { Ring0 = 0x0, Ring1 = 0x1, Ring2 = 0x2, Ring3 = 0x3 }; struct __attribute__((packed)) Access { - bool accessed : 1; // if 0, is set by processor when accessed - bool readwrite : 1; // code seg: read toggle; data seg: write toggle - bool direction : 1; // code seg: conforming bit; data seg: direction bit - bool executable : 1; // executable bit - bool segment : 1; // true for code/data; false for gates/tss - enum Ring privilege : 2; // descriptor privilege level - bool present : 1; // true for every active segment + unsigned accessed : 1; /* if 0, is set by processor when accessed */ + unsigned readwrite : 1; /* code seg: read toggle; data seg: write toggle */ + unsigned direction : 1; /* code seg: conforming bit; data seg: direction bit */ + unsigned executable : 1; /* executable bit */ + unsigned segment : 1; /* true for code/data; false for gates/tss */ + unsigned privilege : 2; /* descriptor privilege level */ + unsigned present : 1; /* true for every active segment */ }; -_Static_assert(sizeof(struct Access) == 1, "access byte size"); - -static const struct Access null_access = {false, false, false, false, false, Ring0, false}; -static const struct Access ktext_access = {.readwrite = true, .executable = true, .segment = true, .present = true}; -static const struct Access kdata_access = {.readwrite = true, .segment = true, .present = true}; - -// Segment Descriptor -// A memory structure (part of a table) that tells the CPU the attributes of a given segment -// |31| | | | | | |24|23|22|21|20|19| | |16|15| | | | | | | 8| 7| | | | | | | 0| -// | base_31_24 | G|DB| | A| lim_19_16 | access | base_23_16 | -// | base_15_0 | limit_15_0 | -// |31| | | | | | | | | | | | | | |16|15| | | | | | | | | | | | | | | 0| -// limit size of segment - 1, either in bytes or in 4KiB chunks (check flags) -// base address of segment -// access -// flags defines the segment chunks and 16/32 bit +/* _Static_assert(sizeof(struct Access) == 1, "access byte size"); */ + +static const struct Access null_access = {0, 0, 0, 0, 0, Ring0, 0}; +static const struct Access ktext_access = {0, 1, 0, 1, 1, Ring0, 1}; +static const struct Access kdata_access = {0, 1, 0, 0, 1, Ring0, 1}; + +/* Segment Descriptor + * A memory structure (part of a table) that tells the CPU the attributes of a given segment + * |31| | | | | | |24|23|22|21|20|19| | |16|15| | | | | | | 8| 7| | | | | | | 0| + * | base_31_24 | G|DB| | A| lim_19_16 | access | base_23_16 | + * | base_15_0 | limit_15_0 | + * |31| | | | | | | | | | | | | | |16|15| | | | | | | | | | | | | | | 0| + * limit size of segment - 1, either in bytes or in 4KiB chunks (check flags) + * base address of segment + * access + * flags defines the segment chunks and 16/32 bit */ struct __attribute__((packed)) SegmentDescriptor_t { - uint16_t limit_15_0; // low bits of segment limit - uint16_t base_15_0; // low bits of segment base address - uint8_t base_23_16; // middle bits of segment base address - uint8_t access; // access byte - uint8_t limit_19_16 : 4; // high bits of segment limit - // flags - bool a : 1; // unused, available for software use - bool rsv : 1; // reserved - bool db : 1; // false => 16-bit seg; true => 32-bit seg - bool granularity : 1; // limit scaled by 4k when set - uint8_t base_31_24; // high bits of segment address + uint16_t limit_15_0; /* low bits of segment limit */ + uint16_t base_15_0; /* low bits of segment base address */ + uint8_t base_23_16; /* middle bits of segment base address */ + uint8_t access; /* access byte */ + unsigned limit_19_16 : 4; /* high bits of segment limit */ + /* flags */ + bool a : 1; /* unused, available for software use */ + bool rsv : 1; /* reserved */ + bool db : 1; /* false => 16-bit seg; true => 32-bit seg */ + bool granularity : 1; /* limit scaled by 4k when set */ + uint8_t base_31_24; /* high bits of segment address */ }; -_Static_assert(sizeof(struct SegmentDescriptor_t) == 8, "segment descriptor size"); +/* _Static_assert(sizeof(struct SegmentDescriptor_t) == 8, "segment descriptor size"); */ void SegmentDescriptor(struct SegmentDescriptor_t *self, unsigned base, unsigned limit, uint8_t access); @@ -51,5 +51,5 @@ void gdt_install(); enum SegmentIndex { ktextDescriptor = 2 * sizeof(struct SegmentDescriptor_t), - kdataDescriptor = 3 * sizeof(struct SegmentDescriptor_t), + kdataDescriptor = 3 * sizeof(struct SegmentDescriptor_t) }; diff --git a/i686/idt.h b/i686/idt.h index 45744dc..ca39bde 100644 --- a/i686/idt.h +++ b/i686/idt.h @@ -10,14 +10,14 @@ struct interrupt_frame { uint32_t ss; }; -// typedef void (*irq_handler)(); +/* typedef void (*irq_handler)(); */ /* isr.c */ void abort_handler(struct interrupt_frame *frame); void syscall_handler(struct interrupt_frame *frame); -void irq0x00(struct interrupt_frame *frame); // timer interrupt -void irq0x01(struct interrupt_frame *frame); // keyboard interrupt -void irq0x0c(struct interrupt_frame *frame); // mouse interrupt +void irq0x00(struct interrupt_frame *frame); /* timer interrupt */ +void irq0x01(struct interrupt_frame *frame); /* keyboard interrupt */ +void irq0x0c(struct interrupt_frame *frame); /* mouse interrupt */ /* lidt.c */ void idt_install(); diff --git a/i686/isr.c b/i686/isr.c index 8af5d33..acc2961 100644 --- a/i686/isr.c +++ b/i686/isr.c @@ -20,7 +20,7 @@ __attribute__((interrupt)) void syscall_handler(__attribute__((unused)) struct interrupt_frame *frame) { unsigned int n; - asm volatile("mov %%eax, %0" : "=r"(n)); + __asm__("mov %%eax, %0" : "=r"(n)); printf("syscall %x\n, n"); abort(); } diff --git a/i686/lgdt.c b/i686/lgdt.c index 10781db..d1b24c3 100644 --- a/i686/lgdt.c +++ b/i686/lgdt.c @@ -10,26 +10,16 @@ static struct SegmentDescriptor_t segments[8] __attribute__((aligned(32))); void gdt_install() { - SegmentDescriptor(&segments[0], 0, 0, 0); // null segment - SegmentDescriptor(&segments[2], 0, 0xffffffff, 0x9a); // ktext - SegmentDescriptor(&segments[3], 0, 0xffffffff, 0x92); // kdata + SegmentDescriptor(&segments[0], 0, 0, 0); /* null segment */ + SegmentDescriptor(&segments[2], 0, 0xffffffff, 0x9a); /* ktext segment */ + SegmentDescriptor(&segments[3], 0, 0xffffffff, 0x92); /* kdata segment */ const struct Pointer ptr = {.limit = sizeof(segments) - 1, .base = (unsigned)&segments}; - asm volatile("lgdt (%0)" : : "a"(&ptr)); + __asm__("lgdt (%0)" : : "a"(&ptr)); - // load the kernel data segment - asm volatile(R"(mov %0, %%ds - mov %0, %%es - mov %0, %%fs - mov %0, %%gs - mov %0, %%ss -)" - : - : "ax"(kdataDescriptor)); + /* load the kernel data segment */ + __asm__("mov %0, %%ds; mov %0, %%es; mov %0, %%fs; mov %0, %%gs; mov %0, %%ss" : : "ax"(kdataDescriptor)); - // load the kernel code segment - asm volatile(R"(ljmp %0, $1f - 1:)" - : - : "i"(ktextDescriptor)); + /* load the kernel code segment */ + __asm__("ljmp %0, $1f\n1:" : : "i"(ktextDescriptor)); } diff --git a/i686/lidt.c b/i686/lidt.c index cf8084e..3260eb9 100644 --- a/i686/lidt.c +++ b/i686/lidt.c @@ -8,17 +8,17 @@ struct __attribute__((packed)) Pointer { enum Type { Null = 0, - Intr = 0x8e, // 1000 1110 32-bit interrupt + Intr = 0x8e, /* 1000 1110 32-bit interrupt */ }; struct __attribute__((packed)) Gate_t { - uint16_t offset_15_0; // segment offset low - uint16_t selector; // code segment selector - uint8_t __unused; // unused in protected mode - uint8_t type; // interrupt type - uint16_t offset_31_16; // segment offset high + uint16_t offset_15_0; /* segment offset low */ + uint16_t selector; /* code segment selector */ + uint8_t __unused; /* unused in protected mode */ + uint8_t type; /* interrupt type */ + uint16_t offset_31_16; /* segment offset high */ }; -_Static_assert(sizeof(struct Gate_t) == 8, "interrupt gate size"); +/* _Static_assert(sizeof(struct Gate_t) == 8, "interrupt gate size"); */ void Gate(struct Gate_t *entry, void (*f)(struct interrupt_frame *), uint16_t selector) @@ -36,18 +36,20 @@ static struct Gate_t interrupt_table[256] __attribute((aligned(4096))); void idt_install() { - // exceptions 0x00~0x13 - for (int i = 0; i <= 0x13; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); + int i; - // irq 0x20~0x2f - for (int i = 0x22; i <= 0x2f; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); + /* exceptions 0x00~0x13 */ + for (i = 0; i <= 0x13; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); + + /* irq 0x20~0x2f */ + for (i = 0x22; i <= 0x2f; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); Gate(&interrupt_table[0x20], &irq0x00, 0x10); Gate(&interrupt_table[0x21], &irq0x01, 0x10); Gate(&interrupt_table[0x2c], &irq0x0c, 0x10); - // syscall 0x80 + /* syscall 0x80 */ Gate(&interrupt_table[0x80], &syscall_handler, 0x10); const struct Pointer ptr = {.limit = sizeof(interrupt_table) - 1, .base = (unsigned)&interrupt_table}; - asm volatile("lidt (%0)" : : "a"(&ptr)); + __asm__("lidt (%0)" : : "a"(&ptr)); } diff --git a/i686/macros.s b/i686/macros.s deleted file mode 100644 index a9b8b4d..0000000 --- a/i686/macros.s +++ /dev/null @@ -1,25 +0,0 @@ -.set PAGE_RO, 0x001 -.set PAGE_RW, 0x003 -/* write section to page table macro - * - * Registers used: - * %ecx: loop counter [ set to $1024 ] - * %edx: temporary - * %esi: current page being mapped - * %edi: page entry [ set to $page_addr ] - */ -.macro mmap_section begin, end, access - mov $\begin, %esi # from $begin -1: cmpl $\end, %esi # until $end - jge 2f - - movl %esi, %edx - orl $\access, %edx - movl %edx, (%edi) - - addl $4096, %esi # move to next page - addl $4, %edi # size of page entry is 4 bytes - loop 1b # loop according to %ecx -2: -.endm - diff --git a/i686/paging.h b/i686/paging.h index f9c04a8..f5bfa78 100644 --- a/i686/paging.h +++ b/i686/paging.h @@ -1,59 +1,59 @@ #pragma once -// DirectoryEntry -// |31| | | | | | | | | | | | | | | | | | | |11| | 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -// | page table 4-kb aligned address | avail | G| S| | A| C| W| U| R| P| +/* DirectoryEntry + * |31| | | | | | | | | | | | | | | | | | | |11| | 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| + * | page table 4-kb aligned address | avail | G| S| | A| C| W| U| R| P| */ struct __attribute__((packed)) DirectoryEntry { - unsigned present : 1; // 0: if set, the page is actually in physical memory - unsigned writeable : 1; // 1: if set, the page is read/write; otherwise the page is read-only - unsigned user : 1; // 2: if set, then page can be access by all; otherwise only the supervisor can access it - unsigned writethrough : 1; // 3: if set, write-through caching is enabled; otherwise write-back is enabled instead - unsigned cachedisable : 1; // 4: if set, the page will not be cached - unsigned accessed : 1; // 5: set by the CPU when the page is read from or written to - unsigned dirty : 1; // 6: used to determine whether a page has been written to - unsigned pagesize : 1; // 7: page size == 0 + unsigned present : 1; /* 0: if set, the page is actually in physical memory */ + unsigned writeable : 1; /* 1: if set, the page is read/write; otherwise the page is read-only */ + unsigned user : 1; /* 2: if set, then page can be access by all; otherwise only the supervisor can access it */ + unsigned writethrough : 1; /* 3: if set, write-through caching is enabled; otherwise write-back is enabled instead */ + unsigned cachedisable : 1; /* 4: if set, the page will not be cached */ + unsigned accessed : 1; /* 5: set by the CPU when the page is read from or written to */ + unsigned dirty : 1; /* 6: used to determine whether a page has been written to */ + unsigned pagesize : 1; /* 7: page size == 0 */ unsigned global : 1; - unsigned int __available__ : 3; // available to the OS + unsigned int __available__ : 3; /* available to the OS */ unsigned int address : 20; }; -_Static_assert(sizeof(struct DirectoryEntry) == 4, "DirectoryEntry size"); +/* TODO _Static_assert(sizeof(struct DirectoryEntry) == 4, "DirectoryEntry size"); */ -// DirectoryEntry4MB -// |31| | | | | | | | |22|21|20| | | | | | |13|12|11| | 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -// | bits 31-22 of address |RS| bits 39-22 of |AT| avail | G|PS| D| A|CD|WT|US|RW| P| -// | |VD| address +/* DirectoryEntry4MB + * |31| | | | | | | | |22|21|20| | | | | | |13|12|11| | 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| + * | bits 31-22 of address |RS| bits 39-22 of |AT| avail | G|PS| D| A|CD|WT|US|RW| P| + * | |VD| address */ struct __attribute__((packed)) DirectoryEntry4MB { - unsigned present : 1; // 0: if set, the page is actually in physical memory - unsigned writeable : 1; // 1: if set, the page is read/write; otherwise the page is read-only - unsigned useraccess : 1; // 2: if set, then page can be access by all; otherwise only the supervisor can access it - unsigned writethrough : 1; // 3: if set, write-through caching is enabled; otherwise write-back is enabled instead - unsigned cachedisable : 1; // 4: if set, the page will not be cached - unsigned accessed : 1; // 5: set by the CPU when the page is read from or written to - unsigned dirty : 1; // 6: used to determine whether a page has been written to - unsigned pagesize : 1; // 7: page size == 1 - unsigned global : 1; // 8: - unsigned __available__ : 3; // 11..9 available to the OS - unsigned pat : 1; // 12: page attribute table + unsigned present : 1; /* 0: if set, the page is actually in physical memory */ + unsigned writeable : 1; /* 1: if set, the page is read/write; otherwise the page is read-only */ + unsigned useraccess : 1; /* 2: if set, then page can be access by all; otherwise only the supervisor can access it */ + unsigned writethrough : 1; /* 3: if set, write-through caching is enabled; otherwise write-back is enabled instead */ + unsigned cachedisable : 1; /* 4: if set, the page will not be cached */ + unsigned accessed : 1; /* 5: set by the CPU when the page is read from or written to */ + unsigned dirty : 1; /* 6: used to determine whether a page has been written to */ + unsigned pagesize : 1; /* 7: page size == 1 */ + unsigned global : 1; /* 8: */ + unsigned __available__ : 3; /* 11..9 available to the OS */ + unsigned pat : 1; /* 12: page attribute table */ unsigned int address_high : 8; - unsigned rsvd : 1; // 21 + unsigned rsvd : 1; /* 21 */ unsigned int address_low : 10; }; -_Static_assert(sizeof(struct DirectoryEntry4MB) == 4, "DirectoryEntry4M size"); +/* TODO _Static_assert(sizeof(struct DirectoryEntry4MB) == 4, "DirectoryEntry4M size"); */ -// TableEntry -// |31| | | | | | | | | | | | | | | | | | | |11| | 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -// | page table 4-kb aligned address | avail | G| | D| A| C| W|US|RW| P| +/* TableEntry + * |31| | | | | | | | | | | | | | | | | | | |11| | 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| + * | page table 4-kb aligned address | avail | G| | D| A| C| W|US|RW| P| */ struct __attribute__((packed)) TableEntry { - unsigned present : 1; // if set, the page is actually in physical memory - unsigned writeable : 1; // if set, the page is read/write; otherwise the page is read-only - unsigned user : 1; // if set, then page can be access by all; otherwise only the supervisor can access it - unsigned writethrough : 1; // if set, write-through caching is enabled; otherwise write-back is enabled instead - unsigned cachedisable : 1; // if set, the page will not be cached - unsigned accessed : 1; // set by the CPU when the page is read from or written to - unsigned dirty : 1; // used to determine whether a page has been written to - unsigned pat : 1; // page attribute table? + unsigned present : 1; /* if set, the page is actually in physical memory */ + unsigned writeable : 1; /* if set, the page is read/write; otherwise the page is read-only */ + unsigned user : 1; /* if set, then page can be access by all; otherwise only the supervisor can access it */ + unsigned writethrough : 1; /* if set, write-through caching is enabled; otherwise write-back is enabled instead */ + unsigned cachedisable : 1; /* if set, the page will not be cached */ + unsigned accessed : 1; /* set by the CPU when the page is read from or written to */ + unsigned dirty : 1; /* used to determine whether a page has been written to */ + unsigned pat : 1; /* page attribute table? */ unsigned global : 1; - unsigned int __available__ : 3; // available to the OS + unsigned int __available__ : 3; /* available to the OS */ unsigned int address : 20; }; -_Static_assert(sizeof(struct TableEntry) == 4, "TableEntry size"); +/* TODO _Static_assert(sizeof(struct TableEntry) == 4, "TableEntry size"); */ diff --git a/i686/sys/control.h b/i686/sys/control.h index 7dde3c8..89ab067 100644 --- a/i686/sys/control.h +++ b/i686/sys/control.h @@ -1,25 +1,24 @@ #pragma once -static inline void +static __inline__ void abort() { /* Symbol h is already defined? -asm volatile(R"(cli +__asm__(R"(cli h: hlt jmp h)"); */ - asm volatile(R"(cli -hlt)"); + __asm__("cli; hlt"); } -static inline void +static __inline__ void enable_interrupts() { - asm volatile("sti"); + __asm__("sti"); } -static inline void +static __inline__ void disable_interrupts() { - asm volatile("cli"); + __asm__("cli"); } diff --git a/i686/sys/cpuid.h b/i686/sys/cpuid.h index 65b43c6..6613967 100644 --- a/i686/sys/cpuid.h +++ b/i686/sys/cpuid.h @@ -12,7 +12,7 @@ struct CPUVersion { unsigned int family_ex : 8; unsigned int __unused_2 : 4; } __attribute__((packed, aligned(__alignof__(unsigned int)))); -// FIXME _Static_assert(sizeof(struct CPUVersion) == sizeof(unsigned int), "cpuid version struct size"); +/* FIXME _Static_assert(sizeof(struct CPUVersion) == sizeof(unsigned int), "cpuid version struct size"); */ unsigned int family(const struct CPUVersion v) diff --git a/i686/sys/io.h b/i686/sys/io.h index da586b9..403dc54 100644 --- a/i686/sys/io.h +++ b/i686/sys/io.h @@ -1,6 +1,6 @@ #pragma once -// port listings +/* port listings */ enum UART { COM1 = 0x3f8, COM2 = 0x2f8, @@ -12,81 +12,81 @@ enum UART { COM8 = 0x4e8, }; -static inline void +static __inline__ void outb(unsigned char val, unsigned short port) { - asm volatile("outb %0,%1" : : "a"(val), "dN"(port)); + __asm__("outb %0,%1" : : "a"(val), "dN"(port)); } -static inline void +static __inline__ void outw(unsigned short val, unsigned short port) { - asm volatile("outw %0,%1" : : "a"(val), "dN"(port)); + __asm__("outw %0,%1" : : "a"(val), "dN"(port)); } -static inline void +static __inline__ void outl(unsigned int val, unsigned short port) { - asm volatile("outl %0,%1" : : "a"(val), "dN"(port)); + __asm__("outl %0,%1" : : "a"(val), "dN"(port)); } -static inline unsigned char +static __inline__ unsigned char inb(unsigned short port) { unsigned char val; - asm volatile("inb %1,%0" : "=a"(val) : "dN"(port)); + __asm__("inb %1,%0" : "=a"(val) : "dN"(port)); return val; } -static inline unsigned short +static __inline__ unsigned short inw(unsigned short port) { unsigned short val; - asm volatile("inw %1,%0" : "=a"(val) : "dN"(port)); + __asm__("inw %1,%0" : "=a"(val) : "dN"(port)); return val; } -static inline unsigned int +static __inline__ unsigned int inl(unsigned short port) { unsigned int val; - asm volatile("inl %1,%0" : "=a"(val) : "dN"(port)); + __asm__("inl %1,%0" : "=a"(val) : "dN"(port)); return val; } -static inline void +static __inline__ void outsb(unsigned short port, const void *__buf, unsigned long __n) { - asm volatile("cld; rep; outsb" : "+S"(__buf), "+c"(__n) : "d"(port)); + __asm__("cld; rep; outsb" : "+S"(__buf), "+c"(__n) : "d"(port)); } -static inline void +static __inline__ void outsw(unsigned short port, const void *__buf, unsigned long __n) { - asm volatile("cld; rep; outsw" : "+S"(__buf), "+c"(__n) : "d"(port)); + __asm__("cld; rep; outsw" : "+S"(__buf), "+c"(__n) : "d"(port)); } -static inline void +static __inline__ void outsl(unsigned short port, const void *__buf, unsigned long __n) { - asm volatile("cld; rep; outsl" : "+S"(__buf), "+c"(__n) : "d"(port)); + __asm__("cld; rep; outsl" : "+S"(__buf), "+c"(__n) : "d"(port)); } -static inline void +static __inline__ void insb(unsigned short port, void *__buf, unsigned long __n) { - asm volatile("cld; rep; insb" : "+D"(__buf), "+c"(__n) : "d"(port)); + __asm__("cld; rep; insb" : "+D"(__buf), "+c"(__n) : "d"(port)); } -static inline void +static __inline__ void insw(unsigned short port, void *__buf, unsigned long __n) { - asm volatile("cld; rep; insw" : "+D"(__buf), "+c"(__n) : "d"(port)); + __asm__("cld; rep; insw" : "+D"(__buf), "+c"(__n) : "d"(port)); } -static inline void +static __inline__ void insl(unsigned short port, void *__buf, unsigned long __n) { - asm volatile("cld; rep; insl" : "+D"(__buf), "+c"(__n) : "d"(port)); + __asm__("cld; rep; insl" : "+D"(__buf), "+c"(__n) : "d"(port)); } diff --git a/i686/test_gdt.cc b/i686/test_gdt.cc index d596c3a..e437168 100644 --- a/i686/test_gdt.cc +++ b/i686/test_gdt.cc @@ -1,6 +1,5 @@ #include -#define _Static_assert static_assert #include "gdt.c" #include "gdt.h" diff --git a/i686/toolchain.mk b/i686/toolchain.mk index f3f4732..460717e 100644 --- a/i686/toolchain.mk +++ b/i686/toolchain.mk @@ -3,10 +3,10 @@ ARCH=i686 # define compiler, linker, archiver and strip and their flags ${ARCH}_AS := i686-elf-as -${ARCH}_CC := i686-elf-gcc +${ARCH}_CC := i686-elf-gcc -ansi ${ARCH}_CCID := $(shell ${${ARCH}_CC} --version | head -n1) ${ARCH}_CFLAGS := -Wall -Wextra -Wpedantic -Werror=shadow -Wconversion -fanalyzer \ - -D__ARCH__="${ARCH}" -ffreestanding -std=gnu11 -mgeneral-regs-only \ + -D__ARCH__="${ARCH}" -ffreestanding -mgeneral-regs-only \ $(shell echo ${CONFIG_CFLAGS}) ${ARCH}_LD := i686-elf-ld -- cgit v1.2.1