~crm/os

b5af0b999e891e2c309b549c09263b9b12017f03 — Christos Margiolis 5 months ago 7dc87eb master
minor changes
11 files changed, 24 insertions(+), 128 deletions(-)

R i386/{reg.h => regs.h}
M kern/boot.s
M kern/idt.c
M kern/idt.h
M kern/kbd.c
M kern/pic.c
M kern/pic.h
M kern/timer.c
D kern/unused/lm.asm
M kern/vga.c
M mk/kern.mk
R i386/reg.h => i386/regs.h +1 -1
@@ 1,7 1,7 @@
#ifndef _REG_H_
#define _REG_H_

struct reg {
struct regs {
	u_int32_t	r_gs;
	u_int32_t	r_fs;
	u_int32_t	r_es;

M kern/boot.s => kern/boot.s +4 -4
@@ 288,17 288,17 @@ puts:
loop:
	mov	al, [si]	; Load character.
	cmp	al, 0		; Check for \0.
	jne	putchar		; If it's not \0, print the character.
	jne	putc		; If it's not \0, print the character.
	popa			; We're done, pop everything.
	ret			; Return back to where we were.
putchar:
putc:
	int	0x10		; BIOS print interrupt.
	inc	si		; `str++`
	jmp	loop		; Go to the next character.

; String declarations.
str_diskerr:	db "Error loading disk.", 0x0a, 0x0d, 0x00
str_a20_fail:	db "The A20 Line is disabled", 0x0a, 0x0d, 0x00
str_diskerr:	db "disk err: load", 0x0a, 0x0d, 0x00
str_a20_fail:	db "a20: disabled", 0x0a, 0x0d, 0x00

; Hard disk.
BOOTDRV:	db 0x80

M kern/idt.c => kern/idt.c +2 -2
@@ 125,7 125,7 @@ static const char *exceptmsg[32] = {
};

void
intr_handler(struct reg *r)
intr_handler(struct regs *r)
{
	intrhand_t handler;



@@ 148,7 148,7 @@ intr_register_handler(int intrno, intrhand_t handler)
}

void
dump_regs(struct reg *r)
dump_regs(struct regs *r)
{
	printf("eax=%#08x\tebx=%#08x\tecx=%#08x\tedx=%#08x\n",
	    r->r_eax, r->r_ebx, r->r_ecx, r->r_edx);

M kern/idt.h => kern/idt.h +4 -4
@@ 2,7 2,7 @@
#define _IDT_H_

#include <u.h>
#include <reg.h>
#include <regs.h>

#define INTVEC(name)	CONCAT(intr_, name)



@@ 67,11 67,11 @@ enum {
	IRQ15,
};

typedef void (*intrhand_t)(struct reg *);
typedef void (*intrhand_t)(struct regs *);

void idt_init(void);
void intr_handler(struct reg *);
void intr_handler(struct regs *);
void intr_register_handler(int, intrhand_t);
void dump_regs(struct reg *); /* FIXME: move elsewhere? */
void dump_regs(struct regs *); /* FIXME: move elsewhere? */

#endif /* _IDT_H_ */

M kern/kbd.c => kern/kbd.c +2 -2
@@ 12,7 12,7 @@
#define KBD_LSHIFT_REL	0xaa
#define KBD_RSHIFT_REL	0xb6

static void kbd_callback(struct reg *);
static void kbd_callback(struct regs *);

static u_char kbdus_upper[128] = {
	0,	/* Error */


@@ 91,7 91,7 @@ static u_char kbdus_lower[128] = {
};

static void
kbd_callback(struct reg *r)
kbd_callback(struct regs *r)
{
	u_int8_t sc;
	int shift = 0;

M kern/pic.c => kern/pic.c +2 -2
@@ 9,7 9,7 @@
void
pic_remap(void)
{
	u_char m1, m2;
	u_int8_t m1, m2;

	/* Save masks */
	m1 = inb(PIC_MASTER_DATA);


@@ 51,7 51,7 @@ pic_eoi(u_int32_t intrno)
}

void
pic_mask(u_char irq, int flag)
pic_mask(u_int8_t irq, int flag)
{
	u_int16_t port;
	u_int8_t v;

M kern/pic.h => kern/pic.h +1 -1
@@ 27,7 27,7 @@

void		pic_remap(void);
void		pic_eoi(u_int32_t);
void		pic_mask(u_char, int);
void		pic_mask(u_int8_t, int);
void		pic_on(void);
void		pic_off(void);


M kern/timer.c => kern/timer.c +2 -2
@@ 9,12 9,12 @@
#define FREQ		1193180
#define HZ		100

static void timer_callback(struct reg *);
static void timer_callback(struct regs *);

static u_int32_t ticks = 0;

static void
timer_callback(struct reg *r)
timer_callback(struct regs *r)
{
	ticks++;
	UNUSED(r);

D kern/unused/lm.asm => kern/unused/lm.asm +0 -106
@@ 1,106 0,0 @@
; call in pm_mode
	call	lm_check

; Check for Long Mode.
lm_check:
	pusha
	pushfd			; Push EFLAGS register to the stack.
	pop	eax		; Pop EFLAGS registers to `eax`.
	mov	ecx, eax	; Keep a backup in `ecx`.
	xor	eax, 1 << 21	; Flip the 21st bit if the it's not 1.
	push	eax
	popfd			; Pop `eax` to EFLAGS.

	pushfd
	pop	eax		; Copy EFLAGS back to `eax`.
	push	ecx
	popfd			; Restore the flipped version.
	xor	eax, ecx
	jz	lm_fail		; If EFLAGS' value hasn't changed, we have CPUID.

	mov	eax, 0x80000000	; CPUID argument.
	cpuid			; CPU identification. `eax` is now populated with info.
	cmp	eax, 0x80000001	; If it's less than 0x80000000 we cannot have Long Mode.
	jb	lm_fail

	mov	eax, 0x80000001	; Get extended processor information.
	cpuid
	test	edx, 1 << 29
	jz	lm_fail		; If the 29th bit is 0, we cannot have Long Mode.

	popa
	ret

; No long mode.
lm_fail:
	popa
	call	kernel_exec
	jmp	$		; Safety hang.

; We'll check for (and switch to) Long Mode here.
lm_enter:
	cli
	mov	eax, cr0
	or	eax, 1 << 31	; Paging Enable.
	mov	cr0, eax
; Set up PAE paging.
	mov	edi, 0x1000	; Page table starts 4KiB in memory.
	mov	cr3, edi	; Hold the location of the highest page table.
	xor	eax, eax	; Clear memory space.
	mov	ecx, 4096
	rep	stosd		; Write 4096 dwords with the value 0.	
	mov	edi, 0x1000	; Go to the initial location.

; Page table locations:
;	Page Map Level 4 Table (PML4T):		0x1000
;	Page Directory Pointer Table (PDPT):	0x2000
;	Page Directory Table (PDT):		0x3000
;	Page Table (PT);			0x4000
;
; In order for each table to point to each other we'll use a size directive.
; Since tables are 4KiB away from each other we'll move dwords.
	mov	dword [edi], 0x2003	; PML4T -> PDPT
	add	edi, 0x1000		; Move 4KiB forward.
	mov	dword [edi], 0x3003	; PDPT -> PDT
	add	edi, 0x1000
	mov	dword [edi], 0x4003	; PDT -> PT
	add	edi, 0x1000

	mov	dword ebx, 3	; Map beginning of code.
	mov	ecx, 512	; Do it 512 times.
setentry:
	mov	dword [edi], ebx
	add	ebx, 0x1000
	add	edi, 8		; Go to the next entry in the page table.
	loop	setentry

; Enable the 6th bit in CR4 (Physical Address Extension Bit) to tell
; the CPU that we're using PAE paging.
	mov	eax, cr4
	or	eax, 1 << 5
	mov	cr4, eax

; Activate Long Mode and Paging using the EFER.
	mov	ecx, 0xc0000080
	rdmsr			; Copy the contents of EFER to `eax`. 
	or	eax, 1 << 8	; Set LME bit to enable Long Mode.
	wrmsr			; Write `eax` back to EFER.	
	
	lgdt	[gdt_ptr]		; Load the GDT.
	jmp	GDT_CODESEG:lm_init	; Switch to Long Mode.

; We're in Long Mode now.
[bits 64]
lm_init:
	mov	ax, GDT_DATASEG
	mov	ds, ax
	mov	ss, ax
	mov	es, ax
	mov	fs, ax
	mov	gs, ax

	mov	rbp, 0x90000
	mov	rsp, rbp
	call	kernel_exec
	jmp	$	


M kern/vga.c => kern/vga.c +5 -4
@@ 11,7 11,7 @@

struct vga {
	volatile u_int16_t *buf;
	size_t row;
	size_t row;	/* XXX: signed? */
	size_t col;
	u_int8_t color;
};


@@ 49,7 49,8 @@ vga_putc(char c)
		vga.col = 0;
		break;
	case '\b':
		vga.col--;
		if (vga.col > 0)
			vga.col--;
		vga.buf[vga.row * VGA_COLS + vga.col] = VGA_PUTC(' ');
		break;
	case '\r':


@@ 63,13 64,13 @@ vga_putc(char c)
		vga.col++;
	}

	if (vga.row >= VGA_ROWS) {
	if (vga.row > VGA_ROWS) {
		/* FIXME: scroll */
		vga_clear(VGA_BLACK, VGA_WHITE);
		vga.row = 0;
		vga.col = 0;
	}
	if (vga.col >= VGA_COLS) {
	if (vga.col > VGA_COLS) {
		vga.row++;
		vga.col = 0;
	}

M mk/kern.mk => mk/kern.mk +1 -0
@@ 21,6 21,7 @@ options:
	@echo "CFLAGS	= ${CFLAGS}"
	@echo "LDFLAGS	= ${LDFLAGS}"

# TODO: boot, dd, kern, cat | start esp when 0x1000 | ld -T x2 | 2mb >>
${BIN}: ${OBJ}
	mkdir -p ${BINDIR}
	${AS} -fbin ${BOOT_FILE} -o ${BOOT_BIN}