/[qemu]/qemu/hw/sun4u.c
ViewVC logotype

Diff of /qemu/hw/sun4u.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by bellard, Sat Jul 2 14:31:34 2005 UTC revision 1.2 by bellard, Sat Jul 23 14:27:54 2005 UTC
# Line 22  Line 22 
22   * THE SOFTWARE.   * THE SOFTWARE.
23   */   */
24  #include "vl.h"  #include "vl.h"
25  #include "m48t08.h"  #include "m48t59.h"
26    
27  #define KERNEL_LOAD_ADDR     0x00004000  #define KERNEL_LOAD_ADDR     0x00404000
28  #define CMDLINE_ADDR         0x007ff000  #define CMDLINE_ADDR         0x003ff000
29  #define INITRD_LOAD_ADDR     0x00800000  #define INITRD_LOAD_ADDR     0x00300000
30  #define PROM_ADDR            0xffd00000  #define PROM_ADDR            0x1fff0000000ULL
31    #define APB_SPECIAL_BASE     0x1fe00000000ULL
32    #define APB_MEM_BASE         0x1ff00000000ULL
33    #define VGA_BASE             (APB_MEM_BASE + 0x400000ULL)
34  #define PROM_FILENAMEB       "proll-sparc64.bin"  #define PROM_FILENAMEB       "proll-sparc64.bin"
35  #define PROM_FILENAMEE       "proll-sparc64.elf"  #define PROM_FILENAMEE       "proll-sparc64.elf"
36  #define PHYS_JJ_EEPROM  0x71200000      /* m48t08 */  #define NVRAM_SIZE           0x2000
 #define PHYS_JJ_IDPROM_OFF      0x1FD8  
 #define PHYS_JJ_EEPROM_SIZE     0x2000  
 // IRQs are not PIL ones, but master interrupt controller register  
 // bits  
 #define PHYS_JJ_MS_KBD  0x71000000      /* Mouse and keyboard */  
 #define PHYS_JJ_MS_KBD_IRQ    14  
 #define PHYS_JJ_SER     0x71100000      /* Serial */  
 #define PHYS_JJ_SER_IRQ    15  
