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

📄 mpc85xx.c

📁 qnx powerpc MPC8245的 BSP源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $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 <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <malloc.h>#include <unistd.h>#include <gulliver.h>#include <sys/mman.h>#include <inttypes.h>#include <signal.h>#include <setjmp.h>#include <fcntl.h>#include <sys/platform.h>#include <sys/rsrcdbmgr.h>#include <sys/slogcodes.h>#include <sys/slog.h>#include <hw/inout.h>#include "mpc85xx.h"#include <ppc/85xxintr.h>pdrvr_entry_t mpc85xx_entry = {	9,	mpc85xx_attach,	mpc85xx_detach,	mpc85xx_cnfg_bridge,	mpc85xx_read_cnfg,	mpc85xx_write_cnfg,	mpc85xx_special_cycle,	mpc85xx_map_irq,	mpc85xx_avail_irq_ads,	mpc85xx_map_addr};   typedef struct pci_window_structure { 	uint32_t	base_addr; 	uint32_t	size; 	uint32_t	length; } pci_window_t;uint32_t	mpc85xx_find_ccsr_info (){	struct	asinfo_entry  *asinfo;	int32_t	i, num;	num = _syspage_ptr->asinfo.entry_size / sizeof(*asinfo);	asinfo = SYSPAGE_ENTRY (asinfo);	for (i = 0; i < num; ++i) {		char *name;		name = __hwi_find_string (asinfo->name);		if (strcmp (name, "immr")) {			asinfo++;			continue;			}		return ((uint32_t) asinfo->start);		}	return (0);} uint32_t	mpc85xx_find_mem_info( uint32_t* mem_start, uint32_t* mem_size ){	struct	asinfo_entry  *asinfo;	int32_t	i, num;		num = _syspage_ptr->asinfo.entry_size / sizeof( *asinfo );	asinfo = SYSPAGE_ENTRY( asinfo );	for( i = 0; i < num; ++i ) {		char *name;		name = __hwi_find_string( asinfo->name );		if( strcmp( name, "ram" ) ) {			asinfo++;			continue;		}		*mem_start = ( uint32_t )asinfo->start;			*mem_size = ( uint32_t )asinfo->end - ( uint32_t )asinfo->start + 1; 			return 1;	}	return 0;}  int  mpc85xx_get_pci_window(char* base_reg_addr, char* attr_reg_addr, pci_window_t* pci_window_buf) { 	uint32_t	offset = 0x20; 	int		reg_count = 8; 	int		pci_count	=	0; 	uint32_t	attr_reg_val = 0x0; 	uint32_t	base_reg_val = 0x0; 	int		pci_index; 	int		loop_1, loop_2; 	uint32_t	temp_addr; 	uint32_t	temp_size; 	uint32_t	temp_length;        /* Search the LAW registers for an actively mapped PCI window. */	     for ( pci_index = 0; pci_index < reg_count; pci_index++ ) 	{ 		attr_reg_val = in32((uintptr_t)attr_reg_addr);		base_reg_val = in32((uintptr_t)base_reg_addr);		if ( attr_reg_val & 0x80000000 && !(attr_reg_val & 0x00f00000) ) 		{ 			pci_window_buf[pci_count].base_addr = base_reg_val << 12; 			pci_window_buf[pci_count].size = attr_reg_val & 0x0000003f; 			pci_window_buf[pci_count].length = 0x1 << (pci_window_buf[pci_count].size + 1); 			pci_count++; 		} 		attr_reg_addr += offset; 		base_reg_addr += offset; 	} 		/* Sort the PCI windows in terms of size.  The largest window will be		used for the memory space and the next largest for the I/O space. */ 	for ( loop_1 = pci_count; loop_1 > 1; loop_1-- ) 	{ 		for ( loop_2 = 0; loop_2 < loop_1-1; loop_2++ ) 		{ 			if ( pci_window_buf[loop_2].size < pci_window_buf[loop_2+1].size ) 			{ 				temp_addr = pci_window_buf[loop_2].base_addr; 				temp_size = pci_window_buf[loop_2].size; 				temp_length = pci_window_buf[loop_2].length; 				 				pci_window_buf[loop_2].base_addr = pci_window_buf[loop_2+1].base_addr; 				pci_window_buf[loop_2].size = pci_window_buf[loop_2+1].size; 				pci_window_buf[loop_2].length = pci_window_buf[loop_2+1].length; 				 				pci_window_buf[loop_2+1].base_addr = temp_addr; 				pci_window_buf[loop_2+1].size = temp_size; 				pci_window_buf[loop_2+1].length = temp_length; 			} 		} 	} 				 	return pci_count; }int		mpc85xx_seed(){	rsrc_alloc_t	ralloc;	// seed memory	ralloc.start	= 0x03ff0000;	ralloc.end		= 0xffffffff;	ralloc.flags	= RSRCDBMGR_MEMORY;	if (rsrcdbmgr_create(&ralloc, 1) == -1) {		perror("Unable to seed resource memory: ");		return ENOMEM;	}	// seed irqs	ralloc.start = 1;			ralloc.end	 = 30;	ralloc.flags = RSRCDBMGR_IRQ;	if (rsrcdbmgr_create(&ralloc, 1) == -1) {		perror("Unable to seed resource irqs: ");		return ENOMEM;	}	return EOK;}intmpc85xx_avail_irq_ads(void *hdl, uint32_t bus, uint32_t devfunc, uint32_t *list, uint32_t *nelm){	uint_t	dev;	uint_t  func;		dev = ( devfunc >> 3 ) & 0x1F;	func = devfunc & 0x07;		if(bus) {		slogf(_SLOGC_PCI, _SLOG_ERROR, "pci_server: Invalid bus %d, interrupt not assigned", bus);		*nelm = 0;		return (-1);	}			else { /* Irqs for Rev A  and Pilot board PCI devices. */		switch( dev ) {			case 18:  			case 12:					if(func==0) list[0] = PPC85xx_INTR_IRQ1;					if(func==1) list[0] = PPC85xx_INTR_IRQ2;					if(func==2) list[0] = PPC85xx_INTR_IRQ3;					if(func==3) list[0] = PPC85xx_INTR_IRQ4;					break;			case 19:			case 13:					if(func==0) list[0] = PPC85xx_INTR_IRQ4;					if(func==1) list[0] = PPC85xx_INTR_IRQ1;					if(func==2) list[0] = PPC85xx_INTR_IRQ2;					if(func==3) list[0] = PPC85xx_INTR_IRQ3;					break;			case 20:			case 14:     					if(func==0) list[0] = PPC85xx_INTR_IRQ3;					if(func==1) list[0] = PPC85xx_INTR_IRQ4;					if(func==2) list[0] = PPC85xx_INTR_IRQ1;					if(func==3) list[0] = PPC85xx_INTR_IRQ2;					break;			case 21: 			case 15:					if(func==0) list[0] = PPC85xx_INTR_IRQ2;					if(func==1) list[0] = PPC85xx_INTR_IRQ3;					if(func==2) list[0] = PPC85xx_INTR_IRQ4;					if(func==3) list[0] = PPC85xx_INTR_IRQ1;					break;			default: 					slogf(_SLOGC_PCI, _SLOG_ERROR, "pci_server: Invalid device %d, interrupt not assigned", dev);					*nelm = 0;					return (-1);		}									*nelm = 1;		return EOK;	}}	intmpc85xx_avail_irq_gen(void *hdl, uint32_t bus, uint32_t devfunc, uint32_t *list, uint32_t *nelm){	mpc85xx_dev_t *pdev = (mpc85xx_dev_t *)(hdl);	uint_t	dev;	uint_t  func;	dev = ( devfunc >> 3 ) & 0x1F;	func = devfunc & 0x07;	if (bus == 0) {		int dev_off = dev - pdev->devbase;		if ((dev_off >= 0) && (dev_off < MAX_SLOTS)) {			int irq_off;			if (pdev->irqrotate) {				irq_off = (func + dev_off) % MAX_SLOTS;			} else {				irq_off = func;			}			list[0] = pdev->irqbase + irq_off;			*nelm = 1;			return EOK;		} else {			slogf(_SLOGC_PCI, _SLOG_ERROR, "pci_server: Invalid device %d, interrupt not assigned", dev);		}	} else {			slogf(_SLOGC_PCI, _SLOG_ERROR, "pci_server: Invalid bus %d, interrupt not assigned", bus);	}		*nelm = 0;	return (-1);}	intmpc85xx_config(mpc85xx_dev_t *pdev, int auto_detect){	rsrc_request_t 	rreq;	rsrc_alloc_t	ralloc;  	pci_window_t	pci_windows[8]; 	int		pci_count = 0;  	uint32_t	temp, mem_cnt, mem_size; 	mpc85xx_seed();	memset ((char *) &rreq, 0, sizeof (rreq));	rreq.length = MPC85XX_PCI_REGISTER_LEN;	rreq.align = 0;	rreq.start = pdev->ccsr_base + MPC85XX_PCI_REGISTER_OFFSET;	rreq.end = rreq.start + MPC85XX_PCI_REGISTER_LEN;	rreq.flags = RSRCDBMGR_MEMORY;	if (rsrcdbmgr_attach(&rreq, 1)) {		perror("Unable to allocate PCI REGISTER memory space: ");		return ENOMEM;	}		pdev->pci_register_base = pdev->ccsr_base + MPC85XX_PCI_REGISTER_OFFSET;	if( ( pdev->register_base = mmap_device_memory( 0, MPC85XX_PCI_REGISTER_LEN, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, pdev->pci_register_base ) ) == MAP_FAILED ) {		perror( "Unable to mmap PCI CNF device memory: " );		return( ENODEV );	}		if ( auto_detect ) 	{ 		if( ( pdev->law_register_base = mmap_device_memory( 0, MPC85XX_LAW_REGISTER_LEN, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, pdev->ccsr_base + MPC85XX_LAW_REGISTER_OFFSET ) ) == MAP_FAILED ) 		{			perror( "Unable to mmap LAW device memory: " );			return( ENODEV );		}		pci_count = mpc85xx_get_pci_window( pdev->law_register_base, pdev->law_register_base+0x8,  pci_windows); 		munmap_device_memory(pdev->law_register_base, MPC85XX_LAW_REGISTER_LEN);				if ( pci_count <= 0 ) 		{ 			perror("No PCI window allocated: "); 			return( ENODEV); 		}  		if ( pci_count == 1 ) 		{ 			pci_windows[0].size -= 1; 			pci_windows[0].length /= 2; 			pci_windows[1].base_addr = pci_windows[0].base_addr + pci_windows[0].length; 			pci_windows[1].size = pci_windows[0].size; 			pci_windows[1].length = pci_windows[0].length; 

⌨️ 快捷键说明

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