Split <kernaux/arch/*.h> and <kernaux/asm/*.h>

This commit is contained in:
Alex Kotov 2021-12-20 11:14:40 +05:00
parent 4eb1ccec09
commit 29542e98d2
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
12 changed files with 157 additions and 117 deletions

View File

@ -25,12 +25,12 @@ libkernaux_a_SOURCES = \
src/libc.c \
src/printf.c
if ARCH_I386
libkernaux_a_SOURCES += src/arch/i386/asm.S
if ASM_I386
libkernaux_a_SOURCES += src/asm/i386.S
endif
if ARCH_X86_64
libkernaux_a_SOURCES += src/arch/x86_64/asm.S
if ASM_X86_64
libkernaux_a_SOURCES += src/asm/x86_64.S
endif
if WITH_CMDLINE

View File

@ -30,10 +30,12 @@ API
---
* Runtime environment
* Architecture-specific code
* [Declarations](/include/kernaux/arch/)
* [Functions](/include/kernaux/asm/)
* [Assertions](/include/kernaux/assert.h)
* [Simple](/examples/assert_simple.c)
* [Guards](/examples/assert_guards.c)
* [Architecture-specific helpers](/include/kernaux/arch/)
* Device drivers (for debugging only)
* [Serial console](/include/kernaux/console.h)
* Framebuffer *(planned)*
@ -177,39 +179,39 @@ To install into specific directory use full path:
`DESTDIR="$(pwd)/dest" sudo make install-exec install-data` instead of
`DESTDIR=dest sudo make install-exec install-data`.
Check if compilation targets i386: `objdump -d src/arch/i386/asm.o`. It should
output something like this:
Check if compilation targets i386: `objdump -d src/asm/i386.o`. It should output
something like this:
```
src/arch/i386/asm.o: file format elf32-i386
src/asm/i386.o: file format elf32-i386
Disassembly of section .text:
00000000 <kernaux_arch_i386_hang>:
00000000 <kernaux_asm_i386_hang>:
0: fa cli
1: f4 hlt
2: eb fc jmp 0 <kernaux_arch_i386_hang>
2: eb fc jmp 0 <kernaux_asm_i386_hang>
00000004 <kernaux_arch_i386_read_cr0>:
00000004 <kernaux_asm_i386_read_cr0>:
4: 0f 20 c0 mov %cr0,%eax
7: c3 ret
00000008 <kernaux_arch_i386_read_cr4>:
00000008 <kernaux_asm_i386_read_cr4>:
8: 0f 20 e0 mov %cr4,%eax
b: c3 ret
0000000c <kernaux_arch_i386_write_cr0>:
0000000c <kernaux_asm_i386_write_cr0>:
c: 8b 44 24 04 mov 0x4(%esp),%eax
10: 0f 22 c0 mov %eax,%cr0
13: c3 ret
00000014 <kernaux_arch_i386_write_cr3>:
00000014 <kernaux_asm_i386_write_cr3>:
14: 8b 44 24 04 mov 0x4(%esp),%eax
18: 0f 22 d8 mov %eax,%cr3
1b: c3 ret
0000001c <kernaux_arch_i386_write_cr4>:
0000001c <kernaux_asm_i386_write_cr4>:
1c: 8b 44 24 04 mov 0x4(%esp),%eax
20: 0f 22 e0 mov %eax,%cr4
23: c3 ret

View File

@ -52,8 +52,8 @@ AS_IF([test "$with_libc" = yes], do_with_libc)
dnl Architecture
AM_CONDITIONAL([ARCH_I386], [test "$host_cpu" = i386])
AM_CONDITIONAL([ARCH_X86_64], [test "$host_cpu" = x86_64])
AM_CONDITIONAL([ASM_I386], [test "$host_cpu" = i386])
AM_CONDITIONAL([ASM_X86_64], [test "$host_cpu" = x86_64])
dnl Features (disabled by default)
AM_CONDITIONAL([ENABLE_ASSERT], [test "$enable_assert" = yes])
@ -76,8 +76,8 @@ AM_CONDITIONAL([WITH_LIBC_STRLEN], [test "$with_libc_strlen" = yes])
dnl Architecture
AS_IF([test "$host_cpu" = i386], [AC_DEFINE([ARCH_I386], [1], [architecture is i386])])
AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ARCH_X86_64], [1], [architecture is x86_64])])
AS_IF([test "$host_cpu" = i386], [AC_DEFINE([ASM_I386], [1], [architecture is i386])])
AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ASM_X86_64], [1], [architecture is x86_64])])
dnl Features (disabled by default)
AS_IF([test "$enable_assert" = yes], [AC_DEFINE([KERNAUX_ENABLE_ASSERT], [1], [enabled runtime assertions])])

View File

@ -2,6 +2,8 @@ nobase_include_HEADERS = \
kernaux.h \
kernaux/arch/i386.h \
kernaux/arch/x86_64.h \
kernaux/asm/i386.h \
kernaux/asm/x86_64.h \
kernaux/assert.h \
kernaux/cmdline.h \
kernaux/console.h \

View File

@ -1,3 +1,14 @@
/*
We don't include <kernaux/asm/*.h> because they
contain architecture-specific assembly functions.
We don't include <kernaux/libc.h> because it may
conflict with actual freestanding or hosted libc.
*/
#include <kernaux/arch/i386.h>
#include <kernaux/arch/x86_64.h>
#include <kernaux/assert.h>
#include <kernaux/cmdline.h>
#include <kernaux/console.h>
@ -7,6 +18,3 @@
#include <kernaux/pfa.h>
#include <kernaux/printf.h>
#include <kernaux/units.h>
// We don't include <kernaux/libc.h> because it may
// conflict with actual freestanding or hosted libc.

