* ========== Copyright Header Begin ==========================================
* Hypervisor Software File: mdsup.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* - Do no alter or remove copyright notices
* - Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of Sun Microsystems, Inc. or the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or maintenance of
* ========== Copyright Header End ============================================
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)mdsup.c 1.14 07/07/18 SMI"
* Support functions for MD scanning
(((uint64_t)&config.hdnametable.hdname_##_name) - \
((uint64_t)&config.hdnametable)), #_name \
#define HDN_X(_names, _offsetx) { \
(((uint64_t)&config.hdnametable.hdname_##_offsetx) - \
((uint64_t)&config.hdnametable)), \
#ifdef CONFIG_SPLIT_SRAM /* { */
#ifdef CONFIG_PCIE /* { */
#ifdef STANDALONE_NET_DEVICES
HDN_X("virtualdevices", vdevs
),
HDN_X("partid", parttag
),
HDN_X("tod-frequency", todfrequency
),
HDN_X("tod-offset", todoffset
),
HDN_X("stick-frequency", stickfrequency
),
HDN_X("ce-blackout-sec", ceblackoutsec
),
HDN_X("ce-poll-sec", cepollsec
),
HDN_X("erpt-pa", erpt_pa
),
HDN_X("erpt-size", erpt_size
),
HDN_X("reset-reason", reset_reason
),
HDN_X("content-version", content_version
),
#ifdef PLX_ERRATUM_LINK_HACK
HDN_X("ignore-plx-link-hack", ignore_plx_link_hack
),
/* -KPIC doesnt relocate preinitialized structure pointers */
namereloc
= (-config
.reloc
);
for (i
= 0; inittable
[i
].strp
!= NULL
; i
++) {
inittable
[i
].strp
+= namereloc
;
preparse_hvmd(bin_md_t
*mdp
)
config
.parse_hvmd
= mdp
; /* stash it */
if (TR_MAJOR(ntoh32(mdp
->hdr
.transport_version
)) !=
TR_MAJOR(MD_TRANSPORT_VERSION
)) {
DBG(c_printf("Hypervisor MD major version mismatch\n"));
basep
= (uint64_t)&config
.hdnametable
;
for (i
= 0; inittable
[i
].strp
!= NULL
; i
++) {
tag
= md_find_name_tag(mdp
, inittable
[i
].strp
);
*((uint64_t *)(basep
+ inittable
[i
].offset
)) = tag
;
* The HVMD update process is effectively double buffered we check the
* new one first, if there are any problems we fail it without making the
* configuration change which means we can roll back to the currently active
* HVMD on a (re)config failure and it is as if nothing ever happened.
config
.active_hvmd
= config
.parse_hvmd
;
* Primitive scan to look for a matching string.
* If not found, then we return -1
md_find_name_tag(bin_md_t
*mdp
, char *namep
)
/* Find the address of the string table */
str_tablep
= (char *)(((uint64_t)&(mdp
->elem
[0])) +
ntoh32(mdp
->hdr
.node_blk_sz
));
size
= ntoh32(mdp
->hdr
.name_blk_sz
);
* Dumb linear scan looking for the string in the
for (start_idx
= 0; start_idx
< size
; ) {
str_basep
= str_tablep
+ start_idx
;
/* Brute force match current and test string */
if (ch1
!= ch2
) goto miss
;
return ((((uint64_t)i
)<<48) |
while (str_basep
[i
] != '\0') i
++;
start_idx
+= i
+1; /* start of next string */
md_find_node(bin_md_t
*mdp
, md_element_t
*startp
, uint64_t token
)
int namelen
= (token
>>48) & 0xff;
int nameoff
= (token
& 0xffffffff);
size
= mdp
->hdr
.node_blk_sz
/ MD_ELEMENT_SIZE
;
elemp
= (startp
== NULL
) ? &(mdp
->elem
[0]) : startp
;
limp
= &(mdp
->elem
[size
]);
case MDET_LIST_END
: goto done
;
if (ntoh32(elemp
->name
) == nameoff
&&
ntoh8(elemp
->namelen
) == namelen
) {
idx
= ntoh32(elemp
->d
.prop_idx
); /* next node */
elemp
= &(mdp
->elem
[idx
]);
elemp
++; /* skip to next element */
"Encountered elem type 0x%x in node search\n",
} while (elemp
>= mdp
->elem
&& elemp
< limp
);
* From a given element in a node, look for and follow an arc of the
* given token, check if the arc points to a node of the given
* token ... return both the arc pointer and the node pointed to if
* there is a match ... else return null.
md_find_node_by_arc(bin_md_t
*mdp
, md_element_t
*elemp
,
uint64_t arc_token
, uint64_t node_token
, md_element_t
**nodep
)
elemp
= md_next_node_elem(mdp
, elemp
, arc_token
);
mdep
= &mdp
->elem
[ntoh64(elemp
->d
.prop_idx
)];
md_node_get_val(bin_md_t
*mdp
, md_element_t
*nodep
,
uint64_t name_token
, uint64_t *valp
)
token
= MDVAL(name_token
);
elemp
= md_next_node_elem(mdp
, nodep
, token
);
*valp
= ntoh64(elemp
->d
.prop_val
);
md_next_node_elem(bin_md_t
*mdp
, md_element_t
*mdep
, uint64_t token
)
while (mdep
->tag
!= MDET_LIST_END
&& mdep
->tag
!= MDET_NODE_END
) {
md_dump_node(bin_md_t
*mdp
, md_element_t
*mdep
)
strp
= (char *)&(mdp
->elem
[0]);
strp
+= mdp
->hdr
.node_blk_sz
;
datap
= (uint8_t *)(strp
+ mdp
->hdr
.name_blk_sz
);
c_printf("node %s node_0x%x {\n",
c_printf("}\nENDOFMD\n");
c_printf("\t%s -> node_0x%x ;\n",
c_printf("\t%s = 0x%x ;\n",
c_printf("\t%s = 0x%x ;\n",
datap
+ mdep
->d
.prop_data
.offset
);
c_printf("\t%s = { ... } /* len = 0x%x */ ;\n",
datap
+ mdep
->d
.prop_data
.len
);
c_printf("\tillegal MD tag 0x%x at elem index 0x%x\n",