Added kinfo, reduced global state

This commit is contained in:
ssimnb 2026-02-23 12:57:09 +01:00
parent 2213707c6a
commit e72c8fe6fd
30 changed files with 510 additions and 574 deletions

View file

@ -46,8 +46,10 @@ all: amd64
deps: deps:
mkdir -p $(BUILD_DIR) || true mkdir -p $(BUILD_DIR) || true
rm -rf build/limine rm -rf build/limine
git clone https://github.com/limine-bootloader/limine.git --branch=v8.x-binary --depth=1 build/limine git clone https://github.com/limine-bootloader/limine.git --branch=v10.x-binary --depth=1 build/limine
git clone https://codeberg.org/Limine/limine-protocol/ build/limine-protocol
make -C build/limine make -C build/limine
cp build/limine-protocol/include/limine.h include/
rm -rf build/flanterm rm -rf build/flanterm
git clone https://codeberg.org/mintsuki/flanterm build/flanterm git clone https://codeberg.org/mintsuki/flanterm build/flanterm
rm -rf build/uACPI rm -rf build/uACPI

View file

@ -1,6 +1,6 @@
/* BSD Zero Clause License */ /* SPDX-License-Identifier: 0BSD */
/* Copyright (C) 2022-2024 mintsuki and contributors. /* Copyright (C) 2022-2026 Mintsuki and contributors.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted. * purpose with or without fee is hereby granted.
@ -17,12 +17,12 @@
#ifndef LIMINE_H #ifndef LIMINE_H
#define LIMINE_H 1 #define LIMINE_H 1
#include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdint.h>
/* Misc */ /* Misc */
#ifdef LIMINE_NO_POINTERS #ifdef LIMINE_NO_POINTERS
@ -31,31 +31,16 @@ extern "C" {
# define LIMINE_PTR(TYPE) TYPE # define LIMINE_PTR(TYPE) TYPE
#endif #endif
#ifdef __GNUC__ #define LIMINE_REQUESTS_START_MARKER { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \
# define LIMINE_DEPRECATED __attribute__((__deprecated__)) 0x785c6ed015d3e316, 0x181e920a7852b9d9 }
# define LIMINE_DEPRECATED_IGNORE_START \ #define LIMINE_REQUESTS_END_MARKER { 0xadc0e0531bb10d03, 0x9572709f31764c62 }
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
# define LIMINE_DEPRECATED_IGNORE_END \
_Pragma("GCC diagnostic pop")
#else
# define LIMINE_DEPRECATED
# define LIMINE_DEPRECATED_IGNORE_START
# define LIMINE_DEPRECATED_IGNORE_END
#endif
#define LIMINE_REQUESTS_START_MARKER \ #define LIMINE_BASE_REVISION(N) { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }
uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \
0x785c6ed015d3e316, 0x181e920a7852b9d9 };
#define LIMINE_REQUESTS_END_MARKER \
uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 };
#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER #define LIMINE_BASE_REVISION_SUPPORTED(VAR) ((VAR)[2] == 0)
#define LIMINE_BASE_REVISION(N) \ #define LIMINE_LOADED_BASE_REVISION_VALID(VAR) ((VAR)[1] != 0x6a7b384944536bdc)
uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; #define LIMINE_LOADED_BASE_REVISION(VAR) ((VAR)[1])
#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0)
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b #define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
@ -75,7 +60,7 @@ struct limine_file {
LIMINE_PTR(void *) address; LIMINE_PTR(void *) address;
uint64_t size; uint64_t size;
LIMINE_PTR(char *) path; LIMINE_PTR(char *) path;
LIMINE_PTR(char *) cmdline; LIMINE_PTR(char *) string;
uint32_t media_type; uint32_t media_type;
uint32_t unused; uint32_t unused;
uint32_t tftp_ip; uint32_t tftp_ip;
@ -89,7 +74,7 @@ struct limine_file {
/* Boot info */ /* Boot info */
#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } #define LIMINE_BOOTLOADER_INFO_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 }
struct limine_bootloader_info_response { struct limine_bootloader_info_response {
uint64_t revision; uint64_t revision;
@ -103,13 +88,29 @@ struct limine_bootloader_info_request {
LIMINE_PTR(struct limine_bootloader_info_response *) response; LIMINE_PTR(struct limine_bootloader_info_response *) response;
}; };
/* Executable command line */
#define LIMINE_EXECUTABLE_CMDLINE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x4b161536e598651e, 0xb390ad4a2f1f303a }
struct limine_executable_cmdline_response {
uint64_t revision;
LIMINE_PTR(char *) cmdline;
};
struct limine_executable_cmdline_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_executable_cmdline_response *) response;
};
/* Firmware type */ /* Firmware type */
#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 } #define LIMINE_FIRMWARE_TYPE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 }
#define LIMINE_FIRMWARE_TYPE_X86BIOS 0 #define LIMINE_FIRMWARE_TYPE_X86BIOS 0
#define LIMINE_FIRMWARE_TYPE_UEFI32 1 #define LIMINE_FIRMWARE_TYPE_EFI32 1
#define LIMINE_FIRMWARE_TYPE_UEFI64 2 #define LIMINE_FIRMWARE_TYPE_EFI64 2
#define LIMINE_FIRMWARE_TYPE_SBI 3
struct limine_firmware_type_response { struct limine_firmware_type_response {
uint64_t revision; uint64_t revision;
@ -124,7 +125,7 @@ struct limine_firmware_type_request {
/* Stack size */ /* Stack size */
#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } #define LIMINE_STACK_SIZE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
struct limine_stack_size_response { struct limine_stack_size_response {
uint64_t revision; uint64_t revision;
@ -139,7 +140,7 @@ struct limine_stack_size_request {
/* HHDM */ /* HHDM */
#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } #define LIMINE_HHDM_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
struct limine_hhdm_response { struct limine_hhdm_response {
uint64_t revision; uint64_t revision;
@ -154,7 +155,7 @@ struct limine_hhdm_request {
/* Framebuffer */ /* Framebuffer */
#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } #define LIMINE_FRAMEBUFFER_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b }
#define LIMINE_FRAMEBUFFER_RGB 1 #define LIMINE_FRAMEBUFFER_RGB 1
@ -205,93 +206,29 @@ struct limine_framebuffer_request {
LIMINE_PTR(struct limine_framebuffer_response *) response; LIMINE_PTR(struct limine_framebuffer_response *) response;
}; };
/* Terminal */
#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 }
#define LIMINE_TERMINAL_CB_DEC 10
#define LIMINE_TERMINAL_CB_BELL 20
#define LIMINE_TERMINAL_CB_PRIVATE_ID 30
#define LIMINE_TERMINAL_CB_STATUS_REPORT 40
#define LIMINE_TERMINAL_CB_POS_REPORT 50
#define LIMINE_TERMINAL_CB_KBD_LEDS 60
#define LIMINE_TERMINAL_CB_MODE 70
#define LIMINE_TERMINAL_CB_LINUX 80
#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1))
#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2))
#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3))
#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4))
/* Response revision 1 */
#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10))
#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11))
#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0)
#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1)
#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2)
#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3)
#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4)
#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5)
#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6)
#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7)
LIMINE_DEPRECATED_IGNORE_START
struct LIMINE_DEPRECATED limine_terminal;
typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t);
typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t);
struct LIMINE_DEPRECATED limine_terminal {
uint64_t columns;
uint64_t rows;
LIMINE_PTR(struct limine_framebuffer *) framebuffer;
};
struct LIMINE_DEPRECATED limine_terminal_response {
uint64_t revision;
uint64_t terminal_count;
LIMINE_PTR(struct limine_terminal **) terminals;
LIMINE_PTR(limine_terminal_write) write;
};
struct LIMINE_DEPRECATED limine_terminal_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_terminal_response *) response;
LIMINE_PTR(limine_terminal_callback) callback;
};
LIMINE_DEPRECATED_IGNORE_END
/* Paging mode */ /* Paging mode */
#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } #define LIMINE_PAGING_MODE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a }
#if defined (__x86_64__) || defined (__i386__)
#define LIMINE_PAGING_MODE_X86_64_4LVL 0 #define LIMINE_PAGING_MODE_X86_64_4LVL 0
#define LIMINE_PAGING_MODE_X86_64_5LVL 1 #define LIMINE_PAGING_MODE_X86_64_5LVL 1
#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_X86_64_4LVL #define LIMINE_PAGING_MODE_X86_64_MIN LIMINE_PAGING_MODE_X86_64_4LVL
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL #define LIMINE_PAGING_MODE_X86_64_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL
#elif defined (__aarch64__)
#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 #define LIMINE_PAGING_MODE_AARCH64_4LVL 0
#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 #define LIMINE_PAGING_MODE_AARCH64_5LVL 1
#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_AARCH64_4LVL #define LIMINE_PAGING_MODE_AARCH64_MIN LIMINE_PAGING_MODE_AARCH64_4LVL
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL #define LIMINE_PAGING_MODE_AARCH64_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL
#elif defined (__riscv) && (__riscv_xlen == 64)
#define LIMINE_PAGING_MODE_RISCV_SV39 0 #define LIMINE_PAGING_MODE_RISCV_SV39 0
#define LIMINE_PAGING_MODE_RISCV_SV48 1 #define LIMINE_PAGING_MODE_RISCV_SV48 1
#define LIMINE_PAGING_MODE_RISCV_SV57 2 #define LIMINE_PAGING_MODE_RISCV_SV57 2
#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_RISCV_SV39 #define LIMINE_PAGING_MODE_RISCV_MIN LIMINE_PAGING_MODE_RISCV_SV39
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 #define LIMINE_PAGING_MODE_RISCV_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48
#elif defined (__loongarch__) && (__loongarch_grlen == 64)
#define LIMINE_PAGING_MODE_LOONGARCH64_4LVL 0 #define LIMINE_PAGING_MODE_LOONGARCH_4LVL 0
#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_LOONGARCH64_4LVL #define LIMINE_PAGING_MODE_LOONGARCH_MIN LIMINE_PAGING_MODE_LOONGARCH_4LVL
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_LOONGARCH64_4LVL #define LIMINE_PAGING_MODE_LOONGARCH_DEFAULT LIMINE_PAGING_MODE_LOONGARCH_4LVL
#else
#error Unknown architecture
#endif
struct limine_paging_mode_response { struct limine_paging_mode_response {
uint64_t revision; uint64_t revision;
@ -307,37 +244,19 @@ struct limine_paging_mode_request {
uint64_t min_mode; uint64_t min_mode;
}; };
/* 5-level paging */ /* MP */
#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } #define LIMINE_MP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 }
LIMINE_DEPRECATED_IGNORE_START struct limine_mp_info;
struct LIMINE_DEPRECATED limine_5_level_paging_response { typedef void (*limine_goto_address)(struct limine_mp_info *);
uint64_t revision;
};
struct LIMINE_DEPRECATED limine_5_level_paging_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_5_level_paging_response *) response;
};
LIMINE_DEPRECATED_IGNORE_END
/* SMP */
#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 }
struct limine_smp_info;
typedef void (*limine_goto_address)(struct limine_smp_info *);
#if defined (__x86_64__) || defined (__i386__) #if defined (__x86_64__) || defined (__i386__)
#define LIMINE_SMP_X2APIC (1 << 0) #define LIMINE_MP_RESPONSE_X86_64_X2APIC (1 << 0)
struct limine_smp_info { struct limine_mp_info {
uint32_t processor_id; uint32_t processor_id;
uint32_t lapic_id; uint32_t lapic_id;
uint64_t reserved; uint64_t reserved;
@ -345,17 +264,17 @@ struct limine_smp_info {
uint64_t extra_argument; uint64_t extra_argument;
}; };
struct limine_smp_response { struct limine_mp_response {
uint64_t revision; uint64_t revision;
uint32_t flags; uint32_t flags;
uint32_t bsp_lapic_id; uint32_t bsp_lapic_id;
uint64_t cpu_count; uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus; LIMINE_PTR(struct limine_mp_info **) cpus;
}; };
#elif defined (__aarch64__) #elif defined (__aarch64__)
struct limine_smp_info { struct limine_mp_info {
uint32_t processor_id; uint32_t processor_id;
uint32_t reserved1; uint32_t reserved1;
uint64_t mpidr; uint64_t mpidr;
@ -364,17 +283,17 @@ struct limine_smp_info {
uint64_t extra_argument; uint64_t extra_argument;
}; };
struct limine_smp_response { struct limine_mp_response {
uint64_t revision; uint64_t revision;
uint64_t flags; uint64_t flags;
uint64_t bsp_mpidr; uint64_t bsp_mpidr;
uint64_t cpu_count; uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus; LIMINE_PTR(struct limine_mp_info **) cpus;
}; };
#elif defined (__riscv) && (__riscv_xlen == 64) #elif defined (__riscv) && (__riscv_xlen == 64)
struct limine_smp_info { struct limine_mp_info {
uint64_t processor_id; uint64_t processor_id;
uint64_t hartid; uint64_t hartid;
uint64_t reserved; uint64_t reserved;
@ -382,39 +301,41 @@ struct limine_smp_info {
uint64_t extra_argument; uint64_t extra_argument;
}; };
struct limine_smp_response { struct limine_mp_response {
uint64_t revision; uint64_t revision;
uint64_t flags; uint64_t flags;
uint64_t bsp_hartid; uint64_t bsp_hartid;
uint64_t cpu_count; uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus; LIMINE_PTR(struct limine_mp_info **) cpus;
}; };
#elif defined (__loongarch__) && (__loongarch_grlen == 64) #elif defined (__loongarch__) && (__loongarch_grlen == 64)
struct limine_smp_info { struct limine_mp_info {
uint64_t reserved; uint64_t reserved;
}; };
struct limine_smp_response { struct limine_mp_response {
uint64_t cpu_count; uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus; LIMINE_PTR(struct limine_mp_info **) cpus;
}; };
#else #else
#error Unknown architecture #error Unknown architecture
#endif #endif
struct limine_smp_request { #define LIMINE_MP_REQUEST_X86_64_X2APIC (1 << 0)
struct limine_mp_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_smp_response *) response; LIMINE_PTR(struct limine_mp_response *) response;
uint64_t flags; uint64_t flags;
}; };
/* Memory map */ /* Memory map */
#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } #define LIMINE_MEMMAP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 }
#define LIMINE_MEMMAP_USABLE 0 #define LIMINE_MEMMAP_USABLE 0
#define LIMINE_MEMMAP_RESERVED 1 #define LIMINE_MEMMAP_RESERVED 1
@ -422,8 +343,9 @@ struct limine_smp_request {
#define LIMINE_MEMMAP_ACPI_NVS 3 #define LIMINE_MEMMAP_ACPI_NVS 3
#define LIMINE_MEMMAP_BAD_MEMORY 4 #define LIMINE_MEMMAP_BAD_MEMORY 4
#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 #define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5
#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 #define LIMINE_MEMMAP_EXECUTABLE_AND_MODULES 6
#define LIMINE_MEMMAP_FRAMEBUFFER 7 #define LIMINE_MEMMAP_FRAMEBUFFER 7
#define LIMINE_MEMMAP_RESERVED_MAPPED 8
struct limine_memmap_entry { struct limine_memmap_entry {
uint64_t base; uint64_t base;
@ -445,7 +367,7 @@ struct limine_memmap_request {
/* Entry point */ /* Entry point */
#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } #define LIMINE_ENTRY_POINT_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a }
typedef void (*limine_entry_point)(void); typedef void (*limine_entry_point)(void);
@ -460,31 +382,31 @@ struct limine_entry_point_request {
LIMINE_PTR(limine_entry_point) entry; LIMINE_PTR(limine_entry_point) entry;
}; };
/* Kernel File */ /* Executable File */
#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } #define LIMINE_EXECUTABLE_FILE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 }
struct limine_kernel_file_response { struct limine_executable_file_response {
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_file *) kernel_file; LIMINE_PTR(struct limine_file *) executable_file;
}; };
struct limine_kernel_file_request { struct limine_executable_file_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_kernel_file_response *) response; LIMINE_PTR(struct limine_executable_file_response *) response;
}; };
/* Module */ /* Module */
#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } #define LIMINE_MODULE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) #define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0)
#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) #define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1)
struct limine_internal_module { struct limine_internal_module {
LIMINE_PTR(const char *) path; LIMINE_PTR(const char *) path;
LIMINE_PTR(const char *) cmdline; LIMINE_PTR(const char *) string;
uint64_t flags; uint64_t flags;
}; };
@ -506,7 +428,7 @@ struct limine_module_request {
/* RSDP */ /* RSDP */
#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } #define LIMINE_RSDP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c }
struct limine_rsdp_response { struct limine_rsdp_response {
uint64_t revision; uint64_t revision;
@ -521,7 +443,7 @@ struct limine_rsdp_request {
/* SMBIOS */ /* SMBIOS */
#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } #define LIMINE_SMBIOS_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee }
struct limine_smbios_response { struct limine_smbios_response {
uint64_t revision; uint64_t revision;
@ -537,7 +459,7 @@ struct limine_smbios_request {
/* EFI system table */ /* EFI system table */
#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } #define LIMINE_EFI_SYSTEM_TABLE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc }
struct limine_efi_system_table_response { struct limine_efi_system_table_response {
uint64_t revision; uint64_t revision;
@ -552,7 +474,7 @@ struct limine_efi_system_table_request {
/* EFI memory map */ /* EFI memory map */
#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } #define LIMINE_EFI_MEMMAP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 }
struct limine_efi_memmap_response { struct limine_efi_memmap_response {
uint64_t revision; uint64_t revision;
@ -568,40 +490,40 @@ struct limine_efi_memmap_request {
LIMINE_PTR(struct limine_efi_memmap_response *) response; LIMINE_PTR(struct limine_efi_memmap_response *) response;
}; };
/* Boot time */ /* Date at boot */
#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } #define LIMINE_DATE_AT_BOOT_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 }
struct limine_boot_time_response { struct limine_date_at_boot_response {
uint64_t revision; uint64_t revision;
int64_t boot_time; int64_t timestamp;
}; };
struct limine_boot_time_request { struct limine_date_at_boot_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_boot_time_response *) response; LIMINE_PTR(struct limine_date_at_boot_response *) response;
}; };
/* Kernel address */ /* Executable address */
#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } #define LIMINE_EXECUTABLE_ADDRESS_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 }
struct limine_kernel_address_response { struct limine_executable_address_response {
uint64_t revision; uint64_t revision;
uint64_t physical_base; uint64_t physical_base;
uint64_t virtual_base; uint64_t virtual_base;
}; };
struct limine_kernel_address_request { struct limine_executable_address_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_kernel_address_response *) response; LIMINE_PTR(struct limine_executable_address_response *) response;
}; };
/* Device Tree Blob */ /* Device Tree Blob */
#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } #define LIMINE_DTB_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 }
struct limine_dtb_response { struct limine_dtb_response {
uint64_t revision; uint64_t revision;
@ -614,6 +536,50 @@ struct limine_dtb_request {
LIMINE_PTR(struct limine_dtb_response *) response; LIMINE_PTR(struct limine_dtb_response *) response;
}; };
/* RISC-V Boot Hart ID */
#define LIMINE_RISCV_BSP_HARTID_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x1369359f025525f9, 0x2ff2a56178391bb6 }
struct limine_riscv_bsp_hartid_response {
uint64_t revision;
uint64_t bsp_hartid;
};
struct limine_riscv_bsp_hartid_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_riscv_bsp_hartid_response *) response;
};
/* Bootloader Performance */
#define LIMINE_BOOTLOADER_PERFORMANCE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x6b50ad9bf36d13ad, 0xdc4c7e88fc759e17 }
struct limine_bootloader_performance_response {
uint64_t revision;
uint64_t reset_usec;
uint64_t init_usec;
uint64_t exec_usec;
};
struct limine_bootloader_performance_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_bootloader_performance_response *) response;
};
#define LIMINE_X86_64_KEEP_IOMMU_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x8ebaabe51f490179, 0x2aa86a59ffb4ab0f }
struct limine_x86_64_keep_iommu_response {
uint64_t revision;
};
struct limine_x86_64_keep_iommu_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_x86_64_keep_iommu_response *) response;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -1,5 +1,15 @@
#pragma once
#include <stdint.h> #include <stdint.h>
void kkill(void);
typedef struct kernel_info {
char *cmdline; // kernel commandline options (maybe split into char**'s?)
uint64_t hhdmoffset; // HHDM offset
uint64_t cpu_count; // number of cpus
uint64_t usable_memory; // amount of usable memory the system has
uint64_t bsp_id; // id of the bsp cpu
int64_t boot_timestamp; // timestamp at boot
} kernel_info;
typedef char link_symbol_ptr[]; typedef char link_symbol_ptr[];
@ -17,4 +27,6 @@ typedef char link_symbol_ptr[];
#define SIZE_IN_PAGES(size) size/PAGE_SIZE #define SIZE_IN_PAGES(size) size/PAGE_SIZE
void *kmalloc(uint64_t size); struct kernel_info *get_kinfo();
void initialize_kinfo();
void kkill(void); // phase this out in favor of assert

View file

@ -29,7 +29,5 @@ void scheduler_init();
[[noreturn]] void sched(); [[noreturn]] void sched();
void yield(); void yield();
#define PROC_MAX 512 // Max number of processes #define PROC_MAX 1024 // Max number of processes per cpu
#define INITIAL_STACK_SIZE 0x10000

View file

@ -13,4 +13,6 @@ int memcmp(const void *s1, const void *s2, uint64_t n);
uint64_t strlen(const char* str); uint64_t strlen(const char* str);
void itoa(char *str, int number);
#endif #endif

View file

@ -1,3 +1,3 @@
#include <stdint.h> #include <stdint.h>
uint64_t get_timestamp_ns(); uint64_t get_timestamp_us();
void sleep(int ms); void sleep(int ms);

View file

@ -1,14 +1,16 @@
#include <sys/acpi.h> #include <sys/acpi.h>
#include <drivers/pmt.h> #include <drivers/pmt.h>
#include <arch/amd64/hal/smp.h> #include <smp.h>
#include <arch/amd64/hal/timer.h> #include <arch/amd64/hal/timer.h>
#include <arch/amd64/hal/ioapic.h> #include <arch/amd64/hal/ioapic.h>
#include <arch/amd64/io.h>
#include <lock.h> #include <lock.h>
#include <kprint.h> #include <kprint.h>
#include <neobbo.h> #include <neobbo.h>
#include <cpuid.h> // GCC specific #include <cpuid.h> // GCC specific
#define IA32_APIC_BASE_MSR 0x1B
#define LAPIC_ID_REG 0x020 #define LAPIC_ID_REG 0x020
#define LAPIC_EOI_REG 0x0B0 #define LAPIC_EOI_REG 0x0B0
#define LAPIC_SPURIOUS_REG 0x0F0 #define LAPIC_SPURIOUS_REG 0x0F0
@ -31,7 +33,6 @@
#define LAPIC_TIMER_VECTOR 69 #define LAPIC_TIMER_VECTOR 69
extern madt_t *madt;
extern uint64_t hhdmoffset; extern uint64_t hhdmoffset;
uint64_t lapic_address = 0; uint64_t lapic_address = 0;
@ -87,7 +88,7 @@ void lapic_timer_init(int us){
void apic_init(void){ void apic_init(void){
asm("cli"); asm("cli");
lapic_address = madt->lic_address + hhdmoffset; lapic_address = rdmsr(IA32_APIC_BASE_MSR) + get_kinfo()->hhdmoffset;
lapic_ao_t *lapic_ao = (lapic_ao_t*) find_ics(0x5); // Local APIC Address Override lapic_ao_t *lapic_ao = (lapic_ao_t*) find_ics(0x5); // Local APIC Address Override
@ -95,7 +96,7 @@ void apic_init(void){
if(lapic_ao){ if(lapic_ao){
/* Check that the field isnt 0 */ /* Check that the field isnt 0 */
if(lapic_ao->lapic_address != 0){ if(lapic_ao->lapic_address != 0){
lapic_address = lapic_ao->lapic_address + hhdmoffset; lapic_address = lapic_ao->lapic_address + get_kinfo()->hhdmoffset;
} }
} }
@ -108,8 +109,8 @@ void apic_init(void){
/* Start the timers for calibration of the APIC timer */ /* Start the timers for calibration of the APIC timer */
timer_init(); timer_init();
/* Start the APIC timer with 10ms timer */ /* Start the APIC timer with 1us timer */
lapic_timer_init(10000); lapic_timer_init(1);
asm("sti"); asm("sti");
} }
@ -120,7 +121,7 @@ void ap_apic_init(){
lapic_write_reg(LAPIC_SPURIOUS_REG, 0x1FF); lapic_write_reg(LAPIC_SPURIOUS_REG, 0x1FF);
/* Start the APIC timer */ /* Start the APIC timer */
lapic_timer_init(10000); lapic_timer_init(1);
asm("sti"); asm("sti");
} }
@ -133,7 +134,6 @@ void apic_timer_handler(){
lapic_write_reg(LAPIC_EOI_REG, 0); lapic_write_reg(LAPIC_EOI_REG, 0);
} }
void apic_send_ipi(uint8_t dest_field, uint8_t dest_shorthand, uint8_t trigger, uint8_t level, uint8_t status, uint8_t destination, uint8_t delivery_mode, uint8_t vector){ void apic_send_ipi(uint8_t dest_field, uint8_t dest_shorthand, uint8_t trigger, uint8_t level, uint8_t status, uint8_t destination, uint8_t delivery_mode, uint8_t vector){

View file

@ -1,6 +1,6 @@
#include <arch/amd64/hal/idt.h> #include <arch/amd64/hal/idt.h>
#include <error.h> #include <error.h>
#include <arch/amd64/hal/smp.h> #include <smp.h>
#include <arch/amd64/hal/timer.h> #include <arch/amd64/hal/timer.h>
#include <kprint.h> #include <kprint.h>
#include <lock.h> #include <lock.h>
@ -205,8 +205,10 @@ extern void *next_frame(void *addr);
void interrupt_handler(interrupt_frame *r){ void interrupt_handler(interrupt_frame *r){
//asm("cli");
if(r->int_no < 32){ if(r->int_no < 32){
kprintf("\nOh no! Received interrupt {d}, '{s}'. Below is the provided stack frame\n\n", r->int_no, exception_messages[r->int_no]); kprintf("\nOh no! Received interrupt 0x{x}, '{s}'. Below is the provided stack frame\n\n", r->int_no, exception_messages[r->int_no]);
if(r->err != 0){ if(r->err != 0){
kprintf("error code 0x{xn}", r->err); kprintf("error code 0x{xn}", r->err);
@ -235,16 +237,21 @@ void interrupt_handler(interrupt_frame *r){
if(r->int_no == 69){ if(r->int_no == 69){
apic_timer_handler(); apic_timer_handler();
return;
} }
if(r->int_no == 69 && get_cpu_struct_initialized() if(r->int_no == 69 && get_cpu_struct_initialized()
&& get_cpu_struct()->scheduler_initialized){ && get_cpu_struct()->scheduler_initialized){
yield(); yield();
return;
} }
if(r->int_no == 70){ if(r->int_no == 70){
for(;;){ for(;;){
asm("cli;hlt"); for(;;){
asm("cli");
__builtin_ia32_pause();
}
} }
} }

View file

@ -13,8 +13,6 @@
#define IOAPICARB 0x2 #define IOAPICARB 0x2
#define IOREDTBL(x) (0x10 + (x * 2)) // 0-23 registers #define IOREDTBL(x) (0x10 + (x * 2)) // 0-23 registers
extern uint64_t hhdmoffset;
extern madt_t *madt; extern madt_t *madt;
uint64_t ioapic_address; uint64_t ioapic_address;
@ -57,6 +55,6 @@ void ioapic_init(void){
kkill(); kkill();
} }
ioapic_address = ioapic->ioapic_address + hhdmoffset; ioapic_address = ioapic->ioapic_address + get_kinfo()->hhdmoffset;
} }

View file

@ -1,114 +0,0 @@
#include <limine.h>
#include <stdbool.h>
#include <stdint.h>
#include <kprint.h>
#include <neobbo.h>
#include <arch/amd64/hal/gdt.h>
#include <arch/amd64/hal/smp.h>
#include <arch/amd64/hal/apic.h>
#include <arch/amd64/hal/idt.h>
#include <mm/vmm.h>
#include <lock.h>
#include <io.h>
#include <string.h>
static volatile struct limine_smp_request smp_request = {
.id = LIMINE_SMP_REQUEST,
.revision = 0,
};
extern void s_load_idt();
extern void s_load_gdt();
extern uint64_t hhdmoffset;
/* Returns the CPU structure for this particular CPU */
cpu_state *get_cpu_struct(){
return (cpu_state*)rdmsr(GSBASE);
}
uint64_t get_cpu_count(){
return smp_request.response->cpu_count;
}
bool get_cpu_struct_initialized(){
if(rdmsr(GSBASE) < hhdmoffset){
return false;
}
return true;
}
atomic_flag ap_init_lock = ATOMIC_FLAG_INIT;
void ap_init(struct limine_smp_info *smp_info){
acquire_spinlock(&ap_init_lock);
/* Load the GDT */
s_load_gdt();
/* Load the IDT */
s_load_idt();
/* Set the CR3 context */
extern uint64_t *kernel_page_map;
vmm_set_ctx(kernel_page_map);
asm volatile(
"movq %%cr3, %%rax\n\
movq %%rax, %%cr3\n"
: : : "rax"
);
cpu_state *cpu_struct = (cpu_state*)kmalloc(sizeof(cpu_state));
memset(cpu_struct, 0, sizeof(cpu_state));
cpu_struct->lapic_id = smp_info->lapic_id;
wrmsr(KERNELGSBASE, (uint64_t)cpu_struct);
wrmsr(GSBASE, (uint64_t)cpu_struct);
/* Initialize APIC & APIC timer */
ap_apic_init();
free_spinlock(&ap_init_lock);
for(;;);
scheduler_init();
}
void smp_init(){
if(!smp_request.response){
klog(__func__, "Failed to get SMP request");
kkill();
}
struct limine_smp_response *smp_response = smp_request.response;
kprintf("smp: {d} CPUs\n", smp_response->cpu_count);
for(uint64_t i = 0; i < smp_response->cpu_count; i++){
/* Pointer to smp_info is passed in RDI by Limine, so no need to pass any arguments here */
smp_response->cpus[i]->goto_address = &ap_init;
}
/* -- Setup CPU structure for BSP -- */
/* Allocate CPU structure */
cpu_state *cpu_struct = (cpu_state*)kmalloc(sizeof(cpu_state));
cpu_struct->lapic_id = smp_response->cpus[0]->lapic_id;
cpu_struct->scheduler_context = (struct context*)kmalloc(sizeof(struct context));
wrmsr(KERNELGSBASE, (uint64_t)cpu_struct);
wrmsr(GSBASE, (uint64_t)cpu_struct);
/* If one of the APs has halted, then halt the BSP */
extern bool kernel_killed;
if(kernel_killed == true){
kkill();
}
}

View file

@ -15,7 +15,7 @@ int calibration_timer = -1;
void timer_init(void){ void timer_init(void){
if(pmt_init() == -1){ if(pmt_init() == -1){
klog(__func__, "PMT Timer not found, falling back"); klog(__func__, "PMT Timer not found, falling back");
/* Fall back to PIT */ /* Fall back to HPET */
}else{ }else{
calibration_timer = PMT; calibration_timer = PMT;
} }

View file

@ -73,5 +73,5 @@ uint64_t tsc_get_timestamp(){
return 0; return 0;
} }
uint64_t read = read_tsc(); uint64_t read = read_tsc();
return read / core_crystal_clock; return (read * 1000ULL) / core_crystal_clock;
} }

View file

@ -54,7 +54,7 @@ void ahci_init(){
/* Map the AHCI registers */ /* Map the AHCI registers */
kmap_pages((uint64_t*)ahci_base_address, 1, PTE_BIT_RW | PTE_BIT_NX | PTE_BIT_UNCACHABLE); kmap_pages((uint64_t*)ahci_base_address, 1, PTE_BIT_RW | PTE_BIT_NX | PTE_BIT_UNCACHABLE);
ahci_base_address += hhdmoffset; ahci_base_address += get_kinfo()->hhdmoffset;
/* BIOS/OS Handoff */ /* BIOS/OS Handoff */
kprintf("ahci: Performing BIOS/OS handoff\n"); kprintf("ahci: Performing BIOS/OS handoff\n");

View file

@ -1,7 +1,7 @@
#include <sys/acpi.h> #include <sys/acpi.h>
#include <kprint.h> #include <kprint.h>
#include <neobbo.h> #include <neobbo.h>
#include <io.h> #include <arch/amd64/io.h>
#define PMT_TIMER_RATE 3579545 #define PMT_TIMER_RATE 3579545
@ -40,7 +40,7 @@ int pmt_init(){
kkill(); kkill();
} }
fadt = (fadt_t*)((uint64_t)fadt + hhdmoffset); fadt = (fadt_t*)((uint64_t)fadt + get_kinfo()->hhdmoffset);
/* Check if timer exists */ /* Check if timer exists */
if(fadt->PMTimerLength == 0){ if(fadt->PMTimerLength == 0){

View file

@ -1,7 +1,7 @@
#include <sys/acpi.h> #include <sys/acpi.h>
#include <arch/amd64/hal/ioapic.h> #include <arch/amd64/hal/ioapic.h>
#include <io.h> #include <arch/amd64/io.h>
#include <kprint.h> #include <kprint.h>
#define COM1 0x3F8 #define COM1 0x3F8
@ -56,13 +56,25 @@ void serial_init(){
} }
uint8_t serial_read(){ uint8_t serial_read(){
while((inb(COM1 + LINE_STAT_REG) & 0x1) == 0){ asm("nop"); } while((inb(COM1 + LINE_STAT_REG) & 0x1) == 0){
#ifdef __x86_64__
__builtin_ia32_pause();
#else
asm("hlt");
#endif
}
return inb(COM1); return inb(COM1);
} }
void serial_write(uint8_t data){ void serial_write(uint8_t data){
while((inb(COM1 + LINE_STAT_REG) & (1 << 5)) == 0){ asm("nop"); } while((inb(COM1 + LINE_STAT_REG) & (1 << 5)) == 0){
#ifdef __x86_64__
__builtin_ia32_pause();
#else
asm("hlt");
#endif
}
outb(COM1, data); outb(COM1, data);
} }

47
src/kinfo.c Normal file
View file

@ -0,0 +1,47 @@
#include <neobbo.h>
#include <assert.h>
#include <limine.h>
#include <error.h>
#include <stdatomic.h>
#include <stddef.h>
static volatile struct limine_hhdm_request hhdm_request = {
.id = LIMINE_HHDM_REQUEST_ID,
.revision = 0,
};
volatile struct limine_mp_request smp_request = {
.id = LIMINE_MP_REQUEST_ID,
.revision = 0,
};
static volatile struct limine_executable_cmdline_request executable_cmdline_request = {
.id = LIMINE_EXECUTABLE_CMDLINE_REQUEST_ID,
.revision = 0,
};
static volatile struct limine_date_at_boot_request date_at_boot_request = {
.id = LIMINE_DATE_AT_BOOT_REQUEST_ID,
.revision = 0,
};
extern struct kernel_info kinfo;
void initialize_kinfo(){
assert(hhdm_request.response != NULL && "HHDM response is NULL");
assert(smp_request.response != NULL && "SMP response is NULL");
assert(executable_cmdline_request.response != NULL && "Exec cmdline response is NULL");
assert(date_at_boot_request.response != NULL && "Date at boot response is NULL");
kinfo.hhdmoffset = hhdm_request.response->offset;
kinfo.cmdline = executable_cmdline_request.response->cmdline;
kinfo.cpu_count = smp_request.response->cpu_count;
kinfo.boot_timestamp = date_at_boot_request.response->timestamp;
#ifdef __x86_64__
kinfo.bsp_id = smp_request.response->bsp_lapic_id;
#endif
}
struct kernel_info *get_kinfo(){
return &kinfo;
}

View file

@ -1,63 +0,0 @@
#include <stdint.h>
uint64_t rdmsr(uint64_t msr){
uint32_t low, high;
asm volatile (
"rdmsr"
: "=a"(low), "=d"(high)
: "c"(msr)
);
return ((uint64_t)high << 32) | low;
}
void wrmsr(uint64_t msr, uint64_t value){
uint32_t low = value & 0xFFFFFFFF;
uint32_t high = value >> 32;
asm volatile (
"wrmsr"
:
: "c"(msr), "a"(low), "d"(high)
);
}
void outb(uint16_t port, uint8_t val){
asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) : "memory");
}
void outw(uint16_t port, uint16_t val){
asm volatile ( "outw %0, %1" : : "a"(val), "Nd"(port) : "memory");
}
void outl(uint16_t port, uint32_t val){
asm volatile ( "outl %0, %1" : : "a"(val), "Nd"(port) : "memory");
}
uint8_t inb(uint16_t port){
uint8_t ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "Nd"(port)
: "memory");
return ret;
}
uint16_t inw(uint16_t port){
uint16_t ret;
asm volatile ( "inw %1, %0"
: "=a"(ret)
: "Nd"(port)
: "memory");
return ret;
}
uint32_t inl(uint16_t port){
uint32_t ret;
asm volatile ( "inl %1, %0"
: "=a"(ret)
: "Nd"(port)
: "memory");
return ret;
}

View file

@ -7,6 +7,7 @@
#include <kprint.h> #include <kprint.h>
#include <drivers/serial.h> #include <drivers/serial.h>
#include <arch/amd64/hal/tsc.h> #include <arch/amd64/hal/tsc.h>
#include <sys/time.h>
#define FORMAT_LENGTH 1 #define FORMAT_LENGTH 1
@ -28,7 +29,35 @@ void klog(const char *func, const char *msg, ...){
serial_kprintf("{ksk}: {s}\n", ANSI_COLOR_MAGENTA, func, ANSI_COLOR_RESET, msg); serial_kprintf("{ksk}: {s}\n", ANSI_COLOR_MAGENTA, func, ANSI_COLOR_RESET, msg);
return; return;
}
void print_timestamp(struct flanterm_context *ft_ctx){
uint64_t time = get_timestamp_us();
char str[100];
uint64_t seconds = time / 1000000ULL;
uint64_t millis = (time % 1000000ULL) / 1000ULL;
str[0] = '[';
str[1] = '\0';
itoa(str + 1, seconds);
size_t len = strlen(str);
str[len] = '.';
str[len + 1] = '\0';
len = strlen(str);
if (millis < 100) str[len++] = '0';
if (millis < 10) str[len++] = '0';
str[len] = '\0';
itoa(str + len, millis);
len = strlen(str);
str[len] = ']';
str[len + 1] = '\0';
print_str(ft_ctx, str);
print_char(ft_ctx, ' ');
} }
atomic_flag printf_lock = ATOMIC_FLAG_INIT; atomic_flag printf_lock = ATOMIC_FLAG_INIT;
@ -55,6 +84,7 @@ int kprintf(const char *format_string, ...){
int state = NORMAL; int state = NORMAL;
va_list a_list; va_list a_list;
va_start(a_list, format_string); va_start(a_list, format_string);
print_timestamp(ft_ctx);
for(uint64_t i = 0; i < strlen(format_string); i++){ for(uint64_t i = 0; i < strlen(format_string); i++){
char current = format_string[i]; // current char in string char current = format_string[i]; // current char in string
switch (state){ switch (state){
@ -123,6 +153,67 @@ int kprintf(const char *format_string, ...){
return 0; return 0;
} }
int ksnprintf(char * str, const char *format_string, ...){
int state = NORMAL;
va_list a_list;
va_start(a_list, format_string);
for(uint64_t i = 0; i < strlen(format_string); i++){
char current = format_string[i]; // current char in string
switch (state){
case NORMAL:
switch (current) {
case '{':
state = FORMAT_SPECIFIER;
break;
default:
*(str+i) = current;
break;
}
break;
case FORMAT_SPECIFIER:
switch (current) {
case 'k':
break;
case 'd':
case 'i':
break;
case 's':
break;
case 'c':
;
int ch = va_arg(a_list, int);
break;
case 'x':
break;
case 'b':
break;
case 'l':
current++;
switch (current) {
case 'd':
break;
}
break;
case '}':
state = NORMAL;
break;
}
break;
}
}
va_end(a_list);
return 0;
}
int serial_kprintf(const char *format_string, ...){ int serial_kprintf(const char *format_string, ...){
int state = NORMAL; int state = NORMAL;
va_list a_list; va_list a_list;
@ -192,7 +283,7 @@ int serial_kprintf(const char *format_string, ...){
return 0; return 0;
} }
#define MAX_INTERGER_SIZE 128 #define MAX_INTEGER_SIZE 128
void print_char(struct flanterm_context *ft_ctx, char c){ void print_char(struct flanterm_context *ft_ctx, char c){
kernel_framebuffer_print(&c, 1); kernel_framebuffer_print(&c, 1);
@ -207,13 +298,13 @@ void print_str(struct flanterm_context *ft_ctx, char *str){
} }
void print_int(struct flanterm_context *ft_ctx, uint64_t num){ void print_int(struct flanterm_context *ft_ctx, uint64_t num){
char buffer[MAX_INTERGER_SIZE] = {0}; char buffer[MAX_INTEGER_SIZE] = {0};
if(num == 0){ if(num == 0){
buffer[0] = '0'; buffer[0] = '0';
} }
int arr[MAX_INTERGER_SIZE] = {0}; int arr[MAX_INTEGER_SIZE] = {0};
int j = 0; int j = 0;
while(num != 0){ while(num != 0){
@ -222,7 +313,7 @@ void print_int(struct flanterm_context *ft_ctx, uint64_t num){
num /= 10; num /= 10;
j++; j++;
if(j == MAX_INTERGER_SIZE){ if(j == MAX_INTEGER_SIZE){
return; return;
} }
} }
@ -236,13 +327,13 @@ void print_int(struct flanterm_context *ft_ctx, uint64_t num){
} }
void print_hex(struct flanterm_context *ft_ctx, uint64_t num){ void print_hex(struct flanterm_context *ft_ctx, uint64_t num){
char buffer[MAX_INTERGER_SIZE] = {0}; char buffer[MAX_INTEGER_SIZE] = {0};
if(num == 0){ if(num == 0){
buffer[0] = '0'; buffer[0] = '0';
} }
int arr[MAX_INTERGER_SIZE] = {0}; int arr[MAX_INTEGER_SIZE] = {0};
int j = 0; int j = 0;
while(num != 0){ while(num != 0){
@ -251,7 +342,7 @@ void print_hex(struct flanterm_context *ft_ctx, uint64_t num){
num /= 16; num /= 16;
j++; j++;
if(j == MAX_INTERGER_SIZE){ if(j == MAX_INTEGER_SIZE){
return; return;
} }
} }
@ -265,9 +356,9 @@ void print_hex(struct flanterm_context *ft_ctx, uint64_t num){
} }
void print_bin(struct flanterm_context *ft_ctx, uint64_t num){ void print_bin(struct flanterm_context *ft_ctx, uint64_t num){
char buffer[MAX_INTERGER_SIZE] = {0}; char buffer[MAX_INTEGER_SIZE] = {0};
int arr[MAX_INTERGER_SIZE] = {0}; int arr[MAX_INTEGER_SIZE] = {0};
int j = 0; int j = 0;
while(num != 0){ while(num != 0){
@ -276,7 +367,7 @@ void print_bin(struct flanterm_context *ft_ctx, uint64_t num){
num /= 2; num /= 2;
j++; j++;
if(j == MAX_INTERGER_SIZE){ if(j == MAX_INTEGER_SIZE){
return; return;
} }
} }
@ -290,9 +381,9 @@ void print_bin(struct flanterm_context *ft_ctx, uint64_t num){
} }
void serial_print_int(uint64_t num){ void serial_print_int(uint64_t num){
char buffer[MAX_INTERGER_SIZE] = {0}; char buffer[MAX_INTEGER_SIZE] = {0};
int arr[MAX_INTERGER_SIZE] = {0}; int arr[MAX_INTEGER_SIZE] = {0};
int j = 0; int j = 0;
while(num != 0){ while(num != 0){
@ -301,7 +392,7 @@ void serial_print_int(uint64_t num){
num /= 10; num /= 10;
j++; j++;
if(j == MAX_INTERGER_SIZE){ if(j == MAX_INTEGER_SIZE){
return; return;
} }
} }
@ -315,9 +406,9 @@ void serial_print_int(uint64_t num){
} }
void serial_print_hex(uint64_t num){ void serial_print_hex(uint64_t num){
char buffer[MAX_INTERGER_SIZE] = {0}; char buffer[MAX_INTEGER_SIZE] = {0};
int arr[MAX_INTERGER_SIZE] = {0}; int arr[MAX_INTEGER_SIZE] = {0};
int j = 0; int j = 0;
while(num != 0){ while(num != 0){
@ -326,7 +417,7 @@ void serial_print_hex(uint64_t num){
num /= 16; num /= 16;
j++; j++;
if(j == MAX_INTERGER_SIZE){ if(j == MAX_INTEGER_SIZE){
return; return;
} }
} }
@ -340,9 +431,9 @@ void serial_print_hex(uint64_t num){
} }
void serial_print_bin(uint64_t num){ void serial_print_bin(uint64_t num){
char buffer[MAX_INTERGER_SIZE] = {0}; char buffer[MAX_INTEGER_SIZE] = {0};
int arr[MAX_INTERGER_SIZE] = {0}; int arr[MAX_INTEGER_SIZE] = {0};
int j = 0; int j = 0;
while(num != 0){ while(num != 0){
@ -351,7 +442,7 @@ void serial_print_bin(uint64_t num){
num /= 2; num /= 2;
j++; j++;
if(j == MAX_INTERGER_SIZE){ if(j == MAX_INTEGER_SIZE){
return; return;
} }
} }
@ -365,62 +456,10 @@ void serial_print_bin(uint64_t num){
} }
char toupper(char c){ char toupper(char c) {
switch(c){ if (c >= 'a' && c <= 'z')
case 'a': return c - ('a' - 'A');
return 'A'; return c;
case 'b':
return 'B';
case 'c':
return 'C';
case 'd':
return 'D';
case 'e':
return 'E';
case 'f':
return 'F';
case 'g':
return 'G';
case 'h':
return 'H';
case 'i':
return 'I';
case 'j':
return 'J';
case 'k':
return 'K';
case 'l':
return 'L';
case 'm':
return 'M';
case 'n':
return 'N';
case 'o':
return 'O';
case 'p':
return 'P';
case 't':
return 'T';
case 'r':
return 'R';
case 's':
return 'S';
case 'u':
return 'U';
case 'v':
return 'V';
case 'w':
return 'W';
case 'x':
return 'X';
case 'y':
return 'Y';
case 'z':
return 'Z';
default:
return c;
}
} }
/* Eventually fix printf so that these print_* functions dont /* Eventually fix printf so that these print_* functions dont

View file

@ -1,4 +1,4 @@
#include "arch/amd64/hal/smp.h" #include "smp.h"
#include "error.h" #include "error.h"
#include <mm/slab.h> #include <mm/slab.h>
#include <lock.h> #include <lock.h>

View file

@ -76,7 +76,29 @@ char dtoc(int digit){
if(digit < 10){ if(digit < 10){
return '0' + digit; return '0' + digit;
}else{ }else{
return 'A' + digit - 10; return 'a' + digit - 10;
}
}
void itoa(char *str, uint64_t number){
int i = 0;
if (number == 0) {
str[i++] = '0';
str[i] = '\0';
return;
}
while (number != 0) {
str[i++] = (number % 10) + '0';
number /= 10;
}
str[i] = '\0';
int start = 0, end = i - 1;
while (start < end) {
char temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
} }
} }

View file

@ -11,7 +11,7 @@
#include <arch/amd64/hal/idt.h> #include <arch/amd64/hal/idt.h>
#include <arch/amd64/hal/apic.h> #include <arch/amd64/hal/apic.h>
#include <arch/amd64/hal/timer.h> #include <arch/amd64/hal/timer.h>
#include <arch/amd64/hal/smp.h> #include <smp.h>
#include <arch/amd64/hal/tsc.h> #include <arch/amd64/hal/tsc.h>
#include <mm/pmm.h> #include <mm/pmm.h>
#include <mm/slab.h> #include <mm/slab.h>
@ -25,30 +25,19 @@
#include <drivers/ahci.h> #include <drivers/ahci.h>
#include <scheduler/sched.h> #include <scheduler/sched.h>
#include <sys/rand.h> #include <sys/rand.h>
#include <sys/time.h>
static volatile struct limine_framebuffer_request framebuffer_request = { static volatile struct limine_framebuffer_request framebuffer_request = {
.id = LIMINE_FRAMEBUFFER_REQUEST, .id = LIMINE_FRAMEBUFFER_REQUEST_ID,
.revision = 0,
};
static volatile struct limine_hhdm_request hhdm_request = {
.id = LIMINE_HHDM_REQUEST,
.revision = 0, .revision = 0,
}; };
struct flanterm_context *ft_ctx; struct flanterm_context *ft_ctx;
uint64_t hhdmoffset = 0; struct kernel_info kinfo;
void _start(void){ void _start(void){
if(hhdm_request.response == NULL){
goto death;
}
hhdmoffset = hhdm_request.response->offset;
/* initalize framebuffer */ /* initalize framebuffer */
struct limine_framebuffer_response *fb_response = framebuffer_request.response; struct limine_framebuffer_response *fb_response = framebuffer_request.response;
@ -78,19 +67,25 @@ void _start(void){
0, 0 0, 0
); );
kprintf("Welcome to Neobbo{n}");
extern link_symbol_ptr text_start_addr, text_end_addr; extern link_symbol_ptr text_start_addr, text_end_addr;
serial_init();
krand_init();
set_gdt(); set_gdt();
set_idt(); set_idt();
initialize_kinfo();
kprintf("Welcome to Neobbo\n");
serial_init();
krand_init();
klog("acpi", "Reading ACPI tables"); klog("acpi", "Reading ACPI tables");
acpi_init(); acpi_init();
bsp_early_init();
klog("apic", "Initalizing APIC"); klog("apic", "Initalizing APIC");
apic_init(); apic_init();
@ -116,18 +111,25 @@ void _start(void){
scheduler_init(); scheduler_init();
/* klog(LOG_INFO, "ahci", "Initializing AHCI controller");
ahci_init();
klog(LOG_SUCCESS, "ahci", "Done!"); */
death: death:
for(;;); for(;;){
//kprintf("d\n");
__builtin_ia32_pause();
}
} }
bool kernel_killed = false; bool kernel_killed = false;
void kkill(void){ [[noreturn]] void kkill(void){
kernel_killed = true; kernel_killed = true;
kprintf("The kernel has been killed.\n"); kprintf("The kernel has been killed.\n");
asm volatile("cli; hlt");
for(;;); #ifdef __x86_64__
asm("cli");
for(;;){
__builtin_ia32_pause();
}
#else
asm("hlt");
#endif
} }

View file

@ -1,3 +1,4 @@
#include <assert.h>
#include <mm/page.h> #include <mm/page.h>
#include <limine.h> #include <limine.h>
#include <mm/vmm.h> #include <mm/vmm.h>
@ -50,11 +51,7 @@ void init_page_array(){
pages = va_alloc_contigious_pages((page_count * sizeof(struct page)) / PAGE_SIZE); pages = va_alloc_contigious_pages((page_count * sizeof(struct page)) / PAGE_SIZE);
if(pages == NULL){ assert(pages != NULL && "Couldn't allocate page structure");
klog(__func__, "Couldn't allocate page structure");
kkill();
return;
}
memset(pages, 0, (page_count * sizeof(struct page)) / PAGE_SIZE); memset(pages, 0, (page_count * sizeof(struct page)) / PAGE_SIZE);

View file

@ -6,7 +6,7 @@
#include <mm/kmalloc.h> #include <mm/kmalloc.h>
static volatile struct limine_memmap_request memmap_request = { static volatile struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST, .id = LIMINE_MEMMAP_REQUEST_ID,
.revision = 0, .revision = 0,
}; };
@ -25,7 +25,7 @@ atomic_flag pmm_lock = ATOMIC_FLAG_INIT;
void pmm_free(uint64_t *addr){ void pmm_free(uint64_t *addr){
acquire_spinlock(&pmm_lock); acquire_spinlock(&pmm_lock);
uint64_t *virt_addr = (uint64_t*)((uint64_t)addr+hhdmoffset); uint64_t *virt_addr = (uint64_t*)((uint64_t)addr+get_kinfo()->hhdmoffset);
/* Make the given page point to the previous free page */ /* Make the given page point to the previous free page */
*virt_addr = (uint64_t)free_list; *virt_addr = (uint64_t)free_list;
@ -45,7 +45,7 @@ uint64_t *pmm_alloc(){
} }
/* Fetch the address of the free page in free_list and make it point to the next free page */ /* Fetch the address of the free page in free_list and make it point to the next free page */
uint64_t *addr = (uint64_t*)((uint64_t)free_list - hhdmoffset); uint64_t *addr = (uint64_t*)((uint64_t)free_list - get_kinfo()->hhdmoffset);
free_list = (uint64_t*)(*free_list); free_list = (uint64_t*)(*free_list);
pmm_free_page_count--; pmm_free_page_count--;
free_spinlock(&pmm_lock); free_spinlock(&pmm_lock);
@ -78,10 +78,10 @@ void pmm_init(){
kprintf("pmm: got a total of {d}MB of memory\n", mem_size / 1048576); kprintf("pmm: got a total of {d}MB of memory\n", mem_size / 1048576);
get_kinfo()->usable_memory = mem_size / 1048576;
bool first_entry = true; bool first_entry = true;
uint64_t j; uint64_t j;
uint64_t i; uint64_t i;
@ -92,7 +92,7 @@ void pmm_init(){
/* First set the first entry if it isn't set already */ /* First set the first entry if it isn't set already */
if(first_entry == true){ if(first_entry == true){
first_entry = false; first_entry = false;
free_list = (uint64_t*)(entries[i]->base + hhdmoffset); free_list = (uint64_t*)(entries[i]->base + get_kinfo()->hhdmoffset);
j = 1; j = 1;
}else{ }else{
j = 0; j = 0;

View file

@ -10,12 +10,12 @@
#include <sys/acpi.h> #include <sys/acpi.h>
#include <arch/amd64/hal/apic.h> #include <arch/amd64/hal/apic.h>
struct limine_kernel_address_request kernel_addr_request = { struct limine_executable_address_request kernel_addr_request = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST, .id = LIMINE_EXECUTABLE_ADDRESS_REQUEST_ID,
.revision = 0 .revision = 0
}; };
struct limine_kernel_address_response *kernel_address; struct limine_executable_address_response *kernel_address;
extern uint64_t hhdmoffset; extern uint64_t hhdmoffset;
@ -29,20 +29,20 @@ uint64_t kernel_start, kernel_end;
void vmm_set_ctx(uint64_t *page_map){ void vmm_set_ctx(uint64_t *page_map){
__asm__ volatile ( __asm__ volatile (
"movq %0, %%cr3\n" "movq %0, %%cr3\n"
: : "r" ((uint64_t)((uint64_t)(page_map) - hhdmoffset)) : "memory" : : "r" ((uint64_t)((uint64_t)(page_map) - get_kinfo()->hhdmoffset)) : "memory"
); );
} }
void vmm_init(){ void vmm_init(){
struct limine_kernel_address_response *kernel_address = kernel_addr_request.response; struct limine_executable_address_response *kernel_address = kernel_addr_request.response;
if(!kernel_address){ if(!kernel_address){
klog(__func__, "Kernel address not recieved"); klog(__func__, "Kernel address not recieved");
} }
kernel_page_map = (uint64_t*)((uint64_t)pmm_alloc() + hhdmoffset); kernel_page_map = (uint64_t*)((uint64_t)pmm_alloc() + get_kinfo()->hhdmoffset);
if(!kernel_page_map){ if(!kernel_page_map){
klog(__func__, "Allocating block for page map failed"); klog(__func__, "Allocating block for page map failed");
@ -68,22 +68,22 @@ void vmm_init(){
for(uint64_t i = 0; i < memmap_response->entry_count; i++){ for(uint64_t i = 0; i < memmap_response->entry_count; i++){
if(memmap_response->entries[i]->type == LIMINE_MEMMAP_USABLE){ if(memmap_response->entries[i]->type == LIMINE_MEMMAP_USABLE){
for(uint64_t j = 0; j < memmap_response->entries[i]->length; j+=PAGE_SIZE){ for(uint64_t j = 0; j < memmap_response->entries[i]->length; j+=PAGE_SIZE){
vmm_map_page(kernel_page_map, memmap_response->entries[i]->base+j+hhdmoffset, memmap_response->entries[i]->base+j, PTE_BIT_PRESENT | PTE_BIT_RW); vmm_map_page(kernel_page_map, memmap_response->entries[i]->base+j+get_kinfo()->hhdmoffset, memmap_response->entries[i]->base+j, PTE_BIT_PRESENT | PTE_BIT_RW);
} }
} }
if(memmap_response->entries[i]->type == LIMINE_MEMMAP_FRAMEBUFFER){ if(memmap_response->entries[i]->type == LIMINE_MEMMAP_FRAMEBUFFER){
for(uint64_t j = 0; j < memmap_response->entries[i]->length; j+=PAGE_SIZE){ for(uint64_t j = 0; j < memmap_response->entries[i]->length; j+=PAGE_SIZE){
vmm_map_page(kernel_page_map, memmap_response->entries[i]->base+j+hhdmoffset, memmap_response->entries[i]->base+j, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX); vmm_map_page(kernel_page_map, memmap_response->entries[i]->base+j+get_kinfo()->hhdmoffset, memmap_response->entries[i]->base+j, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX);
} }
} }
if(memmap_response->entries[i]->type == LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE){ if(memmap_response->entries[i]->type == LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE){
for(uint64_t j = 0; j < memmap_response->entries[i]->length; j+=PAGE_SIZE){ for(uint64_t j = 0; j < memmap_response->entries[i]->length; j+=PAGE_SIZE){
vmm_map_page(kernel_page_map, memmap_response->entries[i]->base+j+hhdmoffset, memmap_response->entries[i]->base+j, PTE_BIT_PRESENT | PTE_BIT_RW); vmm_map_page(kernel_page_map, memmap_response->entries[i]->base+j+get_kinfo()->hhdmoffset, memmap_response->entries[i]->base+j, PTE_BIT_PRESENT | PTE_BIT_RW);
} }
} }
if(memmap_response->entries[i]->type == LIMINE_MEMMAP_ACPI_RECLAIMABLE){ if(memmap_response->entries[i]->type == LIMINE_MEMMAP_ACPI_RECLAIMABLE){
for(uint64_t j = 0; j < memmap_response->entries[i]->length; j+=PAGE_SIZE){ for(uint64_t j = 0; j < memmap_response->entries[i]->length; j+=PAGE_SIZE){
vmm_map_page(kernel_page_map, memmap_response->entries[i]->base+j+hhdmoffset, memmap_response->entries[i]->base+j, PTE_BIT_PRESENT | PTE_BIT_RW); vmm_map_page(kernel_page_map, memmap_response->entries[i]->base+j+get_kinfo()->hhdmoffset, memmap_response->entries[i]->base+j, PTE_BIT_PRESENT | PTE_BIT_RW);
} }
} }
@ -118,7 +118,7 @@ void vmm_init(){
extern uint64_t lapic_address; extern uint64_t lapic_address;
/* Map the APIC */ /* Map the APIC */
vmm_map_page(kernel_page_map, lapic_address, lapic_address - hhdmoffset, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX); vmm_map_page(kernel_page_map, lapic_address, lapic_address - get_kinfo()->hhdmoffset, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX);
/* Map the ACPI tables */ /* Map the ACPI tables */
extern xsdt_t *xsdt; extern xsdt_t *xsdt;
@ -129,12 +129,12 @@ void vmm_init(){
fill an entire page it still requires a page */ fill an entire page it still requires a page */
for(uint64_t i = 0; i < rsdt->header.length / PAGE_SIZE + 1; i++){ for(uint64_t i = 0; i < rsdt->header.length / PAGE_SIZE + 1; i++){
kprintf("mapping 0x{xn}", (uint64_t)rsdt + i * PAGE_SIZE); kprintf("mapping 0x{xn}", (uint64_t)rsdt + i * PAGE_SIZE);
vmm_map_page(kernel_page_map, (uint64_t)rsdt + i * PAGE_SIZE, ((uint64_t)rsdt - hhdmoffset) + i * PAGE_SIZE, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX); vmm_map_page(kernel_page_map, (uint64_t)rsdt + i * PAGE_SIZE, ((uint64_t)rsdt - get_kinfo()->hhdmoffset) + i * PAGE_SIZE, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX);
} }
}else{ }else{
for(uint64_t i = 0; i < xsdt->header.length / PAGE_SIZE + 1; i++){ for(uint64_t i = 0; i < xsdt->header.length / PAGE_SIZE + 1; i++){
kprintf("mapping 0x{xn}", (uint64_t)xsdt + i * PAGE_SIZE); kprintf("mapping 0x{xn}", (uint64_t)xsdt + i * PAGE_SIZE);
vmm_map_page(kernel_page_map, (uint64_t)xsdt + i * PAGE_SIZE, ((uint64_t)xsdt - hhdmoffset) + i * PAGE_SIZE, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX); vmm_map_page(kernel_page_map, (uint64_t)xsdt + i * PAGE_SIZE, ((uint64_t)xsdt - get_kinfo()->hhdmoffset) + i * PAGE_SIZE, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX);
} }
} }
@ -151,7 +151,7 @@ void vmm_init(){
uint64_t *get_lower_table(uint64_t *page_map, uint64_t offset){ uint64_t *get_lower_table(uint64_t *page_map, uint64_t offset){
if((page_map[offset] & PTE_BIT_PRESENT) != 0){ if((page_map[offset] & PTE_BIT_PRESENT) != 0){
return (uint64_t*)( ((uint64_t)page_map[offset] & 0x000ffffffffff000) + hhdmoffset); return (uint64_t*)( ((uint64_t)page_map[offset] & 0x000ffffffffff000) + get_kinfo()->hhdmoffset);
} }
@ -165,11 +165,11 @@ uint64_t *get_lower_table(uint64_t *page_map, uint64_t offset){
return NULL; return NULL;
} }
memset((uint64_t*)((uint64_t)ret + hhdmoffset), 0, PAGE_SIZE); memset((uint64_t*)((uint64_t)ret + get_kinfo()->hhdmoffset), 0, PAGE_SIZE);
page_map[offset] = (uint64_t)ret | PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_US; page_map[offset] = (uint64_t)ret | PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_US;
return (uint64_t*)((uint64_t)ret + hhdmoffset); return (uint64_t*)((uint64_t)ret + get_kinfo()->hhdmoffset);
} }
@ -274,15 +274,15 @@ uint64_t vmm_get_phys_addr(uint64_t *page_map, uint64_t virt_addr){
uint64_t pml4e = page_map[pml4_offset]; uint64_t pml4e = page_map[pml4_offset];
if (!(pml4e & 1)) return 0; // if (!(pml4e & 1)) return 0; //
uint64_t *pdp = (uint64_t *)((pml4e & 0x000ffffffffff000) + hhdmoffset); uint64_t *pdp = (uint64_t *)((pml4e & 0x000ffffffffff000) + get_kinfo()->hhdmoffset);
uint64_t pdpe = pdp[pdp_offset]; uint64_t pdpe = pdp[pdp_offset];
if (!(pdpe & 1)) return 0; if (!(pdpe & 1)) return 0;
uint64_t *pd = (uint64_t *)((pdpe & 0x000ffffffffff000) + hhdmoffset); uint64_t *pd = (uint64_t *)((pdpe & 0x000ffffffffff000) + get_kinfo()->hhdmoffset);
uint64_t pde = pd[pd_offset]; uint64_t pde = pd[pd_offset];
if (!(pde & 1)) return 0; if (!(pde & 1)) return 0;
uint64_t *pt = (uint64_t *)((pde & 0x000ffffffffff000) + hhdmoffset); uint64_t *pt = (uint64_t *)((pde & 0x000ffffffffff000) + get_kinfo()->hhdmoffset);
uint64_t pte = pt[pt_offset]; uint64_t pte = pt[pt_offset];
if (!(pte & 1)) return 0; if (!(pte & 1)) return 0;
@ -326,7 +326,7 @@ void *va_alloc_contigious_pages(size_t pages){
return NULL; return NULL;
} }
vmm_map_page(kernel_page_map, va_base+hhdmoffset+i*PAGE_SIZE, (uint64_t)t, PTE_BIT_RW | PTE_BIT_PRESENT); vmm_map_page(kernel_page_map, va_base+get_kinfo()->hhdmoffset+i*PAGE_SIZE, (uint64_t)t, PTE_BIT_RW | PTE_BIT_PRESENT);
} }
uint64_t va_base_old = va_base; uint64_t va_base_old = va_base;
@ -335,14 +335,14 @@ void *va_alloc_contigious_pages(size_t pages){
free_spinlock(&va_lock); free_spinlock(&va_lock);
return (void*)(va_base_old+hhdmoffset); return (void*)(va_base_old+get_kinfo()->hhdmoffset);
} }
/* Maps pages from phys_addr to phys_addr+size into the kernels address space */ /* Maps pages from phys_addr to phys_addr+size into the kernels address space */
void kmap_pages(void *phys_addr, uint64_t size, uint64_t flags){ void kmap_pages(void *phys_addr, uint64_t size, uint64_t flags){
for(uint64_t i = 0; i < size; i++){ for(uint64_t i = 0; i < size; i++){
vmm_map_page(kernel_page_map, (uint64_t)phys_addr + hhdmoffset + (i * PAGE_SIZE), (uint64_t)phys_addr + (i * PAGE_SIZE), PTE_BIT_PRESENT | flags); vmm_map_page(kernel_page_map, (uint64_t)phys_addr + get_kinfo()->hhdmoffset + (i * PAGE_SIZE), (uint64_t)phys_addr + (i * PAGE_SIZE), PTE_BIT_PRESENT | flags);
} }
} }

View file

@ -3,7 +3,7 @@
#include <kprint.h> #include <kprint.h>
#include <stdint.h> #include <stdint.h>
#include <neobbo.h> #include <neobbo.h>
#include <arch/amd64/hal/smp.h> #include <smp.h>
#include <error.h> #include <error.h>
#include <string.h> #include <string.h>
#include <mm/kmalloc.h> #include <mm/kmalloc.h>
@ -22,26 +22,30 @@ int next_pid = 1;
void idle_task(){ void idle_task(){
for(;;){ for(;;){
kprintf("idling!\n"); __builtin_ia32_pause();
} }
} }
void test_task(){ void test_task(){
kprintf("Hello world from scheduled task!\n"); kprintf("Hello world from scheduled task!\n");
for(;;); //for(;;);
} }
void best_task(){ void best_task(){
kprintf("Hello world I am best\n"); kprintf("Hello world I am best\n");
for(;;); //for(;;);
} }
void thread_exit(){ void thread_exit(){
asm("cli");
#ifdef __x86_64__
asm("cli");
#endif
cpu_state *cpu = get_cpu_struct(); cpu_state *cpu = get_cpu_struct();
struct thread *p = cpu->current_process; struct thread *p = cpu->current_process;
if(p == p->next || p->prev == p){ if(p == p->next && p->prev == p){
// If this is the only thread in the queue then set cpu->head to NULL, so scheduler knows to idle // If this is the only thread in the queue then set cpu->head to NULL, so scheduler knows to idle
cpu->head = NULL; cpu->head = NULL;
}else{ }else{
@ -115,8 +119,11 @@ struct thread *add_thread(uint64_t *entry){
[[noreturn]] void sched(){ [[noreturn]] void sched(){
cpu_state *cpu = get_cpu_struct(); cpu_state *cpu = get_cpu_struct();
cpu->scheduler_initialized = true; // Allow us to get interrupts that schedule us
for(;;){ for(;;){
asm("cli"); // we sti at the end of switch_context #ifdef __x86_64__
asm("cli"); // we sti at the end of switch_context
#endif
struct thread *prev = cpu->current_process; struct thread *prev = cpu->current_process;
@ -144,37 +151,29 @@ void scheduler_init(){
cpu_state *cpu = get_cpu_struct(); cpu_state *cpu = get_cpu_struct();
if(cpu->current_process != NULL){ if(cpu->current_process != NULL){
kprintf("scheduler on CPU {d} already initialized!\n", cpu->lapic_id); kprintf("scheduler on CPU {d} already initialized!\n", cpu->id);
return; return;
} }
idle = alloc_thread(); if(cpu->id == get_kinfo()->bsp_id){
idle->context->rip = (uint64_t)idle_task; idle = alloc_thread();
idle->context->rip = (uint64_t)idle_task;
assert(idle != NULL && "Failed to allocate idle task!"); assert(idle != NULL && "Failed to allocate idle task!");
}
cpu->current_process = idle; cpu->current_process = idle;
cpu->scheduler_stack = kzalloc(4096); kprintf("scheduler on CPU {d} initialized!", cpu->id);
cpu->scheduler_context = (struct context*)((uint64_t)cpu->scheduler_stack + 4096 - sizeof(struct context));
cpu->scheduler_context->rbp = (uint64_t)cpu->scheduler_context;
cpu->scheduler_context->rip = (uint64_t)sched;
kprintf("og scheduler context: 0x{x}\n", cpu->scheduler_context); sched();
struct thread *t1 = add_thread((uint64_t*)test_task);
memcpy(t1->name, "testt", 6);
struct thread *t2 = add_thread((uint64_t *)best_task);
memcpy(t2->name, "bestt", 6);
cpu->scheduler_initialized = true; // Allow us to get interrupts that schedule us
for(;;); for(;;);
} }
void yield(){ void yield(){
asm("cli"); #ifdef __x86_64__
asm("cli");
#endif
switch_context(&get_cpu_struct()->current_process->context, get_cpu_struct()->scheduler_context); switch_context(&get_cpu_struct()->current_process->context, get_cpu_struct()->scheduler_context);
} }

View file

@ -7,7 +7,7 @@
#include <sys/acpi.h> #include <sys/acpi.h>
static volatile struct limine_rsdp_request rsdp_request = { static volatile struct limine_rsdp_request rsdp_request = {
.id = LIMINE_RSDP_REQUEST, .id = LIMINE_RSDP_REQUEST_ID,
.revision = 0, .revision = 0,
}; };
@ -39,7 +39,7 @@ uint64_t *find_acpi_table(char *signature){
} }
/* Get the virtual address of the header so we can access its signature */ /* Get the virtual address of the header so we can access its signature */
desc_header_t *virt = (desc_header_t*)((uint64_t)header + hhdmoffset); desc_header_t *virt = (desc_header_t*)((uint64_t)header + get_kinfo()->hhdmoffset);
if(memcmp(virt->signature, signature, 4) == 0){ if(memcmp(virt->signature, signature, 4) == 0){
return (uint64_t*)header; return (uint64_t*)header;
@ -64,13 +64,13 @@ void acpi_init(void){
/* If the systems ACPI revision is higher/equal than 2, then use XSDT */ /* If the systems ACPI revision is higher/equal than 2, then use XSDT */
if(rsdp->revision >= 2){ if(rsdp->revision >= 2){
rsdt = NULL; rsdt = NULL;
xsdt = (xsdt_t*)(rsdp->xsdt_address + hhdmoffset); xsdt = (xsdt_t*)(rsdp->xsdt_address + get_kinfo()->hhdmoffset);
klog("acpi", "Using XSDT header"); klog("acpi", "Using XSDT header");
kprintf("XSDT address: 0x{x}\n", (uint64_t)xsdt); kprintf("XSDT address: 0x{x}\n", (uint64_t)xsdt);
kprintf("OEMID: {cccccc}\n", xsdt->header.oemid[0], xsdt->header.oemid[1], xsdt->header.oemid[2], xsdt->header.oemid[3], xsdt->header.oemid[4], xsdt->header.oemid[5]); kprintf("OEMID: {cccccc}\n", xsdt->header.oemid[0], xsdt->header.oemid[1], xsdt->header.oemid[2], xsdt->header.oemid[3], xsdt->header.oemid[4], xsdt->header.oemid[5]);
}else{ }else{
xsdt = NULL; xsdt = NULL;
rsdt = (rsdt_t*)(rsdp->rsdt_address + hhdmoffset); rsdt = (rsdt_t*)(rsdp->rsdt_address + get_kinfo()->hhdmoffset);
klog("acpi", "Using RSDT header"); klog("acpi", "Using RSDT header");
kprintf("RSDT address: 0x{x}\n", (uint64_t)rsdt); kprintf("RSDT address: 0x{x}\n", (uint64_t)rsdt);
kprintf("OEMID: {cccccc}\n", rsdt->header.oemid[0], rsdt->header.oemid[1], rsdt->header.oemid[2], rsdt->header.oemid[3], rsdt->header.oemid[4], rsdt->header.oemid[5]); kprintf("OEMID: {cccccc}\n", rsdt->header.oemid[0], rsdt->header.oemid[1], rsdt->header.oemid[2], rsdt->header.oemid[3], rsdt->header.oemid[4], rsdt->header.oemid[5]);

View file

@ -4,6 +4,7 @@
#include <lock.h> #include <lock.h>
#include <sys/acpi.h> #include <sys/acpi.h>
#include <mm/vmm.h> #include <mm/vmm.h>
#include <mm/kmalloc.h>
#include <error.h> #include <error.h>
#include <sys/pci.h> #include <sys/pci.h>
@ -40,7 +41,7 @@ void pci_add_device(pci_structure structure){
/* Find first unused space */ /* Find first unused space */
while(pci_array[i].func_addr[0] != 0){ while(pci_array[i].func_addr[0] != 0){
if(i >= PCI_DEVICE_BUS){ if(i >= PCI_DEVICE_BUS){
klog(__func__, "No more space in the PCI array!"); klog(__func__, "No more space in the PCI array!");
kkill(); kkill();
} }
i++; i++;
@ -93,7 +94,7 @@ void parse_conf_space(){
kprintf(" start pci bus number: 0x{xn}", header.start_pci_num); kprintf(" start pci bus number: 0x{xn}", header.start_pci_num);
kprintf(" end pci bus number: 0x{xn}", header.end_pci_num); kprintf(" end pci bus number: 0x{xn}", header.end_pci_num);
config_space_base_addr = header.base_ecm + hhdmoffset; config_space_base_addr = header.base_ecm + get_kinfo()->hhdmoffset;
start_pci_num = header.start_pci_num; start_pci_num = header.start_pci_num;
end_pci_num = header.end_pci_num; end_pci_num = header.end_pci_num;
} }
@ -175,15 +176,15 @@ void pci_init(){
kkill(); kkill();
} }
mcfg = (mcfg_t*)((uint64_t)mcfg + hhdmoffset); mcfg = (mcfg_t*)((uint64_t)mcfg + get_kinfo()->hhdmoffset);
parse_conf_space(); parse_conf_space();
/* Map the config space */ /* Map the config space */
kmap_pages((uint64_t*)(config_space_base_addr - hhdmoffset), (PCIE_CONF_SPACE_WIDTH * end_pci_num) / PAGE_SIZE, PTE_BIT_RW | PTE_BIT_NX); kmap_pages((uint64_t*)(config_space_base_addr - get_kinfo()->hhdmoffset), (PCIE_CONF_SPACE_WIDTH * end_pci_num) / PAGE_SIZE, PTE_BIT_RW | PTE_BIT_NX);
/* Stores enough for an entire configuration space */ /* Stores enough for an entire configuration space */
pci_array = kmalloc((256 * 32) * sizeof(pci_structure)); pci_array = kzalloc((256 * 32) * sizeof(pci_structure));
if(!pci_array){ if(!pci_array){
klog(__func__, "Failed to allocate memory for PCI structures!"); klog(__func__, "Failed to allocate memory for PCI structures!");
@ -200,7 +201,7 @@ l84_pci_function_return check_device(uint64_t bus, uint64_t device){
pci_header_t *header = (pci_header_t*)get_header(bus, device, 0); pci_header_t *header = (pci_header_t*)get_header(bus, device, 0);
vmm_map_page(kernel_page_map, (uint64_t)header, (uint64_t)header - hhdmoffset, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX); vmm_map_page(kernel_page_map, (uint64_t)header, (uint64_t)header - get_kinfo()->hhdmoffset, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX);
/* If vendor id is 0xffff, that means that this device is unimplemented */ /* If vendor id is 0xffff, that means that this device is unimplemented */
if(header->vendor_id == 0xffff){ if(header->vendor_id == 0xffff){
@ -217,7 +218,7 @@ l84_pci_function_return check_device(uint64_t bus, uint64_t device){
uint64_t *addr = (uint64_t*)(config_space_base_addr + ((bus) << 20 | device << 15 | function << 12)); uint64_t *addr = (uint64_t*)(config_space_base_addr + ((bus) << 20 | device << 15 | function << 12));
pci_header_t *func = (pci_header_t*)((uint64_t)addr); pci_header_t *func = (pci_header_t*)((uint64_t)addr);
vmm_map_page(kernel_page_map, (uint64_t)func, (uint64_t)func - hhdmoffset, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX); vmm_map_page(kernel_page_map, (uint64_t)func, (uint64_t)func - get_kinfo()->hhdmoffset, PTE_BIT_PRESENT | PTE_BIT_RW | PTE_BIT_NX);
if(func->vendor_id != 0xffff){ if(func->vendor_id != 0xffff){
//kprintf("pci multi: bus: 0x{x} device: 0x{x} type: 0x{x} class: 0x{x} subclass: 0x{x} vendorid: 0x{xn}", bus, func->device_id, multi_header_type, func->class_code, func->subclass, func->vendor_id); //kprintf("pci multi: bus: 0x{x} device: 0x{x} type: 0x{x} class: 0x{x} subclass: 0x{x} vendorid: 0x{xn}", bus, func->device_id, multi_header_type, func->class_code, func->subclass, func->vendor_id);
@ -230,7 +231,7 @@ l84_pci_function_return check_device(uint64_t bus, uint64_t device){
ret.multi = false; ret.multi = false;
ret.func_addr[0] = (uint64_t)header; ret.func_addr[0] = (uint64_t)header;
//kprintf("pci: bus: 0x{x} device: 0x{x} type: 0x{x} class: 0x{x} subclass: 0x{x} vendorid: 0x{xn}", bus, header->device_id, header->header_type, header->class_code, header->subclass, header->vendor_id); kprintf("pci: bus: 0x{x} device: 0x{x} type: 0x{x} class: 0x{x} subclass: 0x{x} vendorid: 0x{xn}", bus, header->device_id, header->header_type, header->class_code, header->subclass, header->vendor_id);
//serial_kprintf("pci: bus: 0x{x} device: 0x{x} type: 0x{x} class: 0x{x} subclass: 0x{x} vendorid: 0x{xn}", bus, header->header_type, header->class_code, header->subclass, header->vendor_id); //serial_kprintf("pci: bus: 0x{x} device: 0x{x} type: 0x{x} class: 0x{x} subclass: 0x{x} vendorid: 0x{xn}", bus, header->header_type, header->class_code, header->subclass, header->vendor_id);
return ret; return ret;

View file

@ -17,7 +17,7 @@ void krand_init(){
uint32_t unused, ecx; uint32_t unused, ecx;
__get_cpuid(0x01, &unused, &unused, &ecx, &unused); __get_cpuid(0x01, &unused, &unused, &ecx, &unused);
ecx = (ecx & 2) >> 1; ecx = (ecx >> 30) & 1;
if(ecx == 1){ if(ecx == 1){
/* RDRAND supported */ /* RDRAND supported */

View file

@ -1,19 +1,28 @@
/* Time keeping */ /* Time keeping */
#include "smp.h"
#include <stdint.h> #include <stdint.h>
#include <arch/amd64/hal/tsc.h> #include <arch/amd64/hal/tsc.h>
#include <arch/amd64/hal/apic.h> #include <arch/amd64/hal/apic.h>
#include <kprint.h>
uint64_t get_timestamp_ns(){ uint64_t get_timestamp_us(){
uint64_t ret = 0;
uint64_t tsc = tsc_get_timestamp();
if(tsc == 0){ #ifdef __x86_64__
/* Get APIC timestamp */
} uint64_t tsc = tsc_get_timestamp();
return tsc; if(tsc != 0){
return tsc;
}
if(get_cpu_struct_initialized()){
return get_cpu_struct()->lapic_timer_ticks * 1000ULL;
}
#endif
return 0;
} }

View file

@ -1,4 +1,4 @@
#include "arch/amd64/hal/smp.h" #include "smp.h"
#include <stdatomic.h> #include <stdatomic.h>
#include <uacpi/kernel_api.h> #include <uacpi/kernel_api.h>
#include <uacpi/log.h> #include <uacpi/log.h>
@ -15,7 +15,7 @@
#include <limine.h> #include <limine.h>
#include <kprint.h> #include <kprint.h>
#include <neobbo.h> #include <neobbo.h>
#include <io.h> #include <arch/amd64/io.h>
#include <sys/time.h> #include <sys/time.h>
extern uint64_t hhdmoffset; extern uint64_t hhdmoffset;
@ -76,17 +76,17 @@ uacpi_status uacpi_kernel_pci_read32(uacpi_handle device, uacpi_size offset, uac
} }
uacpi_status uacpi_kernel_pci_write8(uacpi_handle device, uacpi_size offset, uacpi_u8 value){ uacpi_status uacpi_kernel_pci_write8(uacpi_handle device, uacpi_size offset, uacpi_u8 value){
*(uint8_t*)((uint64_t)device + offset + hhdmoffset) = value; *(uint8_t*)((uint64_t)device + offset + get_kinfo()->hhdmoffset) = value;
return UACPI_STATUS_OK; return UACPI_STATUS_OK;
} }
uacpi_status uacpi_kernel_pci_write16(uacpi_handle device, uacpi_size offset, uacpi_u16 value){ uacpi_status uacpi_kernel_pci_write16(uacpi_handle device, uacpi_size offset, uacpi_u16 value){
*(uint16_t*)((uint64_t)device + offset + hhdmoffset) = value; *(uint16_t*)((uint64_t)device + offset + get_kinfo()->hhdmoffset) = value;
return UACPI_STATUS_OK; return UACPI_STATUS_OK;
} }
uacpi_status uacpi_kernel_pci_write32(uacpi_handle device, uacpi_size offset, uacpi_u32 value){ uacpi_status uacpi_kernel_pci_write32(uacpi_handle device, uacpi_size offset, uacpi_u32 value){
*(uint32_t*)((uint64_t)device + offset + hhdmoffset) = value; *(uint32_t*)((uint64_t)device + offset + get_kinfo()->hhdmoffset) = value;
return UACPI_STATUS_OK; return UACPI_STATUS_OK;
} }
@ -149,7 +149,7 @@ uacpi_status uacpi_kernel_io_write(uacpi_handle handle, uacpi_size offset, uacpi
void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len){ void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len){
uint64_t offset = addr % PAGE_SIZE; uint64_t offset = addr % PAGE_SIZE;
kmap_pages((void*)addr, len, 0); kmap_pages((void*)addr, len, 0);
return (void*)addr + hhdmoffset + offset; return (void*)addr + get_kinfo()->hhdmoffset + offset;
} }
void uacpi_kernel_unmap(void *addr, uacpi_size len){ void uacpi_kernel_unmap(void *addr, uacpi_size len){
@ -177,7 +177,7 @@ void uacpi_kernel_free(void *mem){
} }
uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void){ uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void){
return get_timestamp_ns(); return get_timestamp_us() * 1000;
} }
void uacpi_kernel_stall(uacpi_u8 usec){ void uacpi_kernel_stall(uacpi_u8 usec){
@ -185,7 +185,7 @@ void uacpi_kernel_stall(uacpi_u8 usec){
} }
void uacpi_kernel_sleep(uacpi_u64 msec){ void uacpi_kernel_sleep(uacpi_u64 msec){
sleep(msec ); sleep(msec);
} }
uacpi_handle uacpi_kernel_create_mutex(){ uacpi_handle uacpi_kernel_create_mutex(){