Deleted Added
full compact
btx.S (181433) btx.S (189017)
1/*
2 * Copyright (c) 1998 Robert Nordier
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are freely
6 * permitted provided that the above copyright notice and this
7 * paragraph and the following disclaimer are duplicated in all
8 * such forms.
9 *
10 * This software is provided "AS IS" and without any express or
11 * implied warranties, including, without limitation, the implied
12 * warranties of merchantability and fitness for a particular
13 * purpose.
14 *
1/*
2 * Copyright (c) 1998 Robert Nordier
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are freely
6 * permitted provided that the above copyright notice and this
7 * paragraph and the following disclaimer are duplicated in all
8 * such forms.
9 *
10 * This software is provided "AS IS" and without any express or
11 * implied warranties, including, without limitation, the implied
12 * warranties of merchantability and fitness for a particular
13 * purpose.
14 *
15 * $FreeBSD: head/sys/boot/i386/btx/btx/btx.S 181433 2008-08-08 19:39:11Z jhb $
15 * $FreeBSD: head/sys/boot/i386/btx/btx/btx.S 189017 2009-02-24 23:11:15Z jhb $
16 */
17
18/*
19 * Memory layout.
20 */
21 .set MEM_BTX,0x1000 # Start of BTX memory
22 .set MEM_ESP0,0x1800 # Supervisor stack
23 .set MEM_BUF,0x1800 # Scratch buffer

--- 7 unchanged lines hidden (view full) ---

31/*
32 * Paging control.
33 */
34 .set PAG_SIZ,0x1000 # Page size
35 .set PAG_CNT,0x1000 # Pages to map
36/*
37 * Fields in %eflags.
38 */
16 */
17
18/*
19 * Memory layout.
20 */
21 .set MEM_BTX,0x1000 # Start of BTX memory
22 .set MEM_ESP0,0x1800 # Supervisor stack
23 .set MEM_BUF,0x1800 # Scratch buffer

--- 7 unchanged lines hidden (view full) ---

31/*
32 * Paging control.
33 */
34 .set PAG_SIZ,0x1000 # Page size
35 .set PAG_CNT,0x1000 # Pages to map
36/*
37 * Fields in %eflags.
38 */
39 .set PSL_RESERVED_DEFAULT,0x00000002
39 .set PSL_T,0x00000100 # Trap flag
40 .set PSL_I,0x00000200 # Interrupt enable flag
41 .set PSL_VM,0x00020000 # Virtual 8086 mode flag
42 .set PSL_AC,0x00040000 # Alignment check flag
43/*
44 * Segment selectors.
45 */
46 .set SEL_SCODE,0x8 # Supervisor code

--- 403 unchanged lines hidden (view full) ---

450 * -0x28 %esp
451 * -0x2c %ebp
452 * -0x30 %esi
453 * -0x34 %edi
454 * -0x38 %gs
455 * -0x3c %fs
456 * -0x40 %ds
457 * -0x44 %es
40 .set PSL_T,0x00000100 # Trap flag
41 .set PSL_I,0x00000200 # Interrupt enable flag
42 .set PSL_VM,0x00020000 # Virtual 8086 mode flag
43 .set PSL_AC,0x00040000 # Alignment check flag
44/*
45 * Segment selectors.
46 */
47 .set SEL_SCODE,0x8 # Supervisor code

--- 403 unchanged lines hidden (view full) ---

