Revision e9df014c hw/ppc.c

b/hw/ppc.c
1 1
/*
2
 * QEMU generic PPC hardware System Emulator
2
 * QEMU generic PowerPC hardware System Emulator
3 3
 * 
4 4
 * Copyright (c) 2003-2007 Jocelyn Mayer
5 5
 * 
......
24 24
#include "vl.h"
25 25
#include "m48t59.h"
26 26

  
27
//#define PPC_DEBUG_IRQ
28

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

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

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

  
53
void cpu_ppc_irq_init_cpu(CPUState *env)
48
/* PowerPC 6xx / 7xx internal IRQ controller */
49
static void ppc6xx_set_irq (void *opaque, int pin, int level)
54 50
{
55
    qemu_irq *qi;
56
    int i;
51
    CPUState *env = opaque;
52
    int cur_level;
57 53

  
58
    qi = qemu_allocate_irqs(ppc_set_irq, env, 32);
59
    for (i = 0; i < 32; i++) {
60
        env->irq[i] = qi[i];
54
#if defined(PPC_DEBUG_IRQ)
55
    printf("%s: env %p pin %d level %d\n", __func__, env, pin, level);
56
#endif
57
    cur_level = (env->irq_input_state >> pin) & 1;
58
    /* Don't generate spurious events */
59
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0) || 0) {
60
        switch (pin) {
61
        case PPC_INPUT_INT:
62
            /* Level sensitive - asserted high */
63
#if defined(PPC_DEBUG_IRQ)
64
            printf("%s: set the external IRQ state to %d\n", __func__, level);
65
#endif
66
            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
67
            break;
68
        case PPC_INPUT_SMI:
69
            /* Level sensitive - active high */
70
#if defined(PPC_DEBUG_IRQ)
71
            printf("%s: set the SMI IRQ state to %d\n", __func__, level);
72
#endif
73
            ppc_set_irq(env, PPC_INTERRUPT_SMI, level);
74
            break;
75
        case PPC_INPUT_MCP:
76
            /* Negative edge sensitive */
77
            /* XXX: TODO: actual reaction may depends on HID0 status
78
             *            603/604/740/750: check HID0[EMCP]
79
             */
80
            if (cur_level == 1 && level == 0) {
81
#if defined(PPC_DEBUG_IRQ)
82
                printf("%s: raise machine check state\n", __func__);
83
#endif
84
                ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
85
            }
86
            break;
87
        case PPC_INPUT_CKSTP_IN:
88
            /* Level sensitive - active low */
89
            /* XXX: TODO: relay the signal to CKSTP_OUT pin */
90
            if (level) {
91
#if defined(PPC_DEBUG_IRQ)
92
                printf("%s: stop the CPU\n", __func__);
93
#endif
94
                env->halted = 1;
95
            } else {
96
#if defined(PPC_DEBUG_IRQ)
97
                printf("%s: restart the CPU\n", __func__);
98
#endif
99
                env->halted = 0;
100
            }
101
            break;
102
        case PPC_INPUT_HRESET:
103
            /* Level sensitive - active low */
104
            if (level) {
105
#if 0 // XXX: TOFIX
106
#if defined(PPC_DEBUG_IRQ)
107
                printf("%s: reset the CPU\n", __func__);
108
#endif
109
                cpu_reset(env);
110
#endif
111
            }
112
            break;
113
        case PPC_INPUT_SRESET:
114
#if defined(PPC_DEBUG_IRQ)
115
            printf("%s: set the RESET IRQ state to %d\n", __func__, level);
116
#endif
117
            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
118
            break;
119
        default:
120
            /* Unknown pin - do nothing */
121
#if defined(PPC_DEBUG_IRQ)
122
            printf("%s: unknown IRQ pin %d\n", __func__, pin);
123
#endif
124
            return;
125
        }
126
        if (level)
127
            env->irq_input_state |= 1 << pin;
128
        else
129
            env->irq_input_state &= ~(1 << pin);
61 130
    }
62 131
}
63 132

  
64
/* External IRQ callback from OpenPIC IRQ controller */
65
void ppc_openpic_irq (void *opaque, int n_IRQ, int level)
133
void ppc6xx_irq_init (CPUState *env)
66 134
{
67
    switch (n_IRQ) {
68
    case OPENPIC_EVT_INT:
69
        n_IRQ = PPC_INTERRUPT_EXT;
70
        break;
71
    case OPENPIC_EVT_CINT:
72
        /* On PowerPC BookE, critical input use vector 0 */
73
        n_IRQ = PPC_INTERRUPT_RESET;
74
        break;
75
    case OPENPIC_EVT_MCK:
76
        n_IRQ = PPC_INTERRUPT_MCK;
77
        break;
78
    case OPENPIC_EVT_DEBUG:
79
        n_IRQ = PPC_INTERRUPT_DEBUG;
80
        break;
81
    case OPENPIC_EVT_RESET:
82
        qemu_system_reset_request();
83
        return;
84
    }
85
    ppc_set_irq(opaque, n_IRQ, level);
135
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6);
86 136
}
87 137

  
88 138
/*****************************************************************************/
89
/* PPC time base and decrementer emulation */
139
/* PowerPC time base and decrementer emulation */
90 140
//#define DEBUG_TB
91 141

  
92 142
struct ppc_tb_t {

Also available in: Unified diff