Statistics
| Branch: | Revision:

root / hw / sun4u.c @ f68c781c

History | View | Annotate | Download (7.7 kB)

1 3475187d bellard
/*
2 3475187d bellard
 * QEMU Sun4u System Emulator
3 3475187d bellard
 * 
4 3475187d bellard
 * Copyright (c) 2005 Fabrice Bellard
5 3475187d bellard
 * 
6 3475187d bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 3475187d bellard
 * of this software and associated documentation files (the "Software"), to deal
8 3475187d bellard
 * in the Software without restriction, including without limitation the rights
9 3475187d bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 3475187d bellard
 * copies of the Software, and to permit persons to whom the Software is
11 3475187d bellard
 * furnished to do so, subject to the following conditions:
12 3475187d bellard
 *
13 3475187d bellard
 * The above copyright notice and this permission notice shall be included in
14 3475187d bellard
 * all copies or substantial portions of the Software.
15 3475187d bellard
 *
16 3475187d bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 3475187d bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 3475187d bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 3475187d bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 3475187d bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 3475187d bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 3475187d bellard
 * THE SOFTWARE.
23 3475187d bellard
 */
24 3475187d bellard
#include "vl.h"
25 3475187d bellard
#include "m48t08.h"
26 3475187d bellard
27 3475187d bellard
#define KERNEL_LOAD_ADDR     0x00004000
28 3475187d bellard
#define CMDLINE_ADDR         0x007ff000
29 3475187d bellard
#define INITRD_LOAD_ADDR     0x00800000
30 3475187d bellard
#define PROM_ADDR             0xffd00000
31 3475187d bellard
#define PROM_FILENAMEB             "proll-sparc64.bin"
32 3475187d bellard
#define PROM_FILENAMEE             "proll-sparc64.elf"
33 3475187d bellard
#define PHYS_JJ_EEPROM        0x71200000        /* m48t08 */
34 3475187d bellard
#define PHYS_JJ_IDPROM_OFF        0x1FD8
35 3475187d bellard
#define PHYS_JJ_EEPROM_SIZE        0x2000
36 3475187d bellard
// IRQs are not PIL ones, but master interrupt controller register
37 3475187d bellard
// bits
38 3475187d bellard
#define PHYS_JJ_MS_KBD        0x71000000        /* Mouse and keyboard */
39 3475187d bellard
#define PHYS_JJ_MS_KBD_IRQ    14
40 3475187d bellard
#define PHYS_JJ_SER        0x71100000        /* Serial */
41 3475187d bellard
#define PHYS_JJ_SER_IRQ    15
42 3475187d bellard
43 3475187d bellard
/* TSC handling */
44 3475187d bellard
45 3475187d bellard
uint64_t cpu_get_tsc()
46 3475187d bellard
{
47 3475187d bellard
    return qemu_get_clock(vm_clock);
48 3475187d bellard
}
49 3475187d bellard
50 3475187d bellard
int DMA_get_channel_mode (int nchan)
51 3475187d bellard
{
52 3475187d bellard
    return 0;
53 3475187d bellard
}
54 3475187d bellard
int DMA_read_memory (int nchan, void *buf, int pos, int size)
55 3475187d bellard
{
56 3475187d bellard
    return 0;
57 3475187d bellard
}
58 3475187d bellard
int DMA_write_memory (int nchan, void *buf, int pos, int size)
59 3475187d bellard
{
60 3475187d bellard
    return 0;
61 3475187d bellard
}
62 3475187d bellard
void DMA_hold_DREQ (int nchan) {}
63 3475187d bellard
void DMA_release_DREQ (int nchan) {}
64 3475187d bellard
void DMA_schedule(int nchan) {}
65 3475187d bellard
void DMA_run (void) {}
66 3475187d bellard
void DMA_init (int high_page_enable) {}
67 3475187d bellard
void DMA_register_channel (int nchan,
68 3475187d bellard
                           DMA_transfer_handler transfer_handler,
69 3475187d bellard
                           void *opaque)
