⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 standalloc.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lintstatic	char sccsid[] = "@(#)standalloc.c 1.1 92/07/30 SMI";#endif/* * Copyright (c) 1988 by Sun Microsystems, Inc. *//* * standalloc.c * * ROM Monitor's routines for allocating resources needed on a temporary * basis (eg, for initialization or for boot drivers). * * Note, all requests are rounded up to fill a page.  This is not a * malloc() replacement! *//* This flag causes printfs */#ifdef OPENPROMSstatic int alloc_debug = 1;#define	DPRINT	if (alloc_debug) printf#else#define	DPRINT#endif#include <machine/param.h>#include <machine/pte.h>#include <stand/saio.h>#include <machine/mmu.h>/* * Artifice. This should be defined in <mmu.h>. */#ifndef DVMABASE# include <machine/cpu.h># define DVMABASE	(0-DVMASIZE)#endif/* * Artifice so standalone code uses same variable names as monitor's * for debugging.  FIXME?  Or leave this way? */struct globram {	char *g_nextrawvirt;	char *g_nextdmaaddr;	struct pte g_nextmainmap;} gp[1];/* * Valid, supervisor-only, memory page's map entry. * (To be copied to a map entry and then modified.) */struct pte mainmapinit =#if defined(sun3x)	{0, 0, 0, 1, 0, 0, 0, RW, PTE_VALID};#define	pg_pfnum	pte_pfn#elif defined(sun4)	{1, KW, 0, OBMEM, 0, 0, 0, 0};#elif sun4c	{1, KW, 0, OBMEM, 0, 0, 0};#elif sun4m	{0, 0, 0, 0, MMU_STD_SRWX, MMU_ET_PTE };#endifextern	int	memory_avail;/* * Say Something Here FIXME */char *resalloc(type, bytes)	enum RESOURCES type;	register unsigned bytes;{	register char *	addr;	/* Allocated address */	register char *	raddr;	/* Running addr in loop */#ifdef OPENPROMS	if (prom_getversion() > 0) {		switch (type) {		case RES_RAWVIRT:			addr = gp->g_nextrawvirt;			gp->g_nextrawvirt += bytes;			return (addr);		case RES_DMAVIRT:			addr = gp->g_nextdmaaddr;			gp->g_nextdmaaddr += bytes;			return (addr);		case RES_MAINMEM:			addr = gp->g_nextrawvirt;			gp->g_nextrawvirt += bytes;			break;		case RES_DMAMEM:			addr = gp->g_nextdmaaddr;			gp->g_nextdmaaddr += bytes;			break;		default:			return ((char *)0);		}	}#endif#ifndef sun4m	/* Initialize if needed. */	if (gp->g_nextrawvirt == 0) {#ifdef	OPENPROMS		if (prom_getversion() == 0)			reset_alloc((*(romp->v_availmemory))->size);#else 	OPENPROMS		reset_alloc(*romp->v_memoryavail);#endif	OPENPROMS	}	DPRINT("resalloc(%x, %x) %x %x %x\n", type, bytes,	    gp->g_nextrawvirt, gp->g_nextdmaaddr, *(int*)&(gp->g_nextmainmap));	if (bytes == 0)		return ((char *)0);	bytes = (bytes + (PAGESIZE - 1)) & ~(PAGESIZE - 1);	switch (type) {	case RES_RAWVIRT:		addr = gp->g_nextrawvirt;		gp->g_nextrawvirt += bytes;		return (addr);	case RES_DMAVIRT:		addr = gp->g_nextdmaaddr;		gp->g_nextdmaaddr += bytes;		return (addr);	case RES_MAINMEM:		addr = gp->g_nextrawvirt;		gp->g_nextrawvirt += bytes;		break;	case RES_DMAMEM:		addr = gp->g_nextdmaaddr;		gp->g_nextdmaaddr += bytes;		break;	default:		return ((char *)0);	}	/*	 * Now map in main memory.	 * Note that this loop goes backwards!!	 */	DPRINT("mapping to %x returning %x gp %x\n",	    *(int*)&gp->g_nextmainmap, addr, gp);	for (raddr = addr;	    bytes > 0;	    raddr += PAGESIZE, bytes -= PAGESIZE,	    gp->g_nextmainmap.pg_pfnum -= 1) {		setpgmap(raddr, *(int *)&gp->g_nextmainmap);		bzero((caddr_t)raddr, PAGESIZE);	}	return (addr);#endif !sun4m}#ifdef sun3struct pte devmaps[] = {/* MAINMEM */	{1, KW, 0, OBMEM,   0, 0, 0},/* OBIO */	{1, KW, 0, OBIO,    0, 0, 0},/* MBMEM */	{1, KW, 0, VME_D16, 0, 0, btop(0xFF000000) },/* MBIO */	{1, KW, 0, VME_D16, 0, 0, btop(0xFFFF0000) },/* VME16A16D */	{1, KW, 0, VME_D16, 0, 0, btop(0xFFFF0000) },/* VME16A32D */	{1, KW, 0, VME_D32, 0, 0, btop(0xFFFF0000) },/* VME24A16D */	{1, KW, 0, VME_D16, 0, 0, btop(0xFF000000) },/* VME24A32D */	{1, KW, 0, VME_D32, 0, 0, btop(0xFF000000) },/* VME32A16D */	{1, KW, 0, VME_D16, 0, 0, btop(0x00000000) },/* VME32A32D */	{1, KW, 0, VME_D32, 0, 0, btop(0x00000000) },};#endif sun3#ifdef sun3xstruct pte devmaps[] = {/* MAINMEM */	{0,		      0, 0, 0, 0, 0, 0, RW, PTE_VALID},/* OBIO */	{0,		      0, 0, 1, 0, 0, 0, RW, PTE_VALID},/* MBMEM */	{btop(VME24D16_BASE), 0, 0, 1, 0, 0, 0, RW, PTE_VALID},/* MBIO */	{btop(VME16D16_BASE), 0, 0, 1, 0, 0, 0, RW, PTE_VALID},/* VME16A16D */	{btop(VME16D16_BASE), 0, 0, 1, 0, 0, 0, RW, PTE_VALID},/* VME16A32D--not supported */	{0,		      0, 0, 1, 0, 0, 0, RW, 0},/* VME24A16D */	{btop(VME24D16_BASE), 0, 0, 1, 0, 0, 0, RW, PTE_VALID},/* VME24A32D */	{btop(VME24D32_BASE), 0, 0, 1, 0, 0, 0, RW, PTE_VALID},/* VME32A16D--not supported */	{0,                   0, 0, 1, 0, 0, 0, RW, 0},/* VME32A32D */	{btop(VME32D32_BASE), 0, 0, 1, 0, 0, 0, RW, PTE_VALID},};#endif sun3x#ifdef sun4struct pte devmaps[] = {/* MAINMEM */	{1, KW, 0, OBMEM,   0, 0, 0, 0},/* OBIO */	{1, KW, 0, OBIO,    0, 0, 0, 0},/* MBMEM */	{1, KW, 0, VME_D16, 0, 0, 0, btop(0xFF000000) },/* MBIO */	{1, KW, 0, VME_D16, 0, 0, 0, btop(0xFFFF0000) },/* VME16A16D */	{1, KW, 0, VME_D16, 0, 0, 0, btop(0xFFFF0000) },/* VME16A32D */	{1, KW, 0, VME_D32, 0, 0, 0, btop(0xFFFF0000) },/* VME24A16D */	{1, KW, 0, VME_D16, 0, 0, 0, btop(0xFF000000) },/* VME24A32D */	{1, KW, 0, VME_D32, 0, 0, 0, btop(0xFF000000) },/* VME32A16D */	{1, KW, 0, VME_D16, 0, 0, 0, btop(0x00000000) },/* VME32A32D */	{1, KW, 0, VME_D32, 0, 0, 0, btop(0x00000000) },};#endif sun4#ifdef sun4cstruct pte devmaps[] = {/* MAINMEM */	{1, KW, 0, OBMEM, 0, 0, 0},/* OBIO */	{1, KW, 0, OBIO,  0, 0, 0},};#endif sun4c#ifdef nodef#ifdef sun4mstruct pte devmaps[] = {/* MAINMEM */	{0, 0, 0, 0, MMU_STD_SRWX, MMU_ET_PTE},/* OBIO */	{0, 0, 0, 0, MMU_STD_SRWX, MMU_ET_PTE},};#endif sun4m#endif nodef/* * devalloc() allocates virtual memory and maps it to a device * at a specific physical address. * * It returns the virtual address of that physical device. */char *devalloc(devtype, physaddr, bytes)	enum MAPTYPES	devtype;	register char  *physaddr;	register unsigned	bytes;{	char		*addr;	register char  *raddr;	register int	pages;	struct pte	mapper;#ifdef	OPENPROMS	extern char *prom_map();#endif	OPENPROMS	DPRINT("devalloc(%x, %x, %x) ", devtype, physaddr, bytes);	if (!bytes)		return ((char *)0);	pages = bytes + ((int)(physaddr) & (PAGESIZE-1));#ifdef OPENPROMS	if (prom_getversion() > 0)		return (prom_map(0, devtype, physaddr, pages));#endif#ifndef sun4m	addr = resalloc(RES_RAWVIRT, pages);	if (!addr)		return ((char *)0);	mapper = devmaps[(int)devtype];		/* Set it up first */	mapper.pg_pfnum += btop(physaddr);	for (raddr = addr;	    pages > 0;	    raddr += PAGESIZE, pages -= PAGESIZE,	    mapper.pg_pfnum += 1) {		DPRINT("mapping to %x ", *(int *)&mapper);		setpgmap(raddr, *(int *)&mapper);	}	DPRINT("returns roughly %x\n", addr);	return (addr + ((int)(physaddr) & (PAGESIZE-1)));#endif !sun4m}#ifndef sun4m/* * reset_alloc() does all the setup and all the releasing for the PROMs. */reset_alloc(memsize)	unsigned memsize;{#ifdef sun3	int i, addr, pmeg;	gp->g_nextrawvirt = (char *)0x200000;	/*	 * The monitor only allocates as many PMEGs as there is real	 * memory so we have to set up more PMEGs for virtual memory	 * on machines with only 2 megabytes.	 */	for (i=0; i < 0x100000; i += PMGRPSIZE) {	/* 1 Meg */		addr = (int)gp->g_nextrawvirt + i;		pmeg = addr / PMGRPSIZE;		setsegmap(addr, pmeg);	}#elif defined(sun4c)	/*	 * The booter loads itself at 3 Meg so we add an extra half-Meg to	 * get to a place to allocate virtual addresses and still have pmegs.	 * This only applies to Campus proms; OBP machines use the romvec	 * alloc/free routines below.	 */	gp->g_nextrawvirt = (char *)0x380000;#else	/*	 * The booter loads itself at 2 Meg so we add an extra Meg to	 * get to a place to allocate virtual addresses and still have pmegs.	 * This assumes that the minimum memory size for "modern" Suns is 4 Meg.	 */	gp->g_nextrawvirt = (char *)0x300000;#endif 	gp->g_nextdmaaddr = (char *)DVMABASE;	gp->g_nextmainmap = mainmapinit;	gp->g_nextmainmap.pg_pfnum = btop(memsize) - 1;	DPRINT("reset_alloc(%x) mainmap %x gp %x nextmain %x\n",	    memsize, *(int *)&mainmapinit, gp, *(int*)&gp->g_nextmainmap);}#endif !sun4m#ifdef OPENPROMSour_die_routine(retaddr)	register caddr_t retaddr;{	return;}#endif OPENPROMS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -