From 971b2f4803da963993afc0d5aa640fc4d93fcbda Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Mon, 28 Nov 2022 15:00:34 +0400 Subject: [PATCH] Add i386 stuff (#116) * Add struct KernAux_Arch_I386_IDTE * Add struct KernAux_Arch_I386_DTR * Remove unnecessary static check * Add func KernAux_Arch_I386_IDTE_set_offset --- .gitignore | 1 + include/kernaux/arch/i386.h | 27 +++++++++++++++++++++++++++ src/arch/i386.c | 11 ++++++++--- tests/Makefile.am | 12 ++++++++++++ tests/test_arch_i386.c | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 tests/test_arch_i386.c diff --git a/.gitignore b/.gitignore index a7343fb..0637360 100644 --- a/.gitignore +++ b/.gitignore @@ -126,6 +126,7 @@ /tests/multiboot2_header_print2 /tests/multiboot2_info_print1 /tests/multiboot2_info_print2 +/tests/test_arch_i386 /tests/test_cmdline /tests/test_cmdline_gen /tests/test_cmdline_gen.c diff --git a/include/kernaux/arch/i386.h b/include/kernaux/arch/i386.h index 1622004..1d364ab 100644 --- a/include/kernaux/arch/i386.h +++ b/include/kernaux/arch/i386.h @@ -53,6 +53,16 @@ extern "C" { #include +// 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_PACKING_ATTR; + +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 { @@ -74,8 +84,25 @@ struct KernAux_Arch_I386_DTE { } KERNAUX_PACKING_ATTR; +// Interrupt descriptor table entry +// TODO: validate this according to spec +typedef struct KernAux_Arch_I386_IDTE { + uint16_t offset_low; + uint16_t selector; + uint8_t _zero0; + uint8_t flags; + uint16_t offset_high; +} +KERNAUX_PACKING_ATTR +*KernAux_Arch_I386_IDTE; + KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Arch_I386_DTE, 8); +void KernAux_Arch_I386_IDTE_set_offset( + KernAux_Arch_I386_IDTE idte, + uint32_t address +); + /** * @brief Task state segment * @see The manual, page 132, figure 7-1 diff --git a/src/arch/i386.c b/src/arch/i386.c index edb517a..7337f74 100644 --- a/src/arch/i386.c +++ b/src/arch/i386.c @@ -4,6 +4,11 @@ #include -__attribute__((unused)) -static const int -TSS_validation[sizeof(struct KernAux_Arch_I386_TSS) == 104 ? 1 : -1]; +void KernAux_Arch_I386_IDTE_set_offset( + const KernAux_Arch_I386_IDTE idte, + const uint32_t address +) +{ + idte->offset_low = 0xFFFF & address; + idte->offset_high = 0xFFFF & (address >> 16); +} diff --git a/tests/Makefile.am b/tests/Makefile.am index 8049c44..6c15a82 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -56,6 +56,18 @@ multiboot2_info_print2_SOURCES = \ multiboot2_info_example2.h endif +################## +# 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 + ################ # test_cmdline # ################ diff --git a/tests/test_arch_i386.c b/tests/test_arch_i386.c new file mode 100644 index 0000000..37a931a --- /dev/null +++ b/tests/test_arch_i386.c @@ -0,0 +1,33 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +static void test_idte_set_offset(); + +void test_main() +{ + test_idte_set_offset(); +} + +void test_idte_set_offset() +{ + struct KernAux_Arch_I386_IDTE idte; + memset(&idte, 0, sizeof(idte)); + + KernAux_Arch_I386_IDTE_set_offset(&idte, 0); + assert(idte.offset_high == 0); + assert(idte.offset_low == 0); + + KernAux_Arch_I386_IDTE_set_offset(&idte, 0xFFFFFFFF); + assert(idte.offset_high == 0xFFFF); + assert(idte.offset_low == 0xFFFF); + + KernAux_Arch_I386_IDTE_set_offset(&idte, 0x12345678); + assert(idte.offset_high == 0x1234); + assert(idte.offset_low == 0x5678); +}