Пример #1
0
void cpu_init_idt(void)
{
	struct region_descriptor region;

	setregion(&region, idt, NIDT * sizeof(idt[0]) - 1);
	lidt(&region); 
}
Пример #2
0
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void
idt_init(void) {
     /* LAB1 YOUR CODE : STEP 2 */
     /* (1) Where are the entry addrs of each Interrupt Service Routine (ISR)?
      *     All ISR's entry addrs are stored in __vectors. where is uintptr_t __vectors[] ?
      *     __vectors[] is in kern/trap/vector.S which is produced by tools/vector.c
      *     (try "make" command in lab1, then you will find vector.S in kern/trap DIR)
      *     You can use  "extern uintptr_t __vectors[];" to define this extern variable which will be used later.
      * (2) Now you should setup the entries of ISR in Interrupt Description Table (IDT).
      *     Can you see idt[256] in this file? Yes, it's IDT! you can use SETGATE macro to setup each item of IDT
      * (3) After setup the contents of IDT, you will let CPU know where is the IDT by using 'lidt' instruction.
      *     You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more.
      *     Notice: the argument of lidt is idt_pd. try to find it!
      */
    extern uintptr_t __vectors[];
    int i;
    int k;
     k=sizeof(idt)/sizeof(struct gatedesc);
    for (i = 0; i < k; i ++) {
        SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
    }
    SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER);

    lidt(&idt_pd);
}
Пример #3
0
void InterruptUtils::initialise()
{
  // allocate some memory for our handlers
  GateDesc *interrupt_gates = new GateDesc[NUM_INTERRUPT_HANDLERS];

  for (uint32 i = 0; i < NUM_INTERRUPT_HANDLERS; ++i)
  {
    interrupt_gates[i].offset_low = LO_WORD(handlers[i].offset);
    interrupt_gates[i].offset_high = HI_WORD(handlers[i].offset);
    interrupt_gates[i].gate_size = GATE_SIZE_32_BIT;
    interrupt_gates[i].present = 1;
    interrupt_gates[i].reserved = 0;
    interrupt_gates[i].segment_selector = KERNEL_CS;
    interrupt_gates[i].type = TYPE_INTERRUPT_GATE;
    interrupt_gates[i].unused = 0;
    interrupt_gates[i].zeros = 0;
    interrupt_gates[i].dpl = (handlers[i].number == SYSCALL_INTERRUPT ?
        DPL_USER_SPACE : DPL_KERNEL_SPACE);
  }

  IDTR idtr;

  idtr.base =  (uint32)interrupt_gates;
  idtr.limit = sizeof(GateDesc)*NUM_INTERRUPT_HANDLERS - 1;
  lidt(&idtr);
}
Пример #4
0
void InterruptUtils::initialise()
{
  uint32 num_handlers = 0;
  for (uint32 i = 0; handlers[i].offset != 0; ++i)
    num_handlers = handlers[i].number;
  ++num_handlers;
  // allocate some memory for our handlers
  GateDesc *interrupt_gates = new GateDesc[num_handlers];

  uint32 j = 0;
  for (uint32 i = 0; i < num_handlers; ++i)
  {
    while (handlers[j].number < i && handlers[j].offset != 0)
      ++j;
    interrupt_gates[i].offset_low = LO_WORD((handlers[j].number == i && handlers[j].offset != 0) ? handlers[j].offset : arch_dummyHandler);
    interrupt_gates[i].offset_high = HI_WORD((handlers[j].number == i && handlers[j].offset != 0) ? handlers[j].offset : arch_dummyHandler);
    interrupt_gates[i].gate_size = GATE_SIZE_32_BIT;
    interrupt_gates[i].present = 1;
    interrupt_gates[i].reserved = 0;
    interrupt_gates[i].segment_selector = KERNEL_CS;
    interrupt_gates[i].type = TYPE_INTERRUPT_GATE;
    interrupt_gates[i].unused = 0;
    interrupt_gates[i].zeros = 0;
    interrupt_gates[i].dpl = ((i == SYSCALL_INTERRUPT && handlers[j].number == i) ? DPL_USER_SPACE : DPL_KERNEL_SPACE);
  }

  IDTR idtr;

  idtr.base = (uint32) interrupt_gates;
  idtr.limit = sizeof(GateDesc) * num_handlers - 1;
  lidt(&idtr);
}
Пример #5
0
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void
idt_init(void) {
     /* LAB1 2011011384 : STEP 2 */
     /* (1) Where are the entry addrs of each Interrupt Service Routine (ISR)?
      *     All ISR's entry addrs are stored in __vectors. where is uintptr_t __vectors[] ?
      *     __vectors[] is in kern/trap/vector.S which is produced by tools/vector.c
      *     (try "make" command in lab1, then you will find vector.S in kern/trap DIR)
      *     You can use  "extern uintptr_t __vectors[];" to define this extern variable which will be used later.
      * (2) Now you should setup the entries of ISR in Interrupt Description Table (IDT).
      *     Can you see idt[256] in this file? Yes, it's IDT! you can use SETGATE macro to setup each item of IDT
      * (3) After setup the contents of IDT, you will let CPU know where is the IDT by using 'lidt' instruction.
      *     You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more.
      *     Notice: the argument of lidt is idt_pd. try to find it!
      */
    //the global descriptor table is loaded at bootasm.s
    //code seg is at 0x08
    extern uintptr_t __vectors[];
    int i;
    for(i = 0; i < 256; i++) {
        SETGATE(idt[i], 0, 0x08, __vectors[i], 0);
    }
    SETGATE(idt[T_SWITCH_TOU], 0, 0x08, __vectors[T_SWITCH_TOU], 3);
    SETGATE(idt[T_SWITCH_TOK], 0, 0x08, __vectors[T_SWITCH_TOK], 3);
    lidt(&idt_pd);
}
Пример #6
0
/*
 * AP cpu's call this to sync up protected mode.
 *
 * WARNING!  We must ensure that the cpu is sufficiently initialized to
 * be able to use to the FP for our optimized bzero/bcopy code before
 * we enter more mainstream C code.
 *
 * WARNING! %fs is not set up on entry.  This routine sets up %fs.
 */