View File

@ -99,59 +99,6 @@ struct KernAux_Arch_I386_PageTable {
}
__attribute__((packed));
inline static uint8_t kernaux_arch_i386_inportb(uint16_t port);
inline static uint16_t kernaux_arch_i386_inportw(uint16_t port);
inline static uint32_t kernaux_arch_i386_inportd(uint16_t port);
inline static void kernaux_arch_i386_outportb(uint16_t port, uint8_t value);
inline static void kernaux_arch_i386_outportw(uint16_t port, uint16_t value);
inline static void kernaux_arch_i386_outportd(uint16_t port, uint32_t value);
void kernaux_arch_i386_hang() __attribute__((noreturn));
uint32_t kernaux_arch_i386_read_cr0();
uint32_t kernaux_arch_i386_read_cr4();
void kernaux_arch_i386_write_cr0(volatile uint32_t value);
void kernaux_arch_i386_write_cr3(volatile uint32_t value);
void kernaux_arch_i386_write_cr4(volatile uint32_t value);
uint8_t kernaux_arch_i386_inportb(const uint16_t port)
{
register uint8_t result;
__asm__ volatile("inb %1, %0" : "=a" (result) : "dN" (port));
return result;
}
uint16_t kernaux_arch_i386_inportw(const uint16_t port)
{
register uint16_t result;
__asm__ volatile("inw %1, %0" : "=a" (result) : "dN" (port));
return result;
}
uint32_t kernaux_arch_i386_inportd(const uint16_t port)
{
register uint32_t result;
__asm__ volatile("ind %1, %0" : "=a" (result) : "dN" (port));
return result;
}
void kernaux_arch_i386_outportb(const uint16_t port, const uint8_t value)
{
__asm__ volatile("outb %1, %0" : : "dN" (port), "a" (value));
}
void kernaux_arch_i386_outportw(const uint16_t port, const uint16_t value)
{
__asm__ volatile("outw %1, %0" : : "dN" (port), "a" (value));
}
void kernaux_arch_i386_outportd(const uint16_t port, const uint32_t value)
{
__asm__ volatile("outd %1, %0" : : "dN" (port), "a" (value));
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,67 @@
#ifndef KERNAUX_INCLUDED_ASM_I386
#define KERNAUX_INCLUDED_ASM_I386 1
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/arch/i386.h>
void kernaux_asm_i386_hang() __attribute__((noreturn));
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);
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);
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("ind %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("outd %1, %0" : : "dN" (port), "a" (value));
}
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

@ -1,38 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
.global kernaux_arch_i386_hang
.global kernaux_arch_i386_read_cr0
.global kernaux_arch_i386_read_cr4
.global kernaux_arch_i386_write_cr0
.global kernaux_arch_i386_write_cr3
.global kernaux_arch_i386_write_cr4
kernaux_arch_i386_hang:
cli
hlt
jmp kernaux_arch_i386_hang
kernaux_arch_i386_read_cr0:
mov %cr0, %eax
ret
kernaux_arch_i386_read_cr4:
mov %cr4, %eax
ret
kernaux_arch_i386_write_cr0:
mov 4(%esp), %eax
mov %eax, %cr0
ret
kernaux_arch_i386_write_cr3:
mov 4(%esp), %eax
mov %eax, %cr3
ret
kernaux_arch_i386_write_cr4:
mov 4(%esp), %eax
mov %eax, %cr4
ret

38
src/asm/i386.S Normal file
View File

@ -0,0 +1,38 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
.global kernaux_asm_i386_hang
.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_hang:
cli
hlt
jmp kernaux_asm_i386_hang
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

@ -2,8 +2,8 @@
#include "config.h"
#endif
#ifdef ARCH_I386
#include <kernaux/arch/i386.h>
#ifdef ASM_I386
#include <kernaux/asm/i386.h>
#endif
#include <kernaux/console.h>
@ -17,8 +17,8 @@ void kernaux_console_print(const char *const s)
void kernaux_console_putc(const char c __attribute__((unused)))
{
#ifdef ARCH_I386
kernaux_arch_i386_outportb(0x3F8, c);
#ifdef ASM_I386
kernaux_asm_i386_outportb(0x3F8, c);
#endif
}