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

📄 ppcv_cpuconfig_booke.c

📁 qnx powerpc MPC8245的 BSP源文件
💻 C
字号:
/* * $QNXLicenseC:  * Copyright 2007, QNX Software Systems.   *   * Licensed under the Apache License, Version 2.0 (the "License"). You   * may not reproduce, modify or distribute this software except in   * compliance with the License. You may obtain a copy of the License   * at: http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" basis,   * WITHOUT WARRANTIES OF ANY KIND, either express or implied.  *  * This file may contain contributions from others, either as   * contributors under the License or as licensors under other terms.    * Please review this entire file for other proprietary rights or license   * notices, as well as the QNX Development Suite License Guide at   * http://licensing.qnx.com/license-guide/ for other information.  * $  */#include "startup.h"// Clean out the TLB except for the one covering entrystatic voidppcbke_tlb_clean1(int cpu) {	unsigned		i;	ppcbke_tlb_t	tlb;	unsigned		covering = -1;	unsigned		covering_tlb = -1;	uint64_t		tlb_size;	unsigned		save_msr;	unsigned		transfer_idx;	int				num_entries;	int				tlb_num;#if 0//NYI: TEMP TESTING HACK	return;#endif	tlb_num = 0;	for(;;) {		num_entries = ppcbke_tlb.info(MI_NUM_ENTRIES, tlb_num);		if(num_entries < 0) break;		for(i = 0; i < num_entries; ++i) {			ppcbke_tlb.read(tlb_num, i, &tlb);			if(tlb.v) {				tlb_size = (uint64_t)0x400 << (tlb.size*2);				if((tlb.epn < (uintptr_t)&ppcbke_tlb_clean1)				 &&((tlb.epn + tlb_size) > (uintptr_t)&ppcbke_tlb_clean1)) {					covering = i;					covering_tlb = tlb_num;				} else {					tlb.v = 0;					ppcbke_tlb.write(tlb_num, i, &tlb);				}			}		}		++tlb_num;	}	/*		Make sure that TLB slot zero is set up for one-to-one mapping	   	with a size of 256M.//NYI: Should check and make sure 256M is a supported page size....	*/	tlb.rpn = 0;	tlb.epn = 0;	tlb.tid = 0;	tlb.attr = PPCBKE_TLB_ATTR_M | PPCBKEM_TLB_ATTR_IPROT | PPCBKEM_TLB_ATTR_SHAREN;	tlb.access = PPCBKE_TLB_ACCESS_SR|PPCBKE_TLB_ACCESS_SW|PPCBKE_TLB_ACCESS_SX;	tlb.size = PPCBKE_TLB_SIZE_256M;	tlb.v = 1;	tlb.ts = 1;	/* choose a TLB slot that's not zero & not 'covering' */	transfer_idx = (covering ^ 0x02) | 1;	/* enable transfer slot */	ppcbke_tlb.write(covering_tlb, transfer_idx, &tlb);	save_msr = get_msr();	set_msr(save_msr | (PPC_MSR_IS|PPC_MSR_DS));	ppc_isync();	tlb.v = 0;	/* disable old covering slot */	ppcbke_tlb.write(covering_tlb, covering, &tlb);	tlb.ts = 0;	tlb.v = 1;	/* enable new covering entry at slot zero */	ppcbke_tlb.write(covering_tlb, 0, &tlb);	set_msr(save_msr);	ppc_isync();	tlb.v = 0;	/* disable transfer slot */	ppcbke_tlb.write(covering_tlb, transfer_idx, &tlb);	// We're going to use PID == 0 for callout mappings and	// PID == 1 for startup ones.	set_spr(PPCBKE_SPR_PID, 1);}// Clean out the TLB of all the startup mappingsstatic voidppcbke_tlb_clean2(int cpu) {	unsigned		i;	ppcbke_tlb_t	tlb;	unsigned		tlb_num;	int				num_entries;	tlb_num = 0;	for(;;) {		num_entries = ppcbke_tlb.info(MI_NUM_ENTRIES, tlb_num);		if(num_entries < 0) break;		for(i = 0; i < num_entries; ++i) {			ppcbke_tlb.read(tlb_num, i, &tlb);			if(tlb.v && (tlb.tid == 1)) {				tlb.v = 0;				ppcbke_tlb.write(tlb_num, i, &tlb);			}		}		++tlb_num;	}}static voidset_ivor_range(unsigned spr, unsigned loc, unsigned num) {	while(num > 0) {		set_spr_indirect(spr, loc);		loc += 1 << 4;		++spr;		--num;	}}voidppcv_cpuconfig1_booke(int cpu) {	/* mask all timer interrupts */	set_spr(PPCBKE_SPR_TCR, PPCBKE_TCR_ARE);	/* if cpu == 0, init decrementer for full cycle, otherwise kill it */	if(cpu == 0) {		set_spr(PPCBKE_SPR_DECAR, ~0L);		set_spr(PPC_SPR_DEC, ~0L);	} else {		set_spr(PPCBKE_SPR_TCR, 0);		set_spr(PPC_SPR_DEC, 0);	}	set_spr(PPCBKE_SPR_TSR, PPCBKE_TSR_DIS);	ppcbke_tlb_clean1(cpu);}unsigned short ivor32_47_list;unsigned short ivor48_63_list;voidppcv_cpuconfig2_booke(int cpu) {	static const uint32_t handler[] = {		0x7c7043a6,		/* mtsprg0	%r3 */		0x7c7a02a6,		/* mfsrr0   %r3 */		0x38630004,		/* addi		%r3,%r3,4 */		0x7c7a03a6,		/* mtsrr0	%r3 */		0x7c7942a6,		/* mfsprg0	%r3 */		0x4c000064		/* rfi */	};			/*	   Point the exception registers to "safe" locations. The kernel	   will set these addresses to transfer to the unexpected exception	   routine.	*/	set_spr(PPCBKE_SPR_IVPR, 0);	/*		Install an illegal instruction exception handler that skips over		the instruction - this will let us set IVOR's that don't		exist on a particular chip.	*/	memmove(0, handler, sizeof(handler));	icache_flush(0); icache_flush(16);	set_spr(PPCBKE_SPR_IVOR6, 0);	set_ivor_range(IVOR_LIST_SPR(ivor48_63_list), 48 << 4, IVOR_LIST_NUM(ivor48_63_list));	set_ivor_range(IVOR_LIST_SPR(ivor32_47_list), 32 << 4, IVOR_LIST_NUM(ivor32_47_list));	set_ivor_range(PPCBKE_SPR_IVOR16, 16 << 4, 16);	/* have to do these _last_, since IVOR6 gets changed by it */	set_ivor_range(PPCBKE_SPR_IVOR0, 0 << 4, 16);	ppcbke_tlb_clean2(cpu);	// Get the debug control into a clean state	set_msr(get_msr() & ~PPC_MSR_DE);	set_spr(PPCBKE_SPR_DBSR, ~0);	set_spr(PPCBKE_SPR_DBCR0, PPCBKE_DBCR0_IDM | PPCBKE_DBCR0_ICMP);}

⌨️ 快捷键说明

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