⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpx386.s.cpp

📁 一个简单的操作系统minix的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
06197	!*===========================================================================*
06198	! Note this is a macro, it looks like a subroutine.
06199	#define hwint_slave(irq)        \
06200	        call    save                    /* save interrupted process state */;\
06201	        inb     INT2_CTLMASK                                                ;\
06202	        orb     al, [1<<[irq-8]]                                            ;\
06203	        outb    INT2_CTLMASK            /* disable the irq                */;\
06204	        movb    al, ENABLE                                                  ;\
06205	        outb    INT_CTL                 /* reenable master 8259           */;\
06206	        jmp     .+2                     /* delay                          */;\
06207	        outb    INT2_CTL                /* reenable slave 8259            */;\
06208	        sti                             /* enable interrupts              */;\
06209	        push    irq                     /* irq                            */;\
06210	        call    (_irq_table + 4*irq)    /* eax = (*irq_table[irq])(irq)   */;\
06211	        pop     ecx                                                         ;\
06212	        cli                             /* disable interrupts             */;\
06213	        test    eax, eax                /* need to reenable irq?          */;\
06214	        jz      0f                                                          ;\
06215	        inb     INT2_CTLMASK                                                ;\
06216	        andb    al, ~[1<<[irq-8]]                                           ;\
06217	        outb    INT2_CTLMASK            /* enable the irq                 */;\
06218	0:      ret                             /* restart (another) process      */
06219	
06220	! Each of these entry points is an expansion of the hwint_slave macro
06221	        .align  16
06222	_hwint08:               ! Interrupt routine for irq 8 (realtime clock)
06223	        hwint_slave(8)
06224	
06225	        .align  16
06226	_hwint09:               ! Interrupt routine for irq 9 (irq 2 redirected)
06227	        hwint_slave(9)
06228	
06229	        .align  16
06230	_hwint10:               ! Interrupt routine for irq 10
06231	        hwint_slave(10)
06232	
06233	        .align  16
06234	_hwint11:               ! Interrupt routine for irq 11
06235	        hwint_slave(11)
06236	
06237	        .align  16
06238	_hwint12:               ! Interrupt routine for irq 12
06239	        hwint_slave(12)
06240	
06241	        .align  16
06242	_hwint13:               ! Interrupt routine for irq 13 (FPU exception)
06243	        hwint_slave(13)
06244	
06245	        .align  16
06246	_hwint14:               ! Interrupt routine for irq 14 (AT winchester)
06247	        hwint_slave(14)
06248	
06249	        .align  16
06250	_hwint15:               ! Interrupt routine for irq 15
06251	        hwint_slave(15)
06252	
06253	!*===========================================================================*
06254	!*                              save                                         *
06255	!*===========================================================================*
06256	! Save for protected mode.
06257	! This is much simpler than for 8086 mode, because the stack already points
06258	! into the process table, or has already been switched to the kernel stack.
06259	
06260	        .align  16
06261	save:
06262	        cld                     ! set direction flag to a known value
06263	        pushad                  ! save "general" registers
06264	    o16 push    ds              ! save ds
06265	    o16 push    es              ! save es
06266	    o16 push    fs              ! save fs
06267	    o16 push    gs              ! save gs
06268	        mov     dx, ss          ! ss is kernel data segment
06269	        mov     ds, dx          ! load rest of kernel segments
06270	        mov     es, dx          ! kernel does not use fs, gs
06271	        mov     eax, esp        ! prepare to return
06272	        incb    (_k_reenter)    ! from -1 if not reentering
06273	        jnz     set_restart1    ! stack is already kernel stack
06274	        mov     esp, k_stktop
06275	        push    _restart        ! build return address for int handler
06276	        xor     ebp, ebp        ! for stacktrace
06277	        jmp     RETADR-P_STACKBASE(eax)
06278	
06279	        .align  4
06280	set_restart1:
06281	        push    restart1
06282	        jmp     RETADR-P_STACKBASE(eax)
06283	
06284	!*===========================================================================*
06285	!*                              _s_call                                      *
06286	!*===========================================================================*
06287	        .align  16
06288	_s_call:
06289	_p_s_call:
06290	        cld                     ! set direction flag to a known value
06291	        sub     esp, 6*4        ! skip RETADR, eax, ecx, edx, ebx, est
06292	        push    ebp             ! stack already points into proc table
06293	        push    esi
06294	        push    edi
06295	    o16 push    ds
06296	    o16 push    es
06297	    o16 push    fs
06298	    o16 push    gs
06299	        mov     dx, ss
06300	        mov     ds, dx
06301	        mov     es, dx
06302	        incb    (_k_reenter)
06303	        mov     esi, esp        ! assumes P_STACKBASE == 0
06304	        mov     esp, k_stktop
06305	        xor     ebp, ebp        ! for stacktrace
06306	                                ! end of inline save
06307	        sti                     ! allow SWITCHER to be interrupted
06308	                                ! now set up parameters for sys_call()
06309	        push    ebx             ! pointer to user message
06310	        push    eax             ! src/dest
06311	        push    ecx             ! SEND/RECEIVE/BOTH
06312	        call    _sys_call       ! sys_call(function, src_dest, m_ptr)
06313	                                ! caller is now explicitly in proc_ptr
06314	        mov     AXREG(esi), eax ! sys_call MUST PRESERVE si
06315	        cli                     ! disable interrupts 
06316	
06317	! Fall into code to restart proc/task running.
06318	
06319	!*===========================================================================*
06320	!*                              restart                                      *
06321	!*===========================================================================*
06322	_restart:
06323	
06324	! Flush any held-up interrupts.
06325	! This reenables interrupts, so the current interrupt handler may reenter.
06326	! This does not matter, because the current handler is about to exit and no
06327	! other handlers can reenter since flushing is only done when k_reenter == 0.
06328	
06329	        cmp     (_held_head), 0 ! do fast test to usually avoid function call
06330	        jz      over_call_unhold
06331	        call    _unhold         ! this is rare so overhead acceptable
06332	over_call_unhold:
06333	        mov     esp, (_proc_ptr)        ! will assume P_STACKBASE == 0
06334	        lldt    P_LDT_SEL(esp)          ! enable segment descriptors for task
06335	        lea     eax, P_STACKTOP(esp)    ! arrange for next interrupt
06336	        mov     (_tss+TSS3_S_SP0), eax  ! to save state in process table
06337	restart1:
06338	        decb    (_k_reenter)
06339	    o16 pop     gs
06340	    o16 pop     fs
06341	    o16 pop     es
06342	    o16 pop     ds
06343	        popad
06344	        add     esp, 4          ! skip return adr
06345	        iretd                   ! continue process
06346	
06347	!*===========================================================================*
06348	!*                              exception handlers                           *
06349	!*===========================================================================*
06350	_divide_error:
06351	        push    DIVIDE_VECTOR
06352	        jmp     exception
06353	
06354	_single_step_exception:
06355	        push    DEBUG_VECTOR
06356	        jmp     exception
06357	
06358	_nmi:
06359	        push    NMI_VECTOR
06360	        jmp     exception
06361	
06362	_breakpoint_exception:
06363	        push    BREAKPOINT_VECTOR
06364	        jmp     exception
06365	
06366	_overflow:
06367	        push    OVERFLOW_VECTOR
06368	        jmp     exception
06369	
06370	_bounds_check:
06371	        push    BOUNDS_VECTOR
06372	        jmp     exception
06373	
06374	_inval_opcode:
06375	        push    INVAL_OP_VECTOR
06376	        jmp     exception
06377	
06378	_copr_not_available:
06379	        push    COPROC_NOT_VECTOR
06380	        jmp     exception
06381	
06382	_double_fault:
06383	        push    DOUBLE_FAULT_VECTOR
06384	        jmp     errexception
06385	
06386	_copr_seg_overrun:
06387	        push    COPROC_SEG_VECTOR
06388	        jmp     exception
06389	
06390	_inval_tss:
06391	        push    INVAL_TSS_VECTOR
06392	        jmp     errexception
06393	
06394	_segment_not_present:
06395	        push    SEG_NOT_VECTOR
06396	        jmp     errexception
06397	
06398	_stack_exception:
06399	        push    STACK_FAULT_VECTOR
06400	        jmp     errexception
06401	
06402	_general_protection:
06403	        push    PROTECTION_VECTOR
06404	        jmp     errexception
06405	
06406	_page_fault:
06407	        push    PAGE_FAULT_VECTOR
06408	        jmp     errexception
06409	
06410	_copr_error:
06411	        push    COPROC_ERR_VECTOR
06412	        jmp     exception
06413	
06414	!*===========================================================================*
06415	!*                              exception                                    *
06416	!*===========================================================================*
06417	! This is called for all exceptions which do not push an error code.
06418	
06419	        .align  16
06420	exception:
06421	 sseg   mov     (trap_errno), 0         ! clear trap_errno
06422	 sseg   pop     (ex_number)
06423	        jmp     exception1
06424	
06425	!*===========================================================================*
06426	!*                              errexception                                 *
06427	!*===========================================================================*
06428	! This is called for all exceptions which push an error code.
06429	
06430	        .align  16
06431	errexception:
06432	 sseg   pop     (ex_number)
06433	 sseg   pop     (trap_errno)
06434	exception1:                             ! Common for all exceptions.
06435	        push    eax                     ! eax is scratch register
06436	        mov     eax, 0+4(esp)           ! old eip
06437	 sseg   mov     (old_eip), eax
06438	        movzx   eax, 4+4(esp)           ! old cs
06439	 sseg   mov     (old_cs), eax
06440	        mov     eax, 8+4(esp)           ! old eflags
06441	 sseg   mov     (old_eflags), eax
06442	        pop     eax
06443	        call    save
06444	        push    (old_eflags)
06445	        push    (old_cs)
06446	        push    (old_eip)
06447	        push    (trap_errno)
06448	        push    (ex_number)
06449	        call    _exception              ! (ex_number, trap_errno, old_eip,
06450	                                        !       old_cs, old_eflags)
06451	        add     esp, 5*4
06452	        cli
06453	        ret
06454	
06455	!*===========================================================================*
06456	!*                              level0_call                                  *
06457	!*===========================================================================*
06458	_level0_call:
06459	        call    save
06460	        jmp     (_level0_func)
06461	
06462	!*===========================================================================*
06463	!*                              idle_task                                    *
06464	!*===========================================================================*
06465	_idle_task:                     ! executed when there is no work
06466	        jmp     _idle_task      ! a "hlt" before this fails in protected mode
06467	
06468	!*===========================================================================*
06469	!*                              data                                         *
06470	!*===========================================================================*
06471	! These declarations assure that storage will be allocated at the very 
06472	! beginning of the kernel data section, so the boot monitor can be easily 
06473	! told how to patch these locations. Note that the magic number is put
06474	! here by the compiler, but will be read by, and then overwritten by,
06475	! the boot monitor. When the kernel starts the sizes array will be
06476	! found here, as if it had been initialized by the compiler.
06477	
06478	.sect .rom      ! Before the string table please
06479	_sizes:                         ! sizes of kernel, mm, fs filled in by boot
06480	        .data2  0x526F          ! this must be the first data entry (magic #)
06481	        .space  16*2*2-2        ! monitor uses previous word and this space
06482	                                ! extra space allows for additional servers
06483	.sect .bss
06484	k_stack:
06485	        .space  K_STACK_BYTES   ! kernel stack
06486	k_stktop:                       ! top of kernel stack
06487	        .comm   ex_number, 4
06488	        .comm   trap_errno, 4
06489	        .comm   old_eip, 4
06490	        .comm   old_cs, 4
06491	        .comm   old_eflags, 4





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -