From cd133ba10b0370b8db78501d11f20062ce2d7805 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Mon, 28 Nov 2022 15:56:37 +0400 Subject: [PATCH] Add architecture x86 (any of i386 and x86_64) (#117) --- configure.ac | 14 ++++++++ include/Makefile.am | 8 +++++ include/kernaux/arch/i386.h | 1 + include/kernaux/arch/riscv64.h | 2 -- include/kernaux/arch/x86.h | 12 +++++++ include/kernaux/arch/x86_64.h | 2 +- include/kernaux/asm/i386.h | 45 +------------------------ include/kernaux/asm/x86.h | 60 +++++++++++++++++++++++++++++++++ include/kernaux/asm/x86_64.h | 45 +------------------------ src/drivers/console.c | 7 ++-- src/drivers/intel_8253_pit.c | 11 ++---- src/drivers/intel_8259_pic.c | 61 +++++++++++++++++----------------- 12 files changed, 133 insertions(+), 135 deletions(-) create mode 100644 include/kernaux/arch/x86.h create mode 100644 include/kernaux/asm/x86.h diff --git a/configure.ac b/configure.ac index 4f53663..76b4d4c 100644 --- a/configure.ac +++ b/configure.ac @@ -185,6 +185,9 @@ AM_CONDITIONAL([ASM_I386], [test "$host_cpu" = i386]) AM_CONDITIONAL([ASM_RISCV64], [test "$host_cpu" = riscv64]) AM_CONDITIONAL([ASM_X86_64], [test "$host_cpu" = x86_64]) +dnl Architecture (additional) +AM_CONDITIONAL([ASM_X86], [test "$host_cpu" = i386 -o "$host_cpu" = x86_64]) + dnl Features (enabled by default) AM_CONDITIONAL([ENABLE_DEBUG], [test "$enable_debug" = yes]) AM_CONDITIONAL([ENABLE_FLOAT], [test "$enable_float" = yes]) @@ -217,6 +220,9 @@ dnl Packages (disabled by default) AM_CONDITIONAL([WITH_DRIVERS], [test "$with_drivers" = yes]) 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]) + #################### @@ -228,6 +234,10 @@ AS_IF([test "$host_cpu" = i386], [AC_DEFINE([ASM_I386], [1] AS_IF([test "$host_cpu" = riscv64], [AC_DEFINE([ASM_RISCV64], [1], [architecture is RISC-V 64-bit])]) AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ASM_X86_64], [1], [architecture is x86_64])]) +dnl Architecture (additional) +AS_IF([test "$host_cpu" = i386], [AC_DEFINE([ASM_X86], [1], [architecture is x86])]) +AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ASM_X86], [1], [architecture is x86])]) + dnl Features (enabled by default) AS_IF([test "$enable_debug" = yes], [AC_DEFINE([ENABLE_DEBUG], [1], [enabled debugging])]) AS_IF([test "$enable_float" = yes], [AC_DEFINE([ENABLE_FLOAT], [1], [enabled floating-point arithmetic])]) @@ -260,6 +270,10 @@ dnl Packages (disabled by default) AS_IF([test "$with_drivers" = yes], [AC_DEFINE([WITH_DRIVERS], [1], [with drivers])]) 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])]) + dnl Additional AS_IF([test "$enable_debug" = yes], [AC_DEFINE([KERNAUX_DEBUG], [1], [enabled debugging])]) diff --git a/include/Makefile.am b/include/Makefile.am index 5592be4..49f3b62 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -26,6 +26,10 @@ if WITH_ARCH_X86_64 nobase_include_HEADERS += kernaux/arch/x86_64.h endif +if WITH_ARCH_X86 +nobase_include_HEADERS += kernaux/arch/x86.h +endif + ####### # ASM # ####### @@ -40,6 +44,10 @@ endif if ASM_X86_64 nobase_include_HEADERS += kernaux/asm/x86_64.h endif + +if ASM_X86 +nobase_include_HEADERS += kernaux/asm/x86.h +endif endif #################### diff --git a/include/kernaux/arch/i386.h b/include/kernaux/arch/i386.h index 1d364ab..277f139 100644 --- a/include/kernaux/arch/i386.h +++ b/include/kernaux/arch/i386.h @@ -5,6 +5,7 @@ extern "C" { #endif +#include #include #include diff --git a/include/kernaux/arch/riscv64.h b/include/kernaux/arch/riscv64.h index 2af64f4..ff5bfb9 100644 --- a/include/kernaux/arch/riscv64.h +++ b/include/kernaux/arch/riscv64.h @@ -5,8 +5,6 @@ extern "C" { #endif -#include - #ifdef __cplusplus } #endif diff --git a/include/kernaux/arch/x86.h b/include/kernaux/arch/x86.h new file mode 100644 index 0000000..2af320d --- /dev/null +++ b/include/kernaux/arch/x86.h @@ -0,0 +1,12 @@ +#ifndef KERNAUX_INCLUDED_ARCH_X86 +#define KERNAUX_INCLUDED_ARCH_X86 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/kernaux/arch/x86_64.h b/include/kernaux/arch/x86_64.h index 7127d4e..dcb2fc8 100644 --- a/include/kernaux/arch/x86_64.h +++ b/include/kernaux/arch/x86_64.h @@ -5,7 +5,7 @@ extern "C" { #endif -#include +#include #ifdef __cplusplus } diff --git a/include/kernaux/asm/i386.h b/include/kernaux/asm/i386.h index 91eaa4a..a4a46fc 100644 --- a/include/kernaux/asm/i386.h +++ b/include/kernaux/asm/i386.h @@ -6,14 +6,7 @@ extern "C" { #endif #include - -inline static uint8_t kernaux_asm_i386_inportb(uint16_t port); -inline static uint16_t kernaux_asm_i386_inportw(uint16_t port); -inline static uint32_t kernaux_asm_i386_inportd(uint16_t port); - -inline static void kernaux_asm_i386_outportb(uint16_t port, uint8_t value); -inline static void kernaux_asm_i386_outportw(uint16_t port, uint16_t value); -inline static void kernaux_asm_i386_outportd(uint16_t port, uint32_t value); +#include void kernaux_asm_i386_flush_gdt( volatile uint32_t pointer, @@ -30,42 +23,6 @@ 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); -uint8_t kernaux_asm_i386_inportb(const uint16_t port) -{ - register uint8_t result; - __asm__ volatile("inb %1, %0" : "=a" (result) : "dN" (port)); - return result; -} - -uint16_t kernaux_asm_i386_inportw(const uint16_t port) -{ - register uint16_t result; - __asm__ volatile("inw %1, %0" : "=a" (result) : "dN" (port)); - return result; -} - -uint32_t kernaux_asm_i386_inportd(const uint16_t port) -{ - register uint32_t result; - __asm__ volatile("inl %1, %0" : "=a" (result) : "dN" (port)); - return result; -} - -void kernaux_asm_i386_outportb(const uint16_t port, const uint8_t value) -{ - __asm__ volatile("outb %1, %0" : : "dN" (port), "a" (value)); -} - -void kernaux_asm_i386_outportw(const uint16_t port, const uint16_t value) -{ - __asm__ volatile("outw %1, %0" : : "dN" (port), "a" (value)); -} - -void kernaux_asm_i386_outportd(const uint16_t port, const uint32_t value) -{ - __asm__ volatile("outl %1, %0" : : "dN" (port), "a" (value)); -} - #ifdef __cplusplus } #endif diff --git a/include/kernaux/asm/x86.h b/include/kernaux/asm/x86.h new file mode 100644 index 0000000..c225fb4 --- /dev/null +++ b/include/kernaux/asm/x86.h @@ -0,0 +1,60 @@ +#ifndef KERNAUX_INCLUDED_ASM_X86 +#define KERNAUX_INCLUDED_ASM_X86 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +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; + __asm__ volatile("inb %1, %0" : "=a" (result) : "dN" (port)); + return result; +} + +uint16_t kernaux_asm_x86_inportw(const uint16_t port) +{ + register uint16_t result; + __asm__ volatile("inw %1, %0" : "=a" (result) : "dN" (port)); + return result; +} + +uint32_t kernaux_asm_x86_inportd(const uint16_t port) +{ + register uint32_t result; + __asm__ volatile("inl %1, %0" : "=a" (result) : "dN" (port)); + return result; +} + +void kernaux_asm_x86_outportb(const uint16_t port, const uint8_t value) +{ + __asm__ volatile("outb %1, %0" : : "dN" (port), "a" (value)); +} + +void kernaux_asm_x86_outportw(const uint16_t port, const uint16_t value) +{ + __asm__ volatile("outw %1, %0" : : "dN" (port), "a" (value)); +} + +void kernaux_asm_x86_outportd(const uint16_t port, const uint32_t value) +{ + __asm__ volatile("outl %1, %0" : : "dN" (port), "a" (value)); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/kernaux/asm/x86_64.h b/include/kernaux/asm/x86_64.h index 3afc908..1220f8b 100644 --- a/include/kernaux/asm/x86_64.h +++ b/include/kernaux/asm/x86_64.h @@ -6,50 +6,7 @@ extern "C" { #endif #include - -inline static uint8_t kernaux_asm_x86_64_inportb(uint16_t port); -inline static uint16_t kernaux_asm_x86_64_inportw(uint16_t port); -inline static uint32_t kernaux_asm_x86_64_inportd(uint16_t port); - -inline static void kernaux_asm_x86_64_outportb(uint16_t port, uint8_t value); -inline static void kernaux_asm_x86_64_outportw(uint16_t port, uint16_t value); -inline static void kernaux_asm_x86_64_outportd(uint16_t port, uint32_t value); - -uint8_t kernaux_asm_x86_64_inportb(const uint16_t port) -{ - register uint8_t result; - __asm__ volatile("inb %1, %0" : "=a" (result) : "dN" (port)); - return result; -} - -uint16_t kernaux_asm_x86_64_inportw(const uint16_t port) -{ - register uint16_t result; - __asm__ volatile("inw %1, %0" : "=a" (result) : "dN" (port)); - return result; -} - -uint32_t kernaux_asm_x86_64_inportd(const uint16_t port) -{ - register uint32_t result; - __asm__ volatile("inl %1, %0" : "=a" (result) : "dN" (port)); - return result; -} - -void kernaux_asm_x86_64_outportb(const uint16_t port, const uint8_t value) -{ - __asm__ volatile("outb %1, %0" : : "dN" (port), "a" (value)); -} - -void kernaux_asm_x86_64_outportw(const uint16_t port, const uint16_t value) -{ - __asm__ volatile("outw %1, %0" : : "dN" (port), "a" (value)); -} - -void kernaux_asm_x86_64_outportd(const uint16_t port, const uint32_t value) -{ - __asm__ volatile("outl %1, %0" : : "dN" (port), "a" (value)); -} +#include #ifdef __cplusplus } diff --git a/src/drivers/console.c b/src/drivers/console.c index a206f76..e483126 100644 --- a/src/drivers/console.c +++ b/src/drivers/console.c @@ -24,11 +24,8 @@ static void file_putc(char c, void *arg); void kernaux_drivers_console_putc(const char c __attribute__((unused))) { -#ifdef ASM_I386 - kernaux_asm_i386_outportb(0x3f8, c); -#endif -#ifdef ASM_X86_64 - kernaux_asm_x86_64_outportb(0x3f8, c); +#ifdef ASM_X86 + kernaux_asm_x86_outportb(0x3f8, c); #endif } diff --git a/src/drivers/intel_8253_pit.c b/src/drivers/intel_8253_pit.c index 58abccb..cdc2fec 100644 --- a/src/drivers/intel_8253_pit.c +++ b/src/drivers/intel_8253_pit.c @@ -11,11 +11,6 @@ #include -#if defined(ASM_I386) -# define inportb kernaux_asm_i386_inportb -# define outportb kernaux_asm_i386_outportb -#endif - void kernaux_drivers_intel_8253_pit_initialize(const unsigned int freq) { KERNAUX_ASSERT(freq); @@ -25,7 +20,7 @@ void kernaux_drivers_intel_8253_pit_initialize(const unsigned int freq) const uint8_t l = divisor & 0xff; const uint8_t h = (divisor >> 8) & 0xff; - outportb(0x43, 0x36); - outportb(0x40, l); - outportb(0x40, h); + kernaux_asm_x86_outportb(0x43, 0x36); + kernaux_asm_x86_outportb(0x40, l); + kernaux_asm_x86_outportb(0x40, h); } diff --git a/src/drivers/intel_8259_pic.c b/src/drivers/intel_8259_pic.c index 430d536..ce824dd 100644 --- a/src/drivers/intel_8259_pic.c +++ b/src/drivers/intel_8259_pic.c @@ -22,24 +22,19 @@ #define IRQS_COUNT 8 #define IRQS_TOTAL 16 -#if defined(ASM_I386) -# define inportb kernaux_asm_i386_inportb -# define outportb kernaux_asm_i386_outportb -#endif - static unsigned char master_start = 0; static unsigned char slave_start = 8; void kernaux_drivers_intel_8259_pic_enable_all() { - outportb(MASTER_DATA_PORT, 0); - outportb(SLAVE_DATA_PORT, 0); + kernaux_asm_x86_outportb(MASTER_DATA_PORT, 0); + kernaux_asm_x86_outportb(SLAVE_DATA_PORT, 0); } void kernaux_drivers_intel_8259_pic_disable_all() { - outportb(MASTER_DATA_PORT, 0xFF); - outportb(SLAVE_DATA_PORT, 0xFF); + kernaux_asm_x86_outportb(MASTER_DATA_PORT, 0xFF); + kernaux_asm_x86_outportb(SLAVE_DATA_PORT, 0xFF); } void kernaux_drivers_intel_8259_pic_enable(const unsigned char number) @@ -47,11 +42,13 @@ void kernaux_drivers_intel_8259_pic_enable(const unsigned char number) KERNAUX_ASSERT(number < IRQS_TOTAL); if (number < IRQS_COUNT) { - const uint8_t mask = inportb(MASTER_DATA_PORT); - outportb(MASTER_DATA_PORT, mask & ~KERNAUX_BITS8(number)); + const uint8_t mask = kernaux_asm_x86_inportb(MASTER_DATA_PORT); + kernaux_asm_x86_outportb(MASTER_DATA_PORT, + mask & ~KERNAUX_BITS8(number)); } else { - const uint8_t mask = inportb(SLAVE_DATA_PORT); - outportb(SLAVE_DATA_PORT, mask & ~KERNAUX_BITS8((number - IRQS_COUNT))); + const uint8_t mask = kernaux_asm_x86_inportb(SLAVE_DATA_PORT); + kernaux_asm_x86_outportb(SLAVE_DATA_PORT, + mask & ~KERNAUX_BITS8((number - IRQS_COUNT))); } } @@ -60,11 +57,13 @@ void kernaux_drivers_intel_8259_pic_disable(const unsigned char number) KERNAUX_ASSERT(number < IRQS_TOTAL); if (number < IRQS_COUNT) { - const uint8_t mask = inportb(MASTER_DATA_PORT); - outportb(MASTER_DATA_PORT, mask | KERNAUX_BITS8(number)); + const uint8_t mask = kernaux_asm_x86_inportb(MASTER_DATA_PORT); + kernaux_asm_x86_outportb(MASTER_DATA_PORT, + mask | KERNAUX_BITS8(number)); } else { - const uint8_t mask = inportb(SLAVE_DATA_PORT); - outportb(SLAVE_DATA_PORT, mask | KERNAUX_BITS8((number - IRQS_COUNT))); + const uint8_t mask = kernaux_asm_x86_inportb(SLAVE_DATA_PORT); + kernaux_asm_x86_outportb(SLAVE_DATA_PORT, + mask | KERNAUX_BITS8((number - IRQS_COUNT))); } } @@ -76,28 +75,28 @@ void kernaux_drivers_intel_8259_pic_remap( slave_start = new_slave_start; // Save masks - const uint8_t master_mask = inportb(MASTER_DATA_PORT); - const uint8_t slave_mask = inportb(SLAVE_DATA_PORT); + const uint8_t master_mask = kernaux_asm_x86_inportb(MASTER_DATA_PORT); + const uint8_t slave_mask = kernaux_asm_x86_inportb(SLAVE_DATA_PORT); // Start the initialization sequence - outportb(MASTER_COMMAND_PORT, 0x11); - outportb(SLAVE_COMMAND_PORT, 0x11); + kernaux_asm_x86_outportb(MASTER_COMMAND_PORT, 0x11); + kernaux_asm_x86_outportb(SLAVE_COMMAND_PORT, 0x11); // Set IRQ vectors - outportb(MASTER_DATA_PORT, new_master_start); - outportb(SLAVE_DATA_PORT, new_slave_start); + kernaux_asm_x86_outportb(MASTER_DATA_PORT, new_master_start); + kernaux_asm_x86_outportb(SLAVE_DATA_PORT, new_slave_start); // Connect master and slave with each other - outportb(MASTER_DATA_PORT, 0x04); - outportb(SLAVE_DATA_PORT, 0x02); + kernaux_asm_x86_outportb(MASTER_DATA_PORT, 0x04); + kernaux_asm_x86_outportb(SLAVE_DATA_PORT, 0x02); // 8086/88 (MCS-80/85) mode - outportb(MASTER_DATA_PORT, 0x01); - outportb(SLAVE_DATA_PORT, 0x01); + kernaux_asm_x86_outportb(MASTER_DATA_PORT, 0x01); + kernaux_asm_x86_outportb(SLAVE_DATA_PORT, 0x01); // Restore masks - outportb(MASTER_DATA_PORT, master_mask); - outportb(SLAVE_DATA_PORT, slave_mask); + kernaux_asm_x86_outportb(MASTER_DATA_PORT, master_mask); + kernaux_asm_x86_outportb(SLAVE_DATA_PORT, slave_mask); } void kernaux_drivers_intel_8259_pic_eoi(const unsigned char number) @@ -109,6 +108,6 @@ void kernaux_drivers_intel_8259_pic_eoi(const unsigned char number) const bool to_master = to_slave || (number >= master_start && number < master_start + IRQS_COUNT); - if (to_slave) outportb(SLAVE_COMMAND_PORT, 0x20); - if (to_master) outportb(MASTER_COMMAND_PORT, 0x20); + if (to_slave) kernaux_asm_x86_outportb(SLAVE_COMMAND_PORT, 0x20); + if (to_master) kernaux_asm_x86_outportb(MASTER_COMMAND_PORT, 0x20); }