1*3d066281SPatrick Mooney /*
2*3d066281SPatrick Mooney  * This file and its contents are supplied under the terms of the
3*3d066281SPatrick Mooney  * Common Development and Distribution License ("CDDL"), version 1.0.
4*3d066281SPatrick Mooney  * You may only use this file in accordance with the terms of version
5*3d066281SPatrick Mooney  * 1.0 of the CDDL.
6*3d066281SPatrick Mooney  *
7*3d066281SPatrick Mooney  * A full copy of the text of the CDDL should have accompanied this
8*3d066281SPatrick Mooney  * source.  A copy of the CDDL is also available via the Internet at
9*3d066281SPatrick Mooney  * http://www.illumos.org/license/CDDL.
10*3d066281SPatrick Mooney  */
11*3d066281SPatrick Mooney 
12*3d066281SPatrick Mooney /*
13*3d066281SPatrick Mooney  * Copyright 2022 Oxide Computer Company
14*3d066281SPatrick Mooney  */
15*3d066281SPatrick Mooney 
16*3d066281SPatrick Mooney 
17*3d066281SPatrick Mooney #include <stdio.h>
18*3d066281SPatrick Mooney #include <unistd.h>
19*3d066281SPatrick Mooney #include <stropts.h>
20*3d066281SPatrick Mooney #include <strings.h>
21*3d066281SPatrick Mooney #include <signal.h>
22*3d066281SPatrick Mooney #include <setjmp.h>
23*3d066281SPatrick Mooney #include <libgen.h>
24*3d066281SPatrick Mooney 
25*3d066281SPatrick Mooney #include <sys/vmm.h>
26*3d066281SPatrick Mooney #include <sys/vmm_dev.h>
27*3d066281SPatrick Mooney #include <sys/mman.h>
28*3d066281SPatrick Mooney #include <vmmapi.h>
29*3d066281SPatrick Mooney 
30*3d066281SPatrick Mooney #include "common.h"
31*3d066281SPatrick Mooney 
32*3d066281SPatrick Mooney enum test_segs {
33*3d066281SPatrick Mooney 	SEG_LOWMEM = 0,
34*3d066281SPatrick Mooney 	SEG_BOOTROM = 1,
35*3d066281SPatrick Mooney };
36*3d066281SPatrick Mooney #define	PAGE_CNT	2
37*3d066281SPatrick Mooney #define	PAGE_SZ		4096
38*3d066281SPatrick Mooney #define	SEG_SZ		(PAGE_CNT * PAGE_SZ)
39*3d066281SPatrick Mooney #define	WHOLE_SZ	(SEG_SZ * 2)
40*3d066281SPatrick Mooney 
41*3d066281SPatrick Mooney #define	TESTVAL_LOWMEM	0x1000ffff
42*3d066281SPatrick Mooney #define	TESTVAL_BOOTROM	0x2000eeee
43*3d066281SPatrick Mooney 
44*3d066281SPatrick Mooney int
main(int argc,char * argv[])45*3d066281SPatrick Mooney main(int argc, char *argv[])
46*3d066281SPatrick Mooney {
47*3d066281SPatrick Mooney 	struct vmctx *ctx;
48*3d066281SPatrick Mooney 	int res, fd;
49*3d066281SPatrick Mooney 	const char *suite_name = basename(argv[0]);
50*3d066281SPatrick Mooney 
51*3d066281SPatrick Mooney 	ctx = create_test_vm(suite_name);
52*3d066281SPatrick Mooney 	if (ctx == NULL) {
53*3d066281SPatrick Mooney 		perror("could open test VM");
54*3d066281SPatrick Mooney 		return (1);
55*3d066281SPatrick Mooney 	}
56*3d066281SPatrick Mooney 	fd = vm_get_device_fd(ctx);
57*3d066281SPatrick Mooney 
58*3d066281SPatrick Mooney 	res = alloc_memseg(ctx, SEG_LOWMEM, SEG_SZ, "");
59*3d066281SPatrick Mooney 	if (res != 0) {
60*3d066281SPatrick Mooney 		perror("could not alloc lowmem seg");
61*3d066281SPatrick Mooney 		goto bail;
62*3d066281SPatrick Mooney 	}
63*3d066281SPatrick Mooney 	res = alloc_memseg(ctx, SEG_BOOTROM, SEG_SZ, "bootrom");
64*3d066281SPatrick Mooney 	if (res != 0) {
65*3d066281SPatrick Mooney 		perror("could not alloc bootrom seg");
66*3d066281SPatrick Mooney 		goto bail;
67*3d066281SPatrick Mooney 	}
68*3d066281SPatrick Mooney 
69*3d066281SPatrick Mooney 	res = vm_mmap_memseg(ctx, 0, SEG_LOWMEM, 0, SEG_SZ, PROT_ALL);
70*3d066281SPatrick Mooney 	if (res != 0) {
71*3d066281SPatrick Mooney 		perror("could not map lowmem into vmspace");
72*3d066281SPatrick Mooney 		goto bail;
73*3d066281SPatrick Mooney 	}
74*3d066281SPatrick Mooney 	res = vm_mmap_memseg(ctx, SEG_SZ, SEG_BOOTROM, 0, SEG_SZ, PROT_READ);
75*3d066281SPatrick Mooney 	if (res != 0) {
76*3d066281SPatrick Mooney 		perror("could not map bootrom into vmspace");
77*3d066281SPatrick Mooney 		goto bail;
78*3d066281SPatrick Mooney 	}
79*3d066281SPatrick Mooney 
80*3d066281SPatrick Mooney 	void *guest_mem;
81*3d066281SPatrick Mooney 	guest_mem = mmap(NULL, WHOLE_SZ, PROT_READ, MAP_SHARED, fd, 0);
82*3d066281SPatrick Mooney 	if (guest_mem == MAP_FAILED) {
83*3d066281SPatrick Mooney 		perror("could not mmap guest-physical memory");
84*3d066281SPatrick Mooney 		goto bail;
85*3d066281SPatrick Mooney 	}
86*3d066281SPatrick Mooney 
87*3d066281SPatrick Mooney 	void *direct_lowmem, *direct_bootrom;
88*3d066281SPatrick Mooney 	off_t seg_obj_off;
89*3d066281SPatrick Mooney 
90*3d066281SPatrick Mooney 	res = vm_get_devmem_offset(ctx, SEG_LOWMEM, &seg_obj_off);
91*3d066281SPatrick Mooney 	if (res != 0) {
92*3d066281SPatrick Mooney 		perror("could not find mapping offset for lowmem seg");
93*3d066281SPatrick Mooney 		goto bail;
94*3d066281SPatrick Mooney 	}
95*3d066281SPatrick Mooney 	direct_lowmem = mmap(NULL, SEG_SZ, PROT_READ | PROT_WRITE, MAP_SHARED,
96*3d066281SPatrick Mooney 	    fd, seg_obj_off);
97*3d066281SPatrick Mooney 	if (direct_lowmem == MAP_FAILED) {
98*3d066281SPatrick Mooney 		perror("could not mmap lowmem directly");
99*3d066281SPatrick Mooney 		goto bail;
100*3d066281SPatrick Mooney 	}
101*3d066281SPatrick Mooney 
102*3d066281SPatrick Mooney 	res = vm_get_devmem_offset(ctx, SEG_BOOTROM, &seg_obj_off);
103*3d066281SPatrick Mooney 	if (res != 0) {
104*3d066281SPatrick Mooney 		perror("could not find mapping offset for lowmem seg");
105*3d066281SPatrick Mooney 		goto bail;
106*3d066281SPatrick Mooney 	}
107*3d066281SPatrick Mooney 	direct_bootrom = mmap(NULL, SEG_SZ, PROT_READ | PROT_WRITE, MAP_SHARED,
108*3d066281SPatrick Mooney 	    fd, seg_obj_off);
109*3d066281SPatrick Mooney 	if (direct_bootrom == MAP_FAILED) {
110*3d066281SPatrick Mooney 		perror("could not mmap bootrom directly");
111*3d066281SPatrick Mooney 		goto bail;
112*3d066281SPatrick Mooney 	}
113*3d066281SPatrick Mooney 
114*3d066281SPatrick Mooney 	uint32_t *datap;
115*3d066281SPatrick Mooney 
116*3d066281SPatrick Mooney 	datap = direct_lowmem;
117*3d066281SPatrick Mooney 	*datap = TESTVAL_LOWMEM;
118*3d066281SPatrick Mooney 	datap = direct_bootrom;
119*3d066281SPatrick Mooney 	*datap = TESTVAL_BOOTROM;
120*3d066281SPatrick Mooney 
121*3d066281SPatrick Mooney 	/* check that data written though direct access is as expected */
122*3d066281SPatrick Mooney 	datap = guest_mem;
123*3d066281SPatrick Mooney 	if (*datap != TESTVAL_LOWMEM) {
124*3d066281SPatrick Mooney 		(void) fprintf(stderr, "unexpected data in lowmem %x != %x\n",
125*3d066281SPatrick Mooney 		    *datap, TESTVAL_LOWMEM);
126*3d066281SPatrick Mooney 		goto bail;
127*3d066281SPatrick Mooney 	}
128*3d066281SPatrick Mooney 	datap = (guest_mem + SEG_SZ);
129*3d066281SPatrick Mooney 	if (*datap != TESTVAL_BOOTROM) {
130*3d066281SPatrick Mooney 		(void) fprintf(stderr, "unexpected data in bootrom %x != %x\n",
131*3d066281SPatrick Mooney 		    *datap, TESTVAL_BOOTROM);
132*3d066281SPatrick Mooney 		goto bail;
133*3d066281SPatrick Mooney 	}
134*3d066281SPatrick Mooney 
135*3d066281SPatrick Mooney 	/* unmap access mappings */
136*3d066281SPatrick Mooney 	res = munmap(guest_mem, WHOLE_SZ);
137*3d066281SPatrick Mooney 	if (res != 0) {
138*3d066281SPatrick Mooney 		perror("could not munmap vmspace");
139*3d066281SPatrick Mooney 		goto bail;
140*3d066281SPatrick Mooney 	}
141*3d066281SPatrick Mooney 	res = munmap(direct_lowmem, SEG_SZ);
142*3d066281SPatrick Mooney 	if (res != 0) {
143*3d066281SPatrick Mooney 		perror("could not munmap lowmem object");
144*3d066281SPatrick Mooney 		goto bail;
145*3d066281SPatrick Mooney 	}
146*3d066281SPatrick Mooney 	res = munmap(direct_bootrom, SEG_SZ);
147*3d066281SPatrick Mooney 	if (res != 0) {
148*3d066281SPatrick Mooney 		perror("could not munmap bootrom object");
149*3d066281SPatrick Mooney 		goto bail;
150*3d066281SPatrick Mooney 	}
151*3d066281SPatrick Mooney 
152*3d066281SPatrick Mooney 	/* mission accomplished */
153*3d066281SPatrick Mooney 	vm_destroy(ctx);
154*3d066281SPatrick Mooney 	(void) printf("%s\tPASS\n", suite_name);
155*3d066281SPatrick Mooney 	return (0);
156*3d066281SPatrick Mooney 
157*3d066281SPatrick Mooney bail:
158*3d066281SPatrick Mooney 	vm_destroy(ctx);
159*3d066281SPatrick Mooney 	return (1);
160*3d066281SPatrick Mooney }
161