451 * -0x28 %esp
452 * -0x2c %ebp
453 * -0x30 %esi
454 * -0x34 %edi
455 * -0x38 %gs
456 * -0x3c %fs
457 * -0x40 %ds
458 * -0x44 %es
459 * -0x48 zero %eax (hardware int only)
460 * -0x4c zero %ecx (hardware int only)
461 * -0x50 zero %edx (hardware int only)
462 * -0x54 zero %ebx (hardware int only)
463 * -0x58 zero %esp (hardware int only)
464 * -0x5c zero %ebp (hardware int only)
465 * -0x60 zero %esi (hardware int only)
466 * -0x64 zero %edi (hardware int only)
467 * -0x68 zero %gs (hardware int only)
468 * -0x6c zero %fs (hardware int only)
469 * -0x70 zero %ds (hardware int only)
470 * -0x74 zero %es (hardware int only)
458 */
459int_hw: cld # String ops inc
460 pusha # Save gp regs
461 pushl %gs # Save
462 pushl %fs # seg
463 pushl %ds # regs
464 pushl %es
465 push $SEL_SDATA # Set up
466 popl %ds # to
467 pushl %ds # address
468 popl %es # data
469 leal 0x44(%esp,1),%esi # Base of frame
471 */
472int_hw: cld # String ops inc
473 pusha # Save gp regs
474 pushl %gs # Save
475 pushl %fs # seg
476 pushl %ds # regs
477 pushl %es
478 push $SEL_SDATA # Set up
479 popl %ds # to
480 pushl %ds # address
481 popl %es # data
482 leal 0x44(%esp,1),%esi # Base of frame
483 movl %esp,MEM_ESPR-0x04 # Save kernel stack pointer
470 movl -0x14(%esi),%eax # Get Int no
471 cmpl $-1,%eax # Hardware interrupt?
484 movl -0x14(%esi),%eax # Get Int no
485 cmpl $-1,%eax # Hardware interrupt?
472 jne intusr.2 # Yes
486 jne intusr.1 # Yes
473/*
487/*
474 * v86 calls save the btx_v86 pointer on the real mode stack and read the
475 * address and flags from the btx_v86 structure.
488 * v86 calls save the btx_v86 pointer on the real mode stack and read
489 * the address and flags from the btx_v86 structure. For interrupt
490 * handler invocations (VM86 INTx requests), disable interrupts,
491 * tracing, and alignment checking while the handler runs.
476 */
477 movl $MEM_USR,%ebx # User base
478 movl %ebx,%edx # address
479 addl -0x4(%esi),%ebx # User ESP
480 movl (%ebx),%ebp # btx_v86 pointer
481 addl %ebp,%edx # Flatten btx_v86 ptr
482 movl %edx,MEM_ESPR-0x08 # Save btx_v86 ptr
483 movl V86_ADDR(%edx),%eax # Get int no/address
484 movl V86_CTL(%edx),%edx # Get control flags
492 */
493 movl $MEM_USR,%ebx # User base
494 movl %ebx,%edx # address
495 addl -0x4(%esi),%ebx # User ESP
496 movl (%ebx),%ebp # btx_v86 pointer
497 addl %ebp,%edx # Flatten btx_v86 ptr
498 movl %edx,MEM_ESPR-0x08 # Save btx_v86 ptr
499 movl V86_ADDR(%edx),%eax # Get int no/address
500 movl V86_CTL(%edx),%edx # Get control flags
501 movl -0x08(%esi),%ebx # Save user flags in %ebx
502 testl $V86F_ADDR,%edx # Segment:offset?
503 jnz intusr.4 # Yes
504 andl $~(PSL_I|PSL_T|PSL_AC),%ebx # Disable interrupts, tracing,
505 # and alignment checking for
506 # interrupt handler
485 jmp intusr.3 # Skip hardware interrupt
486/*
507 jmp intusr.3 # Skip hardware interrupt
508/*
487 * Hardware interrupts store a NULL btx_v86 pointer and use the address
488 * (interrupt number) from the stack with empty flags. Also, we clear
489 * the segment registers for the interrupt handler.
509 * Hardware interrupts store a NULL btx_v86 pointer and use the
510 * address (interrupt number) from the stack with empty flags. Also,
511 * push a dummy frame of zeros onto the stack for all the general
512 * purpose and segment registers and clear %eflags. This gives the
513 * hardware interrupt handler a clean slate.
490 */
514 */
491intusr.2: xorl %edx,%edx # Control flags
515intusr.1: xorl %edx,%edx # Control flags
492 movl %edx,MEM_ESPR-0x08 # NULL btx_v86 ptr
516 movl %edx,MEM_ESPR-0x08 # NULL btx_v86 ptr
493 movl %edx,-0x38(%esi) # Real mode %gs of 0
494 movl %edx,-0x3c(%esi) # Real mode %fs of 0
495 movl %edx,-0x40(%esi) # Real mode %ds of 0
496 movl %edx,-0x44(%esi) # Real mode %es of 0
517 movl $12,%ecx # Frame is 12 dwords
518intusr.2: pushl $0x0 # Fill frame
519 loop intusr.2 # with zeros
520 movl $PSL_RESERVED_DEFAULT,%ebx # Set clean %eflags
497/*
521/*
498 * %eax now holds either the interrupt number or segment:offset of function.
499 * %edx now holds the V86F_* flags.
500 *
501 * For interrupt handler invocations (either hardware interrupts or VM86
502 * INTx requests) we also disable interrupts, tracing, and alignment checking
503 * while the handler runs.
522 * Look up real mode IDT entry for hardware interrupts and VM86 INTx
523 * requests.
504 */
524 */
505intusr.3: movl -0x08(%esi),%ebx # Save user flags in %ebx
506 testl $V86F_ADDR,%edx # Segment:offset?
507 jnz intusr.4 # Yes
508 shll $0x2,%eax # Scale
525intusr.3: shll $0x2,%eax # Scale
509 movl (%eax),%eax # Load int vector
526 movl (%eax),%eax # Load int vector
510 andl $~(PSL_I|PSL_T|PSL_AC),%ebx # Disable interrupts, tracing,
511 # and alignment checking for
512 # interrupt handler
513 jmp intusr.5 # Skip CALLF test
527 jmp intusr.5 # Skip CALLF test
528/*
529 * Panic if V86F_CALLF isn't set with V86F_ADDR.
530 */
514intusr.4: testl $V86F_CALLF,%edx # Far call?
515 jnz intusr.5 # Ok
516 movl %edx,0x30(%esp,1) # Place VM86 flags in int no
517 movl $badvm86,%esi # Display bad
518 call putstr # VM86 call
519 popl %es # Restore
520 popl %ds # seg
521 popl %fs # regs
522 popl %gs
523 popal # Restore gp regs
524 jmp ex_noc # Panic
531intusr.4: testl $V86F_CALLF,%edx # Far call?
532 jnz intusr.5 # Ok
533 movl %edx,0x30(%esp,1) # Place VM86 flags in int no
534 movl $badvm86,%esi # Display bad
535 call putstr # VM86 call
536 popl %es # Restore
537 popl %ds # seg
538 popl %fs # regs
539 popl %gs
540 popal # Restore gp regs
541 jmp ex_noc # Panic
542/*
543 * %eax now holds the segment:offset of the function.
544 * %ebx now holds the %eflags to pass to real mode.
545 * %edx now holds the V86F_* flags.
546 */
525intusr.5: movw %bx,MEM_ESPR-0x12 # Pass user flags to real mode
526 # target
527/*
528 * If this is a v86 call, copy the seg regs out of the btx_v86 structure.
529 */
530 movl MEM_ESPR-0x08,%ecx # Get btx_v86 ptr
531 jecxz intusr.6 # Skip for hardware ints
532 leal -0x44(%esi),%edi # %edi => kernel stack seg regs
533 pushl %esi # Save
534 leal V86_ES(%ecx),%esi # %esi => btx_v86 seg regs
535 movl $4,%ecx # Copy seg regs
536 rep # from btx_v86
537 movsl # to kernel stack
538 popl %esi # Restore
547intusr.5: movw %bx,MEM_ESPR-0x12 # Pass user flags to real mode
548 # target
549/*
550 * If this is a v86 call, copy the seg regs out of the btx_v86 structure.
551 */
552 movl MEM_ESPR-0x08,%ecx # Get btx_v86 ptr
553 jecxz intusr.6 # Skip for hardware ints
554 leal -0x44(%esi),%edi # %edi => kernel stack seg regs
555 pushl %esi # Save
556 leal V86_ES(%ecx),%esi # %esi => btx_v86 seg regs
557 movl $4,%ecx # Copy seg regs
558 rep # from btx_v86
559 movsl # to kernel stack
560 popl %esi # Restore
539intusr.6: movl %esp,MEM_ESPR-0x04 # Save kernel stack pointer
540 movl -0x08(%esi),%ebx # Copy user flags to real
561intusr.6: movl -0x08(%esi),%ebx # Copy user flags to real
541 movl %ebx,MEM_ESPR-0x0c # mode return trampoline
542 movl $rret_tramp,%ebx # Set return trampoline
543 movl %ebx,MEM_ESPR-0x10 # CS:IP
544 movl %eax,MEM_ESPR-0x16 # Real mode target CS:IP
545 ljmpw $SEL_RCODE,$intusr.7 # Change to 16-bit segment
546 .code16
547intusr.7: movl %cr0,%eax # Leave
548 dec %al # protected

