Annotation of tme/libtme/recode-address.c, revision 1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.