70 3475187d bellard
{
71 3475187d bellard
}
72 3475187d bellard
73 3475187d bellard
static void nvram_set_word (m48t08_t *nvram, uint32_t addr, uint16_t value)
74 3475187d bellard
{
75 3475187d bellard
    m48t08_write(nvram, addr++, (value >> 8) & 0xff);
76 3475187d bellard
    m48t08_write(nvram, addr++, value & 0xff);
77 3475187d bellard
}
78 3475187d bellard
79 3475187d bellard
static void nvram_set_lword (m48t08_t *nvram, uint32_t addr, uint32_t value)
80 3475187d bellard
{
81 3475187d bellard
    m48t08_write(nvram, addr++, value >> 24);
82 3475187d bellard
    m48t08_write(nvram, addr++, (value >> 16) & 0xff);
83 3475187d bellard
    m48t08_write(nvram, addr++, (value >> 8) & 0xff);
84 3475187d bellard
    m48t08_write(nvram, addr++, value & 0xff);
85 3475187d bellard
}
86 3475187d bellard
87 3475187d bellard
static void nvram_set_string (m48t08_t *nvram, uint32_t addr,
88 3475187d bellard
                       const unsigned char *str, uint32_t max)
89 3475187d bellard
{
90 3475187d bellard
    unsigned int i;
91 3475187d bellard
92 3475187d bellard
    for (i = 0; i < max && str[i] != '\0'; i++) {
93 3475187d bellard
        m48t08_write(nvram, addr + i, str[i]);
94 3475187d bellard
    }
95 3475187d bellard
    m48t08_write(nvram, addr + max - 1, '\0');
96 3475187d bellard
}
97 3475187d bellard
98 3475187d bellard
static m48t08_t *nvram;
99 3475187d bellard
100 3475187d bellard
extern int nographic;
101 3475187d bellard
102 3475187d bellard
static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline,
103 3475187d bellard
                       int boot_device, uint32_t RAM_size,
104 3475187d bellard
                       uint32_t kernel_size,
105 3475187d bellard
                       int width, int height, int depth)
106 3475187d bellard
{
107 3475187d bellard
    unsigned char tmp = 0;
108 3475187d bellard
    int i, j;
109 3475187d bellard
110 3475187d bellard
    // Try to match PPC NVRAM
111 3475187d bellard
    nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
112 3475187d bellard
    nvram_set_lword(nvram,  0x10, 0x00000001); /* structure v1 */
113 3475187d bellard
    // NVRAM_size, arch not applicable
114 3475187d bellard
    m48t08_write(nvram, 0x2F, nographic & 0xff);
115 3475187d bellard
    nvram_set_lword(nvram,  0x30, RAM_size);
116 3475187d bellard
    m48t08_write(nvram, 0x34, boot_device & 0xff);
117 3475187d bellard
    nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);
118 3475187d bellard
    nvram_set_lword(nvram,  0x3C, kernel_size);
119 3475187d bellard
    if (cmdline) {
120 3475187d bellard
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
121 3475187d bellard
        nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
122 3475187d bellard
        nvram_set_lword(nvram,  0x44, strlen(cmdline));
123 3475187d bellard
    }
124 3475187d bellard
    // initrd_image, initrd_size passed differently
125 3475187d bellard
    nvram_set_word(nvram,   0x54, width);
126 3475187d bellard
    nvram_set_word(nvram,   0x56, height);
127 3475187d bellard
    nvram_set_word(nvram,   0x58, depth);
128 3475187d bellard
129 3475187d bellard
    // Sun4m specific use
130 3475187d bellard
    i = 0x1fd8;
131 3475187d bellard
    m48t08_write(nvram, i++, 0x01);
132 3475187d bellard
    m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */
133 3475187d bellard
    j = 0;
134 3475187d bellard
    m48t08_write(nvram, i++, macaddr[j++]);
135 3475187d bellard
    m48t08_write(nvram, i++, macaddr[j++]);
136 3475187d bellard
    m48t08_write(nvram, i++, macaddr[j++]);
137 3475187d bellard
    m48t08_write(nvram, i++, macaddr[j++]);
138 3475187d bellard
    m48t08_write(nvram, i++, macaddr[j++]);
139 3475187d bellard
    m48t08_write(nvram, i, macaddr[j]);
140 3475187d bellard
141 3475187d bellard
    /* Calculate checksum */
142 3475187d bellard
    for (i = 0x1fd8; i < 0x1fe7; i++) {
143 3475187d bellard
        tmp ^= m48t08_read(nvram, i);
144 3475187d bellard
    }
145 3475187d bellard
    m48t08_write(nvram, 0x1fe7, tmp);
