|
|
1.1 ! root 1: /* $Id: recode-address.c,v 1.1 2010/02/07 14:07:25 fredette Exp $ */ ! 2: ! 3: /* libtme/recode-rws.c - generic support for recode reads and writes: */ ! 4: ! 5: /* ! 6: * Copyright (c) 2008 Matt Fredette ! 7: * All rights reserved. ! 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 Matt Fredette. ! 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 ! 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ! 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ! 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ! 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ! 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ! 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ! 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! 33: * POSSIBILITY OF SUCH DAMAGE. ! 34: */ ! 35: ! 36: #include <tme/common.h> ! 37: _TME_RCSID("$Id: recode-address.c,v 1.1 2010/02/07 14:07:25 fredette Exp $"); ! 38: ! 39: #if TME_HAVE_RECODE ! 40: ! 41: /* includes: */ ! 42: #include "recode-impl.h" ! 43: ! 44: /* this generic function checks an address type: */ ! 45: void ! 46: tme_recode_address_type_check(const struct tme_recode_ic *ic, ! 47: const struct tme_recode_address_type *address_type) ! 48: { ! 49: tme_uint32_t address_mask_tlb_index_one; ! 50: ! 51: /* the address size can't be bigger than the guest register size: */ ! 52: assert (address_type->tme_recode_address_type_size ! 53: <= ic->tme_recode_ic_reg_size); ! 54: ! 55: /* the minimum alignment must be a power of two: */ ! 56: /* NB: this is a value in bytes, not a TME_RECODE_SIZE_: */ ! 57: assert (address_type->tme_recode_address_type_align_min > 0 ! 58: && (address_type->tme_recode_address_type_align_min ! 59: & (address_type->tme_recode_address_type_align_min - 1)) == 0); ! 60: ! 61: /* the TLB page size must be a power of two: */ ! 62: assert (ic->tme_recode_ic_tlb_page_size > 0 ! 63: && (ic->tme_recode_ic_tlb_page_size ! 64: & (ic->tme_recode_ic_tlb_page_size - 1)) == 0); ! 65: ! 66: /* the TLB index address mask must be some number of consecutive ! 67: one bits, all greater than or equal to the TLB page size: */ ! 68: address_mask_tlb_index_one ! 69: = (address_type->tme_recode_address_type_mask_tlb_index ! 70: & (0 - address_type->tme_recode_address_type_mask_tlb_index)); ! 71: assert (address_mask_tlb_index_one != 0 ! 72: && (((address_type->tme_recode_address_type_mask_tlb_index ! 73: + address_mask_tlb_index_one) ! 74: & address_type->tme_recode_address_type_mask_tlb_index) ! 75: == 0)); ! 76: assert (address_mask_tlb_index_one ! 77: >= ic->tme_recode_ic_tlb_page_size); ! 78: } ! 79: ! 80: /* this generic function returns zero if two address types are the ! 81: same: */ ! 82: int ! 83: tme_recode_address_type_compare(const struct tme_recode_ic *ic, ! 84: const struct tme_recode_address_type *address_type, ! 85: const struct tme_recode_address_type *address_type_other) ! 86: { ! 87: return (TRUE ! 88: ! 89: /* compare ic offset of the context register: */ ! 90: && ((address_type_other->tme_recode_address_type_context_ic_offset < 0) ! 91: ? (address_type->tme_recode_address_type_context_ic_offset < 0) ! 92: : (address_type_other->tme_recode_address_type_context_ic_offset ! 93: == address_type->tme_recode_address_type_context_ic_offset)) ! 94: ! 95: /* compare context register size: */ ! 96: && ((address_type_other->tme_recode_address_type_context_ic_offset < 0) ! 97: || (address_type_other->tme_recode_address_type_context_size ! 98: == address_type->tme_recode_address_type_context_size)) ! 99: ! 100: /* compare address size: */ ! 101: && (address_type_other->tme_recode_address_type_size ! 102: == address_type->tme_recode_address_type_size) ! 103: ! 104: /* compare address signedness: */ ! 105: && ((address_type->tme_recode_address_type_size ! 106: == ic->tme_recode_ic_reg_size) ! 107: || (!address_type_other->tme_recode_address_type_signed ! 108: == !address_type->tme_recode_address_type_signed)) ! 109: ! 110: /* compare minimum alignment: */ ! 111: && (address_type_other->tme_recode_address_type_align_min ! 112: == address_type->tme_recode_address_type_align_min) ! 113: ! 114: /* compare the fixed TLB flags: */ ! 115: && (address_type_other->tme_recode_address_type_tlb_flags ! 116: == address_type->tme_recode_address_type_tlb_flags) ! 117: ! 118: /* compare ic offset of the TLB flags mask: */ ! 119: && (address_type_other->tme_recode_address_type_tlb_flags_ic_offset ! 120: == address_type->tme_recode_address_type_tlb_flags_ic_offset) ! 121: ! 122: /* compare TLB index mask: */ ! 123: && (address_type_other->tme_recode_address_type_mask_tlb_index ! 124: == address_type->tme_recode_address_type_mask_tlb_index) ! 125: ! 126: /* compare ic offset of TLB zero: */ ! 127: && (address_type_other->tme_recode_address_type_tlb0_ic_offset ! 128: == address_type->tme_recode_address_type_tlb0_ic_offset) ! 129: ! 130: ); ! 131: } ! 132: ! 133: /* this returns the recode TLB type for an address type: */ ! 134: void ! 135: tme_recode_address_type_tlb_type(const struct tme_recode_ic *ic, ! 136: const struct tme_recode_address_type *address_type, ! 137: struct tme_recode_tlb_type *tlb_type) ! 138: { ! 139: unsigned long tlb_offset_memory; ! 140: unsigned long tlb_offset_page; ! 141: unsigned long tlb_offset_flags; ! 142: unsigned long tlb_offset_token; ! 143: unsigned long tlb_offset_context; ! 144: unsigned long tlb_sizeof; ! 145: ! 146: /* get information about this guest's recode TLB entries: */ ! 147: #define _TME_RECODE_TLB_INFO_Cn_Am_KEY(csize, asize) (((csize) * (TME_RECODE_SIZE_GUEST_MAX + 1)) + (asize)) ! 148: #define _TME_RECODE_TLB_INFO_C0_Am_KEY(asize) _TME_RECODE_TLB_INFO_Cn_Am_KEY(TME_RECODE_SIZE_GUEST_MAX + 1, asize) ! 149: switch (address_type->tme_recode_address_type_context_ic_offset < 0 ! 150: ? _TME_RECODE_TLB_INFO_C0_Am_KEY(ic->tme_recode_ic_reg_size) ! 151: : _TME_RECODE_TLB_INFO_Cn_Am_KEY(address_type->tme_recode_address_type_context_size, ! 152: ic->tme_recode_ic_reg_size)) { ! 153: default: abort(); ! 154: #define _TME_RECODE_TLB_INFO_OFFSETOF(csize,asize,field) \ ! 155: (((tme_uint8_t *) \ ! 156: &(((struct _TME_CONCAT4(tme_recode_tlb_c,csize,_a,asize) *) 0) \ ! 157: ->_TME_CONCAT5(tme_recode_tlb_c,csize,_a,asize,field))) \ ! 158: - (tme_uint8_t *) 0) ! 159: #define _TME_RECODE_TLB_INFO(csize,asize) \ ! 160: do { \ ! 161: tlb_offset_memory = _TME_RECODE_TLB_INFO_OFFSETOF(csize,asize,_memory); \ ! 162: tlb_offset_page = _TME_RECODE_TLB_INFO_OFFSETOF(csize,asize,_page); \ ! 163: tlb_offset_flags = _TME_RECODE_TLB_INFO_OFFSETOF(csize,asize,_flags); \ ! 164: tlb_offset_token = _TME_RECODE_TLB_INFO_OFFSETOF(csize,asize,_token); \ ! 165: tlb_sizeof = sizeof(struct _TME_CONCAT4(tme_recode_tlb_c,csize,_a,asize)); \ ! 166: } while (/* CONSTCOND */ 0) ! 167: #define _TME_RECODE_TLB_INFO_Cn_Am(csize,asize) \ ! 168: do { \ ! 169: _TME_RECODE_TLB_INFO(csize,asize); \ ! 170: tlb_offset_context = _TME_RECODE_TLB_INFO_OFFSETOF(csize,asize,_context); \ ! 171: } while (/* CONSTCOND */ 0) ! 172: #define _TME_RECODE_TLB_INFO_Am(asize) \ ! 173: do { \ ! 174: _TME_RECODE_TLB_INFO(0,asize); \ ! 175: tlb_offset_context = 0; \ ! 176: } while (/* CONSTCOND */ 0) ! 177: ! 178: #ifdef TME_RECODE_SIZE_128 ! 179: #if TME_RECODE_SIZE_GUEST_MAX >= TME_RECODE_SIZE_128 ! 180: case _TME_RECODE_TLB_INFO_Cn_Am_KEY(TME_RECODE_SIZE_16, TME_RECODE_SIZE_128): ! 181: _TME_RECODE_TLB_INFO_Cn_Am(16,128); ! 182: break; ! 183: #endif /* TME_RECODE_SIZE_GUEST_MAX >= TME_RECODE_SIZE_128 */ ! 184: #endif /* TME_RECODE_SIZE_128 */ ! 185: #ifdef TME_RECODE_SIZE_64 ! 186: #if TME_RECODE_SIZE_GUEST_MAX >= TME_RECODE_SIZE_64 ! 187: case _TME_RECODE_TLB_INFO_Cn_Am_KEY(TME_RECODE_SIZE_16, TME_RECODE_SIZE_64): ! 188: _TME_RECODE_TLB_INFO_Cn_Am(16,64); ! 189: break; ! 190: #endif /* TME_RECODE_SIZE_GUEST_MAX >= TME_RECODE_SIZE_64 */ ! 191: #endif /* TME_RECODE_SIZE_64 */ ! 192: case _TME_RECODE_TLB_INFO_Cn_Am_KEY(TME_RECODE_SIZE_16, TME_RECODE_SIZE_32): ! 193: _TME_RECODE_TLB_INFO_Cn_Am(16,32); ! 194: break; ! 195: } ! 196: ! 197: /* return the information: */ ! 198: tlb_type->tme_recode_tlb_type_offset_memory = tlb_offset_memory; ! 199: tlb_type->tme_recode_tlb_type_offset_page = tlb_offset_page; ! 200: tlb_type->tme_recode_tlb_type_offset_flags = tlb_offset_flags; ! 201: tlb_type->tme_recode_tlb_type_offset_token = tlb_offset_token; ! 202: tlb_type->tme_recode_tlb_type_offset_context = tlb_offset_context; ! 203: tlb_type->tme_recode_tlb_type_sizeof = tlb_sizeof; ! 204: } ! 205: ! 206: #endif /* TME_HAVE_RECODE */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.