📄 heathrow_pic.c.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 + -