diff --git a/docs/Doxyfile b/docs/Doxyfile index 5ec5f80b..32a3f683 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -2581,7 +2581,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = __counted_by(x)= __sized_by(x)= +PREDEFINED = __counted_by(x)= __sized_by(x)= restrict= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/docs/doxygen/groups.dox b/docs/doxygen/groups.dox index e9c977dc..96d779b5 100644 --- a/docs/doxygen/groups.dox +++ b/docs/doxygen/groups.dox @@ -6,4 +6,11 @@ @defgroup kinit Kernel initialization @defgroup hal Hardware abstraction layer @defgroup dt Device tree +@defgroup stdbigos + @defgroup sbi + @defgroup csr + @defgroup trap + @defgroup types + @defgroup string + @defgroup bitutils */ diff --git a/docs/source/pages/api/kernel/mm/palloc.rst b/docs/source/pages/api/kernel/mm/palloc.rst index 6f8b6a4f..6d98e989 100644 --- a/docs/source/pages/api/kernel/mm/palloc.rst +++ b/docs/source/pages/api/kernel/mm/palloc.rst @@ -2,4 +2,4 @@ Physical memory allocator ========================= - .. doxygengroup:: palloc +.. doxygengroup:: palloc diff --git a/docs/source/pages/api/kernel/mm/pmm.rst b/docs/source/pages/api/kernel/mm/pmm.rst index 13c82452..4f067a38 100644 --- a/docs/source/pages/api/kernel/mm/pmm.rst +++ b/docs/source/pages/api/kernel/mm/pmm.rst @@ -2,4 +2,4 @@ Physical memory manager ============================== - .. doxygengroup:: pmm +.. doxygengroup:: pmm diff --git a/docs/source/pages/api/libs/dt.rst b/docs/source/pages/api/libs/dt.rst index 17c3a13c..3ce7ed91 100644 --- a/docs/source/pages/api/libs/dt.rst +++ b/docs/source/pages/api/libs/dt.rst @@ -2,4 +2,4 @@ Device Tree API =============== - .. doxygengroup:: dt +.. doxygengroup:: dt diff --git a/docs/source/pages/api/libs/index.rst b/docs/source/pages/api/libs/index.rst index 270cd8c9..4de83c84 100644 --- a/docs/source/pages/api/libs/index.rst +++ b/docs/source/pages/api/libs/index.rst @@ -6,3 +6,4 @@ Bigos Libraries :maxdepth: 1 dt + stdbigos/index diff --git a/docs/source/pages/api/libs/stdbigos/bitutils.rst b/docs/source/pages/api/libs/stdbigos/bitutils.rst new file mode 100644 index 00000000..8eed3835 --- /dev/null +++ b/docs/source/pages/api/libs/stdbigos/bitutils.rst @@ -0,0 +1,5 @@ +======== +Bitutils +======== + +.. doxygengroup:: bitutils diff --git a/docs/source/pages/api/libs/stdbigos/csr.rst b/docs/source/pages/api/libs/stdbigos/csr.rst new file mode 100644 index 00000000..bce60ec4 --- /dev/null +++ b/docs/source/pages/api/libs/stdbigos/csr.rst @@ -0,0 +1,5 @@ +=== +CSR +=== + +.. doxygengroup:: csr diff --git a/docs/source/pages/api/libs/stdbigos/index.rst b/docs/source/pages/api/libs/stdbigos/index.rst new file mode 100644 index 00000000..66e694b3 --- /dev/null +++ b/docs/source/pages/api/libs/stdbigos/index.rst @@ -0,0 +1,13 @@ +======== +Stdbigos +======== + +.. toctree:: + :maxdepth: 1 + + sbi + csr + trap + types + string + bitutils diff --git a/docs/source/pages/api/libs/stdbigos/sbi.rst b/docs/source/pages/api/libs/stdbigos/sbi.rst new file mode 100644 index 00000000..6e229945 --- /dev/null +++ b/docs/source/pages/api/libs/stdbigos/sbi.rst @@ -0,0 +1,5 @@ +=== +SBI +=== + +.. doxygengroup:: sbi diff --git a/docs/source/pages/api/libs/stdbigos/string.rst b/docs/source/pages/api/libs/stdbigos/string.rst new file mode 100644 index 00000000..cdd94481 --- /dev/null +++ b/docs/source/pages/api/libs/stdbigos/string.rst @@ -0,0 +1,5 @@ +====== +String +====== + +.. doxygengroup:: string diff --git a/docs/source/pages/api/libs/stdbigos/trap.rst b/docs/source/pages/api/libs/stdbigos/trap.rst new file mode 100644 index 00000000..b04f0322 --- /dev/null +++ b/docs/source/pages/api/libs/stdbigos/trap.rst @@ -0,0 +1,5 @@ +==== +Trap +==== + +.. doxygengroup:: trap diff --git a/docs/source/pages/api/libs/stdbigos/types.rst b/docs/source/pages/api/libs/stdbigos/types.rst new file mode 100644 index 00000000..d6807287 --- /dev/null +++ b/docs/source/pages/api/libs/stdbigos/types.rst @@ -0,0 +1,5 @@ +===== +Types +===== + +.. doxygengroup:: types diff --git a/include/stdbigos/address.h b/include/stdbigos/address.h index 54848c55..05fef770 100644 --- a/include/stdbigos/address.h +++ b/include/stdbigos/address.h @@ -1,5 +1,5 @@ -#ifndef _STDBIGOS_ADDRESS_H -#define _STDBIGOS_ADDRESS_H +#ifndef STDBIGOS_ADDRESS +#define STDBIGOS_ADDRESS #ifdef __clang__ #define __noderef __attribute__((noderef)) @@ -13,4 +13,4 @@ #define __iomem #endif -#endif +#endif // !STDBIGOS_ADDRESS diff --git a/include/stdbigos/array_sizes.h b/include/stdbigos/array_sizes.h index 1da8191b..6f408b0d 100644 --- a/include/stdbigos/array_sizes.h +++ b/include/stdbigos/array_sizes.h @@ -1,5 +1,5 @@ -#ifndef _STDBIGOS_ARRAY_SIZES_H -#define _STDBIGOS_ARRAY_SIZES_H +#ifndef STDBIGOS_ARRAY_SIZES +#define STDBIGOS_ARRAY_SIZES #if __has_attribute(__counted_by__) #define __counted_by(member) __attribute__((__counted_by__(member))) @@ -13,4 +13,4 @@ #define __sized_by(member) #endif -#endif +#endif // !STDBIGOS_ARRAY_SIZES diff --git a/include/stdbigos/bitutils.h b/include/stdbigos/bitutils.h index 33e61392..434158ae 100644 --- a/include/stdbigos/bitutils.h +++ b/include/stdbigos/bitutils.h @@ -1,14 +1,24 @@ -#ifndef _STDBIGOS_BITUTILS_H -#define _STDBIGOS_BITUTILS_H +#ifndef STDBIGOS_BITUTILS +#define STDBIGOS_BITUTILS #include +/// @addtogroup stdbigos +/// @{ +/// @addtogroup bitutils +/// @{ + u32 read_be32(const void* addr); + u64 read_be64(const void* addr); u32 read_le32(const void* addr); + u64 read_le64(const void* addr); u32 align_u32(u32 num, u32 align); -#endif +/// @} +/// @} + +#endif // !STDBIGOS_BITUTILS diff --git a/include/stdbigos/buffer.h b/include/stdbigos/buffer.h index 58724d2a..d70818b3 100644 --- a/include/stdbigos/buffer.h +++ b/include/stdbigos/buffer.h @@ -1,15 +1,19 @@ -#ifndef _STDBIGOS_BUFFER_H -#define _STDBIGOS_BUFFER_H +#ifndef STDBIGOS_BUFFER +#define STDBIGOS_BUFFER #include #include +/// @addtogroup stdbigos +/// @{ +/// @addtogroup buffer +/// @{ + typedef struct buffer_t { size_t size; const void* data __sized_by(size); } buffer_t; -// Helpers to create buffers [[nodiscard]] static inline buffer_t make_buffer(const void* data, size_t size) { buffer_t buf = {.data = data, .size = size}; @@ -26,31 +30,24 @@ static inline bool buffer_is_empty(buffer_t buf) { return !buffer_is_valid(buf) || buf.size == 0; } -// Read big-endian 32-bit from buffer at given offset [[nodiscard]] bool buffer_read_u32_be(buffer_t buf, size_t offset, u32* out); -// Read big-endian 64-bit from buffer at given offset [[nodiscard]] bool buffer_read_u64_be(buffer_t buf, size_t offset, u64* out); -// Read little-endian 32-bit from buffer at given offset [[nodiscard]] bool buffer_read_u32_le(buffer_t buf, size_t offset, u32* out); -// Read little-endian 64-bit from buffer at given offset [[nodiscard]] bool buffer_read_u64_le(buffer_t buf, size_t offset, u64* out); -// Read a zero-terminated C-string from buf at offset and output it's length [[nodiscard]] bool buffer_read_cstring_len(buffer_t buf, size_t offset, const char** out_str, u64* len); -// Read a zero-terminated C-string from buf at offset [[nodiscard]] bool buffer_read_cstring(buffer_t buf, size_t offset, const char** out_str); -// Sub buffer [[nodiscard]] buffer_t buffer_sub_buffer(buffer_t buf, size_t offset, size_t max_size); @@ -60,4 +57,7 @@ int buffer_memcmp(buffer_t lhs, buffer_t rhs); [[nodiscard]] bool buffer_equal(buffer_t lhs, buffer_t rhs); -#endif +/// @} +/// @} + +#endif // !STDBIGOS_BUFFER diff --git a/include/stdbigos/csr.h b/include/stdbigos/csr.h index 9d3084a1..6c345a64 100644 --- a/include/stdbigos/csr.h +++ b/include/stdbigos/csr.h @@ -1,5 +1,5 @@ -#ifndef _STDBIGOS_CSR_H_ -#define _STDBIGOS_CSR_H_ +#ifndef STDBIGOS_CSR +#define STDBIGOS_CSR #include "types.h" @@ -57,14 +57,24 @@ __asm__ volatile("csrc " #csr ", %0" : : "rK"(_val) : "memory"); \ }) +/// @addtogroup stdbigos +/// @{ +/// @addtogroup csr +/// @{ + static inline u32 hartid() { return CSR_READ_RELAXED(mhartid); } + static inline void wfi() { __asm__ volatile("wfi" ::: "memory"); } + static inline void ebreak() { __asm__ volatile("ebreak" ::: "memory"); } -#endif +/// @} +/// @} + +#endif // !STDBIGOS_CSR diff --git a/include/stdbigos/error.h b/include/stdbigos/error.h index f442d1fe..4241d7ba 100644 --- a/include/stdbigos/error.h +++ b/include/stdbigos/error.h @@ -1,6 +1,7 @@ -#ifndef BIGOS_INCLUDE_STDBIGOS_ERROR -#define BIGOS_INCLUDE_STDBIGOS_ERROR +#ifndef STDBIGOS_ERROR +#define STDBIGOS_ERROR +/// @ingroup stdbigos error typedef enum [[nodiscard]] { ERR_NONE = 0, ERR_NOT_IMPLEMENTED, diff --git a/include/stdbigos/math.h b/include/stdbigos/math.h index 373b3225..44d4c470 100644 --- a/include/stdbigos/math.h +++ b/include/stdbigos/math.h @@ -1,14 +1,12 @@ -#ifndef _STDBIGOS_MATH_H -#define _STDBIGOS_MATH_H +#ifndef STDBIGOS_MATH +#define STDBIGOS_MATH -#define ALIGN_UP(x, align) (((x) + (align) - 1) / (align) * (align)) -#define ALIGN_UP_POW2(x, pow2) (((x) + (1 << (pow2)) - 1) & ~((1 << (pow2)) - 1)) -#define ALIGN_DOWN(x, align) (((x) / (align) * (align))) -#define ALIGN_DOWN_POW2(x, pow2) (((x) & ~((1 << pow2) - 1))) +#define ALIGN_DOWN(x, align) ((x) & ~((align) - 1)) +#define ALIGN_UP(x, align) (ALIGN_DOWN((x) + (align) - 1, (align))) -#define POW2(x) (1 << (x)) +#define EXP2(x) (1ull << (x)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif +#endif // !STDBIGOS_MATH diff --git a/include/stdbigos/memory_types.h b/include/stdbigos/memory_types.h new file mode 100644 index 00000000..cbd86d56 --- /dev/null +++ b/include/stdbigos/memory_types.h @@ -0,0 +1,112 @@ +#ifndef STDBIGOS_MEMORY_TYPES +#define STDBIGOS_MEMORY_TYPES + +#include +#include +#include +#include + +/// @addtogroup stdbigos +/// @{ +/// @addtogroup types +/// @{ + +/// Represents a contiguous range of valid, addressable memory. +typedef struct { + size_t size; + void* addr __sized_by(size); +} memory_region_t; + +/// Represents a contiguous range of physical memory. +typedef struct { + size_t size; + __phys void* addr __sized_by(size); +} physical_memory_region_t; + +/// Represents a range of memory, which isn't necessarily addressable. +typedef struct { + size_t size; + uintptr_t addr; +} memory_area_t; + +[[nodiscard]] +static inline memory_area_t memory_region_to_area(memory_region_t reg) { + const memory_area_t out = { + .addr = (uintptr_t)reg.addr, + .size = reg.size, + }; + return out; +} + +[[nodiscard]] +static inline memory_area_t physical_memory_region_to_area(physical_memory_region_t reg) { + const memory_area_t out = { + .addr = (uintptr_t)reg.addr, + .size = reg.size, + }; + return out; +} + +[[nodiscard]] +static inline bool do_memory_areas_overlap(memory_area_t area1, memory_area_t area2) { + bool cond1 = area1.addr < area2.addr + area2.size; + bool cond2 = area2.addr < area1.addr + area1.size; + return cond1 && cond2; +} + +[[nodiscard]] +static inline bool do_memory_regions_overlap(memory_region_t reg1, memory_region_t reg2) { + memory_area_t area1 = memory_region_to_area(reg1); + memory_area_t area2 = memory_region_to_area(reg2); + return do_memory_areas_overlap(area1, area2); +} + +[[nodiscard]] +static inline memory_area_t memory_area_expand_to_alignment(memory_area_t area, size_t align) { + memory_area_t aligned_reg = { + .addr = ALIGN_DOWN(area.addr, align), + .size = area.size, + }; + aligned_reg.size = area.size + area.addr - aligned_reg.addr; + aligned_reg.size = ALIGN_UP(aligned_reg.size, align); + return aligned_reg; +} + +[[nodiscard]] +static inline memory_area_t memory_area_shrink_to_alignment(memory_area_t area, size_t align) { + memory_area_t aligned_reg = { + .addr = ALIGN_UP(area.addr, align), + .size = area.size, + }; + aligned_reg.size = area.size - area.addr + aligned_reg.addr; + aligned_reg.size = ALIGN_DOWN(aligned_reg.size, align); + return aligned_reg; +} + +[[nodiscard]] +static inline memory_region_t memory_region_shrink_to_alignment(memory_region_t region, size_t align) { + memory_area_t area = memory_region_to_area(region); + area = memory_area_shrink_to_alignment(area, align); + const memory_region_t out = { + .addr = (void*)area.addr, + .size = area.size, + }; + return out; +} + +[[nodiscard]] +static inline physical_memory_region_t physical_memory_region_shrink_to_alignment(physical_memory_region_t region, + size_t align) { + memory_area_t area = physical_memory_region_to_area(region); + area = memory_area_shrink_to_alignment(area, align); + const physical_memory_region_t out = { + .addr = (__phys void*)area.addr, + .size = area.size, + }; + return out; +} + +/// @} +/// @} + +#endif // !STDBIGOS_MEMORY_TYPES diff --git a/include/stdbigos/sbi.h b/include/stdbigos/sbi.h index ca8cb49b..ee7db01c 100644 --- a/include/stdbigos/sbi.h +++ b/include/stdbigos/sbi.h @@ -3,6 +3,11 @@ #include "types.h" +/// @addtogroup stdbigos +/// @{ +/// @addtogroup sbi +/// @{ + #define SBI_SPEC_VERSION_DEFAULT 0x1 #define SBI_SPEC_VERSION_MAJOR_SHIFT 24 #define SBI_SPEC_VERSION_MAJOR_MASK 0x7f @@ -200,4 +205,7 @@ struct sbiret sbi_mpxy_send_message_with_response(u32 channel_id, u32 message_id struct sbiret sbi_mpxy_send_message_without_response(u32 channel_id, u32 message_id, reg_t message_data_len); struct sbiret sbi_mpxy_get_notification_events(u32 channel_id); +/// @} +/// @} + #endif diff --git a/include/stdbigos/stdio.h b/include/stdbigos/stdio.h index 82aeff5c..7eb2bb66 100644 --- a/include/stdbigos/stdio.h +++ b/include/stdbigos/stdio.h @@ -1,8 +1,8 @@ -#ifndef _STDBIGOS_STDIO_H_ -#define _STDBIGOS_STDIO_H_ +#ifndef STDBIGOS_STDIO +#define STDBIGOS_STDIO #define STB_SPRINTF_DECORATE(name) name #define STB_SPRINTF_NOFLOAT #include -#endif +#endif // !STDBIGOS_STDIO diff --git a/include/stdbigos/string.h b/include/stdbigos/string.h index 89a465f1..4c8edeab 100644 --- a/include/stdbigos/string.h +++ b/include/stdbigos/string.h @@ -1,11 +1,16 @@ -#ifndef _STDBIGOS_STRING_H_ -#define _STDBIGOS_STRING_H_ +#ifndef STDBIGOS_STRING +#define STDBIGOS_STRING #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wattributes" +/// @addtogroup stdbigos +/// @{ +/// @addtogroup string +/// @{ + [[reproducible, gnu::nonnull]] void* memcpy(void* restrict dest, const void* restrict src, size_t n); @@ -69,6 +74,9 @@ char* strpbrk(const char* dest, const char* breakset); [[unsequenced, gnu::nonnull, gnu::pure]] char* strstr(const char* str, const char* substr); +/// @} +/// @} + #pragma GCC diagnostic pop -#endif +#endif // !STDBIGOS_STRING diff --git a/include/stdbigos/trap.h b/include/stdbigos/trap.h index 2861ebac..4552f1ce 100644 --- a/include/stdbigos/trap.h +++ b/include/stdbigos/trap.h @@ -1,8 +1,13 @@ -#ifndef STDBIGOS_TRAP_H_ -#define STDBIGOS_TRAP_H_ +#ifndef STDBIGOS_TRAP +#define STDBIGOS_TRAP #include "types.h" +/// @ingroup stdbigos +/// @{ +/// @ingroup trap +/// @{ + typedef enum InterruptType { IntSSoftware = 1, // 2 is reserved @@ -54,4 +59,7 @@ static inline ExceptionType get_exception_code(reg_t cause) { return cause; } -#endif +/// @} +/// @} + +#endif // !STDBIGOS_TRAP diff --git a/include/stdbigos/types.h b/include/stdbigos/types.h index af24fcb0..ca0c2101 100644 --- a/include/stdbigos/types.h +++ b/include/stdbigos/types.h @@ -1,20 +1,32 @@ -#ifndef _STDBIGOS_TYPES_H_ -#define _STDBIGOS_TYPES_H_ +#ifndef STDBIGOS_TYPES +#define STDBIGOS_TYPES #include #include +/// @addtogroup stdbigos +/// @{ +/// @addtogroup types +/// @{ + typedef uint8_t u8; + typedef uint16_t u16; + typedef uint32_t u32; + typedef uint64_t u64; typedef int8_t i8; + typedef int16_t i16; + typedef int32_t i32; + typedef int64_t i64; typedef unsigned long reg_t; + typedef signed long ireg_t; static_assert(sizeof(reg_t) * 8 == __riscv_xlen); @@ -23,4 +35,7 @@ typedef enum { ENDIAN_BIG = 1, } endianness_t; -#endif +/// @} +/// @} + +#endif // !STDBIGOS_TYPES diff --git a/src/kernel/memory_management/common_types.c b/src/kernel/memory_management/common_types.c deleted file mode 100644 index 8d690313..00000000 --- a/src/kernel/memory_management/common_types.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -#include "stdbigos/types.h" - -memory_area_t memory_region_to_area(memory_region_t reg) { - const memory_area_t out = { - .addr = (uintptr_t)reg.addr, - .size = reg.size, - }; - return out; -} - -bool do_memory_areas_overlap(memory_area_t area1, memory_area_t area2) { - bool cond1 = area1.addr < area2.addr + area2.size; - bool cond2 = area2.addr < area1.addr + area1.size; - return cond1 && cond2; -} - -memory_area_t memory_area_expand_to_alignment(memory_area_t area, u64 align) { - memory_area_t aligned_reg = { - .addr = ALIGN_DOWN(area.addr, align), - .size = area.size, - }; - aligned_reg.size = area.size + area.addr - aligned_reg.addr; - aligned_reg.size = ALIGN_UP(aligned_reg.size, align); - return aligned_reg; -} - -memory_area_t memory_area_shrink_to_alignment(memory_area_t area, u64 align) { - memory_area_t aligned_reg = { - .addr = ALIGN_UP(area.addr, align), - .size = area.size, - }; - aligned_reg.size = area.size - area.addr + aligned_reg.addr; - aligned_reg.size = ALIGN_DOWN(aligned_reg.size, align); - return aligned_reg; -} - -memory_region_t memory_region_shrink_to_alignment(memory_region_t region, u64 align) { - memory_area_t area = memory_region_to_area(region); - area = memory_area_shrink_to_alignment(area, align); - const memory_region_t out = { - .addr = (void*)area.addr, - .size = area.size, - }; - return out; -} diff --git a/src/kernel/memory_management/include/common_types.h b/src/kernel/memory_management/include/common_types.h deleted file mode 100644 index 0852165d..00000000 --- a/src/kernel/memory_management/include/common_types.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef KERNEL_MEMORY_MANAGEMENT_COMMON_TYPES -#define KERNEL_MEMORY_MANAGEMENT_COMMON_TYPES - -#include -#include -#include -#include - -/** - * @ingroup kernel - * @ingroup kmm - * - * memory_region_t represents a contiguous range of valid, addressable memory. - * */ -typedef struct { - size_t size; - void* addr __sized_by(size); -} memory_region_t; - -/** - * @ingroup kernel - * @ingroup kmm - * - * memory_area_t represents a range of memory, which isn't necessarily addressable. - * */ -typedef struct { - size_t size; - uintptr_t addr; -} memory_area_t; - -[[nodiscard]] -memory_area_t memory_region_to_area(memory_region_t reg); - -[[nodiscard]] -bool do_memory_areas_overlap(memory_area_t area1, memory_area_t area2); - -/** - * @ingroup kernel - * @ingroup kmm - * - * @brief Expands a memory area so that its start address and size are aligned to @p align. - * - * The resulting area always fully contains the original @p area. - * - * @param area The memory area to align. - * @param align The alignment in bytes. Must be non-zero. - * - * @return A memory area aligned to @p align that completely encompasses @p area. - */ -[[nodiscard]] -memory_area_t memory_area_expand_to_alignment(memory_area_t area, u64 align); - -/** - * @ingroup kernel - * @ingroup kmm - * - * @brief Shrinks a memory area so that its start address and size are aligned to @p align. - * - * The resulting area is always fully contained in the original @p area. - * - * @param area The memory area to align. - * @param align The alignment in bytes. Must be non-zero. - * - * @return A memory area aligned to @p align that is completely encompassed by @p area. - */ -[[nodiscard]] -memory_area_t memory_area_shrink_to_alignment(memory_area_t area, u64 align); - -/** - * @ingroup kernel - * @ingroup kmm - * - * @brief Shrinks a memory region so that its start address and size are aligned to @p align. - * - * The resulting region is always fully contained in the original @p area. - * - * @param region The memory region to align. - * @param align The alignment in bytes. Must be non-zero. - * - * @return A memory region aligned to @p align that is completely encompassed by @p region. - */ -[[nodiscard]] -memory_region_t memory_region_shrink_to_alignment(memory_region_t region, u64 align); - -#endif diff --git a/src/kernel/memory_management/include/physical_memory/manager.h b/src/kernel/memory_management/include/physical_memory/manager.h index a13aed34..1d043049 100644 --- a/src/kernel/memory_management/include/physical_memory/manager.h +++ b/src/kernel/memory_management/include/physical_memory/manager.h @@ -1,54 +1,26 @@ #ifndef BIGOS_KERNEL_MEMORY_MANAGEMENT_PHYSICAL_MEMORY_MANAGER #define BIGOS_KERNEL_MEMORY_MANAGEMENT_PHYSICAL_MEMORY_MANAGER -#include #include #include +#include #include #include #include -#include "stdbigos/array_sizes.h" - -typedef __phys void* phys_addr_t; - -/// @ingroup kmm -/// @ingroup pmm -typedef struct { - size_t size; - phys_addr_t addr __sized_by(size); -} physical_memory_region_t; - -/// @ingroup kmm -/// @ingroup pmm -static inline memory_area_t phys_mem_reg_to_area(physical_memory_region_t region) { - memory_area_t area; - area.addr = (uintptr_t)region.addr; - area.size = region.size; - return area; -} - -/// @ingroup kmm -/// @ingroup pmm -static inline physical_memory_region_t area_to_phys_mem_reg(memory_area_t area) { - physical_memory_region_t region; - region.addr = (phys_addr_t)area.addr; - region.size = area.size; - return region; -} - /// @ingroup kmm /// @ingroup pmm +/// @todo implement static inline void* physical_to_effective([[maybe_unused]] __phys void* addr) { return nullptr; -} // TODO: this is here temporarly +} -static inline memory_region_t phys_mem_reg_to_reg(physical_memory_region_t pmr) { - memory_region_t reg = { - .size = pmr.size, +static inline memory_region_t physical_memory_region_to_effective(physical_memory_region_t pmr) { + memory_region_t out = { .addr = physical_to_effective(pmr.addr), + .size = pmr.size, }; - return reg; + return out; } /// @ingroup kmm @@ -97,7 +69,7 @@ error_t phys_mem_init(const physical_memory_region_t* pmrs, size_t pmr_count, co * @retval ERR_OUT_OF_MEMORY The block of specified size was not able to be allocated * */ [[gnu::nonnull]] -error_t phys_mem_alloc_frame(frame_size_t frame_size, phys_addr_t* addrOUT); +error_t phys_mem_alloc_frame(frame_size_t frame_size, physical_memory_region_t* regOUT); /** * @ingroup kmm @@ -105,6 +77,6 @@ error_t phys_mem_alloc_frame(frame_size_t frame_size, phys_addr_t* addrOUT); * @retval ERR_NONE * @retval ERR_NOT_VALID The address being freed was reported as not allocated * */ -error_t phys_mem_free_frame(phys_addr_t addr); +error_t phys_mem_free_frame(physical_memory_region_t reg); #endif //! BIGOS_KERNEL_MEMORY_MANAGMENT_PHYSICAL_MEMORY_MANAGMENT diff --git a/src/kernel/memory_management/physical_memory/allocator.c b/src/kernel/memory_management/physical_memory/allocator.c index 0c8bc47c..19e70a0c 100644 --- a/src/kernel/memory_management/physical_memory/allocator.c +++ b/src/kernel/memory_management/physical_memory/allocator.c @@ -1,6 +1,5 @@ #include "allocator.h" -#include "memory_management/include/physical_memory/manager.h" #include "stdbigos/error.h" error_t pmallocator_get_header(memory_area_t area, const memory_area_t* reserved_areas, u32 count, @@ -21,15 +20,15 @@ error_t pmallocator_init_region(memory_area_t area, memory_region_t header, cons return ERR_NOT_IMPLEMENTED; } -error_t pmallocator_allocate(u8 frame_order, memory_region_t header, phys_addr_t* addrOUT) { +error_t pmallocator_allocate(u8 frame_order, memory_region_t header, memory_area_t* areaOUT) { (void)frame_order; - *addrOUT = *addrOUT; + (void)areaOUT; (void)header; return ERR_NOT_IMPLEMENTED; } -error_t pmallocator_free(phys_addr_t addr, memory_region_t header) { - (void)addr; +error_t pmallocator_free(memory_area_t area, memory_region_t header) { + (void)area; (void)header; return ERR_NOT_IMPLEMENTED; } diff --git a/src/kernel/memory_management/physical_memory/allocator.h b/src/kernel/memory_management/physical_memory/allocator.h index c4fc113b..e462418f 100644 --- a/src/kernel/memory_management/physical_memory/allocator.h +++ b/src/kernel/memory_management/physical_memory/allocator.h @@ -1,11 +1,10 @@ #ifndef BIGOS_KERNEL_MEMORY_MANAGEMENT_PHYSICAL_MEMORY_ALLOCATOR #define BIGOS_KERNEL_MEMORY_MANAGEMENT_PHYSICAL_MEMORY_ALLOCATOR -#include #include +#include #include -#include "memory_management/include/common_types.h" #include "stdbigos/types.h" /** @@ -63,7 +62,7 @@ error_t pmallocator_init_region(memory_area_t area, memory_region_t header, cons * @note 4KiB frame (or @p frame_order = 12) must be a valid frame size. * */ [[gnu::nonnull]] -error_t pmallocator_allocate(u8 frame_order, memory_region_t header, phys_addr_t* addrOUT); +error_t pmallocator_allocate(u8 frame_order, memory_region_t header, memory_area_t* areaOUT); /** * @ingroup kmm @@ -75,6 +74,6 @@ error_t pmallocator_allocate(u8 frame_order, memory_region_t header, phys_addr_t * @retval ERR_NONE Success * @retval ERR_NOT_VALID The area represented by @p addr is already free. * */ -error_t pmallocator_free(phys_addr_t addr, memory_region_t header); +error_t pmallocator_free(memory_area_t area, memory_region_t header); #endif diff --git a/src/kernel/memory_management/physical_memory/manager.c b/src/kernel/memory_management/physical_memory/manager.c index af99855e..1431d8f8 100644 --- a/src/kernel/memory_management/physical_memory/manager.c +++ b/src/kernel/memory_management/physical_memory/manager.c @@ -1,10 +1,10 @@ #include "memory_management/include/physical_memory/manager.h" #include +#include #include #include "allocator.h" -#include "memory_management/include/common_types.h" #include "stdbigos/address.h" #include "stdbigos/error.h" @@ -50,11 +50,8 @@ static error_t store_header(physical_memory_region_t header) { if (effective_hsn->next != nullptr) { effective_hsn = physical_to_effective(effective_hsn->next); } else { - physical_memory_region_t new_reg = { - .addr = nullptr, - .size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB), - }; - error_t err = phys_mem_alloc_frame(FRAME_SIZE_4KiB, &new_reg.addr); + physical_memory_region_t new_reg = {0}; + error_t err = phys_mem_alloc_frame(FRAME_SIZE_4KiB, &new_reg); if (err) return err; err = init_header_storage_node(new_reg); @@ -91,10 +88,11 @@ error_t phys_mem_init(const physical_memory_region_t* pmrs, size_t pmr_count, co KLOG_INDENT_BLOCK_START; for (size_t i = 0; i < pmr_count; ++i) { - memory_area_t pmr_area = phys_mem_reg_to_area(pmrs[i]); - pmr_area = memory_area_shrink_to_alignment(pmr_area, 0x1000); - memory_area_t header_area = {0}; + physical_memory_region_t pmr = pmrs[i]; + pmr = physical_memory_region_shrink_to_alignment(pmr, 0x1000); + memory_area_t header_area = {0}; + memory_area_t pmr_area = physical_memory_region_to_area(pmr); error_t err = pmallocator_get_header(pmr_area, reserved_areas, reserved_areas_count, &header_area); if (err) { KLOGLN_WARNING("Failed to get header region of memory region [%p - %p]", pmrs[i].addr, @@ -102,33 +100,37 @@ error_t phys_mem_init(const physical_memory_region_t* pmrs, size_t pmr_count, co continue; } - physical_memory_region_t header_pmr = area_to_phys_mem_reg(header_area); - memory_region_t header_region = phys_mem_reg_to_reg(header_pmr); + physical_memory_region_t header_pmr = { + .addr = (__phys void*)header_area.addr, + .size = header_area.size, + }; + memory_region_t header_eff_reg = physical_memory_region_to_effective(header_pmr); - err = pmallocator_init_region(pmr_area, header_region, reserved_areas, reserved_areas_count); + err = pmallocator_init_region(pmr_area, header_eff_reg, reserved_areas, reserved_areas_count); if (err) { KLOGLN_WARNING("Failed to init header region of memory region [%p - %p]", pmrs[i].addr, pmrs[i].addr + pmrs[i].size); continue; } if (g_root_header_storage_node == nullptr) { - physical_memory_region_t new_reg = { - .size = phys_mem_get_frame_size_in_bytes(FRAME_SIZE_4KiB), - .addr = nullptr, - }; - err = pmallocator_allocate(12, header_region, &new_reg.addr); + memory_area_t new_area = {0}; + err = pmallocator_allocate(12, header_eff_reg, &new_area); // NOTE: Since we failed to allocate the smallest possible frame size, we assume that this region is // useless. if (err) { KLOGLN_WARNING("Failed to allocate a frame of size %zu from region [%p - %p]. This region will be " "ignored from now", - new_reg.size, pmrs[i].addr, pmrs[i].addr + pmrs[i].size); + new_area.size, pmrs[i].addr, pmrs[i].addr + pmrs[i].size); continue; } KLOGLN_TRACE( "Memory region of size: %zu at addr: %p is used as primary node for physical region headers storage", - new_reg.size, new_reg.addr); + new_area.size, (void*)new_area.addr); + physical_memory_region_t new_reg = { + .addr = (__phys void*)new_area.addr, + .size = new_area.size, + }; err = init_header_storage_node(new_reg); if (err) { // No need to free this region since this error is, and should be, fatal @@ -149,38 +151,43 @@ error_t phys_mem_init(const physical_memory_region_t* pmrs, size_t pmr_count, co } // NOLINTEND readability-function-cognitive-complexity -error_t phys_mem_alloc_frame(frame_size_t frame_size, phys_addr_t* addrOUT) { +error_t phys_mem_alloc_frame(frame_size_t frame_size, physical_memory_region_t* regOUT) { u32 idx = 0; physical_memory_region_t header_pmr; while (get_header_pmr(idx, &header_pmr) == ERR_NONE) { - memory_region_t header_region = phys_mem_reg_to_reg(header_pmr); - phys_addr_t frame_data = nullptr; - error_t err = pmallocator_allocate(frame_size + 12, header_region, &frame_data); + memory_region_t header_region = physical_memory_region_to_effective(header_pmr); + memory_area_t area_out; + error_t err = pmallocator_allocate(frame_size + 12, header_region, &area_out); if (err) { ++idx; continue; } - *addrOUT = frame_data; + physical_memory_region_t pmr_out = { + .addr = (__phys void*)area_out.addr, + .size = area_out.size, + }; + *regOUT = pmr_out; KLOGLN_TRACE("Allocated a physical frame of size: %lu at %p", phys_mem_get_frame_size_in_bytes(frame_size), - frame_data); + pmr_out.addr); return ERR_NONE; } KLOGLN_WARNING("Allocation of physical frame of size: %lu failed", phys_mem_get_frame_size_in_bytes(frame_size)); return ERR_OUT_OF_MEMORY; } -error_t phys_mem_free_frame(phys_addr_t addr) { +error_t phys_mem_free_frame(physical_memory_region_t reg) { u32 idx = 0; physical_memory_region_t header_pmr; while (get_header_pmr(idx, &header_pmr) == ERR_NONE) { - memory_region_t header_region = phys_mem_reg_to_reg(header_pmr); - error_t err = pmallocator_free(addr, header_region); + memory_region_t header_region = physical_memory_region_to_effective(header_pmr); + memory_area_t area = physical_memory_region_to_area(reg); + error_t err = pmallocator_free(area, header_region); if (err) { ++idx; continue; } return ERR_NONE; } - KLOGLN_WARNING("Failed to free a physical frame at addr: %p", addr); + KLOGLN_WARNING("Failed to free a physical frame at addr: %p, of size: %zu", reg.addr, reg.size); return ERR_NOT_VALID; }