Home | History | Annotate | Line # | Download | only in sun2
      1 /*	$NetBSD: control.c,v 1.6 2008/04/28 20:23:37 martin Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1996 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Adam Glass, Gordon W. Ross, and Matthew Fredette.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: control.c,v 1.6 2008/04/28 20:23:37 martin Exp $");
     34 
     35 #include <sys/param.h>
     36 
     37 #include <machine/pte.h>
     38 #include <sun2/sun2/control.h>
     39 
     40 int
     41 get_context(void)
     42 {
     43 	return (get_control_byte(CONTEXT_REG) & CONTEXT_MASK);
     44 }
     45 
     46 void
     47 set_context(int c)
     48 {
     49 	set_control_byte(CONTEXT_REG, (c & CONTEXT_MASK));
     50 }
     51 
     52 u_int
     53 get_pte(vaddr_t va)
     54 {
     55 	u_int pte;
     56 
     57 	pte = get_control_word(CONTROL_ADDR_BUILD(PGMAP_BASE, va));
     58 	if (pte & PG_VALID) {
     59 		/*
     60 		 * This clears bit 30 (the kernel readable bit, which
     61 		 * should always be set), bit 28 (which should always
     62 		 * be set), bit 26 (the user writable bit, which we
     63 		 * always have tracking the kernel writable bit), and
     64 		 * bit 25 (the fill-on-demand bit, which should always
     65 		 * be set).  In the protection, this leaves bit 29
     66 		 * (the kernel writable bit) and bit 27 (the user
     67 		 * readable bit).  See pte.h for more about this
     68 		 * hack.
     69 		 */
     70 		pte &= ~(0x56000000);
     71 		/*
     72 		 * Flip bit 27 (the user readable bit) to become bit
     73 		 * 27 (the PG_SYSTEM bit).
     74 		 */
     75 		pte ^= (PG_SYSTEM);
     76 	}
     77 	return (pte);
     78 }
     79 
     80 void
     81 set_pte(vaddr_t va, u_int pte)
     82 {
     83 	if (pte & PG_VALID) {
     84 		/* Clear bit 26 (the user writable bit).  */
     85 		pte &= (~0x04000000);
     86 		/*
     87 		 * Flip bit 27 (the PG_SYSTEM bit) to become bit 27
     88 		 * (the user readable bit).
     89 		 */
     90 		pte ^= (PG_SYSTEM);
     91 		/*
     92 		 * Always set bits 30 (the kernel readable bit), bit
     93 		 * 28, and bit 25 (the fill-on-demand bit), and set
     94 		 * bit 26 (the user writable bit) iff bit 29 (the
     95 		 * kernel writable bit) is set *and* bit 27 (the user
     96 		 * readable bit) is set.  This latter bit of logic is
     97 		 * expressed in the bizarre second term below, chosen
     98 		 * because it needs no branches.
     99 		 */
    100 #if (PG_WRITE >> 2) != PG_SYSTEM
    101 #error	"PG_WRITE and PG_SYSTEM definitions don't match!"
    102 #endif
    103 		pte |= 0x52000000
    104 		    | ((((pte & PG_WRITE) >> 2) & pte) >> 1);
    105 	}
    106 	set_control_word(CONTROL_ADDR_BUILD(PGMAP_BASE, va), pte);
    107 }
    108 
    109 int
    110 get_segmap(vaddr_t va)
    111 {
    112 	return (get_control_byte(CONTROL_ADDR_BUILD(SEGMAP_BASE, va)));
    113 }
    114 
    115 void
    116 set_segmap(vaddr_t va, int sme)
    117 {
    118 	set_control_byte(CONTROL_ADDR_BUILD(SEGMAP_BASE, va), sme);
    119 }
    120