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

📄 heathrow_pic.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
字号:
/*
 * Heathrow PIC support (OldWorld PowerMac)
 *
 * Copyright (c) 2005-2007 Fabrice Bellard
 * Copyright (c) 2007 Jocelyn Mayer
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "hw.h"
#include "ppc_mac.h"
#include "ppc.h"//debugger



//#define DEBUG

typedef struct HeathrowPIC{
    uint32_t SIUMCR;//debugger, no implement
	uint32_t SYPCR;//debugger, no implement
    uint32_t Reserved[2];	
    uint32_t SIPEND;/*used */
	uint32_t SIMASK;
	uint32_t SIEL;
	uint16_t SIVEC;//8 reg
	uint32_t reserved0[4];
	uint32_t emcr;//no implement,2fc030=12reg, 13 regs
    
    uint32_t reserved1[3];	
	
	uint32_t br0;//0x2fc100,debugger, no implement,16regs
    uint32_t or0;//2xfc104
	uint32_t br1;
	uint32_t or1;
		
	uint32_t br2;
    
	uint32_t or2;
	uint32_t br3;
	uint32_t or3;	 //24reg
	//debugger
	uint32_t reserved11[104];
	
	
	uint32_t TBSCR;//2fc200, 128regs

	uint32_t reserved2[7];
	uint32_t piscr;// no implement ,2fc240,144regs
	uint32_t reserverd3[7];
	uint32_t SCCR;//2fc280,160reg
	uint32_t PLPRCR;//2fc284,161regs ,162reg 
    uint32_t resererd4[30];
    uint32_t tbscrk;//192regs,2fc300,no implement
    uint32_t reserverd5[15];// reg	
    uint32_t piscrk;//2fc340,208,no implement
    uint32_t PITCK;//2fc344,no implement;
    uint32_t reseverd6[14];
	uint32_t sccrk;//debugger 2fc380,no implement 224regs

	uint32_t save[743];
}HeathrowPIC;//0x2fc000-0x300000 uisu

typedef struct HeathrowPIC_UIMB{
         	uint32_t umcr;//debugger,0x2307F80
            uint32_t reserved7[7];
            uint32_t UIPEND;//307FA0
            uint32_t reserverd6[23];
           }UIMB;


typedef struct HeathrowPICS {
    HeathrowPIC pics;
	UIMB pic_UIMB;
    qemu_irq *irqs;
} HeathrowPICS;

static inline void creat_decrement(HeathrowPIC *pic)
{
    if(pic->PLPRCR&0x400)//no 21 bit
    	{		
		switch(pic->SCCR&0x3)
		   {
			 case 0x0:
			 	cpu_ppc_set_DEC_clk(2);//Divide by 2
			 	break;
			 case 0x1:
			 	cpu_ppc_set_DEC_clk(4);//Divide by 4
			 	break;
			 case 0x2:
			 	cpu_ppc_set_DEC_clk(8);//Divide by 8
			 	break;
			 case 0x3:
			 	cpu_ppc_set_DEC_clk(16);//Divide by 16
			 	break;
			 case 0x4:
			 	cpu_ppc_set_DEC_clk(32);//Divide by 32
			 	break;
			 case 0x5:
			 	cpu_ppc_set_DEC_clk(64);//Divide by 64
			 	break;
			 case 0x6:
			 	printf("this is resever bit\n");
			 	break;
			 default:
			 	cpu_ppc_set_DEC_clk(256);//Divide by 256
			 	break;
		   }
	     }
    else
    	{
		
		switch((pic->SCCR&0x38)>>3)
		   {
			case 0x0:
			   //Divide by 1, 原来初始化时,已经设置了,无须在改变
			   break;
			case 0x1:
			   cpu_ppc_set_DEC_clk(2);//Divide by 2
			   break;
			case 0x2:
			   cpu_ppc_set_DEC_clk(4);//Divide by 4
			   break;
			case 0x3:
			   cpu_ppc_set_DEC_clk(8);//Divide by 8
			   break;
			case 0x4:
			   cpu_ppc_set_DEC_clk(16);//Divide by 16
			   break;
			case 0x5:
			   cpu_ppc_set_DEC_clk(32);//Divide by 32
			   break;
			case 0x6:
			   cpu_ppc_set_DEC_clk(64);//Divide by 64
			default:
			  printf("\n this is reserver bit\n");
			  break;		
		   }//switch
	    }
}



static inline int priority_arbiter(HeathrowPIC *pics)
{
   int priority=1;
   uint32_t mask=0x40000000;// sao miao piont;
   while(!(mask&pics->SIMASK&pics->SIPEND))
   	   {
          priority++;
		  mask=mask>>1;		  
       }
   return priority;
   
}


