| 1 | /*
 | 
|---|
| 2 |  * Copyright (c) 2011 Vojtech Horky
 | 
|---|
| 3 |  * All rights reserved.
 | 
|---|
| 4 |  *
 | 
|---|
| 5 |  * Redistribution and use in source and binary forms, with or without
 | 
|---|
| 6 |  * modification, are permitted provided that the following conditions
 | 
|---|
| 7 |  * are met:
 | 
|---|
| 8 |  *
 | 
|---|
| 9 |  * - Redistributions of source code must retain the above copyright
 | 
|---|
| 10 |  *   notice, this list of conditions and the following disclaimer.
 | 
|---|
| 11 |  * - Redistributions in binary form must reproduce the above copyright
 | 
|---|
| 12 |  *   notice, this list of conditions and the following disclaimer in the
 | 
|---|
| 13 |  *   documentation and/or other materials provided with the distribution.
 | 
|---|
| 14 |  * - The name of the author may not be used to endorse or promote products
 | 
|---|
| 15 |  *   derived from this software without specific prior written permission.
 | 
|---|
| 16 |  *
 | 
|---|
| 17 |  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 | 
|---|
| 18 |  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
|---|
| 19 |  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
|---|
| 20 |  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
|---|
| 21 |  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
|---|
| 22 |  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
|---|
| 23 |  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
|---|
| 24 |  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
|---|
| 25 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
|---|
| 26 |  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
|---|
| 27 |  */
 | 
|---|
| 28 | 
 | 
|---|
| 29 | #include <stdio.h>
 | 
|---|
| 30 | #include <unistd.h>
 | 
|---|
| 31 | #include <stdlib.h>
 | 
|---|
| 32 | #include <malloc.h>
 | 
|---|
| 33 | #include <as.h>
 | 
|---|
| 34 | #include <errno.h>
 | 
|---|
| 35 | #include "../tester.h"
 | 
|---|
| 36 | 
 | 
|---|
| 37 | #define BUFFER1_PAGES 4
 | 
|---|
| 38 | #define BUFFER2_PAGES 2
 | 
|---|
| 39 | 
 | 
|---|
| 40 | static void *create_as_area(size_t size)
 | 
|---|
| 41 | {
 | 
|---|
| 42 |         void *result = as_get_mappable_page(size);
 | 
|---|
| 43 |         TPRINTF("Creating AS area...\n");
 | 
|---|
| 44 |         if (as_area_create(result, size,
 | 
|---|
| 45 |             AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE) != result) {
 | 
|---|
| 46 |                 return NULL;
 | 
|---|
| 47 |         }
 | 
|---|
| 48 |         return result;
 | 
|---|
| 49 | }
 | 
|---|
| 50 | 
 | 
|---|
| 51 | static void touch_area(void *area, size_t size)
 | 
|---|
| 52 | {
 | 
|---|
| 53 |         TPRINTF("Touching (faulting-in) AS area...\n");
 | 
|---|
| 54 |         
 | 
|---|
| 55 |         char *ptr = (char *)area;
 | 
|---|
| 56 |         
 | 
|---|
| 57 |         while (size > 0) {
 | 
|---|
| 58 |                 *ptr = 0;
 | 
|---|
| 59 |                 size--;
 | 
|---|
| 60 |                 ptr++;
 | 
|---|
| 61 |         }
 | 
|---|
| 62 | }
 | 
|---|
| 63 | 
 | 
|---|
| 64 | #define VERIFY_MAPPING(area, page_count, expected_rc) \
 | 
|---|
| 65 |     verify_mapping((area), (page_count), (expected_rc), #expected_rc)
 | 
|---|
| 66 | 
 | 
|---|
| 67 | static bool verify_mapping(void *area, int page_count, int expected_rc,
 | 
|---|
| 68 |     const char *expected_rc_str)
 | 
|---|
| 69 | {
 | 
|---|
| 70 |         TPRINTF("Verifying mapping (expected: %s).\n", expected_rc_str);
 | 
|---|
| 71 |         int i;
 | 
|---|
| 72 |         for (i = 0; i < page_count; i++) {
 | 
|---|
| 73 |                 void *page_start = ((char *)area) + PAGE_SIZE * i;
 | 
|---|
| 74 |                 int rc = as_get_physical_mapping(page_start, NULL);
 | 
|---|
| 75 |                 if (rc != expected_rc) {
 | 
|---|
| 76 |                         TPRINTF("as_get_physical_mapping() = %d != %d\n",
 | 
|---|
| 77 |                             rc, expected_rc);
 | 
|---|
| 78 |                         return false;
 | 
|---|
| 79 |                 }
 | 
|---|
| 80 |         }
 | 
|---|
| 81 |         return true;
 | 
|---|
| 82 | }
 | 
|---|
| 83 | 
 | 
|---|
| 84 | const char *test_mapping1(void)
 | 
|---|
| 85 | {
 | 
|---|
| 86 |         int rc;
 | 
|---|
| 87 |         
 | 
|---|
| 88 |         size_t buffer1_len = BUFFER1_PAGES * PAGE_SIZE;
 | 
|---|
| 89 |         size_t buffer2_len = BUFFER2_PAGES * PAGE_SIZE;
 | 
|---|
| 90 |         void *buffer1 = create_as_area(buffer1_len);
 | 
|---|
| 91 |         void *buffer2 = create_as_area(buffer2_len);
 | 
|---|
| 92 |         if (!buffer1 || !buffer2) {
 | 
|---|
| 93 |                 return "Cannot allocate memory";
 | 
|---|
| 94 |         }
 | 
|---|
| 95 |         
 | 
|---|
| 96 |         touch_area(buffer1, buffer1_len);
 | 
|---|
| 97 |         touch_area(buffer2, buffer2_len);
 | 
|---|
| 98 |         
 | 
|---|
| 99 |         /* Now verify that mapping to physical frames exist. */
 | 
|---|
| 100 |         if (!VERIFY_MAPPING(buffer1, BUFFER1_PAGES, EOK)) {
 | 
|---|
| 101 |                 return "Failed to find mapping (buffer1)";
 | 
|---|
| 102 |         }
 | 
|---|
| 103 |         if (!VERIFY_MAPPING(buffer2, BUFFER2_PAGES, EOK)) {
 | 
|---|
| 104 |                 return "Failed to find mapping (buffer2)";
 | 
|---|
| 105 |         }
 | 
|---|
| 106 |         
 | 
|---|
| 107 |         /* Let's destroy the buffer1 area and access it again. */
 | 
|---|
| 108 |         rc = as_area_destroy(buffer1);
 | 
|---|
| 109 |         if (rc != EOK) {
 | 
|---|
| 110 |                 return "Failed to destroy AS area";
 | 
|---|
| 111 |         }
 | 
|---|
| 112 |         if (!VERIFY_MAPPING(buffer1, BUFFER1_PAGES, ENOENT)) {
 | 
|---|
| 113 |                 return "Mapping of destroyed area still exists";
 | 
|---|
| 114 |         }
 | 
|---|
| 115 |         
 | 
|---|
| 116 |         /* clean-up */
 | 
|---|
| 117 |         rc = as_area_destroy(buffer2);
 | 
|---|
| 118 |         if (rc != EOK) {
 | 
|---|
| 119 |                 return "Failed to destroy AS area";
 | 
|---|
| 120 |         }
 | 
|---|
| 121 |         
 | 
|---|
| 122 |         return NULL;
 | 
|---|
| 123 | }
 | 
|---|