📄 mpx386.s.cpp
字号:
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 + -