static inline int check_irq(HeathrowPIC *pic)
{
    return (pic->SIMASK&pic->SIPEND);
}

/* update the CPU irq state */
static void heathrow_pic_update(HeathrowPICS *s)
{
    if (check_irq(&(s->pics))) {
    int num=priority_arbiter(&(s->pics));//
	s->pics.SIVEC=(int)(num*4);//SIVEC=interrupt code;	
    qemu_irq_raise(s->irqs[0]);//通知处理器有外部中断发生
    } 
  
}
/*
 
static void heathrow_pic_update(HeathrowPICS *s)
{
    if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) {
        cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
    } else {
        cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
    }
}
*/


static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
{
    HeathrowPICS *s = opaque;
    HeathrowPIC *pic;
    
/* debugger
#ifdef TARGET_WORDS_BIGENDIAN
    value = bswap32(value);
#endif
*/
   
    //printf("pic_writel: " PADDRX " %u: %08x\n", addr, n, value);
    printf("call pic writel addr is %x\n", addr);//debugger
    pic= &(s->pics);	

    //语法规范不 
      
    switch(addr) 
	  {
	case 0x2FC000:
		pic->SIUMCR=value|pic->SIUMCR;//no implement
		break;
	case 0x2FC004:
		pic->SYPCR= value|pic->SYPCR;//no implement
		break;
    case 0x2FC010:
         pic->SIPEND= value|pic->SIPEND;
		 heathrow_pic_update(s);
         break;
    case 0x2FC014:
         pic->SIMASK=value|pic->SIMASK;		 
        break;
    case 0x2FC018:
	     pic->SIEL=value|pic->SIPEND;
	     break;
	case 0x2FC030:
		pic->emcr=value|pic->emcr;
		break;
    case 0x2FC100:
		pic->br0=value|pic->br0;
		break;
	case 0x2FC104:
		pic->or0=value|pic->or0;
		break;

	case 0x2FC200:
		pic->TBSCR= pic->TBSCR|value;
		if(pic->TBSCR&0x10000)//no 15 bit			
			creat_decrement(pic);//open dec,tb			
		break;

	case 0x2FC240:
		pic->piscr=value|pic->piscr;
		break;

    case 0x2FC280:
		 pic->SCCR=pic->SCCR|value;
		 break;
	case 0x2FC284:
		pic->PLPRCR=pic->PLPRCR|value;		
		break;
	case 0x2FC300:
		pic->tbscrk=pic->tbscrk|value;
		break;
	case 0x2FC340:
		pic->piscrk=pic->piscrk|value;
		break;
	case 0x2FC344:
		pic->PITCK=pic->PITCK|value;
		break;
	case 0x2FC380:
		pic->sccrk=pic->sccrk|value;
		break;
    case 0x307F80:
		s->pic_UIMB.umcr=s->pic_UIMB.umcr|value;
		break;
    case 0x307FA0:
		s->pic_UIMB.UIPEND=value|s->pic_UIMB.UIPEND;
		break;
    default:
	    printf("addr is error\n");
        break;
      }	

}


static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
{
    HeathrowPICS *s = opaque;
    HeathrowPIC *pic;
   
    uint32_t value=0;
    

    pic= &(s->pics);
   
    
     	  
    switch(addr) {//目标地址的低4位
    case 0x2FC000:
		value=pic->SIUMCR;//no implement
		break;
	case 0x2FC004:
		value=pic->SYPCR;//no implement
		break;
    case 0x2FC010:
        value=pic->SIPEND;       
        break;
    case 0x2FC014:
        value=pic->SIMASK;
        break;
    case 0x2FC018:
	    value=pic->SIEL;
		break;
	case 0x2FC030:
		value=pic->emcr;
		break;
	case 0x2FC100:
		value=pic->br0;
	    break;
	case 0x2FC104:
		value=pic->or0;
		break;
	case 0x2FC240:
		value=pic->piscr;
		break;
    case 0x2FC280:
	    value=pic->SCCR;
		break;
    case 0x2FC284:
	    value=pic->PLPRCR; 	 
		break;
	case 0x2FC300:
		value=pic->tbscrk;
		break;
		
	case 0x2FC340:
		pic->piscrk=value;
		break;
	case 0x2FC344:
		pic->PITCK=value;
		break;
	case 0x2FC380:
	    pic->sccrk=value;
		break;
	case 0x307F80:
        value=s->pic_UIMB.umcr;
		break;
	case 0x307FA0:
		value=s->pic_UIMB.UIPEND;
		break;
    default:
	    printf("addr is error\n");
        break;
      }/*switch*/  
  
#ifdef DEBUG
    printf("pic_readl: " PADDRX " %u: %08x\n", addr, n, value);
#endif
#ifdef TARGET_WORDS_BIGENDIAN
    value = bswap32(value);
#endif
    return value;
}

