Back to home page

Quest Cross Reference

 
 

    


0001 /* -*- Mode: asm; comment-start: "\/*"; comment-end: "*\/"; indent-tabs-mode: nil -*- */
0002 
0003 /*
0004  *
0005  * interrupt.S
0006  *
0007  */
0008 
0009 /* The movw $0x10...in SREGS_SAVE forces subsequent operation on the
0010  * kernel data segment by loading the appropriate segment
0011  * registers */
0012 
0013 #include "arch/i386-percpu.h"
0014 
0015 #define SREGS_SAVE               \
0016         pushw %ds;               \
0017         pushw %es;               \
0018         pushw %fs;               \
0019         pushw %gs;               \
0020                                  \
0021         pushl %edx;              \
0022         movw $0x10, %dx;         \
0023         movw %dx, %ds;           \
0024         movw %dx, %es;           \
0025         movw %dx, %gs;           \
0026         movl %PER_CPU_DBG, %edx; \
0027         movw %dx, %PER_CPU_SEG;  \
0028                                  \
0029         popl %edx
0030 
0031 #define REGS_RESTORE                                           \
0032         pushfl;                                                \
0033         popl %edx; /* Get eflags into edx and clear NT flag */ \
0034         andl $0xFFFFBFFF, %edx;                                \
0035         pushl %edx;                                            \
0036         popfl;                                                 \
0037                                                                \
0038         popw %gs;                                              \
0039         popw %fs;                                              \
0040         popw %es;                                              \
0041         popw %ds; 
0042 
0043 #define SREGS_RESTORE \
0044         REGS_RESTORE  \
0045         iret;
0046 
0047         
0048         .text
0049         .globl interrupt0
0050         .globl interrupt1
0051         .globl interrupt2
0052         .globl interrupt3
0053         .globl interrupt4
0054         .globl interrupt5
0055         .globl interrupt6
0056         .globl interrupt7
0057         .globl interrupt8
0058         .globl interrupt9
0059         .globl interrupta
0060         .globl interruptb
0061         .globl interruptc
0062         .globl interruptd
0063         .globl interrupte
0064         .globl interruptf
0065         .globl interrupt10
0066         .globl interrupt11
0067         .globl interrupt12
0068         .globl interrupt13
0069         .globl interrupt
0070         .globl syscall0
0071         .globl syscall1
0072         .globl syscall2
0073         .globl syscall3
0074         .globl syscall4
0075         .globl syscall5
0076         .globl syscall6
0077         .globl syscall7
0078         .globl syscall8
0079         .globl syscall9
0080         .globl syscalla
0081         .globl syscallb
0082         .globl syscallc
0083         .globl timer
0084         .globl soundcard
0085         
0086         /* FIXME these are temporary debugging aids... ultimately these
0087         interrupts should be handled by task gates to the process server,
0088         and this code will go away */           
0089 interrupt0:
0090         pushl $0
0091         pushl $0
0092         SREGS_SAVE
0093         pushal
0094     call handle_interrupt
0095     popal
0096         REGS_RESTORE
0097         addl $8, %esp
0098         iret 
0099 
0100 
0101 interrupt1:
0102         pushl $0
0103         pushl $1
0104         SREGS_SAVE
0105         pushal
0106     call handle_interrupt
0107     popal
0108         REGS_RESTORE
0109         addl $8, %esp
0110         iret 
0111         
0112 interrupt2:
0113         pushl $0
0114         pushl $2
0115         SREGS_SAVE
0116         pushal
0117     call handle_interrupt
0118     popal
0119         REGS_RESTORE
0120         addl $8, %esp
0121         iret 
0122 
0123 interrupt3:
0124         pushl $0
0125         pushl $3
0126         SREGS_SAVE
0127         pushal
0128     call handle_interrupt
0129     popal
0130         REGS_RESTORE
0131         addl $8, %esp
0132         iret 
0133 
0134 interrupt4:
0135         pushl $0
0136         pushl $4
0137         SREGS_SAVE
0138         pushal
0139     call handle_interrupt
0140     popal
0141         REGS_RESTORE
0142         addl $8, %esp
0143         iret 
0144 
0145 interrupt5:
0146         pushl $0
0147         pushl $5
0148         SREGS_SAVE
0149         pushal
0150     call handle_interrupt
0151     popal
0152         REGS_RESTORE
0153         addl $8, %esp
0154         iret 
0155 
0156 
0157 interrupt6:
0158         pushl $0
0159         pushl $6
0160         SREGS_SAVE
0161         pushal
0162     call handle_interrupt
0163     popal
0164         REGS_RESTORE
0165         addl $8, %esp
0166         iret 
0167 
0168 interrupt7:
0169         pushl $0
0170         pushl $7
0171         SREGS_SAVE
0172         pushal
0173     call handle_interrupt
0174     popal
0175         REGS_RESTORE
0176         addl $8, %esp
0177         iret 
0178 
0179 interrupt8:
0180         pushl $8
0181         SREGS_SAVE
0182         pushal
0183     call handle_interrupt
0184     popal
0185         REGS_RESTORE
0186         addl $8, %esp
0187         iret 
0188 
0189 interrupt9:
0190         pushl $0
0191         pushl $9
0192         SREGS_SAVE
0193         pushal
0194     call handle_interrupt
0195     popal
0196         REGS_RESTORE
0197         addl $8, %esp
0198         iret 
0199 
0200 interrupta:
0201         pushl $0xA
0202         SREGS_SAVE
0203         pushal
0204     call handle_interrupt
0205     popal
0206         REGS_RESTORE
0207         addl $8, %esp
0208         iret 
0209 
0210 interruptb:
0211         pushl $0xB
0212         SREGS_SAVE
0213         pushal
0214     call handle_interrupt
0215     popal
0216         REGS_RESTORE
0217         addl $8, %esp
0218         iret 
0219 
0220 interruptc:
0221         pushl $0xC
0222         SREGS_SAVE
0223         pushal
0224     call handle_interrupt
0225     popal
0226         REGS_RESTORE
0227         addl $8, %esp
0228         iret 
0229 
0230 interruptd:
0231         pushl $0xD
0232         SREGS_SAVE
0233         pushal
0234     call handle_interrupt
0235     popal
0236         REGS_RESTORE
0237         addl $8, %esp
0238         iret 
0239 
0240 interrupte:
0241         pushl $0xE
0242         SREGS_SAVE
0243         pushal
0244     call handle_interrupt
0245     popal
0246         REGS_RESTORE
0247         addl $8, %esp
0248         iret 
0249 
0250 interruptf:
0251         pushl $0
0252         pushl $0xF
0253         SREGS_SAVE
0254         pushal
0255     call handle_interrupt
0256     popal
0257         REGS_RESTORE
0258         addl $8, %esp
0259         iret
0260 
0261         
0262 interrupt10:
0263         pushl $0
0264         pushl $0x10
0265         SREGS_SAVE
0266         pushal
0267     call handle_interrupt
0268     popal
0269         REGS_RESTORE
0270         addl $8, %esp
0271         iret
0272 
0273 interrupt11:
0274         pushl $0x11
0275         SREGS_SAVE
0276         pushal
0277     call handle_interrupt
0278     popal
0279         REGS_RESTORE
0280         addl $8, %esp
0281         iret 
0282         
0283 interrupt12:
0284         pushl $0
0285         pushl $0x12
0286         SREGS_SAVE
0287         pushal
0288     call handle_interrupt
0289     popal
0290         REGS_RESTORE
0291         addl $8, %esp
0292         iret 
0293         
0294 interrupt13:
0295         pushl $0
0296         pushl $0x13
0297         SREGS_SAVE
0298         pushal
0299     call handle_interrupt
0300     popal
0301         REGS_RESTORE
0302         addl $8, %esp
0303         iret                    
0304 
0305         
0306     /* Handler's Stack: (Figure 5-4, Intel Manual vol. 3)
0307      *
0308      * esp[6]: SS
0309      * esp[5]: ESP
0310      * esp[4]: EFLAGS
0311      * esp[3]: CS 
0312      * esp[2]: EIP 
0313      * esp[1]: ERROR CODE
0314      *
0315      */
0316 
0317 
0318 /* Need to setup syscall stubs */
0319 /* syscall0 is a putchar style call to a video server */ 
0320 syscall0:
0321         SREGS_SAVE
0322         
0323         pushl %ebx
0324         pushl %eax
0325         call handle_syscall0
0326         popl  %eax
0327         popl  %ebx              /* preserve */
0328 
0329         SREGS_RESTORE
0330 
0331 /* For now, this is the fork syscall - will move to a fork server */
0332 syscall1:
0333         SREGS_SAVE
0334         pushl %esp  /* Will use this later to create a TSS with
0335                      * duplicate parent register values
0336                      * See DuplicateTSS() for more info
0337                      */
0338         
0339 
0340         pushl %ebp  /* Also needed to populate child TSS */
0341         call _fork
0342         addl $8, %esp
0343         
0344         SREGS_RESTORE
0345 
0346 /* switch_to syscall supporting coroutines (voluntarily relinquishing CPU) */
0347 syscall2:
0348         SREGS_SAVE
0349 
0350         pushl %eax /* Destination TSS argument */
0351         call _switch_to
0352         addl $4, %esp   
0353         
0354         SREGS_RESTORE
0355 
0356 
0357 /* exec syscall wrapper */      
0358 syscall3:
0359         SREGS_SAVE
0360         pushl %esp  /* 
0361                      *  Use this to patch up esp, eip for new program
0362                      */
0363         pushl %ebx
0364         pushl %eax
0365         call _exec
0366         addl $12, %esp
0367         
0368         SREGS_RESTORE
0369 
0370 /* getchar from keyboard driver */      
0371 syscall4:
0372         SREGS_SAVE
0373 
0374         pushl %ebx
0375         call _getchar
0376         popl %ebx
0377         
0378         SREGS_RESTORE
0379 
0380 /* open */      
0381 syscall5:
0382         SREGS_SAVE
0383 
0384         pushl %ebx              /* flags */
0385         pushl %eax              /* pathname */
0386         call _open
0387         addl $4, %esp
0388         popl %ebx               /* preserve */
0389         
0390         SREGS_RESTORE           
0391         
0392         
0393 /* read */      
0394 syscall6:
0395         SREGS_SAVE
0396 
0397         pushl %ecx              /* byte count */
0398         pushl %ebx              /* buf */
0399         pushl %eax              /* pathname */
0400         call _read
0401         addl $4, %esp
0402         popl %ebx
0403         popl %ecx               /* preserve */
0404         
0405         SREGS_RESTORE
0406 
0407 /* uname */     
0408 syscall7:
0409         SREGS_SAVE
0410 
0411         pushl %eax              /* address of resultant string in user-space */
0412         call _uname
0413         addl $4, %esp
0414         
0415         SREGS_RESTORE
0416 
0417 /* meminfo */   
0418 syscall8:
0419         SREGS_SAVE
0420 
0421         pushl %edx
0422         pushl %eax
0423         call _meminfo
0424         addl $4, %esp
0425         popl %edx               /* preserve */
0426         
0427         SREGS_RESTORE
0428 
0429 /* time */      
0430 syscall9:
0431         SREGS_SAVE
0432 
0433         call _time
0434         
0435         SREGS_RESTORE
0436 
0437 /* _exit */     
0438 syscalla:
0439         SREGS_SAVE
0440 
0441         pushl %eax
0442         call __exit
0443         addl $4, %esp           /* Shouldn't really get here... */
0444         
0445         SREGS_RESTORE
0446 
0447 /* waitpid */   
0448 syscallb:
0449         SREGS_SAVE
0450 
0451         pushl %eax
0452         call _waitpid
0453         addl $4, %esp                   
0454         
0455         SREGS_RESTORE
0456 
0457 
0458 /* sched_setparam */    
0459 syscallc:
0460         SREGS_SAVE
0461 
0462         pushl %ebx
0463         pushl %eax
0464         call _sched_setparam
0465         addl $4, %esp
0466         popl  %ebx              /* preserve */
0467         
0468         SREGS_RESTORE   
0469 
0470 /* IRQ0 - system timer */
0471 timer:  
0472         pushal
0473         SREGS_SAVE
0474 
0475         pushfl
0476         popl %edx
0477         andl $0x4000, %edx
0478         jne panic
0479         
0480         call _timer
0481 
0482         REGS_RESTORE
0483         popal
0484 
0485         iret
0486         
0487 /* IRQ5 - soundcard --??-- in future, don't hardcode to specific IRQ */
0488 soundcard:      
0489         pushal
0490         SREGS_SAVE
0491 
0492         pushfl
0493         popl %edx
0494         andl $0x4000, %edx
0495         jne panic
0496         
0497         call _soundcard
0498 
0499         REGS_RESTORE
0500         popal
0501 
0502         iret            
0503         
0504         
0505 interrupt:
0506         pushl $0
0507         pushl $0xFFFFFFFF
0508         SREGS_SAVE
0509         pushal
0510     call handle_interrupt
0511     popal
0512         REGS_RESTORE
0513         addl $8, %esp
0514         iret
0515 
0516         .globl interruptIGN
0517 interruptIGN:
0518         iret
0519 
0520         .global interrupt29
0521 interrupt29:
0522         pushal
0523         SREGS_SAVE
0524         call _interrupt29
0525         REGS_RESTORE
0526         popal
0527         iret
0528         
0529         .global interrupt3e
0530 interrupt3e:
0531         pushal
0532         SREGS_SAVE
0533         call _interrupt3e
0534         REGS_RESTORE
0535         popal
0536         iret
0537 
0538 
0539 #define EXC(n)                 \
0540         .globl interrupt##n;   \
0541 interrupt##n:                  \
0542         pushl $0;              \
0543         pushl $0x##n;          \
0544         SREGS_SAVE;            \
0545         pushal
0546     call handle_interrupt
0547     popal; \
0548         REGS_RESTORE;          \
0549         addl $8, %esp;         \
0550         iret
0551 
0552 EXC(14)
0553 EXC(15)
0554 EXC(16)
0555 EXC(17)
0556 EXC(18)
0557 EXC(19)
0558 EXC(1a)
0559 EXC(1b)
0560 EXC(1c)
0561 EXC(1d)
0562 EXC(1e)
0563 EXC(1f)
0564 #undef EXC
0565 
0566 #define INT(n)                \
0567         .globl interrupt##n;  \
0568 interrupt##n:                 \
0569         pushal;               \
0570         SREGS_SAVE;           \
0571         pushl $0x##n;         \
0572         call dispatch_vector; \
0573         addl $4, %esp;        \
0574         REGS_RESTORE;         \
0575         popal;                \
0576         iret
0577 
0578 INT(20)
0579 INT(21)
0580 INT(22)
0581 INT(23)
0582 INT(24)
0583 INT(25)
0584 INT(26)
0585 INT(27)
0586 INT(28)
0587 INT(2a)
0588 INT(2b)
0589 INT(2c)
0590 INT(2d)
0591 INT(2e)
0592 INT(2f)
0593 INT(30)
0594 INT(31)
0595 INT(32)
0596 INT(33)
0597 INT(34)
0598 INT(35)
0599 INT(36)
0600 INT(37)
0601 INT(38)
0602 INT(39)
0603 INT(3a)
0604 INT(3b)
0605 INT(3c)
0606 INT(3d)
0607 INT(3f)
0608 
0609 INT(40)
0610 INT(41)
0611 INT(42)
0612 INT(43)
0613 INT(44)
0614 INT(45)
0615 INT(46)
0616 INT(47)
0617 INT(48)
0618 INT(49)
0619 INT(4a)
0620 INT(4b)
0621 INT(4c)
0622 INT(4d)
0623 INT(4e)
0624 INT(4f)
0625 INT(50)
0626 INT(51)
0627 INT(52)
0628 INT(53)
0629 INT(54)
0630 INT(55)
0631 INT(56)
0632 INT(57)
0633 INT(58)
0634 INT(59)
0635 INT(5a)
0636 INT(5b)
0637 INT(5c)
0638 INT(5d)
0639 INT(5e)
0640 INT(5f)
0641 INT(60)
0642 INT(61)
0643 INT(62)
0644 INT(63)
0645 INT(64)
0646 INT(65)
0647 INT(66)
0648 INT(67)
0649 INT(68)
0650 INT(69)
0651 INT(6a)
0652 INT(6b)
0653 INT(6c)
0654 INT(6d)
0655 INT(6e)
0656 INT(6f)
0657 INT(70)
0658 INT(71)
0659 INT(72)
0660 INT(73)
0661 INT(74)
0662 INT(75)
0663 INT(76)
0664 INT(77)
0665 INT(78)
0666 INT(79)
0667 INT(7a)
0668 INT(7b)
0669 INT(7c)
0670 INT(7d)
0671 INT(7e)
0672 INT(7f)
0673 INT(80)
0674 INT(81)
0675 INT(82)
0676 INT(83)
0677 INT(84)
0678 INT(85)
0679 INT(86)
0680 INT(87)
0681 INT(88)
0682 INT(89)
0683 INT(8a)
0684 INT(8b)
0685 INT(8c)
0686 INT(8d)
0687 INT(8e)
0688 INT(8f)
0689 INT(90)
0690 INT(91)
0691 INT(92)
0692 INT(93)
0693 INT(94)
0694 INT(95)
0695 INT(96)
0696 INT(97)
0697 INT(98)
0698 INT(99)
0699 INT(9a)
0700 INT(9b)
0701 INT(9c)
0702 INT(9d)
0703 INT(9e)
0704 INT(9f)
0705 INT(a0)
0706 INT(a1)
0707 INT(a2)
0708 INT(a3)
0709 INT(a4)
0710 INT(a5)
0711 INT(a6)
0712 INT(a7)
0713 INT(a8)
0714 INT(a9)
0715 INT(aa)
0716 INT(ab)
0717 INT(ac)
0718 INT(ad)
0719 INT(ae)
0720 INT(af)
0721 INT(b0)
0722 INT(b1)
0723 INT(b2)
0724 INT(b3)
0725 INT(b4)
0726 INT(b5)
0727 INT(b6)
0728 INT(b7)
0729 INT(b8)
0730 INT(b9)
0731 INT(ba)
0732 INT(bb)
0733 INT(bc)
0734 INT(bd)
0735 INT(be)
0736 INT(bf)
0737 INT(c0)
0738 INT(c1)
0739 INT(c2)
0740 INT(c3)
0741 INT(c4)
0742 INT(c5)
0743 INT(c6)
0744 INT(c7)
0745 INT(c8)
0746 INT(c9)
0747 INT(ca)
0748 INT(cb)
0749 INT(cc)
0750 INT(cd)
0751 INT(ce)
0752 INT(cf)
0753 INT(d0)
0754 INT(d1)
0755 INT(d2)
0756 INT(d3)
0757 INT(d4)
0758 INT(d5)
0759 INT(d6)
0760 INT(d7)
0761 INT(d8)
0762 INT(d9)
0763 INT(da)
0764 INT(db)
0765 INT(dc)
0766 INT(dd)
0767 INT(de)
0768 INT(df)
0769 INT(e0)
0770 INT(e1)
0771 INT(e2)
0772 INT(e3)
0773 INT(e4)
0774 INT(e5)
0775 INT(e6)
0776 INT(e7)
0777 INT(e8)
0778 INT(e9)
0779 INT(ea)
0780 INT(eb)
0781 INT(ec)
0782 INT(ed)
0783 INT(ee)
0784 INT(ef)
0785 INT(f0)
0786 INT(f1)
0787 INT(f2)
0788 INT(f3)
0789 INT(f4)
0790 INT(f5)
0791 INT(f6)
0792 INT(f7)
0793 INT(f8)
0794 INT(f9)
0795 INT(fa)
0796 INT(fb)
0797 INT(fc)
0798 INT(fd)
0799 INT(fe)
0800 INT(ff)
0801 #undef INT
0802 
0803 /* vi: set et sw=8 sts=8: */