#include <internal/ps.h>
#include <internal/string.h>
#include <internal/hal.h>
-#include <internal/hal/segment.h>
-#include <internal/hal/page.h>
+#include <internal/i386/segment.h>
+#include <internal/mmhal.h>
#define NDEBUG
#include <internal/debug.h>
static char null_ldt[8]={0,};
static unsigned int null_ldt_sel=0;
-static PKTHREAD FirstThread=NULL;
+static PETHREAD FirstThread=NULL;
/* FUNCTIONS **************************************************************/
* again
*/
{
+ DPRINT("Scheduling thread %x\n",thread);
DPRINT("Scheduling thread %x\n",thread->Context.nr);
DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",
thread->Context.previous_task,thread->Context.reserved1,
: /* No outputs */
: "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )
: "ax","dx");
-// set_breakpoint(0,&(FirstThread->Context.gs),HBP_READWRITE,HBP_DWORD);
}
static unsigned int allocate_tss_descriptor(void)
for(;;);
}
-BOOLEAN HalInitTask(PKTHREAD thread, PKSTART_ROUTINE fn,
- PVOID StartContext)
+#define FLAG_NT (1<<14)
+#define FLAG_VM (1<<17)
+#define FLAG_IF (1<<9)
+#define FLAG_IOPL ((1<<12)+(1<<13))
+
+NTSTATUS KeValidateUserContext(PCONTEXT Context)
+/*
+ * FUNCTION: Validates a processor context
+ * ARGUMENTS:
+ * Context = Context to validate
+ * RETURNS: Status
+ * NOTE: This only validates the context as not violating system security, it
+ * doesn't guararantee the thread won't crash at some point
+ * NOTE2: This relies on there only being two selectors which can access
+ * system space
+ */
+{
+ if (Context->Eip >= KERNEL_BASE)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegCs == KERNEL_CS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegDs == KERNEL_DS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegEs == KERNEL_DS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegFs == KERNEL_DS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegGs == KERNEL_DS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if ((Context->EFlags & FLAG_IOPL) != 0 ||
+ (Context->EFlags & FLAG_NT) ||
+ (Context->EFlags & FLAG_VM) ||
+ (!(Context->EFlags & FLAG_IF)))
+ {
+ return(STATUS_SUCCESS);
+ }
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
+/*
+ * FUNCTION: Initialize a task with a user mode context
+ * ARGUMENTS:
+ * Thread = Thread to initialize
+ * Context = Processor context to initialize it with
+ * RETURNS: Status
+ */
+{
+ unsigned int desc;
+ unsigned int length;
+ unsigned int base;
+ unsigned int* kernel_stack;
+ NTSTATUS Status;
+
+ DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",
+ Thread,Context);
+
+ assert(sizeof(hal_thread_state)>=0x68);
+
+ if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ desc = allocate_tss_descriptor();
+ length = sizeof(hal_thread_state) - 1;
+ base = (unsigned int)(&(Thread->Tcb.Context));
+ kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);
+
+ /*
+ * Setup a TSS descriptor
+ */
+ gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
+ gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
+ | (base & 0xff000000);
+
+ /*
+ * Initialize the thread context
+ */
+ memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));
+ Thread->Tcb.Context.ldt = null_ldt_sel;
+ Thread->Tcb.Context.eflags = Context->EFlags;
+ Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
+ Thread->Tcb.Context.esp0 = (ULONG)&kernel_stack[1021];
+ Thread->Tcb.Context.ss0 = KERNEL_DS;
+ Thread->Tcb.Context.esp = Context->Esp;
+ Thread->Tcb.Context.ss = Context->SegSs;
+ Thread->Tcb.Context.cs = Context->SegCs;
+ Thread->Tcb.Context.eip = Context->Eip;
+ Thread->Tcb.Context.io_bitmap[0] = 0xff;
+ Thread->Tcb.Context.cr3 =
+ linear_to_physical(Thread->ThreadsProcess->Pcb.PageTableDirectory);
+ Thread->Tcb.Context.ds = Context->SegDs;
+ Thread->Tcb.Context.es = Context->SegEs;
+ Thread->Tcb.Context.fs = Context->SegFs;
+ Thread->Tcb.Context.gs = Context->SegGs;
+ Thread->Tcb.Context.eax = Context->Eax;
+ Thread->Tcb.Context.ebx = Context->Ebx;
+ Thread->Tcb.Context.ecx = Context->Ecx;
+ Thread->Tcb.Context.edx = Context->Edx;
+ Thread->Tcb.Context.edi = Context->Edi;
+ Thread->Tcb.Context.esi = Context->Esi;
+ Thread->Tcb.Context.ebp = Context->Ebp;
+
+ Thread->Tcb.Context.nr = desc * 8;
+ DPRINT("Allocated %x\n",desc*8);
+
+ return(STATUS_SUCCESS);
+}
+
+BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
/*
* FUNCTION: Initializes the HAL portion of a thread object
* ARGUMENTS:
{
unsigned int desc = allocate_tss_descriptor();
unsigned int length = sizeof(hal_thread_state) - 1;
- unsigned int base = (unsigned int)(&(thread->Context));
+ unsigned int base = (unsigned int)(&(thread->Tcb.Context));
unsigned int* kernel_stack = ExAllocatePool(NonPagedPool,4096);
DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",
thread,fn,StartContext);
-
+ DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);
+
/*
* Make sure
*/
/*
* Initialize the thread context
*/
- memset(&thread->Context,0,sizeof(hal_thread_state));
- thread->Context.ldt = null_ldt_sel;
- thread->Context.eflags = (1<<1)+(1<<9);
- thread->Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
- thread->Context.esp0 = &kernel_stack[1021];
- thread->Context.ss0 = KERNEL_DS;
- thread->Context.esp = &kernel_stack[1021];
- thread->Context.ss = KERNEL_DS;
- thread->Context.cs = KERNEL_CS;
- thread->Context.eip = (unsigned long)begin_thread;
- thread->Context.io_bitmap[0] = 0xff;
- thread->Context.cr3 = ((unsigned int)get_page_directory()) - IDMAP_BASE;
- thread->Context.ds = KERNEL_DS;
- thread->Context.es = KERNEL_DS;
- thread->Context.fs = KERNEL_DS;
- thread->Context.gs = KERNEL_DS;
- thread->Context.nr = desc * 8;
+ memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));
+ thread->Tcb.Context.ldt = null_ldt_sel;
+ thread->Tcb.Context.eflags = (1<<1)+(1<<9);
+ thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
+ thread->Tcb.Context.esp0 = &kernel_stack[1021];
+ thread->Tcb.Context.ss0 = KERNEL_DS;
+ thread->Tcb.Context.esp = &kernel_stack[1021];
+ thread->Tcb.Context.ss = KERNEL_DS;
+ thread->Tcb.Context.cs = KERNEL_CS;
+ thread->Tcb.Context.eip = (unsigned long)begin_thread;
+ thread->Tcb.Context.io_bitmap[0] = 0xff;
+ thread->Tcb.Context.cr3 =
+ linear_to_physical(thread->ThreadsProcess->Pcb.PageTableDirectory);
+ thread->Tcb.Context.ds = KERNEL_DS;
+ thread->Tcb.Context.es = KERNEL_DS;
+ thread->Tcb.Context.fs = KERNEL_DS;
+ thread->Tcb.Context.gs = KERNEL_DS;
+ thread->Tcb.Context.nr = desc * 8;
DPRINT("Allocated %x\n",desc*8);
return(TRUE);
}
-void HalInitFirstTask(PKTHREAD thread)
+void HalInitFirstTask(PETHREAD thread)
/*
* FUNCTION: Called to setup the HAL portion of a thread object for the
* initial thread
*/
__asm__("ltr %%ax"
: /* no output */
- : "a" (thread->Context.nr));
+ : "a" (thread->Tcb.Context.nr));
FirstThread = thread;
}