From 3161d5555b4ffe7416fdccaffbd6425dd8479c5a Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Wed, 16 Jan 2013 10:15:24 -0300 Subject: [PATCH] libubb/physmem.c (physmem_xlat_vec): more general version of physmem_xlat --- libubb/include/ubb/physmem.h | 8 ++++++++ libubb/physmem.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/libubb/include/ubb/physmem.h b/libubb/include/ubb/physmem.h index 4449316..a41d6b9 100644 --- a/libubb/include/ubb/physmem.h +++ b/libubb/include/ubb/physmem.h @@ -16,9 +16,17 @@ #include +struct physmem_vec { + unsigned long addr; + size_t len; +}; + + void *physmem_malloc(size_t size); void *physmem_calloc(size_t size); unsigned long physmem_xlat(void *v); +int physmem_xlat_vec(void *v, size_t len, + struct physmem_vec *vec, int vec_len); int physmem_flush(const void *data, size_t size); #endif /* !UBB_PHYSMEM_H */ diff --git a/libubb/physmem.c b/libubb/physmem.c index d774180..104b9ff 100644 --- a/libubb/physmem.c +++ b/libubb/physmem.c @@ -144,6 +144,41 @@ unsigned long physmem_xlat(void *v) } +int physmem_xlat_vec(void *v, size_t len, + struct physmem_vec *vec, int vec_len) +{ + unsigned long vaddr = (unsigned long) v; + unsigned long offset, this_len; + int fd; + int n = 0; + + fd = open(PAGEMAP_FILE, O_RDONLY); + if (fd < 0) { + perror(PAGEMAP_FILE); + exit(1); + } + while (len) { + if (n >= vec_len) { + close(fd); + errno = EOVERFLOW; + return -1; + } + offset = vaddr & (PAGE_SIZE-1); + this_len = PAGE_SIZE-offset; + if (this_len > len) + this_len = len; + vec->addr = xlat_one(fd, vaddr); + vec->len = this_len; + vec++; + n++; + vaddr += this_len; + len -= this_len; + } + close(fd); + return n; +} + + int physmem_flush(const void *v, size_t size) { if (cacheflush((void *) v, size, DCACHE))