diff --git a/.gitignore b/.gitignore index 167f0e63..096540b0 100644 --- a/.gitignore +++ b/.gitignore @@ -110,6 +110,7 @@ /examples/generic_file /examples/generic_malloc /examples/generic_mutex +/examples/macro_bits /examples/macro_container_of /examples/memmap /examples/ntoa diff --git a/ChangeLog b/ChangeLog index 9305dd34..c53b6469 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2022-06-30 Alex Kotov + + * include/kernaux/macro.h: Added macros "KERNAUX_BITS[8|16|32|64]" + +2022-06-27 Alex Kotov + + * include/kernaux/macro.h: Added macro "KERNAUX_CONTAINER_OF" + 2022-06-25 Alex Kotov * configure.ac: Removed package "io" diff --git a/README.md b/README.md index 1905158e..7ab6533f 100644 --- a/README.md +++ b/README.md @@ -38,15 +38,15 @@ We use [semantic versioning](https://semver.org) for stable APIs. Stable APIs can only change when major version number is increased (or minor while major is zero). Work-in-progress APIs can change at any time. -* Runtime environment +* Basic features * [Feature macros](/include/kernaux/version.h.in) (*work in progress*) + * [Macros](/include/kernaux/macro.h) (*non-breaking since* **?.?.?**) + * [Example: CONTAINER_OF](/examples/macro_container_of.c) + * [Example: BITS](/examples/macro_bits.c) * [Assertions](/include/kernaux/assert.h) (*non-breaking since* **0.4.0**) * [Example: Assert](/examples/assert.c) * [Example: Panic](/examples/panic.c) * Stack trace *(planned)* - * Architecture-specific code (*work in progress*) - * [Declarations](/include/kernaux/arch/) - * [Functions](/include/kernaux/asm/) * Generic types * [File](/include/kernaux/generic/file.h) (*non-breaking since* **?.?.?**) * [Example](/examples/generic_file.c) @@ -86,6 +86,9 @@ 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/) * Device drivers (for debugging only) * [Serial console](/include/kernaux/drivers/console.h) (*work in progress*) * [Framebuffer](/include/kernaux/drivers/framebuffer.h) (*planned*) diff --git a/examples/Makefile.am b/examples/Makefile.am index a9ce7706..31bc40fa 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -45,6 +45,14 @@ TESTS += generic_mutex generic_mutex_LDADD = $(top_builddir)/libkernaux.la generic_mutex_SOURCES = main.c generic_mutex.c +############## +# macro_bits # +############## + +TESTS += macro_bits +macro_bits_LDADD = $(top_builddir)/libkernaux.la +macro_bits_SOURCES = main.c macro_bits.c + ###################### # macro_container_of # ###################### diff --git a/examples/macro_bits.c b/examples/macro_bits.c new file mode 100644 index 00000000..c470a7a9 --- /dev/null +++ b/examples/macro_bits.c @@ -0,0 +1,21 @@ +#include + +#include + +void example_main() +{ + assert(KERNAUX_BITS(0) == 0x1); + assert(KERNAUX_BITS(31) == 0x80000000); + + assert(KERNAUX_BITS8(0) == 0x1); + assert(KERNAUX_BITS8(7) == 0x80); + + assert(KERNAUX_BITS16(0) == 0x1); + assert(KERNAUX_BITS16(15) == 0x8000); + + assert(KERNAUX_BITS32(0) == 0x1); + assert(KERNAUX_BITS32(31) == 0x80000000); + + assert(KERNAUX_BITS64(0) == 0x1); + assert(KERNAUX_BITS64(63) == 0x8000000000000000); +} diff --git a/include/kernaux/arch/i386.h b/include/kernaux/arch/i386.h index 0a8a3ce5..1622004e 100644 --- a/include/kernaux/arch/i386.h +++ b/include/kernaux/arch/i386.h @@ -28,27 +28,27 @@ extern "C" { KERNAUX_ARCH_I386_ADDR_TO_PDE_ADDR(addr) // CR0 bits -#define KERNAUX_ARCH_I386_CR0_PE ((uint32_t)0x00000001) // 0: Protected Mode Enable -#define KERNAUX_ARCH_I386_CR0_MP ((uint32_t)0x00000002) // 1: Monitor co-processor -#define KERNAUX_ARCH_I386_CR0_EM ((uint32_t)0x00000004) // 2: x87 FPU Emulation -#define KERNAUX_ARCH_I386_CR0_TS ((uint32_t)0x00000008) // 3: Task switched -#define KERNAUX_ARCH_I386_CR0_ET ((uint32_t)0x00000010) // 4: Extension type -#define KERNAUX_ARCH_I386_CR0_NE ((uint32_t)0x00000020) // 5: Numeric error -#define KERNAUX_ARCH_I386_CR0_WP ((uint32_t)0x00010000) // 16: Write protect -#define KERNAUX_ARCH_I386_CR0_AM ((uint32_t)0x00040000) // 18: Alignment mask -#define KERNAUX_ARCH_I386_CR0_NW ((uint32_t)0x20000000) // 29: Not-write trough -#define KERNAUX_ARCH_I386_CR0_CD ((uint32_t)0x40000000) // 30: Cache disable -#define KERNAUX_ARCH_I386_CR0_PG ((uint32_t)0x80000000) // 31: Paging +#define KERNAUX_ARCH_I386_CR0_PE KERNAUX_BITS32(0) // 0: Protected Mode Enable +#define KERNAUX_ARCH_I386_CR0_MP KERNAUX_BITS32(1) // 1: Monitor co-processor +#define KERNAUX_ARCH_I386_CR0_EM KERNAUX_BITS32(2) // 2: x87 FPU Emulation +#define KERNAUX_ARCH_I386_CR0_TS KERNAUX_BITS32(3) // 3: Task switched +#define KERNAUX_ARCH_I386_CR0_ET KERNAUX_BITS32(4) // 4: Extension type +#define KERNAUX_ARCH_I386_CR0_NE KERNAUX_BITS32(5) // 5: Numeric error +#define KERNAUX_ARCH_I386_CR0_WP KERNAUX_BITS32(16) // 16: Write protect +#define KERNAUX_ARCH_I386_CR0_AM KERNAUX_BITS32(18) // 18: Alignment mask +#define KERNAUX_ARCH_I386_CR0_NW KERNAUX_BITS32(29) // 29: Not-write trough +#define KERNAUX_ARCH_I386_CR0_CD KERNAUX_BITS32(30) // 30: Cache disable +#define KERNAUX_ARCH_I386_CR0_PG KERNAUX_BITS32(31) // 31: Paging // Some CR4 bits -#define KERNAUX_ARCH_I386_CR4_VME ((uint32_t)0x00000001) // 0: Virtual 8086 Mode Extensions -#define KERNAUX_ARCH_I386_CR4_PVI ((uint32_t)0x00000002) // 1: Protected-mode Virtual Interrupts -#define KERNAUX_ARCH_I386_CR4_TSD ((uint32_t)0x00000004) // 2: Time Stamp Disable -#define KERNAUX_ARCH_I386_CR4_DE ((uint32_t)0x00000008) // 3: Debugging Extensions -#define KERNAUX_ARCH_I386_CR4_PSE ((uint32_t)0x00000010) // 4: Page Size Extension -#define KERNAUX_ARCH_I386_CR4_PAE ((uint32_t)0x00000020) // 5: Physical Address Extension -#define KERNAUX_ARCH_I386_CR4_MCE ((uint32_t)0x00000040) // 6: Machine Check Exception -#define KERNAUX_ARCH_I386_CR4_PGE ((uint32_t)0x00000080) // 7: Page Global Enabled +#define KERNAUX_ARCH_I386_CR4_VME KERNAUX_BITS32(0) // 0: Virtual 8086 Mode Extensions +#define KERNAUX_ARCH_I386_CR4_PVI KERNAUX_BITS32(1) // 1: Protected-mode Virtual Interrupts +#define KERNAUX_ARCH_I386_CR4_TSD KERNAUX_BITS32(2) // 2: Time Stamp Disable +#define KERNAUX_ARCH_I386_CR4_DE KERNAUX_BITS32(3) // 3: Debugging Extensions +#define KERNAUX_ARCH_I386_CR4_PSE KERNAUX_BITS32(4) // 4: Page Size Extension +#define KERNAUX_ARCH_I386_CR4_PAE KERNAUX_BITS32(5) // 5: Physical Address Extension +#define KERNAUX_ARCH_I386_CR4_MCE KERNAUX_BITS32(6) // 6: Machine Check Exception +#define KERNAUX_ARCH_I386_CR4_PGE KERNAUX_BITS32(7) // 7: Page Global Enabled // TODO: bits 8-31 #include diff --git a/include/kernaux/macro.h b/include/kernaux/macro.h index be4c3d0b..e31c1f59 100644 --- a/include/kernaux/macro.h +++ b/include/kernaux/macro.h @@ -11,6 +11,13 @@ extern "C" { #define KERNAUX_CONTAINER_OF(ptr, type, member) \ ((type*)((uintptr_t)(ptr) - offsetof(type, member))) +#define KERNAUX_BITS(n) (1u << (n)) + +#define KERNAUX_BITS8(n) ((uint8_t )(((uint8_t )1) << (n))) +#define KERNAUX_BITS16(n) ((uint16_t)(((uint16_t)1) << (n))) +#define KERNAUX_BITS32(n) ((uint32_t)(((uint32_t)1) << (n))) +#define KERNAUX_BITS64(n) ((uint64_t)(((uint64_t)1) << (n))) + #ifdef KERNAUX_ACCESS_PRIVATE # define KERNAUX_PRIVATE_FIELD(id) id # define KERNAUX_PROTECTED_FIELD(id) id diff --git a/include/kernaux/multiboot2.h.in b/include/kernaux/multiboot2.h.in index 728d37e2..b2a38db3 100644 --- a/include/kernaux/multiboot2.h.in +++ b/include/kernaux/multiboot2.h.in @@ -38,8 +38,8 @@ extern "C" { #define KERNAUX_MULTIBOOT2_HTAG_BASE_FLAG_OPTIONAL 1 -#define KERNAUX_MULTIBOOT2_HTAG_FLAGS_REQUIRE_CONSOLE (1 << 0) -#define KERNAUX_MULTIBOOT2_HTAG_FLAGS_EGA_SUPPORT (1 << 1) +#define KERNAUX_MULTIBOOT2_HTAG_FLAGS_REQUIRE_CONSOLE KERNAUX_BITS(0) +#define KERNAUX_MULTIBOOT2_HTAG_FLAGS_EGA_SUPPORT KERNAUX_BITS(1) #include diff --git a/include/kernaux/printf_fmt.h b/include/kernaux/printf_fmt.h index 4ee3b8f5..2b0b3584 100644 --- a/include/kernaux/printf_fmt.h +++ b/include/kernaux/printf_fmt.h @@ -5,20 +5,22 @@ extern "C" { #endif +#include + #include -#define KERNAUX_PRINTF_FMT_FLAGS_ZEROPAD (1u << 0u) -#define KERNAUX_PRINTF_FMT_FLAGS_LEFT (1u << 1u) -#define KERNAUX_PRINTF_FMT_FLAGS_PLUS (1u << 2u) -#define KERNAUX_PRINTF_FMT_FLAGS_SPACE (1u << 3u) -#define KERNAUX_PRINTF_FMT_FLAGS_HASH (1u << 4u) -#define KERNAUX_PRINTF_FMT_FLAGS_UPPERCASE (1u << 5u) -#define KERNAUX_PRINTF_FMT_FLAGS_CHAR (1u << 6u) -#define KERNAUX_PRINTF_FMT_FLAGS_SHORT (1u << 7u) -#define KERNAUX_PRINTF_FMT_FLAGS_LONG (1u << 8u) -#define KERNAUX_PRINTF_FMT_FLAGS_LONG_LONG (1u << 9u) -#define KERNAUX_PRINTF_FMT_FLAGS_PRECISION (1u << 10u) -#define KERNAUX_PRINTF_FMT_FLAGS_ADAPT_EXP (1u << 11u) +#define KERNAUX_PRINTF_FMT_FLAGS_ZEROPAD KERNAUX_BITS(0) +#define KERNAUX_PRINTF_FMT_FLAGS_LEFT KERNAUX_BITS(1) +#define KERNAUX_PRINTF_FMT_FLAGS_PLUS KERNAUX_BITS(2) +#define KERNAUX_PRINTF_FMT_FLAGS_SPACE KERNAUX_BITS(3) +#define KERNAUX_PRINTF_FMT_FLAGS_HASH KERNAUX_BITS(4) +#define KERNAUX_PRINTF_FMT_FLAGS_UPPERCASE KERNAUX_BITS(5) +#define KERNAUX_PRINTF_FMT_FLAGS_CHAR KERNAUX_BITS(6) +#define KERNAUX_PRINTF_FMT_FLAGS_SHORT KERNAUX_BITS(7) +#define KERNAUX_PRINTF_FMT_FLAGS_LONG KERNAUX_BITS(8) +#define KERNAUX_PRINTF_FMT_FLAGS_LONG_LONG KERNAUX_BITS(9) +#define KERNAUX_PRINTF_FMT_FLAGS_PRECISION KERNAUX_BITS(10) +#define KERNAUX_PRINTF_FMT_FLAGS_ADAPT_EXP KERNAUX_BITS(11) enum KernAux_PrintfFmt_Type { KERNAUX_PRINTF_FMT_TYPE_NONE, diff --git a/src/drivers/intel_8259_pic.c b/src/drivers/intel_8259_pic.c index 39d0bc10..430d536a 100644 --- a/src/drivers/intel_8259_pic.c +++ b/src/drivers/intel_8259_pic.c @@ -4,6 +4,7 @@ #include #include +#include #ifdef ASM_I386 #include @@ -47,10 +48,10 @@ void kernaux_drivers_intel_8259_pic_enable(const unsigned char number) if (number < IRQS_COUNT) { const uint8_t mask = inportb(MASTER_DATA_PORT); - outportb(MASTER_DATA_PORT, mask & ~(1 << number)); + outportb(MASTER_DATA_PORT, mask & ~KERNAUX_BITS8(number)); } else { const uint8_t mask = inportb(SLAVE_DATA_PORT); - outportb(SLAVE_DATA_PORT, mask & ~(1 << (number - IRQS_COUNT))); + outportb(SLAVE_DATA_PORT, mask & ~KERNAUX_BITS8((number - IRQS_COUNT))); } } @@ -60,10 +61,10 @@ void kernaux_drivers_intel_8259_pic_disable(const unsigned char number) if (number < IRQS_COUNT) { const uint8_t mask = inportb(MASTER_DATA_PORT); - outportb(MASTER_DATA_PORT, mask | (1 << number)); + outportb(MASTER_DATA_PORT, mask | KERNAUX_BITS8(number)); } else { const uint8_t mask = inportb(SLAVE_DATA_PORT); - outportb(SLAVE_DATA_PORT, mask | (1 << (number - IRQS_COUNT))); + outportb(SLAVE_DATA_PORT, mask | KERNAUX_BITS8((number - IRQS_COUNT))); } } diff --git a/src/pfa.c b/src/pfa.c index aeb83e05..4534a072 100644 --- a/src/pfa.c +++ b/src/pfa.c @@ -3,6 +3,7 @@ #endif #include +#include #include #include "libc.h" @@ -10,7 +11,7 @@ #define PAGE_INDEX(page_addr) ((page_addr) / KERNAUX_PFA_PAGE_SIZE) #define FLAG_INDEX_FROM_INDEX(page_index) ((page_index) / 8) -#define FLAG_MASK_FROM_INDEX(page_index) (1 << ((page_index) % 8)) +#define FLAG_MASK_FROM_INDEX(page_index) KERNAUX_BITS((page_index) % 8) #define FLAG_INDEX_FROM_ADDR(page_addr) \ (FLAG_INDEX_FROM_INDEX(PAGE_INDEX(page_addr)))