~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/sun4u.c

  • Committer: ths
  • Date: 2007-10-08 12:45:38 UTC
  • Revision ID: git-v1:450d4ff553af32fc9d83fef20d7106b0151526b8
CRIS disassembler, originally from binutils, by Edgar E. Iglesias.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3356 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * QEMU Sun4u/Sun4v System Emulator
 
2
 * QEMU Sun4u System Emulator
3
3
 *
4
4
 * Copyright (c) 2005 Fabrice Bellard
5
5
 *
21
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
 * THE SOFTWARE.
23
23
 */
24
 
#include "hw.h"
25
 
#include "pci.h"
26
 
#include "pc.h"
27
 
#include "nvram.h"
28
 
#include "fdc.h"
29
 
#include "net.h"
30
 
#include "qemu-timer.h"
31
 
#include "sysemu.h"
32
 
#include "boards.h"
33
 
#include "firmware_abi.h"
34
 
#include "fw_cfg.h"
35
 
 
36
 
//#define DEBUG_IRQ
37
 
 
38
 
#ifdef DEBUG_IRQ
39
 
#define DPRINTF(fmt, args...)                           \
40
 
    do { printf("CPUIRQ: " fmt , ##args); } while (0)
41
 
#else
42
 
#define DPRINTF(fmt, args...)
43
 
#endif
 
24
#include "vl.h"
 
25
#include "m48t59.h"
44
26
 
45
27
#define KERNEL_LOAD_ADDR     0x00404000
46
28
#define CMDLINE_ADDR         0x003ff000
47
29
#define INITRD_LOAD_ADDR     0x00300000
48
 
#define PROM_SIZE_MAX        (4 * 1024 * 1024)
 
30
#define PROM_SIZE_MAX        (512 * 1024)
 
31
#define PROM_ADDR            0x1fff0000000ULL
49
32
#define PROM_VADDR           0x000ffd00000ULL
50
33
#define APB_SPECIAL_BASE     0x1fe00000000ULL
51
34
#define APB_MEM_BASE         0x1ff00000000ULL
52
35
#define VGA_BASE             (APB_MEM_BASE + 0x400000ULL)
53
36
#define PROM_FILENAME        "openbios-sparc64"
54
37
#define NVRAM_SIZE           0x2000
55
 
#define MAX_IDE_BUS          2
56
 
#define BIOS_CFG_IOPORT      0x510
57
 
 
58
 
#define MAX_PILS 16
59
 
 
60
 
struct hwdef {
61
 
    const char * const default_cpu_model;
62
 
    uint16_t machine_id;
63
 
    uint64_t prom_addr;
64
 
    uint64_t console_serial_base;
65
 
};
 
38
 
 
39
/* TSC handling */
 
40
 
 
41
uint64_t cpu_get_tsc()
 
42
{
 
43
    return qemu_get_clock(vm_clock);
 
44
}
66
45
 
67
46
int DMA_get_channel_mode (int nchan)
68
47
{
79
58
void DMA_hold_DREQ (int nchan) {}
80
59
void DMA_release_DREQ (int nchan) {}
81
60
void DMA_schedule(int nchan) {}
 
61
void DMA_run (void) {}
82
62
void DMA_init (int high_page_enable) {}
83
63
void DMA_register_channel (int nchan,
84
64
                           DMA_transfer_handler transfer_handler,
86
66
{
87
67
}
88
68
 
89
 
static int nvram_boot_set(void *opaque, const char *boot_device)
90
 
{
91
 
    unsigned int i;
92
 
    uint8_t image[sizeof(ohwcfg_v3_t)];
93
 
    ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ
94
 
    m48t59_t *nvram = (m48t59_t *)opaque;
95
 
 
96
 
    for (i = 0; i < sizeof(image); i++)
97
 
        image[i] = m48t59_read(nvram, i) & 0xff;
98
 
 
99
 
    pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices),
100
 
            boot_device);
101
 
    header->nboot_devices = strlen(boot_device) & 0xff;
102
 
    header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
103
 
 
104
 
    for (i = 0; i < sizeof(image); i++)
105
 
        m48t59_write(nvram, i, image[i]);
106
 
 
107
 
    return 0;
108
 
}
109
 
 
110
 
static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
111
 
                                   const char *arch,
112
 
                                   ram_addr_t RAM_size,
113
 
                                   const char *boot_devices,
114
 
                                   uint32_t kernel_image, uint32_t kernel_size,
115
 
                                   const char *cmdline,
116
 
                                   uint32_t initrd_image, uint32_t initrd_size,
117
 
                                   uint32_t NVRAM_image,
118
 
                                   int width, int height, int depth,
119
 
                                   const uint8_t *macaddr)
120
 
{
 
69
/* NVRAM helpers */
 
70
void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
 
71
{
 
72
    m48t59_write(nvram, addr, value);
 
73
}
 
74
 
 
75
uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
 
76
{
 
77
    return m48t59_read(nvram, addr);
 
78
}
 
79
 
 
80
void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
 
81
{
 
82
    m48t59_write(nvram, addr, value >> 8);
 
83
    m48t59_write(nvram, addr + 1, value & 0xFF);
 
84
}
 
85
 
 
86
uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
 
87
{
 
88
    uint16_t tmp;
 
89
 
 
90
    tmp = m48t59_read(nvram, addr) << 8;
 
91
    tmp |= m48t59_read(nvram, addr + 1);
 
92
 
 
93
    return tmp;
 
94
}
 
95
 
 
96
void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
 
97
{
 
98
    m48t59_write(nvram, addr, value >> 24);
 
99
    m48t59_write(nvram, addr + 1, (value >> 16) & 0xFF);
 
100
    m48t59_write(nvram, addr + 2, (value >> 8) & 0xFF);
 
101
    m48t59_write(nvram, addr + 3, value & 0xFF);
 
102
}
 
103
 
 
104
uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
 
105
{
 
106
    uint32_t tmp;
 
107
 
 
108
    tmp = m48t59_read(nvram, addr) << 24;
 
109
    tmp |= m48t59_read(nvram, addr + 1) << 16;
 
110
    tmp |= m48t59_read(nvram, addr + 2) << 8;
 
111
    tmp |= m48t59_read(nvram, addr + 3);
 
112
 
 
113
    return tmp;
 
114
}
 
115
 
 
116
void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
 
117
                       const unsigned char *str, uint32_t max)
 
118
{
 
119
    int i;
 
120
 
 
121
    for (i = 0; i < max && str[i] != '\0'; i++) {
 
122
        m48t59_write(nvram, addr + i, str[i]);
 
123
    }
 
124
    m48t59_write(nvram, addr + max - 1, '\0');
 
125
}
 
126
 
 
127
int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
 
128
{
 
129
    int i;
 
130
 
 
131
    memset(dst, 0, max);
 
132
    for (i = 0; i < max; i++) {
 
133
        dst[i] = NVRAM_get_byte(nvram, addr + i);
 
134
        if (dst[i] == '\0')
 
135
            break;
 
136
    }
 
137
 
 
138
    return i;
 
139
}
 
140
 
 
141
static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
 
142
{
 
143
    uint16_t tmp;
 
144
    uint16_t pd, pd1, pd2;
 
145
 
 
146
    tmp = prev >> 8;
 
147
    pd = prev ^ value;
 
148
    pd1 = pd & 0x000F;
 
149
    pd2 = ((pd >> 4) & 0x000F) ^ pd1;
 
150
    tmp ^= (pd1 << 3) | (pd1 << 8);
 
151
    tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
 
152
 
 
153
    return tmp;
 
154
}
 
155
 
 
156
uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
 
157
{
 
158
    uint32_t i;
 
159
    uint16_t crc = 0xFFFF;
 
160
    int odd;
 
161
 
 
162
    odd = count & 1;
 
163
    count &= ~1;
 
164
    for (i = 0; i != count; i++) {
 
165
        crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
 
166
    }
 
167
    if (odd) {
 
168
        crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
 
169
    }
 
170
 
 
171
    return crc;
 
172
}
 
173
 
 
174
static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr,
 
175
                                const unsigned char *str)
 
