/* * @author xamidev * @brief Framebuffer-based terminal driver * @license GPL-3.0-only */ // Terminal output /* There are a couple of bugs here and there but for now I don't care too much because this shitty implementation will be replaced one day by Flanterm (once memory management is okay: paging & kernel malloc) */ #include #include #include #include #include #include #include #include #include #include #include #define NANOPRINTF_IMPLEMENTATION #include extern struct flanterm_context* ft_ctx; extern struct init_status init; struct spinlock_t term_lock = {0}; extern int panic_count; /* * _putchar - Writes a character to terminal (DEPRECATED) * @character: character to write */ void _putchar(char character) { // TODO: Spinlock here (terminal access) flanterm_write(ft_ctx, &character, 1); } /* * internal_putc - Internal putchar function * @c: char to print * @_: (unused, for nanoprintf) * * Prints a character to the terminal if it's ready, * and also to the serial interface if it's ready. */ void internal_putc(int c, void *_) { (void)_; char ch = (char)c; if (init.terminal) { if (panic_count == 0) { spinlock_acquire(&term_lock); flanterm_write(ft_ctx, &ch, 1); spinlock_release(&term_lock); } else { flanterm_write(ft_ctx, &ch, 1); } } if (init.serial) { if (ch == '\n') { skputc('\r'); } skputc(ch); } } /* * printf - Fromatted printing * @fmt: format string * @...: variadic arguments * * Wrapper for nanoprintf * * Return: * - number of characters sent to the callback */ int printf(const char* fmt, ...) { va_list args; va_start(args, fmt); int ret = npf_vpprintf(internal_putc, NULL, fmt, args); va_end(args); return ret; } /* * kputs - Kernel puts * @str: String to write * * Writes a non-formatted string to terminal */ void kputs(const char* str) { size_t i=0; while (str[i] != 0) { _putchar(str[i]); i++; } _putchar('\r'); } extern struct flanterm_context* ft_ctx; extern struct boot_context boot_ctx; /* * flanterm_free_wrapper - free() wrapper for Flanterm * @ptr: pointer to free * @size: amount of bytes to free * * This function exists solely because the Flanterm initialization * function only accepts a free() function with a size parameter, * and the default one doesn't have it. */ void flanterm_free_wrapper(void* ptr, size_t size) { (void)size; kfree(ptr); } /* * term_init - Video output/terminal initialization * * Uses Flanterm and the framebuffer given by Limine. */ void term_init() { uint32_t bgColor = 0x252525; ft_ctx = flanterm_fb_init( NULL, NULL, boot_ctx.fb->address, boot_ctx.fb->width, boot_ctx.fb->height, boot_ctx.fb->pitch, boot_ctx.fb->red_mask_size, boot_ctx.fb->red_mask_shift, boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift, boot_ctx.fb->blue_mask_size, boot_ctx.fb->blue_mask_shift, NULL, NULL, NULL, &bgColor, NULL, NULL, NULL, NULL, 0, 0, 1, 0, 0, 0, 0 ); init.terminal = true; }