Disabling intrs + NMIs during CMOS access
This commit is contained in:
parent
9aba0ed6ec
commit
d5555d273c
6 changed files with 54 additions and 8 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,4 +1,5 @@
|
|||
config.mk
|
||||
/tags
|
||||
build/
|
||||
drive.img
|
||||
/compile_commands.json
|
||||
|
|
|
|||
1
Makefile
1
Makefile
|
|
@ -10,6 +10,7 @@ CFLAGS += -ggdb
|
|||
KERNEL_SOURCES_x86_64 := \
|
||||
src/x86_64/apic.c \
|
||||
src/x86_64/cmos.c \
|
||||
src/x86_64/interrupt.S \
|
||||
src/x86_64/loadcs.S \
|
||||
src/x86_64/uart.c \
|
||||
src/x86_64/mem.c \
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ LD = $(CROSS_PATH)/$(ARCH)-linux-ld
|
|||
# Compilation flags
|
||||
CFLAGS = -std=c17 -Wall -ffreestanding -nostdlib -mno-red-zone -mcmodel=kernel -mno-sse -mno-mmx -mno-80387
|
||||
CPPFLAGS = -Iinclude
|
||||
LDFLAGS = -nostdlib
|
||||
LDFLAGS = -nostdlib -znoexecstack
|
||||
|
||||
BOOTBOOT = ../bootboot
|
||||
MKBOOTIMG= $(BOOTBOOT)/mkbootimg/mkbootimg
|
||||
|
|
|
|||
9
include/x86_64/interrupt.h
Normal file
9
include/x86_64/interrupt.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef KARLOS_INTERRUPT_H
|
||||
#define KARLOS_INTERRUPT_H
|
||||
|
||||
int int_enable(void);
|
||||
int int_disable(void);
|
||||
int int_save(void);
|
||||
void int_restore(int state);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
#include <sys/socket.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <x86_64/asm.h>
|
||||
#include <x86_64/interrupt.h>
|
||||
#include <x86_64/cmos.h>
|
||||
|
||||
#define CMOS_SEL_PORT 0x70
|
||||
#define CMOS_DATA_PORT 0x71
|
||||
|
||||
#define CMOS_NMI_DISABLE 0x80 // bit in sel port
|
||||
|
||||
#define CMOS_REG_SECONDS 0x00
|
||||
#define CMOS_REG_MINUTES 0x02
|
||||
#define CMOS_REG_HOURS 0x04
|
||||
|
|
@ -49,14 +53,18 @@ bcd_to_binary(uint8_t bcd)
|
|||
static void
|
||||
cmos_access_rtc(struct datetime *dt)
|
||||
{
|
||||
while (cmos_read(CMOS_REG_STATA) & STATA_UPDATING) {}
|
||||
int cpu_state = int_disable();
|
||||
|
||||
dt->seconds = cmos_read(CMOS_REG_SECONDS);
|
||||
dt->minutes = cmos_read(CMOS_REG_MINUTES);
|
||||
dt->hours = cmos_read(CMOS_REG_HOURS);
|
||||
dt->day = cmos_read(CMOS_REG_DAY);
|
||||
dt->month = cmos_read(CMOS_REG_MONTH);
|
||||
while (cmos_read(CMOS_REG_STATA | CMOS_NMI_DISABLE) & STATA_UPDATING) {}
|
||||
|
||||
dt->seconds = cmos_read(CMOS_REG_SECONDS | CMOS_NMI_DISABLE);
|
||||
dt->minutes = cmos_read(CMOS_REG_MINUTES | CMOS_NMI_DISABLE);
|
||||
dt->hours = cmos_read(CMOS_REG_HOURS | CMOS_NMI_DISABLE);
|
||||
dt->day = cmos_read(CMOS_REG_DAY | CMOS_NMI_DISABLE);
|
||||
dt->month = cmos_read(CMOS_REG_MONTH | CMOS_NMI_DISABLE);
|
||||
dt->year = cmos_read(CMOS_REG_YEAR);
|
||||
|
||||
int_restore(cpu_state);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -73,7 +81,10 @@ cmos_current_datetime(struct datetime *dt)
|
|||
dt1.month != dt2.month ||
|
||||
dt1.year != dt2.year);
|
||||
|
||||
uint8_t statb = cmos_read(CMOS_REG_STATB);
|
||||
int cpu_state = int_disable();
|
||||
uint8_t statb = cmos_read(CMOS_REG_STATB | CMOS_NMI_DISABLE);
|
||||
cmos_read(0);
|
||||
int_restore(cpu_state);
|
||||
|
||||
bool pm = false;
|
||||
if (!(statb & STATB_24HOUR)) {
|
||||
|
|
|
|||
24
src/x86_64/interrupt.S
Normal file
24
src/x86_64/interrupt.S
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
.global int_enable
|
||||
.global int_disable
|
||||
.global int_save
|
||||
.global int_restore
|
||||
|
||||
.text
|
||||
|
||||
int_enable: pushfq
|
||||
pop %rax
|
||||
sti
|
||||
ret
|
||||
|
||||
int_disable:pushfq
|
||||
pop %rax
|
||||
cli
|
||||
ret
|
||||
|
||||
int_save: pushfq
|
||||
pop %rax
|
||||
ret
|
||||
|
||||
int_restore:push %rdi
|
||||
popfq
|
||||
ret
|
||||
Loading…
Add table
Reference in a new issue