Remove architecture-specific code

This commit is contained in:
Alex Kotov 2022-12-25 13:51:11 +04:00
parent 286361cabc
commit 78fbb3e7ec
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
22 changed files with 0 additions and 1005 deletions

View File

@ -44,27 +44,3 @@ libkernaux_la_SOURCES = src/runtime.c
if WITH_LIBC
libkernaux_la_LIBADD += libc/libc.la
endif
#######
# ARCH #
#######
if WITH_ARCH_I386
libkernaux_la_SOURCES += src/arch/i386/idt.c
endif
#######
# ASM #
#######
if WITH_ASM
if ASM_I386
libkernaux_la_SOURCES += src/asm/i386.S
endif
if ASM_RISCV64
libkernaux_la_SOURCES += src/asm/riscv64.S
endif
if ASM_X86_64
libkernaux_la_SOURCES += src/asm/x86_64.S
endif
endif

View File

@ -50,9 +50,6 @@ zero). Work-in-progress APIs can change at any time.
* [stdlib.h](/libc/include/stdlib.h)
* [string.h](/libc/include/string.h)
* [sys/types.h](/libc/include/sys/types.h)
* Architecture-specific code (*work in progress*)
* [Declarations](/include/kernaux/arch/)
* [Functions](/include/kernaux/asm/)
### Definitions
@ -114,17 +111,6 @@ stable options.
* `--(enable|disable)-float` - floating-point arithmetic
* `--(enable|disable)-werror` - fail on warning (`CFLAGS+='-Werror'`)
#### Packages
All packages are included by default. To exclude all packages except those
explicitly included, use `--without-all`.
* `--with[out]-arch-all` - all architectures
* `--with[out]-arch-i386` - architecture i386
* `--with[out]-arch-riscv64` - architecture riscv64
* `--with[out]-arch-x86-64` - architecture x86-64
* `--with[out]-asm` - kernel assembler helpers
Tips
@ -181,36 +167,3 @@ The variables include `AR`, `AS`, `CC`, `CCAS`, `LD`, `NM`, `OBJDUMP`, `RANLIB`,
To install into specific directory use full path: `DESTDIR="$(pwd)/dest" make
install` instead of `DESTDIR=dest make install`.
Check if compilation targets i386: `objdump -d src/asm/i386.o`. It should output
something like this:
```
src/asm/i386.o: file format elf32-i386
Disassembly of section .text:
00000000 <kernaux_asm_i386_read_cr0>:
0: 0f 20 c0 mov %cr0,%eax
3: c3 ret
00000004 <kernaux_asm_i386_read_cr4>:
4: 0f 20 e0 mov %cr4,%eax
7: c3 ret
00000008 <kernaux_asm_i386_write_cr0>:
8: 8b 44 24 04 mov 0x4(%esp),%eax
c: 0f 22 c0 mov %eax,%cr0
f: c3 ret
00000010 <kernaux_asm_i386_write_cr3>:
10: 8b 44 24 04 mov 0x4(%esp),%eax
14: 0f 22 d8 mov %eax,%cr3
17: c3 ret
00000018 <kernaux_asm_i386_write_cr4>:
18: 8b 44 24 04 mov 0x4(%esp),%eax
1c: 0f 22 e0 mov %eax,%cr4
1f: c3 ret
```

View File