37    
38  /* TSC handling */  /* TSC handling */
39    
# Line 70  void DMA_register_channel (int nchan, Line 65  void DMA_register_channel (int nchan,
65  {  {
66  }  }
67    
68  static void nvram_set_word (m48t08_t *nvram, uint32_t addr, uint16_t value)  /* NVRAM helpers */
69    void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
70  {  {
71      m48t08_write(nvram, addr++, (value >> 8) & 0xff);      m48t59_set_addr(nvram, addr);
72      m48t08_write(nvram, addr++, value & 0xff);      m48t59_write(nvram, value);
73  }  }
74    
75  static void nvram_set_lword (m48t08_t *nvram, uint32_t addr, uint32_t value)  uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
76  {  {
77      m48t08_write(nvram, addr++, value >> 24);      m48t59_set_addr(nvram, addr);
78      m48t08_write(nvram, addr++, (value >> 16) & 0xff);      return m48t59_read(nvram);
     m48t08_write(nvram, addr++, (value >> 8) & 0xff);  
     m48t08_write(nvram, addr++, value & 0xff);  
79  }  }
80    
81  static void nvram_set_string (m48t08_t *nvram, uint32_t addr,  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,
130                         const unsigned char *str, uint32_t max)                         const unsigned char *str, uint32_t max)
131  {  {
132      unsigned int i;      int i;
133    
134      for (i = 0; i < max && str[i] != '\0'; i++) {      for (i = 0; i < max && str[i] != '\0'; i++) {
135          m48t08_write(nvram, addr + i, str[i]);          m48t59_set_addr(nvram, addr + i);
136            m48t59_write(nvram, str[i]);
137      }      }
138      m48t08_write(nvram, addr + max - 1, '\0');      m48t59_set_addr(nvram, addr + max - 1);
139        m48t59_write(nvram, '\0');
140    }
141    
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  static m48t08_t *nvram;  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    }
188    
189  extern int nographic;  extern int nographic;
190    
191  static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline,  int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
192                         int boot_device, uint32_t RAM_size,                            const unsigned char *arch,
193                         uint32_t kernel_size,                            uint32_t RAM_size, int boot_device,
194                         int width, int height, int depth)                            uint32_t kernel_image, uint32_t kernel_size,
195  {                            const char *cmdline,
196      unsigned char tmp = 0;                            uint32_t initrd_image, uint32_t initrd_size,
197      int i, j;                            uint32_t NVRAM_image,
198                              int width, int height, int depth)
199      // Try to match PPC NVRAM  {
200      nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);      uint16_t crc;
201      nvram_set_lword(nvram,  0x10, 0x00000001); /* structure v1 */  
202      // NVRAM_size, arch not applicable      /* Set parameters for Open Hack'Ware BIOS */
203      m48t08_write(nvram, 0x2F, nographic & 0xff);      NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
204      nvram_set_lword(nvram,  0x30, RAM_size);      NVRAM_set_lword(nvram,  0x10, 0x00000002); /* structure v2 */
205      m48t08_write(nvram, 0x34, boot_device & 0xff);      NVRAM_set_word(nvram,   0x14, NVRAM_size);
206      nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);      NVRAM_set_string(nvram, 0x20, arch, 16);
207      nvram_set_lword(nvram,  0x3C, kernel_size);      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);
212      if (cmdline) {      if (cmdline) {
213          strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);          /* XXX: put the cmdline in NVRAM too ? */
214          nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);          strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
215          nvram_set_lword(nvram,  0x44, strlen(cmdline));          NVRAM_set_lword(nvram,  0x40, CMDLINE_ADDR);
216      }          NVRAM_set_lword(nvram,  0x44, strlen(cmdline));
217      // initrd_image, initrd_size passed differently      } else {
218      nvram_set_word(nvram,   0x54, width);          NVRAM_set_lword(nvram,  0x40, 0);
219      nvram_set_word(nvram,   0x56, height);          NVRAM_set_lword(nvram,  0x44, 0);
     nvram_set_word(nvram,   0x58, depth);  
   
     // Sun4m specific use  
     i = 0x1fd8;  
     m48t08_write(nvram, i++, 0x01);  
     m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */  
     j = 0;  
     m48t08_write(nvram, i++, macaddr[j++]);  
     m48t08_write(nvram, i++, macaddr[j++]);  
     m48t08_write(nvram, i++, macaddr[j++]);  
     m48t08_write(nvram, i++, macaddr[j++]);  
     m48t08_write(nvram, i++, macaddr[j++]);  
     m48t08_write(nvram, i, macaddr[j]);  
   
     /* Calculate checksum */  
     for (i = 0x1fd8; i < 0x1fe7; i++) {  
         tmp ^= m48t08_read(nvram, i);  
220      }      }
221      m48t08_write(nvram, 0x1fe7, tmp);      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;
232  }  }
233    
234  void pic_info()  void pic_info()
# Line 157  void pic_set_irq(int irq, int level) Line 243  void pic_set_irq(int irq, int level)
243  {  {
244  }  }
245    
246  void vga_update_display()  void pic_set_irq_new(void *opaque, int irq, int level)
247  {  {
248  }  }
249    
250  void vga_invalidate_display()  void qemu_system_powerdown(void)
251  {  {
252  }  }
253    
254  void vga_screen_dump(const char *filename)  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 };
257    
258  void qemu_system_powerdown(void)  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;
265    
266  /* Sun4u hardware initialisation */  /* Sun4u hardware initialisation */
267  static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,  static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
# Line 180  static void sun4u_init(int ram_size, int Line 270  static void sun4u_init(int ram_size, int
270               const char *initrd_filename)               const char *initrd_filename)
271  {  {
272      char buf[1024];      char buf[1024];
273        m48t59_t *nvram;
274      int ret, linux_boot;      int ret, linux_boot;
275      unsigned int i;      unsigned int i;
276      long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;      long prom_offset, initrd_size, kernel_size;
277        PCIBus *pci_bus;
278    
279      linux_boot = (kernel_filename != NULL);      linux_boot = (kernel_filename != NULL);
280    
281      /* allocate RAM */      /* allocate RAM */
282      cpu_register_physical_memory(0, ram_size, 0);      cpu_register_physical_memory(0, ram_size, 0);
283    
284      nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE);      prom_offset = ram_size + vga_ram_size;
     // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device  
     // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device  
     slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);  
   
     prom_offset = ram_size + vram_size;  
285    
286      snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);      snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
287      ret = load_elf(buf, phys_ram_base + prom_offset);      ret = load_elf(buf, phys_ram_base + prom_offset);
# Line 211  static void sun4u_init(int ram_size, int Line 298  static void sun4u_init(int ram_size, int
298                                   prom_offset | IO_MEM_ROM);                                   prom_offset | IO_MEM_ROM);
299    
300      kernel_size = 0;      kernel_size = 0;
301        initrd_size = 0;
302      if (linux_boot) {      if (linux_boot) {
303          kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);          kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
304          if (kernel_size < 0)          if (kernel_size < 0)
# Line 224  static void sun4u_init(int ram_size, int Line 312  static void sun4u_init(int ram_size, int
312          }          }
313    
314          /* load initrd */          /* load initrd */
         initrd_size = 0;  
315          if (initrd_filename) {          if (initrd_filename) {
316              initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);              initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
317              if (initrd_size < 0) {              if (initrd_size < 0) {
# Line 244  static void sun4u_init(int ram_size, int Line 331  static void sun4u_init(int ram_size, int
331              }              }
332          }          }
333      }      }
334      nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth);      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    
369  }  }
370    
371  QEMUMachine sun4u_machine = {  QEMUMachine sun4u_machine = {

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26