summaryrefslogtreecommitdiffstats
path: root/core/test
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-08-17 14:49:53 +0800
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-08-17 17:04:14 +1000
commit58033e44b927c80257a72037aeed2cab682e0c85 (patch)
treef58166f8464d0d0aac22cff343d6ea4315493fdf /core/test
parent44088be051802fcdda2e04a2667cd3ff8b71b75a (diff)
downloadblackbird-skiboot-58033e44b927c80257a72037aeed2cab682e0c85.tar.gz
blackbird-skiboot-58033e44b927c80257a72037aeed2cab682e0c85.zip
core/mem_region: Add mem_range_is_reserved()
This change adds a function to check whether a range of memory is covered by one or more reservations. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/test')
-rw-r--r--core/test/Makefile.check1
-rw-r--r--core/test/run-mem_range_is_reserved.c216
2 files changed, 217 insertions, 0 deletions
diff --git a/core/test/Makefile.check b/core/test/Makefile.check
index dfe73605..c1af4b33 100644
--- a/core/test/Makefile.check
+++ b/core/test/Makefile.check
@@ -8,6 +8,7 @@ CORE_TEST := core/test/run-device \
core/test/run-mem_region_release_unused \
core/test/run-mem_region_release_unused_noalloc \
core/test/run-mem_region_reservations \
+ core/test/run-mem_range_is_reserved \
core/test/run-nvram-format \
core/test/run-trace core/test/run-msg \
core/test/run-pel \
diff --git a/core/test/run-mem_range_is_reserved.c b/core/test/run-mem_range_is_reserved.c
new file mode 100644
index 00000000..b5043261
--- /dev/null
+++ b/core/test/run-mem_range_is_reserved.c
@@ -0,0 +1,216 @@
+/* Copyright 2015 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+/* Don't include this, it's PPC-specific */
+#define __CPU_H
+static unsigned int cpu_max_pir = 1;
+struct cpu_thread {
+ unsigned int chip_id;
+};
+
+#include <stdlib.h>
+
+static void *real_malloc(size_t size)
+{
+ return malloc(size);
+}
+
+static void real_free(void *p)
+{
+ return free(p);
+}
+
+#undef malloc
+#undef free
+#undef realloc
+
+#include <skiboot.h>
+#include <mem_region-malloc.h>
+
+/* We need mem_region to accept __location__ */
+#define is_rodata(p) true
+#include "../mem_region.c"
+#include "../malloc.c"
+
+/* But we need device tree to make copies of names. */
+#undef is_rodata
+#define is_rodata(p) false
+#include "../../libc/string/strdup.c"
+
+#include "../device.c"
+#include <assert.h>
+#include <stdio.h>
+
+void lock(struct lock *l)
+{
+ assert(!l->lock_val);
+ l->lock_val++;
+}
+
+void unlock(struct lock *l)
+{
+ assert(l->lock_val);
+ l->lock_val--;
+}
+
+bool lock_held_by_me(struct lock *l)
+{
+ return l->lock_val;
+}
+
+#define TEST_HEAP_ORDER 14
+#define TEST_HEAP_SIZE (1ULL << TEST_HEAP_ORDER)
+
+static void add_mem_node(uint64_t start, uint64_t len)
+{
+ struct dt_node *mem;
+ u64 reg[2];
+ char *name;
+
+ name = (char*)malloc(sizeof("memory@") + STR_MAX_CHARS(reg[0]));
+ assert(name);
+
+ /* reg contains start and length */
+ reg[0] = cpu_to_be64(start);
+ reg[1] = cpu_to_be64(len);
+
+ sprintf(name, "memory@%llx", (long long)start);
+
+ mem = dt_new(dt_root, name);
+ dt_add_property_string(mem, "device_type", "memory");
+ dt_add_property(mem, "reg", reg, sizeof(reg));
+ free(name);
+}
+
+void add_chip_dev_associativity(struct dt_node *dev __attribute__((unused)))
+{
+}
+
+struct test_region {
+ uint64_t start;
+ uint64_t end;
+};
+
+static struct test {
+ struct test_region regions[3];
+ bool reserved;
+} tests[] = {
+ /* empty region set */
+ { { { 0 } }, false },
+
+ /* single exact match */
+ { { { 0x1000, 0x2000 }, }, true },
+
+ /* overlap downwards */
+ { { { 0x0fff, 0x2000 }, }, true },
+
+ /* overlap upwards */
+ { { { 0x1000, 0x2001 }, }, true },
+
+ /* missing first byte */
+ { { { 0x1001, 0x2000 }, }, false },
+
+ /* missing last byte */
+ { { { 0x1000, 0x1fff }, }, false },
+
+ /* two regions, full coverage, split before start of range */
+ { { { 0x0500, 0x1000 }, { 0x1000, 0x2500 } }, true },
+
+ /* two regions, full coverage, split after start of range */
+ { { { 0x0500, 0x1001 }, { 0x1001, 0x2500 } }, true },
+
+ /* two regions, full coverage, split at middle of range */
+ { { { 0x0500, 0x1500 }, { 0x1500, 0x2500 } }, true },
+
+ /* two regions, full coverage, split before end of range */
+ { { { 0x0500, 0x1fff }, { 0x1fff, 0x2500 } }, true },
+
+ /* two regions, full coverage, split after end of range */
+ { { { 0x0500, 0x2000 }, { 0x2000, 0x2500 } }, true },
+
+ /* two regions, missing byte in middle of range */
+ { { { 0x0500, 0x14ff }, { 0x1500, 0x2500 } }, false },
+
+ /* two regions, missing byte after start of range */
+ { { { 0x0500, 0x1000 }, { 0x1001, 0x2500 } }, false },
+
+ /* two regions, missing byte before end of range */
+ { { { 0x0500, 0x1fff }, { 0x2000, 0x2500 } }, false },
+};
+
+static void run_test(struct test *test)
+{
+ struct test_region *r;
+ bool reserved;
+
+ list_head_init(&regions);
+
+ mem_region_init();
+
+ /* create our reservations */
+ for (r = test->regions; r->start; r++)
+ mem_reserve_hw("r", r->start, r->end - r->start);
+
+ reserved = mem_range_is_reserved(0x1000, 0x1000);
+
+ if (reserved != test->reserved) {
+ struct mem_region *r;
+ fprintf(stderr, "test failed; got %s, expected %s\n",
+ reserved ? "reserved" : "unreserved",
+ test->reserved ? "reserved" : "unreserved");
+
+ fprintf(stderr, "reserved regions:\n");
+
+ list_for_each(&regions, r, list) {
+ fprintf(stderr, "\t: %08x[%08x] %s\n",
+ r->start, r->len, r->name);
+ }
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+int main(void)
+{
+ unsigned int i;
+ void *buf;
+
+ /* Use malloc for the heap, so valgrind can find issues. */
+ skiboot_heap.start = (long)real_malloc(TEST_HEAP_SIZE);
+ skiboot_heap.len = TEST_HEAP_SIZE;
+
+ /* shift the OS reserve area out of the way of our playground */
+ skiboot_os_reserve.start = 0x100000;
+ skiboot_os_reserve.len = 0x1000;
+
+ dt_root = dt_new_root("");
+ dt_add_property_cells(dt_root, "#address-cells", 2);
+ dt_add_property_cells(dt_root, "#size-cells", 2);
+
+ buf = real_malloc(1024*1024);
+ add_mem_node((unsigned long)buf, 1024*1024);
+
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
+ run_test(&tests[i]);
+
+ dt_free(dt_root);
+ real_free(buf);
+ real_free((void *)(long)skiboot_heap.start);
+ return 0;
+}
OpenPOWER on IntegriCloud