Merge from vendor branch LIBPCAP:
[dragonfly.git] / sys / i386 / isa / apic_ipl.s
1 /*-
2  * Copyright (c) 1997, by Steve Passe,  All rights reserved.
3  * Copyright (c) 2003, by Matthew Dillon,  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. The name of the developer may NOT be used to endorse or promote products
11  *    derived from this software without specific prior written permission.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  * $FreeBSD: src/sys/i386/isa/apic_ipl.s,v 1.27.2.2 2000/09/30 02:49:35 ps Exp $
26  * $DragonFly: src/sys/i386/isa/Attic/apic_ipl.s,v 1.7 2003/07/06 21:23:49 dillon Exp $
27  */
28
29         .data
30         ALIGN_DATA
31
32         /*
33          * Interrupt mask for APIC interrupts, defaults to all hardware
34          * interrupts turned off.
35          */
36
37         .p2align 2                              /* MUST be 32bit aligned */
38
39         .globl apic_imen
40 apic_imen:
41         .long   HWI_MASK
42
43         .text
44         SUPERALIGN_TEXT
45
46         /*
47          * Functions to enable and disable a hardware interrupt.  Generally
48          * called with only one bit set in the mask but can handle multiple
49          * bits to present the same API as the ICU.
50          */
51
52 ENTRY(INTRDIS)
53         IMASK_LOCK                      /* enter critical reg */
54         movl    4(%esp),%eax
55 1:
56         bsfl    %eax,%ecx
57         jz      2f
58         btrl    %ecx,%eax
59         btsl    %ecx, apic_imen
60         shll    $4, %ecx
61         movl    CNAME(int_to_apicintpin) + 8(%ecx), %edx
62         movl    CNAME(int_to_apicintpin) + 12(%ecx), %ecx
63         testl   %edx, %edx
64         jz      2f
65         movl    %ecx, (%edx)            /* target register index */
66         orl     $IOART_INTMASK,16(%edx) /* set intmask in target apic reg */
67         jmp     1b
68 2:
69         IMASK_UNLOCK                    /* exit critical reg */
70         ret
71
72 ENTRY(INTREN)
73         IMASK_LOCK                      /* enter critical reg */
74         movl    4(%esp), %eax           /* mask into %eax */
75 1:
76         bsfl    %eax, %ecx              /* get pin index */
77         jz      2f
78         btrl    %ecx,%eax
79         btrl    %ecx, apic_imen         /* update apic_imen */
80         shll    $4, %ecx
81         movl    CNAME(int_to_apicintpin) + 8(%ecx), %edx
82         movl    CNAME(int_to_apicintpin) + 12(%ecx), %ecx
83         testl   %edx, %edx
84         jz      2f
85         movl    %ecx, (%edx)            /* write the target register index */
86         andl    $~IOART_INTMASK, 16(%edx) /* clear mask bit */
87         jmp     1b
88 2:      
89         IMASK_UNLOCK                    /* exit critical reg */
90         ret
91
92 /******************************************************************************
93  * 
94  */
95
96 /*
97  * u_int io_apic_write(int apic, int select);
98  */
99 ENTRY(io_apic_read)
100         movl    4(%esp), %ecx           /* APIC # */
101         movl    ioapic, %eax
102         movl    (%eax,%ecx,4), %edx     /* APIC base register address */
103         movl    8(%esp), %eax           /* target register index */
104         movl    %eax, (%edx)            /* write the target register index */
105         movl    16(%edx), %eax          /* read the APIC register data */
106         ret                             /* %eax = register value */
107
108 /*
109  * void io_apic_write(int apic, int select, int value);
110  */
111 ENTRY(io_apic_write)
112         movl    4(%esp), %ecx           /* APIC # */
113         movl    ioapic, %eax
114         movl    (%eax,%ecx,4), %edx     /* APIC base register address */
115         movl    8(%esp), %eax           /* target register index */
116         movl    %eax, (%edx)            /* write the target register index */
117         movl    12(%esp), %eax          /* target register value */
118         movl    %eax, 16(%edx)          /* write the APIC register data */
119         ret                             /* %eax = void */
120
121 /*
122  * Send an EOI to the local APIC.
123  */
124 ENTRY(apic_eoi)
125         movl    $0, lapic+0xb0
126         ret
127