Revision 83469015 hw/sun4u.c

b/hw/sun4u.c
22 22
 * THE SOFTWARE.
23 23
 */
24 24
#include "vl.h"
25
#include "m48t08.h"
25
#include "m48t59.h"
26 26

  
27
#define KERNEL_LOAD_ADDR     0x00004000
28
#define CMDLINE_ADDR         0x007ff000
29
#define INITRD_LOAD_ADDR     0x00800000
30
#define PROM_ADDR	     0xffd00000
27
#define KERNEL_LOAD_ADDR     0x00404000
28
#define CMDLINE_ADDR         0x003ff000
29
#define INITRD_LOAD_ADDR     0x00300000
30
#define PROM_ADDR	     0x1fff0000000ULL
31
#define APB_SPECIAL_BASE     0x1fe00000000ULL
32
#define APB_MEM_BASE	     0x1ff00000000ULL
33
#define VGA_BASE	     (APB_MEM_BASE + 0x400000ULL)
31 34
#define PROM_FILENAMEB	     "proll-sparc64.bin"
32 35
#define PROM_FILENAMEE	     "proll-sparc64.elf"
33
#define PHYS_JJ_EEPROM	0x71200000	/* m48t08 */
34
#define PHYS_JJ_IDPROM_OFF	0x1FD8
35
#define PHYS_JJ_EEPROM_SIZE	0x2000
36
// IRQs are not PIL ones, but master interrupt controller register
37
// bits
38
#define PHYS_JJ_MS_KBD	0x71000000	/* Mouse and keyboard */
39
#define PHYS_JJ_MS_KBD_IRQ    14
40
#define PHYS_JJ_SER	0x71100000	/* Serial */
41
#define PHYS_JJ_SER_IRQ    15
36
#define NVRAM_SIZE           0x2000
42 37

  
43 38
/* TSC handling */
44 39

  
......
70 65
{
71 66
}
72 67

  
73
static void nvram_set_word (m48t08_t *nvram, uint32_t addr, uint16_t value)
68
/* NVRAM helpers */
69
void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
74 70
{
75
    m48t08_write(nvram, addr++, (value >> 8) & 0xff);
76
    m48t08_write(nvram, addr++, value & 0xff);
71
    m48t59_set_addr(nvram, addr);
72
    m48t59_write(nvram, value);
77 73
}
78 74

  
79
static void nvram_set_lword (m48t08_t *nvram, uint32_t addr, uint32_t value)
75
uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
80 76
{
81
    m48t08_write(nvram, addr++, value >> 24);
82
    m48t08_write(nvram, addr++, (value >> 16) & 0xff);
83
    m48t08_write(nvram, addr++, (value >> 8) & 0xff);
84
    m48t08_write(nvram, addr++, value & 0xff);
77
    m48t59_set_addr(nvram, addr);
78
    return m48t59_read(nvram);
85 79
}
86 80

  
87
static void nvram_set_string (m48t08_t *nvram, uint32_t addr,
81
void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
82
{
83
    m48t59_set_addr(nvram, addr);
84
    m48t59_write(nvram, value >> 8);
85
    m48t59_set_addr(nvram, addr + 1);
86
    m48t59_write(nvram, value & 0xFF);
87
}
88

  
89
uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
90
{
91
    uint16_t tmp;
92

  
93
    m48t59_set_addr(nvram, addr);
94
    tmp = m48t59_read(nvram) << 8;
95
    m48t59_set_addr(nvram, addr + 1);
96
    tmp |= m48t59_read(nvram);
97

  
98
    return tmp;
99
}
100

  
101
void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
102
{
103
    m48t59_set_addr(nvram, addr);
104
    m48t59_write(nvram, value >> 24);
105
    m48t59_set_addr(nvram, addr + 1);
106
    m48t59_write(nvram, (value >> 16) & 0xFF);
107
    m48t59_set_addr(nvram, addr + 2);
108
    m48t59_write(nvram, (value >> 8) & 0xFF);
109
    m48t59_set_addr(nvram, addr + 3);
110
    m48t59_write(nvram, value & 0xFF);
111
}
112

  
113
uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
114
{
115
    uint32_t tmp;
116

  
117
    m48t59_set_addr(nvram, addr);
118
    tmp = m48t59_read(nvram) << 24;
119
    m48t59_set_addr(nvram, addr + 1);
120
    tmp |= m48t59_read(nvram) << 16;
121
    m48t59_set_addr(nvram, addr + 2);
122
    tmp |= m48t59_read(nvram) << 8;
123
    m48t59_set_addr(nvram, addr + 3);
124
    tmp |= m48t59_read(nvram);
125

  
126
    return tmp;
127
}
128

  
129
void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
88 130
                       const unsigned char *str, uint32_t max)