176
{
 
177
    uint32_t len;
 
178
 
 
179
    len = strlen(str) + 1;
 
180
    NVRAM_set_string(nvram, addr, str, len);
 
181
 
 
182
    return addr + len;
 
183
}
 
184
 
 
185
static void nvram_finish_partition (m48t59_t *nvram, uint32_t start,
 
186
                                    uint32_t end)
 
187
{
 
188
    unsigned int i, sum;
 
189
 
 
190
    // Length divided by 16
 
191
    m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff);
 
192
    m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff);
 
193
    // Checksum
 
194
    sum = m48t59_read(nvram, start);
 
195
    for (i = 0; i < 14; i++) {
 
196
        sum += m48t59_read(nvram, start + 2 + i);
 
197
        sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
 
198
    }
 
199
    m48t59_write(nvram, start + 1, sum & 0xff);
 
200
}
 
201
 
 
202
extern int nographic;
 
203
 
 
204
int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
 
205
                          const unsigned char *arch,
 
206
                          uint32_t RAM_size, int boot_device,
 
207
                          uint32_t kernel_image, uint32_t kernel_size,
 
208
                          const char *cmdline,
 
209
                          uint32_t initrd_image, uint32_t initrd_size,
 
210
                          uint32_t NVRAM_image,
 
