Revision 47103572

b/cpu-exec.c
256 256
#elif defined(TARGET_PPC)
257 257
    if (env1->halted) {
258 258
        if (env1->msr[MSR_EE] && 
259
            (env1->interrupt_request & 
260
             (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) {
259
            (env1->interrupt_request & CPU_INTERRUPT_HARD)) {
261 260
            env1->halted = 0;
262 261
        } else {
263 262
            return EXCP_HALTED;
......
448 447
                        cpu_ppc_reset(env);
449 448
                    }
450 449
#endif
451
                    if (msr_ee != 0) {
452
                        if ((interrupt_request & CPU_INTERRUPT_HARD)) {
453
			    /* Raise it */
454
			    env->exception_index = EXCP_EXTERNAL;
455
			    env->error_code = 0;
456
                            do_interrupt(env);
457
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
458
#if defined(__sparc__) && !defined(HOST_SOLARIS)
459
                            tmp_T0 = 0;
460
#else
461
                            T0 = 0;
462
#endif
463
                        } else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {
464
                            /* Raise it */
465
                            env->exception_index = EXCP_DECR;
466
                            env->error_code = 0;
467
                            do_interrupt(env);
468
                            env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
450
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
451
                        if (ppc_hw_interrupt(env) == 1) {
452
                            /* Some exception was raised */
453
                            if (env->pending_interrupts == 0)
454
                                env->interrupt_request &= ~CPU_INTERRUPT_HARD;
469 455
#if defined(__sparc__) && !defined(HOST_SOLARIS)
470 456
                            tmp_T0 = 0;
471 457
#else
b/hw/openpic.c
164 164

  
165 165
struct openpic_t {
166 166
    PCIDevice pci_dev;
167
    SetIRQFunc *set_irq;
167 168
    int mem_index;
168 169
    /* Global registers */
169 170
    uint32_t frep; /* Feature reporting register */
......
264 265
    IRQ_setbit(&dst->raised, n_IRQ);
265 266
    if (priority > dst->raised.priority) {
266 267
        IRQ_get_next(opp, &dst->raised);
267
        DPRINTF("Raise CPU IRQ\n");
268
        cpu_interrupt(dst->env, CPU_INTERRUPT_HARD);
268
        DPRINTF("Raise CPU IRQ fn %p env %p\n", opp->set_irq, dst->env);
269
        opp->set_irq(dst->env, OPENPIC_EVT_INT, 1);
269 270
    }
270 271
}
271 272

  
......
532 533
        /* XXX: Should be able to reset any CPU */
533 534
        if (val & 1) {
534 535
            DPRINTF("Reset CPU IRQ\n");
535
            //            cpu_interrupt(first_cpu, CPU_INTERRUPT_RESET);
536
            //                opp->set_irq(dst->env, OPENPIC_EVT_RESET, 1);
536 537
        }
537 538
	break;
538 539
#if MAX_IPI > 0
......
781 782
	    src = &opp->src[n_IRQ];
782 783
	    if (IPVP_PRIORITY(src->ipvp) > dst->servicing.priority) {
783 784
                DPRINTF("Raise CPU IRQ\n");
784
                cpu_interrupt(dst->env, CPU_INTERRUPT_HARD);
785
                opp->set_irq(dst->env, OPENPIC_EVT_INT, 1);
785 786
            }
786 787
	}
787 788
	break;
......
963 964
#endif
964 965
}
965 966

  
966
openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
967
                         CPUPPCState **envp)
967
openpic_t *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
968
                         int *pmem_index, int nb_cpus, CPUPPCState **envp)
968 969
{
969 970
    openpic_t *opp;
970 971
    uint8_t *pci_conf;
......
994 995
    } else {
995 996
        opp = qemu_mallocz(sizeof(openpic_t));
996 997
    }
997

  
998
    opp->set_irq = set_irq;
998 999
    opp->mem_index = cpu_register_io_memory(0, openpic_read,
999 1000
                                            openpic_write, opp);
1000 1001
    
b/hw/ppc.c
24 24
#include "vl.h"
25 25
#include "m48t59.h"
26 26

  
27
extern FILE *logfile;
28
extern int loglevel;
29

  
30
/*****************************************************************************/
31
/* PowerPC internal fake IRQ controller
32
 * used to manage multiple sources hardware events
33
 */
34
/* XXX: should be protected */
35
void ppc_set_irq (void *opaque, int n_IRQ, int level)
36
{
37
    CPUState *env;
38

  
39
    env = opaque;
40
    if (level) {
41
        env->pending_interrupts |= 1 << n_IRQ;
42
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
43
    } else {
44
        env->pending_interrupts &= ~(1 << n_IRQ);
45
        if (env->pending_interrupts == 0)
46
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
47
    }
48
#if 0
49
    printf("%s: %p n_IRQ %d level %d => pending %08x req %08x\n", __func__,
50
           env, n_IRQ, level, env->pending_interrupts, env->interrupt_request);
51
#endif
52
}
53

  
54
/* External IRQ callback from OpenPIC IRQ controller */
55
void ppc_openpic_irq (void *opaque, int n_IRQ, int level)
56
{
57
    switch (n_IRQ) {
58
    case OPENPIC_EVT_INT:
59
        n_IRQ = PPC_INTERRUPT_EXT;
60
        break;
61
    case OPENPIC_EVT_CINT:
62
        /* On PowerPC BookE, critical input use vector 0 */
63
        n_IRQ = PPC_INTERRUPT_RESET;
64
        break;
65
    case OPENPIC_EVT_MCK:
66
        n_IRQ = PPC_INTERRUPT_MCK;
67
        break;
68
    case OPENPIC_EVT_DEBUG:
69
        n_IRQ = PPC_INTERRUPT_DEBUG;
70
        break;
71
    case OPENPIC_EVT_RESET:
72
        qemu_system_reset_request();
73
        return;
74
    }
75
    ppc_set_irq(opaque, n_IRQ, level);
76
}
77

  
27 78
/*****************************************************************************/
28 79
/* PPC time base and decrementer emulation */
29 80
//#define DEBUG_TB
......
35 86
    /* Decrementer management */
36 87
    uint64_t decr_next;    /* Tick for next decr interrupt  */
37 88
    struct QEMUTimer *decr_timer;
89
    void *opaque;
38 90
};
39 91

  
40 92
static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
......
131 183
#ifdef DEBUG_TB
132 184
    printf("raise decrementer exception\n");
133 185
#endif
134
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
186
    ppc_set_irq(env, PPC_INTERRUPT_DECR, 1);
135 187
}
136 188

  
137 189
static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
b/hw/ppc_chrp.c
1 1
/*
2 2
 * QEMU PPC CHRP/PMAC hardware System Emulator
3 3
 * 
4
 * Copyright (c) 2004 Fabrice Bellard
4
 * Copyright (c) 2004-2007 Fabrice Bellard
5 5
 * 
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
......
449 449
        }
450 450

  
451 451
        macio_init(pci_bus, 0x0017);
452
        
452

  
453 453
        nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
454
        
454

  
455 455
        arch_name = "HEATHROW";
456 456
    } else {
457 457
        isa_mem_base = 0x80000000;
458
        
458

  
459 459
        /* Register 8 MB of ISA IO space */
