1
0
Fork 0
mirror of https://github.com/tailix/libkernaux.git synced 2025-03-17 17:14:00 -04:00

Add architecture x86 (any of i386 and x86_64) (#117)

This commit is contained in:
Alex Kotov 2022-11-28 15:56:37 +04:00 committed by GitHub
parent 971b2f4803
commit cd133ba10b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 133 additions and 135 deletions

View file

@ -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])])

View file

@ -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
####################

View file

@ -5,6 +5,7 @@
extern "C" {
#endif
#include <kernaux/arch/x86.h>
#include <kernaux/macro.h>
#include <stdint.h>

View file

@ -5,8 +5,6 @@
extern "C" {
#endif
#include <stdint.h>
#ifdef __cplusplus
}
#endif

View file

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

View file

@ -5,7 +5,7 @@
extern "C" {
#endif
#include <stdint.h>
#include <kernaux/arch/x86.h>
#ifdef __cplusplus
}

View file

@ -6,14 +6,7 @@ extern "C" {
#endif
#include <kernaux/arch/i386.h>
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 <kernaux/asm/x86.h>
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

60
include/kernaux/asm/x86.h Normal file
View file

@ -0,0 +1,60 @@
#ifndef KERNAUX_INCLUDED_ASM_X86
#define KERNAUX_INCLUDED_ASM_X86
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/arch/x86.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;
__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

View file

@ -6,50 +6,7 @@ extern "C" {
#endif
#include <kernaux/arch/x86_64.h>
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 <kernaux/asm/x86.h>
#ifdef __cplusplus
}

View file

@ -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
}

View file

@ -11,11 +11,6 @@
#include <stdint.h>
#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);
}

View file

@ -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);
}