ac_bool test_interrupts(void) { ac_bool error = AC_FALSE; descriptor_ptr idtr; get_idt(&idtr); error |= AC_TEST(idtr.limit != 0); error |= AC_TEST(idtr.iig != 0); // Test we can set an interrupt handler and invoke it set_intr_handler(79, intr_79); print_idt_intr_gate("idt[79]:", get_idt_intr_gate(79)); idt_intr_gate *g = get_idt_intr_gate(79); error |= AC_TEST(GET_IDT_INTR_GATE_OFFSET(*g) == (ac_uptr)intr_79); intr_79_counter = 0; ac_printf("invoke intr(79)\n"); intr(79); ac_printf("done intr(79)\n"); error |= AC_TEST(intr_79_counter == 1); return error; }
/** * Early initialization of this module */ void ac_thread_early_init() { // Initialize timer first, the main reason // is it set slice_default. init_timer(); // Initialize reschedule isr set_intr_handler(RESCHEDULE_ISR_INTR, reschedule_isr); set_intr_handler(TIMER_RESCHEDULE_ISR_INTR, timer_reschedule_isr); // Allocate the initial array total_threads = 0; pthreads = AC_NULL; ac_thread_init(SYSTEM_THREAD_COUNT); ac_assert(pthreads != AC_NULL); pidle_tcb = &pthreads->tcbs[0]; pmain_tcb = &pthreads->tcbs[1]; // Initialize idle and main tcbs tcb_init(pidle_tcb, 0, idle, AC_NULL); tcb_init(pmain_tcb, 1, AC_NULL, AC_NULL); // Initialize idle's stack init_stack_frame(idle_stack, sizeof(idle_stack), DEFAULT_FLAGS, idle, pidle_tcb, &pidle_tcb->sp, &pidle_tcb->ss); // Add main as the initial pready list pmain_tcb->pnext_tcb = pmain_tcb; pmain_tcb->pprev_tcb = pmain_tcb; pready = pmain_tcb; #ifdef SUPPORT_READY_LENGTH ready_length = 1; #endif // Add idle to the pready list add_tcb_after(pidle_tcb, pready); // Initialize waiting tcbs data structures waiting_tcbs_init(SYSTEM_THREAD_COUNT); print_waiting_tcbs(); ac_printf("ac_thread_early_init: pmain=0x%lx pidle=0x%lx rl=%d\n", pmain_tcb, pidle_tcb, get_ready_length()); print_tcb_list("ac_thread_early_init:-ready: ", pready); }
/** * Early APIC Initialization * * @return 0 if initialized, !0 if an error */ ac_uint apic_early_init(void) { ac_uint ret_val; ac_printf("apic_early_init:+present=%b\n", apic_present()); // Get Processor info cpuid if (apic_present()) { // Remap the PIC vectors to 0x20 .. 0x2F remap_pic_vectors(0x20, 0x28); // Disable PIC outb_port_value(0xa1, 0xff); outb_port_value(0x21, 0xff); // Apic is present, map its physical page as uncachable. ac_u64 apic_phy_addr = get_apic_physical_addr(); apic_lin_addr = (void*)apic_phy_addr; //0x00000001ffee00000; page_table_map_lin_to_phy(get_page_table_linear_addr(), apic_lin_addr, apic_phy_addr, FOUR_K_PAGE_SIZE, PAGE_CACHING_STRONG_UNCACHEABLE); // Below we enable the APIC, which can be done two different ways, // See "Intel 64 and IA-32 Architectures Software Developer's Manual" // Volume 3 chapter 10.4.3 "Enabling or Disabling the Local APIC" // // I'm choosing to enable spurious_vector since we set the vector anyway. struct apic_spurious_vector_fields svf = get_apic_spurious_vector(); svf.vector = APIC_SPURIOUS_VECTOR; #if 1 // Enable apic in spurious_vector svf.apic_enable = AC_TRUE; #else // Enable apic in msr struct msr_apic_base_fields abf = msr_get_apic_base(); abf.e = AC_TRUE; msr_set_apic_base(abf); #endif set_apic_spurious_vector(svf); set_intr_handler(APIC_SPURIOUS_VECTOR, apic_spurious_interrupt_isr); // Print tpr and ppr ac_printf("apic_early_init: tpr=0x%x ppr=0x%x esr=0x%x\n", get_apic_tpr(), get_apic_ppr(), get_apic_esr()); apic_irr_print("irr: "); apic_isr_print("isr: "); apic_tmr_print("tmr: "); ret_val = 0; } else { // No apic ret_val = 1; } ac_printf("apic_early_init:-ret_val=%d\n", ret_val); return ret_val; }
/* Function initializes dummy keyboard handler */ void keyb_init(void) { set_intr_handler(1, (void *)&keyb_intr_handler); return; }