89 131
{
90
    unsigned int i;
132
    int i;
91 133

  
92 134
    for (i = 0; i < max && str[i] != '\0'; i++) {
93
        m48t08_write(nvram, addr + i, str[i]);
135
        m48t59_set_addr(nvram, addr + i);
136
        m48t59_write(nvram, str[i]);
94 137
    }
95
    m48t08_write(nvram, addr + max - 1, '\0');
138
    m48t59_set_addr(nvram, addr + max - 1);
139
    m48t59_write(nvram, '\0');
96 140
}
97 141

  
98
static m48t08_t *nvram;
142
int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
143
{
144
    int i;
145

  
146
    memset(dst, 0, max);
147
    for (i = 0; i < max; i++) {
148
        dst[i] = NVRAM_get_byte(nvram, addr + i);
149
        if (dst[i] == '\0')
150
            break;
151
    }
152

  
153
    return i;
154
}
155

  
156
static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
157
{
158
    uint16_t tmp;
159
    uint16_t pd, pd1, pd2;
160

  
161
    tmp = prev >> 8;
162
    pd = prev ^ value;
163
    pd1 = pd & 0x000F;
164
    pd2 = ((pd >> 4) & 0x000F) ^ pd1;
165
    tmp ^= (pd1 << 3) | (pd1 << 8);
166
    tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
167

  
168
    return tmp;
169
}
170

  
171
uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
172
{
173
    uint32_t i;
174
    uint16_t crc = 0xFFFF;
175
    int odd;
176

  
177
    odd = count & 1;
178
    count &= ~1;
179
    for (i = 0; i != count; i++) {
180
	crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
181
    }
182
    if (odd) {
183
	crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
184
    }
185

  
186
    return crc;
187
}
99 188

  
100 189
extern int nographic;
101 190

  
102
static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline,
103
		       int boot_device, uint32_t RAM_size,
104
		       uint32_t kernel_size,
105
		       int width, int height, int depth)
106
{
107
    unsigned char tmp = 0;
108
    int i, j;
109

  
110
    // Try to match PPC NVRAM
111
    nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
112
    nvram_set_lword(nvram,  0x10, 0x00000001); /* structure v1 */
113
    // NVRAM_size, arch not applicable
114
    m48t08_write(nvram, 0x2F, nographic & 0xff);
115
    nvram_set_lword(nvram,  0x30, RAM_size);
116
    m48t08_write(nvram, 0x34, boot_device & 0xff);
117
    nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);
118
    nvram_set_lword(nvram,  0x3C, kernel_size);
191
int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
192
                          const unsigned char *arch,
193
                          uint32_t RAM_size, int boot_device,
194
                          uint32_t kernel_image, uint32_t kernel_size,
195
                          const char *cmdline,
196
                          uint32_t initrd_image, uint32_t initrd_size,
197
                          uint32_t NVRAM_image,
198
                          int width, int height, int depth)