static uint32_t pic_readb (void *opaque, target_phys_addr_t addr)
{
	HeathrowPICS *s = opaque;	
	uint32_t value=0;
	
	HeathrowPIC *pic = &(s->pics);
	

  if(addr==0x2FC01C)
  	value=(uint32_t)(pic->SIVEC&0xFF000000);
  else
  	printf("addr is error ,not 0x2fc01c");

  return (value>>24);
  	
}


static CPUWriteMemoryFunc *HeathrowPIC_write[] = {
    &pic_writel,
    &pic_writel,
    &pic_writel,
};

static CPUReadMemoryFunc *HeathrowPIC_read[] = {
    &pic_readb,
    &pic_readl,
    &pic_readl,
};



static void NMI_control(int signal, HeathrowPICS *s)
{
 
  if(signal==0)
        qemu_irq_reset(s->irqs[0]);//通知处理器有外部中断发生
   else
  	 printf("vector is error");		//decif(signal==1) 	  
}
// send interrupt to pic.
static void heathrow_pic_set_irq(void *opaque, int num, int level)
{
    HeathrowPICS *s = opaque;
    HeathrowPIC *pic;
    
    uint32_t irq_bit;
    pic= &(s->pics);
    
	
#if defined(DEBUG)
    {
        static int last_level[64];//调试技术,为了看最后的level值
        if (last_level[num] != level) {
            printf("set_irq: num=0x%02x level=%d\n", num, level);
            last_level[num] = level;
        }
    }
#endif
    if(num==0)NMI_control(0,s);
	else
	{
         if(num%2==0)
         	{
              if(num<15)
              	{ 
              	irq_bit=0x80000000>>num;
              	pic->SIPEND=pic->SIPEND|irq_bit;
			    }
			  else
			  	{
                    irq_bit=0x80000000>>(num-8);
					pic->SIPEND=pic->SIPEND|0x4000;
				   s->pic_UIMB.UIPEND=s->pic_UIMB.UIPEND|irq_bit;
			    }
		    }
		 else
		 	{
              if(num>15)
              	{
              	  irq_bit=0x80000000>>(num-8);
				  pic->SIPEND=pic->SIPEND|0x4000;
				 s->pic_UIMB.UIPEND=s->pic_UIMB.UIPEND|irq_bit;
		         }
	          else
	  	       {
                  pic->SIPEND=pic->SIPEND|(0x80000000>>num);
		          irq_bit=0x80000000>>(num/2);
	              s->pic_UIMB.UIPEND=s->pic_UIMB.UIPEND|irq_bit;
	          }
	        }/*else--if(num%2==0)*/
         }
    heathrow_pic_update(s);
	
}

qemu_irq *heathrow_pic_init(int *pmem_index,
                            int nb_cpus, qemu_irq **irqs)
{
  
    HeathrowPICS *s;
	s=qemu_mallocz(sizeof(HeathrowPICS));
       /* only 1 CPU */
	
	      /*  register of pic initialized  */
	   s->irqs = irqs[0];
	   
	   s->pics.SIPEND=0x0;
	   s->pics.SIMASK=0x0;
	   s->pics.SIVEC=0x0;
	   s->pics.SIEL=0x0;
	   s->pic_UIMB.UIPEND=0x0;  
	   s->pics.TBSCR=0x0;
	   s->pics.SCCR=0x0;
	   s->pics.SYPCR=0x0;
	   s->pics.SIUMCR=0x0;
	   s->pics.PLPRCR=0x0;
	   s->pics.br0=0x0;//debugger no use and implement
	   s->pics.br1=0x0;
	   s->pics.br2=0x0;
	   s->pics.br3=0x0;
	   s->pics.piscr=0x0;
	   s->pics.piscrk=0x0;
	   s->pics.emcr=0x0;
	   s->pics.or0=0x0;
	   s->pics.or1=0x0;
	   s->pics.or2=0x0;
	   s->pics.or3=0x0;
	   s->pics.PITCK=0x0;
	   s->pics.tbscrk=0x0;
	   s->pics.sccrk=0x0;
	   s->pic_UIMB.umcr=0x0;
   
 *pmem_index = cpu_register_io_memory(0, HeathrowPIC_read, HeathrowPIC_write, s);
 unsigned long tmp,size;
 tmp=*pmem_index;

 
   size=sizeof(HeathrowPIC);
   cpu_register_physical_memory(0x2FC000, size, tmp); 
   printf("size is %d\n",size);//debugger
   size=sizeof(UIMB);
   cpu_register_physical_memory(0x307F80,size,tmp);//debugger,UIMB
   
return qemu_allocate_irqs(heathrow_pic_set_irq, s, 40);
}

⌨️ 快捷键说明

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