diff options
Diffstat (limited to 'abs/core-testing')
-rw-r--r-- | abs/core-testing/nvidia-utils/PKGBUILD | 70 | ||||
-rw-r--r-- | abs/core-testing/nvidia-utils/nvidia.install | 40 | ||||
-rw-r--r-- | abs/core-testing/nvidia-utils/supported-cards.txt | 292 | ||||
-rw-r--r-- | abs/core-testing/nvidia/NVIDIA_kernel-169.12-2286310.diff | 637 | ||||
-rw-r--r-- | abs/core-testing/nvidia/PKGBUILD | 39 | ||||
-rw-r--r-- | abs/core-testing/nvidia/nvidia.install | 22 |
6 files changed, 1100 insertions, 0 deletions
diff --git a/abs/core-testing/nvidia-utils/PKGBUILD b/abs/core-testing/nvidia-utils/PKGBUILD new file mode 100644 index 0000000..d1058c4 --- /dev/null +++ b/abs/core-testing/nvidia-utils/PKGBUILD @@ -0,0 +1,70 @@ +# $Id: PKGBUILD 7914 2008-08-05 08:01:00Z tpowa $ +# Maintainer: Thomas Baechler <thomas@archlinux.org> +# Contributor: James Rayner <iphitus@gmail.com> + +pkgname=nvidia-utils +pkgver=173.14.12 +pkgrel=5 +pkgdesc="NVIDIA drivers utilities and libraries." +arch=('i686' 'x86_64') +[ "$CARCH" = "i686" ] && ARCH=x86 +[ "$CARCH" = "x86_64" ] && ARCH=x86_64 +url="http://www.nvidia.com/" +depends=('xorg-server') +conflicts=('libgl' 'libgl-dri' 'ati-fglrx-utils' 'nvidia-legacy-utils' \ + 'nvidia-71xx-utils' 'nvidia-96xx-utils') +provides=('libgl') +license=('custom') +install=nvidia.install +source=(http://us.download.nvidia.com/XFree86/Linux-${ARCH}/${pkgver}/NVIDIA-Linux-${ARCH}-${pkgver}-pkg0.run \ + supported-cards.txt) +md5sums=('76b8eba1b14fc273a1a4044705b0aa56' + 'bf8d68d66757096c3ab17653230bf2a8') +[ "$CARCH" = "x86_64" ] && md5sums=('8675e4ca65033b343c8c77b2ce82e71d' + 'bf8d68d66757096c3ab17653230bf2a8') + +options=(docs !strip) + +build() +{ + # override nvida install routine and do it the long way. + cd $startdir/src/ + sh NVIDIA-Linux-${ARCH}-${pkgver}-pkg0.run --extract-only + cd NVIDIA-Linux-${ARCH}-${pkgver}-pkg0/usr/ + + mkdir -p $startdir/pkg/usr/{lib,bin,share/applications,share/pixmaps,man/man1} + mkdir -p $startdir/pkg/usr/lib/xorg/modules/{extensions,drivers} + mkdir -p $startdir/pkg/usr/share/licenses/nvidia/ + + install lib/{libGLcore,libGL,libnvidia-cfg,libcuda,tls/libnvidia-tls}.so.${pkgver} \ + $startdir/pkg/usr/lib/ || return 1 + install -m644 share/man/man1/* $startdir/pkg/usr/man/man1/ || return 1 + rm $startdir/pkg/usr/man/man1/nvidia-installer.1.gz || return 1 + install X11R6/lib/libXv* $startdir/pkg/usr/lib/ || return 1 + install -m644 share/applications/nvidia-settings.desktop $startdir/pkg/usr/share/applications/ || return 1 + # fix nvidia .desktop file + sed -e 's:__UTILS_PATH__:/usr/bin:' -e 's:__PIXMAP_PATH__:/usr/share/pixmaps:' -i $startdir/pkg/usr/share/applications/nvidia-settings.desktop + install -m644 share/pixmaps/nvidia-settings.png $startdir/pkg/usr/share/pixmaps/ || return 1 + #install X11R6/lib/modules/libnvidia-wfb.so.$pkgver $startdir/pkg/usr/lib/xorg/modules || return 1 + install X11R6/lib/modules/drivers/nvidia_drv.so $startdir/pkg/usr/lib/xorg/modules/drivers || return 1 + install X11R6/lib/modules/extensions/libglx.so.$pkgver $startdir/pkg/usr/lib/xorg/modules/extensions || return 1 + install -m755 bin/nvidia-{settings,xconfig,bug-report.sh} $startdir/pkg/usr/bin/ || return 1 + cd $startdir/pkg/usr/lib/ + ln -s libGL.so.$pkgver libGL.so || return 1 + ln -s libGL.so.$pkgver libGL.so.1 || return 1 + ln -s libGLcore.so.$pkgver libGLcore.so.1 || return 1 + ln -s libnvidia-cfg.so.$pkgver libnvidia-cfg.so.1 || return 1 + ln -s libnvidia-tls.so.$pkgver libnvidia-tls.so.1 || return 1 + ln -s libcuda.so.$pkgver libcuda.so.1 || return 1 + ln -s libXvMCNVIDIA.so.$pkgver libXvMCNVIDIA_dynamic.so.1 || return 1 + cd $startdir/pkg/usr/lib/xorg/modules/extensions + ln -s libglx.so.$pkgver libglx.so || return 1 + + install -m644 $startdir/src/NVIDIA-Linux-${ARCH}-${pkgver}-pkg0/LICENSE $startdir/pkg/usr/share/licenses/nvidia/ || return 1 + ln -s nvidia $startdir/pkg/usr/share/licenses/nvidia-utils || return 1 + install -D -m644 $startdir/src/NVIDIA-Linux-${ARCH}-${pkgver}-pkg0/usr/share/doc/README.txt $startdir/pkg/usr/share/doc/nvidia/README || return 1 + install -D -m644 $startdir/src/supported-cards.txt $startdir/pkg/usr/share/doc/nvidia/supported-cards.txt || return 1 + + find $startdir/pkg/usr -type d -exec chmod 755 {} \; + # phew :) +} diff --git a/abs/core-testing/nvidia-utils/nvidia.install b/abs/core-testing/nvidia-utils/nvidia.install new file mode 100644 index 0000000..7d46ed6 --- /dev/null +++ b/abs/core-testing/nvidia-utils/nvidia.install @@ -0,0 +1,40 @@ +# arg 1: the new package version +post_install() { + + echo ------------------------------- + echo By using this package you accept the NVIDIA license, + echo which has been installed in /usr/share/licenses/nvidia/LICENSE + echo If you do not accept this license, you must remove the package immediately. + echo Dont forget to update your /etc/X11/xorg.conf + echo In order to use nvidia-settings, you need to install the 'gtk2' package. + echo In order to use nvidia-xconfig, you need to install the 'pkgconfig' package. + echo ------------------------------- + echo nvidia 9746 drops support for Geforce 3 and 4 cards + echo If you have such a card, install the nvidia-96xx, nvidia-96xx-utils, + echo nvidia-96xx-ck, nvidia-96xx-beyond, nvidia-96xx-suspend2 packages + echo For a list of supported cards, see /usr/share/doc/nvidia/supported-cards.txt + echo ------------------------------- + + #echo ":: Updating symlinks to use built-in libwfb" + #ln -sf /usr/lib/xorg/modules/libnvidia-wfb.so.* \ + # /usr/lib/xorg/modules/libwfb.so +} + +# arg 1: the new package version +# arg 2: the old package version +post_upgrade() { + post_install $1 + echo ":: Updating symlinks to use xorg-server libwfb" + ln -sf /usr/lib/xorg/modules/libwfb.so.* \ + /usr/lib/xorg/modules/libwfb.so +} + +post_remove() { + echo ":: Updating symlinks to use xorg-server libwfb" + ln -sf /usr/lib/xorg/modules/libwfb.so.* \ + /usr/lib/xorg/modules/libwfb.so +} + +op=$1 +shift +$op $* diff --git a/abs/core-testing/nvidia-utils/supported-cards.txt b/abs/core-testing/nvidia-utils/supported-cards.txt new file mode 100644 index 0000000..ce4c3d4 --- /dev/null +++ b/abs/core-testing/nvidia-utils/supported-cards.txt @@ -0,0 +1,292 @@ +Archlinux currently manages three branches of the NVIDIA binary driver: + +nvidia (latest nvidia release) +nvidia-96xx (96xx legacy branch) +nvidia-71xx (71xx legacy branch) + +This excerpt from the NVIDIA 100.14.09 README lists the supported devices +for each of those: + +______________________________________________________________________________ + +Appendix A. Supported NVIDIA GPU Products +______________________________________________________________________________ + +For the most complete and accurate listing of supported GPUs, please see the +Supported Products List, available from the NVIDIA Linux x86 Graphics Driver +download page. Please go to http://www.nvidia.com/object/unix.html, follow the +Archive link under the Linux x86 heading, follow the link for the 100.14.09 +driver, and then go to the Supported Products List. + + +A1. NVIDIA GEFORCE GPUS + + + NVIDIA GPU product Device PCI ID + ---------------------------------- ---------------------------------- + GeForce 6800 Ultra 0x0040 + GeForce 6800 0x0041 + GeForce 6800 LE 0x0042 + GeForce 6800 XE 0x0043 + GeForce 6800 XT 0x0044 + GeForce 6800 GT 0x0045 + GeForce 6800 GT 0x0046 + GeForce 6800 GS 0x0047 + GeForce 6800 XT 0x0048 + GeForce 7800 GTX 0x0090 + GeForce 7800 GTX 0x0091 + GeForce 7800 GTX 0x0092 + GeForce 7800 GS 0x0093 + GeForce 7800 SLI 0x0095 + GeForce Go 7800 0x0098 + GeForce Go 7800 GTX 0x0099 + GeForce 6800 GS 0x00C0 + GeForce 6800 0x00C1 + GeForce 6800 LE 0x00C2 + GeForce 6800 XT 0x00C3 + GeForce Go 6800 0x00C8 + GeForce Go 6800 Ultra 0x00C9 + GeForce 6800 Ultra/GeForce 6800 0x00F0 + GeForce 6600 GT 0x00F1 + GeForce 6600 0x00F2 + GeForce 6200 0x00F3 + GeForce 6600 LE 0x00F4 + GeForce 7800 GS 0x00F5 + GeForce 6800 GS/XT 0x00F6 + GeForce 6800 Ultra 0x00F9 + GeForce PCX 5750 0x00FA + GeForce PCX 5900 0x00FB + GeForce PCX 5300 0x00FC + GeForce PCX 4300 0x00FF + GeForce 6600 GT 0x0140 + GeForce 6600 0x0141 + GeForce 6600 LE 0x0142 + GeForce 6600 VE 0x0143 + GeForce Go 6600 0x0144 + GeForce 6610 XL 0x0145 + GeForce Go 6600 TE/6200 TE 0x0146 + GeForce 6700 XL 0x0147 + GeForce Go 6600 0x0148 + GeForce Go 6600 GT 0x0149 + GeForce 6200 0x014F + GeForce 6500 0x0160 + GeForce 6200 TurboCache(TM) 0x0161 + GeForce 6200SE TurboCache(TM) 0x0162 + GeForce 6200 LE 0x0163 + GeForce Go 6200 0x0164 + GeForce Go 6400 0x0166 + GeForce Go 6200 0x0167 + GeForce Go 6400 0x0168 + GeForce 6250 0x0169 + GeForce 7100 GS 0x016A + GeForce 8800 GTX 0x0191 + GeForce 8800 GTS 0x0193 + GeForce 8800 Ultra 0x0194 + GeForce 7350 LE 0x01D0 + GeForce 7300 LE 0x01D1 + GeForce 7300 SE/7200 GS 0x01D3 + GeForce Go 7200 0x01D6 + GeForce Go 7300 0x01D7 + GeForce Go 7400 0x01D8 + GeForce 7500 LE 0x01DD + GeForce 7300 GS 0x01DF + GeForce 6800 0x0211 + GeForce 6800 LE 0x0212 + GeForce 6800 GT 0x0215 + GeForce 6800 XT 0x0218 + GeForce 6200 0x0221 + GeForce 6200 A-LE 0x0222 + GeForce 6150 0x0240 + GeForce 6150 LE 0x0241 + GeForce 6100 0x0242 + GeForce Go 6150 0x0244 + GeForce Go 6100 0x0247 + GeForce 7900 GTX 0x0290 + GeForce 7900 GT/GTO 0x0291 + GeForce 7900 GS 0x0292 + GeForce 7950 GX2 0x0293 + GeForce 7950 GX2 0x0294 + GeForce 7950 GT 0x0295 + GeForce Go 7950 GTX 0x0297 + GeForce Go 7900 GS 0x0298 + GeForce Go 7900 GTX 0x0299 + GeForce 7600 GT/Unknown GPU 0x02E0 + GeForce 7600 GS 0x02E1 + GeForce FX 5800 Ultra 0x0301 + GeForce FX 5800 0x0302 + GeForce FX 5600 Ultra 0x0311 + GeForce FX 5600 0x0312 + GeForce FX 5600XT 0x0314 + GeForce FX Go5600 0x031A + GeForce FX Go5650 0x031B + GeForce FX 5200 0x0320 + GeForce FX 5200 Ultra 0x0321 + GeForce FX 5200 0x0322 + GeForce FX 5200LE 0x0323 + GeForce FX Go5200 0x0324 + GeForce FX Go5250 0x0325 + GeForce FX 5500 0x0326 + GeForce FX 5100 0x0327 + GeForce FX Go5200 32M/64M 0x0328 + GeForce FX Go53xx 0x032C + GeForce FX Go5100 0x032D + GeForce FX 5900 Ultra 0x0330 + GeForce FX 5900 0x0331 + GeForce FX 5900XT 0x0332 + GeForce FX 5950 Ultra 0x0333 + GeForce FX 5900ZT 0x0334 + GeForce FX 5700 Ultra 0x0341 + GeForce FX 5700 0x0342 + GeForce FX 5700LE 0x0343 + GeForce FX 5700VE 0x0344 + GeForce FX Go5700 0x0347 + GeForce FX Go5700 0x0348 + GeForce 7650 GS 0x0390 + GeForce 7600 GT 0x0391 + GeForce 7600 GS 0x0392 + GeForce 7300 GT 0x0393 + GeForce 7600 LE 0x0394 + GeForce 7300 GT 0x0395 + GeForce Go 7600 0x0398 + GeForce 6150SE nForce 430 0x03D0 + GeForce 6100 nForce 405 0x03D1 + GeForce 6100 nForce 400 0x03D2 + GeForce 6100 nForce 420 0x03D5 + GeForce 8600 GTS 0x0400 + GeForce 8600 GT 0x0402 + GeForce 8600M GT 0x0407 + GeForce 8500 GT 0x0421 + GeForce 8400 GS 0x0422 + GeForce 8300 GS 0x0423 + GeForce 8600M GS 0x0425 + GeForce 8400M GT 0x0426 + GeForce 8400M GS 0x0427 + GeForce 8400M G 0x0428 + + + +A2. NVIDIA QUADRO GPUS + + + NVIDIA GPU product Device PCI ID + ------------------------------------------------------ --------------- + Quadro FX 4000 0x004E + Quadro FX 4500 0x009D + Quadro FX Go1400 0x00CC + Quadro FX 3450/4000 SDI 0x00CD + Quadro FX 1400 0x00CE + Quadro FX 4400/Quadro FX 3400 0x00F8 + Quadro FX 330 0x00FC + Quadro NVS 280 PCI-E/Quadro FX 330 0x00FD + Quadro FX 1300 0x00FE + Quadro NVS 440 0x014A + Quadro FX 540M/Quadro FX 540M 0x014C + Quadro FX 550 0x014D + Quadro FX 540 0x014E + Quadro NVS 285 0x0165 + Quadro FX 5600 0x019D + Quadro FX 4600 0x019E + Quadro NVS 110M 0x01D7 + Quadro NVS 110M 0x01DA + Quadro NVS 120M 0x01DB + Quadro FX 350M 0x01DC + Quadro FX 350 0x01DE + Quadro NVS 210S / NVIDIA GeForce 6150LE 0x0245 + Quadro FX 2500M 0x029A + Quadro FX 1500M 0x029B + Quadro FX 5500 0x029C + Quadro FX 3500 0x029D + Quadro FX 1500 0x029E + Quadro FX 4500 X2 0x029F + Quadro FX 2000 0x0308 + Quadro FX 1000 0x0309 + Quadro FX Go700 0x031C + Quadro NVS 55/280 PCI 0x032A + Quadro FX 500/FX 600 0x032B + Quadro FX 3000 0x0338 + Quadro FX 700 0x033F + Quadro FX Go1000 0x034C + Quadro FX 1100 0x034E + Quadro FX 560 0x039E + Quadro NVS 320M 0x040B + Quadro FX 570M 0x040C + Quadro FX 1600M 0x040D + Quadro NVS 140M 0x0429 + Quadro NVS 130M 0x042A + Quadro NVS 135M 0x042B + Quadro FX 360M 0x042D + + +Below are the legacy GPUs that are no longer supported in the unified driver. +These GPUs will continue to be maintained through the special legacy NVIDIA +GPU driver releases. + +The 1.0-96xx driver supports the following set of GPUs: + + + NVIDIA GPU product Device PCI ID + ---------------------------------- ---------------------------------- + GeForce2 MX/MX 400 0x0110 + GeForce2 MX 100/200 0x0111 + GeForce2 Go 0x0112 + Quadro2 MXR/EX/Go 0x0113 + GeForce4 MX 460 0x0170 + GeForce4 MX 440 0x0171 + GeForce4 MX 420 0x0172 + GeForce4 MX 440-SE 0x0173 + GeForce4 440 Go 0x0174 + GeForce4 420 Go 0x0175 + GeForce4 420 Go 32M 0x0176 + GeForce4 460 Go 0x0177 + Quadro4 550 XGL 0x0178 + GeForce4 440 Go 64M 0x0179 + Quadro NVS 400 0x017A + Quadro4 500 GoGL 0x017C + GeForce4 410 Go 16M 0x017D + GeForce4 MX 440 with AGP8X 0x0181 + GeForce4 MX 440SE with AGP8X 0x0182 + GeForce4 MX 420 with AGP8X 0x0183 + GeForce4 MX 4000 0x0185 + Quadro4 580 XGL 0x0188 + Quadro NVS 280 SD 0x018A + Quadro4 380 XGL 0x018B + Quadro NVS 50 PCI 0x018C + GeForce2 Integrated GPU 0x01A0 + GeForce4 MX Integrated GPU 0x01F0 + GeForce3 0x0200 + GeForce3 Ti 200 0x0201 + GeForce3 Ti 500 0x0202 + Quadro DCC 0x0203 + GeForce4 Ti 4600 0x0250 + GeForce4 Ti 4400 0x0251 + GeForce4 Ti 4200 0x0253 + Quadro4 900 XGL 0x0258 + Quadro4 750 XGL 0x0259 + Quadro4 700 XGL 0x025B + GeForce4 Ti 4800 0x0280 + GeForce4 Ti 4200 with AGP8X 0x0281 + GeForce4 Ti 4800 SE 0x0282 + GeForce4 4200 Go 0x0286 + Quadro4 980 XGL 0x0288 + Quadro4 780 XGL 0x0289 + Quadro4 700 GoGL 0x028C + + +The 1.0-71xx driver supports the following set of GPUs: + + + NVIDIA GPU product Device PCI ID + ---------------------------------- ---------------------------------- + RIVA TNT 0x0020 + RIVA TNT2/TNT2 Pro 0x0028 + RIVA TNT2 Ultra 0x0029 + Vanta/Vanta LT 0x002C + RIVA TNT2 Model 64/Model 64 Pro 0x002D + Aladdin TNT2 0x00A0 + GeForce 256 0x0100 + GeForce DDR 0x0101 + Quadro 0x0103 + GeForce2 GTS/GeForce2 Pro 0x0150 + GeForce2 Ti 0x0151 + GeForce2 Ultra 0x0152 + Quadro2 Pro 0x0153 diff --git a/abs/core-testing/nvidia/NVIDIA_kernel-169.12-2286310.diff b/abs/core-testing/nvidia/NVIDIA_kernel-169.12-2286310.diff new file mode 100644 index 0000000..e511cfb --- /dev/null +++ b/abs/core-testing/nvidia/NVIDIA_kernel-169.12-2286310.diff @@ -0,0 +1,637 @@ +diff -ru usr/src/nv/Makefile.kbuild usr/src/nv.2286310/Makefile.kbuild +--- usr/src/nv/Makefile.kbuild 2008-03-16 14:13:10.000000000 -0700 ++++ usr/src/nv.2286310/Makefile.kbuild 2008-03-16 14:37:47.204131496 -0700 +@@ -177,6 +177,7 @@ + vmap \ + signal_struct \ + agp_backend_acquire \ ++ set_pages_uc \ + change_page_attr \ + pci_get_class \ + sysctl_max_map_count \ +diff -ru usr/src/nv/conftest.sh usr/src/nv.2286310/conftest.sh +--- usr/src/nv/conftest.sh 2008-03-16 14:13:10.000000000 -0700 ++++ usr/src/nv.2286310/conftest.sh 2008-03-16 14:37:47.204131496 -0700 +@@ -100,6 +100,32 @@ + fi + ;; + ++ set_pages_uc) ++ # ++ # Determine if the set_pages_uc() function is present. ++ # ++ echo "#include <linux/autoconf.h> ++ #include <asm/cacheflush.h> ++ void conftest_set_pages_uc(void) { ++ set_pages_uc(); ++ }" > conftest$$.c ++ ++ $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1 ++ rm -f conftest$$.c ++ ++ if [ -f conftest$$.o ]; then ++ rm -f conftest$$.o ++ echo "#undef NV_SET_PAGES_UC_PRESENT" >> conftest.h ++ return ++ else ++ echo "#ifdef NV_CHANGE_PAGE_ATTR_PRESENT" >> conftest.h ++ echo "#undef NV_CHANGE_PAGE_ATTR_PRESENT" >> conftest.h ++ echo "#endif" >> conftest.h ++ echo "#define NV_SET_PAGES_UC_PRESENT" >> conftest.h ++ return ++ fi ++ ;; ++ + change_page_attr) + # + # Determine if the change_page_attr() function is +@@ -124,7 +150,9 @@ + rm -f conftest$$.o + return + else ++ echo "#ifndef NV_SET_PAGES_UC_PRESENT" >> conftest.h + echo "#define NV_CHANGE_PAGE_ATTR_PRESENT" >> conftest.h ++ echo "#endif" >> conftest.h + return + fi + ;; +@@ -524,6 +552,8 @@ + return + fi + ++ rm -f conftest$$.o ++ + echo "#include <linux/autoconf.h> + #include <linux/interrupt.h> + irq_handler_t conftest_isr; +diff -ru usr/src/nv/nv-linux.h usr/src/nv.2286310/nv-linux.h +--- usr/src/nv/nv-linux.h 2008-03-16 14:13:10.000000000 -0700 ++++ usr/src/nv.2286310/nv-linux.h 2008-03-16 14:37:47.204131496 -0700 +@@ -871,9 +871,10 @@ + + #define NV_PGD_OFFSET(address, kernel, mm) \ + ({ \ ++ struct mm_struct *__mm = (mm); \ + pgd_t *__pgd; \ + if (!kernel) \ +- __pgd = pgd_offset(mm, address); \ ++ __pgd = pgd_offset(__mm, address); \ + else \ + __pgd = pgd_offset_k(address); \ + __pgd; \ +@@ -1208,21 +1209,24 @@ + nv_check_pci_config_space(nv, cb); \ + } + ++extern int nv_update_memory_types; ++ + /* +- * a BUG() is triggered on early 2.6 x86_64 kernels. the underlying +- * problem actually exists on many architectures and kernels, but +- * these are the only kernels that check the condition and trigger +- * a BUG(). note that this is a problem of the core kernel, not an +- * nvidia bug (and can still be triggered by agpgart). let's avoid +- * change_page_attr on those kernels. ++ * Using change_page_attr() on early Linux/x86-64 2.6 kernels may ++ * result in a BUG() being triggered. The underlying problem ++ * actually exists on multiple architectures and kernels, but only ++ * the above check for the condition and trigger a BUG(). ++ * ++ * Note that this is a due to a bug in the Linux kernel, not an ++ * NVIDIA driver bug (it can also be triggered by AGPGART). ++ * ++ * We therefore need to determine at runtime if change_page_attr() ++ * can be used safely on these kernels. + */ +-#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) +-extern int nv_use_cpa; +- +-#if defined(NVCPU_X86_64) && !defined(KERNEL_2_4) && \ +- (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)) +-#define NV_CHANGE_PAGE_ATTR_BUG_PRESENT 1 +-#endif ++#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) && defined(NVCPU_X86_64) && \ ++ !defined(KERNEL_2_4) && \ ++ (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)) ++#define NV_CHANGE_PAGE_ATTR_BUG_PRESENT + #endif + + #if defined(NVCPU_X86) || defined(NVCPU_X86_64) +@@ -1234,7 +1238,7 @@ + * + * We need to be careful to mask out _PAGE_NX when the host system + * doesn't support this feature or when it's disabled: the kernel +- * may not do this in its implementation of the change_page_attr() ++ * may not do this in its implementation of the change_page_attr() + * interface. + */ + #ifndef X86_FEATURE_NX +diff -ru usr/src/nv/nv-reg.h usr/src/nv.2286310/nv-reg.h +--- usr/src/nv/nv-reg.h 2008-03-16 14:13:10.000000000 -0700 ++++ usr/src/nv.2286310/nv-reg.h 2008-03-16 14:37:47.204131496 -0700 +@@ -391,34 +391,36 @@ + #define NV_REG_REMAP_LIMIT NV_REG_STRING(__NV_REMAP_LIMIT) + + /* +- * Option: UseCPA ++ * Option: UpdateMemoryTypes + * + * Description: + * +- * Many kernels have a broken implementation of change_page_attr that leads +- * to cache aliasing problems. x86_64 kernels between 2.6.0 and 2.6.10 will +- * force a kernel BUG_ON() when this condition is encountered. For this +- * reason, the NVIDIA driver is very careful about not using the CPA kernel +- * interface on these kernels. +- * +- * Some distributions have backported this fix to kernel versions that fall +- * within this version range. The NVIDIA driver attempts to automatically +- * detect these fixes and reenable usage of the change_page_attr interface. +- * +- * Due to the serious nature of the problems that can arise from this, the +- * NVIDIA driver implements a manual registry key to force usage of this API +- * to be enabled or disabled. This registry key can be used to force usage +- * of the API on a known fixed kernel if the NVIDIA driver fails to detect +- * the kernel as fixed. This registry key can also be used to disable usage +- * of the API on a bad kernel that is misdetected as a fixed kernel. +- * +- * The default value is '-1' (use NVIDIA driver default logic) +- * A value of '0' will forcibly disable change_page_attr calls. +- * A value of '1' will forcibly enable change_page_attr calls. ++ * Many kernels have broken implementations of the change_page_attr() ++ * kernel interface that may cause cache aliasing problems. Linux/x86-64 ++ * kernels between 2.6.0 and 2.6.10 may prompt kernel BUG()s due to ++ * improper accounting in the interface's large page management code, for ++ * example. For this reason, the NVIDIA Linux driver is very careful about ++ * not using the change_page_attr() kernel interface on these kernels. ++ * ++ * Due to the serious nature of the problems that can arise from bugs in ++ * the change_page_attr(), set_pages_{uc,wb}() and other kernel interfaces ++ * used to modify memory types, the NVIDIA driver implements a manual ++ * registry key override to allow forcibly enabling or disabling use of ++ * these APIs. ++ * ++ * Possible values: ++ * ++ * ~0 = use the NVIDIA driver's default logic (default) ++ * 0 = enable use of change_page_attr(), etc. ++ * 1 = disable use of change_page_attr(), etc. ++ * ++ * By default, the NVIDIA driver will attempt to auto-detect if it can ++ * safely use the change_page_attr() and other kernel interfaces to modify ++ * the memory types of kernel mappings. + */ + +-#define __NV_USE_CPA UseCPA +-#define NV_REG_USE_CPA NV_REG_STRING(__NV_USE_CPA) ++#define __NV_UPDATE_MEMORY_TYPES UpdateMemoryTypes ++#define NV_REG_UPDATE_MEMORY_TYPES NV_REG_STRING(__NV_UPDATE_MEMORY_TYPES) + + /* + * Option: RegistryDwords +@@ -490,7 +492,7 @@ + NV_DEFINE_REG_ENTRY(__NV_DEVICE_FILE_GID, 0); + NV_DEFINE_REG_ENTRY(__NV_DEVICE_FILE_MODE, 0666); + NV_DEFINE_REG_ENTRY(__NV_REMAP_LIMIT, 0); +-NV_DEFINE_REG_ENTRY(__NV_USE_CPA, -1); ++NV_DEFINE_REG_ENTRY(__NV_UPDATE_MEMORY_TYPES, ~0); + NV_DEFINE_REG_ENTRY(__NV_USE_VBIOS, 1); + NV_DEFINE_REG_ENTRY(__NV_RM_EDGE_INTR_CHECK, 1); + +@@ -535,7 +537,7 @@ + NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_DEVICE_FILE_GID), + NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_DEVICE_FILE_MODE), + NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_REMAP_LIMIT), +- NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_USE_CPA), ++ NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_UPDATE_MEMORY_TYPES), + NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_USE_VBIOS), + NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_RM_EDGE_INTR_CHECK), + {NULL, NULL, NULL} +diff -ru usr/src/nv/nv-vm.c usr/src/nv.2286310/nv-vm.c +--- usr/src/nv/nv-vm.c 2008-03-16 14:13:09.000000000 -0700 ++++ usr/src/nv.2286310/nv-vm.c 2008-03-16 14:37:47.204131496 -0700 +@@ -43,42 +43,40 @@ + } + #endif + +-/* +- * AMD Athlon processors expose a subtle bug in the Linux +- * kernel, that may lead to AGP memory corruption. Recent +- * kernel versions had a workaround for this problem, but +- * 2.4.20 is the first kernel to address it properly. The +- * page_attr API provides the means to solve the problem. +- */ +- + static inline void nv_set_page_attrib_uncached(nv_pte_t *page_ptr) + { +-#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) +- if (nv_use_cpa) ++ if (nv_update_memory_types) + { +- struct page *page = virt_to_page(__va(page_ptr->phys_addr)); ++#if defined(NV_SET_PAGES_UC_PRESENT) ++ struct page *page = NV_GET_PAGE_STRUCT(page_ptr->phys_addr); ++ set_pages_uc(page, 1); ++#elif defined(NV_CHANGE_PAGE_ATTR_PRESENT) ++ struct page *page = NV_GET_PAGE_STRUCT(page_ptr->phys_addr); + pgprot_t prot = PAGE_KERNEL_NOCACHE; + #if defined(NVCPU_X86) || defined(NVCPU_X86_64) + pgprot_val(prot) &= __nv_supported_pte_mask; + #endif + change_page_attr(page, 1, prot); +- } + #endif ++ } + } + + static inline void nv_set_page_attrib_cached(nv_pte_t *page_ptr) + { +-#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) +- if (nv_use_cpa) ++ if (nv_update_memory_types) + { +- struct page *page = virt_to_page(__va(page_ptr->phys_addr)); ++#if defined(NV_SET_PAGES_UC_PRESENT) ++ struct page *page = NV_GET_PAGE_STRUCT(page_ptr->phys_addr); ++ set_pages_wb(page, 1); ++#elif defined(NV_CHANGE_PAGE_ATTR_PRESENT) ++ struct page *page = NV_GET_PAGE_STRUCT(page_ptr->phys_addr); + pgprot_t prot = PAGE_KERNEL; + #if defined(NVCPU_X86) || defined(NVCPU_X86_64) + pgprot_val(prot) &= __nv_supported_pte_mask; + #endif + change_page_attr(page, 1, prot); ++#endif + } +-#endif /* NV_CHANGE_PAGE_ATTR_PRESENT */ + } + + static inline void nv_lock_page(nv_pte_t *page_ptr) +@@ -360,7 +358,8 @@ + #if defined(NV_CPA_NEEDS_FLUSHING) + nv_execute_on_all_cpus(cache_flush, NULL); + #endif +-#if defined (NVCPU_X86) || defined (NVCPU_X86_64) ++#if (defined(NVCPU_X86) || defined(NVCPU_X86_64)) && \ ++ defined(NV_CHANGE_PAGE_ATTR_PRESENT) + global_flush_tlb(); + #endif + nv_ext_flush_caches(); // handle other platform flushes if present +@@ -662,7 +661,7 @@ + + address = (unsigned long)virt_addr + i * PAGE_SIZE; + +- pgd = NV_PGD_OFFSET(address, 1, &init_mm); ++ pgd = NV_PGD_OFFSET(address, 1, NULL); + if (!NV_PGD_PRESENT(pgd)) + goto failed; + +diff -ru usr/src/nv/nv.c usr/src/nv.2286310/nv.c +--- usr/src/nv/nv.c 2008-03-16 14:13:09.000000000 -0700 ++++ usr/src/nv.2286310/nv.c 2008-03-16 14:37:47.208131723 -0700 +@@ -15,6 +15,7 @@ + #include "nv_compiler.h" + #include "os-agp.h" + #include "nv-vm.h" ++#include "nv-reg.h" + + #ifdef MODULE_ALIAS_CHARDEV_MAJOR + MODULE_ALIAS_CHARDEV_MAJOR(NV_MAJOR_DEVICE_NUMBER); +@@ -116,10 +117,7 @@ + unsigned int nv_remap_limit; + #endif + +-#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) +-int nv_use_cpa = 1; +-#endif +- ++int nv_update_memory_types = 1; + static int nv_mmconfig_failure_detected = 0; + + static void *nv_pte_t_cache = NULL; +@@ -1030,30 +1028,26 @@ + #endif /* defined(NV_BUILD_NV_PAT_SUPPORT) */ + } + +- + #if defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT) +- +-/* nv_verify_cpa_interface - determine if the change_page_attr bug is fixed +- * in this kernel. ++/* ++ * nv_verify_cpa_interface() - determine if the change_page_attr() large page ++ * management accounting bug known to exist in early Linux/x86-64 kernels ++ * is present in this kernel. + * +- * there's really not a good way to determine if change_page_attr is fixed. +- * we can't really use cpa on 2.6 x86_64 kernels < 2.6.11, as if we run into +- * the accounting bug, the kernel will throw a BUG. this isn't 100% accurate, +- * as it doesn't throw a bug until we try to restore the caching attributes +- * of the page. so if we can track down a 4M allocation, we can mark it +- * uncached and see if the accounting was done correctly. +- * +- * this is a little ugly, but the most accurate approach to determining if +- * this kernel is good. ++ * There's really no good way to determine if change_page_attr() is working ++ * correctly. We can't reliably use change_page_attr() on Linux/x86-64 2.6 ++ * kernels < 2.6.11: if we run into the accounting bug, the Linux kernel will ++ * trigger a BUG() if we attempt to restore the WB memory type of a page ++ * originally part of a large page. + * +- * why do we even bother? some distributions have back-ported the cpa fix to +- * kernels < 2.6.11. we want to use change_page_attr to avoid random corruption +- * and hangs, but need to make sure it's safe to do so. ++ * So if we can successfully allocate such a page, change its memory type to ++ * UC and check if the accounting was done correctly, we can determine if ++ * the change_page_attr() interface can be used safely. + * +- * return values: +- * 0 - test passed, interface works +- * 1 - test failed, status unclear +- * -1 - test failed, interface broken ++ * Return values: ++ * 0 - test passed, the change_page_attr() interface works ++ * 1 - test failed, the status is unclear ++ * -1 - test failed, the change_page_attr() interface is broken + */ + + static inline pte_t *check_large_page(unsigned long vaddr) +@@ -1061,7 +1055,7 @@ + pgd_t *pgd = NULL; + pmd_t *pmd = NULL; + +- pgd = NV_PGD_OFFSET(vaddr, 1, &init_mm); ++ pgd = NV_PGD_OFFSET(vaddr, 1, NULL); + if (!NV_PGD_PRESENT(pgd)) + return NULL; + +@@ -1171,20 +1165,29 @@ + + return 1; + } +- + #endif /* defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT) */ + +- +-// verify that the kernel's mapping matches the requested type +-// this is to protect against accidental cache aliasing problems ++/* ++ * nv_verify_page_mappings() - verify that the kernel mapping of the specified ++ * page matches the specified type. This is to help detect bugs in the Linux ++ * kernel's change_page_attr() interface, early. ++ * ++ * This function relies on the ability to perform kernel virtul address to PFN ++ * translations and therefore on 'init_mm'. Unfortunately, the latter is no ++ * longer exported in recent Linux/x86 2.6 kernels. The export was removed at ++ * roughtly the same time as the set_pages_{uc,wb}() change_page_attr() ++ * replacement interfaces were introduced; hopefully, it will be sufficient to ++ * check for their presence. ++ */ + int nv_verify_page_mappings( + nv_pte_t *page_ptr, + unsigned int cachetype + ) + { ++#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) || \ ++ (defined(NV_SET_PAGES_UC_PRESENT) && !defined(NVCPU_X86)) + unsigned long retval = -1; + #if defined(NVCPU_X86) || defined(NVCPU_X86_64) +- struct mm_struct *mm; + pgd_t *pgd = NULL; + pmd_t *pmd = NULL; + pte_t *pte = NULL; +@@ -1192,15 +1195,12 @@ + unsigned long address; + static int count = 0; + +-#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) +- if (!nv_use_cpa) ++ if (!nv_update_memory_types) + return 0; +-#endif + + address = (unsigned long)__va(page_ptr->phys_addr); +- mm = &init_mm; // always a kernel page + +- pgd = NV_PGD_OFFSET(address, 1, mm); ++ pgd = NV_PGD_OFFSET(address, 1, NULL); + if (!NV_PGD_PRESENT(pgd)) + { + nv_printf(NV_DBG_ERRORS, "NVRM: pgd not present for addr 0x%lx\n", address); +@@ -1266,8 +1266,11 @@ + } + + failed: +-#endif ++#endif /* defined(NVCPU_X86) || defined(NVCPU_X86_64) */ + return retval; ++#else ++ return 0; ++#endif + } + + #if defined(NV_BUILD_NV_PAT_SUPPORT) && defined(CONFIG_HOTPLUG_CPU) +@@ -1313,7 +1316,7 @@ + static int __init nvidia_init_module(void) + { + int rc; +- U032 i, count; ++ U032 i, count, data; + nv_state_t *nv = NV_STATE_PTR(&nv_ctl_device); + nv_stack_t *sp = NULL; + +@@ -1485,43 +1488,42 @@ + /* create /proc/driver/nvidia */ + nvos_proc_create(); + +-#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) ++ /* ++ * Give users an opportunity to disable the driver's use of ++ * the change_page_attr() and set_pages_{uc,wb}() kernel ++ * interfaces. ++ */ ++ rc = rm_read_registry_dword(sp, nv, ++ "NVreg", NV_REG_UPDATE_MEMORY_TYPES, &data); ++ if ((rc == 0) && ((int)data != ~0)) + { +- int data; +- +- // allow the user to override us with a registry key +- rc = rm_read_registry_dword(sp, nv, "NVreg", "UseCPA", &data); +- if ((rc == 0) && (data != -1)) +- { +- nv_use_cpa = data; +- } ++ nv_update_memory_types = data; ++ } + #if defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT) +- else ++ /* ++ * Unless we explicitely detect that the change_page_attr() ++ * inteface is fixed, disable usage of the interface on ++ * this kernel. Notify the user of this problem using the ++ * driver's /proc warnings interface (read by the installer ++ * and the bug report script). ++ */ ++ else ++ { ++ rc = nv_verify_cpa_interface(); ++ if (rc < 0) + { +- /* +- * Unless we explicitely detect that the change_page_attr() +- * inteface is fixed, disable usage of the interface on +- * this kernel. Notify the user of this problem using the +- * driver's /proc warnings interface (read by the installer +- * and the bug report script). +- */ +- rc = nv_verify_cpa_interface(); +- if (rc < 0) +- { +- nv_prints(NV_DBG_ERRORS, __cpgattr_warning); +- nvos_proc_add_warning_file("change_page_attr", __cpgattr_warning); +- nv_use_cpa = 0; +- } +- else if (rc != 0) +- { +- nv_prints(NV_DBG_ERRORS, __cpgattr_warning_2); +- nvos_proc_add_warning_file("change_page_attr", __cpgattr_warning_2); +- nv_use_cpa = 0; +- } ++ nv_prints(NV_DBG_ERRORS, __cpgattr_warning); ++ nvos_proc_add_warning_file("change_page_attr", __cpgattr_warning); ++ nv_update_memory_types = 0; ++ } ++ else if (rc != 0) ++ { ++ nv_prints(NV_DBG_ERRORS, __cpgattr_warning_2); ++ nvos_proc_add_warning_file("change_page_attr", __cpgattr_warning_2); ++ nv_update_memory_types = 0; + } +-#endif + } +-#endif ++#endif /* defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT) */ + + #if defined(NVCPU_X86_64) && defined(CONFIG_IA32_EMULATION) && !defined(HAVE_COMPAT_IOCTL) + /* Register ioctl()'s for 32-bit clients */ +@@ -3482,8 +3484,21 @@ + pte_t *pte = NULL; + NvU64 retval; + +- mm = (kern) ? &init_mm : current->mm; +- if (!kern) down_read(¤t->mm->mmap_sem); ++ if (!kern) ++ { ++ mm = current->mm; ++ down_read(&mm->mmap_sem); ++ } ++ else ++ { ++#if defined(NV_SET_PAGES_UC_PRESENT) && defined(NVCPU_X86) ++ /* nv_printf(NV_DBG_ERRORS, ++ "NVRM: can't translate KVA in nv_get_phys_address()!\n"); */ ++ return 0; ++#else ++ mm = NULL; ++#endif ++ } + + pgd = NV_PGD_OFFSET(address, kern, mm); + if (!NV_PGD_PRESENT(pgd)) +@@ -3504,22 +3519,24 @@ + retval &= ~_PAGE_NX; + #endif + +- if (!kern) up_read(¤t->mm->mmap_sem); ++ if (!kern) ++ up_read(&mm->mmap_sem); + return retval; + + failed: +- if (!kern) up_read(¤t->mm->mmap_sem); ++ if (!kern) ++ up_read(&mm->mmap_sem); + return 0; + } + + NvU64 NV_API_CALL nv_get_kern_phys_address(NvU64 address) + { +- // make sure this address is a kernel pointer ++ /* make sure this address is a kernel virtual address */ + #if defined(DEBUG) && !defined(CONFIG_X86_4G) + if (address < PAGE_OFFSET) + { + nv_printf(NV_DBG_WARNINGS, +- "NVRM: user address passed to get_kern_phys_address: 0x%lx\n", ++ "NVRM: user address passed to get_kern_phys_address: 0x%llx!\n", + address); + return 0; + } +@@ -3534,12 +3551,12 @@ + + NvU64 NV_API_CALL nv_get_kern_user_address(NvU64 address) + { +- // make sure this address is not a kernel pointer ++ /* make sure this address is not a kernel virtual address */ + #if defined(DEBUG) && !defined(CONFIG_X86_4G) + if (address >= PAGE_OFFSET) + { + nv_printf(NV_DBG_WARNINGS, +- "NVRM: kernel address passed to get_user_phys_address: 0x%lx\n", ++ "NVRM: kernel address passed to get_user_phys_address: 0x%llx!\n", + address); + return 0; + } +@@ -4316,16 +4333,12 @@ + return -1; + } + +-int NV_API_CALL nv_no_incoherent_mappings +-( +- void +-) ++int NV_API_CALL nv_no_incoherent_mappings(void) + { + if(nv_ext_no_incoherent_mappings() == 1) + return 1; +- +-#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) +- return 1; ++#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) || defined(NV_SET_PAGES_UC_PRESENT) ++ return (nv_update_memory_types); + #else + return 0; + #endif +diff -ru usr/src/nv/os-interface.c usr/src/nv.2286310/os-interface.c +--- usr/src/nv/os-interface.c 2008-03-16 14:13:09.000000000 -0700 ++++ usr/src/nv.2286310/os-interface.c 2008-03-16 14:37:47.208131723 -0700 +@@ -1198,6 +1198,18 @@ + { + void *vaddr; + ++ if (start == 0) ++ { ++ if (mode != NV_MEMORY_CACHED) ++ { ++ nv_printf(NV_DBG_ERRORS, ++ "NVRM: os_map_kernel_space: won't map address 0x%0llx UC!\n", start); ++ return NULL; ++ } ++ else ++ return (void *)PAGE_OFFSET; ++ } ++ + if (!NV_MAY_SLEEP()) + { + nv_printf(NV_DBG_ERRORS, +@@ -1230,6 +1242,9 @@ + NvU64 size_bytes + ) + { ++ if (addr == (void *)PAGE_OFFSET) ++ return; ++ + NV_IOUNMAP(addr, size_bytes); + } + diff --git a/abs/core-testing/nvidia/PKGBUILD b/abs/core-testing/nvidia/PKGBUILD new file mode 100644 index 0000000..b1af8b5 --- /dev/null +++ b/abs/core-testing/nvidia/PKGBUILD @@ -0,0 +1,39 @@ +# $Id: PKGBUILD 8443 2008-08-11 05:11:22Z tpowa $ +# Maintainer : Thomas Baechler <thomas@archlinux.org> + +pkgname=nvidia +pkgver=173.14.12 +_kernver='2.6.26-ARCH' +pkgrel=3 +pkgdesc="NVIDIA drivers for kernel26." +arch=('i686' 'x86_64') +[ "$CARCH" = "i686" ] && ARCH=x86 +[ "$CARCH" = "x86_64" ] && ARCH=x86_64 +url="http://www.nvidia.com/" +depends=('kernel26>=2.6.26.2-1' 'kernel26<2.6.27' 'nvidia-utils') +conflicts=('nvidia-96xx' 'nvidia-71xx' 'nvidia-legacy') +license=('custom') +install=nvidia.install +source=(http://us.download.nvidia.com/XFree86/Linux-$ARCH/${pkgver}/NVIDIA-Linux-$ARCH-${pkgver}-pkg0.run) +md5sums=('76b8eba1b14fc273a1a4044705b0aa56') +[ "$CARCH" = "x86_64" ] && md5sums=('8675e4ca65033b343c8c77b2ce82e71d') + +build() +{ + # Extract + cd $startdir/src/ + sh NVIDIA-Linux-$ARCH-${pkgver}-pkg0.run --extract-only + cd NVIDIA-Linux-$ARCH-${pkgver}-pkg0 + + # Any extra patches are applied in here... + + cd usr/src/nv/ + ln -s Makefile.kbuild Makefile + make SYSSRC=/lib/modules/${_kernver}/build module || return 1 + + # install kernel module + mkdir -p $startdir/pkg/lib/modules/${_kernver}/kernel/drivers/video/ + install -m644 nvidia.ko $startdir/pkg/lib/modules/${_kernver}/kernel/drivers/video/ + + sed -i -e "s/KERNEL_VERSION='.*'/KERNEL_VERSION='${_kernver}'/" $startdir/*.install +} diff --git a/abs/core-testing/nvidia/nvidia.install b/abs/core-testing/nvidia/nvidia.install new file mode 100644 index 0000000..dbbec39 --- /dev/null +++ b/abs/core-testing/nvidia/nvidia.install @@ -0,0 +1,22 @@ +# arg 1: the new package version +post_install() { + KERNEL_VERSION='2.6.26-ARCH' + depmod -v $KERNEL_VERSION > /dev/null 2>&1 +} + +# arg 1: the new package version +# arg 2: the old package version +post_upgrade() { + post_install $1 + rmmod nvidia || echo 'In order to use the new nvidia module, exit Xserver and unload it manually.' +} + +# arg 1: the old package version +post_remove() { + KERNEL_VERSION='2.6.26-ARCH' + depmod -v $KERNEL_VERSION > /dev/null 2>&1 +} + +op=$1 +shift +$op $* |