xref: /netbsd-src/sys/arch/prep/stand/boot/io.c (revision cde8f271ec30c028c5652673e0e3c4a6298637d1)
1 /*	$NetBSD: io.c,v 1.6 2022/02/16 23:49:27 riastradh Exp $	*/
2 
3 /*-
4  * Copyright (C) 1995-1997 Gary Thomas (gdt@linuxppc.org)
5  * All rights reserved.
6  *
7  * PCI/ISA I/O support
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Gary Thomas.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <lib/libsa/stand.h>
36 #include <sys/bswap.h>
37 #include "boot.h"
38 
39 
40 volatile u_char *PCI_mem = (u_char *)0xc0000000;
41 volatile u_char *ISA_io  = (u_char *)0x80000000;
42 volatile u_char *ISA_mem = (u_char *)0xc0000000;
43 volatile char *videomem = (char *)0xc00b8000; /* + vram offset */
44 
45 static int dcache_line_size = 32;
46 
47 
48 void
outb(int port,char val)49 outb(int port, char val)
50 {
51 
52 	ISA_io[port] = val;
53 }
54 
55 inline void
outw(int port,u_int16_t val)56 outw(int port, u_int16_t val)
57 {
58         outb(port, val>>8);
59         outb(port+1, val);
60 }
61 
62 u_char
inb(int port)63 inb(int port)
64 {
65 
66 	return (ISA_io[port]);
67 }
68 
69 u_char
readb(u_long addr)70 readb(u_long addr)
71 {
72 
73 	return PCI_mem[addr];
74 }
75 
76 u_short
readw(u_long addr)77 readw(u_long addr)
78 {
79 
80 	return le16toh(*((u_short *)&PCI_mem[addr]));
81 }
82 
83 u_long
readl(u_long addr)84 readl(u_long addr)
85 {
86 
87 	return le32toh(*((u_long *)&PCI_mem[addr]));
88 }
89 
90 void
writeb(u_long addr,u_char val)91 writeb(u_long addr, u_char val)
92 {
93 
94 	PCI_mem[addr] = val;
95 }
96 
97 void
writel(u_long addr,u_long val)98 writel(u_long addr, u_long val)
99 {
100 
101 	*((u_long *)&PCI_mem[addr]) = htole32(val);
102 }
103 
104 void
_wbinv(uint32_t adr,uint32_t siz)105 _wbinv(uint32_t adr, uint32_t siz)
106 {
107 	uint32_t bnd;
108 
109 	asm volatile("eieio" ::: "memory");
110 	for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
111 		asm volatile("dcbf 0,%0" :: "r"(adr) : "memory");
112 	asm volatile("sync" ::: "memory");
113 }
114 
115 void
_inv(uint32_t adr,uint32_t siz)116 _inv(uint32_t adr, uint32_t siz)
117 {
118 	uint32_t bnd, off;
119 
120 	off = adr & (dcache_line_size - 1);
121 	adr -= off;
122 	siz += off;
123 	asm volatile("eieio" ::: "memory");
124 	if (off != 0) {
125 		/* wbinv() leading unaligned dcache line */
126 		asm volatile("dcbf 0,%0" :: "r"(adr) : "memory");
127 		if (siz < dcache_line_size)
128 			goto done;
129 		adr += dcache_line_size;
130 		siz -= dcache_line_size;
131 	}
132 	bnd = adr + siz;
133 	off = bnd & (dcache_line_size - 1);
134 	if (off != 0) {
135 		/* wbinv() trailing unaligned dcache line */
136 		asm volatile("dcbf 0,%0" :: "r"(bnd) : "memory"); /* it's OK */
137 		if (siz < dcache_line_size)
138 			goto done;
139 		siz -= off;
140 	}
141 	for (bnd = adr + siz; adr < bnd; adr += dcache_line_size) {
142 		/* inv() intermediate dcache lines if ever */
143 		asm volatile("dcbi 0,%0" :: "r"(adr) : "memory");
144 	}
145   done:
146 	asm volatile("sync" ::: "memory");
147 }
148 
149 u_long
local_to_PCI(u_long addr)150 local_to_PCI(u_long addr)
151 {
152 
153 	return ((addr & 0x7FFFFFFF) | 0x80000000);
154 }
155