1 /* $NetBSD: alpha_pci_mem.c,v 1.4 2002/07/19 22:03:39 mycroft Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
33 * Support for mapping PCI/EISA/ISA memory space. This is currently used
34 * to provide such support for XFree86. In a perfect world, this would go
35 * away in favor of a real bus space mapping framework.
38 #include <sys/param.h>
41 #include <machine/sysarch.h>
49 struct alpha_bus_window
*alpha_pci_mem_windows
;
50 int alpha_pci_mem_window_count
;
53 alpha_pci_mem_map(bus_addr_t memaddr
, bus_size_t memsize
, int flags
,
54 struct alpha_bus_space_translation
*rabst
)
56 struct alpha_bus_window
*abw
;
58 int prefetchable
= flags
& BUS_SPACE_MAP_PREFETCHABLE
;
59 int linear
= flags
& BUS_SPACE_MAP_LINEAR
;
64 * Can't have linear without prefetchable.
66 if (linear
&& !prefetchable
)
69 if (alpha_pci_mem_windows
== NULL
) {
70 i
= alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_MEM
, &abw
);
74 alpha_pci_mem_windows
= abw
;
75 alpha_pci_mem_window_count
= i
;
78 for (i
= 0; i
< alpha_pci_mem_window_count
; i
++) {
79 abw
= &alpha_pci_mem_windows
[i
];
80 if (memaddr
< abw
->abw_abst
.abst_bus_start
||
81 (memaddr
+ (memsize
- 1)) > abw
->abw_abst
.abst_bus_end
)
85 * Prefetchable memory must be mapped in dense space;
86 * otherwise use sparse space.
89 (abw
->abw_abst
.abst_flags
& ABST_DENSE
) == 0)
92 (abw
->abw_abst
.abst_flags
& ABST_DENSE
) != 0)
95 /* Looks like we have a winner! */
99 /* Not found in any of the windows. */
103 fd
= open(_PATH_MEM
, O_RDWR
, 0600);
108 abw
->abw_abst
.abst_addr_shift
= 0;
109 memsize
<<= abw
->abw_abst
.abst_addr_shift
;
110 offset
= (memaddr
- abw
->abw_abst
.abst_bus_start
) <<
111 abw
->abw_abst
.abst_addr_shift
;
113 addr
= mmap(NULL
, memsize
, PROT_READ
|PROT_WRITE
, MAP_FILE
|MAP_SHARED
,
114 fd
, (off_t
) (abw
->abw_abst
.abst_sys_start
+ offset
));
118 if (addr
!= MAP_FAILED
) {
120 * Make a copy of the space translation so that the caller
121 * can do the correct access.
123 *rabst
= abw
->abw_abst
;
129 alpha_pci_mem_unmap(struct alpha_bus_space_translation
*abst
, void *addr
,
133 (void) munmap(addr
, size
<< abst
->abst_addr_shift
);