Added kinfo, reduced global state
This commit is contained in:
parent
2213707c6a
commit
e72c8fe6fd
30 changed files with 510 additions and 574 deletions
4
Makefile
4
Makefile
|
|
@ -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
|
||||||
|
|
|
||||||
316
include/limine.h
316
include/limine.h
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -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){
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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){
|
||||||
|
|
|
||||||
|
|
@ -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
47
src/kinfo.c
Normal 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;
|
||||||
|
}
|
||||||
63
src/lib/io.c
63
src/lib/io.c
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
189
src/lib/kprint.c
189
src/lib/kprint.c
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
56
src/main.c
56
src/main.c
|
|
@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
10
src/mm/pmm.c
10
src/mm/pmm.c
|
|
@ -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;
|
||||||
|
|
|
||||||
44
src/mm/vmm.c
44
src/mm/vmm.c
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
@ -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]);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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(){
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue