|
|
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.