Skip to content

Commit 18d8bc6

Browse files
committed
Gate SIM_register_typed_attribute behind a compat feature
1 parent 4b0022e commit 18d8bc6

File tree

10 files changed

+166
-7
lines changed

10 files changed

+166
-7
lines changed

RELEASENOTES.docu

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1776,4 +1776,12 @@ extern typedef struct { } my_type_t;</pre> </add-note></build-id>
17761776
the <tt>dead_dml_methods</tt> library, which caused it to never
17771777
detect methods as dead if they occur directly after
17781778
a <tt>footer</tt> block.</add-note></build-id>
1779+
<build-id _6="next" _7="next"><add-note>DMLC's use of the legacy Simics API
1780+
for attribute registration is now controlled by the compatibility feature
1781+
<tt>legacy_attributes</tt>. This feature can be disabled by passing
1782+
<tt>--no-compat=legacy_attributes</tt> to DMLC, in which case the modern
1783+
API will be used instead, which does not support the use of dictionary
1784+
attribute values <bug number="SIMICS-22406"/>.
1785+
<tt>legacy_attributes</tt> will always be disabled with Simics API version
1786+
8 or above.</add-note></build-id>
17791787
</rn>

include/simics/dmllib.h

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
#ifndef SIMICS_DMLLIB_H
99
#define SIMICS_DMLLIB_H
1010

11+
#ifndef DML_LEGACY_ATTRS
12+
#define DML_LEGACY_ATTRS 0
13+
#endif
14+
1115
#include <stddef.h>
1216

1317
#include <simics/base/event.h>
@@ -1819,6 +1823,53 @@ typedef attr_value_t (*_get_attr_t)(conf_object_t *, lang_void *);
18191823
typedef set_error_t (*_set_attr_t)(conf_object_t *, attr_value_t *,
18201824
lang_void *);
18211825