211
                          int width, int height, int depth)
 
212
{
 
213
    uint16_t crc;
121
214
    unsigned int i;
122
215
    uint32_t start, end;
123
 
    uint8_t image[0x1ff0];
124
 
    ohwcfg_v3_t *header = (ohwcfg_v3_t *)&image;
125
 
    struct sparc_arch_cfg *sparc_header;
126
 
    struct OpenBIOS_nvpart_v1 *part_header;
127
 
 
128
 
    memset(image, '\0', sizeof(image));
129
 
 
130
 
    // Try to match PPC NVRAM
131
 
    pstrcpy((char *)header->struct_ident, sizeof(header->struct_ident),
132
 
            "QEMU_BIOS");
133
 
    header->struct_version = cpu_to_be32(3); /* structure v3 */
134
 
 
135
 
    header->nvram_size = cpu_to_be16(NVRAM_size);
136
 
    header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t));
137
 
    header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg));
138
 
    pstrcpy((char *)header->arch, sizeof(header->arch), arch);
139
 
    header->nb_cpus = smp_cpus & 0xff;
140
 
    header->RAM0_base = 0;
141
 
    header->RAM0_size = cpu_to_be64((uint64_t)RAM_size);
142
 
    pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices),
143
 
            boot_devices);
144
 
    header->nboot_devices = strlen(boot_devices) & 0xff;
145
 
    header->kernel_image = cpu_to_be64((uint64_t)kernel_image);
146
 
    header->kernel_size = cpu_to_be64((uint64_t)kernel_size);
 
216
 
 
217
    /* Set parameters for Open Hack'Ware BIOS */
 
218
    NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
 
219
    NVRAM_set_lword(nvram,  0x10, 0x00000002); /* structure v2 */
 
220
    NVRAM_set_word(nvram,   0x14, NVRAM_size);
 
221
    NVRAM_set_string(nvram, 0x20, arch, 16);
 
222
    NVRAM_set_byte(nvram,   0x2f, nographic & 0xff);
 
223
    NVRAM_set_lword(nvram,  0x30, RAM_size);
 
224
    NVRAM_set_byte(nvram,   0x34, boot_device);
 
225
    NVRAM_set_lword(nvram,  0x38, kernel_image);
 
226
    NVRAM_set_lword(nvram,  0x3C, kernel_size);
147
227
    if (cmdline) {
148
 
        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, cmdline);
149
 
        header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR);
150
 
        header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline));
 
228
        /* XXX: put the cmdline in NVRAM too ? */
 
229
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
 
230
        NVRAM_set_lword(nvram,  0x40, CMDLINE_ADDR);
 
231
        NVRAM_set_lword(nvram,  0x44, strlen(cmdline));
 
232
    } else {
 
233
        NVRAM_set_lword(nvram,  0x40, 0);
 
234
        NVRAM_set_lword(nvram,  0x44, 0);
151
235
    }
152
 
    header->initrd_image = cpu_to_be64((uint64_t)initrd_image);
153
 
    header->initrd_size = cpu_to_be64((uint64_t)initrd_size);
154
 
    header->NVRAM_image = cpu_to_be64((uint64_t)NVRAM_image);
155
 
 
156
 
    header->width = cpu_to_be16(width);
157
 
    header->height = cpu_to_be16(height);
158
 
    header->depth = cpu_to_be16(depth);
159
 
    if (nographic)
160
 
        header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);
