4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
33 #include <fcode/private.h>
34 #include <fcode/log.h>
36 #include <fcdriver/fcdriver.h>
40 #define MAP_IS_VALID 0x01
48 } map_table
[MAX_MAPS
];
51 * Originally, this code translated kernel supplied virtual addresses into
52 * "memory cookies", which was a 32-bit number with ascii-M in the upper 8
53 * bits, a 4-bit index and a 20-bit offset. However, this caused two
54 * problems: 1) the 20-bit offset was too small for some devices, esp. some
55 * with frame-buffers; 2) if the fcode used the cookie to program the
56 * hardware, there was no easy way for the software to detect that a
57 * translation needed to be done.
59 * For that reason, "memory cookies" are now just the kernel-supplied
60 * virtual address, and we now check each memory access to see if it's
61 * attempting to access kernel-supplied memory. The only important thing
62 * now is that "is_mcookie" returns 1 (or true) if the tested mcookie
63 * is a kernel virtual address.
65 * There is a potential bug if the kernel virtual address happens to
66 * conflict with a user virtual address. However, the current implementation
67 * of Solaris avoids this conflict.
71 mapping_to_mcookie(uint64_t req_add
, size_t req_size
, uint64_t adj_virt
,
77 for (i
= 0, mp
= map_table
; i
< MAX_MAPS
; i
++, mp
++)
78 if ((mp
->map_flags
& MAP_IS_VALID
) == 0)
81 log_message(MSG_WARN
, "Warning: too many mappings\n");
84 debug_msg(DEBUG_REG_ACCESS
, "Allocating mapping: %d add: 0x%llx"
85 " size: 0x%x\n", i
, req_add
, req_size
);
86 mp
->map_flags
|= MAP_IS_VALID
;
87 mp
->map_add
= req_add
;
88 mp
->map_size
= req_size
;
89 mp
->adj_virt
= adj_virt
;
90 mp
->adj_length
= adj_length
;
91 if (mp
->adj_length
!= 0)
98 delete_mapping(fstack_t mcookie
)
101 struct map_table
*mp
;
103 for (i
= 0, mp
= map_table
; i
< MAX_MAPS
; i
++, mp
++) {
104 if ((mp
->map_flags
& MAP_IS_VALID
) &&
105 mcookie
>= mp
->map_add
&&
106 mcookie
< mp
->map_add
+ mp
->map_size
) {
107 debug_msg(DEBUG_REG_ACCESS
, "Deallocating mapping: %d"
108 " add: 0x%llx size: 0x%x\n", i
, mp
->map_add
,
110 mp
->map_flags
&= ~MAP_IS_VALID
;
118 log_message(MSG_WARN
, "Warning: delete_mapping: invalid"
119 " mcookie: %llx\n", (uint64_t)mcookie
);
123 is_mcookie(fstack_t mcookie
)
125 struct map_table
*mp
;
128 for (i
= 0, mp
= map_table
; i
< MAX_MAPS
; i
++, mp
++)
129 if ((mp
->map_flags
& MAP_IS_VALID
) &&
130 mcookie
>= mp
->map_add
&&
131 mcookie
< mp
->map_add
+ mp
->map_size
)
137 mcookie_to_addr(fstack_t mcookie
)
143 mcookie_to_rlen(fstack_t mcookie
)
146 struct map_table
*mp
;
148 for (i
= 0, mp
= map_table
; i
< MAX_MAPS
; i
++, mp
++) {
149 if ((mp
->map_flags
& MAP_IS_VALID
) &&
150 mcookie
>= mp
->map_add
&&
151 mcookie
< mp
->map_add
+ mp
->map_size
) {
152 return (mp
->map_size
);
155 log_message(MSG_WARN
, "Warning: mcookie_to_rlen: invalid"
156 " mcookie: %llx\n", (uint64_t)mcookie
);
162 mcookie_to_rvirt(fstack_t mcookie
)
165 struct map_table
*mp
;
167 for (i
= 0, mp
= map_table
; i
< MAX_MAPS
; i
++, mp
++) {
168 if ((mp
->map_flags
& MAP_IS_VALID
) &&
169 mcookie
>= mp
->map_add
&&
170 mcookie
< mp
->map_add
+ mp
->map_size
) {
171 return (mp
->map_add
);
174 log_message(MSG_WARN
, "Warning: mcookie_to_rvirt: invalid"
175 " mcookie: %llx\n", (uint64_t)mcookie
);
181 dot_maps(fcode_env_t
*env
)
185 log_message(MSG_DEBUG
, "idx base-addr size\n");
186 for (i
= 0; i
< MAX_MAPS
; i
++) {
187 if (map_table
[i
].map_flags
& MAP_IS_VALID
)
188 log_message(MSG_DEBUG
, "%3d %016llx %8x\n", i
,
189 map_table
[i
].map_add
, map_table
[i
].map_size
);
194 map_qmark(fcode_env_t
*env
)
196 fstack_t d
= POP(DS
);
199 log_message(MSG_INFO
, "%llx: not mcookie\n", (uint64_t)d
);
201 log_message(MSG_INFO
, "%llx -> %llx\n", (uint64_t)d
,
206 add_map(fcode_env_t
*env
)
212 addr
= mapping_to_mcookie(addr
, size
, NULL
, NULL
);
217 del_map(fcode_env_t
*env
)
222 delete_mapping(addr
);
231 fcode_env_t
*env
= initial_env
;
236 FORTH(0, ".maps", dot_maps
);
237 FORTH(0, "map?", map_qmark
);
238 FORTH(0, "add-map", add_map
);
239 FORTH(0, "del-map", del_map
);