--- 57 unchanged lines hidden (view full) ---

606 movw %cx,%ds # seg
607 movw %cx,%es # regs
608 movl MEM_ESPR-0x04,%esp # Switch to kernel stack
609 leal 0x44(%esp,1),%esi # Base of frame
610 andb $~0x2,tss_desc+0x5 # Clear TSS busy
611 movb $SEL_TSS,%cl # Set task
612 ltr %cx # register
613/*
562 movl %ebx,MEM_ESPR-0x0c # mode return trampoline
563 movl $rret_tramp,%ebx # Set return trampoline
564 movl %ebx,MEM_ESPR-0x10 # CS:IP
565 movl %eax,MEM_ESPR-0x16 # Real mode target CS:IP
566 ljmpw $SEL_RCODE,$intusr.7 # Change to 16-bit segment
567 .code16
568intusr.7: movl %cr0,%eax # Leave
569 dec %al # protected

--- 57 unchanged lines hidden (view full) ---

627 movw %cx,%ds # seg
628 movw %cx,%es # regs
629 movl MEM_ESPR-0x04,%esp # Switch to kernel stack
630 leal 0x44(%esp,1),%esi # Base of frame
631 andb $~0x2,tss_desc+0x5 # Clear TSS busy
632 movb $SEL_TSS,%cl # Set task
633 ltr %cx # register
634/*
614 * Now we are back in protected mode. Copy the registers off of the real
615 * mode stack onto the kernel stack. Also, initialize all the seg regs on
616 * the kernel stack.
635 * Now we are back in protected mode. The kernel stack frame set up
636 * before entering real mode is still intact. For hardware interrupts,
637 * leave the frame unchanged.
638 */
639 cmpl $0,MEM_ESPR-0x08 # Leave saved regs unchanged
640 jz rret_tramp.3 # for hardware ints
641/*
642 * For V86 calls, copy the registers off of the real mode stack onto
643 * the kernel stack as we want their updated values. Also, initialize
644 * the segment registers on the kernel stack.
617 *
618 * Note that the %esp in the kernel stack after this is garbage, but popa
619 * ignores it, so we don't have to fix it up.
620 */
621 leal -0x18(%esi),%edi # Kernel stack GP regs
622 pushl %esi # Save
623 movl $MEM_ESPR-0x0c,%esi # Real mode stack GP regs
624 movl $8,%ecx # Copy GP regs from
625 rep # real mode stack
626 movsl # to kernel stack
645 *
646 * Note that the %esp in the kernel stack after this is garbage, but popa
647 * ignores it, so we don't have to fix it up.
648 */
649 leal -0x18(%esi),%edi # Kernel stack GP regs
650 pushl %esi # Save
651 movl $MEM_ESPR-0x0c,%esi # Real mode stack GP regs
652 movl $8,%ecx # Copy GP regs from
653 rep # real mode stack
654 movsl # to kernel stack
627 popl %esi # Restore
628 movl $SEL_UDATA,%eax # Selector for data seg regs
629 movl $4,%ecx # Initialize %ds,
630 rep # %es, %fs, and
631 stosl # %gs
632/*
655 movl $SEL_UDATA,%eax # Selector for data seg regs
656 movl $4,%ecx # Initialize %ds,
657 rep # %es, %fs, and
658 stosl # %gs
659/*
633 * If this was a V86 call, copy the saved seg regs on the real mode stack
634 * back over to the btx_v86 structure. Also, conditionally update the saved
635 * eflags on the kernel stack based on the flags from the user.
660 * For V86 calls, copy the saved seg regs on the real mode stack back
661 * over to the btx_v86 structure. Also, conditionally update the
662 * saved eflags on the kernel stack based on the flags from the user.
636 */
637 movl MEM_ESPR-0x08,%ecx # Get btx_v86 ptr
663 */
664 movl MEM_ESPR-0x08,%ecx # Get btx_v86 ptr
638 jecxz rret_tramp.3 # Skip for hardware ints
639 leal V86_GS(%ecx),%edi # %edi => btx_v86 seg regs
665 leal V86_GS(%ecx),%edi # %edi => btx_v86 seg regs
640 pushl %esi # Save
641 leal MEM_ESPR-0x2c,%esi # %esi => real mode seg regs
642 xchgl %ecx,%edx # Save btx_v86 ptr
643 movl $4,%ecx # Copy seg regs
644 rep # from real mode stack
645 movsl # to btx_v86
646 popl %esi # Restore
647 movl V86_CTL(%edx),%edx # Read V86 control flags
648 testl $V86F_FLAGS,%edx # User wants flags?

--- 399 unchanged lines hidden ---
666 leal MEM_ESPR-0x2c,%esi # %esi => real mode seg regs
667 xchgl %ecx,%edx # Save btx_v86 ptr
668 movl $4,%ecx # Copy seg regs
669 rep # from real mode stack
670 movsl # to btx_v86
671 popl %esi # Restore
672 movl V86_CTL(%edx),%edx # Read V86 control flags
673 testl $V86F_FLAGS,%edx # User wants flags?

--- 399 unchanged lines hidden ---