146 3475187d bellard
}
147 3475187d bellard
148 3475187d bellard
void pic_info()
149 3475187d bellard
{
150 3475187d bellard
}
151 3475187d bellard
152 3475187d bellard
void irq_info()
153 3475187d bellard
{
154 3475187d bellard
}
155 3475187d bellard
156 3475187d bellard
void pic_set_irq(int irq, int level)
157 3475187d bellard
{
158 3475187d bellard
}
159 3475187d bellard
160 3475187d bellard
void vga_update_display()
161 3475187d bellard
{
162 3475187d bellard
}
163 3475187d bellard
164 3475187d bellard
void vga_invalidate_display()
165 3475187d bellard
{
166 3475187d bellard
}
167 3475187d bellard
168 3475187d bellard
void vga_screen_dump(const char *filename)
169 3475187d bellard
{
170 3475187d bellard
}
171 3475187d bellard
172 3475187d bellard
void qemu_system_powerdown(void)
173 3475187d bellard
{
174 3475187d bellard
}
175 3475187d bellard
176 3475187d bellard
/* Sun4u hardware initialisation */
177 3475187d bellard
static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
178 3475187d bellard
             DisplayState *ds, const char **fd_filename, int snapshot,
179 3475187d bellard
             const char *kernel_filename, const char *kernel_cmdline,
180 3475187d bellard
             const char *initrd_filename)
181 3475187d bellard
{
182 3475187d bellard
    char buf[1024];
183 3475187d bellard
    int ret, linux_boot;
184 3475187d bellard
    unsigned int i;
185 3475187d bellard
    long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
186 3475187d bellard
187 3475187d bellard
    linux_boot = (kernel_filename != NULL);
188 3475187d bellard
189 3475187d bellard
    /* allocate RAM */
190 3475187d bellard
    cpu_register_physical_memory(0, ram_size, 0);
191 3475187d bellard
192 3475187d bellard
    nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE);
193 3475187d bellard
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
194 3475187d bellard
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
195 3475187d bellard
    slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);
196 3475187d bellard
197 3475187d bellard
    prom_offset = ram_size + vram_size;
198 3475187d bellard
199 3475187d bellard
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
200 3475187d bellard
    ret = load_elf(buf, phys_ram_base + prom_offset);
201 3475187d bellard
    if (ret < 0) {
202 3475187d bellard
        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
203 3475187d bellard
        ret = load_image(buf, phys_ram_base + prom_offset);
204 3475187d bellard
    }
205 3475187d bellard
    if (ret < 0) {
206 3475187d bellard
        fprintf(stderr, "qemu: could not load prom '%s'\n", 
207 3475187d bellard
                buf);
208 3475187d bellard
        exit(1);
209 3475187d bellard
    }
210 3475187d bellard
    cpu_register_physical_memory(PROM_ADDR, (ret + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK, 
211 3475187d bellard
                                 prom_offset | IO_MEM_ROM);
212 3475187d bellard
213 3475187d bellard
    kernel_size = 0;
214 3475187d bellard
    if (linux_boot) {
215 3475187d bellard
        kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
216 3475187d bellard
        if (kernel_size < 0)
217 3475187d bellard
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
218 3475187d bellard
        if (kernel_size < 0)
219 3475187d bellard
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
220 3475187d bellard
        if (kernel_size < 0) {
221 3475187d bellard
            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
222 3475187d bellard
                    kernel_filename);
223 3475187d bellard
            exit(1);
224 3475187d bellard
        }
225 3475187d bellard
226 3475187d bellard
        /* load initrd */
227 3475187d bellard
        initrd_size = 0;
228 3475187d bellard
        if (initrd_filename) {
229 3475187d bellard
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
230 3475187d bellard
            if (initrd_size < 0) {
231 3475187d bellard
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
232 3475187d bellard
                        initrd_filename);
233 3475187d bellard
                exit(1);
234 3475187d bellard
            }
235 3475187d bellard
        }
236 3475187d bellard
        if (initrd_size > 0) {
237 3475187d bellard
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
238 3475187d bellard
                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
239 3475187d bellard
                    == 0x48647253) { // HdrS
240 3475187d bellard
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
241 3475187d bellard
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
242 3475187d bellard
                    break;
243 3475187d bellard
                }
244 3475187d bellard
            }
245 3475187d bellard
        }
246 3475187d bellard
    }
247 3475187d bellard
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth);
248 3475187d bellard
}
249 3475187d bellard
250 3475187d bellard
QEMUMachine sun4u_machine = {
251 3475187d bellard
    "sun4u",
252 3475187d bellard
    "Sun4u platform",
253 3475187d bellard
    sun4u_init,
254 3475187d bellard
};