summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/fbcopy_pub.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/fbcopy_pub.c')
-rw-r--r--tools/guest-diag/fbcopy_pub.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/tools/guest-diag/fbcopy_pub.c b/tools/guest-diag/fbcopy_pub.c
index ecb38da..a064882 100644
--- a/tools/guest-diag/fbcopy_pub.c
+++ b/tools/guest-diag/fbcopy_pub.c
@@ -573,25 +573,40 @@ int main(int argc, char **argv)
int w = argc > 5 ? atoi(argv[5]) : DEF_W;
int h = argc > 6 ? atoi(argv[6]) : DEF_H;
int pitch = argc > 7 ? atoi(argv[7]) : DEF_PITCH;
- unsigned long long need = off +
- (unsigned long long)(h - 1) * pitch +
+ unsigned long long span = (unsigned long long)(h - 1) * pitch +
(unsigned long long)w * 4;
- size_t wlen = 0;
+ unsigned long long base = off & ~0xfffULL;
+ size_t wlen = (size_t)((off - base) + span);
unsigned char *wmap;
int f, y, x;
- wmap = map_vram(vram_fd, map_size, &wlen);
- if (!wmap) {
- printf("WIN_MAP_FAIL len=0x%zx\n", wlen);
+ if (off + span > map_size) {
+ printf("OFF_RANGE_FAIL need=0x%llx bar=0x%zx\n",
+ off + span, map_size);
return 1;
}
- if (need > wlen) {
- printf("OFF_RANGE_FAIL need=0x%llx window=0x%zx\n",
- need, wlen);
- return 1;
+ /* 2026-10-28 (session 149): nonzero-offset mmaps of BAR1 work
+ * on this mdev (earlier builds assumed only offset 0 <= 64 MB
+ * was mappable). Map directly at the requested offset; fall
+ * back to the old offset-0 64 MB window if that ever fails. */
+ wlen = (wlen + 0xfff) & ~0xfffUL;
+ wmap = mmap(NULL, wlen, PROT_READ, MAP_SHARED, vram_fd,
+ (off_t)base);
+ if (wmap == MAP_FAILED) {
+ size_t got = 0;
+ wmap = map_vram(vram_fd, map_size, &got);
+ if (wmap) {
+ base = 0;
+ wlen = got;
+ }
+ if (!wmap || off + span > wlen) {
+ printf("WIN_MAP_FAIL off=0x%llx len=0x%zx errno=%d\n",
+ base, wlen, errno);
+ return 1;
+ }
}
- printf("PUB off=0x%llx frames=%d fps=%d %dx%d pitch=%d\n",
- off, frames, fps, w, h, pitch);
+ printf("PUB off=0x%llx base=0x%llx len=0x%zx frames=%d fps=%d %dx%d pitch=%d\n",
+ off, base, wlen, frames, fps, w, h, pitch);
hdr->magic = HDR_MAGIC;
hdr->version = 1;
hdr->width = (uint32_t)w;
@@ -602,7 +617,7 @@ int main(int argc, char **argv)
uint64_t t0 = now_ns();
unsigned char *dst = bar + FRAME_OFFSET +
sizeof(struct frame_hdr);
- unsigned char *src = wmap + (size_t)off;
+ unsigned char *src = wmap + (size_t)(off - base);
for (y = 0; y < h; y++) {
unsigned char *s = src + (size_t)y * pitch;