| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  |  * QEMU Sun4u/Sun4v System Emulator | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  |  * Copyright (c) 2005 Fabrice Bellard | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | 
					
						
							|  |  |  |  * of this software and associated documentation files (the "Software"), to deal | 
					
						
							|  |  |  |  * in the Software without restriction, including without limitation the rights | 
					
						
							|  |  |  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
					
						
							|  |  |  |  * copies of the Software, and to permit persons to whom the Software is | 
					
						
							|  |  |  |  * furnished to do so, subject to the following conditions: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The above copyright notice and this permission notice shall be included in | 
					
						
							|  |  |  |  * all copies or substantial portions of the Software. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
					
						
							|  |  |  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
					
						
							|  |  |  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | 
					
						
							|  |  |  |  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
					
						
							|  |  |  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
					
						
							|  |  |  |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
					
						
							|  |  |  |  * THE SOFTWARE. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | #include "hw.h"
 | 
					
						
							|  |  |  | #include "pci.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-11 14:59:56 +02:00
										 |  |  | #include "apb_pci.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | #include "pc.h"
 | 
					
						
							|  |  |  | #include "nvram.h"
 | 
					
						
							|  |  |  | #include "fdc.h"
 | 
					
						
							|  |  |  | #include "net.h"
 | 
					
						
							|  |  |  | #include "qemu-timer.h"
 | 
					
						
							|  |  |  | #include "sysemu.h"
 | 
					
						
							|  |  |  | #include "boards.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  | #include "firmware_abi.h"
 | 
					
						
							| 
									
										
										
										
											2008-09-18 18:27:29 +00:00
										 |  |  | #include "fw_cfg.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  | #include "sysbus.h"
 | 
					
						
							| 
									
										
										
										
											2009-08-20 15:22:20 +02:00
										 |  |  | #include "ide.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-20 14:58:02 +00:00
										 |  |  | #include "loader.h"
 | 
					
						
							|  |  |  | #include "elf.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-24 15:22:24 +00:00
										 |  |  | #include "blockdev.h"
 | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:16 -07:00
										 |  |  | #include "exec-memory.h"
 | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | //#define DEBUG_IRQ
 | 
					
						
							| 
									
										
										
										
											2009-12-30 12:27:17 +00:00
										 |  |  | //#define DEBUG_EBUS
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | //#define DEBUG_TIMER
 | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_IRQ
 | 
					
						
							| 
									
										
										
										
											2009-12-30 12:27:17 +00:00
										 |  |  | #define CPUIRQ_DPRINTF(fmt, ...)                                \
 | 
					
						
							| 
									
										
										
										
											2009-05-13 17:53:17 +00:00
										 |  |  |     do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0) | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2009-12-30 12:27:17 +00:00
										 |  |  | #define CPUIRQ_DPRINTF(fmt, ...)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_EBUS
 | 
					
						
							|  |  |  | #define EBUS_DPRINTF(fmt, ...)                                  \
 | 
					
						
							|  |  |  |     do { printf("EBUS: " fmt , ## __VA_ARGS__); } while (0) | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define EBUS_DPRINTF(fmt, ...)
 | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | #ifdef DEBUG_TIMER
 | 
					
						
							|  |  |  | #define TIMER_DPRINTF(fmt, ...)                                  \
 | 
					
						
							|  |  |  |     do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0) | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define TIMER_DPRINTF(fmt, ...)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  | #define KERNEL_LOAD_ADDR     0x00404000
 | 
					
						
							|  |  |  | #define CMDLINE_ADDR         0x003ff000
 | 
					
						
							| 
									
										
										
										
											2008-04-27 15:29:18 +00:00
										 |  |  | #define PROM_SIZE_MAX        (4 * 1024 * 1024)
 | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  | #define PROM_VADDR           0x000ffd00000ULL
 | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  | #define APB_SPECIAL_BASE     0x1fe00000000ULL
 | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  | #define APB_MEM_BASE         0x1ff00000000ULL
 | 
					
						
							| 
									
										
										
										
											2010-05-25 16:09:03 +04:00
										 |  |  | #define APB_PCI_IO_BASE      (APB_SPECIAL_BASE + 0x02000000ULL)
 | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  | #define PROM_FILENAME        "openbios-sparc64"
 | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  | #define NVRAM_SIZE           0x2000
 | 
					
						
							| 
									
										
										
										
											2007-12-02 04:51:10 +00:00
										 |  |  | #define MAX_IDE_BUS          2
 | 
					
						
							| 
									
										
										
										
											2008-09-18 18:27:29 +00:00
										 |  |  | #define BIOS_CFG_IOPORT      0x510
 | 
					
						
							| 
									
										
										
										
											2009-08-08 10:44:56 +00:00
										 |  |  | #define FW_CFG_SPARC64_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
 | 
					
						
							|  |  |  | #define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
 | 
					
						
							|  |  |  | #define FW_CFG_SPARC64_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
 | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  | #define IVEC_MAX             0x30
 | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 08:47:26 +00:00
										 |  |  | #define TICK_MAX             0x7fffffffffffffffULL
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  | struct hwdef { | 
					
						
							|  |  |  |     const char * const default_cpu_model; | 
					
						
							| 
									
										
										
										
											2008-09-18 18:33:18 +00:00
										 |  |  |     uint16_t machine_id; | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |     uint64_t prom_addr; | 
					
						
							|  |  |  |     uint64_t console_serial_base; | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:22 +03:00
										 |  |  | typedef struct EbusState { | 
					
						
							|  |  |  |     PCIDevice pci_dev; | 
					
						
							|  |  |  |     MemoryRegion bar0; | 
					
						
							|  |  |  |     MemoryRegion bar1; | 
					
						
							|  |  |  | } EbusState; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | int DMA_get_channel_mode (int nchan) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | int DMA_read_memory (int nchan, void *buf, int pos, int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | int DMA_write_memory (int nchan, void *buf, int pos, int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void DMA_hold_DREQ (int nchan) {} | 
					
						
							|  |  |  | void DMA_release_DREQ (int nchan) {} | 
					
						
							|  |  |  | void DMA_schedule(int nchan) {} | 
					
						
							| 
									
										
										
										
											2010-05-22 08:00:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | void DMA_register_channel (int nchan, | 
					
						
							|  |  |  |                            DMA_transfer_handler transfer_handler, | 
					
						
							|  |  |  |                            void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 09:51:29 +00:00
										 |  |  | static int fw_cfg_boot_set(void *opaque, const char *boot_device) | 
					
						
							| 
									
										
										
										
											2008-06-20 16:25:56 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-08 09:51:29 +00:00
										 |  |  |     fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); | 
					
						
							| 
									
										
										
										
											2008-06-20 16:25:56 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-07 08:05:03 +00:00
										 |  |  | static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size, | 
					
						
							|  |  |  |                                   const char *arch, ram_addr_t RAM_size, | 
					
						
							|  |  |  |                                   const char *boot_devices, | 
					
						
							|  |  |  |                                   uint32_t kernel_image, uint32_t kernel_size, | 
					
						
							|  |  |  |                                   const char *cmdline, | 
					
						
							|  |  |  |                                   uint32_t initrd_image, uint32_t initrd_size, | 
					
						
							|  |  |  |                                   uint32_t NVRAM_image, | 
					
						
							|  |  |  |                                   int width, int height, int depth, | 
					
						
							|  |  |  |                                   const uint8_t *macaddr) | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-01 14:16:52 +00:00
										 |  |  |     unsigned int i; | 
					
						
							|  |  |  |     uint32_t start, end; | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  |     uint8_t image[0x1ff0]; | 
					
						
							|  |  |  |     struct OpenBIOS_nvpart_v1 *part_header; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     memset(image, '\0', sizeof(image)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 09:51:29 +00:00
										 |  |  |     start = 0; | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-01 14:16:52 +00:00
										 |  |  |     // OpenBIOS nvram variables
 | 
					
						
							|  |  |  |     // Variable partition
 | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  |     part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | 
					
						
							|  |  |  |     part_header->signature = OPENBIOS_PART_SYSTEM; | 
					
						
							| 
									
										
										
										
											2008-08-21 17:58:08 +00:00
										 |  |  |     pstrcpy(part_header->name, sizeof(part_header->name), "system"); | 
					
						
							| 
									
										
										
										
											2007-05-01 14:16:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  |     end = start + sizeof(struct OpenBIOS_nvpart_v1); | 
					
						
							| 
									
										
										
										
											2007-05-01 14:16:52 +00:00
										 |  |  |     for (i = 0; i < nb_prom_envs; i++) | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  |         end = OpenBIOS_set_var(image, end, prom_envs[i]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // End marker
 | 
					
						
							|  |  |  |     image[end++] = '\0'; | 
					
						
							| 
									
										
										
										
											2007-05-01 14:16:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     end = start + ((end - start + 15) & ~15); | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  |     OpenBIOS_finish_partition(part_header, end - start); | 
					
						
							| 
									
										
										
										
											2007-05-01 14:16:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // free partition
 | 
					
						
							|  |  |  |     start = end; | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  |     part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | 
					
						
							|  |  |  |     part_header->signature = OPENBIOS_PART_FREE; | 
					
						
							| 
									
										
										
										
											2008-08-21 17:58:08 +00:00
										 |  |  |     pstrcpy(part_header->name, sizeof(part_header->name), "free"); | 
					
						
							| 
									
										
										
										
											2007-05-01 14:16:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     end = 0x1fd0; | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  |     OpenBIOS_finish_partition(part_header, end - start); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-15 14:54:01 +00:00
										 |  |  |     Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, 0x80); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-14 19:35:16 +00:00
										 |  |  |     for (i = 0; i < sizeof(image); i++) | 
					
						
							|  |  |  |         m48t59_write(nvram, i, image[i]); | 
					
						
							| 
									
										
										
										
											2007-05-01 14:16:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static uint64_t sun4u_load_kernel(const char *kernel_filename, | 
					
						
							|  |  |  |                                   const char *initrd_filename, | 
					
						
							|  |  |  |                                   ram_addr_t RAM_size, uint64_t *initrd_size, | 
					
						
							|  |  |  |                                   uint64_t *initrd_addr, uint64_t *kernel_addr, | 
					
						
							|  |  |  |                                   uint64_t *kernel_entry) | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int linux_boot; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  |     long kernel_size; | 
					
						
							| 
									
										
										
										
											2010-01-24 21:18:00 +00:00
										 |  |  |     uint8_t *ptr; | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |     uint64_t kernel_top; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     linux_boot = (kernel_filename != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     kernel_size = 0; | 
					
						
							|  |  |  |     if (linux_boot) { | 
					
						
							| 
									
										
										
										
											2009-09-20 14:58:02 +00:00
										 |  |  |         int bswap_needed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef BSWAP_NEEDED
 | 
					
						
							|  |  |  |         bswap_needed = 1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         bswap_needed = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |         kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry, | 
					
						
							|  |  |  |                                kernel_addr, &kernel_top, 1, ELF_MACHINE, 0); | 
					
						
							|  |  |  |         if (kernel_size < 0) { | 
					
						
							|  |  |  |             *kernel_addr = KERNEL_LOAD_ADDR; | 
					
						
							|  |  |  |             *kernel_entry = KERNEL_LOAD_ADDR; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  |             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, | 
					
						
							| 
									
										
										
										
											2009-09-20 14:58:02 +00:00
										 |  |  |                                     RAM_size - KERNEL_LOAD_ADDR, bswap_needed, | 
					
						
							|  |  |  |                                     TARGET_PAGE_SIZE); | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (kernel_size < 0) { | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  |             kernel_size = load_image_targphys(kernel_filename, | 
					
						
							|  |  |  |                                               KERNEL_LOAD_ADDR, | 
					
						
							|  |  |  |                                               RAM_size - KERNEL_LOAD_ADDR); | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  |         if (kernel_size < 0) { | 
					
						
							|  |  |  |             fprintf(stderr, "qemu: could not load kernel '%s'\n", | 
					
						
							|  |  |  |                     kernel_filename); | 
					
						
							|  |  |  |             exit(1); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |         /* load initrd above kernel */ | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  |         *initrd_size = 0; | 
					
						
							|  |  |  |         if (initrd_filename) { | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |             *initrd_addr = TARGET_PAGE_ALIGN(kernel_top); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  |             *initrd_size = load_image_targphys(initrd_filename, | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |                                                *initrd_addr, | 
					
						
							|  |  |  |                                                RAM_size - *initrd_addr); | 
					
						
							|  |  |  |             if ((int)*initrd_size < 0) { | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  |                 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", | 
					
						
							|  |  |  |                         initrd_filename); | 
					
						
							|  |  |  |                 exit(1); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (*initrd_size > 0) { | 
					
						
							|  |  |  |             for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) { | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |                 ptr = rom_ptr(*kernel_addr + i); | 
					
						
							| 
									
										
										
										
											2010-01-24 21:18:00 +00:00
										 |  |  |                 if (ldl_p(ptr + 8) == 0x48647253) { /* HdrS */ | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |                     stl_p(ptr + 24, *initrd_addr + *kernel_addr); | 
					
						
							| 
									
										
										
										
											2010-01-24 21:18:00 +00:00
										 |  |  |                     stl_p(ptr + 28, *initrd_size); | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return kernel_size; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  | void cpu_check_irqs(CPUSPARCState *env) | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-07 23:28:31 +03:00
										 |  |  |     uint32_t pil = env->pil_in | | 
					
						
							|  |  |  |                   (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 17:49:05 +02:00
										 |  |  |     /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */ | 
					
						
							|  |  |  |     if (env->ivec_status & 0x20) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-07 23:28:31 +03:00
										 |  |  |     /* check if TM or SM in SOFTINT are set
 | 
					
						
							|  |  |  |        setting these also causes interrupt 14 */ | 
					
						
							|  |  |  |     if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) { | 
					
						
							|  |  |  |         pil |= 1 << 14; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-25 19:22:38 +02:00
										 |  |  |     /* The bit corresponding to psrpil is (1<< psrpil), the next bit
 | 
					
						
							|  |  |  |        is (2 << psrpil). */ | 
					
						
							|  |  |  |     if (pil < (2 << env->psrpil)){ | 
					
						
							| 
									
										
										
										
											2010-01-07 23:28:31 +03:00
										 |  |  |         if (env->interrupt_request & CPU_INTERRUPT_HARD) { | 
					
						
							|  |  |  |             CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n", | 
					
						
							|  |  |  |                            env->interrupt_index); | 
					
						
							|  |  |  |             env->interrupt_index = 0; | 
					
						
							|  |  |  |             cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (cpu_interrupts_enabled(env)) { | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-07 23:28:31 +03:00
										 |  |  |         for (i = 15; i > env->psrpil; i--) { | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  |             if (pil & (1 << i)) { | 
					
						
							|  |  |  |                 int old_interrupt = env->interrupt_index; | 
					
						
							| 
									
										
										
										
											2010-01-07 23:28:31 +03:00
										 |  |  |                 int new_interrupt = TT_EXTINT | i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 17:49:05 +02:00
										 |  |  |                 if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt | 
					
						
							|  |  |  |                   && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) { | 
					
						
							| 
									
										
										
										
											2010-01-07 23:28:31 +03:00
										 |  |  |                     CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d " | 
					
						
							|  |  |  |                                    "current %x >= pending %x\n", | 
					
						
							|  |  |  |                                    env->tl, cpu_tsptr(env)->tt, new_interrupt); | 
					
						
							|  |  |  |                 } else if (old_interrupt != new_interrupt) { | 
					
						
							|  |  |  |                     env->interrupt_index = new_interrupt; | 
					
						
							|  |  |  |                     CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i, | 
					
						
							|  |  |  |                                    old_interrupt, new_interrupt); | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  |                     cpu_interrupt(env, CPU_INTERRUPT_HARD); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-07-25 19:22:38 +02:00
										 |  |  |     } else if (env->interrupt_request & CPU_INTERRUPT_HARD) { | 
					
						
							| 
									
										
										
										
											2010-01-07 23:28:31 +03:00
										 |  |  |         CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x " | 
					
						
							|  |  |  |                        "current interrupt %x\n", | 
					
						
							|  |  |  |                        pil, env->pil_in, env->softint, env->interrupt_index); | 
					
						
							| 
									
										
										
										
											2011-07-25 19:22:38 +02:00
										 |  |  |         env->interrupt_index = 0; | 
					
						
							|  |  |  |         cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  | static void cpu_kick_irq(CPUSPARCState *env) | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     env->halted = 0; | 
					
						
							|  |  |  |     cpu_check_irqs(env); | 
					
						
							| 
									
										
										
										
											2011-03-12 17:43:57 +01:00
										 |  |  |     qemu_cpu_kick(env); | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  | static void cpu_set_ivec_irq(void *opaque, int irq, int level) | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  |     CPUSPARCState *env = opaque; | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (level) { | 
					
						
							| 
									
										
										
										
											2012-04-03 17:49:04 +02:00
										 |  |  |         if (!(env->ivec_status & 0x20)) { | 
					
						
							|  |  |  |             CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq); | 
					
						
							|  |  |  |             env->halted = 0; | 
					
						
							|  |  |  |             env->interrupt_index = TT_IVEC; | 
					
						
							|  |  |  |             env->ivec_status |= 0x20; | 
					
						
							|  |  |  |             env->ivec_data[0] = (0x1f << 6) | irq; | 
					
						
							|  |  |  |             env->ivec_data[1] = 0; | 
					
						
							|  |  |  |             env->ivec_data[2] = 0; | 
					
						
							|  |  |  |             cpu_interrupt(env, CPU_INTERRUPT_HARD); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         if (env->ivec_status & 0x20) { | 
					
						
							|  |  |  |             CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq); | 
					
						
							|  |  |  |             env->ivec_status &= ~0x20; | 
					
						
							|  |  |  |             cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-09-22 19:50:28 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  | typedef struct ResetData { | 
					
						
							| 
									
										
										
										
											2012-05-03 03:41:16 +02:00
										 |  |  |     SPARCCPU *cpu; | 
					
						
							| 
									
										
										
										
											2009-11-07 10:05:03 +00:00
										 |  |  |     uint64_t prom_addr; | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  | } ResetData; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | void cpu_put_timer(QEMUFile *f, CPUTimer *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qemu_put_be32s(f, &s->frequency); | 
					
						
							|  |  |  |     qemu_put_be32s(f, &s->disabled); | 
					
						
							|  |  |  |     qemu_put_be64s(f, &s->disabled_mask); | 
					
						
							|  |  |  |     qemu_put_sbe64s(f, &s->clock_offset); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qemu_put_timer(f, s->qtimer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void cpu_get_timer(QEMUFile *f, CPUTimer *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qemu_get_be32s(f, &s->frequency); | 
					
						
							|  |  |  |     qemu_get_be32s(f, &s->disabled); | 
					
						
							|  |  |  |     qemu_get_be64s(f, &s->disabled_mask); | 
					
						
							|  |  |  |     qemu_get_sbe64s(f, &s->clock_offset); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qemu_get_timer(f, s->qtimer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  | static CPUTimer* cpu_timer_create(const char* name, CPUSPARCState *env, | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |                                   QEMUBHFunc *cb, uint32_t frequency, | 
					
						
							|  |  |  |                                   uint64_t disabled_mask) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-20 22:09:37 -05:00
										 |  |  |     CPUTimer *timer = g_malloc0(sizeof (CPUTimer)); | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     timer->name = name; | 
					
						
							|  |  |  |     timer->frequency = frequency; | 
					
						
							|  |  |  |     timer->disabled_mask = disabled_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     timer->disabled = 1; | 
					
						
							| 
									
										
										
										
											2011-03-11 16:47:48 +01:00
										 |  |  |     timer->clock_offset = qemu_get_clock_ns(vm_clock); | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 16:47:48 +01:00
										 |  |  |     timer->qtimer = qemu_new_timer_ns(vm_clock, cb, env); | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return timer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void cpu_timer_reset(CPUTimer *timer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     timer->disabled = 1; | 
					
						
							| 
									
										
										
										
											2011-03-11 16:47:48 +01:00
										 |  |  |     timer->clock_offset = qemu_get_clock_ns(vm_clock); | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     qemu_del_timer(timer->qtimer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-21 23:33:12 +00:00
										 |  |  | static void main_cpu_reset(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |     ResetData *s = (ResetData *)opaque; | 
					
						
							| 
									
										
										
										
											2012-05-03 03:41:16 +02:00
										 |  |  |     CPUSPARCState *env = &s->cpu->env; | 
					
						
							| 
									
										
										
										
											2009-11-07 10:05:03 +00:00
										 |  |  |     static unsigned int nr_resets; | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-03 03:41:16 +02:00
										 |  |  |     cpu_reset(CPU(s->cpu)); | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     cpu_timer_reset(env->tick); | 
					
						
							|  |  |  |     cpu_timer_reset(env->stick); | 
					
						
							|  |  |  |     cpu_timer_reset(env->hstick); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |     env->gregs[1] = 0; // Memory start
 | 
					
						
							|  |  |  |     env->gregs[2] = ram_size; // Memory size
 | 
					
						
							|  |  |  |     env->gregs[3] = 0; // Machine description XXX
 | 
					
						
							| 
									
										
										
										
											2009-11-07 10:05:03 +00:00
										 |  |  |     if (nr_resets++ == 0) { | 
					
						
							|  |  |  |         /* Power on reset */ | 
					
						
							|  |  |  |         env->pc = s->prom_addr + 0x20ULL; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         env->pc = s->prom_addr + 0x40ULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |     env->npc = env->pc + 4; | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-10 10:12:00 +00:00
										 |  |  | static void tick_irq(void *opaque) | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  |     CPUSPARCState *env = opaque; | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |     CPUTimer* timer = env->tick; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (timer->disabled) { | 
					
						
							|  |  |  |         CPUIRQ_DPRINTF("tick_irq: softint disabled\n"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         CPUIRQ_DPRINTF("tick: fire\n"); | 
					
						
							| 
									
										
										
										
											2008-12-23 08:47:26 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     env->softint |= SOFTINT_TIMER; | 
					
						
							|  |  |  |     cpu_kick_irq(env); | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-10 10:12:00 +00:00
										 |  |  | static void stick_irq(void *opaque) | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  |     CPUSPARCState *env = opaque; | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |     CPUTimer* timer = env->stick; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (timer->disabled) { | 
					
						
							|  |  |  |         CPUIRQ_DPRINTF("stick_irq: softint disabled\n"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         CPUIRQ_DPRINTF("stick: fire\n"); | 
					
						
							| 
									
										
										
										
											2008-12-23 08:47:26 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     env->softint |= SOFTINT_STIMER; | 
					
						
							|  |  |  |     cpu_kick_irq(env); | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-10 10:12:00 +00:00
										 |  |  | static void hstick_irq(void *opaque) | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  |     CPUSPARCState *env = opaque; | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |     CPUTimer* timer = env->hstick; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (timer->disabled) { | 
					
						
							|  |  |  |         CPUIRQ_DPRINTF("hstick_irq: softint disabled\n"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         CPUIRQ_DPRINTF("hstick: fire\n"); | 
					
						
							| 
									
										
										
										
											2008-12-23 08:47:26 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     env->softint |= SOFTINT_STIMER; | 
					
						
							|  |  |  |     cpu_kick_irq(env); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int64_t cpu_to_timer_ticks(int64_t cpu_ticks, uint32_t frequency) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return muldiv64(cpu_ticks, get_ticks_per_sec(), frequency); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return muldiv64(timer_ticks, frequency, get_ticks_per_sec()); | 
					
						
							| 
									
										
										
										
											2005-11-21 23:33:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | void cpu_tick_set_count(CPUTimer *timer, uint64_t count) | 
					
						
							| 
									
										
										
										
											2008-10-03 19:04:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |     uint64_t real_count = count & ~timer->disabled_mask; | 
					
						
							|  |  |  |     uint64_t disabled_bit = count & timer->disabled_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 16:47:48 +01:00
										 |  |  |     int64_t vm_clock_offset = qemu_get_clock_ns(vm_clock) - | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |                     cpu_to_timer_ticks(real_count, timer->frequency); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n", | 
					
						
							|  |  |  |                   timer->name, real_count, | 
					
						
							|  |  |  |                   timer->disabled?"disabled":"enabled", timer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     timer->disabled = disabled_bit ? 1 : 0; | 
					
						
							|  |  |  |     timer->clock_offset = vm_clock_offset; | 
					
						
							| 
									
										
										
										
											2008-10-03 19:04:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | uint64_t cpu_tick_get_count(CPUTimer *timer) | 
					
						
							| 
									
										
										
										
											2008-10-03 19:04:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |     uint64_t real_count = timer_to_cpu_ticks( | 
					
						
							| 
									
										
										
										
											2011-03-11 16:47:48 +01:00
										 |  |  |                     qemu_get_clock_ns(vm_clock) - timer->clock_offset, | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |                     timer->frequency); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n", | 
					
						
							|  |  |  |            timer->name, real_count, | 
					
						
							|  |  |  |            timer->disabled?"disabled":"enabled", timer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (timer->disabled) | 
					
						
							|  |  |  |         real_count |= timer->disabled_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return real_count; | 
					
						
							| 
									
										
										
										
											2008-10-03 19:04:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit) | 
					
						
							| 
									
										
										
										
											2008-10-03 19:04:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-11 16:47:48 +01:00
										 |  |  |     int64_t now = qemu_get_clock_ns(vm_clock); | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     uint64_t real_limit = limit & ~timer->disabled_mask; | 
					
						
							|  |  |  |     timer->disabled = (limit & timer->disabled_mask) ? 1 : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int64_t expires = cpu_to_timer_ticks(real_limit, timer->frequency) + | 
					
						
							|  |  |  |                     timer->clock_offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (expires < now) { | 
					
						
							|  |  |  |         expires = now + 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TIMER_DPRINTF("%s set_limit limit=0x%016lx (%s) p=%p " | 
					
						
							|  |  |  |                   "called with limit=0x%016lx at 0x%016lx (delta=0x%016lx)\n", | 
					
						
							|  |  |  |                   timer->name, real_limit, | 
					
						
							|  |  |  |                   timer->disabled?"disabled":"enabled", | 
					
						
							|  |  |  |                   timer, limit, | 
					
						
							|  |  |  |                   timer_to_cpu_ticks(now - timer->clock_offset, | 
					
						
							|  |  |  |                                      timer->frequency), | 
					
						
							|  |  |  |                   timer_to_cpu_ticks(expires - now, timer->frequency)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!real_limit) { | 
					
						
							|  |  |  |         TIMER_DPRINTF("%s set_limit limit=ZERO - not starting timer\n", | 
					
						
							|  |  |  |                 timer->name); | 
					
						
							|  |  |  |         qemu_del_timer(timer->qtimer); | 
					
						
							|  |  |  |     } else if (timer->disabled) { | 
					
						
							|  |  |  |         qemu_del_timer(timer->qtimer); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         qemu_mod_timer(timer->qtimer, expires); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-10-03 19:04:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  | static void isa_irq_handler(void *opaque, int n, int level) | 
					
						
							| 
									
										
										
										
											2009-08-28 19:04:13 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  |     static const int isa_irq_to_ivec[16] = { | 
					
						
							|  |  |  |         [1] = 0x29, /* keyboard */ | 
					
						
							|  |  |  |         [4] = 0x2b, /* serial */ | 
					
						
							|  |  |  |         [6] = 0x27, /* floppy */ | 
					
						
							|  |  |  |         [7] = 0x22, /* parallel */ | 
					
						
							|  |  |  |         [12] = 0x2a, /* mouse */ | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     qemu_irq *irqs = opaque; | 
					
						
							|  |  |  |     int ivec; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(n < 16); | 
					
						
							|  |  |  |     ivec = isa_irq_to_ivec[n]; | 
					
						
							|  |  |  |     EBUS_DPRINTF("Set ISA IRQ %d level %d -> ivec 0x%x\n", n, level, ivec); | 
					
						
							|  |  |  |     if (ivec) { | 
					
						
							|  |  |  |         qemu_set_irq(irqs[ivec], level); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-08-28 19:04:13 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-10 11:33:32 +00:00
										 |  |  | /* EBUS (Eight bit bus) bridge */ | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  | static ISABus * | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  | pci_ebus_init(PCIBus *bus, int devfn, qemu_irq *irqs) | 
					
						
							| 
									
										
										
										
											2009-01-10 11:33:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-08-28 19:04:13 +00:00
										 |  |  |     qemu_irq *isa_irq; | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:56 +01:00
										 |  |  |     PCIDevice *pci_dev; | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  |     ISABus *isa_bus; | 
					
						
							| 
									
										
										
										
											2009-08-28 19:04:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:56 +01:00
										 |  |  |     pci_dev = pci_create_simple(bus, devfn, "ebus"); | 
					
						
							|  |  |  |     isa_bus = DO_UPCAST(ISABus, qbus, | 
					
						
							|  |  |  |                         qdev_get_child_bus(&pci_dev->qdev, "isa.0")); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  |     isa_irq = qemu_allocate_irqs(isa_irq_handler, irqs, 16); | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  |     isa_bus_irqs(isa_bus, isa_irq); | 
					
						
							|  |  |  |     return isa_bus; | 
					
						
							| 
									
										
										
										
											2009-07-12 08:54:49 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-10 11:33:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-14 10:36:05 +02:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:22 +03:00
										 |  |  | pci_ebus_init1(PCIDevice *pci_dev) | 
					
						
							| 
									
										
										
										
											2009-07-12 08:54:49 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:22 +03:00
										 |  |  |     EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-10 15:28:11 -07:00
										 |  |  |     isa_bus_new(&pci_dev->qdev, pci_address_space_io(pci_dev)); | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
 | 
					
						
							|  |  |  |     pci_dev->config[0x05] = 0x00; | 
					
						
							|  |  |  |     pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
 | 
					
						
							|  |  |  |     pci_dev->config[0x07] = 0x03; // status = medium devsel
 | 
					
						
							|  |  |  |     pci_dev->config[0x09] = 0x00; // programming i/f
 | 
					
						
							|  |  |  |     pci_dev->config[0x0D] = 0x0a; // latency_timer
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     isa_mmio_setup(&s->bar0, 0x1000000); | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:31 +03:00
										 |  |  |     pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0); | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:22 +03:00
										 |  |  |     isa_mmio_setup(&s->bar1, 0x800000); | 
					
						
							| 
									
										
										
										
											2011-08-08 16:09:31 +03:00
										 |  |  |     pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1); | 
					
						
							| 
									
										
										
										
											2009-08-14 10:36:05 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2009-01-10 11:33:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-04 12:22:06 -06:00
										 |  |  | static void ebus_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     k->init = pci_ebus_init1; | 
					
						
							|  |  |  |     k->vendor_id = PCI_VENDOR_ID_SUN; | 
					
						
							|  |  |  |     k->device_id = PCI_DEVICE_ID_SUN_EBUS; | 
					
						
							|  |  |  |     k->revision = 0x01; | 
					
						
							|  |  |  |     k->class_id = PCI_CLASS_BRIDGE_OTHER; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  | static TypeInfo ebus_info = { | 
					
						
							|  |  |  |     .name          = "ebus", | 
					
						
							|  |  |  |     .parent        = TYPE_PCI_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(EbusState), | 
					
						
							|  |  |  |     .class_init    = ebus_class_init, | 
					
						
							| 
									
										
										
										
											2009-07-12 08:54:49 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 14:31:12 +02:00
										 |  |  | typedef struct PROMState { | 
					
						
							|  |  |  |     SysBusDevice busdev; | 
					
						
							|  |  |  |     MemoryRegion prom; | 
					
						
							|  |  |  | } PROMState; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-14 21:20:59 +01:00
										 |  |  | static uint64_t translate_prom_address(void *opaque, uint64_t addr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     target_phys_addr_t *base_addr = (target_phys_addr_t *)opaque; | 
					
						
							|  |  |  |     return addr + *base_addr - PROM_VADDR; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  | /* Boot PROM (OpenBIOS) */ | 
					
						
							| 
									
										
										
										
											2009-10-01 16:12:16 -05:00
										 |  |  | static void prom_init(target_phys_addr_t addr, const char *bios_name) | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     DeviceState *dev; | 
					
						
							|  |  |  |     SysBusDevice *s; | 
					
						
							|  |  |  |     char *filename; | 
					
						
							|  |  |  |     int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dev = qdev_create(NULL, "openprom"); | 
					
						
							| 
									
										
										
										
											2009-10-07 01:15:58 +02:00
										 |  |  |     qdev_init_nofail(dev); | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  |     s = sysbus_from_qdev(dev); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sysbus_mmio_map(s, 0, addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* load boot prom */ | 
					
						
							|  |  |  |     if (bios_name == NULL) { | 
					
						
							|  |  |  |         bios_name = PROM_FILENAME; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); | 
					
						
							|  |  |  |     if (filename) { | 
					
						
							| 
									
										
										
										
											2010-03-14 21:20:59 +01:00
										 |  |  |         ret = load_elf(filename, translate_prom_address, &addr, | 
					
						
							|  |  |  |                        NULL, NULL, NULL, 1, ELF_MACHINE, 0); | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  |         if (ret < 0 || ret > PROM_SIZE_MAX) { | 
					
						
							|  |  |  |             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-20 22:09:37 -05:00
										 |  |  |         g_free(filename); | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (ret < 0 || ret > PROM_SIZE_MAX) { | 
					
						
							|  |  |  |         fprintf(stderr, "qemu: could not load prom '%s'\n", bios_name); | 
					
						
							|  |  |  |         exit(1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-14 10:36:05 +02:00
										 |  |  | static int prom_init1(SysBusDevice *dev) | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-03 14:31:12 +02:00
										 |  |  |     PROMState *s = FROM_SYSBUS(PROMState, dev); | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 15:59:12 +02:00
										 |  |  |     memory_region_init_ram(&s->prom, "sun4u.prom", PROM_SIZE_MAX); | 
					
						
							|  |  |  |     vmstate_register_ram_global(&s->prom); | 
					
						
							| 
									
										
										
										
											2011-10-03 14:31:12 +02:00
										 |  |  |     memory_region_set_readonly(&s->prom, true); | 
					
						
							| 
									
										
										
										
											2011-11-27 11:38:10 +02:00
										 |  |  |     sysbus_init_mmio(dev, &s->prom); | 
					
						
							| 
									
										
										
										
											2009-08-14 10:36:05 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static Property prom_properties[] = { | 
					
						
							|  |  |  |     {/* end of property list */}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void prom_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  |     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     k->init = prom_init1; | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     dc->props = prom_properties; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  | static TypeInfo prom_info = { | 
					
						
							|  |  |  |     .name          = "openprom", | 
					
						
							|  |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(PROMState), | 
					
						
							|  |  |  |     .class_init    = prom_class_init, | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 10:04:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct RamDevice | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SysBusDevice busdev; | 
					
						
							| 
									
										
										
										
											2011-10-03 14:31:12 +02:00
										 |  |  |     MemoryRegion ram; | 
					
						
							| 
									
										
										
										
											2009-07-21 11:20:11 +00:00
										 |  |  |     uint64_t size; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:04:47 +00:00
										 |  |  | } RamDevice; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* System RAM */ | 
					
						
							| 
									
										
										
										
											2009-08-14 10:36:05 +02:00
										 |  |  | static int ram_init1(SysBusDevice *dev) | 
					
						
							| 
									
										
										
										
											2009-07-21 10:04:47 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     RamDevice *d = FROM_SYSBUS(RamDevice, dev); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 15:59:12 +02:00
										 |  |  |     memory_region_init_ram(&d->ram, "sun4u.ram", d->size); | 
					
						
							|  |  |  |     vmstate_register_ram_global(&d->ram); | 
					
						
							| 
									
										
										
										
											2011-11-27 11:38:10 +02:00
										 |  |  |     sysbus_init_mmio(dev, &d->ram); | 
					
						
							| 
									
										
										
										
											2009-08-14 10:36:05 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:04:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-01 16:12:16 -05:00
										 |  |  | static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size) | 
					
						
							| 
									
										
										
										
											2009-07-21 10:04:47 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     DeviceState *dev; | 
					
						
							|  |  |  |     SysBusDevice *s; | 
					
						
							|  |  |  |     RamDevice *d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* allocate RAM */ | 
					
						
							|  |  |  |     dev = qdev_create(NULL, "memory"); | 
					
						
							|  |  |  |     s = sysbus_from_qdev(dev); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     d = FROM_SYSBUS(RamDevice, s); | 
					
						
							|  |  |  |     d->size = RAM_size; | 
					
						
							| 
									
										
										
										
											2009-10-07 01:15:58 +02:00
										 |  |  |     qdev_init_nofail(dev); | 
					
						
							| 
									
										
										
										
											2009-07-21 10:04:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     sysbus_mmio_map(s, 0, addr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static Property ram_properties[] = { | 
					
						
							|  |  |  |     DEFINE_PROP_UINT64("size", RamDevice, size, 0), | 
					
						
							|  |  |  |     DEFINE_PROP_END_OF_LIST(), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void ram_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  |     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     k->init = ram_init1; | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     dc->props = ram_properties; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  | static TypeInfo ram_info = { | 
					
						
							|  |  |  |     .name          = "memory", | 
					
						
							|  |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(RamDevice), | 
					
						
							|  |  |  |     .class_init    = ram_class_init, | 
					
						
							| 
									
										
										
										
											2009-07-21 10:04:47 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-03 03:33:52 +02:00
										 |  |  | static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef) | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-03 03:29:49 +02:00
										 |  |  |     SPARCCPU *cpu; | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  |     CPUSPARCState *env; | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |     ResetData *reset_info; | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |     uint32_t   tick_frequency = 100*1000000; | 
					
						
							|  |  |  |     uint32_t  stick_frequency = 100*1000000; | 
					
						
							|  |  |  |     uint32_t hstick_frequency = 100*1000000; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-03 03:29:49 +02:00
										 |  |  |     if (cpu_model == NULL) { | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  |         cpu_model = hwdef->default_cpu_model; | 
					
						
							| 
									
										
										
										
											2012-05-03 03:29:49 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     cpu = cpu_sparc_init(cpu_model); | 
					
						
							|  |  |  |     if (cpu == NULL) { | 
					
						
							| 
									
										
										
										
											2007-03-25 07:55:52 +00:00
										 |  |  |         fprintf(stderr, "Unable to find Sparc CPU definition\n"); | 
					
						
							|  |  |  |         exit(1); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-05-03 03:29:49 +02:00
										 |  |  |     env = &cpu->env; | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |     env->tick = cpu_timer_create("tick", env, tick_irq, | 
					
						
							|  |  |  |                                   tick_frequency, TICK_NPT_MASK); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     env->stick = cpu_timer_create("stick", env, stick_irq, | 
					
						
							|  |  |  |                                    stick_frequency, TICK_INT_DIS); | 
					
						
							| 
									
										
										
										
											2007-05-25 18:50:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:00:53 +03:00
										 |  |  |     env->hstick = cpu_timer_create("hstick", env, hstick_irq, | 
					
						
							|  |  |  |                                     hstick_frequency, TICK_INT_DIS); | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-20 22:09:37 -05:00
										 |  |  |     reset_info = g_malloc0(sizeof(ResetData)); | 
					
						
							| 
									
										
										
										
											2012-05-03 03:41:16 +02:00
										 |  |  |     reset_info->cpu = cpu; | 
					
						
							| 
									
										
										
										
											2009-11-07 10:05:03 +00:00
										 |  |  |     reset_info->prom_addr = hwdef->prom_addr; | 
					
						
							| 
									
										
										
										
											2009-06-27 09:25:07 +02:00
										 |  |  |     qemu_register_reset(main_cpu_reset, reset_info); | 
					
						
							| 
									
										
										
										
											2005-11-21 23:33:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-03 03:33:52 +02:00
										 |  |  |     return cpu; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:46:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:21 -07:00
										 |  |  | static void sun4uv_init(MemoryRegion *address_space_mem, | 
					
						
							|  |  |  |                         ram_addr_t RAM_size, | 
					
						
							| 
									
										
										
										
											2009-07-21 10:46:23 +00:00
										 |  |  |                         const char *boot_devices, | 
					
						
							|  |  |  |                         const char *kernel_filename, const char *kernel_cmdline, | 
					
						
							|  |  |  |                         const char *initrd_filename, const char *cpu_model, | 
					
						
							|  |  |  |                         const struct hwdef *hwdef) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-03 03:33:52 +02:00
										 |  |  |     SPARCCPU *cpu; | 
					
						
							| 
									
										
										
										
											2012-03-14 01:38:24 +01:00
										 |  |  |     CPUSPARCState *env; | 
					
						
							| 
									
										
										
										
											2010-02-07 08:05:03 +00:00
										 |  |  |     M48t59State *nvram; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:46:23 +00:00
										 |  |  |     unsigned int i; | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |     uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:46:23 +00:00
										 |  |  |     PCIBus *pci_bus, *pci_bus2, *pci_bus3; | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  |     ISABus *isa_bus; | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  |     qemu_irq *ivec_irqs, *pbm_irqs; | 
					
						
							| 
									
										
										
										
											2009-08-28 15:47:03 +02:00
										 |  |  |     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | 
					
						
							| 
									
										
										
										
											2009-09-22 13:53:18 +02:00
										 |  |  |     DriveInfo *fd[MAX_FD]; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:46:23 +00:00
										 |  |  |     void *fw_cfg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* init CPUs */ | 
					
						
							| 
									
										
										
										
											2012-05-03 03:33:52 +02:00
										 |  |  |     cpu = cpu_devinit(cpu_model, hwdef); | 
					
						
							|  |  |  |     env = &cpu->env; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:46:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 10:04:47 +00:00
										 |  |  |     /* set up devices */ | 
					
						
							|  |  |  |     ram_init(0, RAM_size); | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 09:58:02 +00:00
										 |  |  |     prom_init(hwdef->prom_addr, bios_name); | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  |     ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, env, IVEC_MAX); | 
					
						
							|  |  |  |     pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2, | 
					
						
							|  |  |  |                            &pci_bus3, &pbm_irqs); | 
					
						
							| 
									
										
										
										
											2010-10-15 11:45:13 +02:00
										 |  |  |     pci_vga_init(pci_bus); | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-10 11:33:32 +00:00
										 |  |  |     // XXX Should be pci_bus3
 | 
					
						
							| 
									
										
										
										
											2012-03-10 20:37:00 +00:00
										 |  |  |     isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs); | 
					
						
							| 
									
										
										
										
											2009-01-10 11:33:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |     i = 0; | 
					
						
							|  |  |  |     if (hwdef->console_serial_base) { | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:21 -07:00
										 |  |  |         serial_mm_init(address_space_mem, hwdef->console_serial_base, 0, | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:16 -07:00
										 |  |  |                        NULL, 115200, serial_hds[i], DEVICE_BIG_ENDIAN); | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |         i++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for(; i < MAX_SERIAL_PORTS; i++) { | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  |         if (serial_hds[i]) { | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  |             serial_isa_init(isa_bus, i, serial_hds[i]); | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(i = 0; i < MAX_PARALLEL_PORTS; i++) { | 
					
						
							|  |  |  |         if (parallel_hds[i]) { | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  |             parallel_init(isa_bus, i, parallel_hds[i]); | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-13 19:47:10 +00:00
										 |  |  |     for(i = 0; i < nb_nics; i++) | 
					
						
							| 
									
										
										
										
											2009-09-25 03:53:51 +02:00
										 |  |  |         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-03 20:32:46 +09:00
										 |  |  |     ide_drive_get(hd, MAX_IDE_BUS); | 
					
						
							| 
									
										
										
										
											2007-12-02 04:51:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-17 18:41:53 +00:00
										 |  |  |     pci_cmd646_ide_init(pci_bus, hd, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  |     isa_create_simple(isa_bus, "i8042"); | 
					
						
							| 
									
										
										
										
											2007-12-02 04:51:10 +00:00
										 |  |  |     for(i = 0; i < MAX_FD; i++) { | 
					
						
							| 
									
										
										
										
											2009-09-22 13:53:18 +02:00
										 |  |  |         fd[i] = drive_get(IF_FLOPPY, 0, i); | 
					
						
							| 
									
										
										
										
											2007-12-02 04:51:10 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  |     fdctrl_init_isa(isa_bus, fd); | 
					
						
							|  |  |  |     nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59); | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     initrd_size = 0; | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |     initrd_addr = 0; | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  |     kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename, | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |                                     ram_size, &initrd_size, &initrd_addr, | 
					
						
							|  |  |  |                                     &kernel_addr, &kernel_entry); | 
					
						
							| 
									
										
										
										
											2009-07-21 10:49:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-10 10:12:00 +00:00
										 |  |  |     sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices, | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |                            kernel_addr, kernel_size, | 
					
						
							| 
									
										
										
										
											2008-07-15 14:54:01 +00:00
										 |  |  |                            kernel_cmdline, | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |                            initrd_addr, initrd_size, | 
					
						
							| 
									
										
										
										
											2008-07-15 14:54:01 +00:00
										 |  |  |                            /* XXX: need an option to load a NVRAM image */ | 
					
						
							|  |  |  |                            0, | 
					
						
							|  |  |  |                            graphic_width, graphic_height, graphic_depth, | 
					
						
							|  |  |  |                            (uint8_t *)&nd_table[0].macaddr); | 
					
						
							| 
									
										
										
										
											2005-07-23 14:27:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-18 18:27:29 +00:00
										 |  |  |     fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0); | 
					
						
							|  |  |  |     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); | 
					
						
							| 
									
										
										
										
											2008-09-18 18:33:18 +00:00
										 |  |  |     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); | 
					
						
							|  |  |  |     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |     fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry); | 
					
						
							|  |  |  |     fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); | 
					
						
							| 
									
										
										
										
											2009-03-08 09:51:29 +00:00
										 |  |  |     if (kernel_cmdline) { | 
					
						
							| 
									
										
										
										
											2010-01-09 21:27:04 +00:00
										 |  |  |         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, | 
					
						
							|  |  |  |                        strlen(kernel_cmdline) + 1); | 
					
						
							| 
									
										
										
										
											2009-12-27 18:25:49 +00:00
										 |  |  |         fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA, | 
					
						
							|  |  |  |                          (uint8_t*)strdup(kernel_cmdline), | 
					
						
							|  |  |  |                          strlen(kernel_cmdline) + 1); | 
					
						
							| 
									
										
										
										
											2009-03-08 09:51:29 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2010-01-09 21:27:04 +00:00
										 |  |  |         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0); | 
					
						
							| 
									
										
										
										
											2009-03-08 09:51:29 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-05-12 17:20:52 +00:00
										 |  |  |     fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); | 
					
						
							|  |  |  |     fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); | 
					
						
							| 
									
										
										
										
											2009-03-08 09:51:29 +00:00
										 |  |  |     fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]); | 
					
						
							| 
									
										
										
										
											2009-08-08 10:44:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width); | 
					
						
							|  |  |  |     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height); | 
					
						
							|  |  |  |     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH, graphic_depth); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 09:51:29 +00:00
										 |  |  |     qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-18 18:33:18 +00:00
										 |  |  | enum { | 
					
						
							|  |  |  |     sun4u_id = 0, | 
					
						
							|  |  |  |     sun4v_id = 64, | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |     niagara_id, | 
					
						
							| 
									
										
										
										
											2008-09-18 18:33:18 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  | static const struct hwdef hwdefs[] = { | 
					
						
							|  |  |  |     /* Sun4u generic PC-like machine */ | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-05-25 16:08:57 +04:00
										 |  |  |         .default_cpu_model = "TI UltraSparc IIi", | 
					
						
							| 
									
										
										
										
											2008-09-18 18:33:18 +00:00
										 |  |  |         .machine_id = sun4u_id, | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |         .prom_addr = 0x1fff0000000ULL, | 
					
						
							|  |  |  |         .console_serial_base = 0, | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |     /* Sun4v generic PC-like machine */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         .default_cpu_model = "Sun UltraSparc T1", | 
					
						
							| 
									
										
										
										
											2008-09-18 18:33:18 +00:00
										 |  |  |         .machine_id = sun4v_id, | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |         .prom_addr = 0x1fff0000000ULL, | 
					
						
							|  |  |  |         .console_serial_base = 0, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     /* Sun4v generic Niagara machine */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         .default_cpu_model = "Sun UltraSparc T1", | 
					
						
							|  |  |  |         .machine_id = niagara_id, | 
					
						
							|  |  |  |         .prom_addr = 0xfff0000000ULL, | 
					
						
							|  |  |  |         .console_serial_base = 0xfff0c2c000ULL, | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Sun4u hardware initialisation */ | 
					
						
							| 
									
										
										
										
											2009-10-01 16:12:16 -05:00
										 |  |  | static void sun4u_init(ram_addr_t RAM_size, | 
					
						
							| 
									
										
										
										
											2009-01-16 19:04:14 +00:00
										 |  |  |                        const char *boot_devices, | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  |                        const char *kernel_filename, const char *kernel_cmdline, | 
					
						
							|  |  |  |                        const char *initrd_filename, const char *cpu_model) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:21 -07:00
										 |  |  |     sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename, | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  |                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Sun4v hardware initialisation */ | 
					
						
							| 
									
										
										
										
											2009-10-01 16:12:16 -05:00
										 |  |  | static void sun4v_init(ram_addr_t RAM_size, | 
					
						
							| 
									
										
										
										
											2009-01-16 19:04:14 +00:00
										 |  |  |                        const char *boot_devices, | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  |                        const char *kernel_filename, const char *kernel_cmdline, | 
					
						
							|  |  |  |                        const char *initrd_filename, const char *cpu_model) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:21 -07:00
										 |  |  |     sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename, | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  |                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  | /* Niagara hardware initialisation */ | 
					
						
							| 
									
										
										
										
											2009-10-01 16:12:16 -05:00
										 |  |  | static void niagara_init(ram_addr_t RAM_size, | 
					
						
							| 
									
										
										
										
											2009-01-16 19:04:14 +00:00
										 |  |  |                          const char *boot_devices, | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |                          const char *kernel_filename, const char *kernel_cmdline, | 
					
						
							|  |  |  |                          const char *initrd_filename, const char *cpu_model) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:21 -07:00
										 |  |  |     sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename, | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-20 18:38:09 -05:00
										 |  |  | static QEMUMachine sun4u_machine = { | 
					
						
							| 
									
										
										
										
											2008-08-12 15:51:09 +00:00
										 |  |  |     .name = "sun4u", | 
					
						
							|  |  |  |     .desc = "Sun4u platform", | 
					
						
							|  |  |  |     .init = sun4u_init, | 
					
						
							| 
									
										
										
										
											2008-11-02 16:51:02 +00:00
										 |  |  |     .max_cpus = 1, // XXX for now
 | 
					
						
							| 
									
										
										
										
											2009-05-21 20:41:01 -05:00
										 |  |  |     .is_default = 1, | 
					
						
							| 
									
										
										
										
											2005-07-02 14:31:34 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-20 18:38:09 -05:00
										 |  |  | static QEMUMachine sun4v_machine = { | 
					
						
							| 
									
										
										
										
											2008-08-12 15:51:09 +00:00
										 |  |  |     .name = "sun4v", | 
					
						
							|  |  |  |     .desc = "Sun4v platform", | 
					
						
							|  |  |  |     .init = sun4v_init, | 
					
						
							| 
									
										
										
										
											2008-11-02 16:51:02 +00:00
										 |  |  |     .max_cpus = 1, // XXX for now
 | 
					
						
							| 
									
										
										
										
											2008-07-22 07:07:34 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-20 18:38:09 -05:00
										 |  |  | static QEMUMachine niagara_machine = { | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  |     .name = "Niagara", | 
					
						
							|  |  |  |     .desc = "Sun4v platform, Niagara", | 
					
						
							|  |  |  |     .init = niagara_init, | 
					
						
							| 
									
										
										
										
											2008-11-02 16:51:02 +00:00
										 |  |  |     .max_cpus = 1, // XXX for now
 | 
					
						
							| 
									
										
										
										
											2008-09-26 19:48:58 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-05-20 18:38:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void sun4u_register_types(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     type_register_static(&ebus_info); | 
					
						
							|  |  |  |     type_register_static(&prom_info); | 
					
						
							|  |  |  |     type_register_static(&ram_info); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-20 18:38:09 -05:00
										 |  |  | static void sun4u_machine_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qemu_register_machine(&sun4u_machine); | 
					
						
							|  |  |  |     qemu_register_machine(&sun4v_machine); | 
					
						
							|  |  |  |     qemu_register_machine(&niagara_machine); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | type_init(sun4u_register_types) | 
					
						
							| 
									
										
										
										
											2009-05-20 18:38:09 -05:00
										 |  |  | machine_init(sun4u_machine_init); |