panic: move to separate file, add KASSERT macro

main
anna 3 years ago
parent 24c6e9504d
commit b6385aea0a
Signed by: fef
GPG Key ID: EC22E476DC2D3D84

@ -28,6 +28,9 @@ configure_file(
include("arch/${ARCH}/config/toolchain.cmake")
# Used by the KASSERT macro for printing the filename relative to the source root
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -nostdinc -ffreestanding -fno-stack-protector")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -pipe -D_ASM_SOURCE")
if(DEBUG)

@ -55,6 +55,9 @@
*/
#define __packed __attribute__(( packed ))
#define __printflike(fmt_argn, firstva_argn) \
__attribute__(( format(printf, fmt_argn, firstva_argn) ))
/**
* @brief Function does not have any side effects or internal state.
* Subsequent calls with the same parameters always return the same result.

@ -18,8 +18,7 @@
* @returns The amount of bytes written,
* or a negative number from `errno.h` on failure
*/
__attribute__(( format(printf, 1, 2) ))
int kprintf(const char *__restrict fmt, ...);
int kprintf(const char *__restrict fmt, ...) __printflike(1, 2);
/**
* @brief Print to the kernel log.
@ -29,7 +28,7 @@ int kprintf(const char *__restrict fmt, ...);
* @returns The amount of bytes written,
* or a negative number from `errno.h` on failure
*/
int kvprintf(const char *__restrict fmt, va_list args);
int kvprintf(const char *__restrict fmt, va_list args) __printflike(1, 0);
/**
* @brief Printing functions that `kprintf()` and friends call for writing.

@ -25,6 +25,11 @@ struct task {
tcb_t tcb;
struct task *parent;
pid_t pid;
/**
* @brief 0 = interruptable, > 0 = uninterruptible, < 0 = we messed up.
* Increment/decrement using `critical_enter()`/`critical_leave()`.
*/
volatile int critnest;
enum task_state state;
};

@ -0,0 +1,64 @@
/* See the end of this file for copyright and license terms. */
#pragma once
#include <gay/cdefs.h>
#include <gay/sched.h>
#include <gay/types.h>
/**
* @brief Print an error message and halt the system immediately.
*
* @param fmt printf style format string
*/
void panic(const char *fmt, ...) __noreturn __printflike(1, 2);
#ifdef DEBUG
/**
* @brief Assert that statement `x` is true.
* If it is not and debugging is enabled, the kernel panics.
*/
#define KASSERT(x) do { \
if ( __predict_false(!(x)) ) { \
panic("Assertion \"%s\" failed!\n" \
" in function %s()\n" \
" in file %s, line %u\n", \
#x, __func__, __FILENAME__, __LINE__); \
} \
} while (0)
#else
#define KASSERT(x) do { } while (0)
#endif
static inline void critical_enter(void)
{
struct task *tsk = current;
tsk->critnest++;
}
static inline void critical_leave(void)
{
struct task *tsk = current;
tsk->critnest--;
KASSERT(tsk->critnest >= 0);
}
static inline bool in_critical(void)
{
return current->critnest > 0;
}
/*
* This file is part of GayBSD.
* Copyright (c) 2021 fef <owo@fef.moe>.
*
* GayBSD is nonviolent software: you may only use, redistribute, and/or
* modify it under the terms of the Cooperative Nonviolent Public License
* (CNPL) as found in the LICENSE file in the source code root directory
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
* of the license, or (at your option) any later version.
*
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
* permitted by applicable law. See the CNPL for details.
*/

@ -5,8 +5,6 @@
#include <gay/cdefs.h>
#include <gay/types.h>
void panic(const char *fmt, ...) __noreturn;
/**
* @brief Get the number of elements in a statically allocated array.
*
@ -49,20 +47,20 @@ static __always_inline bool sus_nil(const void *ptr)
return ptr < (void *)0x1000;
}
/**
* @brief Align `ptr` such that `ptr % n == 0`.
*
* @param ptr Pointer to align
* @param log The log2 of the alignment. If negative, the pointer will be
* aligned to the next lower address, otherwise to the next higher one.
* @returns The aligned pointer
*/
void *ptr_align(void *ptr, int log);
static __always_inline uintptr_t _align_floor(uintptr_t ptr, usize size)
{
return ptr - ptr % size;
}
#define align_floor(ptr, size) ( (typeof(ptr))_align_floor((uintptr_t)(ptr), size) )
static __always_inline uintptr_t uintptr_align(uintptr_t ptr, int log)
static __always_inline uintptr_t _align_ceil(uintptr_t ptr, usize size)
{
return (uintptr_t)ptr_align((void *)ptr, log);
uintptr_t aligned = ptr - ptr % size;
if (aligned < ptr)
aligned += size;
return aligned;
}
#define align_ceil(ptr, size) ( (typeof(ptr))_align_ceil((uintptr_t)(ptr), size) )
/*
* This file is part of GayBSD.

@ -13,8 +13,8 @@ target_sources(gay_kernel PRIVATE
kprintf.c
main.c
mutex.c
panic.c
sched.c
util.c
)
add_subdirectory(mm)

@ -38,7 +38,7 @@ int kmalloc_init(uintptr_t _phys_start, uintptr_t _phys_end)
phys_start = image_end_phys;
}
phys_start = uintptr_align(phys_start, +HUGEPAGE_SHIFT);
phys_start = align_ceil(phys_start, HUGEPAGE_SIZE);
/*
* This is intentionally not aligned to hugepages, because __early_get_page()
* shrinks it in single PAGE_SIZE steps whenever it is called anyway.
@ -48,7 +48,7 @@ int kmalloc_init(uintptr_t _phys_start, uintptr_t _phys_end)
* be able to allocate pages before the page frame allocator is set up
* in the first place).
*/
phys_end = uintptr_align(phys_end, -PAGE_SHIFT);
phys_end = align_floor(phys_end, PAGE_SIZE);
int err = pages_init();
if (err)

@ -2,12 +2,13 @@
#include <arch/cpufunc.h>
#include <gay/cdefs.h>
#include <gay/config.h>
#include <gay/kprintf.h>
#include <gay/types.h>
#include <gay/util.h>
#include <stdarg.h>
__noreturn
void panic(const char *fmt, ...)
{
va_list args;
@ -21,7 +22,7 @@ void panic(const char *fmt, ...)
else
kvprintf(fmt, args);
kprintf("\nSystem halted");
kprintf("\nKernel version: %s\nSystem halted", GAY_VERSION_STR);
/* no need for va_end() here i guess */
while (1) {
@ -30,17 +31,6 @@ void panic(const char *fmt, ...)
}
}
void *ptr_align(void *ptr, int log)
{
uintptr_t shifted = 1 << abs(log);
uintptr_t aligned = (uintptr_t)ptr & ~(shifted - 1);
if (log > 0 && aligned != (uintptr_t)ptr)
aligned += shifted;
return (void *)aligned;
}
/*
* This file is part of GayBSD.
* Copyright (c) 2021 fef <owo@fef.moe>.

@ -11,6 +11,7 @@ struct task kernel_task = {
.parent = nil,
.pid = 0,
.state = TASK_READY,
.critnest = 0,
};
struct task *current_array[CFG_MAX_CPU] = {
@ -40,6 +41,9 @@ void schedule(void)
struct task *old = current;
struct task *new = nil;
if (old->critnest)
return;
clist_add(inactive_queue, &old->run_queue);
/* Dijkstra would be so mad if he saw this */

Loading…
Cancel
Save