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