460 460
        isa_mmio_init(0xf2000000, 0x00800000);
461
        
461

  
462 462
        /* UniN init */
463 463
        unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
464 464
        cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
465 465

  
466
        pic = openpic_init(NULL, &openpic_mem_index, 1, &env);
466
        pic = openpic_init(NULL, &ppc_openpic_irq, &openpic_mem_index, 1, &env);
467 467
        set_irq = openpic_set_irq;
468 468
        pci_bus = pci_pmac_init(pic);
469 469
        /* init basic PC hardware */
b/hw/ppc_prep.c
1 1
/*
2 2
 * QEMU PPC PREP hardware System Emulator
3 3
 * 
4
 * Copyright (c) 2003-2004 Jocelyn Mayer
4
 * Copyright (c) 2003-2007 Jocelyn Mayer
5 5
 * 
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
......
84 84
#endif
85 85
}
86 86

  
87
static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
87
static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
88 88
{
89 89
#if 0
90 90
    int out;
91 91
    out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
92 92
    dummy_refresh_clock ^= 1;
93 93
    return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
94
      (dummy_refresh_clock << 4);
94
        (dummy_refresh_clock << 4);
95 95
#endif
96 96
    return 0;
97 97
}
98 98

  
99
static void pic_irq_request(void *opaque, int level)
99
static void pic_irq_request (void *opaque, int level)
100 100
{
101
    if (level)
102
        cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
103
    else
104
        cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
101
    ppc_set_irq(opaque, PPC_INTERRUPT_EXT, level);
105 102
}
106 103

  
107 104
/* PCI intack register */
108 105
/* Read-only register (?) */
109
static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value)
106
static void _PPC_intack_write (void *opaque,
107
                               target_phys_addr_t addr, uint32_t value)
110 108
{
111 109
    //    printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
112 110
}
......
294 292
        /* Special port 92 */
295 293
        /* Check soft reset asked */
296 294
        if (val & 0x01) {
297
            //            cpu_interrupt(first_cpu, CPU_INTERRUPT_RESET);
295
            //            cpu_interrupt(first_cpu, PPC_INTERRUPT_RESET);
298 296
        }
299 297
        /* Check LE mode */
300 298
        if (val & 0x02) {
b/target-ppc/cpu.h
740 740
    int exception_index;
741 741
    int error_code;
742 742
    int interrupt_request;
743
    uint32_t pending_interrupts;
743 744

  
744 745
    /* Those resources are used only during code translation */
745 746
    /* Next instruction pointer */
......
1267 1268
    EXCP_TRAP          = 0x40,
1268 1269
};
1269 1270

  
1271
/* Hardware interruption sources:
1272
 * all those exception can be raised simulteaneously
1273
 */
