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