@ -58,14 +58,6 @@ AC_ARG_ENABLE([split-libc], AS_HELP_STRING([--enable-split-libc], [spl
dnl Features (with parameter)
AC_ARG_ENABLE([pkg-config], AS_HELP_STRING([--enable-pkg-config@<:@=PATH@:>@], [install pkg-config files @<:@PATH='${libdir}/pkgconfig'@:>@]))
dnl Packages (enabled by default)
AC_ARG_WITH( [all], AS_HELP_STRING([--without-all], [without all default packages]))
AC_ARG_WITH( [arch-all], AS_HELP_STRING([--without-arch-all], [without all architectures]))
AC_ARG_WITH( [arch-i386], AS_HELP_STRING([--without-arch-i386], [without architecture i386]))
AC_ARG_WITH( [arch-riscv64], AS_HELP_STRING([--without-arch-riscv64], [without architecture riscv64]))
AC_ARG_WITH( [arch-x86-64], AS_HELP_STRING([--without-arch-x86-64], [without architecture x86-64]))
AC_ARG_WITH( [asm], AS_HELP_STRING([--without-asm], [without kernel assembler helpers]))
dnl Packages (disabled by default)
AC_ARG_WITH( [libc], AS_HELP_STRING([--with-libc], [with libc replacement]))
@ -82,23 +74,6 @@ if test -z "$enable_checks_cppcheck"; then enable_checks_cppcheck=yes; fi
])
AS_IF([test "$enable_checks_all" = yes], do_enable_checks_all)
AC_DEFUN([do_without_arch_all],
[
if test -z "$with_arch_i386"; then with_arch_i386=no; fi
if test -z "$with_arch_riscv64"; then with_arch_riscv64=no; fi
if test -z "$with_arch_x86_64"; then with_arch_x86_64=no; fi
])
AS_IF([test "$with_arch_all" = no], do_without_arch_all)
AC_DEFUN([do_without_all],
[
if test -z "$with_arch_i386"; then with_arch_i386=no; fi
if test -z "$with_arch_riscv64"; then with_arch_riscv64=no; fi
if test -z "$with_arch_x86_64"; then with_arch_x86_64=no; fi
if test -z "$with_asm"; then with_asm=no; fi
])
AS_IF([test "$with_all" = no], do_without_all)
##################
@ -121,14 +96,6 @@ dnl Features (with parameter)
AS_IF([test "$enable_pkg_config" = yes], [enable_pkg_config='${libdir}/pkgconfig'])
AS_IF([test "$enable_pkg_config" = no ], [enable_pkg_config=''])
dnl Packages (enabled by default)
AS_IF([test "$with_all" = no ], [with_all=no], [with_all=yes])
AS_IF([test "$with_arch_all" = no ], [with_arch_all=no], [with_arch_all=yes])
AS_IF([test "$with_arch_i386" = no ], [with_arch_i386=no], [with_arch_i386=yes])
AS_IF([test "$with_arch_riscv64" = no ], [with_arch_riscv64=no], [with_arch_riscv64=yes])
AS_IF([test "$with_arch_x86_64" = no ], [with_arch_x86_64=no], [with_arch_x86_64=yes])
AS_IF([test "$with_asm" = no ], [with_asm=no], [with_asm=yes])
dnl Packages (disabled by default)
AS_IF([test "$with_libc" = yes], [with_libc=yes], [with_libc=no])
@ -169,18 +136,9 @@ AM_CONDITIONAL([ENABLE_SPLIT_LIBC], [test "$enable_split_libc" = yes])
dnl Features (with parameter)
AM_CONDITIONAL([ENABLE_PKG_CONFIG], [test ! -z "$enable_pkg_config"])
dnl Packages (enabled by default)
AM_CONDITIONAL([WITH_ARCH_I386], [test "$with_arch_i386" = yes])
AM_CONDITIONAL([WITH_ARCH_RISCV64], [test "$with_arch_riscv64" = yes])
AM_CONDITIONAL([WITH_ARCH_X86_64], [test "$with_arch_x86_64" = yes])
AM_CONDITIONAL([WITH_ASM], [test "$with_asm" = yes])
dnl Packages (disabled by default)
AM_CONDITIONAL([WITH_LIBC], [test "$with_libc" = yes])
dnl Packages (virtual)
AM_CONDITIONAL([WITH_ARCH_X86], [test "$with_arch_i386" = yes -o "$with_arch_x86_64" = yes])
####################
@ -207,19 +165,9 @@ AS_IF([test "$enable_checks" = yes], [AC_DEFINE([ENABLE_CHECKS],
AS_IF([test "$enable_checks_cppcheck" = yes], [AC_DEFINE([ENABLE_CHECKS_CPPCHECK], [1], [enabled cppcheck])])
AS_IF([test "$enable_split_libc" = yes], [AC_DEFINE([ENABLE_SPLIT_LIBC], [1], [split off libc])])
dnl Packages (enabled by default)
AS_IF([test "$with_arch_i386" = yes], [AC_DEFINE([WITH_ARCH_I386], [1], [with architecture i386])])
AS_IF([test "$with_arch_riscv64" = yes], [AC_DEFINE([WITH_ARCH_RISCV64], [1], [with architecture riscv64])])
AS_IF([test "$with_arch_x86_64" = yes], [AC_DEFINE([WITH_ARCH_X86_64], [1], [with architecture x86_64])])
AS_IF([test "$with_asm" = yes], [AC_DEFINE([WITH_ASM], [1], [with kernel assembler helpers])])
dnl Packages (disabled by default)
AS_IF([test "$with_libc" = yes], [AC_DEFINE([WITH_LIBC], [1], [with libc replacement])])
dnl Packages (virtual)
AS_IF([test "$with_arch_i386" = yes], [AC_DEFINE([WITH_ARCH_X86], [1], [with architecture x86])])
AS_IF([test "$with_arch_x86_64" = yes], [AC_DEFINE([WITH_ARCH_X86], [1], [with architecture x86])])
##########################
@ -229,11 +177,6 @@ AS_IF([test "$with_arch_x86_64" = yes], [AC_DEFINE([WITH_ARCH_X86],
dnl Features (with parameter)
AC_SUBST([pkgconfdir], [$enable_pkg_config])
dnl Packages (enabled by default)
AS_IF([test "$with_arch_i386" = no], [AC_SUBST([comment_line_arch_i386], [//])])
AS_IF([test "$with_arch_riscv64" = no], [AC_SUBST([comment_line_arch_riscv64], [//])])
AS_IF([test "$with_arch_x86_64" = no], [AC_SUBST([comment_line_arch_x86_64], [//])])
###################

View File

@ -1,14 +1,5 @@
nobase_include_HEADERS = \
kernaux.h \
kernaux/arch/i386.h \
kernaux/arch/i386-idt.h \
kernaux/arch/riscv64.h \
kernaux/arch/x86_64.h \
kernaux/arch/x86.h \
kernaux/asm/i386.h \
kernaux/asm/riscv64.h \
kernaux/asm/x86_64.h \
kernaux/asm/x86.h \
kernaux/macro.h \
kernaux/macro/packing_end.run \
kernaux/macro/packing_start.run \

View File

@ -1,10 +1,2 @@
/*
We don't include <kernaux/asm/*.h> because they
contain architecture-specific assembly functions.
*/
#include <kernaux/arch/i386.h>
#include <kernaux/arch/riscv64.h>
#include <kernaux/arch/x86_64.h>
#include <kernaux/macro.h>
#include <kernaux/runtime.h>

View File

@ -1,62 +0,0 @@
#ifndef KERNAUX_INCLUDED_ARCH_I386_IDT
#define KERNAUX_INCLUDED_ARCH_I386_IDT
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/macro.h>
#include <stdint.h>
#include <kernaux/macro/packing_start.run>
/**
* @brief Interrupt Descriptor Table entry
*
* @see https://en.wikibooks.org/wiki/X86_Assembly/Advanced_Interrupts#The_Interrupt_Descriptor_Table
*/
typedef struct KernAux_Arch_I386_IDTE {
uint16_t offset_low;
uint16_t selector;
uint8_t _;
uint8_t flags;
uint16_t offset_high;
}
KERNAUX_PACKED
KERNAUX_ALIGNED(8)
*KernAux_Arch_I386_IDTE;
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Arch_I386_IDTE, 8);
#include <kernaux/macro/packing_end.run>
void KernAux_Arch_I386_IDTE_init_intr(
KernAux_Arch_I386_IDTE idte,
uint32_t offset,
uint16_t cs_selector,
uint8_t dpl
);
void KernAux_Arch_I386_IDTE_init_task(
KernAux_Arch_I386_IDTE idte,
uint16_t tss_selector,
uint8_t dpl
);
void KernAux_Arch_I386_IDTE_init_trap(
KernAux_Arch_I386_IDTE idte,
uint32_t offset,
uint16_t cs_selector,
uint8_t dpl
);
uint32_t KernAux_Arch_I386_IDTE_offset(KernAux_Arch_I386_IDTE idte);
uint8_t KernAux_Arch_I386_IDTE_dpl (KernAux_Arch_I386_IDTE idte);
void
KernAux_Arch_I386_IDTE_set_offset(KernAux_Arch_I386_IDTE idte, uint32_t offset);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,217 +0,0 @@
#ifndef KERNAUX_INCLUDED_ARCH_I386
#define KERNAUX_INCLUDED_ARCH_I386
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/arch/i386-idt.h>
#include <kernaux/arch/x86.h>
#include <kernaux/macro.h>
#include <stdbool.h>
#include <stdint.h>
#define KERNAUX_ARCH_I386_PAGE_SIZE (1024 * 4) // 4 KiB
#define KERNAUX_ARCH_I386_PAGE_BIG_SIZE (1024 * 1024 * 4) // 4 MiB
#define KERNAUX_ARCH_I386_PAGE_DIR_ENTRIES_COUNT 1024
#define KERNAUX_ARCH_I386_PAGE_TABLE_ENTRIES_COUNT 1024
#define KERNAUX_ARCH_I386_PAGES_COUNT_MAX (1024 * 1024)
#define KERNAUX_ARCH_I386_ADDR_TO_PDE_INDEX(addr) \
((((uint32_t)addr) & 0xffffffff) >> 22)
#define KERNAUX_ARCH_I386_ADDR_TO_PTE_INDEX(addr) \
(((((uint32_t)addr) & 0xffffffff) >> 12) & 0x3ff)
#define KERNAUX_ARCH_I386_ADDR_TO_PDE_ADDR(addr) \
((((uint32_t)addr) & 0xffffffff) >> 12)
#define KERNAUX_ARCH_I386_ADDR_TO_PTE_ADDR(addr) \
KERNAUX_ARCH_I386_ADDR_TO_PDE_ADDR(addr)
#include <kernaux/macro/packing_start.run>
/**
* @brief CR0 bits
*
* @details
* Contains system control flags that control
* operating mode and states of the processor.
*
* @see https://en.wikipedia.org/wiki/Control_register#CR0
* @see https://wiki.osdev.org/CPU_Registers_x86#CR0
*/
KERNAUX_ARCH_X86_DEFINE_CR0(I386, uint32_t);
KERNAUX_STATIC_TEST_UNION_SIZE(KernAux_Arch_I386_CR0, 4);
/**
* @brief CR4 bits
*
* @details
* Contains a group of flags that enable several architectural extensions,
* and indicate operating system or executive support for specific processor
* capabilities.
*
* @see https://en.wikipedia.org/wiki/Control_register#CR4
* @see https://wiki.osdev.org/CPU_Registers_x86#CR4
*/
KERNAUX_ARCH_X86_DEFINE_CR4(I386, uint32_t);
KERNAUX_STATIC_TEST_UNION_SIZE(KernAux_Arch_I386_CR4, 4);
// Global, local or interrupt descriptor table register
// TODO: validate this according to spec
struct KernAux_Arch_I386_DTR {
uint16_t size;
uint32_t offset;
}
KERNAUX_PACKED;
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Arch_I386_DTR, 6);
// Global or local descriptor table entry
// TODO: validate this according to spec
struct KernAux_Arch_I386_DTE {
uint16_t limit_low;
unsigned base_low : 24;
unsigned accessed : 1;
unsigned read_write : 1;
unsigned conforming_expand_down : 1;
unsigned code : 1;
unsigned always_1 : 1;
unsigned DPL : 2;
unsigned present : 1;
unsigned limit_high : 4;
unsigned available : 1;
unsigned always_0 : 1;
unsigned big : 1;
unsigned gran : 1;
uint8_t base_high;
}
KERNAUX_PACKED;
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Arch_I386_DTE, 8);
/**
* @brief Task state segment
* @see The manual, page 132, figure 7-1
*/
struct KernAux_Arch_I386_TSS {
// 0x00
uint16_t prev_tss;
uint16_t _zero0;
// 0x04
uint32_t esp0;
uint16_t ss0;
uint16_t _zero1;
uint32_t esp1;
uint16_t ss1;
uint16_t _zero2;
uint32_t esp2;
uint16_t ss2;
uint16_t _zero3;
// 0x1c
uint32_t cr3;
uint32_t eip;
uint32_t eflags;
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t ebx;
uint32_t esp;
uint32_t ebp;
uint32_t esi;
uint32_t edi;
// 0x48
uint16_t es;
uint16_t _zero4;
uint16_t cs;
uint16_t _zero5;
uint16_t ss;
uint16_t _zero6;
uint16_t ds;
uint16_t _zero7;
uint16_t fs;
uint16_t _zero8;
uint16_t gs;
uint16_t _zero9;
uint16_t ldt;
uint16_t _zero10;
// 0x64
uint16_t _zero11;
uint16_t io_map_base;
}
KERNAUX_PACKED;
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Arch_I386_TSS, 104);
// Page directory entry
// TODO: validate this according to spec
union KernAux_Arch_I386_PDE {
uint32_t number;
#ifdef KERNAUX_BITFIELDS
struct {
unsigned present : 1;
unsigned writable : 1;
unsigned user : 1;
unsigned write_through : 1;
unsigned cache_disabled : 1;
unsigned accessed : 1;
unsigned available0 : 1;
unsigned page_size : 1;
unsigned available1 : 4;
unsigned addr : 20;
} KERNAUX_PACKED bitfields;
#endif
}
KERNAUX_PACKED;
KERNAUX_STATIC_TEST_UNION_SIZE(KernAux_Arch_I386_PDE, 4);
// Page table entry
// TODO: validate this according to spec
union KernAux_Arch_I386_PTE {
uint32_t number;
#ifdef KERNAUX_BITFIELDS
struct {
unsigned present : 1;
unsigned writable : 1;
unsigned user : 1;
unsigned write_through : 1;
unsigned cache_disabled : 1;
unsigned accessed : 1;
unsigned dirty : 1;
unsigned attr_table : 1;
unsigned global : 1;
unsigned available : 3;
unsigned addr : 20;
} KERNAUX_PACKED bitfields;
#endif
}
KERNAUX_PACKED;
KERNAUX_STATIC_TEST_UNION_SIZE(KernAux_Arch_I386_PTE, 4);
// Page directory
struct KernAux_Arch_I386_PageDir {
union KernAux_Arch_I386_PDE pdes[KERNAUX_ARCH_I386_PAGE_DIR_ENTRIES_COUNT];
}
KERNAUX_PACKED;
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Arch_I386_PageDir, KERNAUX_ARCH_I386_PAGE_SIZE);
// Page table
struct KernAux_Arch_I386_PageTable {
union KernAux_Arch_I386_PTE ptes[KERNAUX_ARCH_I386_PAGE_TABLE_ENTRIES_COUNT];
}
KERNAUX_PACKED;
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Arch_I386_PageTable, KERNAUX_ARCH_I386_PAGE_SIZE);
#include <kernaux/macro/packing_end.run>
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,12 +0,0 @@
#ifndef KERNAUX_INCLUDED_ARCH_RISCV64
#define KERNAUX_INCLUDED_ARCH_RISCV64
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,113 +0,0 @@
#ifndef KERNAUX_INCLUDED_ARCH_X86
#define KERNAUX_INCLUDED_ARCH_X86
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/macro.h>
#include <stdbool.h>
#ifndef KERNAUX_BITFIELDS
#define KERNAUX_ARCH_X86_DEFINE_CR0(arch, number_type) \
union KernAux_Arch_##arch##_CR0 { number_type number; } KERNAUX_PACKED
#else
#define KERNAUX_ARCH_X86_DEFINE_CR0(arch, number_type) \
union KernAux_Arch_##arch##_CR0 { \
number_type number; \
struct { \
bool pe : 1; /* 0: Protection Enable */ \
bool mp : 1; /* 1: Monitor Coprocessor */ \
bool em : 1; /* 2: Emulation (x87 FPU) */ \
bool ts : 1; /* 3: Task Switched */ \
bool et : 1; /* 4: Extension Type */ \
bool ne : 1; /* 5: Numeric Error */ \
unsigned _0 : 10; \
bool wp : 1; /* 16: Write Protect */ \
unsigned _1 : 1; \
bool am : 1; /* 18: Alignment Mask */ \
unsigned _2 : 10; \
bool nw : 1; /* 29: Not Write-trough */ \
bool cd : 1; /* 30: Cache Disable */ \
bool pg : 1; /* 31: Paging */ \
} KERNAUX_PACKED bitfields; \
} KERNAUX_PACKED
#endif
#define KERNAUX_ARCH_X86_CR0_PE KERNAUX_BITS32(0) // Protection Enable
#define KERNAUX_ARCH_X86_CR0_MP KERNAUX_BITS32(1) // Monitor Coprocessor
#define KERNAUX_ARCH_X86_CR0_EM KERNAUX_BITS32(2) // Emulation (x87 FPU)
#define KERNAUX_ARCH_X86_CR0_TS KERNAUX_BITS32(3) // Task Switched
#define KERNAUX_ARCH_X86_CR0_ET KERNAUX_BITS32(4) // Extension Type
#define KERNAUX_ARCH_X86_CR0_NE KERNAUX_BITS32(5) // Numeric Error
#define KERNAUX_ARCH_X86_CR0_WP KERNAUX_BITS32(16) // Write Protect
#define KERNAUX_ARCH_X86_CR0_AM KERNAUX_BITS32(18) // Alignment Mask
#define KERNAUX_ARCH_X86_CR0_NW KERNAUX_BITS32(29) // Not Write-trough
#define KERNAUX_ARCH_X86_CR0_CD KERNAUX_BITS32(30) // Cache Disable
#define KERNAUX_ARCH_X86_CR0_PG KERNAUX_BITS32(31) // Paging
#ifndef KERNAUX_BITFIELDS
#define KERNAUX_ARCH_X86_DEFINE_CR4(arch, number_type) \
union KernAux_Arch_##arch##_CR4 { number_type number; } KERNAUX_PACKED
#else
#define KERNAUX_ARCH_X86_DEFINE_CR4(arch, number_type) \
union KernAux_Arch_##arch##_CR4 { \
number_type number; \
struct { \
bool vme : 1; /* 0: Virtual-8086 Mode Extensions */ \
bool pvi : 1; /* 1: Protected-Mode Virtual Interrupts */ \
bool tsd : 1; /* 2: Time Stamp Disable */ \
bool de : 1; /* 3: Debugging Extensions */ \
bool pse : 1; /* 4: Page Size Extension */ \
bool pae : 1; /* 5: Physical Address Extension */ \
bool mce : 1; /* 6: Machine-Check Exception */ \
bool pge : 1; /* 7: Page Global Enable */ \
bool pce : 1; /* 8: Performance-Monitoring Counter Enabled */ \
bool osfxsr : 1; /* 9: Operating System Support for */ \
/* FXSAVE and FXRSTOR instructions */ \
bool osxmmexcpt : 1; /* 10: Operating System Support for */ \
/* Unmasked SIMD Floating-Point Exceptions */ \
bool umip : 1; /* 11: User-Mode Instruction Prevention */ \
unsigned _0 : 1; \
bool vmxe : 1; /* 13: VME (Virtual Machine Extensions) Enable */ \
bool smxe : 1; /* 14: SME (Safer Mode Extensions) Enable */ \
unsigned _1 : 1; \
bool fsgsbase : 1; /* 16: FSGSBASE Enable */ \
bool pcide : 1; /* 17: PCID Enable */ \
bool osxsave : 1; /* 18: XSAVE and Processor Extended States Enable */ \
unsigned _2 : 1; \
bool smep : 1; /* 20: SMEP (Supervisor Mode Execution Protection) Enable */ \
bool smap : 1; /* 21: SMAP (Supervisor Mode Access Prevention) Enable */ \
bool pke : 1; /* 22: Protection Key Enable */ \
unsigned _3 : 9; \
} KERNAUX_PACKED bitfields; \
} KERNAUX_PACKED
#endif
#define KERNAUX_ARCH_X86_CR4_VME KERNAUX_BITS32(0) // Virtual-8086 Mode Extensions
#define KERNAUX_ARCH_X86_CR4_PVI KERNAUX_BITS32(1) // Protected-Mode Virtual Interrupts
#define KERNAUX_ARCH_X86_CR4_TSD KERNAUX_BITS32(2) // Time Stamp Disable
#define KERNAUX_ARCH_X86_CR4_DE KERNAUX_BITS32(3) // Debugging Extensions
#define KERNAUX_ARCH_X86_CR4_PSE KERNAUX_BITS32(4) // Page Size Extension
#define KERNAUX_ARCH_X86_CR4_PAE KERNAUX_BITS32(5) // Physical Address Extension
#define KERNAUX_ARCH_X86_CR4_MCE KERNAUX_BITS32(6) // Machine-Check Exception
#define KERNAUX_ARCH_X86_CR4_PGE KERNAUX_BITS32(7) // Page Global Enable
#define KERNAUX_ARCH_X86_CR4_PCE KERNAUX_BITS32(8) // Performance-Monitoring Counter Enabled
#define KERNAUX_ARCH_X86_CR4_OSFXSR KERNAUX_BITS32(9) // Operating System Support for FXSAVE and FXRSTOR instructions
#define KERNAUX_ARCH_X86_CR4_OSXMMEXCPT KERNAUX_BITS32(10) // Operating System Support for Unmasked SIMD Floating-Point Exceptions
#define KERNAUX_ARCH_X86_CR4_UMIP KERNAUX_BITS32(11) // User-Mode Instruction Prevention
#define KERNAUX_ARCH_X86_CR4_VMXE KERNAUX_BITS32(13) // VME (Virtual Machine Extensions) Enable
#define KERNAUX_ARCH_X86_CR4_SMXE KERNAUX_BITS32(14) // SME (Safer Mode Extensions) Enable
#define KERNAUX_ARCH_X86_CR4_FSGSBASE KERNAUX_BITS32(16) // FSGSBASE Enable (enable the instructions RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE)
#define KERNAUX_ARCH_X86_CR4_PCIDE KERNAUX_BITS32(17) // PCID Enable
#define KERNAUX_ARCH_X86_CR4_OSXSAVE KERNAUX_BITS32(18) // XSAVE and Processor Extended States Enable
#define KERNAUX_ARCH_X86_CR4_SMEP KERNAUX_BITS32(20) // SMEP (Supervisor Mode Execution Protection) Enable
#define KERNAUX_ARCH_X86_CR4_SMAP KERNAUX_BITS32(21) // SMAP (Supervisor Mode Access Prevention) Enable
#define KERNAUX_ARCH_X86_CR4_PKE KERNAUX_BITS32(22) // Protection Key Enable
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,41 +0,0 @@
#ifndef KERNAUX_INCLUDED_ARCH_X86_64
#define KERNAUX_INCLUDED_ARCH_X86_64
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/arch/x86.h>
/**
* @brief CR0 bits
*
* @details
* Contains system control flags that control
* operating mode and states of the processor.
*
* @see https://en.wikipedia.org/wiki/Control_register#CR0
* @see https://wiki.osdev.org/CPU_Registers_x86#CR0
*/
KERNAUX_ARCH_X86_DEFINE_CR0(X86_64, uint64_t);
KERNAUX_STATIC_TEST_UNION_SIZE(KernAux_Arch_X86_64_CR0, 8);
/**
* @brief CR4 bits
*
* @details
* Contains a group of flags that enable several architectural extensions,
* and indicate operating system or executive support for specific processor
* capabilities.
*
* @see https://en.wikipedia.org/wiki/Control_register#CR4
* @see https://wiki.osdev.org/CPU_Registers_x86#CR4
*/
KERNAUX_ARCH_X86_DEFINE_CR4(X86_64, uint64_t);
KERNAUX_STATIC_TEST_UNION_SIZE(KernAux_Arch_X86_64_CR4, 8);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,30 +0,0 @@
#ifndef KERNAUX_INCLUDED_ASM_I386
#define KERNAUX_INCLUDED_ASM_I386
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/arch/i386.h>
#include <kernaux/asm/x86.h>
void kernaux_asm_i386_flush_gdt(
volatile uint32_t pointer,
volatile uint32_t data_selector,
volatile uint32_t code_selector
);
void kernaux_asm_i386_flush_idt(volatile uint32_t pointer);
void kernaux_asm_i386_flush_tss(volatile uint16_t selector);
uint32_t kernaux_asm_i386_read_cr0();
uint32_t kernaux_asm_i386_read_cr4();
void kernaux_asm_i386_write_cr0(volatile uint32_t value);
void kernaux_asm_i386_write_cr3(volatile uint32_t value);
void kernaux_asm_i386_write_cr4(volatile uint32_t value);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,14 +0,0 @@
#ifndef KERNAUX_INCLUDED_ASM_RISCV64
#define KERNAUX_INCLUDED_ASM_RISCV64
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/arch/riscv64.h>
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,61 +0,0 @@
#ifndef KERNAUX_INCLUDED_ASM_X86
#define KERNAUX_INCLUDED_ASM_X86
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/arch/x86.h>
#include <kernaux/macro.h>
#include <stdint.h>
inline static uint8_t kernaux_asm_x86_inportb(uint16_t port);
inline static uint16_t kernaux_asm_x86_inportw(uint16_t port);
inline static uint32_t kernaux_asm_x86_inportd(uint16_t port);
inline static void kernaux_asm_x86_outportb(uint16_t port, uint8_t value);
inline static void kernaux_asm_x86_outportw(uint16_t port, uint16_t value);
inline static void kernaux_asm_x86_outportd(uint16_t port, uint32_t value);
uint8_t kernaux_asm_x86_inportb(const uint16_t port)
{
register uint8_t result;
KERNAUX_ASM("inb %1, %0" : "=a" (result) : "dN" (port));
return result;
}
uint16_t kernaux_asm_x86_inportw(const uint16_t port)
{
register uint16_t result;
KERNAUX_ASM("inw %1, %0" : "=a" (result) : "dN" (port));
return result;
}
uint32_t kernaux_asm_x86_inportd(const uint16_t port)
{
register uint32_t result;
KERNAUX_ASM("inl %1, %0" : "=a" (result) : "dN" (port));
return result;
}
void kernaux_asm_x86_outportb(const uint16_t port, const uint8_t value)
{
KERNAUX_ASM("outb %1, %0" : : "dN" (port), "a" (value));
}
void kernaux_asm_x86_outportw(const uint16_t port, const uint16_t value)
{
KERNAUX_ASM("outw %1, %0" : : "dN" (port), "a" (value));
}
void kernaux_asm_x86_outportd(const uint16_t port, const uint32_t value)
{
KERNAUX_ASM("outl %1, %0" : : "dN" (port), "a" (value));
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,15 +0,0 @@
#ifndef KERNAUX_INCLUDED_ASM_X86_64
#define KERNAUX_INCLUDED_ASM_X86_64
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/arch/x86_64.h>
#include <kernaux/asm/x86.h>
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,13 +1,4 @@
include/kernaux.h
include/kernaux/arch/i386-idt.h
include/kernaux/arch/i386.h
include/kernaux/arch/riscv64.h
include/kernaux/arch/x86.h
include/kernaux/arch/x86_64.h
include/kernaux/asm/i386.h
include/kernaux/asm/riscv64.h
include/kernaux/asm/x86.h
include/kernaux/asm/x86_64.h
include/kernaux/macro.h
include/kernaux/macro/packing_end.run
include/kernaux/macro/packing_start.run

View File

@ -1,75 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "../../assert.h"
#include <kernaux/arch/i386.h>
#include <string.h>
#define DPL (0x60u & (dpl << 5))
void KernAux_Arch_I386_IDTE_init_intr(
const KernAux_Arch_I386_IDTE idte,
const uint32_t offset,
const uint16_t cs_selector,
const uint8_t dpl
) {
KERNAUX_NOTNULL(idte);
memset(idte, 0, sizeof(*idte));
KernAux_Arch_I386_IDTE_set_offset(idte, offset);
idte->selector = cs_selector;
idte->flags |= 0x80u | DPL | 0xeu; // 1-00-01110
}
void KernAux_Arch_I386_IDTE_init_task(
const KernAux_Arch_I386_IDTE idte,
const uint16_t tss_selector,
const uint8_t dpl
) {
KERNAUX_NOTNULL(idte);
memset(idte, 0, sizeof(*idte));
idte->selector = tss_selector;
idte->flags |= 0x80u | DPL | 0x5u; // 1-00-00101
}
void KernAux_Arch_I386_IDTE_init_trap(
const KernAux_Arch_I386_IDTE idte,
const uint32_t offset,
const uint16_t cs_selector,
const uint8_t dpl
) {
KERNAUX_NOTNULL(idte);
memset(idte, 0, sizeof(*idte));
KernAux_Arch_I386_IDTE_set_offset(idte, offset);
idte->selector = cs_selector;
idte->flags |= 0x80u | DPL | 0xfu; // 1-00-01111
}
uint32_t KernAux_Arch_I386_IDTE_offset(const KernAux_Arch_I386_IDTE idte)
{
KERNAUX_NOTNULL(idte);
return (idte->offset_high << 16) | idte->offset_low;
}
uint8_t KernAux_Arch_I386_IDTE_dpl(const KernAux_Arch_I386_IDTE idte)
{
KERNAUX_NOTNULL(idte);
return 3 & (idte->flags >> 5);
}
void KernAux_Arch_I386_IDTE_set_offset(
const KernAux_Arch_I386_IDTE idte,
const uint32_t offset
) {
KERNAUX_NOTNULL(idte);
idte->offset_low = 0xffffu & offset;
idte->offset_high = 0xffffu & (offset >> 16);
}

View File

@ -1,60 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
.global kernaux_asm_i386_flush_gdt
.global kernaux_asm_i386_flush_idt
.global kernaux_asm_i386_flush_tss
.global kernaux_asm_i386_read_cr0
.global kernaux_asm_i386_read_cr4
.global kernaux_asm_i386_write_cr0
.global kernaux_asm_i386_write_cr3
.global kernaux_asm_i386_write_cr4
kernaux_asm_i386_flush_gdt:
mov 4(%esp), %eax
mov 8(%esp), %edx
lgdt (%eax)
mov %edx, %ds
mov %edx, %es
mov %edx, %fs
mov %edx, %gs
mov %edx, %ss
pushl 12(%esp)
push $.flush
ljmp *(%esp)
.flush:
ret
kernaux_asm_i386_flush_idt:
mov 4(%esp), %eax
lidt (%eax)
ret
kernaux_asm_i386_flush_tss:
mov 4(%esp), %ax
ltr %ax
ret
kernaux_asm_i386_read_cr0:
mov %cr0, %eax
ret
kernaux_asm_i386_read_cr4:
mov %cr4, %eax
ret
kernaux_asm_i386_write_cr0:
mov 4(%esp), %eax
mov %eax, %cr0
ret
kernaux_asm_i386_write_cr3:
mov 4(%esp), %eax
mov %eax, %cr3
ret
kernaux_asm_i386_write_cr4:
mov 4(%esp), %eax
mov %eax, %cr4
ret

View File

@ -1,3 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

View File

@ -1,3 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

1
tests/.gitignore vendored
View File

@ -1 +0,0 @@
/test_arch_i386

View File

@ -3,15 +3,3 @@ include $(top_srcdir)/make/shared.am
CLEANFILES =
TESTS =
noinst_PROGRAMS = $(TESTS)
##################
# test_arch_i386 #
##################
if WITH_ARCH_I386
TESTS += test_arch_i386
test_arch_i386_LDADD = $(top_builddir)/libkernaux.la
test_arch_i386_SOURCES = \
main.c \
test_arch_i386.c
endif

View File

@ -1,132 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <kernaux/arch/i386.h>
#include <assert.h>
#include <string.h>
static void test_idte_init_intr();
static void test_idte_init_task();
static void test_idte_init_trap();
static void test_idte_get_and_set_offset();
static void test_idte_get_dpl();
void test_main()
{
test_idte_init_intr();
test_idte_init_task();
test_idte_init_trap();
test_idte_get_and_set_offset();
test_idte_get_dpl();
}
void test_idte_init_intr()
{
struct KernAux_Arch_I386_IDTE idte;
memset(&idte, 0xff, sizeof(idte));
KernAux_Arch_I386_IDTE_init_intr(&idte, 0x12345678, 0xcafe, 0);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0x12345678);
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 0);
assert(idte.selector == 0xcafe);
assert(idte._ == 0);
assert(idte.flags == 0x8e); // 1-00-01110
KernAux_Arch_I386_IDTE_init_intr(&idte, 0x12345678, 0xcafe, 3);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0x12345678);
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 3);
assert(idte.selector == 0xcafe);
assert(idte._ == 0);
assert(idte.flags == 0xee); // 1-11-01110
}
void test_idte_init_task()
{
struct KernAux_Arch_I386_IDTE idte;
memset(&idte, 0xff, sizeof(idte));
KernAux_Arch_I386_IDTE_init_task(&idte, 0xcafe, 0);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0);
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 0);
assert(idte.selector == 0xcafe);
assert(idte._ == 0);
assert(idte.flags == 0x85); // 1-00-00101
KernAux_Arch_I386_IDTE_init_task(&idte, 0xcafe, 3);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0);
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 3);
assert(idte.selector == 0xcafe);
assert(idte._ == 0);
assert(idte.flags == 0xe5); // 1-11-00101
}
void test_idte_init_trap()
{
struct KernAux_Arch_I386_IDTE idte;
memset(&idte, 0xff, sizeof(idte));
KernAux_Arch_I386_IDTE_init_trap(&idte, 0x12345678, 0xcafe, 0);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0x12345678);
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 0);
assert(idte.selector == 0xcafe);
assert(idte._ == 0);
assert(idte.flags == 0x8f); // 1-00-01111
KernAux_Arch_I386_IDTE_init_trap(&idte, 0x12345678, 0xcafe, 3);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0x12345678);
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 3);
assert(idte.selector == 0xcafe);
assert(idte._ == 0);
assert(idte.flags == 0xef); // 1-11-01111
}
void test_idte_get_and_set_offset()
{
struct KernAux_Arch_I386_IDTE idte;
memset(&idte, 0xff, sizeof(idte));
KernAux_Arch_I386_IDTE_set_offset(&idte, 0);
assert(idte.offset_high == 0);
assert(idte.offset_low == 0);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0);
memset(&idte, 0, sizeof(idte));
KernAux_Arch_I386_IDTE_set_offset(&idte, 0xffffffff);
assert(idte.offset_high == 0xffff);
assert(idte.offset_low == 0xffff);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0xffffffff);
memset(&idte, 0, sizeof(idte));
KernAux_Arch_I386_IDTE_set_offset(&idte, 0x12345678);
assert(idte.offset_high == 0x1234);
assert(idte.offset_low == 0x5678);
assert(KernAux_Arch_I386_IDTE_offset(&idte) == 0x12345678);
}
void test_idte_get_dpl()
{
struct KernAux_Arch_I386_IDTE idte;
memset(&idte, 0, sizeof(idte));
idte.flags = 0; // 0-00-00000
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 0);
idte.flags = 0x80; // 1-00-00000
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 0);
idte.flags = 0x20; // 0-01-00000
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 1);
idte.flags = 0xa0; // 1-01-00000
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 1);
idte.flags = 0x40; // 0-10-00000
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 2);
idte.flags = 0xc0; // 1-10-00000
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 2);
idte.flags = 0x60; // 0-11-00000
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 3);
idte.flags = 0xe0; // 1-11-00000
assert(KernAux_Arch_I386_IDTE_dpl(&idte) == 3);
}