1/* $OpenBSD: vcc.c,v 1.2 2021/10/24 17:05:04 mpi Exp $ */ 2/* 3 * Copyright (c) 2009 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#include <sys/param.h> 19#include <sys/buf.h> 20#include <sys/device.h> 21#include <sys/malloc.h> 22#include <sys/systm.h> 23 24#include <machine/autoconf.h> 25#include <machine/hypervisor.h> 26#include <machine/mdesc.h> 27 28#include <sparc64/dev/cbusvar.h> 29 30#ifdef VCC_DEBUG 31#define DPRINTF(x) printf x 32#else 33#define DPRINTF(x) 34#endif 35 36struct vcc_softc { 37 struct device sc_dv; 38 bus_space_tag_t sc_bustag; 39 bus_dma_tag_t sc_dmatag; 40}; 41 42int vcc_match(struct device *, void *, void *); 43void vcc_attach(struct device *, struct device *, void *); 44 45const struct cfattach vcc_ca = { 46 sizeof(struct vcc_softc), vcc_match, vcc_attach 47}; 48 49struct cfdriver vcc_cd = { 50 NULL, "vcc", DV_DULL 51}; 52 53void vcc_get_channel_endpoint(int, struct cbus_attach_args *); 54 55int 56vcc_match(struct device *parent, void *match, void *aux) 57{ 58 struct cbus_attach_args *ca = aux; 59 60 if (strcmp(ca->ca_name, "virtual-console-concentrator") == 0) 61 return (1); 62 63 return (0); 64} 65 66void 67vcc_attach(struct device *parent, struct device *self, void *aux) 68{ 69 struct cbus_attach_args *ca = aux; 70 struct cbus_attach_args nca; 71 struct md_header *hdr; 72 struct md_element *elem; 73 const char *name_blk; 74 const char *str; 75 int idx; 76 int arc; 77 78 printf("\n"); 79 80 hdr = (struct md_header *)mdesc; 81 elem = (struct md_element *)(mdesc + sizeof(struct md_header)); 82 name_blk = mdesc + sizeof(struct md_header) + hdr->node_blk_sz; 83 84 idx = ca->ca_idx; 85 for (; elem[idx].tag != 'E'; idx++) { 86 str = name_blk + elem[idx].name_offset; 87 if (elem[idx].tag != 'a' || strcmp(str, "fwd") != 0) 88 continue; 89 90 arc = elem[idx].d.val; 91 str = name_blk + elem[arc].name_offset; 92 if (strcmp(str, "virtual-device-port") == 0) { 93 str = mdesc_get_prop_str(arc, "vcc-domain-name"); 94 if (str) { 95 bzero(&nca, sizeof(nca)); 96 nca.ca_name = str; 97 nca.ca_node = ca->ca_node; 98 nca.ca_bustag = ca->ca_bustag; 99 nca.ca_dmatag = ca->ca_dmatag; 100 vcc_get_channel_endpoint(arc, &nca); 101 config_found(self, &nca, cbus_print); 102 } 103 } 104 } 105} 106 107void 108vcc_get_channel_endpoint(int idx, struct cbus_attach_args *ca) 109{ 110 struct md_header *hdr; 111 struct md_element *elem; 112 const char *name_blk; 113 const char *str; 114 int arc; 115 116 hdr = (struct md_header *)mdesc; 117 elem = (struct md_element *)(mdesc + sizeof(struct md_header)); 118 name_blk = mdesc + sizeof(struct md_header) + hdr->node_blk_sz; 119 120 ca->ca_idx = idx; 121 122 ca->ca_id = -1; 123 ca->ca_tx_ino = -1; 124 ca->ca_rx_ino = -1; 125 126 for (; elem[idx].tag != 'E'; idx++) { 127 str = name_blk + elem[idx].name_offset; 128 if (elem[idx].tag != 'a' || strcmp(str, "fwd") != 0) 129 continue; 130 131 arc = elem[idx].d.val; 132 str = name_blk + elem[arc].name_offset; 133 if (strcmp(str, "channel-endpoint") == 0) { 134 ca->ca_id = mdesc_get_prop_val(arc, "id"); 135 ca->ca_tx_ino = mdesc_get_prop_val(arc, "tx-ino"); 136 ca->ca_rx_ino = mdesc_get_prop_val(arc, "rx-ino"); 137 return; 138 } 139 } 140} 141