Compare commits

..

3 commits

33 changed files with 557 additions and 439 deletions

View file

@ -46,8 +46,10 @@ all: amd64
deps:
mkdir -p $(BUILD_DIR) || true
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
cp build/limine-protocol/include/limine.h include/
rm -rf build/flanterm
git clone https://codeberg.org/mintsuki/flanterm build/flanterm
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
* purpose with or without fee is hereby granted.
@ -17,12 +17,12 @@
#ifndef LIMINE_H
#define LIMINE_H 1
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/* Misc */
#ifdef LIMINE_NO_POINTERS
@ -31,31 +31,16 @@ extern "C" {
# define LIMINE_PTR(TYPE) TYPE
#endif
#ifdef __GNUC__
# define LIMINE_DEPRECATED __attribute__((__deprecated__))
# define LIMINE_DEPRECATED_IGNORE_START \
_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 { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \
0x785c6ed015d3e316, 0x181e920a7852b9d9 }
#define LIMINE_REQUESTS_END_MARKER { 0xadc0e0531bb10d03, 0x9572709f31764c62 }
#define LIMINE_REQUESTS_START_MARKER \
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_BASE_REVISION(N) { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }
#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER
#define LIMINE_BASE_REVISION_SUPPORTED(VAR) ((VAR)[2] == 0)
#define LIMINE_BASE_REVISION(N) \
uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) };
#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0)
#define LIMINE_LOADED_BASE_REVISION_VALID(VAR) ((VAR)[1] != 0x6a7b384944536bdc)
#define LIMINE_LOADED_BASE_REVISION(VAR) ((VAR)[1])
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
@ -75,7 +60,7 @@ struct limine_file {
LIMINE_PTR(void *) address;
uint64_t size;
LIMINE_PTR(char *) path;
LIMINE_PTR(char *) cmdline;
LIMINE_PTR(char *) string;
uint32_t media_type;
uint32_t unused;
uint32_t tftp_ip;
@ -89,7 +74,7 @@ struct limine_file {
/* 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 {
uint64_t revision;
@ -103,13 +88,29 @@ struct limine_bootloader_info_request {
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 */
#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_UEFI32 1
#define LIMINE_FIRMWARE_TYPE_UEFI64 2
#define LIMINE_FIRMWARE_TYPE_EFI32 1
#define LIMINE_FIRMWARE_TYPE_EFI64 2
#define LIMINE_FIRMWARE_TYPE_SBI 3
struct limine_firmware_type_response {
uint64_t revision;
@ -124,7 +125,7 @@ struct limine_firmware_type_request {
/* 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 {
uint64_t revision;
@ -139,7 +140,7 @@ struct limine_stack_size_request {
/* HHDM */
#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
#define LIMINE_HHDM_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
struct limine_hhdm_response {
uint64_t revision;
@ -154,7 +155,7 @@ struct limine_hhdm_request {
/* 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
@ -205,93 +206,29 @@ struct limine_framebuffer_request {
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 */
#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_5LVL 1
#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_X86_64_4LVL
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL
#elif defined (__aarch64__)
#define LIMINE_PAGING_MODE_X86_64_MIN LIMINE_PAGING_MODE_X86_64_4LVL
#define LIMINE_PAGING_MODE_X86_64_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL
#define LIMINE_PAGING_MODE_AARCH64_4LVL 0
#define LIMINE_PAGING_MODE_AARCH64_5LVL 1
#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_AARCH64_4LVL
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL
#elif defined (__riscv) && (__riscv_xlen == 64)
#define LIMINE_PAGING_MODE_AARCH64_MIN LIMINE_PAGING_MODE_AARCH64_4LVL
#define LIMINE_PAGING_MODE_AARCH64_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL
#define LIMINE_PAGING_MODE_RISCV_SV39 0
#define LIMINE_PAGING_MODE_RISCV_SV48 1
#define LIMINE_PAGING_MODE_RISCV_SV57 2
#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_RISCV_SV39
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48
#elif defined (__loongarch__) && (__loongarch_grlen == 64)
#define LIMINE_PAGING_MODE_LOONGARCH64_4LVL 0
#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_LOONGARCH64_4LVL
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_LOONGARCH64_4LVL
#else
#error Unknown architecture
#endif
#define LIMINE_PAGING_MODE_RISCV_MIN LIMINE_PAGING_MODE_RISCV_SV39
#define LIMINE_PAGING_MODE_RISCV_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48
#define LIMINE_PAGING_MODE_LOONGARCH_4LVL 0
#define LIMINE_PAGING_MODE_LOONGARCH_MIN LIMINE_PAGING_MODE_LOONGARCH_4LVL
#define LIMINE_PAGING_MODE_LOONGARCH_DEFAULT LIMINE_PAGING_MODE_LOONGARCH_4LVL
struct limine_paging_mode_response {
uint64_t revision;
@ -307,37 +244,19 @@ struct limine_paging_mode_request {
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 {
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 *);
typedef void (*limine_goto_address)(struct limine_mp_info *);
#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 lapic_id;
uint64_t reserved;
@ -345,17 +264,17 @@ struct limine_smp_info {
uint64_t extra_argument;
};
struct limine_smp_response {
struct limine_mp_response {
uint64_t revision;
uint32_t flags;
uint32_t bsp_lapic_id;
uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus;
LIMINE_PTR(struct limine_mp_info **) cpus;
};
#elif defined (__aarch64__)
struct limine_smp_info {
struct limine_mp_info {
uint32_t processor_id;
uint32_t reserved1;
uint64_t mpidr;
@ -364,17 +283,17 @@ struct limine_smp_info {
uint64_t extra_argument;
};
struct limine_smp_response {
struct limine_mp_response {
uint64_t revision;
uint64_t flags;
uint64_t bsp_mpidr;
uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus;
LIMINE_PTR(struct limine_mp_info **) cpus;
};
#elif defined (__riscv) && (__riscv_xlen == 64)
struct limine_smp_info {
struct limine_mp_info {
uint64_t processor_id;
uint64_t hartid;
uint64_t reserved;
@ -382,39 +301,41 @@ struct limine_smp_info {
uint64_t extra_argument;
};
struct limine_smp_response {
struct limine_mp_response {
uint64_t revision;
uint64_t flags;
uint64_t bsp_hartid;
uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus;
LIMINE_PTR(struct limine_mp_info **) cpus;
};
#elif defined (__loongarch__) && (__loongarch_grlen == 64)
struct limine_smp_info {
struct limine_mp_info {
uint64_t reserved;
};
struct limine_smp_response {
struct limine_mp_response {
uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus;
LIMINE_PTR(struct limine_mp_info **) cpus;
};
#else
#error Unknown architecture
#endif
struct limine_smp_request {
#define LIMINE_MP_REQUEST_X86_64_X2APIC (1 << 0)
struct limine_mp_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_smp_response *) response;
LIMINE_PTR(struct limine_mp_response *) response;
uint64_t flags;
};
/* 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_RESERVED 1
@ -422,8 +343,9 @@ struct limine_smp_request {
#define LIMINE_MEMMAP_ACPI_NVS 3
#define LIMINE_MEMMAP_BAD_MEMORY 4
#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_RESERVED_MAPPED 8
struct limine_memmap_entry {
uint64_t base;
@ -445,7 +367,7 @@ struct limine_memmap_request {
/* 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);
@ -460,31 +382,31 @@ struct limine_entry_point_request {
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;
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 revision;
LIMINE_PTR(struct limine_kernel_file_response *) response;
LIMINE_PTR(struct limine_executable_file_response *) response;
};
/* 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_COMPRESSED (1 << 1)
struct limine_internal_module {
LIMINE_PTR(const char *) path;
LIMINE_PTR(const char *) cmdline;
LIMINE_PTR(const char *) string;
uint64_t flags;
};
@ -506,7 +428,7 @@ struct limine_module_request {
/* RSDP */
#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c }
#define LIMINE_RSDP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c }
struct limine_rsdp_response {
uint64_t revision;
@ -521,7 +443,7 @@ struct limine_rsdp_request {
/* SMBIOS */
#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee }
#define LIMINE_SMBIOS_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee }
struct limine_smbios_response {
uint64_t revision;
@ -537,7 +459,7 @@ struct limine_smbios_request {
/* 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 {
uint64_t revision;
@ -552,7 +474,7 @@ struct limine_efi_system_table_request {
/* 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 {
uint64_t revision;
@ -568,40 +490,40 @@ struct limine_efi_memmap_request {
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;
int64_t boot_time;
int64_t timestamp;
};
struct limine_boot_time_request {
struct limine_date_at_boot_request {
uint64_t id[4];
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 physical_base;
uint64_t virtual_base;
};
struct limine_kernel_address_request {
struct limine_executable_address_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_kernel_address_response *) response;
LIMINE_PTR(struct limine_executable_address_response *) response;
};
/* 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 {
uint64_t revision;
@ -614,6 +536,50 @@ struct limine_dtb_request {
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
}
#endif

View file

@ -1,5 +1,15 @@
#pragma once
#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[];
@ -17,4 +27,6 @@ typedef char link_symbol_ptr[];
#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

@ -22,13 +22,12 @@ struct thread {
proc_state state;
uint16_t pid;
struct context *context;
char name[8];
};
void scheduler_init();
[[noreturn]] void sched();
void yield();
#define PROC_MAX 512 // Max number of processes
#define INITIAL_STACK_SIZE 0x10000
#define PROC_MAX 1024 // Max number of processes per cpu

View file

@ -8,7 +8,7 @@
#define KERNELGSBASE 0xC0000102
typedef struct cpu_state {
uint32_t lapic_id;
uint32_t id;
uint64_t lapic_timer_ticks;
struct thread *head;
struct thread *base;
@ -22,5 +22,6 @@ typedef struct cpu_state {
void smp_init();
cpu_state *get_cpu_struct();
uint64_t get_cpu_count();
void bsp_early_init();
bool get_cpu_struct_initialized();

View file

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

View file

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

View file

View file

@ -1,14 +1,16 @@
#include <sys/acpi.h>
#include <drivers/pmt.h>
#include <arch/amd64/hal/smp.h>
#include <smp.h>
#include <arch/amd64/hal/timer.h>
#include <arch/amd64/hal/ioapic.h>
#include <arch/amd64/io.h>
#include <lock.h>
#include <kprint.h>
#include <neobbo.h>
#include <cpuid.h> // GCC specific
#define IA32_APIC_BASE_MSR 0x1B
#define LAPIC_ID_REG 0x020
#define LAPIC_EOI_REG 0x0B0
#define LAPIC_SPURIOUS_REG 0x0F0
@ -31,7 +33,6 @@
#define LAPIC_TIMER_VECTOR 69
extern madt_t *madt;
extern uint64_t hhdmoffset;
uint64_t lapic_address = 0;
@ -87,7 +88,7 @@ void lapic_timer_init(int us){
void apic_init(void){
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
@ -95,7 +96,7 @@ void apic_init(void){
if(lapic_ao){
/* Check that the field isnt 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 */
timer_init();
/* Start the APIC timer with 10ms timer */
lapic_timer_init(10000);
/* Start the APIC timer with 1us timer */
lapic_timer_init(1);
asm("sti");
}
@ -120,7 +121,7 @@ void ap_apic_init(){
lapic_write_reg(LAPIC_SPURIOUS_REG, 0x1FF);
/* Start the APIC timer */
lapic_timer_init(10000);
lapic_timer_init(1);
asm("sti");
}
@ -133,7 +134,6 @@ void apic_timer_handler(){
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){

View file

@ -1,6 +1,6 @@
#include <arch/amd64/hal/idt.h>
#include <error.h>
#include <arch/amd64/hal/smp.h>
#include <smp.h>
#include <arch/amd64/hal/timer.h>
#include <kprint.h>
#include <lock.h>
@ -205,8 +205,10 @@ extern void *next_frame(void *addr);
void interrupt_handler(interrupt_frame *r){
//asm("cli");
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){
kprintf("error code 0x{xn}", r->err);
@ -235,16 +237,21 @@ void interrupt_handler(interrupt_frame *r){
if(r->int_no == 69){
apic_timer_handler();
return;
}
if(r->int_no == 69 && get_cpu_struct_initialized()
&& get_cpu_struct()->scheduler_initialized){
yield();
return;
}
if(r->int_no == 70){
for(;;){
asm("cli;hlt");
for(;;){
asm("cli");
__builtin_ia32_pause();
}
}
}

View file

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

View file

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

View file

@ -73,5 +73,5 @@ uint64_t tsc_get_timestamp(){
return 0;
}
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 */
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 */
kprintf("ahci: Performing BIOS/OS handoff\n");

View file

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

View file

@ -1,7 +1,7 @@
#include <sys/acpi.h>
#include <arch/amd64/hal/ioapic.h>
#include <io.h>
#include <arch/amd64/io.h>
#include <kprint.h>
#define COM1 0x3F8
@ -56,13 +56,25 @@ void serial_init(){
}
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);
}
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);
}

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

@ -7,6 +7,7 @@
#include <kprint.h>
#include <drivers/serial.h>
#include <arch/amd64/hal/tsc.h>
#include <sys/time.h>
#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);
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;
@ -55,6 +84,7 @@ int kprintf(const char *format_string, ...){
int state = NORMAL;
va_list a_list;
va_start(a_list, format_string);
print_timestamp(ft_ctx);
for(uint64_t i = 0; i < strlen(format_string); i++){
char current = format_string[i]; // current char in string
switch (state){
@ -123,6 +153,67 @@ int kprintf(const char *format_string, ...){
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 state = NORMAL;
va_list a_list;
@ -192,7 +283,7 @@ int serial_kprintf(const char *format_string, ...){
return 0;
}
#define MAX_INTERGER_SIZE 128
#define MAX_INTEGER_SIZE 128
void print_char(struct flanterm_context *ft_ctx, char c){
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){
char buffer[MAX_INTERGER_SIZE] = {0};
char buffer[MAX_INTEGER_SIZE] = {0};
if(num == 0){
buffer[0] = '0';
}
int arr[MAX_INTERGER_SIZE] = {0};
int arr[MAX_INTEGER_SIZE] = {0};
int j = 0;
while(num != 0){
@ -222,7 +313,7 @@ void print_int(struct flanterm_context *ft_ctx, uint64_t num){
num /= 10;
j++;
if(j == MAX_INTERGER_SIZE){
if(j == MAX_INTEGER_SIZE){
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){
char buffer[MAX_INTERGER_SIZE] = {0};
char buffer[MAX_INTEGER_SIZE] = {0};
if(num == 0){
buffer[0] = '0';
}
int arr[MAX_INTERGER_SIZE] = {0};
int arr[MAX_INTEGER_SIZE] = {0};
int j = 0;
while(num != 0){
@ -251,7 +342,7 @@ void print_hex(struct flanterm_context *ft_ctx, uint64_t num){
num /= 16;
j++;
if(j == MAX_INTERGER_SIZE){
if(j == MAX_INTEGER_SIZE){
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){
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;
while(num != 0){
@ -276,7 +367,7 @@ void print_bin(struct flanterm_context *ft_ctx, uint64_t num){
num /= 2;
j++;
if(j == MAX_INTERGER_SIZE){
if(j == MAX_INTEGER_SIZE){
return;
}
}
@ -290,9 +381,9 @@ void print_bin(struct flanterm_context *ft_ctx, 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;
while(num != 0){
@ -301,7 +392,7 @@ void serial_print_int(uint64_t num){
num /= 10;
j++;
if(j == MAX_INTERGER_SIZE){
if(j == MAX_INTEGER_SIZE){
return;
}
}
@ -315,9 +406,9 @@ void serial_print_int(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;
while(num != 0){
@ -326,7 +417,7 @@ void serial_print_hex(uint64_t num){
num /= 16;
j++;
if(j == MAX_INTERGER_SIZE){
if(j == MAX_INTEGER_SIZE){
return;
}
}
@ -340,9 +431,9 @@ void serial_print_hex(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;
while(num != 0){
@ -351,7 +442,7 @@ void serial_print_bin(uint64_t num){
num /= 2;
j++;
if(j == MAX_INTERGER_SIZE){
if(j == MAX_INTEGER_SIZE){
return;
}
}
@ -365,62 +456,10 @@ void serial_print_bin(uint64_t num){
}
char toupper(char c){
switch(c){
case 'a':
return 'A';
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:
char toupper(char c) {
if (c >= 'a' && c <= 'z')
return c - ('a' - 'A');
return c;
}
}
/* 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 <mm/slab.h>
#include <lock.h>

View file

@ -76,7 +76,29 @@ char dtoc(int digit){
if(digit < 10){
return '0' + digit;
}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/apic.h>
#include <arch/amd64/hal/timer.h>
#include <arch/amd64/hal/smp.h>
#include <smp.h>
#include <arch/amd64/hal/tsc.h>
#include <mm/pmm.h>
#include <mm/slab.h>
@ -25,30 +25,19 @@
#include <drivers/ahci.h>
#include <scheduler/sched.h>
#include <sys/rand.h>
#include <sys/time.h>
static volatile struct limine_framebuffer_request framebuffer_request = {
.id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0,
};
static volatile struct limine_hhdm_request hhdm_request = {
.id = LIMINE_HHDM_REQUEST,
.id = LIMINE_FRAMEBUFFER_REQUEST_ID,
.revision = 0,
};
struct flanterm_context *ft_ctx;
uint64_t hhdmoffset = 0;
struct kernel_info kinfo;
void _start(void){
if(hhdm_request.response == NULL){
goto death;
}
hhdmoffset = hhdm_request.response->offset;
/* initalize framebuffer */
struct limine_framebuffer_response *fb_response = framebuffer_request.response;
@ -78,19 +67,25 @@ void _start(void){
0, 0
);
kprintf("Welcome to Neobbo{n}");
extern link_symbol_ptr text_start_addr, text_end_addr;
serial_init();
krand_init();
set_gdt();
set_idt();
initialize_kinfo();
kprintf("Welcome to Neobbo\n");
serial_init();
krand_init();
klog("acpi", "Reading ACPI tables");
acpi_init();
bsp_early_init();
klog("apic", "Initalizing APIC");
apic_init();
@ -116,18 +111,25 @@ void _start(void){
scheduler_init();
/* klog(LOG_INFO, "ahci", "Initializing AHCI controller");
ahci_init();
klog(LOG_SUCCESS, "ahci", "Done!"); */
death:
for(;;);
for(;;){
//kprintf("d\n");
__builtin_ia32_pause();
}
}
bool kernel_killed = false;
void kkill(void){
[[noreturn]] void kkill(void){
kernel_killed = true;
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 <limine.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);
if(pages == NULL){
klog(__func__, "Couldn't allocate page structure");
kkill();
return;
}
assert(pages != NULL && "Couldn't allocate page structure");
memset(pages, 0, (page_count * sizeof(struct page)) / PAGE_SIZE);

View file

@ -6,7 +6,7 @@
#include <mm/kmalloc.h>
static volatile struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST,
.id = LIMINE_MEMMAP_REQUEST_ID,
.revision = 0,
};
@ -25,7 +25,7 @@ atomic_flag pmm_lock = ATOMIC_FLAG_INIT;
void pmm_free(uint64_t *addr){
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 */
*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 */
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);
pmm_free_page_count--;
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);
get_kinfo()->usable_memory = mem_size / 1048576;
bool first_entry = true;
uint64_t j;
uint64_t i;
@ -92,7 +92,7 @@ void pmm_init(){
/* First set the first entry if it isn't set already */
if(first_entry == true){
first_entry = false;
free_list = (uint64_t*)(entries[i]->base + hhdmoffset);
free_list = (uint64_t*)(entries[i]->base + get_kinfo()->hhdmoffset);
j = 1;
}else{
j = 0;

View file

@ -10,12 +10,12 @@
#include <sys/acpi.h>
#include <arch/amd64/hal/apic.h>
struct limine_kernel_address_request kernel_addr_request = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
struct limine_executable_address_request kernel_addr_request = {
.id = LIMINE_EXECUTABLE_ADDRESS_REQUEST_ID,
.revision = 0
};
struct limine_kernel_address_response *kernel_address;
struct limine_executable_address_response *kernel_address;
extern uint64_t hhdmoffset;
@ -29,20 +29,20 @@ uint64_t kernel_start, kernel_end;
void vmm_set_ctx(uint64_t *page_map){
__asm__ volatile (
"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(){
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){
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){
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++){
if(memmap_response->entries[i]->type == LIMINE_MEMMAP_USABLE){
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){
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){
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){
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;
/* 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 */
extern xsdt_t *xsdt;
@ -129,12 +129,12 @@ void vmm_init(){
fill an entire page it still requires a page */
for(uint64_t i = 0; i < rsdt->header.length / PAGE_SIZE + 1; i++){
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{
for(uint64_t i = 0; i < xsdt->header.length / PAGE_SIZE + 1; i++){
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){
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;
}
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;
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];
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];
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];
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];
if (!(pte & 1)) return 0;
@ -326,7 +326,7 @@ void *va_alloc_contigious_pages(size_t pages){
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;
@ -335,14 +335,14 @@ void *va_alloc_contigious_pages(size_t pages){
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 */
void kmap_pages(void *phys_addr, uint64_t size, uint64_t flags){
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 <stdint.h>
#include <neobbo.h>
#include <arch/amd64/hal/smp.h>
#include <smp.h>
#include <error.h>
#include <string.h>
#include <mm/kmalloc.h>
@ -11,6 +11,7 @@
#include <scheduler/sched.h>
extern void switch_context(struct context **old, struct context *new);
extern void sched_enter(void *a);
struct ma_cache *thread_cache;
struct thread *idle;
@ -21,7 +22,7 @@ int next_pid = 1;
void idle_task(){
for(;;){
kprintf("idling!\n");
__builtin_ia32_pause();
}
}
@ -36,21 +37,22 @@ void best_task(){
}
void thread_exit(){
#ifdef __x86_64__
asm("cli");
#endif
cpu_state *cpu = get_cpu_struct();
struct thread *p = cpu->current_process;
if(p == p->next){
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
cpu->head = NULL;
}else{
// Remove process from circular linked list
p->next->prev = p->prev;
p->prev->next = p->next;
if(p == cpu->head){
//cpu->head = p->next;
}
cpu->head = p->next;
}
p->state = ZOMBIE;
@ -72,6 +74,7 @@ struct thread *alloc_thread(void){
uint64_t *sp = (uint64_t*)((uint64_t)t->kstack + 8 * 4096);
// Push the exit function (the thread will return to it when it finishes)
*--sp = (uint64_t)thread_exit;
@ -115,26 +118,26 @@ struct thread *add_thread(uint64_t *entry){
[[noreturn]] void sched(){
for(;;){
asm("cli"); // we sti at the end of switch_context
cpu_state *cpu = get_cpu_struct();
struct thread *prev = cpu->current_process;
cpu->scheduler_initialized = true; // Allow us to get interrupts that schedule us
for(;;){
#ifdef __x86_64__
asm("cli"); // we sti at the end of switch_context
#endif
if(prev->state == ZOMBIE){
kprintf("we are freeing allocated thread 0x{x}\n", prev);
ma_cache_dealloc(prev);
}else{
prev->state = READY;
}
struct thread *prev = cpu->current_process;
if(cpu->head == NULL){
cpu->current_process = idle;
}else{
if(prev->next){
cpu->current_process = prev->next;
}else{
cpu->current_process = cpu->head;
cpu->head = cpu->head->next;
}
if(prev->state == ZOMBIE){
ma_cache_dealloc(prev);
}else{
prev->state = READY;
}
cpu->current_process->state = RUNNING;
@ -148,31 +151,29 @@ void scheduler_init(){
cpu_state *cpu = get_cpu_struct();
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;
}
if(cpu->id == get_kinfo()->bsp_id){
idle = alloc_thread();
idle->context->rip = (uint64_t)idle;
idle->context->rip = (uint64_t)idle_task;
assert(idle != NULL && "Failed to allocate idle task!");
}
cpu->current_process = idle;
cpu->scheduler_stack = kzalloc(4096);
cpu->scheduler_context = (struct context*)((uint64_t)cpu->scheduler_stack + 4096);
cpu->scheduler_context->rbp = (uint64_t)cpu->scheduler_context;
cpu->scheduler_context->rip = (uint64_t)sched;
kprintf("scheduler on CPU {d} initialized!", cpu->id);
add_thread((uint64_t*)test_task);
sched();
add_thread((uint64_t *)best_task);
// Initialize scheduler -> we will now get timer interrupts to switch us into sched()
cpu->scheduler_initialized = true;
for(;;);
}
void yield(){
#ifdef __x86_64__
asm("cli");
#endif
switch_context(&get_cpu_struct()->current_process->context, get_cpu_struct()->scheduler_context);
}

View file

@ -1,25 +1,23 @@
#include <assert.h>
#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 <smp.h>
#include <arch/amd64/hal/apic.h>
#include <arch/amd64/hal/idt.h>
#include <mm/vmm.h>
#include <mm/kmalloc.h>
#include <lock.h>
#include <io.h>
#include <arch/amd64/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;
extern volatile struct limine_mp_request smp_request;
/* Returns the CPU structure for this particular CPU */
cpu_state *get_cpu_struct(){
@ -27,11 +25,15 @@ cpu_state *get_cpu_struct(){
}
uint64_t get_cpu_count(){
if(smp_request.response != NULL){
return smp_request.response->cpu_count;
}
return 0;
}
bool get_cpu_struct_initialized(){
if(rdmsr(GSBASE) < hhdmoffset){
if(rdmsr(GSBASE) < get_kinfo()->hhdmoffset){
return false;
}
@ -40,7 +42,7 @@ bool get_cpu_struct_initialized(){
atomic_flag ap_init_lock = ATOMIC_FLAG_INIT;
void ap_init(struct limine_smp_info *smp_info){
void ap_init(struct limine_mp_info *smp_info){
acquire_spinlock(&ap_init_lock);
@ -61,9 +63,9 @@ void ap_init(struct limine_smp_info *smp_info){
: : : "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;
cpu_state *cpu_struct = (cpu_state*)kzalloc(sizeof(cpu_state));
cpu_struct->id = smp_info->lapic_id;
wrmsr(KERNELGSBASE, (uint64_t)cpu_struct);
wrmsr(GSBASE, (uint64_t)cpu_struct);
@ -78,14 +80,11 @@ void ap_init(struct limine_smp_info *smp_info){
scheduler_init();
}
static cpu_state bsp_cpu;
void smp_init(){
if(!smp_request.response){
klog(__func__, "Failed to get SMP request");
kkill();
}
struct limine_smp_response *smp_response = smp_request.response;
struct limine_mp_response *smp_response = smp_request.response;
kprintf("smp: {d} CPUs\n", smp_response->cpu_count);
@ -94,16 +93,7 @@ void smp_init(){
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);
bsp_cpu.scheduler_context = (struct context*)kmalloc(sizeof(struct context));
/* If one of the APs has halted, then halt the BSP */
extern bool kernel_killed;
@ -112,3 +102,14 @@ void smp_init(){
}
}
void bsp_early_init(){
assert(smp_request.response != NULL && "Failed to get SMP request");
struct limine_mp_response *smp_response = smp_request.response;
bsp_cpu.id = smp_response->cpus[0]->lapic_id;
wrmsr(KERNELGSBASE, (uint64_t)&bsp_cpu);
wrmsr(GSBASE, (uint64_t)&bsp_cpu);
}

View file

@ -7,7 +7,7 @@
#include <sys/acpi.h>
static volatile struct limine_rsdp_request rsdp_request = {
.id = LIMINE_RSDP_REQUEST,
.id = LIMINE_RSDP_REQUEST_ID,
.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 */
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){
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(rsdp->revision >= 2){
rsdt = NULL;
xsdt = (xsdt_t*)(rsdp->xsdt_address + hhdmoffset);
xsdt = (xsdt_t*)(rsdp->xsdt_address + get_kinfo()->hhdmoffset);
klog("acpi", "Using XSDT header");
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]);
}else{
xsdt = NULL;
rsdt = (rsdt_t*)(rsdp->rsdt_address + hhdmoffset);
rsdt = (rsdt_t*)(rsdp->rsdt_address + get_kinfo()->hhdmoffset);
klog("acpi", "Using RSDT header");
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]);

View file

@ -4,6 +4,7 @@
#include <lock.h>
#include <sys/acpi.h>
#include <mm/vmm.h>
#include <mm/kmalloc.h>
#include <error.h>
#include <sys/pci.h>
@ -93,7 +94,7 @@ void parse_conf_space(){
kprintf(" start pci bus number: 0x{xn}", header.start_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;
end_pci_num = header.end_pci_num;
}
@ -175,15 +176,15 @@ void pci_init(){
kkill();
}
mcfg = (mcfg_t*)((uint64_t)mcfg + hhdmoffset);
mcfg = (mcfg_t*)((uint64_t)mcfg + get_kinfo()->hhdmoffset);
parse_conf_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 */
pci_array = kmalloc((256 * 32) * sizeof(pci_structure));
pci_array = kzalloc((256 * 32) * sizeof(pci_structure));
if(!pci_array){
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);
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(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));
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){
//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.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);
return ret;

View file

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

View file

@ -1,19 +1,28 @@
/* Time keeping */
#include "smp.h"
#include <stdint.h>
#include <arch/amd64/hal/tsc.h>
#include <arch/amd64/hal/apic.h>
#include <kprint.h>
uint64_t get_timestamp_us(){
#ifdef __x86_64__
uint64_t get_timestamp_ns(){
uint64_t ret = 0;
uint64_t tsc = tsc_get_timestamp();
if(tsc == 0){
/* Get APIC timestamp */
if(tsc != 0){
return tsc;
}
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 <uacpi/kernel_api.h>
#include <uacpi/log.h>
@ -15,7 +15,7 @@
#include <limine.h>
#include <kprint.h>
#include <neobbo.h>
#include <io.h>
#include <arch/amd64/io.h>
#include <sys/time.h>
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){
*(uint8_t*)((uint64_t)device + offset + hhdmoffset) = value;
*(uint8_t*)((uint64_t)device + offset + get_kinfo()->hhdmoffset) = value;
return UACPI_STATUS_OK;
}
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;
}
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;
}
@ -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){
uint64_t offset = addr % PAGE_SIZE;
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){
@ -177,7 +177,7 @@ void uacpi_kernel_free(void *mem){
}
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){
@ -185,7 +185,7 @@ void uacpi_kernel_stall(uacpi_u8 usec){
}
void uacpi_kernel_sleep(uacpi_u64 msec){
sleep(msec );
sleep(msec);
}
uacpi_handle uacpi_kernel_create_mutex(){