2 Commits

Author SHA1 Message Date
xamidev 0fbaf6d26e Date functions (get current time) 2026-03-26 17:59:02 +01:00
xamidev 532953da4d CPU Name identification 2026-03-26 16:53:39 +01:00
11 changed files with 220 additions and 3 deletions
+4
View File
@@ -10,6 +10,10 @@ void wrmsr(uint32_t msr, uint64_t value);
bool x86_has_msr(); bool x86_has_msr();
void x86_arch_init(); void x86_arch_init();
void x86_cpu_identification();
int cpuid_get_vendor_string(char* str);
/* Interrupt Descriptor Table */ /* Interrupt Descriptor Table */
void idt_init(void); void idt_init(void);
+1 -1
View File
@@ -10,7 +10,7 @@
/* version */ /* version */
#define PEPPEROS_VERSION_MAJOR "0" #define PEPPEROS_VERSION_MAJOR "0"
#define PEPPEROS_VERSION_MINOR "0" #define PEPPEROS_VERSION_MINOR "0"
#define PEPPEROS_VERSION_PATCH "58" #define PEPPEROS_VERSION_PATCH "109"
#define PEPPEROS_SPLASH \ #define PEPPEROS_SPLASH \
"\x1b[38;5;196m \x1b[38;5;231m____ _____\r\n\x1b[0m"\ "\x1b[38;5;196m \x1b[38;5;231m____ _____\r\n\x1b[0m"\
"\x1b[38;5;196m ____ ___ ____ ____ ___ _____\x1b[38;5;231m/ __ \\/ ___/\r\n\x1b[0m"\ "\x1b[38;5;196m ____ ___ ____ ____ ___ _____\x1b[38;5;231m/ __ \\/ ___/\r\n\x1b[0m"\
+2
View File
@@ -7,6 +7,7 @@
#ifndef KERNEL_H #ifndef KERNEL_H
#define KERNEL_H #define KERNEL_H
#include "limine.h"
enum ErrorCodes { enum ErrorCodes {
ENOMEM, ENOMEM,
EIO EIO
@@ -52,6 +53,7 @@ struct boot_context {
struct limine_memmap_response* mmap; struct limine_memmap_response* mmap;
struct limine_hhdm_response* hhdm; struct limine_hhdm_response* hhdm;
struct limine_kernel_address_response* kaddr; struct limine_kernel_address_response* kaddr;
struct limine_boot_time_response* bootdate;
}; };
// Are these modules initialized yet? // Are these modules initialized yet?
+1
View File
@@ -8,6 +8,7 @@
#define MEM_UTILS_H #define MEM_UTILS_H
#include <stddef.h> #include <stddef.h>
#include <limine.h>
void* memcpy(void* restrict dest, const void* restrict src, size_t n); void* memcpy(void* restrict dest, const void* restrict src, size_t n);
void* memset(void* s, int c, size_t n); void* memset(void* s, int c, size_t n);
+25
View File
@@ -0,0 +1,25 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Date helper functions
* @license GPL-3.0-only
*/
#ifndef DATE_H
#define DATE_H
#include <stdint.h>
struct date {
uint64_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
struct date date_timestamp_to_date(uint64_t timestamp);
struct date date_now();
#endif
+27
View File
@@ -6,6 +6,8 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <kernel.h>
#include <string/string.h>
/* /*
* cpuid - Wrapper for CPUID instruction * cpuid - Wrapper for CPUID instruction
@@ -19,3 +21,28 @@ void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t*
{ {
__asm__ volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf)); __asm__ volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf));
} }
/*
* cpuid_get_vendor_string - Get the CPU vendor string
* @str: String at least 13 bytes long (for output)
*
* Return:
* %0 - on success
*/
int cpuid_get_vendor_string(char* str)
{
uint32_t eax, ebx, ecx, edx;
cpuid(0, &eax, &ebx, &ecx, &edx);
char output[13] = {0};
uint32_t regs[3] = {ebx, edx, ecx};
for (unsigned int j=0; j<3; j++) {
for (unsigned int i=0; i<4; i++) {
output[4*j+i] = (char)((regs[j] >> 8*i) & 0xff);
}
}
strncpy(str, output, 13);
return 0;
}
+47
View File
@@ -8,6 +8,7 @@
#include <stdint.h> #include <stdint.h>
#include <arch/x86.h> #include <arch/x86.h>
#include <kernel.h> #include <kernel.h>
#include <mem/utils.h>
/* /*
* x86_overwrite_pat - Set PAT to WC * x86_overwrite_pat - Set PAT to WC
@@ -41,6 +42,52 @@ static void x86_overwrite_pat()
void x86_arch_init() void x86_arch_init()
{ {
x86_overwrite_pat(); x86_overwrite_pat();
x86_cpu_identification();
idt_init(); idt_init();
gdt_init(); gdt_init();
} }
/*
* cpu_supports_brandstring - Does the CPU support brand strings?
*
* Return:
* true - if it does
* false - if it doesn't
*/
bool cpu_supports_brandstring() {
uint32_t eax, ebx, ecx, edx;
cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
if (eax < 0x80000004) {
return false;
} else {
return true;
}
}
/*
* x86_cpu_idenfitication - get info about the CPU
*
* This function displays the CPU vendor name or the
* extended "brand string" if it's supported, on
* debug output.
*/
void x86_cpu_identification()
{
if (cpu_supports_brandstring()) {
uint32_t regs[12];
// Some CPUs don't return null-terminated values so we do it as a failsafe default
char str[sizeof(regs)+1] = {0};
cpuid(0x80000002, &regs[0], &regs[1], &regs[2], &regs[3]);
cpuid(0x80000003, &regs[4], &regs[5], &regs[6], &regs[7]);
cpuid(0x80000004, &regs[8], &regs[9], &regs[10], &regs[11]);
memcpy(str, regs, sizeof(regs));
str[sizeof(regs)] = '\0';
DEBUG("CPU: %s", str);
} else {
char vendor_string[13] = {0};
cpuid_get_vendor_string(vendor_string);
DEBUG("CPU vendor is: %s", vendor_string);
}
}
+6
View File
@@ -35,6 +35,12 @@ volatile struct limine_kernel_address_request kerneladdr_request = {
.revision = 0 .revision = 0
}; };
__attribute__((used, section(".limine_requests")))
volatile struct limine_boot_time_request date_request = {
.id = LIMINE_BOOT_TIME_REQUEST,
.revision = 0
};
__attribute__((used, section(".limine_requests_start"))) __attribute__((used, section(".limine_requests_start")))
volatile LIMINE_REQUESTS_START_MARKER; volatile LIMINE_REQUESTS_START_MARKER;
+14 -2
View File
@@ -10,6 +10,7 @@
#include <string/string.h> #include <string/string.h>
#include <stdint.h> #include <stdint.h>
#include <kernel.h> #include <kernel.h>
#include <time/date.h>
/* /*
* pedicel_main - Kernel shell main function * pedicel_main - Kernel shell main function
@@ -31,9 +32,13 @@ void pedicel_main(void* arg)
keyboard_getline(input_buf, PEDICEL_INPUT_SIZE); keyboard_getline(input_buf, PEDICEL_INPUT_SIZE);
if (strncmp(input_buf, "help", 4) == 0) { if (strncmp(input_buf, "help", 4) == 0) {
printf("\r\npanic - trigger a test panic\r\n" printf("\r\nYou are currently running the test kernel shell. This is not\r\n"
"a fully-fledged shell like you'd find in a complete operating system,\r\n"
"but rather a toy to play around in the meantime.\r\n\r\n"
"panic - trigger a test panic\r\n"
"syscall - trigger int 0x80\r\n" "syscall - trigger int 0x80\r\n"
"pf - trigger a page fault\r\n"); "pf - trigger a page fault\r\n"
"now - get current date\r\n");
continue; continue;
} }
@@ -52,6 +57,13 @@ void pedicel_main(void* arg)
fault[0] = 1; fault[0] = 1;
} }
if (strncmp(input_buf, "now", 3) == 0) {
struct date now = date_now();
printf("Now is %02u:%02u:%02u on %u/%u/%u\r\n", now.hour, now.minute,
now.second, now.day, now.month, now.year);
continue;
}
printf("%s: command not found\r\n", input_buf); printf("%s: command not found\r\n", input_buf);
} }
} }
+4
View File
@@ -5,6 +5,7 @@
*/ */
#include "arch/x86.h" #include "arch/x86.h"
#include "time/date.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <limine.h> #include <limine.h>
@@ -61,6 +62,7 @@ extern volatile struct limine_framebuffer_request framebuffer_request;
extern volatile struct limine_memmap_request memmap_request; extern volatile struct limine_memmap_request memmap_request;
extern volatile struct limine_hhdm_request hhdm_request; extern volatile struct limine_hhdm_request hhdm_request;
extern volatile struct limine_kernel_address_request kerneladdr_request; extern volatile struct limine_kernel_address_request kerneladdr_request;
extern volatile struct limine_boot_time_request date_request;
extern struct process_t* processes_list; extern struct process_t* processes_list;
extern struct process_t* current_process; extern struct process_t* current_process;
@@ -97,10 +99,12 @@ void kmain()
if (!LIMINE_BASE_REVISION_SUPPORTED) hcf(); if (!LIMINE_BASE_REVISION_SUPPORTED) hcf();
// Populate boot context // Populate boot context
// This stays valid only if the BOOTLOADER_RECLAIMABLE regions are preserved
boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL; boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL;
boot_ctx.mmap = memmap_request.response ? memmap_request.response : NULL; boot_ctx.mmap = memmap_request.response ? memmap_request.response : NULL;
boot_ctx.hhdm = hhdm_request.response ? hhdm_request.response : NULL; boot_ctx.hhdm = hhdm_request.response ? hhdm_request.response : NULL;
boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL; boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL;
boot_ctx.bootdate = date_request.response ? date_request.response : NULL;
term_init(); term_init();
serial_init(); serial_init();
+89
View File
@@ -0,0 +1,89 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Date helper functions
* @license GPL-3.0-only
*/
#include <stdint.h>
#include <time/date.h>
#include <mem/utils.h>
#include <kernel.h>
extern struct boot_context boot_ctx;
// Unix epoch used as reference: Jan 1st 1970, 00:00:00 UTC
struct date epoch = {
.year = 1970,
.month = 1,
.day = 1,
.hour = 0,
.minute = 0,
.second = 0
};
/*
* date_timestamp_to_date - Convert UNIX timestamp to a date structure
* @timestamp: UNIX timestamp
*
* Return:
* <date> - date structure
*/
struct date date_timestamp_to_date(uint64_t timestamp)
{
struct date result;
memcpy(&result, &epoch, sizeof(struct date));
uint64_t nr_days = timestamp / 86400;
while (nr_days > 0) {
unsigned int nr_month = 0;
int leap_year = 0;
if (result.year % 4 == 0 && (result.year % 100 != 0 || result.year % 400 == 0)) {
leap_year = 1;
} else {
leap_year = 0;
}
if (result.month == 2) {
if (leap_year != 0) {
nr_month = 29;
} else {
nr_month = 28;
}
} else {
nr_month = 31 - ((result.month -1) % 7 % 2);
}
if (nr_days >= nr_month) {
nr_days -= nr_month;
result.month++;
if (result.month > 12) {
result.month = 1;
result.year++;
}
} else {
result.day += nr_days;
nr_days = 0;
}
}
result.second = timestamp % 60;
timestamp /= 60;
result.minute = timestamp % 60;
timestamp /= 60;
result.hour = timestamp % 24;
return result;
}
/*
* date_now - Get the current date (time at boot + timer ticks)
*
* Return:
* <date> - date structure
*/
struct date date_now()
{
uint64_t timestamp_now = boot_ctx.bootdate->boot_time + (ticks/1000);
return date_timestamp_to_date(timestamp_now);
}