LCOV - code coverage report
Current view: top level - hw/test - phys-map-test.c (source / functions) Hit Total Coverage
Test: skiboot.info Lines: 63 104 60.6 %
Date: 2024-01-02 21:04:04 Functions: 4 6 66.7 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  * Physical memory map test
       4                 :            :  *
       5                 :            :  * Copyright 2013-2017 IBM Corp.
       6                 :            :  */
       7                 :            : 
       8                 :            : #include "../../core/test/stubs.c"
       9                 :            : #include "../phys-map.c"
      10                 :            : 
      11                 :            : enum proc_gen proc_gen;
      12                 :            : 
      13                 :          0 : static inline void print_entry(const struct phys_map_entry *e)
      14                 :            : {
      15                 :          0 :         printf("type:%i index:%i addr:%016lx size:%016lx",
      16                 :          0 :                e->type, e->index, e->addr, e->size);
      17                 :          0 : }
      18                 :            : 
      19                 :            : /* Check table directly for overlaps */
      20                 :          3 : static void check_table_directly(void)
      21                 :            : {
      22                 :            :         const struct phys_map_entry *e, *prev;
      23                 :            :         uint64_t start, end, pstart, pend;
      24                 :            :         bool passed;
      25                 :            : 
      26                 :            :         /* Loop over table entries ...  */
      27                 :        283 :         for (e = phys_map->table; !phys_map_entry_null(e); e++) {
      28                 :            : 
      29                 :        280 :                 start = e->addr;
      30                 :        280 :                 end = e->addr + e->size;
      31                 :            :                 /* ... see if they overlap with previous entries */
      32                 :      13391 :                 for (prev = phys_map->table; prev != e; prev++) {
      33                 :      13111 :                         passed = true;
      34                 :            :                         /* Check for overlaping regions */
      35                 :      13111 :                         pstart = prev->addr;
      36                 :      13111 :                         pend = prev->addr + prev->size;
      37                 :      13111 :                         if ((start > pstart) && (start < pend))
      38                 :          0 :                                 passed = false;
      39                 :      13111 :                         if ((end > pstart) && (end < pend))
      40                 :          0 :                                 passed = false;
      41                 :            : 
      42                 :            :                         /* Check for duplicate entries */
      43                 :      13111 :                         if ((e->type == prev->type) &&
      44                 :        941 :                             (e->index == prev->index))
      45                 :          0 :                                 passed = false;
      46                 :            : 
      47                 :      13111 :                         if (passed)
      48                 :      13111 :                                 continue;
      49                 :            : 
      50                 :          0 :                         printf("Phys map direct test FAILED: Entry overlaps\n");
      51                 :          0 :                         printf("First:  ");
      52                 :          0 :                         print_entry(prev);
      53                 :          0 :                         printf("\n");
      54                 :          0 :                         printf("Second: ");
      55                 :          0 :                         print_entry(e);
      56                 :          0 :                         printf("\n");
      57                 :          0 :                         assert(0);
      58                 :            :                 }
      59                 :            :         }
      60                 :          3 : }
      61                 :            : 
      62                 :            : struct map_call_entry {
      63                 :            :         uint64_t start;
      64                 :            :         uint64_t end;
      65                 :            : };
      66                 :            : 
      67                 :      13671 : static inline bool map_call_entry_null(const struct map_call_entry *t)
      68                 :            : {
      69                 :      13671 :         if ((t->start == 0) &&
      70                 :        283 :             (t->end == 0))
      71                 :        283 :                 return true;
      72                 :      13388 :         return false;
      73                 :            : }
      74                 :            : 
      75                 :            : /* Check calls to map to see if they overlap.
      76                 :            :  * Creates a new table for each of the entries it gets to check against
      77                 :            :  */
      78                 :            : 
      79                 :            : /* Pick a chip ID, any ID. */
      80                 :            : #define FAKE_CHIP_ID 8
      81                 :            : 
      82                 :          0 : struct proc_chip *get_chip(uint32_t chip_id __unused)
      83                 :            : {
      84                 :          0 :         return NULL;
      85                 :            : }
      86                 :            : 
      87                 :          3 : static void check_map_call(void)
      88                 :            : {
      89                 :            :         uint64_t start, size, end;
      90                 :            :         const struct phys_map_entry *e;
      91                 :            :         struct map_call_entry *tbl, *t, *tnext;
      92                 :          3 :         int tbl_size = 0;
      93                 :            :         bool passed;
      94                 :            : 
      95                 :        283 :         for (e = phys_map->table; !phys_map_entry_null(e); e++)
      96                 :        280 :                 tbl_size++;
      97                 :            : 
      98                 :          3 :         tbl_size++; /* allow for null entry at end */
      99                 :          3 :         tbl_size *= sizeof(struct map_call_entry);
     100                 :          3 :         tbl = malloc(tbl_size);
     101                 :          3 :         assert(tbl != NULL);
     102                 :          3 :         memset(tbl, 0, tbl_size);
     103                 :            : 
     104                 :            :         /* Loop over table entries ...  */
     105                 :        283 :         for (e = phys_map->table; !phys_map_entry_null(e); e++) {
     106                 :        280 :                 __phys_map_get(FAKE_CHIP_ID, FAKE_CHIP_ID, e->type, e->index, &start, &size);
     107                 :            : 
     108                 :            :                 /* Check for alignment */
     109                 :        280 :                 if ((e->type != SYSTEM_MEM) && (e->type != RESV)) {
     110                 :            :                         /* Size is power of 2? */
     111                 :        245 :                         assert(__builtin_popcountl(size) == 1);
     112                 :            :                         /* Start is aligned to size? */
     113                 :        245 :                         assert((start % size) == 0);
     114                 :            :                 }
     115                 :            : 
     116                 :        280 :                 end = start + size;
     117                 :      13391 :                 for (t = tbl; !map_call_entry_null(t); t++) {
     118                 :      13111 :                         passed = true;
     119                 :            : 
     120                 :            :                         /* Check for overlaping regions */
     121                 :      13111 :                         if ((start > t->start) && (start < t->end))
     122                 :          0 :                                 passed = false;
     123                 :      13111 :                         if ((end > t->start) && (end < t->end))
     124                 :          0 :                                 passed = false;
     125                 :            : 
     126                 :      13111 :                         if (passed)
     127                 :      13111 :                                 continue;
     128                 :            : 
     129                 :          0 :                         printf("Phys map call test FAILED: Entry overlaps\n");
     130                 :          0 :                         printf("First:  addr:%016lx size:%016lx\n",
     131                 :          0 :                                t->start, t->end - t->start);
     132                 :          0 :                         printf("Second: addr:%016lx size:%016lx\n  ",
     133                 :            :                                start, size);
     134                 :          0 :                         print_entry(e);
     135                 :          0 :                         printf("\n");
     136                 :          0 :                         assert(0);
     137                 :            :                 }
     138                 :            :                 /* Insert entry at end of table */
     139                 :        280 :                 t->start = start;
     140                 :        280 :                 t->end = end;
     141                 :            :         }
     142                 :            : 
     143                 :        280 :         for (t = tbl; !map_call_entry_null(t + 1); t++) {
     144                 :        277 :                 tnext = t + 1;
     145                 :            :                 /* Make sure the table is sorted */
     146                 :        277 :                 if (t->start > tnext->start) {
     147                 :          0 :                         printf("Phys map test FAILED: Entry not sorted\n");
     148                 :          0 :                         printf("First:  addr:%016lx size:%016lx\n",
     149                 :          0 :                                t->start, t->end - t->start);
     150                 :          0 :                         printf("Second:  addr:%016lx size:%016lx\n",
     151                 :          0 :                                tnext->start, tnext->end - tnext->start);
     152                 :          0 :                         assert(0);
     153                 :            :                 }
     154                 :            : 
     155                 :            :                 /* Look for holes in the table in MMIO region */
     156                 :            :                 /* We assume over 1PB is MMIO. */
     157                 :        277 :                 if ((t->end != tnext->start) &&
     158                 :          8 :                     (t->start > 0x0004000000000000)) {
     159                 :          0 :                         printf("Phys map test FAILED: Hole in map\n");
     160                 :          0 :                         printf("First:  addr:%016lx size:%016lx\n",
     161                 :          0 :                                t->start, t->end - t->start);
     162                 :          0 :                         printf("Second:  addr:%016lx size:%016lx\n",
     163                 :          0 :                                tnext->start, tnext->end - tnext->start);
     164                 :          0 :                         assert(0);
     165                 :            :                 }
     166                 :            :         }
     167                 :            : 
     168                 :          3 :         free(tbl);
     169                 :          3 : }
     170                 :            : 
     171                 :            : /* Fake PVR definitions. See include/processor.h */
     172                 :            : unsigned long fake_pvr[] = {
     173                 :            :         0x004e0200,     /* PVR_P9 */
     174                 :            :         0x004f0100,     /* PVR_P9P */
     175                 :            :         0x00800100,     /* PVR_P10 */
     176                 :            : };
     177                 :            : 
     178                 :          1 : int main(void)
     179                 :            : {
     180                 :          4 :         for (int i = 0; i < ARRAY_SIZE(fake_pvr); i++) {
     181                 :          3 :                 switch(PVR_TYPE(fake_pvr[i])) {
     182                 :          2 :                 case PVR_TYPE_P9:
     183                 :            :                 case PVR_TYPE_P9P:
     184                 :          2 :                         proc_gen = proc_gen_p9;
     185                 :          2 :                         break;
     186                 :          1 :                 case PVR_TYPE_P10:
     187                 :          1 :                         proc_gen = proc_gen_p10;
     188                 :          1 :                         break;
     189                 :          0 :                 default:
     190                 :          0 :                         printf("Unknown PVR 0x%lx\n", fake_pvr[i]);
     191                 :          0 :                         return 1;
     192                 :            :                         break;
     193                 :            :                 }
     194                 :            : 
     195                 :          3 :                 phys_map_init(fake_pvr[i]);
     196                 :            : 
     197                 :            :                 /* Run tests */
     198                 :          3 :                 check_table_directly();
     199                 :          3 :                 check_map_call();
     200                 :            :         }
     201                 :            : 
     202                 :          1 :         return(0);
     203                 :            : }

Generated by: LCOV version 1.14