From 0a41dae5f406d498b5c9ab1542cb5660e0d982f6 Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Wed, 1 Jun 2016 19:37:09 -0700 Subject: Initial checkin of toy OS project. --- kernel/hal/Makefile | 20 +++ kernel/hal/counters.c | 17 +++ kernel/hal/interrupts.c | 230 ++++++++++++++++++++++++++++++++ kernel/hal/interrupts.h | 92 +++++++++++++ kernel/hal/intsupport.asm | 326 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/hal/io.c | 40 ++++++ kernel/hal/timer.c | 43 ++++++ kernel/hal/timestamp.asm | 19 +++ kernel/hal/video.h | 15 +++ 9 files changed, 802 insertions(+) create mode 100644 kernel/hal/Makefile create mode 100644 kernel/hal/counters.c create mode 100644 kernel/hal/interrupts.c create mode 100644 kernel/hal/interrupts.h create mode 100644 kernel/hal/intsupport.asm create mode 100644 kernel/hal/io.c create mode 100644 kernel/hal/timer.c create mode 100644 kernel/hal/timestamp.asm create mode 100644 kernel/hal/video.h (limited to 'kernel/hal') diff --git a/kernel/hal/Makefile b/kernel/hal/Makefile new file mode 100644 index 0000000..3725f18 --- /dev/null +++ b/kernel/hal/Makefile @@ -0,0 +1,20 @@ +CC= gcc +CFLAGS= -Wall -imacros ../defines -I../inc +OBJS= video.o io.o interrupts.o intsupport.o keyboard.o timer.o \ + timestamp.o counters.o +RM= /bin/rm +NASM= nasm +NASMFLAGS= -f elf + +.SUFFIXES: .c .o .asm + +all: $(OBJS) + +.c.o: + $(CC) $(CFLAGS) -c $< + +.asm.o: + $(NASM) $(NASMFLAGS) -o $*.o $< + +clean: + $(RM) -f $(OBJS) *~ #*# .#* diff --git a/kernel/hal/counters.c b/kernel/hal/counters.c new file mode 100644 index 0000000..9bd9466 --- /dev/null +++ b/kernel/hal/counters.c @@ -0,0 +1,17 @@ +//+---------------------------------------------------------------------------- +// +// File: counters.c +// +// Module: +// +// Synopsis: +// +// Copyright (C) 2003 Scott Gasch +// +// Created: sgasch 24 Oct 2003 +// +//+---------------------------------------------------------------------------- + +#include "kernel.h" + +UINT64 g_ullTimeStampCounter = 0; diff --git a/kernel/hal/interrupts.c b/kernel/hal/interrupts.c new file mode 100644 index 0000000..94f2528 --- /dev/null +++ b/kernel/hal/interrupts.c @@ -0,0 +1,230 @@ +//+---------------------------------------------------------------------------- +// +// File: interrupts.c +// +// Module: +// +// Synopsis: +// +// Created: sgasch 6 Jul 2003 +// +//+---------------------------------------------------------------------------- + +#include "kernel.h" +#include "hal.h" +#include "rtl.h" +#include "interrupts.h" + +IDT_ENTRY g_IDT[NUM_IDT_ENTRIES]; +INTERRUPT_HANDLER g_InterruptHandlerTable[NUM_IDT_ENTRIES]; +ULONG g_uInterruptsEnabled = 0; + +void +HalEnableInterrupts(void) +{ + g_uInterruptsEnabled++; + ASSERT(g_uInterruptsEnabled == 1); + + __asm__ __volatile__ ( + "sti" + ); +} + +void +HalDisableInterrupts(void) +{ + g_uInterruptsEnabled--; + ASSERT(g_uInterruptsEnabled == 0); + + __asm__ __volatile__ ( + "cli" + ); +} + + +//+---------------------------------------------------------------------------- +// +// Function: DoNothing +// +// Synopsis: The default interrupt handler, do nothing +// +// Arguments: INTERRUPT_STATE *p +// +// Returns: void +// +//+---------------------------------------------------------------------------- +void HalDoNothing(INTERRUPT_STATE *p) +{ + ; +} + + +//+---------------------------------------------------------------------------- +// +// Function: InterruptSendIrqEoi +// +// Synopsis: Send Interrupt ReQuest End Of Interrupt to the PIC. +// +// Arguments: INTERRUPT_STATE *is +// +// Returns: void +// +//+---------------------------------------------------------------------------- +void +HalInterruptSendIrqEoi(INTERRUPT_STATE *is) +{ + ULONG uIrq; + BYTE bCommand; + BYTE *p = (BYTE *)0x000B8000; + + *p = '3'; + *(p + 1) = ' '; + + if ((is->uIntNum >= FIRST_EXTERNAL_INT) && + (is->uIntNum <= LAST_EXTERNAL_INT)) + { + uIrq = (is->uIntNum - FIRST_EXTERNAL_INT); + ASSERT(uIrq >= 0); + ASSERT(uIrq <= 15); + bCommand = 0x60 | (uIrq & 0x7); + + if (uIrq < 8) + { + // EOI to master PIC + out(0x20, bCommand); + HalIoDelay(); + } + else + { + // EOI to slave PIC and cascade line EOI to master PIC + out(0xA0, bCommand); + out(0x20, 0x62); + HalIoDelay(); + } + } + + *p = '4'; + *(p + 1) = ' '; +} + +//+---------------------------------------------------------------------------- +// +// Function: InterruptInitializeGate +// +// Synopsis: Initializes an interrupt gate with given handler address +// and descriptor privilege level. +// +// Arguments: IDT_ENTRY *pEntry, +// void *pPreamble, +// ULONG uDpl +// +// Returns: void +// +//+---------------------------------------------------------------------------- +void +HalInterruptInitializeGate(IDT_ENTRY *pEntry, + void *pPreamble, + ULONG uDpl) +{ + ULONG u = (ULONG)pPreamble; + + pEntry->i.offsetLow = u & 0xffff; + pEntry->i.segmentSelector = (1<<3); + pEntry->i.reserved = 0; + pEntry->i.signature = 0x70; // == 01110000b + pEntry->i.dpl = uDpl; + pEntry->i.present = 1; + pEntry->i.offsetHigh = u >> 16; +} + + +//+---------------------------------------------------------------------------- +// +// Function: InterruptInstallHandler +// +// Synopsis: Installs an interrupt handler routine for a given IRQ number +// +// Arguments: ULONG uInterruptNumber, +// INTERRUPT_HANDLER pHandler +// +// Returns: void +// +//+---------------------------------------------------------------------------- +void +HalInterruptInstallHandler(ULONG uInterruptNumber, + INTERRUPT_HANDLER pHandler) +{ + ASSERT(uInterruptNumber < ARRAY_LENGTH(g_InterruptHandlerTable)); + + g_InterruptHandlerTable[uInterruptNumber] = pHandler; +} + + +//+---------------------------------------------------------------------------- +// +// Function: InterruptInitialize +// +// Synopsis: Initialize the interrupt system +// +// Arguments: void +// +// Returns: void +// +//+---------------------------------------------------------------------------- +void +HalInitializeInterrupts(void) +{ + ULONG uPreambleEntrySize = (ULONG)&HalInterruptHandlerPreambleAfter; + ULONG u; + ULONG uDpl; + USHORT uLimitAndBase[3]; + BYTE *p; + + // + // Determine the size of an interrupt preamble table entry. + // + uPreambleEntrySize -= (ULONG)&HalInterruptHandlerPreambleBefore; + + // + // Set the base interrupt number for each PIC. See comments in + // intsupport.asm. + // + HalInterruptInitializePICs(); + + // + // Build interrupt descriptor table + // + for (u = 0, p = &HalInterruptHandlerPreamble; + u < ARRAY_LENGTH(g_IDT); + u++, p += uPreambleEntrySize) + { + uDpl = (u == 0x2E) ? USER_PRIVILEGE : KERNEL_PRIVILEGE; + + HalInterruptInitializeGate(&(g_IDT[u]), p, uDpl); + HalInterruptInstallHandler(u, HalDoNothing); + } + + // + // Install the IDT + // + u = (ULONG)&(g_IDT); + uLimitAndBase[0] = 8 * NUM_IDT_ENTRIES; + uLimitAndBase[1] = (USHORT)(u & 0xffff); + uLimitAndBase[2] = (USHORT)(u >> 16); + + HalInterruptLoadIDTR((void *)uLimitAndBase); + + // + // Install interrupt handlers + // + HalInterruptInstallHandler(IRQ0, HalTimerInt); + HalInterruptInstallHandler(IRQ1, HalKeyboardInt); + + out(0x21, 0xFC); // turn on keyboard and timer + + // + // Enable interrupts + // + HalEnableInterrupts(); +} + diff --git a/kernel/hal/interrupts.h b/kernel/hal/interrupts.h new file mode 100644 index 0000000..673b13b --- /dev/null +++ b/kernel/hal/interrupts.h @@ -0,0 +1,92 @@ +//+---------------------------------------------------------------------------- +// +// File: interrupts.h +// +// Module: +// +// Synopsis: +// +// Created: sgasch 6 Jul 2003 +// +//+---------------------------------------------------------------------------- + +#ifndef _INTERRUPTS_H_ +#define _INTERRUPTS_H_ + +#define NUM_IDT_ENTRIES (256) + +// Exceptions range from 0x00..0x11 +#define FIRST_EXCEPTION 0x00 +#define LAST_EXCEPTION 0x11 +#define NUM_EXCEPTIONS 18 + +// External IRQs range from 0x30..0x3F +#define FIRST_EXTERNAL_INT 0x30 +#define LAST_EXTERNAL_INT 0x3F +#define IRQ0 0x30 +#define IRQ1 0x31 +#define IRQ2 0x39 +#define IRQ3 0x33 +#define IRQ4 0x34 +#define IRQ5 0x35 +#define IRQ6 0x36 +#define IRQ7 0x37 +#define IRQ8 0x38 +#define IRQ9 0x39 +#define IRQ10 0x3A +#define IRQ11 0x3B +#define IRQ12 0x3C +#define IRQ13 0x3D +#define IRQ14 0x3E +#define IRQ15 0x3F +#define NUM_EXTERNAL_INTS 16 + +typedef struct _INTERRUPT_GATE +{ + USHORT offsetLow; + USHORT segmentSelector; + USHORT reserved : 5; + USHORT signature : 8; + USHORT dpl : 2; + USHORT present : 1; + USHORT offsetHigh; +} +INTERRUPT_GATE; + +typedef union _IDT_ENTRY +{ + INTERRUPT_GATE i; + // In theory we could have members for trap gates + // and task gates if we wanted. +} +IDT_ENTRY; + +// +// Defined in intsupport.asm +// +extern void HalInterruptInitializePICs(void); +extern void HalInterruptLoadIDTR(void *uLimitAndBase); +extern void HalIoDelay(void); +extern BYTE HalInterruptHandlerPreamble; +extern BYTE HalInterruptHandlerPreambleBefore; +extern BYTE HalInterruptHandlerPreambleAfter; + +// +// Defined in interrupts.c +// +extern void HalDisableInterrupts(void); +extern void HalEnableInterrupts(void); + + +// +// Defined in keyboard.c +// +extern void HalKeyboardInt(INTERRUPT_STATE *is); + +// +// Defined in timer.c +// +extern void HalTimerInt(INTERRUPT_STATE *is); + +#endif + diff --git a/kernel/hal/intsupport.asm b/kernel/hal/intsupport.asm new file mode 100644 index 0000000..3d1fcc8 --- /dev/null +++ b/kernel/hal/intsupport.asm @@ -0,0 +1,326 @@ +[BITS 32] + +FIRST_EXTERNAL_INT equ 0x30 +LAST_EXTERNAL_INT equ 0x30+15 + +GLOBAL HalInterruptLoadIDTR +GLOBAL HalInterruptGenericHandler +GLOBAL HalInterruptHandlerPreamble +GLOBAL HalInterruptHandlerPreambleBefore +GLOBAL HalInterruptHandlerPreambleAfter +GLOBAL HalInterruptInitializePICs +GLOBAL HalIoDelay + +EXTERN g_InterruptHandlerTable +EXTERN HalVideoPrint +EXTERN HalInterruptSendIrqEoi + +;; Save registers prior to calling a handler function. +;; This must be kept up to date with: +;; - Interrupt_State struct in int.h +;; - Setup_Initial_Thread_Context() in kthread.c +%macro SAVE_REGISTERS 0 + push eax + push ebx + push ecx + push edx + push esi + push edi + push ebp + push ds + push es + push fs + push gs +%endmacro + +;; Restore registers and clean up the stack after calling a handler function +;; (i.e., just before we return from the interrupt via an iret instruction). +%macro RESTORE_REGISTERS 0 + pop gs + pop fs + pop es + pop ds + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + pop eax + add esp, 8 +%endmacro + +%macro INT_NO_ERROR 1 +align 8 + push 0xffffffff ; fake the error code + push %1 ; push the int number + jmp HalInterruptGenericHandler; +%endmacro + +%macro INT_WITH_ERROR 1 +align 8 + push %1 ; error code already pushed, just push int num + jmp HalInterruptGenericHandler +%endmacro + +[SECTION .text] +;;; +;;; void +;;; InterruptLoadIDTR(IDT *p) +;;; +;;; Function to load the interrupt descriptor table register (IDTR) +;;; callable from C. +;;; +HalInterruptLoadIDTR: + mov eax, [esp+4] ; p + lidt [eax] + ret + +;;; +;;; The following is code to initialize the master and slave 8259 +;;; programmable interrupt controllers (PICs). +;;; +;;; For ISA machines there are two 8259's, a master and a slave. Each has +;;; eight interrupt request (IR) pins and one interrupt (INT) pin. The +;;; master's INT pin is tied to the INT line of the microprocessor. The +;;; slave's INT pin is tied to the master's IR2 line. Thus the master's +;;; IR0, IR1, and IR3..7 are real devices. But the master's IR2 means +;;; that some IR pin on the slave is asserted. So the system IRQs are: +;;; +;;; (highest default priority) +;;; IRQ0 = master IR0 [IRQ0 = system timer] +;;; IRQ1 = master IR1 [IRQ1 = keyboard] +;;; IRQ2 = master IR2 --> IRQ8..IRQ15 = slave IR0..7 +;;; [IRQ8 = rt. timer][IRQ13 = coproc.] +;;; IRQ3 = master IR3 +;;; IRQ4 = master IR4 +;;; IRQ5 = master IR5 +;;; IRQ6 = master IR6 +;;; IRQ7 = master IR7 +;;; (lowest default priority) +;;; +;;; By default these IRQs raise the following interrupt numbers: +;;; +;;; IRQ0 = int 0x8 [collides with double exception] +;;; IRQ1 = int 0x9 [collides with coprocessor exception] +;;; IRQ2/9 = int 0x71 +;;; IRQ3 = int 0xb [collides with segment not present exception] +;;; IRQ4 = int 0xc [collides with stack fault exception] +;;; IRQ5 = int 0xd [collides with general protection exception] +;;; IRQ6 = int 0xe [collides with page fault] +;;; IRQ7 = int 0xf +;;; IRQ8 = int 0x70 +;;; IRQ10 = int 0x72 +;;; IRQ11 = int 0x73 +;;; IRQ12 = int 0x74 +;;; IRQ13 = int 0x75 +;;; IRQ14 = int 0x76 +;;; IRQ15 = int 0x77 +;;; +;;; So the problem is that IRQ0, IRQ1, IRQ3..6 all, by default, map to +;;; interrupt numbers that collide with interrupts raised by the cpu +;;; as a result of a software exception. The solution to this problem +;;; is to remap what interrupts are raised by these IRQs by reprogramming +;;; the 8259 PICs to raise new interrupt numbers. +;;; +;;; This is accomplished by sending initialization command words (ICWs) +;;; to I/O ports 0x20-0x21 (master PIC) and 0xA0-0xA1 (slave PIC). By doing +;;; so we can remap the interrupt numbers raised by IRQs so that: +;;; +;;; IRQ0 = 0x30 IRQ8 = 0x38 +;;; IRQ1 = 0x31 IRQ10 = 0x3A +;;; IRQ2/9 = 0x39 IRQ11 = 0x3B +;;; IRQ3 = 0x33 IRQ12 = 0x3C +;;; IRQ4 = 0x34 IRQ13 = 0x3D +;;; IRQ5 = 0x35 IRQ14 = 0x3E +;;; IRQ6 = 0x36 IRQ15 = 0x3F +;;; IRQ7 = 0x37 +;;; +;;; ICW1 is the same for both the master and slave PIC. Here's the meaning +;;; of the individual bits in the word: +;;; +;;; F E D C B A 9 8 | 7 6 5 4 3 2 1 0 +;;; (not used) | | | | |__ 1=expect ICW4 +;;; | | | |_____ 0=cascade 1=single +;;; | | |________ 0=interval-4, 1=8 +;;; | |___________ 0=edge triggered +;;; | 1=level triggered +;;; |______________ must be 1 +;;; +;;; +BOTH_ICW1 equ 0x11 ; expect ICW4, cascade mode, call address + ; interval=8, edge triggered mode + +;;; +;;; ICW2 tells the PICs their base interrupt number. For example, the +;;; default base interrupt for the master PIC is 0x8. Thus IRQ0=0x8, +;;; IRQ1=0x9 ... IRQ7=0xF. As stated, we want to relocate these. +;;; +MASTER_ICW2 equ 0x30 ; use ints 0x30..0x37 +SLAVE_ICW2 equ 0x38 ; use ints 0x38..0x3F + +;;; +;;; ICW3 to the master tells it which of its IR pins is connected to the +;;; slave PIC. ICW3 to the slave tells its id number. +;;; +MASTER_ICW3 equ 0x04 ; slave on IR pin 2 +SLAVE_ICW3 equ 0x02 ; slave id=2 + +;;; +;;; ICW4 to both PICs is another bitvector to set some features: +;;; +;;; +;;; F E D C B A 9 8 | 7 6 5 4 3 2 1 0 +;;; (not used) | ---- | |__ 0=MCS80/85 1=8086/88 +;;; | | |_____ 0=normal 1=auto EOI +;;; | |_________ 00=non-buf mode +;;; | 10=buf mode, slave +;;; | 11=buf mode, master +;;; |______________ 0=!nested 1=nested +;;; +BOTH_ICW4 equ 0x01 + +HalInterruptInitializePICs: + mov al, BOTH_ICW1 + out 0x20, al ; ICW1 to master PIC + call HalIoDelay + out 0xA0, al ; ICW1 to slave PIC + call HalIoDelay + + mov al, MASTER_ICW2 + out 0x21, al ; ICW2 to master PIC + call HalIoDelay + mov al, SLAVE_ICW2 + out 0xA1, al ; ICW2 to slave PIC + call HalIoDelay + + mov al, MASTER_ICW3 + out 0x21, al ; ICW3 to master PIC + call HalIoDelay + mov al, SLAVE_ICW3 + out 0xA1, al ; ICW3 to slave PIC + call HalIoDelay + + mov al, BOTH_ICW4 + out 0x21, al ; ICW4 to master PIC + call HalIoDelay + out 0xA1, al ; ICW4 to slave PIC + call HalIoDelay + +;;; +;;; After the four ICW sequence has been completed any subsequent writes +;;; to port 0x21 or 0xA1 set the IRQ mask for the master/slave PIC. If +;;; this mask is 0xFF all IRQs are disabled. If this mask is 0x00 +;;; all IRQs are enabled. +;;; + mov al, 0xff ; slave PIC cannot interrupt + out 0xA1, al + call HalIoDelay + mov al, 0xfb ; mask all IRQs but 2 (the slave PIC) in master + out 0x21, al + call HalIoDelay + ret + +;;; +;;; When doing I/O operations this routine can be used to "delay" long +;;; enough to let the external controller keep up with the cpu. +;;; +HalIoDelay: + jmp .done +.done: ret + +;;; +;;; This is the start of the main interrupt handler code. The first section +;;; of this code is called the InterruptHandlerPreamble. It consists of +;;; 256 entry points in a table (one per possible interrupt number). These +;;; preamble entry points push the interrupt number and (when needed for +;;; interrupt numbers that the processor doesn't automatically push an error +;;; code for) a fake error code. Then they jump to the main generic interrupt +;;; handling routing: InterruptGenericHandler. Thus the stack is always layed +;;; out in the same way when control passes to the generic handler: +;;; +;;; saved ss (pushed by cpu for system calls) +;;; saved esp (pushed by cpu for system calls) +;;; ------------ +;;; saved eflags (pushed by cpu) +;;; saved CS (pushed by cpu) +;;; saved IP (pushed by cpu) +;;; error code (pushed by preamble or cpu) +;;; interrupt number (pushed by preamble) +;;; esp --> return address (pushed by jmp InteruptGenericHandler) +;;; +;;; The first thing InterruptGenericHandler does is push the rest of the +;;; registers onto the stack. +;;; +align 8 +HalInterruptHandlerPreamble: +HalInterruptHandlerPreambleBefore: + INT_NO_ERROR 0 + align 8 +HalInterruptHandlerPreambleAfter: + INT_NO_ERROR 1 + INT_NO_ERROR 2 + INT_NO_ERROR 3 + INT_NO_ERROR 4 + INT_NO_ERROR 5 + INT_NO_ERROR 6 + INT_NO_ERROR 7 + INT_WITH_ERROR 8 + INT_NO_ERROR 9 + INT_WITH_ERROR 10 + INT_WITH_ERROR 11 + INT_WITH_ERROR 12 + INT_WITH_ERROR 13 + INT_WITH_ERROR 14 + INT_NO_ERROR 15 + INT_NO_ERROR 16 + INT_WITH_ERROR 17 + +;;; +;;; The rest of the interrupt numbers are INT_NO_ERRORs. Use nasm's +;;; %rep command to do them all at once. +;;; +%assign intNum 18 +%rep (256 - 18) + INT_NO_ERROR intNum +%assign intNum intNum + 1 +%endrep + +;;; +;;; This is the generic interrupt handler which is called by the preambles +;;; above. It's job is to save the registers on the stack and then transfer +;;; control to a specific per-interrupt handler. It finds the address of +;;; the per-interrupt handler to call by indexing into g_InterruptHandlerTable +;;; +align 8 +HalInterruptGenericHandler: + SAVE_REGISTERS + + ;; Ensure that we're using the kernel data segment + mov ax, (2<<3) + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ;; Get interrupt number the preamble pushed for us + mov esi, [esp+44] + + ;; Get the address of the handler function from the + ;; table of handler functions. + mov eax, g_InterruptHandlerTable + mov ebx, [eax+esi*4] + + ;; Call the handler. The argument passed is a pointer to + ;; INTERRUPT_STATE. Interrupts are enabled at this point + ;; so if the handler is non-reentrant it must disable them. + push esp + call ebx + add esp, 4 + + push esp + call HalInterruptSendIrqEoi + add esp, 4 + + RESTORE_REGISTERS + iret diff --git a/kernel/hal/io.c b/kernel/hal/io.c new file mode 100644 index 0000000..d97a211 --- /dev/null +++ b/kernel/hal/io.c @@ -0,0 +1,40 @@ +#include "kernel.h" + +// Write a byte to an I/O port. +void +out(WORD port, BYTE value ) +{ + __asm__ __volatile__ ( + "outb %b0, %w1" + : + : "a" (value), "Nd" (port) + ); +} + +// Read a byte from an I/O port. +BYTE +in(WORD port) +{ + BYTE value; + + __asm__ __volatile__ ( + "inb %w1, %b0" + : "=a" (value) + : "Nd" (port) + ); + + return value; +} + +// Short delay. May be needed when talking to some +// (slow) I/O devices. +void +iodelay(void) +{ + BYTE value = 0; + __asm__ __volatile__ ( + "outb %0, $0x80" + : + : "a" (value) + ); +} diff --git a/kernel/hal/timer.c b/kernel/hal/timer.c new file mode 100644 index 0000000..3c82691 --- /dev/null +++ b/kernel/hal/timer.c @@ -0,0 +1,43 @@ +//+---------------------------------------------------------------------------- +// +// File: timer.c +// +// Module: +// +// Synopsis: +// +// Created: sgasch 21 Oct 2003 +// +//+---------------------------------------------------------------------------- + +#include "kernel.h" +#include "hal.h" +#include "rtl.h" +#include "interrupts.h" + +void +HalTimerInt(INTERRUPT_STATE *is) +{ + static CHAR whee[] = "|/-\\\0"; + static ULONG u = 0; + static BYTE b = 0; + static unsigned int foo; + BYTE *p = (BYTE *)0x000B8000; + + out(0x61, 0x80); + u++; + + CURRENT_STAMP(&foo); + + if ((u % 500) == 0) + { + b++; + if (whee[b] == '\0') + { + b = 0; + } + *(p + 158) = whee[b]; + *(p + 159) = ' '; + } +} + diff --git a/kernel/hal/timestamp.asm b/kernel/hal/timestamp.asm new file mode 100644 index 0000000..b56bedb --- /dev/null +++ b/kernel/hal/timestamp.asm @@ -0,0 +1,19 @@ + + [BITS 32] + +GLOBAL HalReadTimestampCounter +EXTERN g_ullTimeStampCounter + +[SECTION .text] +;;; +;;; ULONGLONG +;;; HalReadTimestampCounter(void) +;;; +;;; Function to read the processor's timestamp counter +;;; +HalReadTimestampCounter: + ALIGN 4 + rdtsc + mov [g_ullTimeStampCounter], edx + mov [g_ullTimeStampCounter+4], eax + ret diff --git a/kernel/hal/video.h b/kernel/hal/video.h new file mode 100644 index 0000000..dcd7b01 --- /dev/null +++ b/kernel/hal/video.h @@ -0,0 +1,15 @@ +//+---------------------------------------------------------------------------- +// +// File: video.h +// +// Module: +// +// Synopsis: +// +// Created: sgasch 5 Jul 2003 +// +//+---------------------------------------------------------------------------- +#ifndef VIDEO_H +#define VIDEO_H + +#endif // VIDEO_H -- cgit v1.3