The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/icu_vector.s

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *      from: vector.s, 386BSD 0.1 unknown origin
    3  * $FreeBSD$
    4  */
    5 
    6 /*
    7  * modified for PC98 by Kakefuda
    8  */
    9 
   10 #ifdef PC98
   11 #define ICU_IMR_OFFSET          2       /* IO_ICU{1,2} + 2 */
   12 #else
   13 #define ICU_IMR_OFFSET          1       /* IO_ICU{1,2} + 1 */
   14 #endif
   15 
   16 #define ICU_EOI                 0x20    /* XXX - define elsewhere */
   17 
   18 #define IRQ_BIT(irq_num)        (1 << ((irq_num) % 8))
   19 #define IRQ_BYTE(irq_num)       ((irq_num) >> 3)
   20 
   21 #ifdef AUTO_EOI_1
   22 #define ENABLE_ICU1             /* use auto-EOI to reduce i/o */
   23 #define OUTB_ICU1
   24 #else
   25 #define ENABLE_ICU1 \
   26         movb    $ICU_EOI,%al ;  /* as soon as possible send EOI ... */ \
   27         OUTB_ICU1               /* ... to clear in service bit */
   28 #define OUTB_ICU1 \
   29         outb    %al,$IO_ICU1
   30 #endif
   31 
   32 #ifdef AUTO_EOI_2
   33 /*
   34  * The data sheet says no auto-EOI on slave, but it sometimes works.
   35  */
   36 #define ENABLE_ICU1_AND_2       ENABLE_ICU1
   37 #else
   38 #define ENABLE_ICU1_AND_2 \
   39         movb    $ICU_EOI,%al ;  /* as above */ \
   40         outb    %al,$IO_ICU2 ;  /* but do second icu first ... */ \
   41         OUTB_ICU1               /* ... then first icu (if !AUTO_EOI_1) */
   42 #endif
   43 
   44 /*
   45  * Macros for interrupt interrupt entry, call to handler, and exit.
   46  */
   47 
   48 #define FAST_INTR(irq_num, vec_name, enable_icus) \
   49         .text ; \
   50         SUPERALIGN_TEXT ; \
   51 IDTVEC(vec_name) ; \
   52         pushl   %eax ;          /* save only call-used registers */ \
   53         pushl   %ecx ; \
   54         pushl   %edx ; \
   55         pushl   %ds ; \
   56         MAYBE_PUSHL_ES ; \
   57         movl    $KDSEL,%eax ; \
   58         movl    %ax,%ds ; \
   59         MAYBE_MOVW_AX_ES ; \
   60         FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
   61         pushl   _intr_unit + (irq_num) * 4 ; \
   62         call    *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
   63         enable_icus ;           /* (re)enable ASAP (helps edge trigger?) */ \
   64         addl    $4,%esp ; \
   65         incl    _cnt+V_INTR ;   /* book-keeping can wait */ \
   66         movl    _intr_countp + (irq_num) * 4,%eax ; \
   67         incl    (%eax) ; \
   68         movl    _cpl,%eax ;     /* are we unmasking pending HWIs or SWIs? */ \
   69         notl    %eax ; \
   70         andl    _ipending,%eax ; \
   71         jne     2f ;            /* yes, maybe handle them */ \
   72 1: ; \
   73         MEXITCOUNT ; \
   74         MAYBE_POPL_ES ; \
   75         popl    %ds ; \
   76         popl    %edx ; \
   77         popl    %ecx ; \
   78         popl    %eax ; \
   79         iret ; \
   80 ; \
   81         ALIGN_TEXT ; \
   82 2: ; \
   83         cmpb    $3,_intr_nesting_level ;        /* is there enough stack? */ \
   84         jae     1b ;            /* no, return */ \
   85         movl    _cpl,%eax ; \
   86         /* XXX next line is probably unnecessary now. */ \
   87         movl    $HWI_MASK|SWI_MASK,_cpl ;       /* limit nesting ... */ \
   88         incb    _intr_nesting_level ;   /* ... really limit it ... */ \
   89         sti ;                   /* ... to do this as early as possible */ \
   90         MAYBE_POPL_ES ;         /* discard most of thin frame ... */ \
   91         popl    %ecx ;          /* ... original %ds ... */ \
   92         popl    %edx ; \
   93         xchgl   %eax,4(%esp) ;  /* orig %eax; save cpl */ \
   94         pushal ;                /* build fat frame (grrr) ... */ \
   95         pushl   %ecx ;          /* ... actually %ds ... */ \
   96         pushl   %es ; \
   97         movl    $KDSEL,%eax ; \
   98         movl    %ax,%es ; \
   99         movl    (2+8+0)*4(%esp),%ecx ;  /* ... %ecx from thin frame ... */ \
  100         movl    %ecx,(2+6)*4(%esp) ;    /* ... to fat frame ... */ \
  101         movl    (2+8+1)*4(%esp),%eax ;  /* ... cpl from thin frame */ \
  102         pushl   %eax ; \
  103         subl    $4,%esp ;       /* junk for unit number */ \
  104         MEXITCOUNT ; \
  105         jmp     _doreti
  106 
  107 #define INTR(irq_num, vec_name, icu, enable_icus, reg) \
  108         .text ; \
  109         SUPERALIGN_TEXT ; \
  110 IDTVEC(vec_name) ; \
  111         pushl   $0 ;            /* dummy error code */ \
  112         pushl   $0 ;            /* dummy trap type */ \
  113         pushal ; \
  114         pushl   %ds ;           /* save our data and extra segments ... */ \
  115         pushl   %es ; \
  116         movl    $KDSEL,%eax ;   /* ... and reload with kernel's own ... */ \
  117         movl    %ax,%ds ;       /* ... early for obsolete reasons */ \
  118         movl    %ax,%es ; \
  119         movb    _imen + IRQ_BYTE(irq_num),%al ; \
  120         orb     $IRQ_BIT(irq_num),%al ; \
  121         movb    %al,_imen + IRQ_BYTE(irq_num) ; \
  122         outb    %al,$icu+ICU_IMR_OFFSET ; \
  123         enable_icus ; \
  124         movl    _cpl,%eax ; \
  125         testb   $IRQ_BIT(irq_num),%reg ; \
  126         jne     2f ; \
  127         incb    _intr_nesting_level ; \
  128 __CONCAT(Xresume,irq_num): ; \
  129         FAKE_MCOUNT(12*4(%esp)) ;       /* XXX late to avoid double count */ \
  130         incl    _cnt+V_INTR ;   /* tally interrupts */ \
  131         movl    _intr_countp + (irq_num) * 4,%eax ; \
  132         incl    (%eax) ; \
  133         movl    _cpl,%eax ; \
  134         pushl   %eax ; \
  135         pushl   _intr_unit + (irq_num) * 4 ; \
  136         orl     _intr_mask + (irq_num) * 4,%eax ; \
  137         movl    %eax,_cpl ; \
  138         sti ; \
  139         call    *_intr_handler + (irq_num) * 4 ; \
  140         cli ;                   /* must unmask _imen and icu atomically */ \
  141         movb    _imen + IRQ_BYTE(irq_num),%al ; \
  142         andb    $~IRQ_BIT(irq_num),%al ; \
  143         movb    %al,_imen + IRQ_BYTE(irq_num) ; \
  144         outb    %al,$icu+ICU_IMR_OFFSET ; \
  145         sti ;                   /* XXX _doreti repeats the cli/sti */ \
  146         MEXITCOUNT ; \
  147         /* We could usually avoid the following jmp by inlining some of */ \
  148         /* _doreti, but it's probably better to use less cache. */ \
  149         jmp     _doreti ; \
  150 ; \
  151         ALIGN_TEXT ; \
  152 2: ; \
  153         /* XXX skip mcounting here to avoid double count */ \
  154         orb     $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \
  155         popl    %es ; \
  156         popl    %ds ; \
  157         popal ; \
  158         addl    $4+4,%esp ; \
  159         iret
  160 
  161 MCOUNT_LABEL(bintr)
  162         FAST_INTR(0,fastintr0, ENABLE_ICU1)
  163         FAST_INTR(1,fastintr1, ENABLE_ICU1)
  164         FAST_INTR(2,fastintr2, ENABLE_ICU1)
  165         FAST_INTR(3,fastintr3, ENABLE_ICU1)
  166         FAST_INTR(4,fastintr4, ENABLE_ICU1)
  167         FAST_INTR(5,fastintr5, ENABLE_ICU1)
  168         FAST_INTR(6,fastintr6, ENABLE_ICU1)
  169         FAST_INTR(7,fastintr7, ENABLE_ICU1)
  170         FAST_INTR(8,fastintr8, ENABLE_ICU1_AND_2)
  171         FAST_INTR(9,fastintr9, ENABLE_ICU1_AND_2)
  172         FAST_INTR(10,fastintr10, ENABLE_ICU1_AND_2)
  173         FAST_INTR(11,fastintr11, ENABLE_ICU1_AND_2)
  174         FAST_INTR(12,fastintr12, ENABLE_ICU1_AND_2)
  175         FAST_INTR(13,fastintr13, ENABLE_ICU1_AND_2)
  176         FAST_INTR(14,fastintr14, ENABLE_ICU1_AND_2)
  177         FAST_INTR(15,fastintr15, ENABLE_ICU1_AND_2)
  178         INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al)
  179         INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al)
  180         INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al)
  181         INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al)
  182         INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al)
  183         INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al)
  184         INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al)
  185         INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al)
  186         INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah)
  187         INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah)
  188         INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah)
  189         INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah)
  190         INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah)
  191         INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah)
  192         INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah)
  193         INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah)
  194 MCOUNT_LABEL(eintr)
  195 
  196         .data
  197         .globl  _ihandlers
  198 _ihandlers:                     /* addresses of interrupt handlers */
  199                                 /* actually resumption addresses for HWI's */
  200         .long   Xresume0, Xresume1, Xresume2, Xresume3 
  201         .long   Xresume4, Xresume5, Xresume6, Xresume7
  202         .long   Xresume8, Xresume9, Xresume10, Xresume11
  203         .long   Xresume12, Xresume13, Xresume14, Xresume15 
  204         .long   _swi_null, swi_net, _swi_null, _swi_null
  205         .long   _swi_vm, _swi_null, _swi_null, _swi_null
  206         .long   _swi_null, _swi_null, _swi_null, _swi_null
  207         .long   _swi_null, _swi_null, _softclock, swi_ast
  208 
  209 imasks:                         /* masks for interrupt handlers */
  210         .space  NHWI*4          /* padding; HWI masks are elsewhere */
  211 
  212         .long   SWI_TTY_MASK, SWI_NET_MASK, SWI_CAMNET_MASK, SWI_CAMBIO_MASK
  213         .long   SWI_VM_MASK, 0, 0, 0
  214         .long   0, 0, 0, 0
  215         .long   0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
  216 
  217 /*
  218  * Interrupt counters and names.  The format of these and the label names
  219  * must agree with what vmstat expects.  The tables are indexed by device
  220  * ids so that we don't have to move the names around as devices are
  221  * attached.
  222  */
  223 #include "vector.h"
  224         .globl  _intrcnt, _eintrcnt
  225 _intrcnt:
  226         .space  (NR_DEVICES + ICU_LEN) * 4
  227 _eintrcnt:
  228 
  229         .globl  _intrnames, _eintrnames
  230 _intrnames:
  231         .ascii  DEVICE_NAMES
  232         .asciz  "stray irq0"
  233         .asciz  "stray irq1"
  234         .asciz  "stray irq2"
  235         .asciz  "stray irq3"
  236         .asciz  "stray irq4"
  237         .asciz  "stray irq5"
  238         .asciz  "stray irq6"
  239         .asciz  "stray irq7"
  240         .asciz  "stray irq8"
  241         .asciz  "stray irq9"
  242         .asciz  "stray irq10"
  243         .asciz  "stray irq11"
  244         .asciz  "stray irq12"
  245         .asciz  "stray irq13"
  246         .asciz  "stray irq14"
  247         .asciz  "stray irq15"
  248 _eintrnames:
  249 
  250         .text

Cache object: 7e182d18a7a7a3908f12f9b96d10608c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.