|
|
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.