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

📄 ofmem.c

📁 open source bios with linux platform, very good and can be reused.
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	}	return (ulong)-1;}static ulongofmem_claim_phys_( ulong phys, ulong size, ulong align, int min, int max, int reverse ){	if( !align ) {		if( !is_free( phys, size, ofmem.phys_range ) ) {			printk("Non-free physical memory claimed!\n");			return -1;		}		add_entry( phys, size, &ofmem.phys_range );		return phys;	}	phys = find_area( align, size, ofmem.phys_range, min, max, reverse );	if( phys == (ulong)-1 ) {		printk("ofmem_claim_phys - out of space\n");		return -1;	}	add_entry( phys, size, &ofmem.phys_range );	return phys;}/* if align != 0, phys is ignored. Returns -1 on error */ulongofmem_claim_phys( ulong phys, ulong size, ulong align ){	/* printk("+ ofmem_claim phys %08lx %lx %ld\n", phys, size, align ); */	return ofmem_claim_phys_( phys, size, align, 0, RAMSIZE, 0 );}static ulongofmem_claim_virt_( ulong virt, ulong size, ulong align, int min, int max, int reverse ){	if( !align ) {		if( !is_free( virt, size, ofmem.virt_range ) ) {			printk("Non-free physical memory claimed!\n");			return -1;		}		add_entry( virt, size, &ofmem.virt_range );		return virt;	}		virt = find_area( align, size, ofmem.virt_range, min, max, reverse );	if( virt == (ulong)-1 ) {		printk("ofmem_claim_virt - out of space\n");		return -1;	}	add_entry( virt, size, &ofmem.virt_range );	return virt;}ulongofmem_claim_virt( ulong virt, ulong size, ulong align ){	/* printk("+ ofmem_claim virt %08lx %lx %ld\n", virt, size, align ); */	return ofmem_claim_virt_( virt, size, align, RAMSIZE, 0x80000000, 0 );}/* allocate both physical and virtual space and add a translation */ulongofmem_claim( ulong addr, ulong size, ulong align ){	ulong virt, phys;	ulong offs = addr & 0xfff;	/* printk("+ ofmem_claim %08lx %lx %ld\n", addr, size, align ); */	virt = phys = 0;	if( !align ) {		if( is_free(addr, size, ofmem.virt_range) && is_free(addr, size, ofmem.phys_range) ) {			ofmem_claim_phys_( addr, size, 0, 0, 0, 0 );			ofmem_claim_virt_( addr, size, 0, 0, 0, 0 );			virt = phys = addr;		} else {			printk("**** ofmem_claim failure ***!\n");			return -1;		}	} else {		if( align < 0x1000 )			align = 0x1000;		phys = ofmem_claim_phys_( addr, size, align, 0, RAMSIZE, 1 /* reverse */ );		virt = ofmem_claim_virt_( addr, size, align, 0, RAMSIZE, 1 /* reverse */ );		if( phys == (ulong)-1 || virt == (ulong)-1 ) {			printk("ofmem_claim failed\n");			return -1;		}		/* printk("...phys = %08lX, virt = %08lX, size = %08lX\n", phys, virt, size ); */	}	/* align */	if( phys & 0xfff ) {		size += (phys & 0xfff);		virt -= (phys & 0xfff);		phys &= ~0xfff;	}	if( size & 0xfff )		size = (size + 0xfff) & ~0xfff;		/* printk("...free memory found... phys: %08lX, virt: %08lX, size %lX\n", phys, virt, size ); */	ofmem_map( phys, virt, size, def_memmode(phys) );	return virt + offs;}/************************************************************************//*	keep track of ea -> phys translations				*//************************************************************************/static voidsplit_trans( ulong virt ){	translation_t *t, *t2;		for( t=ofmem.trans; t; t=t->next ) {		if( virt > t->virt && virt < t->virt + t->size-1 ) {			t2 = (translation_t*)malloc( sizeof(translation_t) );			t2->virt = virt;			t2->size = t->size - (virt - t->virt);			t->size = virt - t->virt;			t2->phys = t->phys + t->size;			t2->mode = t->mode;			t2->next = t->next;			t->next = t2;		}	}}static intmap_page_range( ulong virt, ulong phys, ulong size, int mode ){	translation_t *t, **tt;		split_trans( virt );	split_trans( virt + size );	/* detect remappings */	for( t=ofmem.trans; t; ) {		if( virt == t->virt || (virt < t->virt && virt + size > t->virt )) {			if( t->phys + virt - t->virt != phys ) {				printk("mapping altered (ea %08lx)\n", t->virt );			} else if( t->mode != mode ){				printk("mapping mode altered\n");			}			for( tt=&ofmem.trans; *tt != t ; tt=&(**tt).next )				;			*tt = t->next;			free((char*)t);			t=ofmem.trans;			continue;		}		t=t->next;	}	/* add mapping */	for( tt=&ofmem.trans; *tt && (**tt).virt < virt ; tt=&(**tt).next )		;	t = (translation_t*)malloc( sizeof(translation_t) );	t->virt = virt;	t->phys = phys;	t->size = size;	t->mode = mode;	t->next = *tt;	*tt = t;	return 0;}intofmem_map( ulong phys, ulong virt, ulong size, int mode ){	/* printk("+ofmem_map: %08lX --> %08lX (size %08lX, mode 0x%02X)\n", 	   virt, phys, size, mode ); */       	if( (phys & 0xfff) || (virt & 0xfff) || (size & 0xfff) ) {		printk("ofmem_map: Bad parameters (%08lX %08lX %08lX)\n", phys, virt, size );		phys &= ~0xfff;		virt &= ~0xfff;		size = (size + 0xfff) & ~0xfff;	}#if 1	/* claim any unclaimed virtual memory in the range */	fill_range( virt, size, &ofmem.virt_range );	/* hmm... we better claim the physical range too */	fill_range( phys, size, &ofmem.phys_range );#endif	//printk("map_page_range %08lx -> %08lx %08lx\n", virt, phys, size );	map_page_range( virt, phys, size, (mode==-1)? def_memmode(phys) : mode );	return 0;}/* virtual -> physical. */ulongofmem_translate( ulong virt, ulong *mode ){	translation_t *t;		for( t=ofmem.trans; t && t->virt <= virt ; t=t->next ) {		ulong offs;		if( t->virt + t->size - 1 < virt )			continue;		offs = virt - t->virt;		*mode = t->mode;		return t->phys + offs;	}	//printk("ofmem_translate: no translation defined (%08lx)\n", virt);	//print_trans();	return -1;}/* release memory allocated by ofmem_claim */voidofmem_release( ulong virt, ulong size ){	/* printk("ofmem_release unimplemented (%08lx, %08lx)\n", virt, size ); */}/************************************************************************//*	page fault handler						*//************************************************************************/static ulongea_to_phys( ulong ea, int *mode ){	ulong phys;	/* hardcode our translation needs */	if( ea >= OF_CODE_START && ea < FREE_BASE_2 ) {		*mode = def_memmode( ea );		return ea;	}	if( (phys=ofmem_translate(ea, (ulong*)mode)) == (ulong)-1 ) {#ifdef I_WANT_MOLISMS		if( ea != 0x80816c00 )			printk("ea_to_phys: no translation for %08lx, using 1-1\n", ea );#endif		phys = ea;		*mode = def_memmode( phys );#ifdef I_WANT_MOLISMS		forth_segv_handler( (char*)ea );		OSI_Debugger(1);#endif		/* print_virt_range(); */		/* print_phys_range(); */		/* print_trans(); */	}	return phys;}static voidhash_page( ulong ea, ulong phys, int mode ){	static int next_grab_slot=0;	ulong *upte, cmp, hash1;	int i, vsid, found;	mPTE_t *pp;		vsid = (ea>>28) + SEGR_BASE;	cmp = BIT(0) | (vsid << 7) | ((ea & 0x0fffffff) >> 22);	hash1 = vsid;	hash1 ^= (ea >> 12) & 0xffff;	hash1 &= (HASH_SIZE-1) >> 6;	pp = (mPTE_t*)(HASH_BASE + (hash1 << 6));	upte = (ulong*)pp;		/* replace old translation */	for( found=0, i=0; !found && i<8; i++ )		if( cmp == upte[i*2] )			found=1;	/* otherwise use a free slot */	for( i=0; !found && i<8; i++ )		if( !pp[i].v )			found=1;	/* out of slots, just evict one */	if( !found ) {		i = next_grab_slot + 1;		next_grab_slot = (next_grab_slot + 1) % 8;	}	i--;	upte[i*2] = cmp;	upte[i*2+1] = (phys & ~0xfff) | mode;	asm volatile( "tlbie %0"  :: "r"(ea) );}voiddsi_exception( void ){	ulong dar, dsisr;	int mode;	asm volatile("mfdar %0" : "=r" (dar) : );	asm volatile("mfdsisr %0" : "=r" (dsisr) : );		//printk("dsi-exception @ %08lx <%08lx>\n", dar, dsisr );	hash_page( dar, ea_to_phys(dar, &mode), mode );}voidisi_exception( void ){	ulong nip, srr1;	int mode;	asm volatile("mfsrr0 %0" : "=r" (nip) : );	asm volatile("mfsrr1 %0" : "=r" (srr1) : );		//printk("isi-exception @ %08lx <%08lx>\n", nip, srr1 );	hash_page( nip, ea_to_phys(nip, &mode), mode );}/************************************************************************//*	init / cleanup							*//************************************************************************/voidsetup_mmu( ulong code_base, ulong code_size, ulong ramsize ){	ulong sdr1 = HASH_BASE | ((HASH_SIZE-1) >> 16);	ulong sr_base = (0x20 << 24) | SEGR_BASE;	ulong msr;	int i;	asm volatile("mtsdr1 %0" :: "r" (sdr1) );	for( i=0; i<16; i++ ) {		int j = i << 28;		asm volatile("mtsrin %0,%1" :: "r" (sr_base + i), "r" (j) );	}	asm volatile("mfmsr %0" : "=r" (msr) : );	msr |= MSR_IR | MSR_DR;	asm volatile("mtmsr %0" :: "r" (msr) );}voidofmem_init( void ){	/* In case we can't rely on memory being zero initialized */	memset(&ofmem, 0, sizeof(ofmem));	ofmem_claim_phys( 0, FREE_BASE_1, 0 );	ofmem_claim_virt( 0, FREE_BASE_1, 0 );	ofmem_claim_phys( OF_CODE_START, FREE_BASE_2 - OF_CODE_START, 0 );	ofmem_claim_virt( OF_CODE_START, FREE_BASE_2 - OF_CODE_START, 0 );}

⌨️ 快捷键说明

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