|
|
1.1 ! root 1: /* ! 2: * mem_cache.c - remember correspondences between virtual and physical ! 3: * addresses. ! 4: */ ! 5: #include <sys/coherent.h> ! 6: ! 7: #ifndef NULL ! 8: #define NULL ((char *) 0) ! 9: #endif /* NULL */ ! 10: ! 11: /* ! 12: * We maintain a dynamicly allocated linked list of vaddr/paddr pairs. ! 13: */ ! 14: typedef struct cache_entry { ! 15: struct cache_entry *next; ! 16: struct cache_entry *prev; ! 17: ! 18: caddr_t vaddr; ! 19: paddr_t paddr; ! 20: } CACHE_ENTRY; ! 21: ! 22: static CACHE_ENTRY *find_vaddr(); ! 23: static CACHE_ENTRY *find_paddr(); ! 24: ! 25: /* ! 26: * cache_head is the head of the linked list of stored addresses. ! 27: */ ! 28: static CACHE_ENTRY *cache_head = NULL; ! 29: ! 30: /* ! 31: * Remember that 'vaddr' and 'paddr' correspond. ! 32: * ! 33: * If we run out of memory, we just do a printf(). :-( ! 34: */ ! 35: void ! 36: mem_remember(vaddr, paddr) ! 37: caddr_t vaddr; ! 38: paddr_t paddr; ! 39: { ! 40: CACHE_ENTRY *entry; ! 41: ! 42: T_PIGGY( 0x40, printf("mem_remember(v:%x, p:%x)", vaddr, paddr); ); ! 43: ! 44: /* Be sure to overwrite any existing entry. */ ! 45: if (NULL != (entry = find_paddr(paddr))) { ! 46: entry->vaddr = vaddr; ! 47: entry->paddr = paddr; ! 48: } else { /* We need to create a new entry. */ ! 49: if (NULL == (entry = kalloc(sizeof(CACHE_ENTRY)))) { ! 50: printf( ! 51: "mem_remember(v:%x, p:%x): no more kernel memory.\n", ! 52: vaddr, paddr); ! 53: return; ! 54: } ! 55: ! 56: T_PIGGY( 0x40, printf(": creating %x,", entry); ); ! 57: ! 58: /* Store the data. */ ! 59: entry->vaddr = vaddr; ! 60: entry->paddr = paddr; ! 61: ! 62: /* Insert 'entry' at the head of the list. */ ! 63: entry->prev = NULL; ! 64: entry->next = cache_head; ! 65: if (NULL != cache_head) { cache_head->prev = entry; } ! 66: ! 67: cache_head = entry; ! 68: } ! 69: } /* mem_remember() */ ! 70: ! 71: /* ! 72: * Forget the vaddr/paddr pair that goes with 'vaddr'. ! 73: * Do nothing if we didn't know about vaddr. ! 74: */ ! 75: void ! 76: mem_forget(vaddr) ! 77: { ! 78: CACHE_ENTRY *entry, *my_next, *my_prev; ! 79: T_PIGGY( 0x40, printf("mem_forget(v:%x)", vaddr); ); ! 80: ! 81: if (NULL != (entry = find_vaddr(vaddr))) { ! 82: T_PIGGY( 0x40, printf("forgetting(p:%x)", entry->paddr); ); ! 83: ! 84: /* Remove 'entry' from the linked list. */ ! 85: my_next = entry->next; ! 86: my_prev = entry->prev; ! 87: ! 88: if (NULL != my_next) { my_next->prev = my_prev; } ! 89: if (NULL != my_prev) { my_prev->next = my_next; } ! 90: ! 91: if (entry == cache_head) { cache_head = my_next; } ! 92: ! 93: kfree(entry); ! 94: } ! 95: } /* mem_forget() */ ! 96: ! 97: ! 98: /* ! 99: * Recall the vaddr that goes with 'paddr'. Returns 0 if we don't know ! 100: * what paddr goes with. ! 101: */ ! 102: caddr_t ! 103: mem_recall(paddr) ! 104: paddr_t paddr; ! 105: { ! 106: CACHE_ENTRY *entry; ! 107: caddr_t retval; ! 108: ! 109: T_PIGGY( 0x40, printf("mem_recall(%x)=", paddr); ); ! 110: ! 111: if (NULL == (entry = find_paddr(paddr))) { ! 112: retval = 0; ! 113: } else { ! 114: retval = entry->vaddr; ! 115: } ! 116: ! 117: T_PIGGY( 0x40, printf("%x, ", retval); ); ! 118: ! 119: return( retval ); ! 120: } /* mem_recall() */ ! 121: ! 122: ! 123: /* ! 124: * Given a vaddr, 'vaddr', find the corresponding cache_entry. ! 125: * Returns NULL if it can not find 'vaddr'. ! 126: */ ! 127: static CACHE_ENTRY * ! 128: find_vaddr(vaddr) ! 129: register caddr_t vaddr; ! 130: { ! 131: register CACHE_ENTRY *entry; ! 132: ! 133: /* ! 134: * Walk forward through the cache looking for a matching address. ! 135: * If we don't find it, 'entry' will be NULL, which is exactly ! 136: * what we want. ! 137: */ ! 138: for (entry = cache_head; entry != NULL; entry = entry->next) { ! 139: if (vaddr == entry->vaddr) { ! 140: break; ! 141: } ! 142: } ! 143: ! 144: return( entry ); ! 145: } /* find_vaddr() */ ! 146: ! 147: ! 148: /* ! 149: * Given a paddr, 'paddr', find the corresponding cache_entry. ! 150: * Returns NULL if it can not find 'paddr'. ! 151: */ ! 152: static CACHE_ENTRY * ! 153: find_paddr(paddr) ! 154: register paddr_t paddr; ! 155: { ! 156: register CACHE_ENTRY *entry; ! 157: ! 158: /* ! 159: * Walk forward through the cache looking for a matching address. ! 160: * If we don't find it, 'entry' will be NULL, which is exactly ! 161: * what we want. ! 162: */ ! 163: for (entry = cache_head; entry != NULL; entry = entry->next) { ! 164: if (paddr == entry->paddr) { ! 165: break; ! 166: } ! 167: } ! 168: ! 169: return( entry ); ! 170: } /* find_paddr() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.