1274
enum {
1275
    PPC_INTERRUPT_RESET  = 0, /* Reset / critical input               */
1276
    PPC_INTERRUPT_MCK    = 1, /* Machine check exception              */
1277
    PPC_INTERRUPT_EXT    = 2, /* External interrupt                   */
1278
    PPC_INTERRUPT_DECR   = 3, /* Decrementer exception                */
1279
    PPC_INTERRUPT_HDECR  = 4, /* Hypervisor decrementer exception     */
1280
    PPC_INTERRUPT_PIT    = 5, /* Programmable inteval timer interrupt */
1281
    PPC_INTERRUPT_FIT    = 6, /* Fixed interval timer interrupt       */
1282
    PPC_INTERRUPT_WDT    = 7, /* Watchdog timer interrupt             */
1283
    PPC_INTERRUPT_DEBUG  = 8, /* External debug exception             */
1284
};
1285

  
1270 1286
/*****************************************************************************/
1271 1287

  
1272 1288
#endif /* !defined (__CPU_PPC_H__) */
b/target-ppc/helper.c
1229 1229
{
1230 1230
    env->exception_index = -1;
1231 1231
}
1232

  
1233
int ppc_hw_interrupt (CPUState *env)
1234
{
1235
    env->exception_index = -1;
1236

  
1237
    return 0;
1238
}
1232 1239
#else /* defined (CONFIG_USER_ONLY) */
1233 1240
static void dump_syscall(CPUState *env)
1234 1241
{
......
1753 1760
    env->nip = excp;
1754 1761
    env->exception_index = EXCP_NONE;
1755 1762
}
1763

  
1764
int ppc_hw_interrupt (CPUState *env)
1765
{
1766
    int raised = 0;
1767

  
1768
#if 0
1769
    printf("%s: %p pending %08x req %08x %08x me %d ee %d\n",
1770
           __func__, env, env->pending_interrupts,
1771
           env->interrupt_request, interrupt_request,
1772
           msr_me, msr_ee);
1773
#endif
1774
    /* Raise it */
1775
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
1776
        /* External reset / critical input */
1777
        env->exception_index = EXCP_RESET;
1778
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
1779
        raised = 1;
1780
    }
1781
    if (raised == 0 && msr_me != 0) {
1782
        /* Machine check exception */
1783
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
1784
            env->exception_index = EXCP_MACHINE_CHECK;
1785
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
1786
            raised = 1;
1787
        }
1788
    }
1789
    if (raised == 0 && msr_ee != 0) {
1790
#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
1791
        /* Hypervisor decrementer exception */
1792
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
1793
            env->exception_index = EXCP_HDECR;
1794
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
1795
            raised = 1;
1796
        } else
1797
#endif
1798
        /* Decrementer exception */
1799
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
1800
            env->exception_index = EXCP_DECR;
1801
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
1802
            raised = 1;
1803
        /* Programmable interval timer on embedded PowerPC */
1804
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
1805
            env->exception_index = EXCP_40x_PIT;
1806
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
1807
            raised = 1;
1808
        /* Fixed interval timer on embedded PowerPC */
1809
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
1810
            env->exception_index = EXCP_40x_FIT;
1811
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
1812
            raised = 1;
1813
        /* Watchdog timer on embedded PowerPC */
1814
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
1815
            env->exception_index = EXCP_40x_WATCHDOG;
1816
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
1817
            raised = 1;
1818
        /* External interrupt */
1819
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
1820
            env->exception_index = EXCP_EXTERNAL;
1821
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
1822
            raised = 1;
1823
        }
1824
#if 0 // TODO
1825
    /* External debug exception */
1826
    } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
1827
        env->exception_index = EXCP_xxx;
1828
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
1829
        raised = 1;
1830
#endif
1831
    }
1832
    if (raised != 0) {
1833
        env->error_code = 0;
1834
        do_interrupt(env);
1835
    }
1836
    
1837
    return raised;
1838
}
1756 1839
#endif /* !CONFIG_USER_ONLY */
b/vl.h
852 852

  
853 853
/* openpic.c */
854 854
typedef struct openpic_t openpic_t;
855
enum {
856
    OPENPIC_EVT_INT = 0, /* IRQ                       */
857
    OPENPIC_EVT_CINT,    /* critical IRQ              */
858
    OPENPIC_EVT_MCK,     /* Machine check event       */
859
    OPENPIC_EVT_DEBUG,   /* Inconditional debug event */
860
    OPENPIC_EVT_RESET,   /* Core reset event          */
861
};
855 862
void openpic_set_irq(void *opaque, int n_IRQ, int level);
856
openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
857
                         CPUState **envp);
863
openpic_t *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
864
                         int *pmem_index, int nb_cpus, CPUPPCState **envp);
858 865

  
859 866
/* heathrow_pic.c */
860 867
typedef struct HeathrowPICS HeathrowPICS;
......
1115 1122
extern QEMUMachine shix_machine;
1116 1123

  
1117 1124
#ifdef TARGET_PPC
1125
/* PowerPC hardware exceptions management helpers */
1126
void ppc_set_irq (void *opaque, int n_IRQ, int level);
1127
void ppc_openpic_irq (void *opaque, int n_IRQ, int level);
1128
int ppc_hw_interrupt (CPUState *env);
1118 1129
ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
1119 1130
#endif
1120 1131
void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);

Also available in: Unified diff