xref: /netbsd/sys/arch/arc/arc/bus_space_sparse.c (revision bf9ec67e)
1 /*	$NetBSD: bus_space_sparse.c,v 1.6 2001/09/10 21:19:31 chris Exp $	*/
2 /*	NetBSD: bus_machdep.c,v 1.1 2000/01/26 18:48:00 drochner Exp 	*/
3 
4 /*-
5  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
10  * Simulation Facility, NASA Ames Research Center.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *	This product includes software developed by the NetBSD
23  *	Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42  * For sparse bus space
43  *
44  * This bus_space uses KSEG2 mapping, if the physical address is not
45  * accessible via KSEG0/KSEG1.
46  */
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/malloc.h>
51 #include <sys/extent.h>
52 
53 #include <uvm/uvm_extern.h>
54 
55 #include <mips/cpuregs.h>
56 #include <mips/pte.h>
57 
58 #include <machine/bus.h>
59 
60 extern paddr_t kvtophys __P((vaddr_t));	/* XXX */
61 
62 void	arc_kseg2_make_cacheable __P((vaddr_t vaddr, vsize_t size));
63 
64 void
65 arc_kseg2_make_cacheable(vaddr, size)
66 	vaddr_t vaddr;
67 	vsize_t size;
68 {
69 	vaddr_t start, end;
70 	pt_entry_t *pte;
71 	u_int32_t entry, mask;
72 
73 	start = mips_trunc_page(vaddr);
74 	end = mips_round_page(vaddr + size);
75 	mask = ~(CPUISMIPS3 ? MIPS3_PG_UNCACHED : MIPS1_PG_N);
76 	for (; start < end; start += NBPG) {
77 		pte = kvtopte(start);
78 		entry = pte->pt_entry & mask;
79 		pte->pt_entry &= entry;
80 		MachTLBUpdate(start, entry);
81 	}
82 }
83 
84 void
85 arc_sparse_bus_space_init(bst, name, paddr, start, size)
86 	bus_space_tag_t bst;
87 	const char *name;
88 	paddr_t paddr;
89 	bus_addr_t start;
90 	bus_size_t size;
91 {
92 	arc_bus_space_init(bst, name, paddr, ARC_BUS_SPACE_UNMAPPED,
93 	    start, size);
94 	bst->bs_compose_handle = arc_sparse_bus_space_compose_handle;
95 	bst->bs_dispose_handle = arc_sparse_bus_space_dispose_handle;
96 	bst->bs_paddr = arc_sparse_bus_space_paddr;
97 }
98 
99 int
100 arc_sparse_bus_space_compose_handle(bst, addr, size, flags, bshp)
101 	bus_space_tag_t bst;
102 	bus_addr_t addr;
103 	bus_size_t size;
104 	int flags;
105 	bus_space_handle_t *bshp;
106 {
107 	bus_size_t offset = addr - bst->bs_start;
108 	/*
109 	 * Since all buses can be linearly mappable, we don't have to check
110 	 * BUS_SPACE_MAP_LINEAR and BUS_SPACE_MAP_PREFETCHABLE.
111 	 */
112 	int cacheable = (flags & BUS_SPACE_MAP_CACHEABLE);
113 
114 	/*
115 	 * XXX - `bst->bs_pbase' must be page aligned,
116 	 * mips_trunc/round_page() cannot treat paddr_t due to overflow.
117 	 */
118 	paddr_t start = bst->bs_pbase + mips_trunc_page(offset);
119 	paddr_t end = bst->bs_pbase + mips_round_page(offset + size);
120 
121 	if (end <= MIPS_KSEG1_START - MIPS_KSEG0_START) {
122 		/* mappable on KSEG0 or KSEG1 */
123 		*bshp = (cacheable ?
124 		    MIPS_PHYS_TO_KSEG0(start) :
125 		    MIPS_PHYS_TO_KSEG1(start));
126 	} else {
127 		vaddr_t va,
128 		    vaddr = uvm_km_valloc(kernel_map, (vsize_t)(end - start));
129 
130 		if (vaddr == NULL)
131 			panic("arc_sparse_bus_space_compose_handle: "
132 			      "cannot allocate KVA 0x%llx..0x%llx",
133 			      start, end);
134 		for (va = vaddr; start < end; start += NBPG, va += NBPG)
135 			pmap_kenter_pa(va, start, VM_PROT_READ|VM_PROT_WRITE);
136 		pmap_update(pmap_kernel());
137 		vaddr += (offset & PGOFSET);
138 		if (cacheable)
139 			arc_kseg2_make_cacheable(vaddr, size);
140 		*bshp = vaddr;
141 	}
142 	return (0);
143 }
144 
145 int
146 arc_sparse_bus_space_dispose_handle(bst, bsh, size)
147 	bus_space_tag_t bst;
148 	bus_space_handle_t bsh;
149 	bus_size_t size;
150 {
151 	vaddr_t start = mips_trunc_page(bsh);
152 	vaddr_t end = mips_round_page(bsh + size);
153 
154 	if (start < MIPS_KSEG2_START) /* KSEG0/KSEG1 */
155 		return (0);
156 
157 	uvm_km_free(kernel_map, start, end - start);
158 	return (0);
159 }
160 
161 int
162 arc_sparse_bus_space_paddr(bst, bsh, pap)
163 	bus_space_tag_t bst;
164 	bus_space_handle_t bsh;
165 	paddr_t *pap;
166 {
167 	*pap = kvtophys(bsh);
168 	return (0);
169 }
170