1 1.2 apb /* $NetBSD: v7fs_endian.c,v 1.2 2011/07/18 21:51:49 apb Exp $ */ 2 1.1 uch 3 1.1 uch /*- 4 1.1 uch * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 1.1 uch * All rights reserved. 6 1.1 uch * 7 1.1 uch * This code is derived from software contributed to The NetBSD Foundation 8 1.1 uch * by UCHIYAMA Yasushi. 9 1.1 uch * 10 1.1 uch * Redistribution and use in source and binary forms, with or without 11 1.1 uch * modification, are permitted provided that the following conditions 12 1.1 uch * are met: 13 1.1 uch * 1. Redistributions of source code must retain the above copyright 14 1.1 uch * notice, this list of conditions and the following disclaimer. 15 1.1 uch * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 uch * notice, this list of conditions and the following disclaimer in the 17 1.1 uch * documentation and/or other materials provided with the distribution. 18 1.1 uch * 19 1.1 uch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 uch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 uch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 uch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 uch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 uch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 uch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 uch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 uch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 uch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 uch * POSSIBILITY OF SUCH DAMAGE. 30 1.1 uch */ 31 1.1 uch 32 1.2 apb #if HAVE_NBTOOL_CONFIG_H 33 1.2 apb #include "nbtool_config.h" 34 1.2 apb #endif 35 1.2 apb 36 1.1 uch #include <sys/cdefs.h> 37 1.2 apb __KERNEL_RCSID(0, "$NetBSD: v7fs_endian.c,v 1.2 2011/07/18 21:51:49 apb Exp $"); 38 1.1 uch #if defined _KERNEL_OPT 39 1.1 uch #include "opt_v7fs.h" 40 1.1 uch #endif 41 1.1 uch 42 1.1 uch #include "v7fs.h" 43 1.1 uch #include "v7fs_endian.h" 44 1.1 uch #include "v7fs_impl.h" 45 1.1 uch 46 1.1 uch #ifndef BYTE_ORDER 47 1.1 uch #error 48 1.1 uch #endif 49 1.1 uch 50 1.1 uch /* PDP to Little */ 51 1.1 uch #define bswap32pdp_le(x) \ 52 1.1 uch ((uint32_t) \ 53 1.1 uch ((((x) & 0xffff0000) >> 16) | \ 54 1.1 uch (((x) & 0x0000ffff) << 16))) 55 1.1 uch /* PDP to Big */ 56 1.1 uch #define bswap32pdp_be(x) \ 57 1.1 uch ((uint32_t) \ 58 1.1 uch ((((x) & 0xff00ff00) >> 8) | \ 59 1.1 uch (((x) & 0x00ff00ff) << 8))) 60 1.1 uch #ifdef V7FS_EI 61 1.1 uch static uint32_t val32_normal_order(uint32_t); 62 1.1 uch static uint32_t val32_reverse_order(uint32_t); 63 1.1 uch #if BYTE_ORDER == LITTLE_ENDIAN 64 1.1 uch static uint32_t val32_pdp_to_little(uint32_t); 65 1.1 uch #else 66 1.1 uch static uint32_t val32_pdp_to_big(uint32_t); 67 1.1 uch #endif 68 1.1 uch static uint16_t val16_normal_order(uint16_t); 69 1.1 uch static uint16_t val16_reverse_order(uint16_t); 70 1.1 uch static v7fs_daddr_t val24_reverse_order_read(uint8_t *); 71 1.1 uch static void val24_reverse_order_write(v7fs_daddr_t, uint8_t *); 72 1.1 uch static v7fs_daddr_t val24_pdp_read(uint8_t *); 73 1.1 uch static void val24_pdp_write(v7fs_daddr_t, uint8_t *); 74 1.1 uch 75 1.1 uch static uint32_t 76 1.1 uch val32_normal_order(uint32_t v) 77 1.1 uch { 78 1.1 uch 79 1.1 uch return v; 80 1.1 uch } 81 1.1 uch 82 1.1 uch static uint32_t 83 1.1 uch val32_reverse_order(uint32_t v) 84 1.1 uch { 85 1.1 uch 86 1.1 uch return bswap32(v); 87 1.1 uch } 88 1.1 uch #if BYTE_ORDER == LITTLE_ENDIAN 89 1.1 uch static uint32_t 90 1.1 uch val32_pdp_to_little(uint32_t v) 91 1.1 uch { 92 1.1 uch 93 1.1 uch return bswap32pdp_le(v); 94 1.1 uch } 95 1.1 uch #else 96 1.1 uch static uint32_t 97 1.1 uch val32_pdp_to_big(uint32_t v) 98 1.1 uch { 99 1.1 uch 100 1.1 uch return bswap32pdp_be(v); 101 1.1 uch } 102 1.1 uch #endif 103 1.1 uch static uint16_t 104 1.1 uch val16_normal_order(uint16_t v) 105 1.1 uch { 106 1.1 uch 107 1.1 uch return v; 108 1.1 uch } 109 1.1 uch 110 1.1 uch static uint16_t 111 1.1 uch val16_reverse_order(uint16_t v) 112 1.1 uch { 113 1.1 uch 114 1.1 uch return bswap16(v); 115 1.1 uch } 116 1.1 uch 117 1.1 uch static v7fs_daddr_t 118 1.1 uch val24_reverse_order_read(uint8_t *a) 119 1.1 uch { 120 1.1 uch #if BYTE_ORDER == LITTLE_ENDIAN 121 1.1 uch return (a[0] << 16) | (a[1] << 8) | a[2]; 122 1.1 uch #else 123 1.1 uch return (a[2] << 16) | (a[1] << 8) | a[0]; 124 1.1 uch #endif 125 1.1 uch } 126 1.1 uch 127 1.1 uch static void 128 1.1 uch val24_reverse_order_write(v7fs_daddr_t addr, uint8_t *a) 129 1.1 uch { 130 1.1 uch #if BYTE_ORDER == LITTLE_ENDIAN 131 1.1 uch a[0] = (addr >> 16) & 0xff; 132 1.1 uch a[1] = (addr >> 8) & 0xff; 133 1.1 uch a[2] = addr & 0xff; 134 1.1 uch #else 135 1.1 uch a[0] = addr & 0xff; 136 1.1 uch a[1] = (addr >> 8) & 0xff; 137 1.1 uch a[2] = (addr >> 16) & 0xff; 138 1.1 uch #endif 139 1.1 uch } 140 1.1 uch 141 1.1 uch static v7fs_daddr_t 142 1.1 uch val24_pdp_read(uint8_t *a) 143 1.1 uch { 144 1.1 uch 145 1.1 uch return (a[0] << 16) | a[1] | (a[2] << 8); 146 1.1 uch } 147 1.1 uch 148 1.1 uch static void 149 1.1 uch val24_pdp_write(v7fs_daddr_t addr, uint8_t *a) 150 1.1 uch { 151 1.1 uch 152 1.1 uch a[0] = (addr >> 16) & 0xff; 153 1.1 uch a[1] = addr & 0xff; 154 1.1 uch a[2] = (addr >> 8) & 0xff; 155 1.1 uch } 156 1.1 uch 157 1.1 uch void 158 1.1 uch v7fs_endian_init(struct v7fs_self *fs) 159 1.1 uch { 160 1.1 uch struct endian_conversion_ops *ops = &fs->val; 161 1.1 uch 162 1.1 uch switch (fs->endian) 163 1.1 uch { 164 1.1 uch #if BYTE_ORDER == LITTLE_ENDIAN 165 1.1 uch case LITTLE_ENDIAN: 166 1.1 uch ops->conv32 = val32_normal_order; 167 1.1 uch ops->conv16 = val16_normal_order; 168 1.1 uch ops->conv24read = val24_normal_order_read; 169 1.1 uch ops->conv24write = val24_normal_order_write; 170 1.1 uch break; 171 1.1 uch case BIG_ENDIAN: 172 1.1 uch ops->conv32 = val32_reverse_order; 173 1.1 uch ops->conv16 = val16_reverse_order; 174 1.1 uch ops->conv24read = val24_reverse_order_read; 175 1.1 uch ops->conv24write = val24_reverse_order_write; 176 1.1 uch break; 177 1.1 uch case PDP_ENDIAN: 178 1.1 uch ops->conv32 = val32_pdp_to_little; 179 1.1 uch ops->conv16 = val16_normal_order; 180 1.1 uch ops->conv24read = val24_pdp_read; 181 1.1 uch ops->conv24write = val24_pdp_write; 182 1.1 uch break; 183 1.1 uch #else /* BIG_ENDIAN */ 184 1.1 uch case LITTLE_ENDIAN: 185 1.1 uch ops->conv32 = val32_reverse_order; 186 1.1 uch ops->conv16 = val16_reverse_order; 187 1.1 uch ops->conv24read = val24_reverse_order_read; 188 1.1 uch ops->conv24write = val24_reverse_order_write; 189 1.1 uch break; 190 1.1 uch case BIG_ENDIAN: 191 1.1 uch ops->conv32 = val32_normal_order; 192 1.1 uch ops->conv16 = val16_normal_order; 193 1.1 uch ops->conv24read = val24_normal_order_read; 194 1.1 uch ops->conv24write = val24_normal_order_write; 195 1.1 uch break; 196 1.1 uch case PDP_ENDIAN: 197 1.1 uch ops->conv32 = val32_pdp_to_big; 198 1.1 uch ops->conv16 = val16_reverse_order; 199 1.1 uch ops->conv24read = val24_pdp_read; 200 1.1 uch ops->conv24write = val24_pdp_write; 201 1.1 uch break; 202 1.1 uch #endif 203 1.1 uch } 204 1.1 uch } 205 1.1 uch #endif /* V7FS_EI */ 206 1.1 uch v7fs_daddr_t 207 1.1 uch val24_normal_order_read(uint8_t *a) 208 1.1 uch { 209 1.1 uch /*(v7fs_daddr_t)cast is required for int 16bit system. */ 210 1.1 uch #if BYTE_ORDER == LITTLE_ENDIAN 211 1.1 uch return ((v7fs_daddr_t)a[2] << 16) | ((v7fs_daddr_t)a[1] << 8) | 212 1.1 uch (v7fs_daddr_t)a[0]; 213 1.1 uch #else 214 1.1 uch return ((v7fs_daddr_t)a[0] << 16) | ((v7fs_daddr_t)a[1] << 8) | 215 1.1 uch (v7fs_daddr_t)a[2]; 216 1.1 uch #endif 217 1.1 uch } 218 1.1 uch 219 1.1 uch void 220 1.1 uch val24_normal_order_write(v7fs_daddr_t addr, uint8_t *a) 221 1.1 uch { 222 1.1 uch #if BYTE_ORDER == LITTLE_ENDIAN 223 1.1 uch a[0] = addr & 0xff; 224 1.1 uch a[1] = (addr >> 8) & 0xff; 225 1.1 uch a[2] = (addr >> 16) & 0xff; 226 1.1 uch #else 227 1.1 uch a[0] = (addr >> 16) & 0xff; 228 1.1 uch a[1] = (addr >> 8) & 0xff; 229 1.1 uch a[2] = addr & 0xff; 230 1.1 uch #endif 231 1.1 uch } 232