Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marsupilami draft #2

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions generate_parsetabs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# © 2021-2022 Intel Corporation
# SPDX-License-Identifier: MPL-2.0

# Hubba hubba zut zut

import os
import sys

Expand Down
48 changes: 27 additions & 21 deletions include/simics/dmllib.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,23 @@ DML_eq(uint64 a, uint64 b)
({_traitref_t __tref = traitref; \
((struct _ ## type *) __tref.trait)->method(dev, __tref);}) \

// A parameter is represented in the vtable using a pointer that points to the
// parameter value. A parameter whose value varies across indices is stored as
// an array of all values, indexed by encoded_index. This is marked by setting
// bit 0 of the vtable's pointer to 1. A parameter that stays constant across
// indices is represented as a single value, this is marked by setting bit 0 of
// the pointer to 0. Parameter values are always stored with an alignment of at
// least 2.
#define VTABLE_PARAM(traitref, vtable_type, member) \
({_traitref_t __tref = traitref; \
uintptr_t __member \
= (uintptr_t)((vtable_type *)__tref.trait)->member; \
(__member & 1) \
? ((typeof(((vtable_type*)NULL)->member))(__member - 1))[ \
__tref.id.encoded_index] \
: *(typeof(((vtable_type*)NULL)->member))__member; })


#define _raw_load_uint8_be_t UNALIGNED_LOAD_BE8
#define _raw_load_uint16_be_t UNALIGNED_LOAD_BE16
#define _raw_load_uint32_be_t UNALIGNED_LOAD_BE32
Expand Down Expand Up @@ -601,14 +618,10 @@ _identity_eq(const _identity_t a, const _identity_t b) {

// List of vtables of a specific trait in one specific object
typedef struct {
// first trait vtable instance. Instances are stored linearly in a
// possibly multi-dimensional array, with outer index corresponding to
// index of outer DML object.
uintptr_t base;
// trait vtable instance
void *vtable;
// total number of elements (product of object's dimsizes)
uint64 num;
// offset between two vtable instances; at least sizeof(<vtable type>)
uint32 offset;
// The unique object id
uint32 id;
} _vtable_list_t;
Expand Down Expand Up @@ -807,20 +820,18 @@ typedef struct {
get_attr_t get;
set_attr_t set;
uint32 array_size;
uint32 array_delta;
} _port_array_attr_t;
static attr_value_t
_getattr_from_portobj_array(lang_void *ptr, conf_object_t *obj,
attr_value_t *idx)
{
ASSERT(SIM_attr_is_nil(*idx));
_port_array_attr_t *port = (_port_array_attr_t *)ptr;
uintptr_t port_obj_ptr_base = (uintptr_t)obj
+ port->port_obj_base_offset;
conf_object_t **port_obj_ptr_base = (conf_object_t **)(
(uintptr_t)obj + port->port_obj_base_offset);
attr_value_t vals = SIM_alloc_attr_list(port->array_size);
for (uint32 i = 0; i < port->array_size; i++) {
conf_object_t *port_obj = *(conf_object_t **)(
port_obj_ptr_base + (uint64)i * port->array_delta);
conf_object_t *port_obj = port_obj_ptr_base[i];
attr_value_t val = port->get(NULL, port_obj, NULL);
if (SIM_attr_is_invalid(val)) {
SIM_attr_free(&vals);
Expand All @@ -836,11 +847,10 @@ _setattr_from_portobj_array(lang_void *ptr, conf_object_t *obj,
{
ASSERT(SIM_attr_is_nil(*idx));
_port_array_attr_t *port = (_port_array_attr_t *)ptr;
uintptr_t port_obj_ptr_base = (uintptr_t)obj
+ port->port_obj_base_offset;
conf_object_t **port_obj_ptr_base = (conf_object_t **)(
(uintptr_t)obj + port->port_obj_base_offset);
for (uint32 i = 0; i < port->array_size; i++) {
conf_object_t *port_obj = *(conf_object_t **)(
port_obj_ptr_base + (uint64)i * port->array_delta);
conf_object_t *port_obj = port_obj_ptr_base[i];
attr_value_t val = SIM_attr_list_item(*vals, i);
set_error_t err = port->set(NULL, port_obj, &val, NULL);
if (err != Sim_Set_Ok) {
Expand All @@ -850,11 +860,10 @@ _setattr_from_portobj_array(lang_void *ptr, conf_object_t *obj,
return Sim_Set_Ok;
}
// port_obj_offset is the offset within the device struct of the first pointer
// to a port object. Pointers to remaining port object in the array are located
// array_delta bytes apart.
// to a port object. Remaining port objects are stored consecutively in memory.
UNUSED static void
_register_port_array_attr(conf_class_t *devcls, conf_class_t *portcls,
ptrdiff_t port_obj_offset, ptrdiff_t array_delta,
ptrdiff_t port_obj_offset,
uint32 array_size, bool is_bank,
const char *portname, const char *attrname,
get_attr_t getter, set_attr_t setter,
Expand All @@ -867,9 +876,6 @@ _register_port_array_attr(conf_class_t *devcls, conf_class_t *portcls,
data->get = getter;
data->set = setter;
data->array_size = array_size;
data->array_delta = array_delta;
// storing ptrdiff in uint32, overflow will not happen in practise
ASSERT(data->array_delta == array_delta);
char name[strlen(portname) + strlen(attrname) + 2];
sprintf(name, "%s_%s", portname, attrname);
strbuf_t proxy_desc = sb_newf("Proxy attribute for %s.%s[].%s",
Expand Down
Loading