161
 
 
162
 
    header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
163
 
 
164
 
    // Architecture specific header
165
 
    start = sizeof(ohwcfg_v3_t);
166
 
    sparc_header = (struct sparc_arch_cfg *)&image[start];
167
 
    sparc_header->valid = 0;
168
 
    start += sizeof(struct sparc_arch_cfg);
 
236
    NVRAM_set_lword(nvram,  0x48, initrd_image);
 
237
    NVRAM_set_lword(nvram,  0x4C, initrd_size);
 
238
    NVRAM_set_lword(nvram,  0x50, NVRAM_image);
 
239
 
 
240
    NVRAM_set_word(nvram,   0x54, width);
 
241
    NVRAM_set_word(nvram,   0x56, height);
 
242
    NVRAM_set_word(nvram,   0x58, depth);
 
243
    crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
 
244
    NVRAM_set_word(nvram,  0xFC, crc);
169
245
 
170
246
    // OpenBIOS nvram variables
171
247
    // Variable partition
172
 
    part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
173
 
    part_header->signature = OPENBIOS_PART_SYSTEM;
174
 
    pstrcpy(part_header->name, sizeof(part_header->name), "system");
 
248
    start = 256;
 
249
    m48t59_write(nvram, start, 0x70);
 
250
    NVRAM_set_string(nvram, start + 4, "system", 12);
175
251
 
176
 
    end = start + sizeof(struct OpenBIOS_nvpart_v1);
 
252
    end = start + 16;
177
253
    for (i = 0; i < nb_prom_envs; i++)
178
 
        end = OpenBIOS_set_var(image, end, prom_envs[i]);
179
 
 
180
 
    // End marker
181
 
    image[end++] = '\0';
182
 
 
 
254
        end = nvram_set_var(nvram, end, prom_envs[i]);
 
255
 
 
256
    m48t59_write(nvram, end++ , 0);
183
257
    end = start + ((end - start + 15) & ~15);
184
 
    OpenBIOS_finish_partition(part_header, end - start);
 
258
    nvram_finish_partition(nvram, start, end);
185
259
 
186
260
    // free partition
187
261
    start = end;
188
 
    part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
189
 
    part_header->signature = OPENBIOS_PART_FREE;
190
 
    pstrcpy(part_header->name, sizeof(part_header->name), "free");
 
262
    m48t59_write(nvram, start, 0x7f);
 
263
    NVRAM_set_string(nvram, start + 4, "free", 12);
191
264
 
192
265
    end = 0x1fd0;
193
 
    OpenBIOS_finish_partition(part_header, end - start);
194
 
 
195
 
    Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, 0x80);
196
 
 
197
 
    for (i = 0; i < sizeof(image); i++)
198
 
        m48t59_write(nvram, i, image[i]);
199
 
 
200
 
    qemu_register_boot_set(nvram_boot_set, nvram);
 
266
    nvram_finish_partition(nvram, start, end);
201
267
 
202
268
    return 0;
203
269
}
204
270
 
205
 
void pic_info(void)
206
 
{
207
 
}
208
 
 
209
 
void irq_info(void)
210
 
{
211
 
}
212
 
 
213
 
void cpu_check_irqs(CPUState *env)
214
 
{
215
 
    uint32_t pil = env->pil_in | (env->softint & ~SOFTINT_TIMER) |
216
 
        ((env->softint & SOFTINT_TIMER) << 14);
217
 
 
218
 
    if (pil && (env->interrupt_index == 0 ||
219
 
                (env->interrupt_index & ~15) == TT_EXTINT)) {
220
 
        unsigned int i;
221
 
 
222
 
        for (i = 15; i > 0; i--) {
223
 
            if (pil & (1 << i)) {
224
 
                int old_interrupt = env->interrupt_index;
225
 
 
226
 
                env->interrupt_index = TT_EXTINT | i;
227
 
                if (old_interrupt != env->interrupt_index) {
228
 
                    DPRINTF("Set CPU IRQ %d\n", i);
229
 
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
230
 
                }
231
 
                break;
232
 
            }
233
 
        }
234
 
    } else if (!pil && (env->interrupt_index & ~15) == TT_EXTINT) {
235
 
        DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
236
 
        env->interrupt_index = 0;
237
 
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
238
 
    }
239
 
}
240
 
 
241
 
