|
|
1.1 root 1: /* standalloc.c 1.1 86/02/03 */
2:
3: /*
4: * Copyright (c) 1985 by Sun Microsystems, Inc.
5: */
6:
7: /*
8: * standalloc.c
9: *
10: * ROM Monitor's routines for allocating resources needed on a temporary
11: * basis (eg, for initialization or for boot drivers).
12: *
13: * Note, all requests are rounded up to fill a page. This is not a
14: * malloc() replacement!
15: */
16:
17: /* This flag causes printfs */
18: #undef PD
19:
20: #include "../mon/cpu.map.h"
21: #include "../mon/cpu.addrs.h"
22: #include <sys/param.h>
23: #include <sys/inode.h>
24: #include "saio.h"
25:
26: /*
27: * Artifice so standalone code uses same variable names as monitor's
28: * for debugging. FIXME? Or leave this way?
29: */
30: struct globram {
31: char *g_nextrawvirt;
32: char *g_nextdmaaddr;
33: struct pgmapent g_nextmainmap;
34: } gp[1];
35:
36:
37: /*
38: * Valid, supervisor-only, memory page's map entry.
39: * (To be copied to a map entry and then modified.)
40: */
41: struct pgmapent mainmapinit =
42: {1, PMP_SUP, VPM_MEMORY, 0, 0, 0};
43:
44:
45: /*
46: * Say Something Here FIXME
47: */
48: char *
49: resalloc(type, bytes)
50: enum RESOURCES type;
51: register unsigned bytes;
52: {
53: register char * addr; /* Allocated address */
54: register char * raddr; /* Running addr in loop */
55:
56: /* Initialize if needed. */
57: if (gp->g_nextrawvirt == 0) {
58: #ifdef SUN2
59: reset_alloc(0x100000);
60: #endif
61: #ifdef SUN3
62: reset_alloc(*romp->v_memoryavail);
63: #endif
64: }
65:
66: #ifdef PD
67: printf("resalloc(%x, %x) %x %x ", type, bytes,
68: gp->g_nextrawvirt, gp->g_nextdmaaddr);
69: #endif PD
70: if (bytes == 0)
71: return (char *)0;
72:
73: bytes = (bytes + (BYTESPERPG - 1)) & ~(BYTESPERPG - 1);
74:
75: switch (type) {
76:
77: case RES_RAWVIRT:
78: addr = gp->g_nextrawvirt;
79: gp->g_nextrawvirt += bytes;
80: return addr;
81:
82: case RES_DMAVIRT:
83: addr = gp->g_nextdmaaddr;
84: gp->g_nextdmaaddr += bytes;
85: return addr;
86:
87: case RES_MAINMEM:
88: addr = gp->g_nextrawvirt;
89: gp->g_nextrawvirt += bytes;
90: break;
91:
92: case RES_DMAMEM:
93: addr = gp->g_nextdmaaddr;
94: gp->g_nextdmaaddr += bytes;
95: break;
96:
97: default:
98: return (char *)0;
99: }
100:
101: /*
102: * Now map in main memory.
103: * Note that this loop goes backwards!!
104: */
105: #ifdef PD
106: printf("mapping to %x returning %x\n", gp->g_nextmainmap, addr);
107: #endif
108: for (raddr = addr;
109: bytes > 0;
110: raddr += BYTESPERPG, bytes -= BYTESPERPG,
111: gp->g_nextmainmap.pm_page -= 1) {
112: setpgmap(raddr, gp->g_nextmainmap);
113: bzero((caddr_t)raddr, BYTESPERPG);
114: }
115:
116: return addr;
117: }
118:
119: #ifdef SUN2
120: struct pgmapent devmaps[] = {
121: /* MAINMEM */
122: {1, PMP_SUP, MPM_MEMORY, 0, 0, 0},
123: /* OBIO */
124: {1, PMP_SUP, MPM_IO, 0, 0, 0},
125: /* MBMEM */
126: {1, PMP_SUP, VPM_VME0, 0, 0, 0xFF000000 >> BYTES_PG_SHIFT},
127: /* MBIO */
128: {1, PMP_SUP, VPM_VME8, 0, 0, 0xFFFF0000 >> BYTES_PG_SHIFT},
129: /* VME16A16D */
130: {1, PMP_SUP, VPM_VME8, 0, 0, 0xFFFF0000 >> BYTES_PG_SHIFT},
131: /* VME16A32D -- invalid */
132: {0, PMP_SUP, VPM_VME8, 0, 0, 0xFFFF0000 >> BYTES_PG_SHIFT},
133: /* VME24A16D -- kludge low 8 megs only */
134: {1, PMP_SUP, VPM_VME0, 0, 0, 0xFF000000 >> BYTES_PG_SHIFT},
135: /* VME24A32D -- invalid */
136: {0, PMP_SUP, VPM_VME0, 0, 0, 0xFF000000 >> BYTES_PG_SHIFT},
137: /* VME32A16D -- invalid */
138: {0, PMP_SUP, VPM_VME0, 0, 0, 0x00000000 >> BYTES_PG_SHIFT},
139: /* VME32A32D -- invalid */
140: {0, PMP_SUP, VPM_VME0, 0, 0, 0x00000000 >> BYTES_PG_SHIFT},
141: };
142: #endif SUN2
143:
144: #ifdef SUN3
145: struct pgmapent devmaps[] = {
146: /* MAINMEM */
147: {1, PMP_SUP, VPM_MEMORY, 0, 0, 0},
148: /* OBIO */
149: {1, PMP_SUP, VPM_IO, 0, 0, 0},
150: /* MBMEM */
151: {1, PMP_SUP, VPM_VME16, 0, 0, 0xFF000000 >> BYTES_PG_SHIFT},
152: /* MBIO */
153: {1, PMP_SUP, VPM_VME16, 0, 0, 0xFFFF0000 >> BYTES_PG_SHIFT},
154: /* VME16A16D */
155: {1, PMP_SUP, VPM_VME16, 0, 0, 0xFFFF0000 >> BYTES_PG_SHIFT},
156: /* VME16A32D */
157: {1, PMP_SUP, VPM_VME32, 0, 0, 0xFFFF0000 >> BYTES_PG_SHIFT},
158: /* VME24A16D */
159: {1, PMP_SUP, VPM_VME16, 0, 0, 0xFF000000 >> BYTES_PG_SHIFT},
160: /* VME24A32D */
161: {1, PMP_SUP, VPM_VME32, 0, 0, 0xFF000000 >> BYTES_PG_SHIFT},
162: /* VME32A16D */
163: {1, PMP_SUP, VPM_VME16, 0, 0, 0x00000000 >> BYTES_PG_SHIFT},
164: /* VME32A32D */
165: {1, PMP_SUP, VPM_VME32, 0, 0, 0x00000000 >> BYTES_PG_SHIFT},
166: };
167: #endif SUN3
168:
169:
170: /*
171: * devalloc() allocates virtual memory and maps it to a device
172: * at a specific physical address.
173: *
174: * It returns the virtual address of that physical device.
175: */
176: char *
177: devalloc(devtype, physaddr, bytes)
178: enum MAPTYPES devtype;
179: register char * physaddr;
180: register unsigned bytes;
181: {
182: char * addr;
183: register char * raddr;
184: register int pages;
185: struct pgmapent mapper;
186:
187: #ifdef PD
188: printf("devalloc(%x, %x, %x) ", devtype, physaddr, bytes);
189: #endif
190: if (!bytes)
191: return (char *)0;
192:
193: pages = bytes + ((int)(physaddr) & (BYTESPERPG-1));
194: addr = resalloc(RES_RAWVIRT, pages);
195: if (!addr)
196: return (char *)0;
197:
198: mapper = devmaps[(int)devtype]; /* Set it up first */
199: mapper.pm_page += (int)(physaddr) >> BYTES_PG_SHIFT;
200:
201: for (raddr = addr;
202: pages > 0;
203: raddr += BYTESPERPG, pages -= BYTESPERPG,
204: mapper.pm_page += 1) {
205: #ifdef PD
206: printf("mapping to %x ", mapper);
207: #endif
208: setpgmap(raddr, mapper);
209: }
210:
211: #ifdef PD
212: printf("returns roughly %x\n", addr);
213: #endif
214: return addr + ((int)(physaddr) & (BYTESPERPG-1));
215: }
216:
217: /*
218: * reset_alloc() does all the setup and all the releasing for the PROMs.
219: */
220: reset_alloc(memsize)
221: unsigned memsize;
222: {
223: #ifdef SUN2
224: gp->g_nextrawvirt = (char *)0x100000;
225: #endif
226: #ifdef SUN3
227: int i, addr, pmeg;
228:
229: gp->g_nextrawvirt = (char *)0x200000;
230: /*
231: * The monitor only allocates as many PMEGs as there is real
232: * memory so we have to set up more PMEGs for virtual memory
233: * on machines with only 2 megabytes.
234: */
235: for (i=0; i < 0x100000; i += PGSPERSEG*BYTESPERPG) { /* 1 Meg */
236: addr = (int)gp->g_nextrawvirt + i;
237: pmeg = addr / (PGSPERSEG*BYTESPERPG);
238: setsegmap(addr, pmeg);
239: }
240: #endif
241: gp->g_nextdmaaddr = DVMA_BASE;
242: gp->g_nextmainmap = mainmapinit;
243: gp->g_nextmainmap.pm_page = (memsize>>BYTES_PG_SHIFT) - 1;
244: #ifdef PD
245: printf("reset_alloc(%x)\n", memsize);
246: #endif
247: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.