void
init_secondary(void)
{
	int	gsel_tss;
	int	x, myid = bootAP;
	u_int	cr0;
	struct mdglobaldata *md;
	struct privatespace *ps;

	ps = &CPU_prvspace[myid];

	gdt_segs[GPRIV_SEL].ssd_base = (int)ps;
	gdt_segs[GPROC0_SEL].ssd_base =
		(int) &ps->mdglobaldata.gd_common_tss;
	ps->mdglobaldata.mi.gd_prvspace = ps;

	for (x = 0; x < NGDT; x++) {
		ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
	}

	r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
	r_gdt.rd_base = (int) &gdt[myid * NGDT];
	lgdt(&r_gdt);			/* does magic intra-segment return */

	lidt(&r_idt);

	lldt(_default_ldt);
	mdcpu->gd_currentldt = _default_ldt;

	gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
	gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS;

	md = mdcpu;	/* loaded through %fs:0 (mdglobaldata.mi.gd_prvspace)*/

	md->gd_common_tss.tss_esp0 = 0;	/* not used until after switch */
	md->gd_common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
	md->gd_common_tss.tss_ioopt = (sizeof md->gd_common_tss) << 16;
	md->gd_tss_gdt = &gdt[myid * NGDT + GPROC0_SEL].sd;
	md->gd_common_tssd = *md->gd_tss_gdt;
	ltr(gsel_tss);

	/*
	 * Set to a known state:
	 * Set by mpboot.s: CR0_PG, CR0_PE
	 * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM
	 */
	cr0 = rcr0();
	cr0 &= ~(CR0_CD | CR0_NW | CR0_EM);
	load_cr0(cr0);
	pmap_set_opt();		/* PSE/4MB pages, etc */

	/* set up CPU registers and state */
	cpu_setregs();

	/* set up FPU state on the AP */
	npxinit(__INITIAL_NPXCW__);

	/* set up SSE registers */
	enable_sse();
}
Пример #7
0
void InterruptUtils::initialise()
{
  uint32 num_handlers = 0;
  for (uint32 i = 0; handlers[i].offset != 0; ++i)
    num_handlers = handlers[i].number;
  ++num_handlers;
  // allocate some memory for our handlers
  GateDesc *interrupt_gates = new GateDesc[num_handlers];
  size_t dummy_handler_sled_size = (((size_t) arch_dummyHandlerMiddle) - (size_t) arch_dummyHandler);
  assert((dummy_handler_sled_size % 128) == 0 && "cannot handle weird padding in the kernel binary");
  dummy_handler_sled_size /= 128;

  uint32 j = 0;
  for (uint32 i = 0; i < num_handlers; ++i)
  {
    while (handlers[j].number < i && handlers[j].offset != 0)
      ++j;
    interrupt_gates[i].offset_low = LO_WORD((handlers[j].number == i && handlers[j].offset != 0) ? (size_t)handlers[j].offset : (((size_t)arch_dummyHandler)+i*dummy_handler_sled_size));
    interrupt_gates[i].offset_high = HI_WORD((handlers[j].number == i && handlers[j].offset != 0) ? (size_t)handlers[j].offset : (((size_t)arch_dummyHandler)+i*dummy_handler_sled_size));
    interrupt_gates[i].gate_size = GATE_SIZE_32_BIT;
    interrupt_gates[i].present = 1;
    interrupt_gates[i].reserved = 0;
    interrupt_gates[i].segment_selector = KERNEL_CS;
    interrupt_gates[i].type = TYPE_INTERRUPT_GATE;
    interrupt_gates[i].unused = 0;
    interrupt_gates[i].zeros = 0;
    interrupt_gates[i].dpl = ((i == SYSCALL_INTERRUPT && handlers[j].number == i) ? DPL_USER_SPACE : DPL_KERNEL_SPACE);
  }

  IDTR idtr;

  idtr.base = (uint32) interrupt_gates;
  idtr.limit = sizeof(GateDesc) * num_handlers - 1;
  lidt(&idtr);
}
Пример #8
0
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void
idt_init(void) {
     /* LAB1 2011010312 : STEP 2 */
     /* (1) Where are the entry addrs of each Interrupt Service Routine (ISR)?
      *     All ISR's entry addrs are stored in __vectors. where is uintptr_t __vectors[] ?
      *     __vectors[] is in kern/trap/vector.S which is produced by tools/vector.c
      *     (try "make" command in lab1, then you will find vector.S in kern/trap DIR)
      *     You can use  "extern uintptr_t __vectors[];" to define this extern variable which will be used later.
      * (2) Now you should setup the entries of ISR in Interrupt Description Table (IDT).
      *     Can you see idt[256] in this file? Yes, it's IDT! you can use SETGATE macro to setup each item of IDT
      * (3) After setup the contents of IDT, you will let CPU know where is the IDT by using 'lidt' instruction.
      *     You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more.
      *     Notice: the argument of lidt is idt_pd. try to find it!
      */
     /* LAB5 2011010312 */
     //you should update your lab1 code (just add ONE or TWO lines of code), let user app to use syscall to get the service of ucore
     //so you should setup the syscall interrupt gate in here
    extern uintptr_t __vectors[];
    int i;
    for(i = 0; i < 256; i++) {
        SETGATE(idt[i], 0, KERNEL_CS, __vectors[i], DPL_KERNEL);
    }
    SETGATE(idt[T_SYSCALL], 1, KERNEL_CS, __vectors[T_SYSCALL], DPL_USER);
    lidt(&idt_pd);
}
Пример #9
0
initevec()
{
	int		i;
	STATWORD	ps;

#ifdef __COM32__
	puts_com32("initevec() begin");
#endif
	for (i=0; i<NID; ++i)
		set_evec(i, (int)defevec[i]);
	/*
	 * "girmask" masks all (bus) interrupts with the default handler.
	 * initially, all, then cleared as handlers are set via set_evec()
	 */
	girmask = 0xfffb;	/* leave bit 2 enabled for IC cascade */

#ifdef __COM32__
	puts_com32("initevec() set_evec() done\n");
#endif
	lidt();

#ifdef __COM32__
	puts_com32("initevec() lidt() done\n");
#endif
	init8259();
	
#ifdef __COM32__
	puts_com32("initevec() init8259() done\n");
#endif
}
Пример #10
0
// Initialize and load the per-CPU TSS and IDT
void
trap_init_percpu(void)
{

	// The example code here sets up the Task State Segment (TSS) and
	// the TSS descriptor for CPU 0. But it is incorrect if we are
	// running on other CPUs because each CPU has its own kernel stack.
	// Fix the code so that it works for all CPUs.
	//
	// Hints:
	//   - The macro "thiscpu" always refers to the current CPU's
	//     struct CpuInfo;
	//   - The ID of the current CPU is given by cpunum() or
	//     thiscpu->cpu_id;
	//   - Use "thiscpu->cpu_ts" as the TSS for the current CPU,
	//     rather than the global "ts" variable;
	//   - Use gdt[(GD_TSS0 >> 3) + i] for CPU i's TSS descriptor;
	//   - You mapped the per-CPU kernel stacks in mem_init_mp()
	//
	// ltr sets a 'busy' flag in the TSS selector, so if you
	// accidentally load the same TSS on more than one CPU, you'll
	// get a triple fault.  If you set up an individual CPU's TSS
	// wrong, you may not get a fault until you try to return from
	// user space on that CPU.
	//
	// LAB 4: Your code here:
//------------  Lab4  ----------------------------------------------------------------------------------------		
	int cpuid = thiscpu->cpu_id;
	thiscpu->cpu_ts.ts_esp0 = KSTACKTOP - cpuid * (KSTKGAP + KSTKSIZE);
	thiscpu->cpu_ts.ts_ss0 = GD_KD;

	gdt[(GD_TSS0 >> 3) + cpuid] = SEG16(STS_T32A, (uint32_t) (&(thiscpu->cpu_ts)),
					sizeof(struct Taskstate), 0);
	gdt[(GD_TSS0 >> 3) + cpuid].sd_s = 0;

	ltr(GD_TSS0 + (cpuid << 3));

	lidt(&idt_pd);
	
//------------  Lab4  ----------------------------------------------------------------------------------------			
/*
	// Setup a TSS so that we get the right stack
	// when we trap to the kernel.
	ts.ts_esp0 = KSTACKTOP;
	ts.ts_ss0 = GD_KD;

	// Initialize the TSS slot of the gdt.
	gdt[GD_TSS0 >> 3] = SEG16(STS_T32A, (uint32_t) (&ts),
					sizeof(struct Taskstate), 0);
	gdt[GD_TSS0 >> 3].sd_s = 0;

	// Load the TSS selector (like other segment selectors, the
	// bottom three bits are special; we leave them 0)
	ltr(GD_TSS0);

	// Load the IDT
	lidt(&idt_pd);
*/	
}
Пример #11
0
static void
cpu_reset_real()
{
	struct region_descriptor null_idt;
	int b;

	disable_intr();

	/*
	 * Attempt to do a CPU reset via the keyboard controller,
	 * do not turn off GateA20, as any machine that fails
	 * to do the reset here would then end up in no man's land.
	 */
	outb(IO_KBD + 4, 0xFE);
	DELAY(500000);	/* wait 0.5 sec to see if that did it */

	/*
	 * Attempt to force a reset via the Reset Control register at
	 * I/O port 0xcf9.  Bit 2 forces a system reset when it
	 * transitions from 0 to 1.  Bit 1 selects the type of reset
	 * to attempt: 0 selects a "soft" reset, and 1 selects a
	 * "hard" reset.  We try a "hard" reset.  The first write sets
	 * bit 1 to select a "hard" reset and clears bit 2.  The
	 * second write forces a 0 -> 1 transition in bit 2 to trigger
	 * a reset.
	 */
	outb(0xcf9, 0x2);
	outb(0xcf9, 0x6);
	DELAY(500000);  /* wait 0.5 sec to see if that did it */

	/*
	 * Attempt to force a reset via the Fast A20 and Init register
	 * at I/O port 0x92.  Bit 1 serves as an alternate A20 gate.
	 * Bit 0 asserts INIT# when set to 1.  We are careful to only
	 * preserve bit 1 while setting bit 0.  We also must clear bit
	 * 0 before setting it if it isn't already clear.
	 */
	b = inb(0x92);
	if (b != 0xff) {
		if ((b & 0x1) != 0)
			outb(0x92, b & 0xfe);
		outb(0x92, b | 0x1);
		DELAY(500000);  /* wait 0.5 sec to see if that did it */
	}

	printf("No known reset method worked, attempting CPU shutdown\n");
	DELAY(1000000);	/* wait 1 sec for printf to complete */

	/* Wipe the IDT. */
	null_idt.rd_limit = 0;
	null_idt.rd_base = 0;
	lidt(&null_idt);

	/* "good night, sweet prince .... <THUNK!>" */
	breakpoint();

	/* NOTREACHED */
	while(1);
}
Пример #12
0
void load_idtr()
{
    idtr.limit  = 256*(sizeof(IDT_t)-1);
    idtr.base   = idt;

	// load IDTR with lidt
	lidt(&idtr);
}
Пример #13
0
void
idt_init(void) {
    extern uintptr_t __vectors[];
    int i;
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
        SETGATE(idt[i], 1, GD_KTEXT, __vectors[i], DPL_KERNEL);
    }
    SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER);
    lidt(&idt_pd);
}
Пример #14
0
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void
idt_init(void) {
    extern uintptr_t __vectors[];
    int i;
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
        SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
    }

    // load the IDT
    lidt(&idt_pd);
}
Пример #15
0
/*
* void populate_idt();
*   Inputs: none
*   Return Value: void
*	Function: Fills the idt with the correct functions
*/
void populate_idt()
{
	int i;
	/*initializing the specific interrupts 0 - 20*/ 
	void (* arr[NUM_VEC]) = 
	{ &divide_by_zero, &reserved_1, &non_maskable_interrupt, 
	&breakpoint, &overflow, &BOUND_range_exceeded, &invalid_opcode,
	&device_not_available, &double_fault, &coprocessor_segment_overrun, 
	&invalid_TSS, &segment_not_present, &stack_segment_fault, &general_protection,
	&page_fault, &common_interrupt, &floating_point_error, &alignment_check, 
	&machine_check, &SIMD_floating_point_exception
	};

	/*iterating through idt, populating with correct interrupts*/
	for(i = 0; i< NUM_VEC; i++)
	{
		idt[i].present = 1;
		idt[i].dpl = 0;
		idt[i].reserved0 = 0;
		idt[i].size = 1;
		idt[i].reserved1 = 1;
		idt[i].reserved2 = 1;
		idt[i].reserved3 = 0;
		idt[i].reserved4 = 0;
		idt[i].seg_selector = KERNEL_CS;

		/*Do not set IDT_ENTRY for 20 - 32 (Intel Reserved) */ 
		if(i >= EXCEPTION_INDEX) 
		{
			/*Set common interrupt for user defined*/ 
			SET_IDT_ENTRY(idt[i],&common_interrupt);	
		}
		else if(i < 20)
		{
			if( i == 15 )
			{
				/*DO NOTHING, Intel Reserved*/ 
			}else{
				SET_IDT_ENTRY(idt[i], arr[i]); 
			}	
		}
	}
	/*setting more specific interrupts*/ 
	SET_IDT_ENTRY(idt[RTC_INDEX],&asm_rtc);
	SET_IDT_ENTRY(idt[KEYBOARD_INDEX],&asm_keyboard);
	SET_IDT_ENTRY(idt[SYS_CALLS_INDEX],&syscall);
	idt[SYS_CALLS_INDEX].dpl = 3;
	idt[SYS_CALLS_INDEX].reserved3 = 1;
	SET_IDT_ENTRY(idt[PIT_INDEX],&next_task);

	/*loading IDTR*/ 
	lidt(idt_desc_ptr);
}
Пример #16
0
void initevec(void)
{
	int		i;

        /* bzero( idt, sizeof( struct idt ) * 256 ); */
	memset( idt, 0, sizeof( struct idt ) * 256 ); 

	for (i=0; i<NID; ++i)
		set_evec(i, (long)defevec[i]);

	lidt();
	init8259();
	set_exception=&set_evec;
}
Пример #17
0
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void
idt_init(void) {
    extern uintptr_t __vectors[];
    int i;
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
        SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
    }

    // set for switch from user to kernel
    SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER);

    // load the IDT
    lidt(&idt_pd);
}
Пример #18
0
void trap_init_percpu()
{
	extern struct seg_descriptor gdt[CPUNUMS + 5];
	extern int ncpu;
	uint32_t cid = get_cpuid();
	struct taskstate *pts = &(thiscpu->cpu_ts);
	//pts->ts_esp0 = KERNEL_STACKTOP - (KERNEL_STKSIZE + KERNEL_STKGAP) * cid;
	pts->ts_esp0 = KERN_STACKTOP;
	pts->ts_ss0 = _KERNEL_DS_;

	gdt[(_TSS0_ >> 3) + cid] = set_seg(STS_T32A, (uint32_t) (pts), sizeof(struct taskstate), 0);
	gdt[(_TSS0_ >> 3) + cid].s = 0;
	
	ltr(_TSS0_ + cid * sizeof(struct seg_descriptor));
	lidt(&idt_pd);
}
Пример #19
0
int initevec()
{
	int		i;

	for (i=0; i<NID; ++i)
		set_evec(i, (long)defevec[i]);
	/*
	 * "girmask" masks all (bus) interrupts with the default handler.
	 * initially, all, then cleared as handlers are set via set_evec()
	 */
	girmask = 0xfffb;	/* leave bit 2 enabled for IC cascade */

	lidt();
	init8259();
        return(OK);
}
Пример #20
0
// Initialize and load the per-CPU TSS and IDT
void
trap_init_percpu(void)
{
	// Setup a TSS so that we get the right stack
	// when we trap to the kernel.  
        ts.ts_esp0 = KSTACKTOP;

	// Initialize the TSS slot of the gdt.
	SETTSS((struct SystemSegdesc64 *)((gdt_pd>>16)+40),STS_T64A, (uint64_t) (&ts),sizeof(struct Taskstate), 0);
	// Load the TSS selector (like other segment selectors, the
	// bottom three bits are special; we leave them 0)
	ltr(GD_TSS0);

	// Load the IDT
	lidt(&idt_pd);
}
Пример #21
0
/** Reboot the system. */
void platform_reboot(void) {
	uint8_t val;

	/* Try the keyboard controller. */
	do {
		val = in8(0x64);
		if(val & (1<<0)) {
			in8(0x60);
		}
	} while(val & (1<<1));
	out8(0x64, 0xfe);
	spin(5000);

	/* Fall back on a triple fault. */
	lidt(0, 0);
	__asm__ volatile("ud2");
}
Пример #22
0
// Initialize and load the per-CPU TSS and IDT
void
trap_init_percpu(void)
{
	// The example code here sets up the Task State Segment (TSS) and
	// the TSS descriptor for CPU 0. But it is incorrect if we are
	// running on other CPUs because each CPU has its own kernel stack.
	// Fix the code so that it works for all CPUs.
	//
	// Hints:
	//   - The macro "thiscpu" always refers to the current CPU's
	//     struct CpuInfo;
	//   - The ID of the current CPU is given by cpunum() or
	//     thiscpu->cpu_id;
	//   - Use "thiscpu->cpu_ts" as the TSS for the current CPU,
	//     rather than the global "ts" variable;
	//   - Use gdt[(GD_TSS0 >> 3) + 2*i] for CPU i's TSS descriptor;
	//   - You mapped the per-CPU kernel stacks in mem_init_mp()
	//
	// ltr sets a 'busy' flag in the TSS selector, so if you
	// accidentally load the same TSS on more than one CPU, you'll
	// get a triple fault.  If you set up an individual CPU's TSS
	// wrong, you may not get a fault until you try to return from
	// user space on that CPU.
	//
	// LAB 4: Your code here:

	// Setup a TSS so that we get the right stack
	// when we trap to the kernel.
	int id = thiscpu->cpu_id;
	size_t kstacktop_ncpus = KSTACKTOP - id*(KSTKSIZE+KSTKGAP);
	thiscpu->cpu_ts.ts_esp0 = kstacktop_ncpus;
	SETTSS((struct SystemSegdesc64 *)(&gdt[(GD_TSS0>>3)+2*id]),STS_T64A, (uint64_t) (&thiscpu->cpu_ts),sizeof(struct Taskstate), 0);
	/*
	ts.ts_esp0 = KSTACKTOP;

	// Initialize the TSS slot of the gdt.
	SETTSS((struct SystemSegdesc64 *)((gdt_pd>>16)+40),STS_T64A, (uint64_t) (&ts),sizeof(struct Taskstate), 0);
	// Load the TSS selector (like other segment selectors, the
	// bottom three bits are special; we leave them 0)	*/
	ltr(GD_TSS0 + ((2*id << 3) & (~0x7)));
	//ltr(GD_TSS0+2*id);
	
	// Load the IDT
	lidt(&idt_pd);
}
Пример #23
0
// Initialize and load the per-CPU TSS and IDT
void
trap_init_percpu(void)
{
	// Setup a TSS so that we get the right stack
	// when we trap to the kernel.
	ts.ts_esp0 = KSTACKTOP;
	ts.ts_ss0 = GD_KD;

	// Initialize the TSS slot of the gdt.
	gdt[GD_TSS0 >> 3] = SEG16(STS_T32A, (uint32_t) (&ts),
					sizeof(struct Taskstate) - 1, 0);
	gdt[GD_TSS0 >> 3].sd_s = 0;

	// Load the TSS selector (like other segment selectors, the
	// bottom three bits are special; we leave them 0)
	ltr(GD_TSS0);

	// Load the IDT
	lidt(&idt_pd);
}
Пример #24
0
int
setup_idt (void)
{
    uint_t i;

    ulong_t irq_start = (ulong_t)&early_irq_handlers;
    ulong_t excp_start = (ulong_t)&early_excp_handlers;

    // clear the IDT out
    memset(&idt64, 0, sizeof(struct gate_desc64) * NUM_IDT_ENTRIES);

    for (i = 0; i < NUM_EXCEPTIONS; i++) {
        set_intr_gate(idt64, i, (void*)(excp_start + i*16));
        idt_assign_entry(i, (ulong_t)null_excp_handler);
    }

    for (i = 32; i < NUM_IDT_ENTRIES; i++) {
        set_intr_gate(idt64, i, (void*)(irq_start + (i-32)*16));
        idt_assign_entry(i, (ulong_t)null_irq_handler);
    }

    if (idt_assign_entry(PF_EXCP, (ulong_t)nk_pf_handler) < 0) {
        ERROR_PRINT("Couldn't assign page fault handler\n");
        return -1;
    }

    if (idt_assign_entry(DF_EXCP, (ulong_t)df_handler) < 0) {
        ERROR_PRINT("Couldn't assign double fault handler\n");
        return -1;
    }

    if (idt_assign_entry(0xf, (ulong_t)pic_spur_int_handler) < 0) {
        ERROR_PRINT("Couldn't assign PIC spur int handler\n");
        return -1;
    }

    lidt(&idt_descriptor);

    return 0;
}
Пример #25
0
void i86_idt_init(void)
{
    memset(IDT32, 0, IDT32_NB_DESCRIPTORS * sizeof(idt_descriptor_t));

    // all interrupts are initialized as interrupt gates and only can be executed
    // with ring 0's priviledges.
    idt_descriptor_flags_t flags;
    memset(&flags, 0, sizeof(idt_descriptor_flags_t));

    flags.gate_type = IDT_DESC_TYPE_32BIT_INTERRUPT_GATE;
    flags.privilege_level = IDT_DESC_PRIVILEGE_RING_0;
    flags.present = IDT_DESC_PRESENT_IN_MEMORY;

    for (uint16_t i=0; i<IDT32_NB_DESCRIPTORS; ++i) {

        if (IDT32_PIC1_INT_VECT_OFFSET <= i
                && i < IDT32_PIC1_INT_VECT_OFFSET + PIC1INTNBR) {
            idt_desc_init(ISR32_SEG, _asm_default_pic1_int, flags, &IDT32[i]);

        } else if (IDT32_PIC1_INT_VECT_OFFSET <= i
                && i < IDT32_PIC1_INT_VECT_OFFSET + PIC1INTNBR) {
            idt_desc_init(ISR32_SEG, _asm_default_pic2_int, flags, &IDT32[i]);

        } else {
            idt_desc_init(ISR32_SEG, _asm_default_int, flags, &IDT32[i]);
        }
    }

    cntxt_p_mode_32bit.ptr_idt.base = (uint32_t) &IDT32;
    cntxt_p_mode_32bit.ptr_idt.limit = sizeof(idt_descriptor_t) * IDT32_NB_DESCRIPTORS;

    // load the 32-bit IDT's pointer
    lidt(&cntxt_p_mode_32bit.ptr_idt);
#ifdef DEBUG_IDT
    debug_printf("IDT: ridt=%#08x, base=%#08x, limit=%#x\r\n",
            &cntxt_p_mode_32bit.ptr_idt,
            cntxt_p_mode_32bit.ptr_idt.base,
            cntxt_p_mode_32bit.ptr_idt.limit);
#endif
}
Пример #26
0
// Initialize and load the per-CPU TSS and IDT
void
trap_init_percpu(void)
{
	// The example code here sets up the Task State Segment (TSS) and
	// the TSS descriptor for CPU 0. But it is incorrect if we are
	// running on other CPUs because each CPU has its own kernel stack.
	// Fix the code so that it works for all CPUs.
	//
	// Hints:
	//   - The macro "thiscpu" always refers to the current CPU's
	//     struct Cpu;
	//   - The ID of the current CPU is given by cpunum() or
	//     thiscpu->cpu_id;
	//   - Use "thiscpu->cpu_ts" as the TSS for the current CPU,
	//     rather than the global "ts" variable;
	//   - Use gdt[(GD_TSS0 >> 3) + 2*i] for CPU i's TSS descriptor;
	//   - You mapped the per-CPU kernel stacks in mem_init_mp()
	//
	// ltr sets a 'busy' flag in the TSS selector, so if you
	// accidentally load the same TSS on more than one CPU, you'll
	// get a triple fault.  If you set up an individual CPU's TSS
	// wrong, you may not get a fault until you try to return from
	// user space on that CPU.
	//
	// Ashish

	thiscpu->cpu_ts.ts_esp0 = KSTACKTOP - thiscpu->cpu_id * (KSTKSIZE + KSTKGAP);
	SETTSS((struct SystemSegdesc64 *)(&(gdt[(GD_TSS0 >> 3)+thiscpu->cpu_id * 2])), // We want the TSS0 at 0x28, TSS1 at 0x38, TSS2 at 0x48, etc
										       // The size of gdt is 2*NCPU+5 because - 2bytes for tss of each cpu

	// Initialize the TSS slot of the gdt.
		STS_T64A, (uint64_t) (&(thiscpu->cpu_ts)), sizeof(struct Taskstate), 0);
	// Load the TSS selector (like other segment selectors, the
	// bottom three bits are special; we leave them 0)
	ltr(GD_TSS0+(thiscpu->cpu_id * 8 * 2)); // Byte offset of TSSs

	// Load the IDT
	lidt(&idt_pd);
}
Пример #27
0
void
idtinit(void)
{
  lidt(idt, sizeof(idt));
}
Пример #28
0
/* Check if MAGIC is valid and print the Multiboot information structure
   pointed by ADDR. */
