[BACK]Return to patch.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / x86 / x86

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/x86/x86/patch.c between version 1.1 and 1.1.2.1

version 1.1, 2007/01/27 07:09:03 version 1.1.2.1, 2007/01/27 07:09:03
Line 0 
Line 1 
   /*      $NetBSD$        */
   
   /*-
    * Copyright (c) 2007 The NetBSD Foundation, Inc.
    * All rights reserved.
    *
    * This code is derived from software contributed to The NetBSD Foundation
    * 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.
    */
   
   /*
    * Patch kernel code at boot time, depending on available CPU features.
    */
   
   #include <sys/cdefs.h>
   __KERNEL_RCSID(0, "$NetBSD$");
   
   #include "opt_multiprocessor.h"
   #include "opt_lockdebug.h"
   #ifdef i386
   #include "opt_cputype.h"
   #endif
   
   #include <sys/types.h>
   #include <sys/systm.h>
   
   #include <machine/cpu.h>
   #include <machine/cpufunc.h>
   #include <machine/specialreg.h>
   
   #include <x86/cpuvar.h>
   #include <x86/cputypes.h>
   
   void    spllower(int);
   void    spllower_end(void);
   void    i686_spllower(int);
   void    i686_spllower_end(void);
   void    i686_spllower_patch(void);
   void    amd64_spllower(int);
   void    amd64_spllower_end(void);
   void    amd64_spllower_patch(void);
   
   void    smutex_exit(int);
   void    smutex_exit_end(void);
   void    i686_smutex_exit(int);
   void    i686_smutex_exit_end(void);
   void    i686_smutex_exit_patch(void);
   
   #define X86_NOP         0x90
   #define X86_REP         0xf3
   #define X86_RET         0xc3
   
   static void __attribute__ ((__unused__))
   patchfunc(void *from_s, void *from_e, void *to_s, void *to_e,
             void *pcrel)
   {
           uint8_t *ptr;
           u_long psl;
   
           if ((uintptr_t)from_e - (uintptr_t)from_s !=
               (uintptr_t)to_e - (uintptr_t)to_s)
                   panic("patchfunc: sizes do not match (from=%p)", from_s);
   
           psl = read_psl();
           disable_intr();
           memcpy(to_s, from_s, (uintptr_t)to_e - (uintptr_t)to_s);
           if (pcrel != NULL) {
                   ptr = pcrel;
                   /* Branch hints */
                   if (ptr[0] == 0x2e || ptr[0] == 0x3e)
                           ptr++;
                   /* Conditional jumps */
                   if (ptr[0] == 0x0f)
                           ptr++;
                   /* 4-byte relative jump or call */
                   *(uint32_t *)(ptr + 1 - (uintptr_t)from_s + (uintptr_t)to_s) +=
                       ((uint32_t)(uintptr_t)from_s - (uint32_t)(uintptr_t)to_s);
           }
           x86_flush();
           write_psl(psl);
   }
   
   static inline void  __attribute__ ((__unused__))
   patchbyte(void *addr, uint8_t byte)
   {
           *(uint8_t *)addr = byte;
   }
   
   void
   x86_patch(void)
   {
           static int again;
           u_long cr0;
   
           if (again)
                   return;
           again = 1;
   
           /* Disable write protection in supervisor mode. */
           cr0 = rcr0();
           lcr0(cr0 & ~CR0_WP);
   
   #ifdef I686_CPU
           if (cpu_class == CPUCLASS_686 && (cpu_feature & CPUID_CX8) != 0) {
                   patchfunc(i686_spllower, i686_spllower_end, spllower,
                       spllower_end, i686_spllower_patch);
   #if !defined(LOCKDEBUG) && !defined(I386_CPU) && !defined(DIAGNOSTIC)
                   patchfunc(i686_smutex_exit, i686_smutex_exit_end,
                       smutex_exit, smutex_exit_end, i686_smutex_exit_patch);
   #endif  /* !defined(LOCKDEBUG) && !defined(I386_CPU) */
           }
   #endif  /* I686_CPU */
   
   #ifdef __x86_64__
           patchfunc(amd64_spllower, amd64_spllower_end, spllower,
               spllower_end, amd64_spllower_patch);
   #endif  /* __x86_64__ */
   
           lcr0(cr0);
   }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.1

CVSweb <webmaster@jp.NetBSD.org>