static void cpu_set_irq(void *opaque, int irq, int level)
242
 
{
243
 
    CPUState *env = opaque;
244
 
 
245
 
    if (level) {
246
 
        DPRINTF("Raise CPU IRQ %d\n", irq);
247
 
        env->halted = 0;
248
 
        env->pil_in |= 1 << irq;
249
 
        cpu_check_irqs(env);
250
 
    } else {
251
 
        DPRINTF("Lower CPU IRQ %d\n", irq);
252
 
        env->pil_in &= ~(1 << irq);
253
 
        cpu_check_irqs(env);
254
 
    }
 
271
void pic_info()
 
272
{
 
273
}
 
274
 
 
275
void irq_info()
 
276
{
255
277
}
256
278
 
257
279
void qemu_system_powerdown(void)
258
280
{
259
281
}
260
282
 
261
 
typedef struct ResetData {
262
 
    CPUState *env;
263
 
    uint64_t reset_addr;
264
 
} ResetData;
265
 
 
266
283
static void main_cpu_reset(void *opaque)
267
284
{
268
 
    ResetData *s = (ResetData *)opaque;
269
 
    CPUState *env = s->env;
 
285
    CPUState *env = opaque;
270
286
 
271
287
    cpu_reset(env);
272
288
    ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1);
275
291
    ptimer_run(env->stick, 0);
276
292
    ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1);
277
293
    ptimer_run(env->hstick, 0);
278
 
    env->gregs[1] = 0; // Memory start
279
 
    env->gregs[2] = ram_size; // Memory size
280
 
    env->gregs[3] = 0; // Machine description XXX
281
 
    env->pc = s->reset_addr;
282
 
    env->npc = env->pc + 4;
283
 
}
284
 
 
285
 
static void tick_irq(void *opaque)
286
 
{
287
 
    CPUState *env = opaque;
288
 
 
289
 
    env->softint |= SOFTINT_TIMER;
290
 
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
291
 
}
292
 
 
293
 
static void stick_irq(void *opaque)
294
 
{
295
 
    CPUState *env = opaque;
296
 
 
297
 
    env->softint |= SOFTINT_TIMER;
298
 
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
299
 
}
300
 
 
301
 
static void hstick_irq(void *opaque)
302
 
{
303
 
    CPUState *env = opaque;
304
 
 
305
 
    env->softint |= SOFTINT_TIMER;
306
 
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
307
 
}
308
 
 
309
 
void cpu_tick_set_count(void *opaque, uint64_t count)
310
 
{
311
 
    ptimer_set_count(opaque, -count);
312
 
}
313
 
 
314
 
uint64_t cpu_tick_get_count(void *opaque)
315
 
{
316
 
    return -ptimer_get_count(opaque);
317
 
}
318
 
 
319
 
void cpu_tick_set_limit(void *opaque, uint64_t limit)
320
 
{
321
 
    ptimer_set_limit(opaque, -limit, 0);
 
294
}
 
295
 
 
296
void tick_irq(void *opaque)
 
297
{
 
298
    CPUState *env = opaque;
 
299
 
 
300
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
 
301
}
 
302
 
 
303
void stick_irq(void *opaque)
 
304
{
 
305
    CPUState *env = opaque;
 
306
 
 
307
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
 
308
}
 
309
 
 
310
void hstick_irq(void *opaque)
 
311
{
 
312
    CPUState *env = opaque;
 
313
 
 
314
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
 
315
}
 
316
 
 
317
static void dummy_cpu_set_irq(void *opaque, int irq, int level)
 
318
{
322
319
}
323
320
 
324
321
static const int ide_iobase[2] = { 0x1f0, 0x170 };
333
330
 
334
331
static fdctrl_t *floppy_controller;
335
332
 
336
 
static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
337
 
                        const char *boot_devices, DisplayState *ds,
338
 
                        const char *kernel_filename, const char *kernel_cmdline,
339
 
                        const char *initrd_filename, const char *cpu_model,
340
 
                        const struct hwdef *hwdef)
 
333
/* Sun4u hardware initialisation */
 
334
static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
 
335
             DisplayState *ds, const char **fd_filename, int snapshot,
 
336
             const char *kernel_filename, const char *kernel_cmdline,
 
337
             const char *initrd_filename, const char *cpu_model)
