diff --git a/Makefile b/Makefile index b3c7953..6b6faaf 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ endif ifeq ($(DEBUG), 1) CFLAGS += -DDEBUG -ggdb -O0 -fdiagnostics-color=always LDFLAGS += -ggdb -O0 -g - NASMFLAGS += -F dwarf -g + NASMFLAGS += -felf32 -g WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable ifeq ($(TESTING), 1) CFLAGS += -DTESTING diff --git a/arch/amd64/cpu/idt.hpp b/arch/amd64/cpu/idt.hpp index ecea884..2c7efe8 100644 --- a/arch/amd64/cpu/idt.hpp +++ b/arch/amd64/cpu/idt.hpp @@ -7,9 +7,9 @@ namespace InterruptDescriptorTable { typedef enum _InterruptDescriptorTableFlags { - FlagGate_TASK = 0b0101, - FlagGate_16BIT_INT = 0b0110, - FlagGate_16BIT_TRAP = 0b0111, + FlagGate_TASK = 0b101, + FlagGate_16BIT_INT = 0b110, + FlagGate_16BIT_TRAP = 0b111, FlagGate_32BIT_INT = 0b1110, FlagGate_32BIT_TRAP = 0b1111, FlagGate_RING0 = 0b0, diff --git a/arch/i686/ArithmeticOperations.c b/arch/i686/ArithmeticOperations.c new file mode 100644 index 0000000..29f6fa1 --- /dev/null +++ b/arch/i686/ArithmeticOperations.c @@ -0,0 +1,284 @@ +/* Source: https://github.com/glitchub/arith64 */ +#define arith64_u64 unsigned long long int +#define arith64_s64 signed long long int +#define arith64_u32 unsigned int +#define arith64_s32 int + +typedef union +{ + arith64_u64 u64; + arith64_s64 s64; + struct + { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + arith64_u32 hi; + arith64_u32 lo; +#else + arith64_u32 lo; + arith64_u32 hi; +#endif + } u32; + struct + { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + arith64_s32 hi; + arith64_s32 lo; +#else + arith64_s32 lo; + arith64_s32 hi; +#endif + } s32; +} arith64_word; + +#define arith64_hi(n) (arith64_word){.u64 = n}.u32.hi +#define arith64_lo(n) (arith64_word){.u64 = n}.u32.lo +#define arith64_neg(a, b) (((a) ^ ((((arith64_s64)(b)) >= 0) - 1)) + (((arith64_s64)(b)) < 0)) +#define arith64_abs(a) arith64_neg(a, a) + +arith64_s64 __absvdi2(arith64_s64 a) +{ + return arith64_abs(a); +} + +arith64_s64 __ashldi3(arith64_s64 a, int b) +{ + arith64_word w = {.s64 = a}; + + b &= 63; + + if (b >= 32) + { + w.u32.hi = w.u32.lo << (b - 32); + w.u32.lo = 0; + } + else if (b) + { + w.u32.hi = (w.u32.lo >> (32 - b)) | (w.u32.hi << b); + w.u32.lo <<= b; + } + return w.s64; +} + +arith64_s64 __ashrdi3(arith64_s64 a, int b) +{ + arith64_word w = {.s64 = a}; + + b &= 63; + + if (b >= 32) + { + w.s32.lo = w.s32.hi >> (b - 32); + w.s32.hi >>= 31; // 0xFFFFFFFF or 0 + } + else if (b) + { + w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b); + w.s32.hi >>= b; + } + return w.s64; +} + +int __clzsi2(arith64_u32 a) +{ + int b, n = 0; + b = !(a & 0xffff0000) << 4; + n += b; + a <<= b; + b = !(a & 0xff000000) << 3; + n += b; + a <<= b; + b = !(a & 0xf0000000) << 2; + n += b; + a <<= b; + b = !(a & 0xc0000000) << 1; + n += b; + a <<= b; + return n + !(a & 0x80000000); +} + +int __clzdi2(arith64_u64 a) +{ + int b, n = 0; + b = !(a & 0xffffffff00000000ULL) << 5; + n += b; + a <<= b; + b = !(a & 0xffff000000000000ULL) << 4; + n += b; + a <<= b; + b = !(a & 0xff00000000000000ULL) << 3; + n += b; + a <<= b; + b = !(a & 0xf000000000000000ULL) << 2; + n += b; + a <<= b; + b = !(a & 0xc000000000000000ULL) << 1; + n += b; + a <<= b; + return n + !(a & 0x8000000000000000ULL); +} + +int __ctzsi2(arith64_u32 a) +{ + int b, n = 0; + b = !(a & 0x0000ffff) << 4; + n += b; + a >>= b; + b = !(a & 0x000000ff) << 3; + n += b; + a >>= b; + b = !(a & 0x0000000f) << 2; + n += b; + a >>= b; + b = !(a & 0x00000003) << 1; + n += b; + a >>= b; + return n + !(a & 0x00000001); +} + +int __ctzdi2(arith64_u64 a) +{ + int b, n = 0; + b = !(a & 0x00000000ffffffffULL) << 5; + n += b; + a >>= b; + b = !(a & 0x000000000000ffffULL) << 4; + n += b; + a >>= b; + b = !(a & 0x00000000000000ffULL) << 3; + n += b; + a >>= b; + b = !(a & 0x000000000000000fULL) << 2; + n += b; + a >>= b; + b = !(a & 0x0000000000000003ULL) << 1; + n += b; + a >>= b; + return n + !(a & 0x0000000000000001ULL); +} + +arith64_u64 __divmoddi4(arith64_u64 a, arith64_u64 b, arith64_u64 *c) +{ + if (b > a) // + { + if (c) + *c = a; + return 0; + } + if (!arith64_hi(b)) + { + if (b == 0) + { + volatile char x = 0; + x = 1 / x; + } + if (b == 1) + { + if (c) + *c = 0; + return a; + } + if (!arith64_hi(a)) + { + if (c) + *c = arith64_lo(a) % arith64_lo(b); + return arith64_lo(a) / arith64_lo(b); + } + } + + + char bits = __clzdi2(b) - __clzdi2(a) + 1; + arith64_u64 rem = a >> bits; + a <<= 64 - bits; + arith64_u64 wrap = 0; + while (bits-- > 0) + { + rem = (rem << 1) | (a >> 63); + a = (a << 1) | (wrap & 1); + wrap = ((arith64_s64)(b - rem - 1) >> 63); + rem -= b & wrap; + } + if (c) + *c = rem; + return (a << 1) | (wrap & 1); +} + + +arith64_s64 __divdi3(arith64_s64 a, arith64_s64 b) +{ + arith64_u64 q = __divmoddi4(arith64_abs(a), arith64_abs(b), (void *)0); + return arith64_neg(q, a ^ b); +} + + + +int __ffsdi2(arith64_u64 a) +{ + return a ? __ctzdi2(a) + 1 : 0; +} + + +arith64_u64 __lshrdi3(arith64_u64 a, int b) +{ + arith64_word w = {.u64 = a}; + + b &= 63; + + if (b >= 32) + { + w.u32.lo = w.u32.hi >> (b - 32); + w.u32.hi = 0; + } + else if (b) + { + w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b); + w.u32.hi >>= b; + } + return w.u64; +} + + +arith64_s64 __moddi3(arith64_s64 a, arith64_s64 b) +{ + arith64_u64 r; + __divmoddi4(arith64_abs(a), arith64_abs(b), &r); + return arith64_neg(r, a); +} + + +int __popcountsi2(arith64_u32 a) +{ + + a = a - ((a >> 1) & 0x55555555); + a = ((a >> 2) & 0x33333333) + (a & 0x33333333); + a = (a + (a >> 4)) & 0x0F0F0F0F; + a = (a + (a >> 16)); + + return (a + (a >> 8)) & 63; +} + + +int __popcountdi2(arith64_u64 a) +{ + + a = a - ((a >> 1) & 0x5555555555555555ULL); + a = ((a >> 2) & 0x3333333333333333ULL) + (a & 0x3333333333333333ULL); + a = (a + (a >> 4)) & 0x0F0F0F0F0F0F0F0FULL; + a = (a + (a >> 32)); + a = (a + (a >> 16)); + + return (a + (a >> 8)) & 127; +} + + +arith64_u64 __udivdi3(arith64_u64 a, arith64_u64 b) +{ + return __divmoddi4(a, b, (void *)0); +} + + +arith64_u64 __umoddi3(arith64_u64 a, arith64_u64 b) +{ + arith64_u64 r; + __divmoddi4(a, b, &r); + return r; +} diff --git a/arch/i686/linker.ld b/arch/i686/linker.ld index e69de29..ab00c84 100644 --- a/arch/i686/linker.ld +++ b/arch/i686/linker.ld @@ -0,0 +1,44 @@ +OUTPUT_FORMAT(elf32-i386) +OUTPUT_ARCH(i386) + +ENTRY(kernel_entry) + +SECTIONS +{ + . += 0xC0000000; + + .text : + { + *(.text .text.*) + } + _kernel_text_end = ALIGN(CONSTANT(MAXPAGESIZE)); + . += CONSTANT(MAXPAGESIZE); + + .data : + { + *(.data .data.*) + } + _kernel_data_end = ALIGN(CONSTANT(MAXPAGESIZE)); + . += CONSTANT(MAXPAGESIZE); + + .rodata : + { + *(.rodata .rodata.*) + } + _kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE)); + . += CONSTANT(MAXPAGESIZE); + + .bss : + { + *(COMMON) + *(.bss .bss.*) + } + . += CONSTANT(MAXPAGESIZE); + _kernel_end = ALIGN(CONSTANT(MAXPAGESIZE)); + + /DISCARD/ : + { + *(.eh_frame) + *(.note .note.*) + } +}