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