341
338
{
342
339
    CPUState *env;
343
340
    char buf[1024];
344
341
    m48t59_t *nvram;
345
342
    int ret, linux_boot;
346
343
    unsigned int i;
347
 
    ram_addr_t ram_offset, prom_offset, vga_ram_offset;
348
 
    long initrd_size, kernel_size;
 
344
    long prom_offset, initrd_size, kernel_size;
349
345
    PCIBus *pci_bus;
 
346
    const sparc_def_t *def;
350
347
    QEMUBH *bh;
351
348
    qemu_irq *irq;
352
 
    int drive_index;
353
 
    BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
354
 
    BlockDriverState *fd[MAX_FD];
355
 
    void *fw_cfg;
356
 
    ResetData *reset_info;
357
349
 
358
350
    linux_boot = (kernel_filename != NULL);
359
351
 
360
352
    /* init CPUs */
361
 
    if (!cpu_model)
362
 
        cpu_model = hwdef->default_cpu_model;
363
 
 
364
 
    env = cpu_init(cpu_model);
365
 
    if (!env) {
 
353
    if (cpu_model == NULL)
 
354
        cpu_model = "TI UltraSparc II";
 
355
    sparc_find_by_name(cpu_model, &def);
 
356
    if (def == NULL) {
366
357
        fprintf(stderr, "Unable to find Sparc CPU definition\n");
367
358
        exit(1);
368
359
    }
 
360
    env = cpu_init();
 
361
    cpu_sparc_register(env, def);
369
362
    bh = qemu_bh_new(tick_irq, env);
370
363
    env->tick = ptimer_init(bh);
371
364
    ptimer_set_period(env->tick, 1ULL);
377
370
    bh = qemu_bh_new(hstick_irq, env);
378
371
    env->hstick = ptimer_init(bh);
379
372
    ptimer_set_period(env->hstick, 1ULL);
380
 
 
381
 
    reset_info = qemu_mallocz(sizeof(ResetData));
382
 
    reset_info->env = env;
383
 
    reset_info->reset_addr = hwdef->prom_addr + 0x40ULL;
384
 
    qemu_register_reset(main_cpu_reset, reset_info);
385
 
    main_cpu_reset(reset_info);
386
 
    // Override warm reset address with cold start address
387
 
    env->pc = hwdef->prom_addr + 0x20ULL;
388
 
    env->npc = env->pc + 4;
 
373
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 
374
    qemu_register_reset(main_cpu_reset, env);
 
375
    main_cpu_reset(env);
389
376
 
390
377
    /* allocate RAM */
391
 
    ram_offset = qemu_ram_alloc(RAM_size);
392
 
    cpu_register_physical_memory(0, RAM_size, ram_offset);
 
378
    cpu_register_physical_memory(0, ram_size, 0);
393
379
 
394
 
    prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
395
 
    cpu_register_physical_memory(hwdef->prom_addr,
396
 
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
397
 
                                 TARGET_PAGE_MASK,
 
380
    prom_offset = ram_size + vga_ram_size;
 
381
    cpu_register_physical_memory(PROM_ADDR,
 
382
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK,
398
383
                                 prom_offset | IO_MEM_ROM);
399
384
 
400
385
    if (bios_name == NULL)
401
386
        bios_name = PROM_FILENAME;
402
387
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
403
 
    ret = load_elf(buf, hwdef->prom_addr - PROM_VADDR, NULL, NULL, NULL);
 
388
    ret = load_elf(buf, PROM_ADDR - PROM_VADDR, NULL, NULL, NULL);
404
389
    if (ret < 0) {
405
 
        ret = load_image_targphys(buf, hwdef->prom_addr,
406
 
                                  (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
407
 
                                  TARGET_PAGE_MASK);
408
 
        if (ret < 0) {
409
 
            fprintf(stderr, "qemu: could not load prom '%s'\n",
410
 
                    buf);
411
 
            exit(1);
412
 
        }
 
390
        fprintf(stderr, "qemu: could not load prom '%s'\n",
 
391
                buf);
 
392
        exit(1);
413
393
    }
414
394
 
415
395
    kernel_size = 0;
418
398
        /* XXX: put correct offset */
419
399
        kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL);
420
400
        if (kernel_size < 0)
421
 
            kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
422
 
                                    ram_size - KERNEL_LOAD_ADDR);
 
401
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
423
402
        if (kernel_size < 0)
424
 
            kernel_size = load_image_targphys(kernel_filename,
425
 
                                              KERNEL_LOAD_ADDR,
426
 
                                              ram_size - KERNEL_LOAD_ADDR);
 
403
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
427
404
        if (kernel_size < 0) {
428
405
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
429
406
                    kernel_filename);
432
409
 
433
410
        /* load initrd */
434
411
        if (initrd_filename) {
435
 
            initrd_size = load_image_targphys(initrd_filename,
436
 
                                              INITRD_LOAD_ADDR,
437
 
                                              ram_size - INITRD_LOAD_ADDR);
 
412
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
438
413
            if (initrd_size < 0) {
439
414
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
440
415
                        initrd_filename);
443
418
        }
444
419
        if (initrd_size > 0) {
445
420
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
446
 
                if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
447
 
                    stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
448
 
                    stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size);
 
421
                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
 
422
                    == 0x48647253) { // HdrS
 
423
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
 
424
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
449
425
                    break;
450
426
                }
451
427
            }
