Добавлен RTC

This commit is contained in:
Aren Elchinyan 2024-01-22 21:45:56 +03:00
parent 969ef786bd
commit df965c2218
3 changed files with 90 additions and 1 deletions

View File

@ -12,6 +12,7 @@
#include <lock.h>
#include <stdint.h>
#include <sys.h>
#define STACK_SIZE 8192 // 8 килобайт на стек
@ -57,10 +58,11 @@ struct frame {
typedef void (*int_entry_t)(struct frame *state);
extern lock_t task_lock;
extern uint64_t task_f_init;
void arch_init( );
void task_init( );
void task_switch(struct frame *state);
void task_switch( );
uint64_t task_new_thread(void (*func)(void *));
void cpu_init( );
void gdt_init( );
@ -73,6 +75,7 @@ uint64_t arch_get_tick_l( );
uint64_t arch_get_tick( );
void com_write_byte(uint8_t byte);
void com_write_bytes(char *c, uint64_t n);
time_t rtc_get_time( );
static inline void outb(uint16_t port, uint8_t val) {
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));

82
kernel/cpu/rtc.c Normal file
View File

@ -0,0 +1,82 @@
/**
* rtc.c
* Часы реального времени
*
* Функции даты и времени с точностью до секунды
*
*/
#include <lock.h>
#include <log.h>
#include <stdint.h>
#include <sys.h>
#include <tool.h>
#define CMOS_ADDR_PORT 0x70
#define CMOS_DATA_PORT 0x71
static int century_register = 0;
static uint8_t century = 20;
static inline uint8_t read_cmos(uint8_t addr) {
outb(CMOS_ADDR_PORT, addr);
return inb(CMOS_DATA_PORT);
}
static inline int get_update_in_progress_flag( ) {
outb(CMOS_ADDR_PORT, 0x0A);
return (inb(CMOS_DATA_PORT) & 0x80);
}
time_t rtc_get_time( ) {
uint8_t last_second, last_minute, last_hour, last_day, last_month, last_year;
time_t rtc_time;
while (get_update_in_progress_flag( ))
;
rtc_time.second = read_cmos(0x00);
rtc_time.minutes = read_cmos(0x02);
rtc_time.hours = read_cmos(0x04);
rtc_time.day = read_cmos(0x07);
rtc_time.month = read_cmos(0x08);
rtc_time.year = read_cmos(0x09);
if (century_register != 0) { rtc_time.year += century * 100; }
do {
last_second = rtc_time.second;
last_minute = rtc_time.minutes;
last_hour = rtc_time.hours;
last_day = rtc_time.day;
last_month = rtc_time.month;
last_year = rtc_time.year;
while (get_update_in_progress_flag( ))
;
rtc_time.second = read_cmos(0x00);
rtc_time.minutes = read_cmos(0x02);
rtc_time.hours = read_cmos(0x04);
rtc_time.day = read_cmos(0x07);
rtc_time.month = read_cmos(0x08);
rtc_time.year = read_cmos(0x09);
if (century_register != 0) { rtc_time.year += century * 100; }
} while ((last_second != rtc_time.second) || (last_minute != rtc_time.minutes) || (last_hour != rtc_time.hours) ||
(last_day != rtc_time.day) || (last_month != rtc_time.month) || (last_year != rtc_time.year));
uint8_t reg_b = read_cmos(0x0B);
// Преобразуем BCD значения в бинарные, если необходимо
if (!(reg_b & 0x04)) {
rtc_time.second = (rtc_time.second & 0x0F) + ((rtc_time.second / 16) * 10);
rtc_time.minutes = (rtc_time.minutes & 0x0F) + ((rtc_time.minutes / 16) * 10);
rtc_time.hours = ((rtc_time.hours & 0x0F) + (((rtc_time.hours & 0x70) / 16) * 10)) | (rtc_time.hours & 0x80);
rtc_time.day = (rtc_time.day & 0x0F) + ((rtc_time.day / 16) * 10);
rtc_time.month = (rtc_time.month & 0x0F) + ((rtc_time.month / 16) * 10);
rtc_time.year = (rtc_time.year & 0x0F) + ((rtc_time.year / 16) * 10);
}
return rtc_time;
}

View File

@ -40,12 +40,16 @@ void _start( ) {
LOG("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__);
time_t time = rtc_get_time( );
LOG("Время: %2u:%2u.%2u, %2u.%2u.%2u\n", time.hours, time.minutes, time.second, time.day, time.month, time.year);
pit_init( );
task_init( );
task_new_thread(finally);
full_init = 1;
task_f_init = 1;
asm volatile("sti");