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

📄 pci_ide_bus.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "ide_bus.h"#include "pci_ide_bus.h"#include "ide_drive.h"#include <kernel/arch/cpu.h>#include <kernel/debug.h>#include <kernel/heap.h>#include <kernel/vfs.h>#include <kernel/sem.h>#include <kernel/int.h>#include <kernel/vm.h>#include <kernel/bus/bus.h>#include <kernel/bus/pci/pci_bus.h>#include <nulibc/string.h>#include <nulibc/stdarg.h>#define CB_DC_HD15   0x08  // bit should always be set to one#define CB_DC_SRST   0x04  // soft reset#define CB_DC_NIEN   0x02  // disable interrupts#define CB_DH_DEV0 0xa0    // select device 0#define CB_DH_DEV1 0xb0    // select device 1#define CB_STAT_BSY  0x80  // busy#define CB_STAT_RDY  0x40  // ready#define CB_STAT_DF   0x20  // device fault#define CB_STAT_WFT  0x20  // write fault (old name)#define CB_STAT_SKC  0x10  // seek complete#define CB_STAT_SERV 0x10  // service#define CB_STAT_DRQ  0x08  // data request#define CB_STAT_CORR 0x04  // corrected#define CB_STAT_IDX  0x02  // index#define CB_STAT_ERR  0x01  // error (ATA)#define CB_STAT_CHK  0x01  // check (ATAPI)#define DMA_SEL5 0x01#define DMA_SEL6 0x02#define DMA_SEL7 0x03#define DMA_TC5 0x02#define DMA_TC6 0x04#define DMA_TC7 0x08#define DMA_MODE_DEMAND 0x00     // modeByte bits for various dma modes#define DMA_MODE_BLOCK  0x80#define DMA_MODE_SINGLE 0x40#define DMA_MODE_MEMR 0x08       // modeByte memory read or write#define DMA_MODE_MEMW 0x04#define DMA_MASK_ENABLE  0x00    // bits for enable/disable#define DMA_MASK_DISABLE 0x04#define BM_COMMAND_REG    0            // offset to command reg#define BM_CR_MASK_READ    0x00           // read from memory#define BM_CR_MASK_WRITE   0x08           // write to memory#define BM_CR_MASK_START   0x01           // start transfer#define BM_CR_MASK_STOP    0x00           // stop transfer#define BM_STATUS_REG     2            // offset to status reg#define BM_SR_MASK_SIMPLEX 0x80           // simplex only#define BM_SR_MASK_DRV1    0x40           // drive 1 can do dma#define BM_SR_MASK_DRV0    0x20           // drive 0 can do dma#define BM_SR_MASK_INT     0x04           // INTRQ signal asserted#define BM_SR_MASK_ERR     0x02           // error#define BM_SR_MASK_ACT     0x01           // active#define BM_PRD_ADDR_LOW   4            // offset to prd addr reg low 16 bits#define BM_PRD_ADDR_HIGH  6            // offset to prd addr reg high 16 bitstypedef	struct{	uint32		address;	uint16		count;	uint8		reserved_1;	uint8 		reserved_2 : 7;	uint8 		eot : 1;}prd_entry;typedef	struct{	int		base_reg;	int		status_reg;	ide_drive	*drives[2];	void		*drive_cookie[2];	unsigned int	pio_reg_addrs[10];	region_id	prd_region_id;	int		channel;	bool		dma_supported;	sem_id		bus_semaphore;	int		io_port;	int		irq;	bool		busMasterActivated;	uint32		*prd_buf_address;	addr_t		prd_phy_address;	uint8		stat_reg;	uint8		rw_control;	uint8		*raw_buffer;	uint8		*mapped_address;	uint8		*current_dma;	uint32		current_dma_length;}pci_bus_cookie;//#define IDE_TRACE 0uint32		*tmp_buffer = (uint32*)0x80000;#if IDE_TRACE#define TRACE(x) dprintf x#else#define TRACE(x)#endifstatic int ide_interrupt_handler(void* data){  TRACE(("in ide interrupt handler %p\n",data));  pci_bus_cookie	*cookie = data;  TRACE(("drive = %p drive_cookie=%p\n",cookie->drives[0],cookie->drive_cookie[0]));  TRACE(("drive = %p drive_cookie=%p\n",cookie->drives[1],cookie->drive_cookie[1]));	if(cookie->drives[0]!=NULL)	{		if ( ( in8( cookie->io_port  + BM_STATUS_REG )& BM_SR_MASK_INT ))                                // done yet ?			cookie->drives[0]->signal_interrupt(cookie,cookie->drive_cookie[0]);	}	if(cookie->drives[1]!=NULL)	{		if ( ( in8( cookie->io_port  + BM_STATUS_REG )& BM_SR_MASK_INT ))                                // done yet ?  			cookie->drives[1]->signal_interrupt(cookie,cookie->drive_cookie[1]);  	}  return  INT_RESCHEDULE;}extern	void	init_ide_struct(int bus,int device,int partition_id);static	int	ide_raw_init(pci_bus_cookie *cookie){   cookie->pio_reg_addrs[ CB_DATA ] = cookie->base_reg + 0;  // 0   cookie->pio_reg_addrs[ CB_FR   ] = cookie->base_reg + 1;  // 1   cookie->pio_reg_addrs[ CB_SC   ] = cookie->base_reg + 2;  // 2   cookie->pio_reg_addrs[ CB_SN   ] = cookie->base_reg + 3;  // 3   cookie->pio_reg_addrs[ CB_CL   ] = cookie->base_reg + 4;  // 4   cookie->pio_reg_addrs[ CB_CH   ] = cookie->base_reg + 5;  // 5   cookie->pio_reg_addrs[ CB_DH   ] = cookie->base_reg + 6;  // 6   cookie->pio_reg_addrs[ CB_CMD  ] = cookie->base_reg + 7;  // 7   cookie->pio_reg_addrs[ CB_DC   ] = cookie->status_reg + 6;  // 8   cookie->pio_reg_addrs[ CB_DA   ] = cookie->status_reg + 7;  // 9   return 0;}#define	_INTEL_VENDORID		0x8086#define	_82371AB_DEVICE_ID	0x7111static	int	pci_init(pci_bus_cookie *cookie){	id_list 	*vendor_ids;	id_list 	*device_ids;	int 		err;	device 		dev;	int 		i,j;	int		fd;	struct pci_cfg 	cfg;	int		pp;	vendor_ids = kmalloc(sizeof(id_list) + sizeof(uint32));	vendor_ids->num_ids = 1;	vendor_ids->id[0] = _INTEL_VENDORID;	device_ids = kmalloc(sizeof(id_list) + sizeof(uint32));	device_ids->num_ids = 1;	device_ids->id[0] = _82371AB_DEVICE_ID;	err = bus_find_device(1, vendor_ids, device_ids, &dev);	if(err < 0)	{		TRACE(("unable to pci find controller\n"));		err = -1;		goto err;	}	fd = sys_open(dev.dev_path,STREAM_TYPE_DEVICE,0);	sys_ioctl(fd, PCI_DUMP_CFG, NULL, 0);	sys_ioctl(fd, PCI_GET_CFG, &cfg, sizeof(struct pci_cfg));	sys_close(fd);	cookie->io_port = dev.base[4];	cookie->busMasterActivated = /*(buffer[0x9] & 0x80)!=0*/true;	if(cookie->channel==0)	{		cookie->irq = 0x14;		cookie->base_reg = 0x1F0;		cookie->status_reg = 0x200 + cookie->base_reg;	}	else	{		cookie->irq = 0x15;		cookie->base_reg = 0x170;		cookie->status_reg = 0x200 + cookie->base_reg;	}	TRACE(("pci_init:irq=%X\n",cfg.irq));	TRACE(("pci_init:header=%X\n",cfg.header_type));	TRACE(("pci_init: found device at '%s'\n", dev.dev_path));	for(i=0; i<MAX_DEV_IO_RANGES; i++)	{		TRACE(("pci_init: found device at base '%X'\n", dev.base[i]));	}	TRACE(("pci_init: found device at irq '%X'\n", dev.irq));err:	kfree(vendor_ids);	kfree(device_ids);	return err;}static	uint8	read_register(void *cookie,int reg);static	int	init_dma(pci_bus_cookie *cookie){	addr_t	temp;	uint8	val = in8(cookie->io_port + BM_STATUS_REG );	TRACE(("entering init_dma status = %d\n",val));	if (!( val &( BM_SR_MASK_DRV1 | BM_SR_MASK_DRV0 )))	{      		TRACE(("BM_STATUS is wrong %d\n",val));      		return -1;      	}	cookie->prd_region_id = vm_create_anonymous_region(vm_get_kernel_aspace_id(), "ide_prd_buf", (void **)&cookie->prd_buf_address,							REGION_ADDR_ANY_ADDRESS, 4096, REGION_WIRING_WIRED_CONTIG, LOCK_KERNEL|LOCK_RW);   	cookie->stat_reg = in8( cookie->io_port +  + BM_STATUS_REG );   	cookie->stat_reg = cookie->stat_reg & 0xe0;	memset(cookie->prd_buf_address, 0, 4096);	vm_get_page_mapping(vm_get_kernel_aspace_id(), (addr_t)cookie->prd_buf_address, &cookie->prd_phy_address);	cookie->raw_buffer = (uint8*)0x80000;	vm_map_physical_memory(vm_get_kernel_aspace_id(), "test", (void *)&cookie->mapped_address, REGION_ADDR_ANY_ADDRESS,0x10000, LOCK_RW|LOCK_KERNEL, (addr_t)cookie->raw_buffer);	TRACE(("mapped address is %X\n",cookie->mapped_address));      	return 0;}static	int	init(int channel){	char 		temp[64];	pci_bus_cookie	*current_cookie = kmalloc(sizeof(pci_bus_cookie));	current_cookie->channel = channel;	pci_init(current_cookie);	//return -1;	bus_cookies[channel] = current_cookie;	current_cookie->dma_supported = true;	sprintf(temp, "pci_ide_sem%d", channel);	current_cookie->bus_semaphore =  sem_create(1, temp);    	if(current_cookie->bus_semaphore < 0)      	{		kfree(current_cookie);		return -1;      	}	TRACE(("trying to discover devices on channel %d\n",channel));	if(channel==0)	{		current_cookie->base_reg = 0x1f0;		current_cookie->status_reg = 0x3f0;	}	else	{		current_cookie->base_reg = 0x170;		current_cookie->status_reg = 0x370;	}	if(ide_raw_init(current_cookie)==0)	{		int	current_drive;		init_dma(current_cookie);		for(current_drive=0;current_drive<2;current_drive++)		{			int		i = 0;			current_cookie->drives[current_drive] = NULL;			TRACE(("trying to discover device %d/%d\n",channel,current_drive));			while(ide_drives[i]!=NULL)			{				void	*drive_cookie = ide_drives[i]->init_drive(&pci_bus,current_cookie,channel,current_drive);				if(drive_cookie!=NULL)				{					TRACE(("trying to discover device %d/%d is a %s\n",channel,current_drive,ide_drives[i]->device_name));					current_cookie->drives[current_drive] = ide_drives[i];					current_cookie->drive_cookie[current_drive] = drive_cookie;					init_ide_struct(channel,current_drive,-1);      					TRACE(("done discovering device\n"));    					TRACE(("Cookie for interrupt is %p\n",current_cookie));

⌨️ 快捷键说明

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