453
429
    }
454
430
    pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL);
455
431
    isa_mem_base = VGA_BASE;
456
 
    vga_ram_offset = qemu_ram_alloc(vga_ram_size);
457
 
    pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + vga_ram_offset,
458
 
                        vga_ram_offset, vga_ram_size);
 
432
    pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size, vga_ram_size);
459
433
 
460
 
    i = 0;
461
 
    if (hwdef->console_serial_base) {
462
 
        serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200,
463
 
                       serial_hds[i], 1);
464
 
        i++;
465
 
    }
466
 
    for(; i < MAX_SERIAL_PORTS; i++) {
 
434
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
467
435
        if (serial_hds[i]) {
468
 
            serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200,
469
 
                        serial_hds[i]);
 
436
            serial_init(serial_io[i], NULL/*serial_irq[i]*/, serial_hds[i]);
470
437
        }
471
438
    }
472
439
 
473
440
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
474
441
        if (parallel_hds[i]) {
475
 
            parallel_init(parallel_io[i], NULL/*parallel_irq[i]*/,
476
 
                          parallel_hds[i]);
 
442
            parallel_init(parallel_io[i], NULL/*parallel_irq[i]*/, parallel_hds[i]);
477
443
        }
478
444
    }
479
445
 
483
449
        pci_nic_init(pci_bus, &nd_table[i], -1);
484
450
    }
485
451
 
486
 
    irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
487
 
    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
488
 
        fprintf(stderr, "qemu: too many IDE bus\n");
489
 
        exit(1);
490
 
    }
491
 
    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
492
 
        drive_index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS,
493
 
                                      i % MAX_IDE_DEVS);
494
 
       if (drive_index != -1)
495
 
           hd[i] = drives_table[drive_index].bdrv;
496
 
       else
497
 
           hd[i] = NULL;
498
 
    }
499
 
 
500
 
    // XXX pci_cmd646_ide_init(pci_bus, hd, 1);
501
 
    pci_piix3_ide_init(pci_bus, hd, -1, irq);
 
452
    irq = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, 32);
 
453
    // XXX pci_cmd646_ide_init(pci_bus, bs_table, 1);
 
454
    pci_piix3_ide_init(pci_bus, bs_table, -1, irq);
502
455
    /* FIXME: wire up interrupts.  */
503
456
    i8042_init(NULL/*1*/, NULL/*12*/, 0x60);
504
 
    for(i = 0; i < MAX_FD; i++) {
505
 
        drive_index = drive_get_index(IF_FLOPPY, 0, i);
506
 
       if (drive_index != -1)
507
 
           fd[i] = drives_table[drive_index].bdrv;
508
 
       else
509
 
           fd[i] = NULL;
510
 
    }
511
 
    floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd);
 
457
    floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table);
512
458
    nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59);
513
 
    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
514
 
                           KERNEL_LOAD_ADDR, kernel_size,
515
 
                           kernel_cmdline,
516
 
                           INITRD_LOAD_ADDR, initrd_size,
517
 
                           /* XXX: need an option to load a NVRAM image */
518
 
                           0,
519
 
                           graphic_width, graphic_height, graphic_depth,