199
{
200
    uint16_t crc;
201

  
202
    /* Set parameters for Open Hack'Ware BIOS */
203
    NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
204
    NVRAM_set_lword(nvram,  0x10, 0x00000002); /* structure v2 */
205
    NVRAM_set_word(nvram,   0x14, NVRAM_size);
206
    NVRAM_set_string(nvram, 0x20, arch, 16);
207
    NVRAM_set_byte(nvram,   0x2f, nographic & 0xff);
208
    NVRAM_set_lword(nvram,  0x30, RAM_size);
209
    NVRAM_set_byte(nvram,   0x34, boot_device);
210
    NVRAM_set_lword(nvram,  0x38, kernel_image);
211
    NVRAM_set_lword(nvram,  0x3C, kernel_size);
119 212
    if (cmdline) {
120
	strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
121
	nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
122
        nvram_set_lword(nvram,  0x44, strlen(cmdline));
213
        /* XXX: put the cmdline in NVRAM too ? */
214
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
215
        NVRAM_set_lword(nvram,  0x40, CMDLINE_ADDR);
216
        NVRAM_set_lword(nvram,  0x44, strlen(cmdline));
217
    } else {
218
        NVRAM_set_lword(nvram,  0x40, 0);
219
        NVRAM_set_lword(nvram,  0x44, 0);
123 220
    }
124
    // initrd_image, initrd_size passed differently
125
    nvram_set_word(nvram,   0x54, width);
126
    nvram_set_word(nvram,   0x56, height);
127
    nvram_set_word(nvram,   0x58, depth);
128

  
129
    // Sun4m specific use
130
    i = 0x1fd8;
131
    m48t08_write(nvram, i++, 0x01);
132
    m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */
133
    j = 0;
134
    m48t08_write(nvram, i++, macaddr[j++]);
135
    m48t08_write(nvram, i++, macaddr[j++]);
136
    m48t08_write(nvram, i++, macaddr[j++]);
137
    m48t08_write(nvram, i++, macaddr[j++]);
138
    m48t08_write(nvram, i++, macaddr[j++]);
139
    m48t08_write(nvram, i, macaddr[j]);
140

  
141
    /* Calculate checksum */
142
    for (i = 0x1fd8; i < 0x1fe7; i++) {
143
	tmp ^= m48t08_read(nvram, i);
144
    }
145
    m48t08_write(nvram, 0x1fe7, tmp);
221
    NVRAM_set_lword(nvram,  0x48, initrd_image);
222
    NVRAM_set_lword(nvram,  0x4C, initrd_size);
223
    NVRAM_set_lword(nvram,  0x50, NVRAM_image);
224

  
225
    NVRAM_set_word(nvram,   0x54, width);
226
    NVRAM_set_word(nvram,   0x56, height);
227
    NVRAM_set_word(nvram,   0x58, depth);
228
    crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
229
    NVRAM_set_word(nvram,  0xFC, crc);
230

  
231
    return 0;
146 232
}
147 233

  
148 234
void pic_info()
......
157 243
{
158 244
}
159 245

  
160
void vga_update_display()
246
void pic_set_irq_new(void *opaque, int irq, int level)
161 247
{
162 248
}
163 249

  
164
void vga_invalidate_display()
250
void qemu_system_powerdown(void)
165 251
{
166 252
}
167 253

  
168
void vga_screen_dump(const char *filename)
169
{
170
}
254
static const int ide_iobase[2] = { 0x1f0, 0x170 };
255
static const int ide_iobase2[2] = { 0x3f6, 0x376 };
256
static const int ide_irq[2] = { 14, 15 };
171 257

  
172
void qemu_system_powerdown(void)
173
{
174
}
258
static const int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
259
static const int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
260

  
261
static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
262
static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
263

  
264
static fdctrl_t *floppy_controller;
175 265

  
176 266
/* Sun4u hardware initialisation */
177 267
static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
......
180 270
             const char *initrd_filename)
181 271
{
182 272
    char buf[1024];
273
    m48t59_t *nvram;
183 274
    int ret, linux_boot;
184 275
    unsigned int i;
185
    long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
276
    long prom_offset, initrd_size, kernel_size;
277
    PCIBus *pci_bus;
186 278

  
187 279
    linux_boot = (kernel_filename != NULL);
188 280

  
189 281
    /* allocate RAM */
190 282
    cpu_register_physical_memory(0, ram_size, 0);
191 283

  
192
    nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE);
193
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
194
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
195
    slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);
196

  
197
    prom_offset = ram_size + vram_size;
284
    prom_offset = ram_size + vga_ram_size;
198 285

  
199 286
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
200 287
    ret = load_elf(buf, phys_ram_base + prom_offset);
......
211 298
                                 prom_offset | IO_MEM_ROM);
212 299

  
213 300
    kernel_size = 0;
301
    initrd_size = 0;
214 302
    if (linux_boot) {
215 303
        kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
216 304
        if (kernel_size < 0)
......
224 312
        }
225 313

  
226 314
        /* load initrd */
227
        initrd_size = 0;
228 315
        if (initrd_filename) {
229 316
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
230 317
            if (initrd_size < 0) {
......
244 331
	    }
245 332
        }
246 333
    }
247
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth);
334
    pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE);
335
    isa_mem_base = VGA_BASE;
336
    vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
337
                   vga_ram_size, 0, 0);
338
    cpu_register_physical_memory(VGA_BASE, vga_ram_size, ram_size);
339
    //pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size, vga_ram_size);
340

  
341
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
342
        if (serial_hds[i]) {
343
            serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
344
        }
345
    }
346

  
347
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
348
        if (parallel_hds[i]) {
349
            parallel_init(parallel_io[i], parallel_irq[i], parallel_hds[i]);
350
        }
351
    }
352

  
353
    for(i = 0; i < nb_nics; i++) {
354
	pci_ne2000_init(pci_bus, &nd_table[i]);
355
    }
356

  
357
    pci_cmd646_ide_init(pci_bus, bs_table, 1);
358
    kbd_init();
359
    floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
360
    nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE);
361
    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device,
362
                         KERNEL_LOAD_ADDR, kernel_size,
363
                         kernel_cmdline,
364
                         INITRD_LOAD_ADDR, initrd_size,
365
                         /* XXX: need an option to load a NVRAM image */
366
                         0,
367
                         graphic_width, graphic_height, graphic_depth);
368

  
248 369
}
249 370

  
250 371
QEMUMachine sun4u_machine = {

Also available in: Unified diff