]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/isa/apic_ipl.s
Add ACPI S2-S4BIOS Suspend/Resume code.
[FreeBSD/FreeBSD.git] / sys / i386 / isa / apic_ipl.s
1 /*-
2  * Copyright (c) 1997, by Steve Passe
3  * 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$
26  */
27
28         .data
29         ALIGN_DATA
30
31 /*
32  * Note:
33  *      This is the UP equivilant of _imen.
34  *      It is OPAQUE, and must NOT be accessed directly.
35  *      It MUST be accessed along with the IO APIC as a 'critical region'.
36  *      Accessed by:
37  *              INTREN()
38  *              INTRDIS()
39  *              imen_dump()
40  */
41         .p2align 2                              /* MUST be 32bit aligned */
42         .globl apic_imen
43 apic_imen:
44         .long   HWI_MASK
45
46         .text
47         SUPERALIGN_TEXT
48
49 /******************************************************************************
50  * XXX FIXME: figure out where these belong.
51  */
52
53 /* this nonsense is to verify that masks ALWAYS have 1 and only 1 bit set */
54 #define QUALIFY_MASKS_NOT
55
56 #ifdef QUALIFY_MASKS
57 #define QUALIFY_MASK            \
58         btrl    %ecx, %eax ;    \
59         andl    %eax, %eax ;    \
60         jz      1f ;            \
61         pushl   $bad_mask ;     \
62         call    panic ;         \
63 1:
64
65 bad_mask:       .asciz  "bad mask"
66 #else
67 #define QUALIFY_MASK
68 #endif
69
70 /*
71  * (soon to be) MP-safe function to clear ONE INT mask bit.
72  * The passed arg is a 32bit u_int MASK.
73  * It sets the associated bit in _apic_imen.
74  * It sets the mask bit of the associated IO APIC register.
75  */
76 ENTRY(INTREN)
77         pushfl                          /* save state of EI flag */
78         cli                             /* prevent recursion */
79         IMASK_LOCK                      /* enter critical reg */
80
81         movl    8(%esp), %eax           /* mask into %eax */
82         bsfl    %eax, %ecx              /* get pin index */
83         btrl    %ecx, apic_imen         /* update apic_imen */
84
85         QUALIFY_MASK
86
87         shll    $4, %ecx
88         movl    CNAME(int_to_apicintpin) + 8(%ecx), %edx
89         movl    CNAME(int_to_apicintpin) + 12(%ecx), %ecx
90         testl   %edx, %edx
91         jz      1f
92
93         movl    %ecx, (%edx)            /* write the target register index */
94         movl    16(%edx), %eax          /* read the target register data */
95         andl    $~IOART_INTMASK, %eax   /* clear mask bit */
96         movl    %eax, 16(%edx)          /* write the APIC register data */
97 1:      
98         IMASK_UNLOCK                    /* exit critical reg */
99         popfl                           /* restore old state of EI flag */
100         ret
101
102 /*
103  * (soon to be) MP-safe function to set ONE INT mask bit.
104  * The passed arg is a 32bit u_int MASK.
105  * It clears the associated bit in _apic_imen.
106  * It clears the mask bit of the associated IO APIC register.
107  */
108 ENTRY(INTRDIS)
109         pushfl                          /* save state of EI flag */
110         cli                             /* prevent recursion */
111         IMASK_LOCK                      /* enter critical reg */
112
113         movl    8(%esp), %eax           /* mask into %eax */
114         bsfl    %eax, %ecx              /* get pin index */
115         btsl    %ecx, apic_imen         /* update apic_imen */
116
117         QUALIFY_MASK
118
119         shll    $4, %ecx
120         movl    CNAME(int_to_apicintpin) + 8(%ecx), %edx
121         movl    CNAME(int_to_apicintpin) + 12(%ecx), %ecx
122         testl   %edx, %edx
123         jz      1f
124
125         movl    %ecx, (%edx)            /* write the target register index */
126         movl    16(%edx), %eax          /* read the target register data */
127         orl     $IOART_INTMASK, %eax    /* set mask bit */
128         movl    %eax, 16(%edx)          /* write the APIC register data */
129 1:      
130         IMASK_UNLOCK                    /* exit critical reg */
131         popfl                           /* restore old state of EI flag */
132         ret