520
 
                           (uint8_t *)&nd_table[0].macaddr);
521
 
 
522
 
    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
523
 
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
524
 
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
525
 
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
526
 
}
527
 
 
528
 
enum {
529
 
    sun4u_id = 0,
530
 
    sun4v_id = 64,
531
 
    niagara_id,
532
 
};
533
 
 
534
 
static const struct hwdef hwdefs[] = {
535
 
    /* Sun4u generic PC-like machine */
536
 
    {
537
 
        .default_cpu_model = "TI UltraSparc II",
538
 
        .machine_id = sun4u_id,
539
 
        .prom_addr = 0x1fff0000000ULL,
540
 
        .console_serial_base = 0,
541
 
    },
542
 
    /* Sun4v generic PC-like machine */
543
 
    {
544
 
        .default_cpu_model = "Sun UltraSparc T1",
545
 
        .machine_id = sun4v_id,
546
 
        .prom_addr = 0x1fff0000000ULL,
547
 
        .console_serial_base = 0,
548
 
    },
549
 
    /* Sun4v generic Niagara machine */
550
 
    {
551
 
        .default_cpu_model = "Sun UltraSparc T1",
552
 
        .machine_id = niagara_id,
553
 
        .prom_addr = 0xfff0000000ULL,
554
 
        .console_serial_base = 0xfff0c2c000ULL,
555
 
    },
556
 
};
557
 
 
558
 
/* Sun4u hardware initialisation */
559
 
static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size,
560
 
                       const char *boot_devices, DisplayState *ds,
561
 
                       const char *kernel_filename, const char *kernel_cmdline,
562
 
                       const char *initrd_filename, const char *cpu_model)
563
 
{
564
 
    sun4uv_init(RAM_size, vga_ram_size, boot_devices, ds, kernel_filename,
565
 
                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]);
566
 
}
567
 
 
568
 
/* Sun4v hardware initialisation */
569
 
static void sun4v_init(ram_addr_t RAM_size, int vga_ram_size,
570
 
                       const char *boot_devices, DisplayState *ds,
571
 
                       const char *kernel_filename, const char *kernel_cmdline,
572
 
                       const char *initrd_filename, const char *cpu_model)
573
 
{
574
 
    sun4uv_init(RAM_size, vga_ram_size, boot_devices, ds, kernel_filename,
575
 
                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
576
 
}
577
 
 
578
 
/* Niagara hardware initialisation */
579
 
static void niagara_init(ram_addr_t RAM_size, int vga_ram_size,
580
 
                         const char *boot_devices, DisplayState *ds,
581
 
                         const char *kernel_filename, const char *kernel_cmdline,
582
 
                         const char *initrd_filename, const char *cpu_model)
583
 
{
584
 
    sun4uv_init(RAM_size, vga_ram_size, boot_devices, ds, kernel_filename,
585
 
                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
 
459
    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device,
 
460
                         KERNEL_LOAD_ADDR, kernel_size,
 
461
                         kernel_cmdline,
 
462
                         INITRD_LOAD_ADDR, initrd_size,
 
463
                         /* XXX: need an option to load a NVRAM image */
 
464
                         0,
 
465
                         graphic_width, graphic_height, graphic_depth);
 
466
 
586
467
}
587
468
 
588
469
QEMUMachine sun4u_machine = {
589
 
    .name = "sun4u",
590
 
    .desc = "Sun4u platform",
591
 
    .init = sun4u_init,
592
 
    .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
593
 
    .nodisk_ok = 1,
594
 
    .max_cpus = 1, // XXX for now
595
 
};
596
 
 
597
 
QEMUMachine sun4v_machine = {
598
 
    .name = "sun4v",
599
 
    .desc = "Sun4v platform",
600
 
    .init = sun4v_init,
601
 
    .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
602
 
    .nodisk_ok = 1,
603
 
    .max_cpus = 1, // XXX for now
604
 
};
605
 
 
606
 
QEMUMachine niagara_machine = {
607
 
    .name = "Niagara",
608
 
    .desc = "Sun4v platform, Niagara",
609
 
    .init = niagara_init,
610
 
    .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
611
 
    .nodisk_ok = 1,
612
 
    .max_cpus = 1, // XXX for now
 
470
    "sun4u",
 
471
    "Sun4u platform",
 
472
    sun4u_init,
613
473
};