[BACK]Return to cpufunc.h CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / include

Annotation of sys/arch/i386/include/cpufunc.h, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: cpufunc.h,v 1.13 2007/02/17 17:38:37 tom Exp $        */
                      2: /*     $NetBSD: cpufunc.h,v 1.8 1994/10/27 04:15:59 cgd Exp $  */
                      3:
                      4: /*
                      5:  * Copyright (c) 1993 Charles Hannum.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed by Charles Hannum.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
                     34: #ifndef _I386_CPUFUNC_H_
                     35: #define        _I386_CPUFUNC_H_
                     36:
                     37: #ifdef _KERNEL
                     38:
                     39: /*
                     40:  * Functions to provide access to i386-specific instructions.
                     41:  */
                     42:
                     43: #include <sys/cdefs.h>
                     44: #include <sys/types.h>
                     45:
                     46: #include <machine/specialreg.h>
                     47:
                     48: static __inline void invlpg(u_int);
                     49: static __inline void lidt(void *);
                     50: static __inline void lldt(u_short);
                     51: static __inline void ltr(u_short);
                     52: static __inline void lcr0(u_int);
                     53: static __inline u_int rcr0(void);
                     54: static __inline u_int rcr2(void);
                     55: static __inline void lcr3(u_int);
                     56: static __inline u_int rcr3(void);
                     57: static __inline void lcr4(u_int);
                     58: static __inline u_int rcr4(void);
                     59: static __inline void tlbflush(void);
                     60: static __inline void tlbflushg(void);
                     61: static __inline void disable_intr(void);
                     62: static __inline void enable_intr(void);
                     63: static __inline u_int read_eflags(void);
                     64: static __inline void write_eflags(u_int);
                     65: static __inline void wbinvd(void);
                     66: static __inline void wrmsr(u_int, u_int64_t);
                     67: static __inline u_int64_t rdmsr(u_int);
                     68: static __inline void breakpoint(void);
                     69:
                     70: static __inline void
                     71: invlpg(u_int addr)
                     72: {
                     73:         __asm __volatile("invlpg (%0)" : : "r" (addr) : "memory");
                     74: }
                     75:
                     76: static __inline void
                     77: lidt(void *p)
                     78: {
                     79:        __asm __volatile("lidt (%0)" : : "r" (p));
                     80: }
                     81:
                     82: static __inline void
                     83: lldt(u_short sel)
                     84: {
                     85:        __asm __volatile("lldt %0" : : "r" (sel));
                     86: }
                     87:
                     88: static __inline void
                     89: ltr(u_short sel)
                     90: {
                     91:        __asm __volatile("ltr %0" : : "r" (sel));
                     92: }
                     93:
                     94: static __inline void
                     95: lcr0(u_int val)
                     96: {
                     97:        __asm __volatile("movl %0,%%cr0" : : "r" (val));
                     98: }
                     99:
                    100: static __inline u_int
                    101: rcr0(void)
                    102: {
                    103:        u_int val;
                    104:        __asm __volatile("movl %%cr0,%0" : "=r" (val));
                    105:        return val;
                    106: }
                    107:
                    108: static __inline u_int
                    109: rcr2(void)
                    110: {
                    111:        u_int val;
                    112:        __asm __volatile("movl %%cr2,%0" : "=r" (val));
                    113:        return val;
                    114: }
                    115:
                    116: static __inline void
                    117: lcr3(u_int val)
                    118: {
                    119:        __asm __volatile("movl %0,%%cr3" : : "r" (val));
                    120: }
                    121:
                    122: static __inline u_int
                    123: rcr3(void)
                    124: {
                    125:        u_int val;
                    126:        __asm __volatile("movl %%cr3,%0" : "=r" (val));
                    127:        return val;
                    128: }
                    129:
                    130: static __inline void
                    131: lcr4(u_int val)
                    132: {
                    133:        __asm __volatile("movl %0,%%cr4" : : "r" (val));
                    134: }
                    135:
                    136: static __inline u_int
                    137: rcr4(void)
                    138: {
                    139:        u_int val;
                    140:        __asm __volatile("movl %%cr4,%0" : "=r" (val));
                    141:        return val;
                    142: }
                    143:
                    144: static __inline void
                    145: tlbflush(void)
                    146: {
                    147:        u_int val;
                    148:        __asm __volatile("movl %%cr3,%0" : "=r" (val));
                    149:        __asm __volatile("movl %0,%%cr3" : : "r" (val));
                    150: }
                    151:
                    152: static __inline void
                    153: tlbflushg(void)
                    154: {
                    155:        /*
                    156:         * Big hammer: flush all TLB entries, including ones from PTE's
                    157:         * with the G bit set.  This should only be necessary if TLB
                    158:         * shootdown falls far behind.
                    159:         *
                    160:         * Intel Architecture Software Developer's Manual, Volume 3,
                    161:         *      System Programming, section 9.10, "Invalidating the
                    162:         * Translation Lookaside Buffers (TLBS)":
                    163:         * "The following operations invalidate all TLB entries, irrespective
                    164:         * of the setting of the G flag:
                    165:         * ...
                    166:         * "(P6 family processors only): Writing to control register CR4 to
                    167:         * modify the PSE, PGE, or PAE flag."
                    168:         *
                    169:         * (the alternatives not quoted above are not an option here.)
                    170:         *
                    171:         * If PGE is not in use, we reload CR3 for the benefit of
                    172:         * pre-P6-family processors.
                    173:         */
                    174:
                    175: #if defined(I686_CPU)
                    176:        if (cpu_feature & CPUID_PGE) {
                    177:                u_int cr4 = rcr4();
                    178:                lcr4(cr4 & ~CR4_PGE);
                    179:                lcr4(cr4);
                    180:        } else
                    181: #endif
                    182:                tlbflush();
                    183: }
                    184:
                    185: #ifdef notyet
                    186: void   setidt(int idx, /*XXX*/caddr_t func, int typ, int dpl);
                    187: #endif
                    188:
                    189:
                    190: /* XXXX ought to be in psl.h with spl() functions */
                    191:
                    192: static __inline void
                    193: disable_intr(void)
                    194: {
                    195:        __asm __volatile("cli");
                    196: }
                    197:
                    198: static __inline void
                    199: enable_intr(void)
                    200: {
                    201:        __asm __volatile("sti");
                    202: }
                    203:
                    204: static __inline u_int
                    205: read_eflags(void)
                    206: {
                    207:        u_int ef;
                    208:
                    209:        __asm __volatile("pushfl; popl %0" : "=r" (ef));
                    210:        return (ef);
                    211: }
                    212:
                    213: static __inline void
                    214: write_eflags(u_int ef)
                    215: {
                    216:        __asm __volatile("pushl %0; popfl" : : "r" (ef));
                    217: }
                    218:
                    219: static __inline void
                    220: wbinvd(void)
                    221: {
                    222:         __asm __volatile("wbinvd");
                    223: }
                    224:
                    225:
                    226: static __inline void
                    227: wrmsr(u_int msr, u_int64_t newval)
                    228: {
                    229:         __asm __volatile("wrmsr" : : "A" (newval), "c" (msr));
                    230: }
                    231:
                    232: static __inline u_int64_t
                    233: rdmsr(u_int msr)
                    234: {
                    235:         u_int64_t rv;
                    236:
                    237:         __asm __volatile("rdmsr" : "=A" (rv) : "c" (msr));
                    238:         return (rv);
                    239: }
                    240:
                    241: /*
                    242:  * Some of the undocumented AMD64 MSRs need a 'passcode' to access.
                    243:  *
                    244:  * See LinuxBIOSv2: src/cpu/amd/model_fxx/model_fxx_init.c
                    245:  */
                    246:
                    247: #define        OPTERON_MSR_PASSCODE    0x9c5a203a
                    248:
                    249: static __inline u_int64_t
                    250: rdmsr_locked(u_int msr, u_int code)
                    251: {
                    252:        uint64_t rv;
                    253:        __asm volatile("rdmsr"
                    254:            : "=A" (rv)
                    255:            : "c" (msr), "D" (code));
                    256:        return (rv);
                    257: }
                    258:
                    259: static __inline void
                    260: wrmsr_locked(u_int msr, u_int code, u_int64_t newval)
                    261: {
                    262:        __asm volatile("wrmsr"
                    263:            :
                    264:            : "A" (newval), "c" (msr), "D" (code));
                    265: }
                    266:
                    267: /* Break into DDB/KGDB. */
                    268: static __inline void
                    269: breakpoint(void)
                    270: {
                    271:        __asm __volatile("int $3");
                    272: }
                    273:
                    274: #ifdef I686_CPU
                    275: void amd64_errata(struct cpu_info *);
                    276: #endif
                    277:
                    278: #endif /* _KERNEL */
                    279: #endif /* !_I386_CPUFUNC_H_ */

CVSweb