1826+
#if DML_LEGACY_ATTRS
1827+
typedef struct {
1828+
_get_attr_t get_attr;
1829+
_set_attr_t set_attr;
1830+
lang_void *user_data_get;
1831+
lang_void *user_data_set;
1832+
} _dml_legacy_attr_info_t;
1833+
1834+
UNUSED static attr_value_t
1835+
_DML_legacy_attr_get_trampoline(lang_void *_info, conf_object_t *obj,
1836+
attr_value_t *_idx) {
1837+
const _dml_legacy_attr_info_t *info = (_dml_legacy_attr_info_t *)_info;
1838+
return info->get_attr(obj, info->user_data_get);
1839+
}
1840+
1841+
UNUSED static set_error_t
1842+
_DML_legacy_attr_set_trampoline(lang_void *_info, conf_object_t *obj,
1843+
attr_value_t *out, attr_value_t *_idx) {
1844+
const _dml_legacy_attr_info_t *info = (_dml_legacy_attr_info_t *)_info;
1845+
return info->set_attr(obj, out, info->user_data_set);
1846+
}
1847+
1848+
UNUSED static void
1849+
_DML_register_attribute(
1850+
conf_class_t *NOTNULL cls, const char *NOTNULL name,
1851+
_get_attr_t get_attr, lang_void *user_data_get,
1852+
_set_attr_t set_attr, lang_void *user_data_set,
1853+
attr_attr_t attr, const char *type, const char *desc) {
1854+
_dml_legacy_attr_info_t *info = MM_MALLOC(1, _dml_legacy_attr_info_t);
1855+
info->get_attr = get_attr;
1856+
info->set_attr = set_attr;
1857+
info->user_data_get = user_data_get;
1858+
info->user_data_set = user_data_set;
1859+
1860+
SIM_register_typed_attribute(cls, name,
1861+
get_attr ? _DML_legacy_attr_get_trampoline
1862+
: NULL,
1863+
get_attr ? (lang_void *)info : NULL,
1864+
set_attr ? _DML_legacy_attr_set_trampoline
1865+
: NULL,
1866+
set_attr ? (lang_void *)info : NULL,
1867+
attr, type, NULL, desc);
1868+
}
1869+
#else
1870+
#define _DML_register_attribute SIM_register_attribute_with_user_data
1871+
#endif
1872+
18221873
UNUSED static void
18231874
_DML_register_hook_attribute(conf_class_t *cls, const char *attrname,
18241875
_get_attr_t getter, _set_attr_t setter,
@@ -1984,9 +2035,8 @@ _register_port_attr_no_aux(conf_class_t *portcls, const char *attrname,
19842035
attr_attr_t attr, const char *type,
19852036
const char *desc)
19862037
{
1987-
SIM_register_attribute_with_user_data(
1988-
portcls, attrname, getter, NULL, setter, NULL,
1989-
attr, type, desc);
2038+
_DML_register_attribute(portcls, attrname, getter, NULL, setter, NULL,
2039+
attr, type, desc);
19902040
}
19912041

19922042
// port_obj_offset is the offset within the device struct of a pointer to the
@@ -2015,7 +2065,8 @@ _register_port_legacy_proxy_attr(conf_class_t *devcls, conf_class_t *portcls,
20152065
strbuf_t proxy_desc = sb_newf(
20162066
"Proxy attribute for %s.%s.%s",
20172067
is_bank ? "bank" : "port", portname, attrname);
2018-
SIM_register_attribute_with_user_data(
2068+
2069+
_DML_register_attribute(
20192070
devcls, name,
20202071
getter ? _get_legacy_proxy_attr : NULL, data,
20212072
setter ? _set_legacy_proxy_attr : NULL, data,
@@ -2116,7 +2167,7 @@ _register_port_array_legacy_proxy_attr(
21162167
is_bank ? "bank" : "port",
21172168
portname, attrname);
21182169
strbuf_t proxy_type = sb_newf("[%s{%d}]", type, array_size);
2119-
SIM_register_attribute_with_user_data(
2170+
_DML_register_attribute(
21202171
devcls, name,
21212172
getter ? _get_legacy_proxy_array_attr : NULL, data,
21222173
setter ? _set_legacy_proxy_array_attr : NULL, data,
@@ -3414,7 +3465,7 @@ UNUSED static void _DML_register_attributes(
34143465
MM_FREE(tmp_type);
34153466
}
34163467
conf_class_t *parent_obj_class = attr_info.parent_obj_class;
3417-
SIM_register_attribute_with_user_data(
3468+
_DML_register_attribute(
34183469
parent_obj_class ? parent_obj_class : dev_class,
34193470
attr_info.name,
34203471
attr_info.readable ? parent_obj_class ? get_portobj_attr : get_attr

lib/1.2/dml-builtins.dml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ template device {
215215
parameter _compat_io_memory auto;
216216
parameter _compat_shared_logs_on_device auto;
217217
parameter _compat_suppress_WLOGMIXUP auto;
218+
parameter _compat_legacy_attributes auto;
218219
parameter _compat_dml12_inline auto;
219220
parameter _compat_dml12_not auto;
220221
parameter _compat_dml12_goto auto;

lib/1.4/dml-builtins.dml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ template device {
561561
param _compat_io_memory auto;
562562
param _compat_shared_logs_on_device auto;
563563
param _compat_suppress_WLOGMIXUP auto;
564+
param _compat_legacy_attributes auto;
564565
param _compat_dml12_inline auto;
565566
param _compat_dml12_not auto;
566567
param _compat_dml12_goto auto;

py/dml/c_backend.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ def generate_hfile(device, headers, filename):
260260
out("/* Generated by dmlc, do not edit! */\n\n")
261261
emit_guard_start(filename)
262262
out('#define DML_PREFIX(x) '+crep.cname(device)+'_##x\n\n')
263+
legacy_attrs = int(compat.legacy_attributes in dml.globals.enabled_compat)
264+
out(f'#define DML_LEGACY_ATTRS {legacy_attrs}\n')
263265

264266
with allow_linemarks():
265267
for c in headers:
@@ -624,7 +626,7 @@ def generate_attribute_common(initcode, node, port, dimsizes, prefix,
624626
attr_flag, attr_type, doc.read()))
625627
else:
626628
initcode.out(
627-
f'SIM_register_attribute_with_user_data(class, "{attrname}", '
629+
f'_DML_register_attribute(class, "{attrname}", '
628630
+ f'{getter}, NULL, {setter}, NULL, {attr_flag}, "{attr_type}", '
629631
+ f'{doc.read()});\n')
630632

py/dml/compat.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,23 @@ class suppress_WLOGMIXUP(CompatFeature):
198198
short = "Suppress the warning 'WLOGMIXUP' by default"
199199
last_api_version = api_6
200200

201+
@feature
202+
class legacy_attributes(CompatFeature):
203+
'''This compatibility feature makes DMLC register all attributes using the
204+
legacy `SIM_register_typed_attribute` API function instead of the modern
205+
`SIM_register_attribute` family of API functions.
206+
207+
Disabling this feature will make the dictionary attribute type ("D" in type
208+
strings) to become unsupported, and any usage of it rejected by Simics.
209+
Thus, when migrating away from this feature, any attribute of the model
210+
that leverages dictionary values should be changed to leverage a different
211+
representation. In general, any dictionary can instead be represented by a
212+
list of two-element lists, e.g. <code>[[<em>X</em>,<em>Y</em>]*]</code>,
213+
where _X_ describes the type of keys, and _Y_ describes the type of
214+
values.'''
215+
short = ("Use legacy attribute registration, which supports use of the "
216+
+ "dictionary type ('D')")
217+
last_api_version = api_7
201218

202219
@feature
203220
class dml12_inline(CompatFeature):
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
© 2024 Intel Corporation
3+
SPDX-License-Identifier: MPL-2.0
4+
*/
5+
dml 1.4;
6+
device test;
7+
8+
// NOTE: this test relies on proxy attributes
9+
/// DMLC-FLAG --simics-api=7
10+
/// DMLC-FLAG --no-compat=legacy_attributes
11+
12+
import "legacy_attributes.dml";
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
© 2024 Intel Corporation
3+
SPDX-License-Identifier: MPL-2.0
4+
*/
5+
dml 1.4;
6+
device test;
7+
8+
/// DMLC-FLAG --simics-api=7
9+
10+
import "legacy_attributes.dml";
11+
12+
attribute dict_attr is read_only_attr "some dict attr" {
13+
param type = "D";
14+
method get() -> (attr_value_t) {
15+
return SIM_alloc_attr_dict(0);
16+
}
17+
}
18+
19+
method init() {
20+
default();
21+
assert SIM_attr_is_dict((SIM_get_attribute(dev.obj, "dict_attr")));
22+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
© 2024 Intel Corporation
3+
SPDX-License-Identifier: MPL-2.0
4+
*/
5+
dml 1.4;
6+
7+
import "simics/simulator/conf-object.dml";
8+
9+
saved int s;
10+
hook() h;
11+
12+
attribute a is uint64_attr;
13+
14+
bank b {
15+
saved int s;
16+
hook() h;
17+
attribute a is uint64_attr;
18+
}
19+
20+
method init() default {
21+
local attr_value_t val = SIM_make_attr_uint64(0xC0FFEE);
22+
#foreach r in ([dev, b]) {
23+
local conf_class_t *cls = SIM_object_class(r.obj);
24+
assert (SIM_get_attribute_attributes(cls, "s") & Sim_Attr_Legacy)
25+
== 0;
26+
assert (SIM_get_attribute_attributes(cls, "h") & Sim_Attr_Legacy)
27+
== 0;
28+
29+
assert ((SIM_get_attribute_attributes(cls, "a") & Sim_Attr_Legacy)
30+
!= 0) == _compat_legacy_attributes;
31+
32+
SIM_set_attribute(r.obj, "a", &val);
33+
assert SIM_attr_integer(SIM_get_attribute(r.obj, "a"))
34+
== 0xC0FFEE;
35+
}
36+
assert ((SIM_get_attribute_attributes(SIM_object_class(dev.obj), "b_a")
37+
& Sim_Attr_Legacy) != 0) == _compat_legacy_attributes;
38+
39+
val = SIM_make_attr_uint64(0xDEADBEEF);
40+
SIM_set_attribute(dev.obj, "b_a", &val);
41+
assert SIM_attr_integer(SIM_get_attribute(dev.obj, "b_a")) == 0xDEADBEEF;
42+
assert SIM_attr_integer(SIM_get_attribute(b.obj, "a")) == 0xDEADBEEF;
43+
}

test/1.4/structure/T_portobj.dml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ dml 1.4;
66

77
device test;
88

9+
/// DMLC-FLAG --no-compat=legacy_attributes
10+
911
import "simics/simulator/conf-object.dml";
1012

1113
bank b[i<2] {

0 commit comments

Comments
 (0)