1 /* $OpenBSD: io.c,v 1.6 2021/09/17 15:18:04 deraadt Exp $ */ 2 /*- 3 * Copyright (c) 1998 Doug Rabson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/types.h> 29 #include <sys/sysctl.h> 30 #include <machine/cpu.h> 31 #include <stdlib.h> 32 #include <err.h> 33 34 #include "io.h" 35 36 static struct io_ops *ops; 37 38 int 39 ioperm(unsigned long from, unsigned long num, int on) 40 { 41 int error; 42 int bwx; 43 size_t len = sizeof(bwx); 44 int mib[3]; 45 46 mib[0] = CTL_MACHDEP; 47 mib[1] = CPU_CHIPSET; 48 mib[2] = CPU_CHIPSET_BWX; 49 if ((error = sysctl(mib, 3, &bwx, &len, NULL, 0)) < 0) 50 return error; 51 if (bwx) 52 ops = &bwx_io_ops; 53 else 54 #ifdef notyet 55 ops = &swiz_io_ops; 56 #else 57 errx(1, "libio is only available on bwx capable machines"); 58 #endif 59 60 return ops->ioperm(from, num, on); 61 } 62 63 u_int8_t 64 inb(u_int32_t port) 65 { 66 return ops->inb(port); 67 } 68 69 u_int16_t 70 inw(u_int32_t port) 71 { 72 return ops->inw(port); 73 } 74 75 u_int32_t 76 inl(u_int32_t port) 77 { 78 return ops->inl(port); 79 } 80 81 void 82 outb(u_int32_t port, u_int8_t val) 83 { 84 ops->outb(port, val); 85 } 86 87 void 88 outw(u_int32_t port, u_int16_t val) 89 { 90 ops->outw(port, val); 91 } 92 93 void 94 outl(u_int32_t port, u_int32_t val) 95 { 96 ops->outl(port, val); 97 } 98 99 void * 100 map_memory(u_int32_t address, u_int32_t size) 101 { 102 return ops->map_memory(address, size); 103 } 104 105 void 106 unmap_memory(void *handle, u_int32_t size) 107 { 108 ops->unmap_memory(handle, size); 109 } 110 111 u_int8_t 112 readb(void *handle, u_int32_t offset) 113 { 114 return ops->readb(handle, offset); 115 } 116 117 u_int16_t 118 readw(void *handle, u_int32_t offset) 119 { 120 return ops->readw(handle, offset); 121 } 122 123 u_int32_t 124 readl(void *handle, u_int32_t offset) 125 { 126 return ops->readl(handle, offset); 127 } 128 129 void 130 writeb(void *handle, u_int32_t offset, u_int8_t val) 131 { 132 ops->writeb(handle, offset, val); 133 __asm__ volatile ("mb"); 134 } 135 136 void 137 writew(void *handle, u_int32_t offset, u_int16_t val) 138 { 139 ops->writew(handle, offset, val); 140 __asm__ volatile ("mb"); 141 } 142 143 void 144 writel(void *handle, u_int32_t offset, u_int32_t val) 145 { 146 ops->writel(handle, offset, val); 147 __asm__ volatile ("mb"); 148 } 149 150 void 151 writeb_nb(void *handle, u_int32_t offset, u_int8_t val) 152 { 153 ops->writeb(handle, offset, val); 154 } 155 156 void 157 writew_nb(void *handle, u_int32_t offset, u_int16_t val) 158 { 159 ops->writew(handle, offset, val); 160 } 161 162 void 163 writel_nb(void *handle, u_int32_t offset, u_int32_t val) 164 { 165 ops->writel(handle, offset, val); 166 } 167 168 u_int64_t 169 dense_base(void) 170 { 171 static u_int64_t base = 0; 172 173 if (base == 0) { 174 size_t len = sizeof(base); 175 int error; 176 int mib[3]; 177 178 mib[0] = CTL_MACHDEP; 179 mib[1] = CPU_CHIPSET; 180 mib[2] = CPU_CHIPSET_DENSE; 181 182 if ((error = sysctl(mib, 3, &base, &len, NULL, 0)) < 0) 183 err(1, "machdep.chipset.dense_base"); 184 } 185 186 return base; 187 } 188