Home | History | Annotate | Line # | Download | only in mipsco
      1 /*	$NetBSD: bus_space.c,v 1.14 2023/12/20 15:29:05 thorpej Exp $ 	*/
      2 
      3 /*
      4  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
      9  * Simulation Facility, NASA Ames Research Center.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include <sys/cdefs.h>
     34 __KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.14 2023/12/20 15:29:05 thorpej Exp $");
     35 
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 
     39 #include <uvm/uvm_extern.h>
     40 
     41 #include <machine/bus.h>
     42 
     43 void
     44 mipsco_bus_space_init(bus_space_tag_t bst, const char *name, paddr_t paddr, vaddr_t vaddr, bus_addr_t start, bus_size_t size)
     45 {
     46 	bst->bs_name = name;
     47 	bst->bs_spare = NULL;
     48 	bst->bs_start = start;
     49 	bst->bs_size = size;
     50 	bst->bs_pbase = paddr;
     51 	bst->bs_vbase = vaddr;
     52 	bst->bs_compose_handle = mipsco_bus_space_compose_handle;
     53 	bst->bs_dispose_handle = mipsco_bus_space_dispose_handle;
     54 	bst->bs_paddr = mipsco_bus_space_paddr;
     55 	bst->bs_map = mipsco_bus_space_map;
     56 	bst->bs_unmap = mipsco_bus_space_unmap;
     57 	bst->bs_subregion = mipsco_bus_space_subregion;
     58 	bst->bs_mmap = mipsco_bus_space_mmap;
     59 	bst->bs_alloc = mipsco_bus_space_alloc;
     60 	bst->bs_free = mipsco_bus_space_free;
     61 	bst->bs_aux = NULL;
     62 	bst->bs_bswap = 0; /* No byte swap for stream methods */
     63 	mipsco_bus_space_set_aligned_stride(bst, 0);
     64 }
     65 
     66 void
     67 mipsco_bus_space_set_aligned_stride(bus_space_tag_t bst, unsigned int shift)
     68 	/* shift:		 log2(alignment) */
     69 {
     70 	bst->bs_stride = shift;
     71 
     72 	if (shift == 2) {		/* XXX Assumes Big Endian & 4B */
     73 	    bst->bs_offset_1 = 3;
     74 	    bst->bs_offset_2 = 2;
     75 	} else {
     76 	    bst->bs_offset_1 = 0;
     77 	    bst->bs_offset_2 = 0;
     78 	}
     79 	bst->bs_offset_4 = 0;
     80 	bst->bs_offset_8 = 0;
     81 }
     82 
     83 int
     84 mipsco_bus_space_compose_handle(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp)
     85 {
     86 	bus_space_handle_t bsh = bst->bs_vbase +
     87 	    ((addr - bst->bs_start) << bst->bs_stride);
     88 
     89 	/*
     90 	 * Since all buses can be linearly mappable, we don't have to check
     91 	 * BUS_SPACE_MAP_LINEAR and BUS_SPACE_MAP_PREFETCHABLE.
     92 	 */
     93 	if ((flags & BUS_SPACE_MAP_CACHEABLE) == 0) {
     94 		*bshp = bsh;
     95 		return (0);
     96 	}
     97 	if (bsh < MIPS_KSEG1_START) /* KUSEG or KSEG0 */
     98 		panic("mipsco_bus_space_compose_handle: bad address 0x%x", bsh);
     99 	if (bsh < MIPS_KSEG2_START) { /* KSEG1 */
    100 		*bshp = MIPS_PHYS_TO_KSEG0(MIPS_KSEG1_TO_PHYS(bsh));
    101 		return (0);
    102 	}
    103 	/*
    104 	 * KSEG2:
    105 	 * Do not make the page cacheable in this case, since:
    106 	 * - the page which this bus_space belongs might include
    107 	 *   other bus_spaces.
    108 	 * or
    109 	 * - this bus might be mapped by wired TLB, in that case,
    110 	 *   we cannot manupulate cacheable attribute with page granularity.
    111 	 */
    112 #ifdef DIAGNOSTIC
    113 	printf("mipsco_bus_space_compose_handle: ignore cacheable 0x%x\n", bsh);
    114 #endif
    115 	*bshp = bsh;
    116 	return (0);
    117 }
    118 
    119 int
    120 mipsco_bus_space_dispose_handle(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size)
    121 {
    122 	return (0);
    123 }
    124 
    125 int
    126 mipsco_bus_space_paddr(bus_space_tag_t bst, bus_space_handle_t bsh, paddr_t *pap)
    127 {
    128 	if (bsh < MIPS_KSEG0_START) /* KUSEG */
    129 		panic("mipsco_bus_space_paddr(%p): bad address", (void *)bsh);
    130 	else if (bsh < MIPS_KSEG1_START) /* KSEG0 */
    131 		*pap = MIPS_KSEG0_TO_PHYS(bsh);
    132 	else if (bsh < MIPS_KSEG2_START) /* KSEG1 */
    133 		*pap = MIPS_KSEG1_TO_PHYS(bsh);
    134 	else { /* KSEG2 */
    135 		/*
    136 		 * Since this region may be mapped by wired TLB,
    137 		 * kvtophys() is not always available.
    138 		 */
    139 		*pap = bst->bs_pbase + (bsh - bst->bs_vbase);
    140 	}
    141 	return (0);
    142 }
    143 
    144 int
    145 mipsco_bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp)
    146 {
    147 
    148 	if (addr < bst->bs_start || addr + size > bst->bs_start + bst->bs_size)
    149 		return (EINVAL);
    150 
    151 	return (bus_space_compose_handle(bst, addr, size, flags, bshp));
    152 }
    153 
    154 void
    155 mipsco_bus_space_unmap(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size)
    156 {
    157 	bus_space_dispose_handle(bst, bsh, size);
    158 }
    159 
    160 int
    161 mipsco_bus_space_subregion(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
    162 {
    163 	*nbshp = bsh + (offset << bst->bs_stride);
    164 	return (0);
    165 }
    166 
    167 paddr_t
    168 mipsco_bus_space_mmap(bus_space_tag_t bst, bus_addr_t addr, off_t off, int prot, int flags)
    169 {
    170 
    171 	/*
    172 	 * XXX We do not disallow mmap'ing of I/O space here,
    173 	 * XXX which we should be doing.
    174 	 */
    175 
    176 	if (addr < bst->bs_start ||
    177 	    (addr + off) >= (bst->bs_start + bst->bs_size))
    178 		return (-1);
    179 
    180 	return (mips_btop(bst->bs_pbase + (addr - bst->bs_start) + off));
    181 }
    182 
    183 int
    184 mipsco_bus_space_alloc(bus_space_tag_t bst, bus_addr_t start, bus_addr_t end, bus_size_t size, bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, bus_space_handle_t *bshp)
    185 {
    186 
    187 	panic("bus_space_alloc() not implemented");
    188 }
    189