📄 startup.c
字号:
#endif PROFILING#ifdef QUOTA palloclim(quota, struct quota, nquota, quotaNQUOTA); palloclim(dquot, struct dquot, ndquot, dquotNDQUOT);#endif { /* allocate space for and initialize gateway screen freelist */ char *screen_storage; palloc(screen_storage, char, screen_space_needed()); screen_init_freelist(screen_storage); } fpage = btoc(K0_TO_PHYS((u_int)paddr)); /* * Initialize the proc table to point to the table which contains * per process tlb mapping information. These mappings are dropped * into the tlb wired entries and include mappings for the u-area. * This table is naturally a part of the proc table but could be * configurable in size. * It is undesirable to change the size of the proc table at * sysgen time because of the programs that know about its structure. * This is the same trick used in SysV to deal with the pregion table. */ for (i=0; i<nproc; i++) { proc[i].p_addr = &umap[i*UPAGES]; proc[i].p_tlbinfo = &wtlb[i*NPAGEMAP]; } /* * initialize proc[0]'s u page */ for (i = 0; i < UPAGES; i++) { *(int *)&proc[0].p_addr[i] = (fpage << PTE_PFNSHIFT)|PG_V|PG_M|PG_G|PG_KW;#ifndef SABLE clearseg(fpage);#endif fpage++; tlbwired(TLBWIREDBASE+i, 0, UADDR+(i*NBPG), proc[0].p_addr[i]); } clear_tlbmappings(&proc[0]); up = &u; /* handle on u for debugging */ u.u_pcb.pcb_cpuptr = &boot_cpudata; /* put the cpudata pointer in the real u */ u.u_ar0 = (int *)&USER_REG(0); u.u_procp = &proc[0]; init_tlbpid(); u.u_procp->p_tlbpid = -1; get_tlbpid(u.u_procp); /* * Now allocate space for core map * Allow space for all of physical memory minus the amount * dedicated to the system. fpage indicates the first * physical page currently available. */#if NOMEMCACHE==1 paddr = (caddr_t)PHYS_TO_K1(ctob(fpage));#else paddr = (caddr_t)PHYS_TO_K0(ctob(fpage));#endif /* Calculate # of physical memory pages for buffer cache */ base = bufpages / nbuf; residual = bufpages % nbuf; bcpages = (residual * ((base + 1) * CLSIZE)) + ((nbuf - residual) * (base * CLSIZE)); /* * Allocate one cmap entry for the head of the list. */ palloc(cmap, struct cmap, 1); /* * Calculate how may cmap entry/page frame pairs will fit in * the remaining physical memory. */ ncmap = (ctob(maxmem - (fpage+bcpages)))/(sizeof(struct cmap)+ctob(1)); palloc(ecmap, struct cmap, ncmap); ecmap = (struct cmap *)paddr; fpage = btoc(K0_TO_PHYS((u_int)paddr)); /* Save PFN of last kernel page to dump for crashdump code */ lastkpage = fpage; /* * Allocate space for mapped system data structures. * The first available real memory page is in "fpage". * The first available kernel virtual address is in "v". * As kernel virtual address space is allocated, "v" is incremented. * A virtual page number for the kernel page table corresponding to * the virtual memory address maintained in "v" is kept in "mapvpn". * TODO: it would be more space efficient to allocate all page * aligned things at once, followed by non-paged aligned structures. */ v = (caddr_t)K2BASE; mapvpn = btop(v);#define valloc(name, type, num) \ (name) = (type *)(v); \ (v) = (caddr_t)((name)+(num))#define valloclim(name, type, num, lim) \ (name) = (type *)(v); \ (v) = (caddr_t)((lim) = ((name)+(num)))if (bufdebug) {printf("startup: valloc buffers, nbuf %d MAXBSIZE %d v 0x%x\n", nbuf, MAXBSIZE, v);} valloc(buffers, char, MAXBSIZE * nbuf); base = bufpages / nbuf; /* pages of physical memory per buf struct */ residual = bufpages % nbuf;if (bufdebug) {printf("startup: base (pages/buf) = %d, residual = %d\n", base, residual);} for (i = 0; i < residual; i++) { for (j = 0; j < (base + 1) * CLSIZE; j++) { if (cache_bufcache) mapin(mapvpn + j, fpage, PG_V|PG_KW); else mapin(mapvpn + j, fpage, PG_V|PG_KW|PG_N);#ifndef SABLE clearseg((unsigned)fpage);#endif fpage++; } mapvpn += MAXBSIZE / NBPG; } for (i = residual; i < nbuf; i++) { for (j = 0; j < base * CLSIZE; j++) { if (cache_bufcache) mapin(mapvpn + j, fpage, PG_V|PG_KW); else mapin(mapvpn + j, fpage, PG_V|PG_KW|PG_N);#ifndef SABLE clearseg((unsigned)fpage);#endif fpage++; } mapvpn += MAXBSIZE / NBPG; } if (fpage >= maxmem - 8*UPAGES) panic("no memory"); /* * Initialize callouts */ callfree = callout; for (i = 1; i < ncallout; i++) callout[i-1].c_next = &callout[i]; /* * Initialize memory allocator and swap * and user page table maps. * * THE USER PAGE TABLE MAP IS CALLED ``kernelmap'' * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME. */ meminit(fpage, maxmem); maxmem = freemem; /* freemem is a global set by meminit */ /* * km_alloc's can be used after this */ kmeminit(); rminit(kernelmap, (long)usrptsize, (long)1, "usrpt", nproc*3);}/* * Size memory by walking thru memory invoking the BADADDR macro, * which calls a processor specific badaddr routine. */msize_baddr(fpage){ register int i; causevec[EXC_DBE>>CAUSE_EXCSHIFT] = VEC_nofault; for (i = fpage; i < btop(K0SIZE); i++) { if (BADADDR(PHYS_TO_K1((unsigned)ptob(i)),4)) break; clearseg(i); } causevec[EXC_DBE>>CAUSE_EXCSHIFT] = VEC_trap; return(i);}/* * Size memory by using the bitmap. */msize_bitmap(fpage){ register int i,j; int *bitmap, memsize, start = 0; u_int bitmaplen; struct mem_bitmap *mbmp; if(console_magic == REX_MAGIC) { mbmp = rex_map; /* rex_getbitmap returns number of bytes, the algorithm */ /* below uses number of long words */ bitmaplen = rex_getbitmap(rex_map) / 4; if (mbmp->mbmap_pagesize != NBPG) rex_printf("msize_bitmap: bitmap page size not NBPG\n"); /* DAD */ bitmap = (int *)mbmp->mbmap_bitmap; } else { bitmap = (int *)xtob((char *)prom_getenv("bitmap")); bitmaplen = xtob(prom_getenv("bitmaplen")); } memsize = 0; /* if DS_5000, rom is returning the first and third 64k chunks as bad */ /* assume the are good */ if (cpu == DS_5000) { bitmap += 2; memsize += 64; start = 2; /* start at the second longword, since we hardwired the */ /* first two */ } for (i = start; i < bitmaplen; i++, bitmap++) { if (*bitmap == 0xffffffff) { memsize += 32; continue; } else { for (j = 0; j < 32; j++) { if (*bitmap & (1 << j)) memsize += 1; else break; } break; } } if ((cpu == DS_5800) || (cpu == DS_5500) || (cpu == DS_5100)) { /* * Bitmap page representation is 512 byte pages, * so convert to natural machine page size. * * Take the number of (512-size) pages * 512 to get the * total memory size, then divide by 4k by shifting * right 12, to get the number of 4k pages available. * This drops the remainder, hence leaving any partial * page as unusable. This corrects the problem of * marking bitmaps which don't fall on 4k boundries * as unusable which was caused by using btoc(). * */ memsize = (memsize * 512) >> PGSHIFT ; } for (i = fpage; i < memsize; i++) { clearseg(i); } return(memsize);}init_restartblk(){ register struct restart_blk *rb = (struct restart_blk *)RESTART_ADDR; register struct save_state *sst = (struct save_state *)SST_ADDR; register int i, sum; extern int doadump(); rb->rb_magic = RESTART_MAGIC; rb->rb_occurred = 0; rb->rb_restart = doadump; sum = 0; for (i = 0; i < RESTART_CSUMCNT; i++) sum += ((int *)rb->rb_restart)[i]; rb->rb_checksum = sum; /* * Save state for ULTRIX */ sst->sst_magic = SST_MAGIC; sst->sst_dump = doadump; sst->cpu = cpu;}/* * Determine what we are running on and return the system type. * To be used as the index into the cpu switch (system specific switch table). * * Parameter: * cpu_systype Entire system type work from the PROM * * Return: * Value to be stored in cpu, defined in cpuconf.h */system_type(cpu_systype) unsigned cpu_systype;{ int ret_val = UNKN_SYSTEM; /* Assume we don't know yet */ switch (GETCPUTYPE(cpu_systype)) { case R3000_CPU: /* case R2000a_CPU: */ switch (GETSYSTYPE(cpu_systype)) { case ST_DS3100: ret_val = DS_3100; break; case ST_DS5000: ret_val = DS_5000; break; case ST_DS5000_100: ret_val = DS_5000_100; break; case ST_DS5100: ret_val = DS_5100; break; case ST_DS5400: ret_val = DS_5400; break; case ST_DS5500: ret_val = DS_5500; break; case ST_DS5800: ret_val = DS_5800; break; } break; } return(ret_val);}/* * Get pointer to cpusw table entry for the system we are currently running * on. The pointer returned by this routine will go into "cpup". * * The "cpu" variable (ULTRIX system type) is passed in and compared to the * system_type entry in the cpusw table for a match. */struct cpusw *cpuswitch_entry(cpu) int cpu; /* the ULTRIX system type */{ register int i; /* loop index */ for (i = 0; cpusw[i].system_type != 0; i++) { if (cpusw[i].system_type == cpu) return(&cpusw[i]); } panic("processor type not configured");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -