File: [cvs.NetBSD.org] / src / sys / arch / i386 / i386 / i386func.S (download)
Revision 1.1, Wed Sep 26 19:48:36 2007 UTC (16 years, 6 months ago) by ad
Branch: MAIN
x86 changes for pcc and LKMs.
- Replace most inline assembly with proper functions. As a side effect
this reduces the size of amd64 GENERIC by about 120kB, and i386 by a
smaller amount. Nearly all of the inlines did something slow, or something
that does not need to be fast.
- Make curcpu() and curlwp functions proper, unless __GNUC__ && _KERNEL.
In that case make them inlines. Makes curlwp LKM and preemption safe.
- Make bus_space and bus_dma more LKM friendly.
- Share a few more files between the ports.
- Other minor changes.
|
/* $NetBSD: i386func.S,v 1.1 2007/09/26 19:48:36 ad Exp $ */
/*-
* Copyright (c) 1998, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Charles M. Hannum, and by Andrew Doran.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Functions to provide access to i386-specific instructions.
*
* These are _not_ shared with NetBSD/xen.
*/
#include <machine/asm.h>
#include <machine/specialreg.h>
#include <machine/segments.h>
#include "assym.h"
/* Small and slow, so align less. */
#undef _ALIGN_TEXT
#define _ALIGN_TEXT .align 8
NENTRY(invlpg)
movl 4(%esp), %eax
invlpg (%eax)
ret
NENTRY(lldt)
movl 4(%esp), %eax
lldt %ax
ret
NENTRY(ltr)
movl 4(%esp), %eax
ltr %ax
ret
NENTRY(lcr0)
movl 4(%esp), %eax
movl %eax, %cr0
ret
NENTRY(rcr0)
movl %cr0, %eax
ret
NENTRY(lcr3)
movl 4(%esp), %eax
movl %eax, %cr3
ret
/*
* Big hammer: flush all TLB entries, including ones from PTE's
* with the G bit set. This should only be necessary if TLB
* shootdown falls far behind.
*
* Intel Architecture Software Developer's Manual, Volume 3,
* System Programming, section 9.10, "Invalidating the
* Translation Lookaside Buffers (TLBS)":
* "The following operations invalidate all TLB entries, irrespective
* of the setting of the G flag:
* ...
* "(P6 family processors only): Writing to control register CR4 to
* modify the PSE, PGE, or PAE flag."
*
* (the alternatives not quoted above are not an option here.)
*
* If PGE is not in use, we reload CR3 for the benefit of
* pre-P6-family processors.
*/
NENTRY(tlbflushg)
testl $CPUID_PGE, _C_LABEL(cpu_feature)
jz 1f
movl %cr4, %eax
movl %eax, %edx
andl $~CR4_PGE, %edx
movl %edx, %cr4
movl %eax, %cr4
ret
NENTRY(tlbflush)
1:
movl %cr3, %eax
movl %eax, %cr3
ret
NENTRY(ldr6)
movl 4(%esp), %eax
movl %eax, %dr6
ret
NENTRY(rdr6)
movl %dr6, %eax
ret
NENTRY(rcr2)
movl %cr2, %eax
ret
NENTRY(wbinvd)
wbinvd
ret
NENTRY(x86_disable_intr)
cli
ret
NENTRY(x86_enable_intr)
sti
ret
/*
* void lgdt(struct region_descriptor *rdp);
*
* Load a new GDT pointer (and do any necessary cleanup).
* XXX It's somewhat questionable whether reloading all the segment registers
* is necessary, since the actual descriptor data is not changed except by
* process creation and exit, both of which clean up via task switches. OTOH,
* this only happens at run time when the GDT is resized.
*/
NENTRY(lgdt)
/* Reload the descriptor table. */
movl 4(%esp), %eax
lgdt (%eax)
/* Flush the prefetch queue. */
jmp 1f
nop
1: /* Reload "stale" selectors. */
movl $GSEL(GDATA_SEL, SEL_KPL), %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %gs
movl %eax, %ss
movl $GSEL(GCPU_SEL, SEL_KPL), %eax
movl %eax, %fs
jmp _C_LABEL(x86_flush)