void
entry (unsigned long magic, unsigned long addr)
{
	multiboot_info_t *mbi;

	/* Clear the screen. */
	clear();

	paging_init();

	/* Am I booted by a Multiboot-compliant boot loader? */
	if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
	{
		printf ("Invalid magic number: 0x%#x\n", (unsigned) magic);
		return;
	}

	/* Set MBI to the address of the Multiboot information structure. */
	mbi = (multiboot_info_t *) addr;

	/* Print out the flags. */
	printf ("flags = 0x%#x\n", (unsigned) mbi->flags);

	/* Are mem_* valid? */
	if (CHECK_FLAG (mbi->flags, 0))
		printf ("mem_lower = %uKB, mem_upper = %uKB\n",
				(unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);

	/* Is boot_device valid? */
	if (CHECK_FLAG (mbi->flags, 1))
		printf ("boot_device = 0x%#x\n", (unsigned) mbi->boot_device);

	/* Is the command line passed? */
	if (CHECK_FLAG (mbi->flags, 2))
		printf ("cmdline = %s\n", (char *) mbi->cmdline);

	if (CHECK_FLAG (mbi->flags, 3)) {
		int mod_count = 0;
		int i;
		module_t* mod = (module_t*)mbi->mods_addr;
		while(mod_count < mbi->mods_count) {
			printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start);
			printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end);
			printf("First few bytes of module:\n");
			for(i = 0; i<16; i++) {
				printf("0x%x ", *((char*)(mod->mod_start+i)));
			}
			printf("\n");
			mod_count++;
		}
	}
	/* Bits 4 and 5 are mutually exclusive! */
	if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
	{
		printf ("Both bits 4 and 5 are set.\n");
		return;
	}

	/* Is the section header table of ELF valid? */
	if (CHECK_FLAG (mbi->flags, 5))
	{
		elf_section_header_table_t *elf_sec = &(mbi->elf_sec);

		printf ("elf_sec: num = %u, size = 0x%#x,"
				" addr = 0x%#x, shndx = 0x%#x\n",
				(unsigned) elf_sec->num, (unsigned) elf_sec->size,
				(unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
	}

	/* Are mmap_* valid? */
	if (CHECK_FLAG (mbi->flags, 6))
	{
		memory_map_t *mmap;

		printf ("mmap_addr = 0x%#x, mmap_length = 0x%x\n",
				(unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
		for (mmap = (memory_map_t *) mbi->mmap_addr;
				(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
				mmap = (memory_map_t *) ((unsigned long) mmap
					+ mmap->size + sizeof (mmap->size)))
			printf (" size = 0x%x,     base_addr = 0x%#x%#x\n"
					"     type = 0x%x,  length    = 0x%#x%#x\n",
					(unsigned) mmap->size,
					(unsigned) mmap->base_addr_high,
					(unsigned) mmap->base_addr_low,
					(unsigned) mmap->type,
					(unsigned) mmap->length_high,
					(unsigned) mmap->length_low);
	}

	/* Construct an LDT entry in the GDT */
	{
		seg_desc_t the_ldt_desc;
		the_ldt_desc.granularity    = 0;
		the_ldt_desc.opsize         = 1;
		the_ldt_desc.reserved       = 0;
		the_ldt_desc.avail          = 0;
		the_ldt_desc.present        = 1;
		the_ldt_desc.dpl            = 0x0;
		the_ldt_desc.sys            = 0;
		the_ldt_desc.type           = 0x2;

		SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size);
		ldt_desc_ptr = the_ldt_desc;
		lldt(KERNEL_LDT);
	}

	/* Construct a TSS entry in the GDT */
	{
		seg_desc_t the_tss_desc;
		the_tss_desc.granularity    = 0;
		the_tss_desc.opsize         = 0;
		the_tss_desc.reserved       = 0;
		the_tss_desc.avail          = 0;
		the_tss_desc.seg_lim_19_16  = TSS_SIZE & 0x000F0000;
		the_tss_desc.present        = 1;
		the_tss_desc.dpl            = 0x0;
		the_tss_desc.sys            = 0;
		the_tss_desc.type           = 0x9;
		the_tss_desc.seg_lim_15_00  = TSS_SIZE & 0x0000FFFF;

		SET_TSS_PARAMS(the_tss_desc, &tss, tss_size);

		tss_desc_ptr = the_tss_desc;

		tss.ldt_segment_selector = KERNEL_LDT;
		tss.ss0 = KERNEL_DS;
		tss.esp0 = 0x800000;
		ltr(KERNEL_TSS);
	}


	idt_desc_t interrupt;

	interrupt.seg_selector = KERNEL_CS;
	interrupt.dpl = 0;
	interrupt.size = 1;
	interrupt.reserved0 = 0;
	interrupt.reserved1 = 1;
	interrupt.reserved2 = 1;
	interrupt.reserved3 = 0;
	interrupt.reserved4 = 0;
	interrupt.present = 1;

	idt_desc_t divide_error_desc = interrupt;
	SET_IDT_ENTRY(divide_error_desc, divide_error);
	idt[0] = divide_error_desc;

	idt_desc_t reserved_desc = interrupt;
	SET_IDT_ENTRY(reserved_desc, reserved);
	idt[1] = reserved_desc;

	idt_desc_t nmi_interrupt_desc = interrupt;
	SET_IDT_ENTRY(nmi_interrupt_desc, nmi_interrupt);
	idt[2] = nmi_interrupt_desc;

	idt_desc_t breakpoint_desc = interrupt;
	SET_IDT_ENTRY(breakpoint_desc, breakpoint);
	idt[3] = breakpoint_desc;

	idt_desc_t overflow_desc = interrupt;
	SET_IDT_ENTRY(overflow_desc, overflow);
	idt[4] = overflow_desc;

	idt_desc_t bound_range_exceeded_desc = interrupt;
	SET_IDT_ENTRY(bound_range_exceeded_desc, bound_range_exceeded);
	idt[5] = bound_range_exceeded_desc;

	idt_desc_t invalid_opcode_desc = interrupt;
	SET_IDT_ENTRY(invalid_opcode_desc, invalid_opcode);
	idt[6] = invalid_opcode_desc;

	idt_desc_t device_not_available_desc = interrupt;
	SET_IDT_ENTRY(device_not_available_desc, device_not_available);
	idt[7] = device_not_available_desc;

	idt_desc_t double_fault_desc = interrupt;
	SET_IDT_ENTRY(double_fault_desc, double_fault);
	idt[8] = double_fault_desc;

	idt_desc_t coprocessor_segment_overrun_desc = interrupt;
	SET_IDT_ENTRY(coprocessor_segment_overrun_desc, coprocessor_segment_overrun);
	idt[9] = divide_error_desc;

	idt_desc_t invalid_tss_desc = interrupt;
	SET_IDT_ENTRY(invalid_tss_desc, invalid_tss);
	idt[10] = invalid_tss_desc;

	idt_desc_t segment_not_present_desc = interrupt;
	segment_not_present_desc.present = 0;
	SET_IDT_ENTRY(segment_not_present_desc, segment_not_present);
	idt[11] = segment_not_present_desc;

	idt_desc_t stack_segment_fault_desc = interrupt;
	SET_IDT_ENTRY(stack_segment_fault_desc, stack_segment_fault);
	idt[12] = stack_segment_fault_desc;

	idt_desc_t general_protection_desc = interrupt;
	SET_IDT_ENTRY(general_protection_desc, general_protection);
	idt[13] = general_protection_desc;

	idt_desc_t page_fault_desc = interrupt;
	SET_IDT_ENTRY(page_fault_desc, page_fault);
	idt[14] = page_fault_desc;

	idt_desc_t math_fault_desc = interrupt;
	SET_IDT_ENTRY(math_fault_desc, math_fault);
	idt[16] = math_fault_desc;

	idt_desc_t alignment_check_desc = interrupt;
	SET_IDT_ENTRY(alignment_check_desc, alignment_check);
	idt[17] = alignment_check_desc;

	idt_desc_t machine_check_desc = interrupt;
	SET_IDT_ENTRY(machine_check_desc, machine_check);
	idt[18] = machine_check_desc;

	idt_desc_t simd_desc = interrupt;
	SET_IDT_ENTRY(simd_desc, simd_floating_exception);
	idt[19] = simd_desc;

	idt_desc_t keyboard_desc = interrupt;
	SET_IDT_ENTRY(keyboard_desc, &keyboard_wrapper);
	idt[0x21] = keyboard_desc;

	idt_desc_t rtc_desc = interrupt;
	SET_IDT_ENTRY(rtc_desc, &rtc_wrapper);
	idt[0x28] = rtc_desc;

	// load idt
	lidt(idt_desc_ptr);

	/* Init the PIC */
	i8259_init();

	/* Initialize devices, memory, filesystem, enable device interrupts on the
	 * PIC, any other initialization stuff... */

	// initialize rtc
	rtc_init();

	// enable irq1 for keyboard
	 enable_irq(1);


	/* Enable interrupts */
	/* Do not enable the following until after you have set up your
	 * IDT correctly otherwise QEMU will triple fault and simple close
	 * without showing you any output */
	printf("Enabling Interrupts\n");
	sti();

	int freq = 0x0010;
	write_rtc((char *) (&freq));

	// while(1) {
	// 	printf("h");
	// 	read_rtc();
	// }

	// int x = 3 / 0;
	// int * x = 0x12345000;
	// int y;
	// y = *x;

	/* Execute the first program (`shell') ... */

	/* Spin (nicely, so we don't chew up cycles) */
	asm volatile(".1: hlt; jmp .1;");
}
Пример #29
0
/* Check if MAGIC is valid and print the Multiboot information structure
   pointed by ADDR. */
void
entry (unsigned long magic, unsigned long addr)
{
	multiboot_info_t *mbi;

	/* Clear the screen. */
	clear();
	
	uint32_t filestart;
	/* Am I booted by a Multiboot-compliant boot loader? */
	if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
	{
		printf ("Invalid magic number: 0x%#x\n", (unsigned) magic);
		return;
	}

	/* Set MBI to the address of the Multiboot information structure. */
	mbi = (multiboot_info_t *) addr;

	/* Print out the flags. */
	printf ("flags = 0x%#x\n", (unsigned) mbi->flags);

	/* Are mem_* valid? */
	if (CHECK_FLAG (mbi->flags, 0))
		printf ("mem_lower = %uKB, mem_upper = %uKB\n",
				(unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);

	/* Is boot_device valid? */
	if (CHECK_FLAG (mbi->flags, 1))
		printf ("boot_device = 0x%#x\n", (unsigned) mbi->boot_device);

	/* Is the command line passed? */
	if (CHECK_FLAG (mbi->flags, 2))
		printf ("cmdline = %s\n", (char *) mbi->cmdline);

	if (CHECK_FLAG (mbi->flags, 3)) {
		int mod_count = 0;
		int i;
		module_t* mod = (module_t*)mbi->mods_addr;
		while(mod_count < mbi->mods_count) {
			printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start);
			filestart = mod->mod_start;
			printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end);
			printf("First few bytes of module:\n");
			for(i = 0; i<16; i++) {
				printf("0x%x ", *((char*)(mod->mod_start+i)));
			}
			printf("\n");
			mod_count++;
		}
	}
	/* Bits 4 and 5 are mutually exclusive! */
	if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
	{
		printf ("Both bits 4 and 5 are set.\n");
		return;
	}

	/* Is the section header table of ELF valid? */
	if (CHECK_FLAG (mbi->flags, 5))
	{
		elf_section_header_table_t *elf_sec = &(mbi->elf_sec);

		printf ("elf_sec: num = %u, size = 0x%#x,"
				" addr = 0x%#x, shndx = 0x%#x\n",
				(unsigned) elf_sec->num, (unsigned) elf_sec->size,
				(unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
	}

	/* Are mmap_* valid? */
	if (CHECK_FLAG (mbi->flags, 6))
	{
		memory_map_t *mmap;

		printf ("mmap_addr = 0x%#x, mmap_length = 0x%x\n",
				(unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
		for (mmap = (memory_map_t *) mbi->mmap_addr;
				(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
				mmap = (memory_map_t *) ((unsigned long) mmap
					+ mmap->size + sizeof (mmap->size)))
			printf (" size = 0x%x,     base_addr = 0x%#x%#x\n"
					"     type = 0x%x,  length    = 0x%#x%#x\n",
					(unsigned) mmap->size,
					(unsigned) mmap->base_addr_high,
					(unsigned) mmap->base_addr_low,
					(unsigned) mmap->type,
					(unsigned) mmap->length_high,
					(unsigned) mmap->length_low);
	}

	/* Construct an LDT entry in the GDT */
	{
		seg_desc_t the_ldt_desc;
		the_ldt_desc.granularity    = 0;
		the_ldt_desc.opsize         = 1;
		the_ldt_desc.reserved       = 0;
		the_ldt_desc.avail          = 0;
		the_ldt_desc.present        = 1;
		the_ldt_desc.dpl            = 0x0;
		the_ldt_desc.sys            = 0;
		the_ldt_desc.type           = 0x2;

		SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size);
		ldt_desc_ptr = the_ldt_desc;
		lldt(KERNEL_LDT);
	}

	/* Construct a TSS entry in the GDT */
	{
		seg_desc_t the_tss_desc;
		the_tss_desc.granularity    = 0;
		the_tss_desc.opsize         = 0;
		the_tss_desc.reserved       = 0;
		the_tss_desc.avail          = 0;
		the_tss_desc.seg_lim_19_16  = TSS_SIZE & 0x000F0000;
		the_tss_desc.present        = 1;
		the_tss_desc.dpl            = 0x0;
		the_tss_desc.sys            = 0;
		the_tss_desc.type           = 0x9;
		the_tss_desc.seg_lim_15_00  = TSS_SIZE & 0x0000FFFF;

		SET_TSS_PARAMS(the_tss_desc, &tss, tss_size);

		tss_desc_ptr = the_tss_desc;

		tss.ldt_segment_selector = KERNEL_LDT;
		tss.ss0 = KERNEL_DS;
		tss.esp0 = 0x800000;
		ltr(KERNEL_TSS);
	}
		//Initialization of IDE
	{
		printf("Initilization of Idt table...");
		set_trap_gate(0,divide_error);
		set_trap_gate(1,debug);
		set_intr_gate(2,nmi);
		set_system_intr_gate(3,int3);	
		set_system_gate(4,overflow);
		set_system_gate(5,bounds);
		set_trap_gate(6,invalid_op);
		set_trap_gate(7,device_not_available);
		set_task_gate(8,31);	
		set_trap_gate(9,coprocessor_segment_overrun);
		set_trap_gate(10,invalid_TSS);
		set_trap_gate(11,segment_not_present);
		set_trap_gate(12,stack_segment);
		set_trap_gate(13,general_protection);
		set_trap_gate(14,page_fault);//intr
		set_trap_gate(16,coprocessor_error);
		set_trap_gate(17,alignment_check);
		set_trap_gate(18,machine_check);
		set_trap_gate(19,simd_coprocessor_error);
		set_system_gate(128,system_call);
		set_intr_gate(32,irq0);  //intr 
		set_intr_gate(33,irq1); //intr
		set_intr_gate(34,0); //intr
		set_intr_gate(40,irq8);  //intr   
		//set_intr_gate(44,irq12); //intr
		lidt(idt_desc_ptr);
		printf("ok!\n");
	}
	
	// Init the PIC 
	i8259_init();
	
	//Enable interrupts

 
	enable_irq(1);
	enable_irq(2);
	open_rtc();
    enable_irq(8);
	enable_irq(12);

    uint8_t file =0x00;
	
	//Enable paging
    printf("Enabling paging...\n");
	paging();
    printf("ok!\n");
	
	//Restore interrupts
	sti();

	//Mounting file system
	printf("Mounting filesystem...\n");
	open_terminal(&file);
	setstart(filestart);
	printf("ok!\n");
	
	//clear();
    //Executing first program shell
    uint8_t cmd[10]={"shell "};
#if debug_by_showing_dentries
test_dentries();
while(1);
#endif

    test_system_call((int32_t)cmd, NULL, 0, 2);

	asm volatile(".1: hlt; jmp .1;");
}
Пример #30
0
/* Check if MAGIC is valid and print the Multiboot information structure
   pointed by ADDR. */
void
entry (unsigned long magic, unsigned long addr)
{
	multiboot_info_t *mbi;
	uint8_t* filesystem_address;

	/* Clear the screen. */
	clear();

	/* Am I booted by a Multiboot-compliant boot loader? */
	if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
	{
		printf ("Invalid magic number: 0x%#x\n", (unsigned) magic);
		return;
	}

	/* Set MBI to the address of the Multiboot information structure. */
	mbi = (multiboot_info_t *) addr;

	/* Print out the flags. */
	printf ("flags = 0x%#x\n", (unsigned) mbi->flags);

	/* Are mem_* valid? */
	if (CHECK_FLAG (mbi->flags, 0))
		printf ("mem_lower = %uKB, mem_upper = %uKB\n",
				(unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);

	/* Is boot_device valid? */
	if (CHECK_FLAG (mbi->flags, 1))
		printf ("boot_device = 0x%#x\n", (unsigned) mbi->boot_device);

	/* Is the command line passed? */
	if (CHECK_FLAG (mbi->flags, 2))
		printf ("cmdline = %s\n", (char *) mbi->cmdline);

	if (CHECK_FLAG (mbi->flags, 3)) {
		int mod_count = 0;
		int i;
		module_t* mod = (module_t*)mbi->mods_addr;
		while(mod_count < mbi->mods_count) {
			filesystem_address = (uint8_t*)mod->mod_start;
			printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start);
			printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end);
			printf("First few bytes of module:\n");
			for(i = 0; i<16; i++) {
				printf("0x%x ", *((char*)(mod->mod_start+i)));
			}
			printf("\n");
			mod_count++;
			mod++;
		}
	}
	/* Bits 4 and 5 are mutually exclusive! */
	if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
	{
		printf ("Both bits 4 and 5 are set.\n");
		return;
	}

	/* Is the section header table of ELF valid? */
	if (CHECK_FLAG (mbi->flags, 5))
	{
		elf_section_header_table_t *elf_sec = &(mbi->elf_sec);

		printf ("elf_sec: num = %u, size = 0x%#x,"
				" addr = 0x%#x, shndx = 0x%#x\n",
				(unsigned) elf_sec->num, (unsigned) elf_sec->size,
				(unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
	}

	/* Are mmap_* valid? */
	if (CHECK_FLAG (mbi->flags, 6))
	{
		memory_map_t *mmap;

		printf ("mmap_addr = 0x%#x, mmap_length = 0x%x\n",
				(unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
		for (mmap = (memory_map_t *) mbi->mmap_addr;
				(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
				mmap = (memory_map_t *) ((unsigned long) mmap
					+ mmap->size + sizeof (mmap->size)))
			printf (" size = 0x%x,     base_addr = 0x%#x%#x\n"
					"     type = 0x%x,  length    = 0x%#x%#x\n",
					(unsigned) mmap->size,
					(unsigned) mmap->base_addr_high,
					(unsigned) mmap->base_addr_low,
					(unsigned) mmap->type,
					(unsigned) mmap->length_high,
					(unsigned) mmap->length_low);
	}

	/* Construct an LDT entry in the GDT */
	{
		seg_desc_t the_ldt_desc;
		the_ldt_desc.granularity    = 0;
		the_ldt_desc.opsize         = 1;
		the_ldt_desc.reserved       = 0;
		the_ldt_desc.avail          = 0;
		the_ldt_desc.present        = 1;
		the_ldt_desc.dpl            = 0x0;
		the_ldt_desc.sys            = 0;
		the_ldt_desc.type           = 0x2;

		SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size);
		ldt_desc_ptr = the_ldt_desc;
		lldt(KERNEL_LDT);
	}

	/* Construct a TSS entry in the GDT */
	{
		seg_desc_t the_tss_desc;
		the_tss_desc.granularity    = 0;
		the_tss_desc.opsize         = 0;
		the_tss_desc.reserved       = 0;
		the_tss_desc.avail          = 0;
		the_tss_desc.seg_lim_19_16  = TSS_SIZE & 0x000F0000;
		the_tss_desc.present        = 1;
		the_tss_desc.dpl            = 0x0;
		the_tss_desc.sys            = 0;
		the_tss_desc.type           = 0x9;
		the_tss_desc.seg_lim_15_00  = TSS_SIZE & 0x0000FFFF;

		SET_TSS_PARAMS(the_tss_desc, &tss, tss_size);

		tss_desc_ptr = the_tss_desc;

		tss.ldt_segment_selector = KERNEL_LDT;
		tss.ss0 = KERNEL_DS;
		tss.esp0 = 0x800000;
		ltr(KERNEL_TSS);
	}
	

	int z = 0;
	reset_scr();

	//set the IDT	
	set_idt();
	lidt(idt_desc_ptr);
	
	/* Init the PIC */
	i8259_init();

	/* Initialize devices, memory, filesystem, enable device interrupts on the
	 * PIC, any other initialization stuff... */

	//init paging
	init_paging();
			
	//init filesystem
	init_filesys(filesystem_address);
	
	//init keyboard
	init_keyboard();

	//init the rtc
	init_rtc();

	//init the mouse
	init_mouse();

	//clear the screen
	reset_scr();
	
	// boot_screen();
	for(z = 0; z < 3; z++)
	{
		terminal_init();
	}
	node* buffer = screens[0];
	reset_buf(buffer);
	//display the status bar

	/* Enable interrupts */
	
	sti();
	/* Do not enable the following until after you have set up your
	 * IDT correctly otherwise QEMU will triple fault and simple close
	 * without showing you any output */


	boot_screen();
	//sample mario sound
	for(z = 0; z < 500000; z++)
		play_sound(1000);

	for(z = 0; z < 500000; z++)
		play_sound(100);

	for(z = 0; z < 500000; z++)
		play_sound(900);

	for(z = 0; z < 50000; z++)
		play_sound(200);

	for(z = 0; z < 500000; z++)
		play_sound(800);

	for(z = 0; z < 500000; z++)
		play_sound(300);

	for(z = 0; z < 500000; z++)
		play_sound(700);

	for(z = 0; z < 500000; z++)
		play_sound(400);

	for(z = 0; z < 500000; z++)
		play_sound(600);

	for(z = 0; z < 500000; z++)
		play_sound(500);

	for(z = 0; z < 500000; z++)
		play_sound(500);

	for(z = 0; z < 500000; z++)
		play_sound(1000);

	for(z = 0; z < 500000; z++)
		play_sound(400);

	for(z = 0; z < 500000; z++)
		play_sound(300);

	for(z = 0; z < 500000; z++)
		play_sound(300);

	for(z = 0; z < 500000; z++)
		play_sound(200);

	//boot_screen();
	nosound();
	reset_scr();

	//init PIT for sound, timer
	init_pit(0, 100);

	/////////////////////////////////////////////////////////////

//	void imperial();

	status_bar();
	/* Execute the first program (`shell') ... */
	uint8_t fname[33] = "shell";
	execute(fname);

	/* We should never get to this point */
	//printf("Initial shell halted.");

	/* Spin (nicely, so we don't chew up cycles) */
	asm volatile(".1: hlt; jmp .1;");
}