aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/kernel/acpi/acpi.c37
-rw-r--r--src/kernel/acpi/acpi.h28
-rw-r--r--src/kernel/cmos/rtc.c99
-rw-r--r--src/kernel/cmos/rtc.h15
-rw-r--r--src/kernel/commands/command.c7
-rw-r--r--src/kernel/graphics/vesa.c10
-rw-r--r--src/kernel/kernel.c4
7 files changed, 161 insertions, 39 deletions
diff --git a/src/kernel/acpi/acpi.c b/src/kernel/acpi/acpi.c
index ef27369..b90c730 100644
--- a/src/kernel/acpi/acpi.c
+++ b/src/kernel/acpi/acpi.c
@@ -1,8 +1,10 @@
#include <kernel/io/io.h>
#include <kernel/lib/lib.h>
#include <kernel/timer/timer.h>
+#include <kernel/acpi/acpi.h>
#include <stddef.h>
+struct FACP *facp;
uint32_t *SMI_CMD;
char ACPI_ENABLE;
char ACPI_DISABLE;
@@ -14,30 +16,6 @@ int SLP_EN;
int SCI_EN;
char PM1_CNT_LEN;
-struct RSDPtr {
- char Signature[8];
- char CheckSum;
- char OemID[6];
- char Revision;
- uint32_t *RsdtAddress;
-};
-
-struct FACP {
- char Signature[4];
- uint32_t Length;
- char unneded1[40 - 8];
- uint32_t *DSDT;
- char unneded2[48 - 44];
- uint32_t *SMI_CMD;
- char ACPI_ENABLE;
- char ACPI_DISABLE;
- char unneded3[64 - 54];
- uint32_t *PM1a_CNT_BLK;
- uint32_t *PM1b_CNT_BLK;
- char unneded4[89 - 72];
- char PM1_CNT_LEN;
-};
-
unsigned int *acpi_check_rsd_ptr(unsigned int *ptr) {
char *sig = "RSD PTR ";
struct RSDPtr *rsdp = (struct RSDPtr *) ptr;
@@ -53,7 +31,7 @@ unsigned int *acpi_check_rsd_ptr(unsigned int *ptr) {
}
if (check == 0) {
- return (unsigned int *) rsdp->RsdtAddress;
+ return (unsigned int *) rsdp->rsdt_address;
}
}
@@ -138,16 +116,16 @@ int acpi_install() {
while (0 < entrys--) {
if (acpi_check_header((unsigned int *) *ptr, "FACP") == 0) {
entrys = -2;
- struct FACP *facp = (struct FACP *) *ptr;
+ facp = (struct FACP *) *ptr;
if (acpi_check_header((unsigned int *) facp->DSDT, "DSDT") == 0) {
char *S5Addr = (char *) facp->DSDT + 36;
- int dsdtLength = *(facp->DSDT + 1) - 36;
- while (0 < dsdtLength--) {
+ int dsdt_length = *(facp->DSDT + 1) - 36;
+ while (0 < dsdt_length--) {
if (memory_compare(S5Addr, "_S5_", 4) == 0)
break;
S5Addr++;
}
- if (dsdtLength > 0) {
+ if (dsdt_length > 0) {
if ((*(S5Addr - 1) == 0x08 || (*(S5Addr - 2) == 0x08 && *(S5Addr - 1) == '\\')) &&
*(S5Addr + 4) == 0x12) {
S5Addr += 5;
@@ -187,7 +165,6 @@ int acpi_install() {
}
void acpi_poweroff() {
- acpi_install();
acpi_enable();
if (SCI_EN == 0) {
diff --git a/src/kernel/acpi/acpi.h b/src/kernel/acpi/acpi.h
index 53c57b4..1d18182 100644
--- a/src/kernel/acpi/acpi.h
+++ b/src/kernel/acpi/acpi.h
@@ -17,4 +17,32 @@ void reboot();
*/
void acpi_poweroff();
+struct RSDPtr {
+ char Signature[8];
+ char CheckSum;
+ char OemID[6];
+ char Revision;
+ uint32_t *rsdt_address;
+};
+
+struct FACP {
+ char Signature[4];
+ uint32_t Length;
+ char unneded1[40 - 8];
+ uint32_t *DSDT;
+ char unneded2[48 - 44];
+ uint32_t *SMI_CMD;
+ char ACPI_ENABLE;
+ char ACPI_DISABLE;
+ char unneded3[64 - 54];
+ uint32_t *PM1a_CNT_BLK;
+ uint32_t *PM1b_CNT_BLK;
+ char unneded4[89 - 72];
+ char PM1_CNT_LEN;
+ char unneeded5[18];
+ char century;
+};
+
+extern struct FACP *facp;
+
#endif
diff --git a/src/kernel/cmos/rtc.c b/src/kernel/cmos/rtc.c
new file mode 100644
index 0000000..ed7c494
--- /dev/null
+++ b/src/kernel/cmos/rtc.c
@@ -0,0 +1,99 @@
+#include <kernel/io/io.h>
+#include <kernel/graphics/vesa.h>
+#include <kernel/acpi/acpi.h>
+
+unsigned char second;
+unsigned char minute;
+unsigned char hour;
+unsigned char day;
+unsigned char month;
+unsigned int year;
+
+int get_update_in_progress_flag() {
+ send_b(0x70, 0x0A);
+ return (receive_b(0x71) & 0x80);
+}
+
+unsigned char get_rtc_register(int reg) {
+ send_b(0x70, reg);
+ return receive_b(0x71);
+}
+
+void read_rtc() {
+ unsigned int century;
+ unsigned char last_second;
+ unsigned char last_minute;
+ unsigned char last_hour;
+ unsigned char last_day;
+ unsigned char last_month;
+ unsigned char last_year;
+ unsigned char last_century;
+ unsigned char registerB;
+
+ while (get_update_in_progress_flag());
+ second = get_rtc_register(0x00);
+ minute = get_rtc_register(0x02);
+ hour = get_rtc_register(0x04);
+ day = get_rtc_register(0x07);
+ month = get_rtc_register(0x08);
+ year = get_rtc_register(0x09);
+ century = get_rtc_register(facp->century);
+
+ // Try until the values are the same (fix for RTC updates)
+ do {
+ last_second = second;
+ last_minute = minute;
+ last_hour = hour;
+ last_day = day;
+ last_month = month;
+ last_year = year;
+ last_century = century;
+
+ while (get_update_in_progress_flag());
+ second = get_rtc_register(0x00);
+ minute = get_rtc_register(0x02);
+ hour = get_rtc_register(0x04);
+ day = get_rtc_register(0x07);
+ month = get_rtc_register(0x08);
+ year = get_rtc_register(0x09);
+ century = get_rtc_register(facp->century);
+ } while ((last_second != second) || (last_minute != minute) || (last_hour != hour) ||
+ (last_day != day) || (last_month != month) || (last_year != year) ||
+ (last_century != century));
+
+ registerB = get_rtc_register(0x0B);
+
+ if (!(registerB & 0x04)) {
+ second = (second & 0x0F) + ((second / 16) * 10);
+ minute = (minute & 0x0F) + ((minute / 16) * 10);
+ hour = ((hour & 0x0F) + (((hour & 0x70) / 16) * 10)) | (hour & 0x80);
+ day = (day & 0x0F) + ((day / 16) * 10);
+ month = (month & 0x0F) + ((month / 16) * 10);
+ year = (year & 0x0F) + ((year / 16) * 10);
+ century = (century & 0x0F) + ((century / 16) * 10);
+ }
+
+ year += century * 100;
+
+ // Convert to 24h if necessary
+ if (!(registerB & 0x02) && (hour & 0x80)) {
+ hour = ((hour & 0x7F) + 12) % 24;
+ }
+}
+
+void write_time() {
+ read_rtc();
+ vesa_draw_string("Current time: ");
+ vesa_draw_number(hour);
+ vesa_draw_string(":");
+ vesa_draw_number(minute);
+ vesa_draw_string(":");
+ vesa_draw_number(second);
+ vesa_draw_string(" ");
+ vesa_draw_number(month);
+ vesa_draw_string("/");
+ vesa_draw_number(day);
+ vesa_draw_string("/");
+ vesa_draw_number(year);
+ vesa_draw_string("\n");
+} \ No newline at end of file
diff --git a/src/kernel/cmos/rtc.h b/src/kernel/cmos/rtc.h
new file mode 100644
index 0000000..82ff86c
--- /dev/null
+++ b/src/kernel/cmos/rtc.h
@@ -0,0 +1,15 @@
+#ifndef MELVIX_RTC_H
+#define MELVIX_RTC_H
+
+unsigned char second;
+unsigned char minute;
+unsigned char hour;
+unsigned char day;
+unsigned char month;
+unsigned int year;
+
+void read_rtc();
+
+void write_time();
+
+#endif
diff --git a/src/kernel/commands/command.c b/src/kernel/commands/command.c
index 8ddbb08..2334219 100644
--- a/src/kernel/commands/command.c
+++ b/src/kernel/commands/command.c
@@ -2,6 +2,8 @@
#include <kernel/io/io.h>
#include <kernel/acpi/acpi.h>
#include <kernel/graphics/vesa.h>
+#include <kernel/cmos/rtc.h>
+#include <kernel/timer/timer.h>
int32_t starts_with(const char *a, const char *b) {
size_t length_pre = strlen(b);
@@ -22,6 +24,11 @@ void exec_command(char *command) {
acpi_poweroff();
else if (starts_with(command, "zzz"))
vesa_draw_string("Not implemented\n");
+ else if (starts_with(command, "time")) {
+ vesa_draw_number(get_time());
+ vesa_draw_string("\n");
+ } else if (starts_with(command, "date"))
+ write_time();
else if (starts_with(command, "reboot"))
reboot();
else
diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c
index cc46a6b..d9318e2 100644
--- a/src/kernel/graphics/vesa.c
+++ b/src/kernel/graphics/vesa.c
@@ -113,8 +113,8 @@ void set_optimal_resolution() {
serial_write_dec(mode_info->bpp);
serial_write("\n");
- //if (mode_info->width > vbe_width || (mode_info->width == vbe_width && (mode_info->bpp >> 3) > vbe_bpl))) {
- if (mode_info->width > vbe_width || (mode_info->bpp == 16)) {
+ if (mode_info->width > vbe_width || (mode_info->width == vbe_width && (mode_info->bpp >> 3) > vbe_bpl)) {
+ // if ((mode_info->bpp == 8)) { // Force specific bpp for debugging
// (float) mode_info->width / (float) mode_info->height < 2.0 &&) {
highest = *mode;
vbe_width = mode_info->width;
@@ -199,10 +199,6 @@ uint16_t terminal_x = 1;
uint16_t terminal_y = 1;
void vesa_convert_color(uint32_t *color_array, uint32_t color) {
- serial_write("Converting ");
- serial_write_hex(color);
- serial_write(" to ");
-
uint8_t red = (color >> 16) & 255;
uint8_t green = (color >> 8) & 255;
uint8_t blue = color & 255;
@@ -224,8 +220,6 @@ void vesa_convert_color(uint32_t *color_array, uint32_t color) {
} else {
panic("Unknown color bpp!");
}
-
- serial_write("\n");
}
void vesa_set_pixel(uint16_t x, uint16_t y, const uint32_t color[3]) {
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 859b6f1..dc93824 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -5,6 +5,7 @@
#include <kernel/timer/timer.h>
#include <kernel/paging/paging.h>
#include <kernel/input/input.h>
+#include <kernel/acpi/acpi.h>
void init() {
vga_log("Installing basic features of Melvix...", 0);
@@ -12,10 +13,11 @@ void init() {
gdt_install();
init_serial();
paging_install();
- keyboard_install();
+ acpi_install();
idt_install();
isrs_install();
irq_install();
+ keyboard_install();
set_optimal_resolution();
asm volatile ("sti");
}