Commit 8346901560d96edf94b803fd3f94db940ad370b3

Authored by bellard
1 parent b7c7b181

sparc64 fixes (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1514 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -297,7 +297,10 @@ VL_OBJS+= mips_r4k.o dma.o vga.o serial.o ne2000.o i8259.o @@ -297,7 +297,10 @@ VL_OBJS+= mips_r4k.o dma.o vga.o serial.o ne2000.o i8259.o
297 endif 297 endif
298 ifeq ($(TARGET_BASE_ARCH), sparc) 298 ifeq ($(TARGET_BASE_ARCH), sparc)
299 ifeq ($(TARGET_ARCH), sparc64) 299 ifeq ($(TARGET_ARCH), sparc64)
300 -VL_OBJS+= sun4u.o m48t08.o magic-load.o slavio_serial.o 300 +VL_OBJS+= sun4u.o ide.o ne2000.o pckbd.o vga.o
  301 +VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
  302 +VL_OBJS+= cirrus_vga.o parallel.o
  303 +VL_OBJS+= magic-load.o
301 else 304 else
302 VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t08.o magic-load.o slavio_intctl.o slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o 305 VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t08.o magic-load.o slavio_intctl.o slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o
303 endif 306 endif
configure
@@ -153,6 +153,8 @@ for opt do @@ -153,6 +153,8 @@ for opt do
153 ;; 153 ;;
154 --cc=*) cc=`echo $opt | cut -d '=' -f 2` 154 --cc=*) cc=`echo $opt | cut -d '=' -f 2`
155 ;; 155 ;;
  156 + --host-cc=*) host_cc=`echo $opt | cut -d '=' -f 2`
  157 + ;;
156 --make=*) make=`echo $opt | cut -d '=' -f 2` 158 --make=*) make=`echo $opt | cut -d '=' -f 2`
157 ;; 159 ;;
158 --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}" 160 --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
@@ -339,6 +341,7 @@ echo "Advanced options (experts only):" @@ -339,6 +341,7 @@ echo "Advanced options (experts only):"
339 echo " --source-path=PATH path of source code [$source_path]" 341 echo " --source-path=PATH path of source code [$source_path]"
340 echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]" 342 echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]"
341 echo " --cc=CC use C compiler CC [$cc]" 343 echo " --cc=CC use C compiler CC [$cc]"
  344 +echo " --host-cc=CC use C compiler CC [$cc] for dyngen etc."
342 echo " --make=MAKE use specified make [$make]" 345 echo " --make=MAKE use specified make [$make]"
343 echo " --static enable static build [$static]" 346 echo " --static enable static build [$static]"
344 echo " --enable-mingw32 enable Win32 cross compilation with mingw32" 347 echo " --enable-mingw32 enable Win32 cross compilation with mingw32"
@@ -420,6 +423,7 @@ echo "ELF interp prefix $interp_prefix" @@ -420,6 +423,7 @@ echo "ELF interp prefix $interp_prefix"
420 fi 423 fi
421 echo "Source path $source_path" 424 echo "Source path $source_path"
422 echo "C compiler $cc" 425 echo "C compiler $cc"
  426 +echo "Host C compiler $host_cc"
423 echo "make $make" 427 echo "make $make"
424 echo "host CPU $cpu" 428 echo "host CPU $cpu"
425 echo "host big endian $bigendian" 429 echo "host big endian $bigendian"
hw/magic-load.c
@@ -139,7 +139,7 @@ int load_elf(const char *filename, uint8_t *addr) @@ -139,7 +139,7 @@ int load_elf(const char *filename, uint8_t *addr)
139 139
140 if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD)) 140 if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD))
141 goto error; 141 goto error;
142 - retval = read_program64(fd, &phdr, addr, ehdr64.e_entry); 142 + retval = read_program64(fd, &phdr, phys_ram_base + ehdr64.e_entry, ehdr64.e_entry);
143 if (retval < 0) 143 if (retval < 0)
144 goto error; 144 goto error;
145 load_symbols64(&ehdr64, fd); 145 load_symbols64(&ehdr64, fd);
hw/pci.c
@@ -1291,6 +1291,253 @@ PCIBus *pci_pmac_init(void) @@ -1291,6 +1291,253 @@ PCIBus *pci_pmac_init(void)
1291 return s; 1291 return s;
1292 } 1292 }
1293 1293
  1294 +/* Ultrasparc APB PCI host */
  1295 +static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
  1296 + uint32_t val)
  1297 +{
  1298 + PCIBus *s = opaque;
  1299 + int i;
  1300 +
  1301 + for (i = 11; i < 32; i++) {
  1302 + if ((val & (1 << i)) != 0)
  1303 + break;
  1304 + }
  1305 + s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
  1306 +}
  1307 +
  1308 +static uint32_t pci_apb_config_readl (void *opaque,
  1309 + target_phys_addr_t addr)
  1310 +{
  1311 + PCIBus *s = opaque;
  1312 + uint32_t val;
  1313 + int devfn;
  1314 +
  1315 + devfn = (s->config_reg >> 8) & 0xFF;
  1316 + val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
  1317 + return val;
  1318 +}
  1319 +
  1320 +static CPUWriteMemoryFunc *pci_apb_config_write[] = {
  1321 + &pci_apb_config_writel,
  1322 + &pci_apb_config_writel,
  1323 + &pci_apb_config_writel,
  1324 +};
  1325 +
  1326 +static CPUReadMemoryFunc *pci_apb_config_read[] = {
  1327 + &pci_apb_config_readl,
  1328 + &pci_apb_config_readl,
  1329 + &pci_apb_config_readl,
  1330 +};
  1331 +
  1332 +static void apb_config_writel (void *opaque, target_phys_addr_t addr,
  1333 + uint32_t val)
  1334 +{
  1335 + //PCIBus *s = opaque;
  1336 +
  1337 + switch (addr & 0x3f) {
  1338 + case 0x00: // Control/Status
  1339 + case 0x10: // AFSR
  1340 + case 0x18: // AFAR
  1341 + case 0x20: // Diagnostic
  1342 + case 0x28: // Target address space
  1343 + // XXX
  1344 + default:
  1345 + break;
  1346 + }
  1347 +}
  1348 +
  1349 +static uint32_t apb_config_readl (void *opaque,
  1350 + target_phys_addr_t addr)
  1351 +{
  1352 + //PCIBus *s = opaque;
  1353 + uint32_t val;
  1354 +
  1355 + switch (addr & 0x3f) {
  1356 + case 0x00: // Control/Status
  1357 + case 0x10: // AFSR
  1358 + case 0x18: // AFAR
  1359 + case 0x20: // Diagnostic
  1360 + case 0x28: // Target address space
  1361 + // XXX
  1362 + default:
  1363 + val = 0;
  1364 + break;
  1365 + }
  1366 + return val;
  1367 +}
  1368 +
  1369 +static CPUWriteMemoryFunc *apb_config_write[] = {
  1370 + &apb_config_writel,
  1371 + &apb_config_writel,
  1372 + &apb_config_writel,
  1373 +};
  1374 +
  1375 +static CPUReadMemoryFunc *apb_config_read[] = {
  1376 + &apb_config_readl,
  1377 + &apb_config_readl,
  1378 + &apb_config_readl,
  1379 +};
  1380 +
  1381 +static void pci_apb_writeb (void *opaque, target_phys_addr_t addr,
  1382 + uint32_t val)
  1383 +{
  1384 + PCIBus *s = opaque;
  1385 +
  1386 + pci_data_write(s, addr & 7, val, 1);
  1387 +}
  1388 +
  1389 +static void pci_apb_writew (void *opaque, target_phys_addr_t addr,
  1390 + uint32_t val)
  1391 +{
  1392 + PCIBus *s = opaque;
  1393 +
  1394 + pci_data_write(s, addr & 7, val, 2);
  1395 +}
  1396 +
  1397 +static void pci_apb_writel (void *opaque, target_phys_addr_t addr,
  1398 + uint32_t val)
  1399 +{
  1400 + PCIBus *s = opaque;
  1401 +
  1402 + pci_data_write(s, addr & 7, val, 4);
  1403 +}
  1404 +
  1405 +static uint32_t pci_apb_readb (void *opaque, target_phys_addr_t addr)
  1406 +{
  1407 + PCIBus *s = opaque;
  1408 + uint32_t val;
  1409 +
  1410 + val = pci_data_read(s, addr & 7, 1);
  1411 + return val;
  1412 +}
  1413 +
  1414 +static uint32_t pci_apb_readw (void *opaque, target_phys_addr_t addr)
  1415 +{
  1416 + PCIBus *s = opaque;
  1417 + uint32_t val;
  1418 +
  1419 + val = pci_data_read(s, addr & 7, 2);
  1420 + return val;
  1421 +}
  1422 +
  1423 +static uint32_t pci_apb_readl (void *opaque, target_phys_addr_t addr)
  1424 +{
  1425 + PCIBus *s = opaque;
  1426 + uint32_t val;
  1427 +
  1428 + val = pci_data_read(s, addr, 4);
  1429 + return val;
  1430 +}
  1431 +
  1432 +static CPUWriteMemoryFunc *pci_apb_write[] = {
  1433 + &pci_apb_writeb,
  1434 + &pci_apb_writew,
  1435 + &pci_apb_writel,
  1436 +};
  1437 +
  1438 +static CPUReadMemoryFunc *pci_apb_read[] = {
  1439 + &pci_apb_readb,
  1440 + &pci_apb_readw,
  1441 + &pci_apb_readl,
  1442 +};
  1443 +
  1444 +static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
  1445 + uint32_t val)
  1446 +{
  1447 + cpu_outb(NULL, addr & 0xffff, val);
  1448 +}
  1449 +
  1450 +static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
  1451 + uint32_t val)
  1452 +{
  1453 + cpu_outw(NULL, addr & 0xffff, val);
  1454 +}
  1455 +
  1456 +static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
  1457 + uint32_t val)
  1458 +{
  1459 + cpu_outl(NULL, addr & 0xffff, val);
  1460 +}
  1461 +
  1462 +static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
  1463 +{
  1464 + uint32_t val;
  1465 +
  1466 + val = cpu_inb(NULL, addr & 0xffff);
  1467 + return val;
  1468 +}
  1469 +
  1470 +static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
  1471 +{
  1472 + uint32_t val;
  1473 +
  1474 + val = cpu_inw(NULL, addr & 0xffff);
  1475 + return val;
  1476 +}
  1477 +
  1478 +static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
  1479 +{
  1480 + uint32_t val;
  1481 +
  1482 + val = cpu_inl(NULL, addr & 0xffff);
  1483 + return val;
  1484 +}
  1485 +
  1486 +static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
  1487 + &pci_apb_iowriteb,
  1488 + &pci_apb_iowritew,
  1489 + &pci_apb_iowritel,
  1490 +};
  1491 +
  1492 +static CPUReadMemoryFunc *pci_apb_ioread[] = {
  1493 + &pci_apb_ioreadb,
  1494 + &pci_apb_ioreadw,
  1495 + &pci_apb_ioreadl,
  1496 +};
  1497 +
  1498 +PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base)
  1499 +{
  1500 + PCIBus *s;
  1501 + PCIDevice *d;
  1502 + int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
  1503 +
  1504 + /* Ultrasparc APB main bus */
  1505 + s = pci_register_bus();
  1506 + s->set_irq = pci_set_irq_simple;
  1507 +
  1508 + pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
  1509 + pci_apb_config_write, s);
  1510 + apb_config = cpu_register_io_memory(0, apb_config_read,
  1511 + apb_config_write, s);
  1512 + pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
  1513 + pci_apb_write, s);
  1514 + pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
  1515 + pci_apb_iowrite, s);
  1516 +
  1517 + cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
  1518 + cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
  1519 + cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
  1520 + cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
  1521 +
  1522 + d = pci_register_device(s, "Advanced PCI Bus", sizeof(PCIDevice),
  1523 + -1, NULL, NULL);
  1524 + d->config[0x00] = 0x8e; // vendor_id : Sun
  1525 + d->config[0x01] = 0x10;
  1526 + d->config[0x02] = 0x00; // device_id
  1527 + d->config[0x03] = 0xa0;
  1528 + d->config[0x04] = 0x06; // command = bus master, pci mem
  1529 + d->config[0x05] = 0x00;
  1530 + d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
  1531 + d->config[0x07] = 0x03; // status = medium devsel
  1532 + d->config[0x08] = 0x00; // revision
  1533 + d->config[0x09] = 0x00; // programming i/f
  1534 + d->config[0x0A] = 0x00; // class_sub = pci host
  1535 + d->config[0x0B] = 0x06; // class_base = PCI_bridge
  1536 + d->config[0x0D] = 0x10; // latency_timer
  1537 + d->config[0x0E] = 0x00; // header_type
  1538 + return s;
  1539 +}
  1540 +
1294 /***********************************************************/ 1541 /***********************************************************/
1295 /* generic PCI irq support */ 1542 /* generic PCI irq support */
1296 1543
hw/sun4u.c
@@ -22,23 +22,18 @@ @@ -22,23 +22,18 @@
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24 #include "vl.h" 24 #include "vl.h"
25 -#include "m48t08.h" 25 +#include "m48t59.h"
26 26
27 -#define KERNEL_LOAD_ADDR 0x00004000  
28 -#define CMDLINE_ADDR 0x007ff000  
29 -#define INITRD_LOAD_ADDR 0x00800000  
30 -#define PROM_ADDR 0xffd00000 27 +#define KERNEL_LOAD_ADDR 0x00404000
  28 +#define CMDLINE_ADDR 0x003ff000
  29 +#define INITRD_LOAD_ADDR 0x00300000
  30 +#define PROM_ADDR 0x1fff0000000ULL
  31 +#define APB_SPECIAL_BASE 0x1fe00000000ULL
  32 +#define APB_MEM_BASE 0x1ff00000000ULL
  33 +#define VGA_BASE (APB_MEM_BASE + 0x400000ULL)
31 #define PROM_FILENAMEB "proll-sparc64.bin" 34 #define PROM_FILENAMEB "proll-sparc64.bin"
32 #define PROM_FILENAMEE "proll-sparc64.elf" 35 #define PROM_FILENAMEE "proll-sparc64.elf"
33 -#define PHYS_JJ_EEPROM 0x71200000 /* m48t08 */  
34 -#define PHYS_JJ_IDPROM_OFF 0x1FD8  
35 -#define PHYS_JJ_EEPROM_SIZE 0x2000  
36 -// IRQs are not PIL ones, but master interrupt controller register  
37 -// bits  
38 -#define PHYS_JJ_MS_KBD 0x71000000 /* Mouse and keyboard */  
39 -#define PHYS_JJ_MS_KBD_IRQ 14  
40 -#define PHYS_JJ_SER 0x71100000 /* Serial */  
41 -#define PHYS_JJ_SER_IRQ 15 36 +#define NVRAM_SIZE 0x2000
42 37
43 /* TSC handling */ 38 /* TSC handling */
44 39
@@ -70,79 +65,170 @@ void DMA_register_channel (int nchan, @@ -70,79 +65,170 @@ void DMA_register_channel (int nchan,
70 { 65 {
71 } 66 }
72 67
73 -static void nvram_set_word (m48t08_t *nvram, uint32_t addr, uint16_t value) 68 +/* NVRAM helpers */
  69 +void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
74 { 70 {
75 - m48t08_write(nvram, addr++, (value >> 8) & 0xff);  
76 - m48t08_write(nvram, addr++, value & 0xff); 71 + m48t59_set_addr(nvram, addr);
  72 + m48t59_write(nvram, value);
77 } 73 }
78 74
79 -static void nvram_set_lword (m48t08_t *nvram, uint32_t addr, uint32_t value) 75 +uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
80 { 76 {
81 - m48t08_write(nvram, addr++, value >> 24);  
82 - m48t08_write(nvram, addr++, (value >> 16) & 0xff);  
83 - m48t08_write(nvram, addr++, (value >> 8) & 0xff);  
84 - m48t08_write(nvram, addr++, value & 0xff); 77 + m48t59_set_addr(nvram, addr);
  78 + return m48t59_read(nvram);
85 } 79 }
86 80
87 -static void nvram_set_string (m48t08_t *nvram, uint32_t addr, 81 +void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
  82 +{
  83 + m48t59_set_addr(nvram, addr);
  84 + m48t59_write(nvram, value >> 8);
  85 + m48t59_set_addr(nvram, addr + 1);
  86 + m48t59_write(nvram, value & 0xFF);
  87 +}
  88 +
  89 +uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
  90 +{
  91 + uint16_t tmp;
  92 +
  93 + m48t59_set_addr(nvram, addr);
  94 + tmp = m48t59_read(nvram) << 8;
  95 + m48t59_set_addr(nvram, addr + 1);
  96 + tmp |= m48t59_read(nvram);
  97 +
  98 + return tmp;
  99 +}
  100 +
  101 +void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
  102 +{
  103 + m48t59_set_addr(nvram, addr);
  104 + m48t59_write(nvram, value >> 24);
  105 + m48t59_set_addr(nvram, addr + 1);
  106 + m48t59_write(nvram, (value >> 16) & 0xFF);
  107 + m48t59_set_addr(nvram, addr + 2);
  108 + m48t59_write(nvram, (value >> 8) & 0xFF);
  109 + m48t59_set_addr(nvram, addr + 3);
  110 + m48t59_write(nvram, value & 0xFF);
  111 +}
  112 +
  113 +uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
  114 +{
  115 + uint32_t tmp;
  116 +
  117 + m48t59_set_addr(nvram, addr);
  118 + tmp = m48t59_read(nvram) << 24;
  119 + m48t59_set_addr(nvram, addr + 1);
  120 + tmp |= m48t59_read(nvram) << 16;
  121 + m48t59_set_addr(nvram, addr + 2);
  122 + tmp |= m48t59_read(nvram) << 8;
  123 + m48t59_set_addr(nvram, addr + 3);
  124 + tmp |= m48t59_read(nvram);
  125 +
  126 + return tmp;
  127 +}
  128 +
  129 +void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
88 const unsigned char *str, uint32_t max) 130 const unsigned char *str, uint32_t max)
89 { 131 {
90 - unsigned int i; 132 + int i;
91 133
92 for (i = 0; i < max && str[i] != '\0'; i++) { 134 for (i = 0; i < max && str[i] != '\0'; i++) {
93 - m48t08_write(nvram, addr + i, str[i]); 135 + m48t59_set_addr(nvram, addr + i);
  136 + m48t59_write(nvram, str[i]);
94 } 137 }
95 - m48t08_write(nvram, addr + max - 1, '\0'); 138 + m48t59_set_addr(nvram, addr + max - 1);
  139 + m48t59_write(nvram, '\0');
96 } 140 }
97 141
98 -static m48t08_t *nvram; 142 +int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
  143 +{
  144 + int i;
  145 +
  146 + memset(dst, 0, max);
  147 + for (i = 0; i < max; i++) {
  148 + dst[i] = NVRAM_get_byte(nvram, addr + i);
  149 + if (dst[i] == '\0')
  150 + break;
  151 + }
  152 +
  153 + return i;
  154 +}
  155 +
  156 +static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
  157 +{
  158 + uint16_t tmp;
  159 + uint16_t pd, pd1, pd2;
  160 +
  161 + tmp = prev >> 8;
  162 + pd = prev ^ value;
  163 + pd1 = pd & 0x000F;
  164 + pd2 = ((pd >> 4) & 0x000F) ^ pd1;
  165 + tmp ^= (pd1 << 3) | (pd1 << 8);
  166 + tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
  167 +
  168 + return tmp;
  169 +}
  170 +
  171 +uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
  172 +{
  173 + uint32_t i;
  174 + uint16_t crc = 0xFFFF;
  175 + int odd;
  176 +
  177 + odd = count & 1;
  178 + count &= ~1;
  179 + for (i = 0; i != count; i++) {
  180 + crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
  181 + }
  182 + if (odd) {
  183 + crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
  184 + }
  185 +
  186 + return crc;
  187 +}
99 188
100 extern int nographic; 189 extern int nographic;
101 190
102 -static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline,  
103 - int boot_device, uint32_t RAM_size,  
104 - uint32_t kernel_size,  
105 - int width, int height, int depth)  
106 -{  
107 - unsigned char tmp = 0;  
108 - int i, j;  
109 -  
110 - // Try to match PPC NVRAM  
111 - nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);  
112 - nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */  
113 - // NVRAM_size, arch not applicable  
114 - m48t08_write(nvram, 0x2F, nographic & 0xff);  
115 - nvram_set_lword(nvram, 0x30, RAM_size);  
116 - m48t08_write(nvram, 0x34, boot_device & 0xff);  
117 - nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR);  
118 - nvram_set_lword(nvram, 0x3C, kernel_size); 191 +int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
  192 + const unsigned char *arch,
  193 + uint32_t RAM_size, int boot_device,
  194 + uint32_t kernel_image, uint32_t kernel_size,
  195 + const char *cmdline,
  196 + uint32_t initrd_image, uint32_t initrd_size,
  197 + uint32_t NVRAM_image,
  198 + int width, int height, int depth)
  199 +{
  200 + uint16_t crc;
  201 +
  202 + /* Set parameters for Open Hack'Ware BIOS */
  203 + NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
  204 + NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */
  205 + NVRAM_set_word(nvram, 0x14, NVRAM_size);
  206 + NVRAM_set_string(nvram, 0x20, arch, 16);
  207 + NVRAM_set_byte(nvram, 0x2f, nographic & 0xff);
  208 + NVRAM_set_lword(nvram, 0x30, RAM_size);
  209 + NVRAM_set_byte(nvram, 0x34, boot_device);
  210 + NVRAM_set_lword(nvram, 0x38, kernel_image);
  211 + NVRAM_set_lword(nvram, 0x3C, kernel_size);
119 if (cmdline) { 212 if (cmdline) {
120 - strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);  
121 - nvram_set_lword(nvram, 0x40, CMDLINE_ADDR);  
122 - nvram_set_lword(nvram, 0x44, strlen(cmdline)); 213 + /* XXX: put the cmdline in NVRAM too ? */
  214 + strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
  215 + NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR);
  216 + NVRAM_set_lword(nvram, 0x44, strlen(cmdline));
  217 + } else {
  218 + NVRAM_set_lword(nvram, 0x40, 0);
  219 + NVRAM_set_lword(nvram, 0x44, 0);
123 } 220 }
124 - // initrd_image, initrd_size passed differently  
125 - nvram_set_word(nvram, 0x54, width);  
126 - nvram_set_word(nvram, 0x56, height);  
127 - nvram_set_word(nvram, 0x58, depth);  
128 -  
129 - // Sun4m specific use  
130 - i = 0x1fd8;  
131 - m48t08_write(nvram, i++, 0x01);  
132 - m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */  
133 - j = 0;  
134 - m48t08_write(nvram, i++, macaddr[j++]);  
135 - m48t08_write(nvram, i++, macaddr[j++]);  
136 - m48t08_write(nvram, i++, macaddr[j++]);  
137 - m48t08_write(nvram, i++, macaddr[j++]);  
138 - m48t08_write(nvram, i++, macaddr[j++]);  
139 - m48t08_write(nvram, i, macaddr[j]);  
140 -  
141 - /* Calculate checksum */  
142 - for (i = 0x1fd8; i < 0x1fe7; i++) {  
143 - tmp ^= m48t08_read(nvram, i);  
144 - }  
145 - m48t08_write(nvram, 0x1fe7, tmp); 221 + NVRAM_set_lword(nvram, 0x48, initrd_image);
  222 + NVRAM_set_lword(nvram, 0x4C, initrd_size);
  223 + NVRAM_set_lword(nvram, 0x50, NVRAM_image);
  224 +
  225 + NVRAM_set_word(nvram, 0x54, width);
  226 + NVRAM_set_word(nvram, 0x56, height);
  227 + NVRAM_set_word(nvram, 0x58, depth);
  228 + crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
  229 + NVRAM_set_word(nvram, 0xFC, crc);
  230 +
  231 + return 0;
146 } 232 }
147 233
148 void pic_info() 234 void pic_info()
@@ -157,21 +243,25 @@ void pic_set_irq(int irq, int level) @@ -157,21 +243,25 @@ void pic_set_irq(int irq, int level)
157 { 243 {
158 } 244 }
159 245
160 -void vga_update_display() 246 +void pic_set_irq_new(void *opaque, int irq, int level)
161 { 247 {
162 } 248 }
163 249
164 -void vga_invalidate_display() 250 +void qemu_system_powerdown(void)
165 { 251 {
166 } 252 }
167 253
168 -void vga_screen_dump(const char *filename)  
169 -{  
170 -} 254 +static const int ide_iobase[2] = { 0x1f0, 0x170 };
  255 +static const int ide_iobase2[2] = { 0x3f6, 0x376 };
  256 +static const int ide_irq[2] = { 14, 15 };
171 257
172 -void qemu_system_powerdown(void)  
173 -{  
174 -} 258 +static const int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
  259 +static const int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
  260 +
  261 +static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
  262 +static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
  263 +
  264 +static fdctrl_t *floppy_controller;
175 265
176 /* Sun4u hardware initialisation */ 266 /* Sun4u hardware initialisation */
177 static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, 267 static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
@@ -180,21 +270,18 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, @@ -180,21 +270,18 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
180 const char *initrd_filename) 270 const char *initrd_filename)
181 { 271 {
182 char buf[1024]; 272 char buf[1024];
  273 + m48t59_t *nvram;
183 int ret, linux_boot; 274 int ret, linux_boot;
184 unsigned int i; 275 unsigned int i;
185 - long vram_size = 0x100000, prom_offset, initrd_size, kernel_size; 276 + long prom_offset, initrd_size, kernel_size;
  277 + PCIBus *pci_bus;
186 278
187 linux_boot = (kernel_filename != NULL); 279 linux_boot = (kernel_filename != NULL);
188 280
189 /* allocate RAM */ 281 /* allocate RAM */
190 cpu_register_physical_memory(0, ram_size, 0); 282 cpu_register_physical_memory(0, ram_size, 0);
191 283
192 - nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE);  
193 - // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device  
194 - // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device  
195 - slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);  
196 -  
197 - prom_offset = ram_size + vram_size; 284 + prom_offset = ram_size + vga_ram_size;
198 285
199 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE); 286 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
200 ret = load_elf(buf, phys_ram_base + prom_offset); 287 ret = load_elf(buf, phys_ram_base + prom_offset);
@@ -211,6 +298,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, @@ -211,6 +298,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
211 prom_offset | IO_MEM_ROM); 298 prom_offset | IO_MEM_ROM);
212 299
213 kernel_size = 0; 300 kernel_size = 0;
  301 + initrd_size = 0;
214 if (linux_boot) { 302 if (linux_boot) {
215 kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); 303 kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
216 if (kernel_size < 0) 304 if (kernel_size < 0)
@@ -224,7 +312,6 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, @@ -224,7 +312,6 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
224 } 312 }
225 313
226 /* load initrd */ 314 /* load initrd */
227 - initrd_size = 0;  
228 if (initrd_filename) { 315 if (initrd_filename) {
229 initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR); 316 initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
230 if (initrd_size < 0) { 317 if (initrd_size < 0) {
@@ -244,7 +331,41 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, @@ -244,7 +331,41 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
244 } 331 }
245 } 332 }
246 } 333 }
247 - nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth); 334 + pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE);
  335 + isa_mem_base = VGA_BASE;
  336 + vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size,
  337 + vga_ram_size, 0, 0);
  338 + cpu_register_physical_memory(VGA_BASE, vga_ram_size, ram_size);
  339 + //pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size, vga_ram_size);
  340 +
  341 + for(i = 0; i < MAX_SERIAL_PORTS; i++) {
  342 + if (serial_hds[i]) {
  343 + serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
  344 + }
  345 + }
  346 +
  347 + for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
  348 + if (parallel_hds[i]) {
  349 + parallel_init(parallel_io[i], parallel_irq[i], parallel_hds[i]);
  350 + }
  351 + }
  352 +
  353 + for(i = 0; i < nb_nics; i++) {
  354 + pci_ne2000_init(pci_bus, &nd_table[i]);
  355 + }
  356 +
  357 + pci_cmd646_ide_init(pci_bus, bs_table, 1);
  358 + kbd_init();
  359 + floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
  360 + nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE);
  361 + sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device,
  362 + KERNEL_LOAD_ADDR, kernel_size,
  363 + kernel_cmdline,
  364 + INITRD_LOAD_ADDR, initrd_size,
  365 + /* XXX: need an option to load a NVRAM image */
  366 + 0,
  367 + graphic_width, graphic_height, graphic_depth);
  368 +
248 } 369 }
249 370
250 QEMUMachine sun4u_machine = { 371 QEMUMachine sun4u_machine = {
qemu-doc.texi
@@ -1058,6 +1058,19 @@ Set the initial TCX graphic mode. The default is 1024x768. @@ -1058,6 +1058,19 @@ Set the initial TCX graphic mode. The default is 1024x768.
1058 Use the executable @file{qemu-system-sparc64} to simulate a Sun4u machine. 1058 Use the executable @file{qemu-system-sparc64} to simulate a Sun4u machine.
1059 The emulator is not usable for anything yet. 1059 The emulator is not usable for anything yet.
1060 1060
  1061 +QEMU emulates the following sun4u peripherals:
  1062 +
  1063 +@itemize @minus
  1064 +@item
  1065 +UltraSparc IIi APB PCI Bridge
  1066 +@item
  1067 +PCI VGA compatible card with VESA Bochs Extensions
  1068 +@item
  1069 +Non Volatile RAM M48T59
  1070 +@item
  1071 +PC-compatible serial ports
  1072 +@end itemize
  1073 +
1061 @chapter MIPS System emulator invocation 1074 @chapter MIPS System emulator invocation
1062 1075
1063 Use the executable @file{qemu-system-mips} to simulate a MIPS machine. 1076 Use the executable @file{qemu-system-mips} to simulate a MIPS machine.
qemu-tech.texi
@@ -163,7 +163,6 @@ implemented. Floating point exception support is untested. @@ -163,7 +163,6 @@ implemented. Floating point exception support is untested.
163 @item Atomic instructions are not correctly implemented. 163 @item Atomic instructions are not correctly implemented.
164 164
165 @item Sparc64 emulators are not usable for anything yet. 165 @item Sparc64 emulators are not usable for anything yet.
166 -Address space is limited to first 4 gigabytes.  
167 166
168 @end itemize 167 @end itemize
169 168
target-sparc/cpu.h
@@ -6,9 +6,11 @@ @@ -6,9 +6,11 @@
6 #if !defined(TARGET_SPARC64) 6 #if !defined(TARGET_SPARC64)
7 #define TARGET_LONG_BITS 32 7 #define TARGET_LONG_BITS 32
8 #define TARGET_FPREGS 32 8 #define TARGET_FPREGS 32
  9 +#define TARGET_PAGE_BITS 12 /* 4k */
9 #else 10 #else
10 #define TARGET_LONG_BITS 64 11 #define TARGET_LONG_BITS 64
11 #define TARGET_FPREGS 64 12 #define TARGET_FPREGS 64
  13 +#define TARGET_PAGE_BITS 12 /* XXX */
12 #endif 14 #endif
13 #define TARGET_FPREG_T float 15 #define TARGET_FPREG_T float
14 16
@@ -35,6 +37,7 @@ @@ -35,6 +37,7 @@
35 #define TT_TRAP 0x80 37 #define TT_TRAP 0x80
36 #else 38 #else
37 #define TT_TFAULT 0x08 39 #define TT_TFAULT 0x08
  40 +#define TT_TMISS 0x09
38 #define TT_ILL_INSN 0x10 41 #define TT_ILL_INSN 0x10
39 #define TT_PRIV_INSN 0x11 42 #define TT_PRIV_INSN 0x11
40 #define TT_NFPU_INSN 0x20 43 #define TT_NFPU_INSN 0x20
@@ -42,6 +45,9 @@ @@ -42,6 +45,9 @@
42 #define TT_CLRWIN 0x24 45 #define TT_CLRWIN 0x24
43 #define TT_DIV_ZERO 0x28 46 #define TT_DIV_ZERO 0x28
44 #define TT_DFAULT 0x30 47 #define TT_DFAULT 0x30
  48 +#define TT_DMISS 0x31
  49 +#define TT_DPROT 0x32
  50 +#define TT_PRIV_ACT 0x37
45 #define TT_EXTINT 0x40 51 #define TT_EXTINT 0x40
46 #define TT_SPILL 0x80 52 #define TT_SPILL 0x80
47 #define TT_FILL 0xc0 53 #define TT_FILL 0xc0
@@ -65,10 +71,14 @@ @@ -65,10 +71,14 @@
65 #define TBR_BASE_MASK 0xfffff000 71 #define TBR_BASE_MASK 0xfffff000
66 72
67 #if defined(TARGET_SPARC64) 73 #if defined(TARGET_SPARC64)
  74 +#define PS_IG (1<<11)
  75 +#define PS_MG (1<<10)
  76 +#define PS_RED (1<<5)
68 #define PS_PEF (1<<4) 77 #define PS_PEF (1<<4)
69 #define PS_AM (1<<3) 78 #define PS_AM (1<<3)
70 #define PS_PRIV (1<<2) 79 #define PS_PRIV (1<<2)
71 #define PS_IE (1<<1) 80 #define PS_IE (1<<1)
  81 +#define PS_AG (1<<0)
72 #endif 82 #endif
73 83
74 /* Fcc */ 84 /* Fcc */
@@ -166,7 +176,7 @@ typedef struct CPUSPARCState { @@ -166,7 +176,7 @@ typedef struct CPUSPARCState {
166 context) */ 176 context) */
167 unsigned long mem_write_pc; /* host pc at which the memory was 177 unsigned long mem_write_pc; /* host pc at which the memory was
168 written */ 178 written */
169 - unsigned long mem_write_vaddr; /* target virtual addr at which the 179 + target_ulong mem_write_vaddr; /* target virtual addr at which the
170 memory was written */ 180 memory was written */
171 /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */ 181 /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */
172 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; 182 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
@@ -201,11 +211,13 @@ typedef struct CPUSPARCState { @@ -201,11 +211,13 @@ typedef struct CPUSPARCState {
201 uint32_t pstate; 211 uint32_t pstate;
202 uint32_t tl; 212 uint32_t tl;
203 uint32_t cansave, canrestore, otherwin, wstate, cleanwin; 213 uint32_t cansave, canrestore, otherwin, wstate, cleanwin;
204 - target_ulong agregs[8]; /* alternate general registers */  
205 - target_ulong igregs[8]; /* interrupt general registers */  
206 - target_ulong mgregs[8]; /* mmu general registers */ 214 + uint64_t agregs[8]; /* alternate general registers */
  215 + uint64_t bgregs[8]; /* backup for normal global registers */
  216 + uint64_t igregs[8]; /* interrupt general registers */
  217 + uint64_t mgregs[8]; /* mmu general registers */
207 uint64_t version; 218 uint64_t version;
208 uint64_t fprs; 219 uint64_t fprs;
  220 + uint64_t tick_cmpr, stick_cmpr;
209 #endif 221 #endif
210 #if !defined(TARGET_SPARC64) && !defined(reg_T2) 222 #if !defined(TARGET_SPARC64) && !defined(reg_T2)
211 target_ulong t2; 223 target_ulong t2;
@@ -275,7 +287,6 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); @@ -275,7 +287,6 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
275 struct siginfo; 287 struct siginfo;
276 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc); 288 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc);
277 289
278 -#define TARGET_PAGE_BITS 12 /* 4k */  
279 #include "cpu-all.h" 290 #include "cpu-all.h"
280 291
281 #endif 292 #endif
target-sparc/exec.h
@@ -65,6 +65,9 @@ void do_fcmpd_fcc2(void); @@ -65,6 +65,9 @@ void do_fcmpd_fcc2(void);
65 void do_fcmps_fcc3(void); 65 void do_fcmps_fcc3(void);
66 void do_fcmpd_fcc3(void); 66 void do_fcmpd_fcc3(void);
67 void do_popc(); 67 void do_popc();
  68 +void do_wrpstate();
  69 +void do_done();
  70 +void do_retry();
68 #endif 71 #endif
69 void do_ldd_kernel(target_ulong addr); 72 void do_ldd_kernel(target_ulong addr);
70 void do_ldd_user(target_ulong addr); 73 void do_ldd_user(target_ulong addr);
target-sparc/helper.c
1 /* 1 /*
2 * sparc helpers 2 * sparc helpers
3 * 3 *
4 - * Copyright (c) 2003 Fabrice Bellard 4 + * Copyright (c) 2003-2005 Fabrice Bellard
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,6 @@ @@ -28,7 +28,6 @@
28 #include "cpu.h" 28 #include "cpu.h"
29 #include "exec-all.h" 29 #include "exec-all.h"
30 30
31 -//#define DEBUG_PCALL  
32 //#define DEBUG_MMU 31 //#define DEBUG_MMU
33 32
34 /* Sparc MMU emulation */ 33 /* Sparc MMU emulation */
@@ -62,6 +61,9 @@ int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, @@ -62,6 +61,9 @@ int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
62 #else 61 #else
63 62
64 #ifndef TARGET_SPARC64 63 #ifndef TARGET_SPARC64
  64 +/*
  65 + * Sparc V8 Reference MMU (SRMMU)
  66 + */
65 static const int access_table[8][8] = { 67 static const int access_table[8][8] = {
66 { 0, 0, 0, 0, 2, 0, 3, 3 }, 68 { 0, 0, 0, 0, 2, 0, 3, 3 },
67 { 0, 0, 0, 0, 2, 0, 0, 0 }, 69 { 0, 0, 0, 0, 2, 0, 0, 0 },
@@ -229,6 +231,9 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -229,6 +231,9 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
229 } 231 }
230 } 232 }
231 #else 233 #else
  234 +/*
  235 + * UltraSparc IIi I/DMMUs
  236 + */
232 static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot, 237 static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
233 int *access_index, target_ulong address, int rw, 238 int *access_index, target_ulong address, int rw,
234 int is_user) 239 int is_user)
@@ -237,46 +242,55 @@ static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical @@ -237,46 +242,55 @@ static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical
237 unsigned int i; 242 unsigned int i;
238 243
239 if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */ 244 if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
240 - *physical = address & 0xffffffff; 245 + *physical = address;
241 *prot = PAGE_READ | PAGE_WRITE; 246 *prot = PAGE_READ | PAGE_WRITE;
242 return 0; 247 return 0;
243 } 248 }
244 249
245 for (i = 0; i < 64; i++) { 250 for (i = 0; i < 64; i++) {
246 - if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {  
247 - switch (env->dtlb_tte[i] >> 60) {  
248 - default:  
249 - case 0x4: // 8k  
250 - mask = 0xffffffffffffe000ULL;  
251 - break;  
252 - case 0x5: // 64k  
253 - mask = 0xffffffffffff0000ULL;  
254 - break;  
255 - case 0x6: // 512k  
256 - mask = 0xfffffffffff80000ULL;  
257 - break;  
258 - case 0x7: // 4M  
259 - mask = 0xffffffffffc00000ULL;  
260 - break;  
261 - }  
262 - // ctx match, vaddr match?  
263 - if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&  
264 - (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {  
265 - // access ok?  
266 - if (((env->dtlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) ||  
267 - (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {  
268 - env->exception_index = TT_DFAULT;  
269 - return 1;  
270 - }  
271 - *physical = env->dtlb_tte[i] & 0xffffe000;  
272 - *prot = PAGE_READ;  
273 - if (env->dtlb_tte[i] & 0x2)  
274 - *prot |= PAGE_WRITE;  
275 - return 0; 251 + switch ((env->dtlb_tte[i] >> 61) & 3) {
  252 + default:
  253 + case 0x0: // 8k
  254 + mask = 0xffffffffffffe000ULL;
  255 + break;
  256 + case 0x1: // 64k
  257 + mask = 0xffffffffffff0000ULL;
  258 + break;
  259 + case 0x2: // 512k
  260 + mask = 0xfffffffffff80000ULL;
  261 + break;
  262 + case 0x3: // 4M
  263 + mask = 0xffffffffffc00000ULL;
  264 + break;
  265 + }
  266 + // ctx match, vaddr match?
  267 + if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
  268 + (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
  269 + // valid, access ok?
  270 + if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
  271 + ((env->dtlb_tte[i] & 0x4) && is_user) ||
  272 + (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
  273 + if (env->dmmuregs[3]) /* Fault status register */
  274 + env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
  275 + env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
  276 + env->dmmuregs[4] = address; /* Fault address register */
  277 + env->exception_index = TT_DFAULT;
  278 +#ifdef DEBUG_MMU
  279 + printf("DFAULT at 0x%llx\n", address);
  280 +#endif
  281 + return 1;
276 } 282 }
  283 + *physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
  284 + *prot = PAGE_READ;
  285 + if (env->dtlb_tte[i] & 0x2)
  286 + *prot |= PAGE_WRITE;
  287 + return 0;
277 } 288 }
278 } 289 }
279 - env->exception_index = TT_DFAULT; 290 +#ifdef DEBUG_MMU
  291 + printf("DMISS at 0x%llx\n", address);
  292 +#endif
  293 + env->exception_index = TT_DMISS;
280 return 1; 294 return 1;
281 } 295 }
282 296
@@ -288,42 +302,51 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical @@ -288,42 +302,51 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
288 unsigned int i; 302 unsigned int i;
289 303
290 if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */ 304 if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
291 - *physical = address & 0xffffffff; 305 + *physical = address;
292 *prot = PAGE_READ; 306 *prot = PAGE_READ;
293 return 0; 307 return 0;
294 } 308 }
  309 +
295 for (i = 0; i < 64; i++) { 310 for (i = 0; i < 64; i++) {
296 - if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {  
297 - switch (env->itlb_tte[i] >> 60) {  
298 - default:  
299 - case 0x4: // 8k  
300 - mask = 0xffffffffffffe000ULL;  
301 - break;  
302 - case 0x5: // 64k  
303 - mask = 0xffffffffffff0000ULL;  
304 - break;  
305 - case 0x6: // 512k  
306 - mask = 0xfffffffffff80000ULL;  
307 - break;  
308 - case 0x7: // 4M  
309 - mask = 0xffffffffffc00000ULL; 311 + switch ((env->itlb_tte[i] >> 61) & 3) {
  312 + default:
  313 + case 0x0: // 8k
  314 + mask = 0xffffffffffffe000ULL;
  315 + break;
  316 + case 0x1: // 64k
  317 + mask = 0xffffffffffff0000ULL;
  318 + break;
  319 + case 0x2: // 512k
  320 + mask = 0xfffffffffff80000ULL;
  321 + break;
  322 + case 0x3: // 4M
  323 + mask = 0xffffffffffc00000ULL;
310 break; 324 break;
  325 + }
  326 + // ctx match, vaddr match?
  327 + if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
  328 + (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
  329 + // valid, access ok?
  330 + if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
  331 + ((env->itlb_tte[i] & 0x4) && is_user)) {
  332 + if (env->immuregs[3]) /* Fault status register */
  333 + env->immuregs[3] = 2; /* overflow (not read before another fault) */
  334 + env->immuregs[3] |= (is_user << 3) | 1;
  335 + env->exception_index = TT_TFAULT;
  336 +#ifdef DEBUG_MMU
  337 + printf("TFAULT at 0x%llx\n", address);
  338 +#endif
  339 + return 1;
311 } 340 }
312 - // ctx match, vaddr match?  
313 - if (env->immuregs[1] == (env->itlb_tag[i] & 0x1fff) &&  
314 - (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {  
315 - // access ok?  
316 - if ((env->itlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) {  
317 - env->exception_index = TT_TFAULT;  
318 - return 1;  
319 - }  
320 - *physical = env->itlb_tte[i] & 0xffffe000;  
321 - *prot = PAGE_READ;  
322 - return 0;  
323 - } 341 + *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
  342 + *prot = PAGE_READ;
  343 + return 0;
324 } 344 }
325 } 345 }
326 - env->exception_index = TT_TFAULT; 346 +#ifdef DEBUG_MMU
  347 + printf("TMISS at 0x%llx\n", address);
  348 +#endif
  349 + env->exception_index = TT_TMISS;
327 return 1; 350 return 1;
328 } 351 }
329 352
@@ -341,15 +364,17 @@ int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot, @@ -341,15 +364,17 @@ int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
341 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 364 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
342 int is_user, int is_softmmu) 365 int is_user, int is_softmmu)
343 { 366 {
344 - target_ulong virt_addr; 367 + target_ulong virt_addr, vaddr;
345 target_phys_addr_t paddr; 368 target_phys_addr_t paddr;
346 - unsigned long vaddr;  
347 int error_code = 0, prot, ret = 0, access_index; 369 int error_code = 0, prot, ret = 0, access_index;
348 370
349 error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user); 371 error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
350 if (error_code == 0) { 372 if (error_code == 0) {
351 virt_addr = address & TARGET_PAGE_MASK; 373 virt_addr = address & TARGET_PAGE_MASK;
352 vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1)); 374 vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
  375 +#ifdef DEBUG_MMU
  376 + printf("Translate at 0x%llx -> 0x%llx, vaddr 0x%llx\n", address, paddr, vaddr);
  377 +#endif
353 ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); 378 ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
354 return ret; 379 return ret;
355 } 380 }
@@ -471,4 +496,77 @@ void dump_mmu(CPUState *env) @@ -471,4 +496,77 @@ void dump_mmu(CPUState *env)
471 printf("MMU dump ends\n"); 496 printf("MMU dump ends\n");
472 } 497 }
473 #endif 498 #endif
  499 +#else
  500 +#ifdef DEBUG_MMU
  501 +void dump_mmu(CPUState *env)
  502 +{
  503 + unsigned int i;
  504 + const char *mask;
  505 +
  506 + printf("MMU contexts: Primary: %lld, Secondary: %lld\n", env->dmmuregs[1], env->dmmuregs[2]);
  507 + if ((env->lsu & DMMU_E) == 0) {
  508 + printf("DMMU disabled\n");
  509 + } else {
  510 + printf("DMMU dump:\n");
  511 + for (i = 0; i < 64; i++) {
  512 + switch ((env->dtlb_tte[i] >> 61) & 3) {
  513 + default:
  514 + case 0x0:
  515 + mask = " 8k";
  516 + break;
  517 + case 0x1:
  518 + mask = " 64k";
  519 + break;
  520 + case 0x2:
  521 + mask = "512k";
  522 + break;
  523 + case 0x3:
  524 + mask = " 4M";
  525 + break;
  526 + }
  527 + if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
  528 + printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %lld\n",
  529 + env->dtlb_tag[i] & ~0x1fffULL,
  530 + env->dtlb_tte[i] & 0x1ffffffe000ULL,
  531 + mask,
  532 + env->dtlb_tte[i] & 0x4? "priv": "user",
  533 + env->dtlb_tte[i] & 0x2? "RW": "RO",
  534 + env->dtlb_tte[i] & 0x40? "locked": "unlocked",
  535 + env->dtlb_tag[i] & 0x1fffULL);
  536 + }
  537 + }
  538 + }
  539 + if ((env->lsu & IMMU_E) == 0) {
  540 + printf("IMMU disabled\n");
  541 + } else {
  542 + printf("IMMU dump:\n");
  543 + for (i = 0; i < 64; i++) {
  544 + switch ((env->itlb_tte[i] >> 61) & 3) {
  545 + default:
  546 + case 0x0:
  547 + mask = " 8k";
  548 + break;
  549 + case 0x1:
  550 + mask = " 64k";
  551 + break;
  552 + case 0x2:
  553 + mask = "512k";
  554 + break;
  555 + case 0x3:
  556 + mask = " 4M";
  557 + break;
  558 + }
  559 + if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
  560 + printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %lld\n",
  561 + env->itlb_tag[i] & ~0x1fffULL,
  562 + env->itlb_tte[i] & 0x1ffffffe000ULL,
  563 + mask,
  564 + env->itlb_tte[i] & 0x4? "priv": "user",
  565 + env->itlb_tte[i] & 0x40? "locked": "unlocked",
  566 + env->itlb_tag[i] & 0x1fffULL);
  567 + }
  568 + }
  569 + }
  570 +}
  571 +#endif
474 #endif 572 #endif
target-sparc/op.c
@@ -267,15 +267,6 @@ @@ -267,15 +267,6 @@
267 #endif 267 #endif
268 268
269 #ifdef TARGET_SPARC64 269 #ifdef TARGET_SPARC64
270 -#undef JUMP_TB  
271 -#define JUMP_TB(opname, tbparam, n, eip) \  
272 - do { \  
273 - GOTO_TB(opname, tbparam, n); \  
274 - T0 = (long)(tbparam) + (n); \  
275 - env->pc = (eip) & 0xffffffff; \  
276 - EXIT_TB(); \  
277 - } while (0)  
278 -  
279 #ifdef WORDS_BIGENDIAN 270 #ifdef WORDS_BIGENDIAN
280 typedef union UREG64 { 271 typedef union UREG64 {
281 struct { uint16_t v3, v2, v1, v0; } w; 272 struct { uint16_t v3, v2, v1, v0; } w;
@@ -388,7 +379,7 @@ void OPPROTO op_add_T1_T0_cc(void) @@ -388,7 +379,7 @@ void OPPROTO op_add_T1_T0_cc(void)
388 env->psr |= PSR_ZERO; 379 env->psr |= PSR_ZERO;
389 if ((int32_t) T0 < 0) 380 if ((int32_t) T0 < 0)
390 env->psr |= PSR_NEG; 381 env->psr |= PSR_NEG;
391 - if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) 382 + if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
392 env->psr |= PSR_CARRY; 383 env->psr |= PSR_CARRY;
393 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) & 384 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
394 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) 385 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
@@ -433,7 +424,7 @@ void OPPROTO op_addx_T1_T0_cc(void) @@ -433,7 +424,7 @@ void OPPROTO op_addx_T1_T0_cc(void)
433 env->psr |= PSR_ZERO; 424 env->psr |= PSR_ZERO;
434 if ((int32_t) T0 < 0) 425 if ((int32_t) T0 < 0)
435 env->psr |= PSR_NEG; 426 env->psr |= PSR_NEG;
436 - if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) 427 + if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
437 env->psr |= PSR_CARRY; 428 env->psr |= PSR_CARRY;
438 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) & 429 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
439 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) 430 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
@@ -478,7 +469,7 @@ void OPPROTO op_sub_T1_T0_cc(void) @@ -478,7 +469,7 @@ void OPPROTO op_sub_T1_T0_cc(void)
478 env->psr |= PSR_ZERO; 469 env->psr |= PSR_ZERO;
479 if ((int32_t) T0 < 0) 470 if ((int32_t) T0 < 0)
480 env->psr |= PSR_NEG; 471 env->psr |= PSR_NEG;
481 - if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) 472 + if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
482 env->psr |= PSR_CARRY; 473 env->psr |= PSR_CARRY;
483 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & 474 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
484 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) 475 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
@@ -523,7 +514,7 @@ void OPPROTO op_subx_T1_T0_cc(void) @@ -523,7 +514,7 @@ void OPPROTO op_subx_T1_T0_cc(void)
523 env->psr |= PSR_ZERO; 514 env->psr |= PSR_ZERO;
524 if ((int32_t) T0 < 0) 515 if ((int32_t) T0 < 0)
525 env->psr |= PSR_NEG; 516 env->psr |= PSR_NEG;
526 - if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) 517 + if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
527 env->psr |= PSR_CARRY; 518 env->psr |= PSR_CARRY;
528 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & 519 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
529 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) 520 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
@@ -585,7 +576,11 @@ void OPPROTO op_umul_T1_T0(void) @@ -585,7 +576,11 @@ void OPPROTO op_umul_T1_T0(void)
585 { 576 {
586 uint64_t res; 577 uint64_t res;
587 res = (uint64_t) T0 * (uint64_t) T1; 578 res = (uint64_t) T0 * (uint64_t) T1;
  579 +#ifdef TARGET_SPARC64
  580 + T0 = res;
  581 +#else
588 T0 = res & 0xffffffff; 582 T0 = res & 0xffffffff;
  583 +#endif
589 env->y = res >> 32; 584 env->y = res >> 32;
590 } 585 }
591 586
@@ -593,7 +588,11 @@ void OPPROTO op_smul_T1_T0(void) @@ -593,7 +588,11 @@ void OPPROTO op_smul_T1_T0(void)
593 { 588 {
594 uint64_t res; 589 uint64_t res;
595 res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1); 590 res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
  591 +#ifdef TARGET_SPARC64
  592 + T0 = res;
  593 +#else
596 T0 = res & 0xffffffff; 594 T0 = res & 0xffffffff;
  595 +#endif
597 env->y = res >> 32; 596 env->y = res >> 32;
598 } 597 }
599 598
@@ -902,7 +901,7 @@ void OPPROTO op_rdpstate(void) @@ -902,7 +901,7 @@ void OPPROTO op_rdpstate(void)
902 901
903 void OPPROTO op_wrpstate(void) 902 void OPPROTO op_wrpstate(void)
904 { 903 {
905 - env->pstate = T0 & 0x1f; 904 + do_wrpstate();
906 } 905 }
907 906
908 // CWP handling is reversed in V9, but we still use the V8 register 907 // CWP handling is reversed in V9, but we still use the V8 register
@@ -1201,12 +1200,12 @@ void OPPROTO op_eval_xbvc(void) @@ -1201,12 +1200,12 @@ void OPPROTO op_eval_xbvc(void)
1201 #ifdef TARGET_SPARC64 1200 #ifdef TARGET_SPARC64
1202 void OPPROTO op_eval_brz(void) 1201 void OPPROTO op_eval_brz(void)
1203 { 1202 {
1204 - T2 = T0; 1203 + T2 = (T0 == 0);
1205 } 1204 }
1206 1205
1207 void OPPROTO op_eval_brnz(void) 1206 void OPPROTO op_eval_brnz(void)
1208 { 1207 {
1209 - T2 = !T0; 1208 + T2 = (T0 != 0);
1210 } 1209 }
1211 1210
1212 void OPPROTO op_eval_brlz(void) 1211 void OPPROTO op_eval_brlz(void)
@@ -1266,43 +1265,32 @@ void OPPROTO op_next_insn(void) @@ -1266,43 +1265,32 @@ void OPPROTO op_next_insn(void)
1266 env->npc = env->npc + 4; 1265 env->npc = env->npc + 4;
1267 } 1266 }
1268 1267
1269 -void OPPROTO op_branch(void) 1268 +void OPPROTO op_goto_tb0(void)
1270 { 1269 {
1271 - env->npc = (uint32_t)PARAM3; /* XXX: optimize */  
1272 - JUMP_TB(op_branch, PARAM1, 0, PARAM2); 1270 + GOTO_TB(op_goto_tb0, PARAM1, 0);
1273 } 1271 }
1274 1272
1275 -void OPPROTO op_branch2(void) 1273 +void OPPROTO op_goto_tb1(void)
1276 { 1274 {
1277 - if (T2) {  
1278 - env->npc = (uint32_t)PARAM2 + 4;  
1279 - JUMP_TB(op_branch2, PARAM1, 0, PARAM2);  
1280 - } else {  
1281 - env->npc = (uint32_t)PARAM3 + 4;  
1282 - JUMP_TB(op_branch2, PARAM1, 1, PARAM3);  
1283 - }  
1284 - FORCE_RET(); 1275 + GOTO_TB(op_goto_tb1, PARAM1, 1);
1285 } 1276 }
1286 1277
1287 -void OPPROTO op_branch_a(void) 1278 +void OPPROTO op_jmp_label(void)
1288 { 1279 {
1289 - if (T2) {  
1290 - env->npc = (uint32_t)PARAM2; /* XXX: optimize */  
1291 - JUMP_TB(op_branch_a, PARAM1, 0, PARAM3);  
1292 - } else {  
1293 - env->npc = (uint32_t)PARAM3 + 8; /* XXX: optimize */  
1294 - JUMP_TB(op_branch_a, PARAM1, 1, PARAM3 + 4);  
1295 - } 1280 + GOTO_LABEL_PARAM(1);
  1281 +}
  1282 +
  1283 +void OPPROTO op_jnz_T2_label(void)
  1284 +{
  1285 + if (T2)
  1286 + GOTO_LABEL_PARAM(1);
1296 FORCE_RET(); 1287 FORCE_RET();
1297 } 1288 }
1298 1289
1299 -void OPPROTO op_generic_branch(void) 1290 +void OPPROTO op_jz_T2_label(void)
1300 { 1291 {
1301 - if (T2) {  
1302 - env->npc = (uint32_t)PARAM1;  
1303 - } else {  
1304 - env->npc = (uint32_t)PARAM2;  
1305 - } 1292 + if (!T2)
  1293 + GOTO_LABEL_PARAM(1);
1306 FORCE_RET(); 1294 FORCE_RET();
1307 } 1295 }
1308 1296
@@ -1547,18 +1535,12 @@ void OPPROTO op_popc(void) @@ -1547,18 +1535,12 @@ void OPPROTO op_popc(void)
1547 1535
1548 void OPPROTO op_done(void) 1536 void OPPROTO op_done(void)
1549 { 1537 {
1550 - env->pc = env->tnpc[env->tl];  
1551 - env->npc = env->tnpc[env->tl] + 4;  
1552 - env->pstate = env->tstate[env->tl];  
1553 - env->tl--; 1538 + do_done();
1554 } 1539 }
1555 1540
1556 void OPPROTO op_retry(void) 1541 void OPPROTO op_retry(void)
1557 { 1542 {
1558 - env->pc = env->tpc[env->tl];  
1559 - env->npc = env->tnpc[env->tl];  
1560 - env->pstate = env->tstate[env->tl];  
1561 - env->tl--; 1543 + do_retry();
1562 } 1544 }
1563 1545
1564 void OPPROTO op_sir(void) 1546 void OPPROTO op_sir(void)
target-sparc/op_helper.c
1 #include "exec.h" 1 #include "exec.h"
2 2
  3 +//#define DEBUG_PCALL
3 //#define DEBUG_MMU 4 //#define DEBUG_MMU
4 5
5 void raise_exception(int tt) 6 void raise_exception(int tt)
@@ -223,7 +224,7 @@ void do_fcmpd_fcc3 (void) @@ -223,7 +224,7 @@ void do_fcmpd_fcc3 (void)
223 #ifndef TARGET_SPARC64 224 #ifndef TARGET_SPARC64
224 void helper_ld_asi(int asi, int size, int sign) 225 void helper_ld_asi(int asi, int size, int sign)
225 { 226 {
226 - uint32_t ret; 227 + uint32_t ret = 0;
227 228
228 switch (asi) { 229 switch (asi) {
229 case 3: /* MMU probe */ 230 case 3: /* MMU probe */
@@ -299,7 +300,8 @@ void helper_st_asi(int asi, int size, int sign) @@ -299,7 +300,8 @@ void helper_st_asi(int asi, int size, int sign)
299 } 300 }
300 case 4: /* write MMU regs */ 301 case 4: /* write MMU regs */
301 { 302 {
302 - int reg = (T0 >> 8) & 0xf, oldreg; 303 + int reg = (T0 >> 8) & 0xf;
  304 + uint32_t oldreg;
303 305
304 oldreg = env->mmuregs[reg]; 306 oldreg = env->mmuregs[reg];
305 switch(reg) { 307 switch(reg) {
@@ -339,7 +341,7 @@ void helper_st_asi(int asi, int size, int sign) @@ -339,7 +341,7 @@ void helper_st_asi(int asi, int size, int sign)
339 // value (T1) = src 341 // value (T1) = src
340 // address (T0) = dst 342 // address (T0) = dst
341 // copy 32 bytes 343 // copy 32 bytes
342 - int src = T1, dst = T0; 344 + uint32_t src = T1, dst = T0;
343 uint8_t temp[32]; 345 uint8_t temp[32];
344 346
345 tswap32s(&src); 347 tswap32s(&src);
@@ -353,7 +355,8 @@ void helper_st_asi(int asi, int size, int sign) @@ -353,7 +355,8 @@ void helper_st_asi(int asi, int size, int sign)
353 // value (T1, T2) 355 // value (T1, T2)
354 // address (T0) = dst 356 // address (T0) = dst
355 // fill 32 bytes 357 // fill 32 bytes
356 - int i, dst = T0; 358 + int i;
  359 + uint32_t dst = T0;
357 uint64_t val; 360 uint64_t val;
358 361
359 val = (((uint64_t)T1) << 32) | T2; 362 val = (((uint64_t)T1) << 32) | T2;
@@ -366,7 +369,7 @@ void helper_st_asi(int asi, int size, int sign) @@ -366,7 +369,7 @@ void helper_st_asi(int asi, int size, int sign)
366 return; 369 return;
367 case 0x20 ... 0x2f: /* MMU passthrough */ 370 case 0x20 ... 0x2f: /* MMU passthrough */
368 { 371 {
369 - int temp = T1; 372 + uint32_t temp = T1;
370 if (size == 4) 373 if (size == 4)
371 tswap32s(&temp); 374 tswap32s(&temp);
372 else if (size == 2) 375 else if (size == 2)
@@ -383,10 +386,10 @@ void helper_st_asi(int asi, int size, int sign) @@ -383,10 +386,10 @@ void helper_st_asi(int asi, int size, int sign)
383 386
384 void helper_ld_asi(int asi, int size, int sign) 387 void helper_ld_asi(int asi, int size, int sign)
385 { 388 {
386 - uint64_t ret; 389 + uint64_t ret = 0;
387 390
388 if (asi < 0x80 && (env->pstate & PS_PRIV) == 0) 391 if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
389 - raise_exception(TT_PRIV_INSN); 392 + raise_exception(TT_PRIV_ACT);
390 393
391 switch (asi) { 394 switch (asi) {
392 case 0x14: // Bypass 395 case 0x14: // Bypass
@@ -401,8 +404,23 @@ void helper_ld_asi(int asi, int size, int sign) @@ -401,8 +404,23 @@ void helper_ld_asi(int asi, int size, int sign)
401 tswap16s((uint16_t *)&ret); 404 tswap16s((uint16_t *)&ret);
402 break; 405 break;
403 } 406 }
  407 + case 0x04: // Nucleus
  408 + case 0x0c: // Nucleus Little Endian (LE)
  409 + case 0x10: // As if user primary
  410 + case 0x11: // As if user secondary
  411 + case 0x18: // As if user primary LE
  412 + case 0x19: // As if user secondary LE
404 case 0x1c: // Bypass LE 413 case 0x1c: // Bypass LE
405 case 0x1d: // Bypass, non-cacheable LE 414 case 0x1d: // Bypass, non-cacheable LE
  415 + case 0x24: // Nucleus quad LDD 128 bit atomic
  416 + case 0x2c: // Nucleus quad LDD 128 bit atomic
  417 + case 0x4a: // UPA config
  418 + case 0x82: // Primary no-fault
  419 + case 0x83: // Secondary no-fault
  420 + case 0x88: // Primary LE
  421 + case 0x89: // Secondary LE
  422 + case 0x8a: // Primary no-fault LE
  423 + case 0x8b: // Secondary no-fault LE
406 // XXX 424 // XXX
407 break; 425 break;
408 case 0x45: // LSU 426 case 0x45: // LSU
@@ -418,8 +436,22 @@ void helper_ld_asi(int asi, int size, int sign) @@ -418,8 +436,22 @@ void helper_ld_asi(int asi, int size, int sign)
418 case 0x51: // I-MMU 8k TSB pointer 436 case 0x51: // I-MMU 8k TSB pointer
419 case 0x52: // I-MMU 64k TSB pointer 437 case 0x52: // I-MMU 64k TSB pointer
420 case 0x55: // I-MMU data access 438 case 0x55: // I-MMU data access
421 - case 0x56: // I-MMU tag read 439 + // XXX
422 break; 440 break;
  441 + case 0x56: // I-MMU tag read
  442 + {
  443 + unsigned int i;
  444 +
  445 + for (i = 0; i < 64; i++) {
  446 + // Valid, ctx match, vaddr match
  447 + if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
  448 + env->itlb_tag[i] == T0) {
  449 + ret = env->itlb_tag[i];
  450 + break;
  451 + }
  452 + }
  453 + break;
  454 + }
423 case 0x58: // D-MMU regs 455 case 0x58: // D-MMU regs
424 { 456 {
425 int reg = (T0 >> 3) & 0xf; 457 int reg = (T0 >> 3) & 0xf;
@@ -427,16 +459,34 @@ void helper_ld_asi(int asi, int size, int sign) @@ -427,16 +459,34 @@ void helper_ld_asi(int asi, int size, int sign)
427 ret = env->dmmuregs[reg]; 459 ret = env->dmmuregs[reg];
428 break; 460 break;
429 } 461 }
  462 + case 0x5e: // D-MMU tag read
  463 + {
  464 + unsigned int i;
  465 +
  466 + for (i = 0; i < 64; i++) {
  467 + // Valid, ctx match, vaddr match
  468 + if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
  469 + env->dtlb_tag[i] == T0) {
  470 + ret = env->dtlb_tag[i];
  471 + break;
  472 + }
  473 + }
  474 + break;
  475 + }
430 case 0x59: // D-MMU 8k TSB pointer 476 case 0x59: // D-MMU 8k TSB pointer
431 case 0x5a: // D-MMU 64k TSB pointer 477 case 0x5a: // D-MMU 64k TSB pointer
432 case 0x5b: // D-MMU data pointer 478 case 0x5b: // D-MMU data pointer
433 case 0x5d: // D-MMU data access 479 case 0x5d: // D-MMU data access
434 - case 0x5e: // D-MMU tag read 480 + case 0x48: // Interrupt dispatch, RO
  481 + case 0x49: // Interrupt data receive
  482 + case 0x7f: // Incoming interrupt vector, RO
  483 + // XXX
435 break; 484 break;
436 case 0x54: // I-MMU data in, WO 485 case 0x54: // I-MMU data in, WO
437 case 0x57: // I-MMU demap, WO 486 case 0x57: // I-MMU demap, WO
438 case 0x5c: // D-MMU data in, WO 487 case 0x5c: // D-MMU data in, WO
439 case 0x5f: // D-MMU demap, WO 488 case 0x5f: // D-MMU demap, WO
  489 + case 0x77: // Interrupt vector, WO
440 default: 490 default:
441 ret = 0; 491 ret = 0;
442 break; 492 break;
@@ -447,7 +497,7 @@ void helper_ld_asi(int asi, int size, int sign) @@ -447,7 +497,7 @@ void helper_ld_asi(int asi, int size, int sign)
447 void helper_st_asi(int asi, int size, int sign) 497 void helper_st_asi(int asi, int size, int sign)
448 { 498 {
449 if (asi < 0x80 && (env->pstate & PS_PRIV) == 0) 499 if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
450 - raise_exception(TT_PRIV_INSN); 500 + raise_exception(TT_PRIV_ACT);
451 501
452 switch(asi) { 502 switch(asi) {
453 case 0x14: // Bypass 503 case 0x14: // Bypass
@@ -463,8 +513,19 @@ void helper_st_asi(int asi, int size, int sign) @@ -463,8 +513,19 @@ void helper_st_asi(int asi, int size, int sign)
463 cpu_physical_memory_write(T0, (void *) &temp, size); 513 cpu_physical_memory_write(T0, (void *) &temp, size);
464 } 514 }
465 return; 515 return;
  516 + case 0x04: // Nucleus
  517 + case 0x0c: // Nucleus Little Endian (LE)
  518 + case 0x10: // As if user primary
  519 + case 0x11: // As if user secondary
  520 + case 0x18: // As if user primary LE
  521 + case 0x19: // As if user secondary LE
466 case 0x1c: // Bypass LE 522 case 0x1c: // Bypass LE
467 case 0x1d: // Bypass, non-cacheable LE 523 case 0x1d: // Bypass, non-cacheable LE
  524 + case 0x24: // Nucleus quad LDD 128 bit atomic
  525 + case 0x2c: // Nucleus quad LDD 128 bit atomic
  526 + case 0x4a: // UPA config
  527 + case 0x88: // Primary LE
  528 + case 0x89: // Secondary LE
468 // XXX 529 // XXX
469 return; 530 return;
470 case 0x45: // LSU 531 case 0x45: // LSU
@@ -475,8 +536,13 @@ void helper_st_asi(int asi, int size, int sign) @@ -475,8 +536,13 @@ void helper_st_asi(int asi, int size, int sign)
475 env->lsu = T1 & (DMMU_E | IMMU_E); 536 env->lsu = T1 & (DMMU_E | IMMU_E);
476 // Mappings generated during D/I MMU disabled mode are 537 // Mappings generated during D/I MMU disabled mode are
477 // invalid in normal mode 538 // invalid in normal mode
478 - if (oldreg != env->lsu) 539 + if (oldreg != env->lsu) {
  540 +#ifdef DEBUG_MMU
  541 + printf("LSU change: 0x%llx -> 0x%llx\n", oldreg, env->lsu);
  542 + dump_mmu(env);
  543 +#endif
479 tlb_flush(env, 1); 544 tlb_flush(env, 1);
  545 + }
480 return; 546 return;
481 } 547 }
482 case 0x50: // I-MMU regs 548 case 0x50: // I-MMU regs
@@ -506,7 +572,7 @@ void helper_st_asi(int asi, int size, int sign) @@ -506,7 +572,7 @@ void helper_st_asi(int asi, int size, int sign)
506 env->immuregs[reg] = T1; 572 env->immuregs[reg] = T1;
507 #ifdef DEBUG_MMU 573 #ifdef DEBUG_MMU
508 if (oldreg != env->immuregs[reg]) { 574 if (oldreg != env->immuregs[reg]) {
509 - printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->immuregs[reg]); 575 + printf("mmu change reg[%d]: 0x%08llx -> 0x%08llx\n", reg, oldreg, env->immuregs[reg]);
510 } 576 }
511 dump_mmu(env); 577 dump_mmu(env);
512 #endif 578 #endif
@@ -544,6 +610,7 @@ void helper_st_asi(int asi, int size, int sign) @@ -544,6 +610,7 @@ void helper_st_asi(int asi, int size, int sign)
544 return; 610 return;
545 } 611 }
546 case 0x57: // I-MMU demap 612 case 0x57: // I-MMU demap
  613 + // XXX
547 return; 614 return;
548 case 0x58: // D-MMU regs 615 case 0x58: // D-MMU regs
549 { 616 {
@@ -574,7 +641,7 @@ void helper_st_asi(int asi, int size, int sign) @@ -574,7 +641,7 @@ void helper_st_asi(int asi, int size, int sign)
574 env->dmmuregs[reg] = T1; 641 env->dmmuregs[reg] = T1;
575 #ifdef DEBUG_MMU 642 #ifdef DEBUG_MMU
576 if (oldreg != env->dmmuregs[reg]) { 643 if (oldreg != env->dmmuregs[reg]) {
577 - printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->dmmuregs[reg]); 644 + printf("mmu change reg[%d]: 0x%08llx -> 0x%08llx\n", reg, oldreg, env->dmmuregs[reg]);
578 } 645 }
579 dump_mmu(env); 646 dump_mmu(env);
580 #endif 647 #endif
@@ -612,6 +679,8 @@ void helper_st_asi(int asi, int size, int sign) @@ -612,6 +679,8 @@ void helper_st_asi(int asi, int size, int sign)
612 return; 679 return;
613 } 680 }
614 case 0x5f: // D-MMU demap 681 case 0x5f: // D-MMU demap
  682 + case 0x49: // Interrupt data receive
  683 + // XXX
615 return; 684 return;
616 case 0x51: // I-MMU 8k TSB pointer, RO 685 case 0x51: // I-MMU 8k TSB pointer, RO
617 case 0x52: // I-MMU 64k TSB pointer, RO 686 case 0x52: // I-MMU 64k TSB pointer, RO
@@ -620,6 +689,12 @@ void helper_st_asi(int asi, int size, int sign) @@ -620,6 +689,12 @@ void helper_st_asi(int asi, int size, int sign)
620 case 0x5a: // D-MMU 64k TSB pointer, RO 689 case 0x5a: // D-MMU 64k TSB pointer, RO
621 case 0x5b: // D-MMU data pointer, RO 690 case 0x5b: // D-MMU data pointer, RO
622 case 0x5e: // D-MMU tag read, RO 691 case 0x5e: // D-MMU tag read, RO
  692 + case 0x48: // Interrupt dispatch, RO
  693 + case 0x7f: // Incoming interrupt vector, RO
  694 + case 0x82: // Primary no-fault, RO
  695 + case 0x83: // Secondary no-fault, RO
  696 + case 0x8a: // Primary no-fault LE, RO
  697 + case 0x8b: // Secondary no-fault LE, RO
623 default: 698 default:
624 return; 699 return;
625 } 700 }
@@ -704,6 +779,61 @@ void do_popc() @@ -704,6 +779,61 @@ void do_popc()
704 T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL); 779 T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL);
705 T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL); 780 T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL);
706 } 781 }
  782 +
  783 +static inline uint64_t *get_gregset(uint64_t pstate)
  784 +{
  785 + switch (pstate) {
  786 + default:
  787 + case 0:
  788 + return env->bgregs;
  789 + case PS_AG:
  790 + return env->agregs;
  791 + case PS_MG:
  792 + return env->mgregs;
  793 + case PS_IG:
  794 + return env->igregs;
  795 + }
  796 +}
  797 +
  798 +void do_wrpstate()
  799 +{
  800 + uint64_t new_pstate, pstate_regs, new_pstate_regs;
  801 + uint64_t *src, *dst;
  802 +
  803 + new_pstate = T0 & 0xf3f;
  804 + pstate_regs = env->pstate & 0xc01;
  805 + new_pstate_regs = new_pstate & 0xc01;
  806 + if (new_pstate_regs != pstate_regs) {
  807 + // Switch global register bank
  808 + src = get_gregset(new_pstate_regs);
  809 + dst = get_gregset(pstate_regs);
  810 + memcpy32(dst, env->gregs);
  811 + memcpy32(env->gregs, src);
  812 + }
  813 + env->pstate = new_pstate;
  814 +}
  815 +
  816 +void do_done(void)
  817 +{
  818 + env->tl--;
  819 + env->pc = env->tnpc[env->tl];
  820 + env->npc = env->tnpc[env->tl] + 4;
  821 + PUT_CCR(env, env->tstate[env->tl] >> 32);
  822 + env->asi = (env->tstate[env->tl] >> 24) & 0xff;
  823 + env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;
  824 + set_cwp(env->tstate[env->tl] & 0xff);
  825 +}
  826 +
  827 +void do_retry(void)
  828 +{
  829 + env->tl--;
  830 + env->pc = env->tpc[env->tl];
  831 + env->npc = env->tnpc[env->tl];
  832 + PUT_CCR(env, env->tstate[env->tl] >> 32);
  833 + env->asi = (env->tstate[env->tl] >> 24) & 0xff;
  834 + env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;
  835 + set_cwp(env->tstate[env->tl] & 0xff);
  836 +}
707 #endif 837 #endif
708 838
709 void set_cwp(int new_cwp) 839 void set_cwp(int new_cwp)
@@ -744,7 +874,7 @@ void do_interrupt(int intno) @@ -744,7 +874,7 @@ void do_interrupt(int intno)
744 #ifdef DEBUG_PCALL 874 #ifdef DEBUG_PCALL
745 if (loglevel & CPU_LOG_INT) { 875 if (loglevel & CPU_LOG_INT) {
746 static int count; 876 static int count;
747 - fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n", 877 + fprintf(logfile, "%6d: v=%04x pc=%016llx npc=%016llx SP=%016llx\n",
748 count, intno, 878 count, intno,
749 env->pc, 879 env->pc,
750 env->npc, env->regwptr[6]); 880 env->npc, env->regwptr[6]);
@@ -766,8 +896,8 @@ void do_interrupt(int intno) @@ -766,8 +896,8 @@ void do_interrupt(int intno)
766 } 896 }
767 #endif 897 #endif
768 #if !defined(CONFIG_USER_ONLY) 898 #if !defined(CONFIG_USER_ONLY)
769 - if (env->pstate & PS_IE) {  
770 - cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index); 899 + if (env->tl == MAXTL) {
  900 + cpu_abort(cpu_single_env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
771 return; 901 return;
772 } 902 }
773 #endif 903 #endif
@@ -776,8 +906,16 @@ void do_interrupt(int intno) @@ -776,8 +906,16 @@ void do_interrupt(int intno)
776 env->tpc[env->tl] = env->pc; 906 env->tpc[env->tl] = env->pc;
777 env->tnpc[env->tl] = env->npc; 907 env->tnpc[env->tl] = env->npc;
778 env->tt[env->tl] = intno; 908 env->tt[env->tl] = intno;
779 - env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4);  
780 - env->tl++; 909 + env->pstate = PS_PEF | PS_PRIV | PS_AG;
  910 + env->tbr &= ~0x7fffULL;
  911 + env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
  912 + if (env->tl < MAXTL - 1) {
  913 + env->tl++;
  914 + } else {
  915 + env->pstate |= PS_RED;
  916 + if (env->tl != MAXTL)
  917 + env->tl++;
  918 + }
781 env->pc = env->tbr; 919 env->pc = env->tbr;
782 env->npc = env->pc + 4; 920 env->npc = env->pc + 4;
783 env->exception_index = 0; 921 env->exception_index = 0;
target-sparc/op_mem.h
@@ -105,20 +105,10 @@ void OPPROTO glue(op_casx, MEMSUFFIX)(void) @@ -105,20 +105,10 @@ void OPPROTO glue(op_casx, MEMSUFFIX)(void)
105 105
106 void OPPROTO glue(op_ldsw, MEMSUFFIX)(void) 106 void OPPROTO glue(op_ldsw, MEMSUFFIX)(void)
107 { 107 {
108 - T1 = (int64_t)glue(ldl, MEMSUFFIX)(T0); 108 + T1 = (int64_t)(glue(ldl, MEMSUFFIX)(T0) & 0xffffffff);
109 } 109 }
110 110
111 -void OPPROTO glue(op_ldx, MEMSUFFIX)(void)  
112 -{  
113 - // XXX  
114 - T1 = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;  
115 - T1 |= glue(ldl, MEMSUFFIX)(T0);  
116 -}  
117 -  
118 -void OPPROTO glue(op_stx, MEMSUFFIX)(void)  
119 -{  
120 - glue(stl, MEMSUFFIX)(T0, T1 >> 32);  
121 - glue(stl, MEMSUFFIX)(T0, T1 & 0xffffffff);  
122 -} 111 +SPARC_LD_OP(ldx, ldq);
  112 +SPARC_ST_OP(stx, stq);
123 #endif 113 #endif
124 #undef MEMSUFFIX 114 #undef MEMSUFFIX
target-sparc/translate.c
@@ -86,6 +86,12 @@ enum { @@ -86,6 +86,12 @@ enum {
86 #define DFPREG(r) (r) 86 #define DFPREG(r) (r)
87 #endif 87 #endif
88 88
  89 +#ifdef USE_DIRECT_JUMP
  90 +#define TBPARAM(x)
  91 +#else
  92 +#define TBPARAM(x) (long)(x)
  93 +#endif
  94 +
89 static int sign_extend(int x, int len) 95 static int sign_extend(int x, int len)
90 { 96 {
91 len = 32 - len; 97 len = 32 - len;
@@ -462,7 +468,7 @@ OP_LD_TABLE(casx); @@ -462,7 +468,7 @@ OP_LD_TABLE(casx);
462 468
463 static inline void gen_movl_imm_TN(int reg, uint32_t imm) 469 static inline void gen_movl_imm_TN(int reg, uint32_t imm)
464 { 470 {
465 - gen_op_movl_TN_im[reg] (imm); 471 + gen_op_movl_TN_im[reg](imm);
466 } 472 }
467 473
468 static inline void gen_movl_imm_T1(uint32_t val) 474 static inline void gen_movl_imm_T1(uint32_t val)
@@ -529,15 +535,6 @@ static inline void gen_movl_T1_reg(int reg) @@ -529,15 +535,6 @@ static inline void gen_movl_T1_reg(int reg)
529 gen_movl_TN_reg(reg, 1); 535 gen_movl_TN_reg(reg, 1);
530 } 536 }
531 537
532 -/* call this function before using T2 as it may have been set for a jump */  
533 -static inline void flush_T2(DisasContext * dc)  
534 -{  
535 - if (dc->npc == JUMP_PC) {  
536 - gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);  
537 - dc->npc = DYNAMIC_PC;  
538 - }  
539 -}  
540 -  
541 static inline void gen_jmp_im(target_ulong pc) 538 static inline void gen_jmp_im(target_ulong pc)
542 { 539 {
543 #ifdef TARGET_SPARC64 540 #ifdef TARGET_SPARC64
@@ -564,10 +561,88 @@ static inline void gen_movl_npc_im(target_ulong npc) @@ -564,10 +561,88 @@ static inline void gen_movl_npc_im(target_ulong npc)
564 #endif 561 #endif
565 } 562 }
566 563
  564 +static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
  565 +{
  566 + int l1;
  567 +
  568 + l1 = gen_new_label();
  569 +
  570 + gen_op_jz_T2_label(l1);
  571 +
  572 + gen_op_goto_tb0(TBPARAM(tb));
  573 + gen_jmp_im(pc1);
  574 + gen_movl_npc_im(pc1 + 4);
  575 + gen_op_movl_T0_im((long)tb + 0);
  576 + gen_op_exit_tb();
  577 +
  578 + gen_set_label(l1);
  579 + gen_op_goto_tb1(TBPARAM(tb));
  580 + gen_jmp_im(pc2);
  581 + gen_movl_npc_im(pc2 + 4);
  582 + gen_op_movl_T0_im((long)tb + 1);
  583 + gen_op_exit_tb();
  584 +}
  585 +
  586 +static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
  587 +{
  588 + int l1;
  589 +
  590 + l1 = gen_new_label();
  591 +
  592 + gen_op_jz_T2_label(l1);
  593 +
  594 + gen_op_goto_tb0(TBPARAM(tb));
  595 + gen_jmp_im(pc2);
  596 + gen_movl_npc_im(pc1);
  597 + gen_op_movl_T0_im((long)tb + 0);
  598 + gen_op_exit_tb();
  599 +
  600 + gen_set_label(l1);
  601 + gen_op_goto_tb1(TBPARAM(tb));
  602 + gen_jmp_im(pc2 + 4);
  603 + gen_movl_npc_im(pc2 + 8);
  604 + gen_op_movl_T0_im((long)tb + 1);
  605 + gen_op_exit_tb();
  606 +}
  607 +
  608 +static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc)
  609 +{
  610 + gen_op_goto_tb0(TBPARAM(tb));
  611 + gen_jmp_im(pc);
  612 + gen_movl_npc_im(npc);
  613 + gen_op_movl_T0_im((long)tb + 0);
  614 + gen_op_exit_tb();
  615 +}
  616 +
  617 +static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2)
  618 +{
  619 + int l1, l2;
  620 +
  621 + l1 = gen_new_label();
  622 + l2 = gen_new_label();
  623 + gen_op_jz_T2_label(l1);
  624 +
  625 + gen_movl_npc_im(npc1);
  626 + gen_op_jmp_label(l2);
  627 +
  628 + gen_set_label(l1);
  629 + gen_movl_npc_im(npc2);
  630 + gen_set_label(l2);
  631 +}
  632 +
  633 +/* call this function before using T2 as it may have been set for a jump */
  634 +static inline void flush_T2(DisasContext * dc)
  635 +{
  636 + if (dc->npc == JUMP_PC) {
  637 + gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
  638 + dc->npc = DYNAMIC_PC;
  639 + }
  640 +}
  641 +
567 static inline void save_npc(DisasContext * dc) 642 static inline void save_npc(DisasContext * dc)
568 { 643 {
569 if (dc->npc == JUMP_PC) { 644 if (dc->npc == JUMP_PC) {
570 - gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]); 645 + gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
571 dc->npc = DYNAMIC_PC; 646 dc->npc = DYNAMIC_PC;
572 } else if (dc->npc != DYNAMIC_PC) { 647 } else if (dc->npc != DYNAMIC_PC) {
573 gen_movl_npc_im(dc->npc); 648 gen_movl_npc_im(dc->npc);
@@ -583,7 +658,7 @@ static inline void save_state(DisasContext * dc) @@ -583,7 +658,7 @@ static inline void save_state(DisasContext * dc)
583 static inline void gen_mov_pc_npc(DisasContext * dc) 658 static inline void gen_mov_pc_npc(DisasContext * dc)
584 { 659 {
585 if (dc->npc == JUMP_PC) { 660 if (dc->npc == JUMP_PC) {
586 - gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]); 661 + gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
587 gen_op_mov_pc_npc(); 662 gen_op_mov_pc_npc();
588 dc->pc = DYNAMIC_PC; 663 dc->pc = DYNAMIC_PC;
589 } else if (dc->npc == DYNAMIC_PC) { 664 } else if (dc->npc == DYNAMIC_PC) {
@@ -769,7 +844,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc) @@ -769,7 +844,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
769 flush_T2(dc); 844 flush_T2(dc);
770 gen_cond[cc][cond](); 845 gen_cond[cc][cond]();
771 if (a) { 846 if (a) {
772 - gen_op_branch_a((long)dc->tb, target, dc->npc); 847 + gen_branch_a(dc, (long)dc->tb, target, dc->npc);
773 dc->is_br = 1; 848 dc->is_br = 1;
774 } else { 849 } else {
775 dc->pc = dc->npc; 850 dc->pc = dc->npc;
@@ -808,7 +883,7 @@ static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc) @@ -808,7 +883,7 @@ static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
808 flush_T2(dc); 883 flush_T2(dc);
809 gen_fcond[cc][cond](); 884 gen_fcond[cc][cond]();
810 if (a) { 885 if (a) {
811 - gen_op_branch_a((long)dc->tb, target, dc->npc); 886 + gen_branch_a(dc, (long)dc->tb, target, dc->npc);
812 dc->is_br = 1; 887 dc->is_br = 1;
813 } else { 888 } else {
814 dc->pc = dc->npc; 889 dc->pc = dc->npc;
@@ -829,7 +904,7 @@ static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn) @@ -829,7 +904,7 @@ static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
829 flush_T2(dc); 904 flush_T2(dc);
830 gen_cond_reg(cond); 905 gen_cond_reg(cond);
831 if (a) { 906 if (a) {
832 - gen_op_branch_a((long)dc->tb, target, dc->npc); 907 + gen_branch_a(dc, (long)dc->tb, target, dc->npc);
833 dc->is_br = 1; 908 dc->is_br = 1;
834 } else { 909 } else {
835 dc->pc = dc->npc; 910 dc->pc = dc->npc;
@@ -893,7 +968,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -893,7 +968,7 @@ static void disas_sparc_insn(DisasContext * dc)
893 target <<= 2; 968 target <<= 2;
894 target = sign_extend(target, 16); 969 target = sign_extend(target, 16);
895 rs1 = GET_FIELD(insn, 13, 17); 970 rs1 = GET_FIELD(insn, 13, 17);
896 - gen_movl_T0_reg(rs1); 971 + gen_movl_reg_T0(rs1);
897 do_branch_reg(dc, target, insn); 972 do_branch_reg(dc, target, insn);
898 goto jmp_insn; 973 goto jmp_insn;
899 } 974 }
@@ -952,7 +1027,15 @@ static void disas_sparc_insn(DisasContext * dc) @@ -952,7 +1027,15 @@ static void disas_sparc_insn(DisasContext * dc)
952 /*CALL*/ { 1027 /*CALL*/ {
953 target_long target = GET_FIELDs(insn, 2, 31) << 2; 1028 target_long target = GET_FIELDs(insn, 2, 31) << 2;
954 1029
  1030 +#ifdef TARGET_SPARC64
  1031 + if (dc->pc == (uint32_t)dc->pc) {
  1032 + gen_op_movl_T0_im(dc->pc);
  1033 + } else {
  1034 + gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
  1035 + }
  1036 +#else
955 gen_op_movl_T0_im(dc->pc); 1037 gen_op_movl_T0_im(dc->pc);
  1038 +#endif
956 gen_movl_T0_reg(15); 1039 gen_movl_T0_reg(15);
957 target += dc->pc; 1040 target += dc->pc;
958 gen_mov_pc_npc(dc); 1041 gen_mov_pc_npc(dc);
@@ -1039,6 +1122,25 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1039,6 +1122,25 @@ static void disas_sparc_insn(DisasContext * dc)
1039 gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs)); 1122 gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
1040 gen_movl_T0_reg(rd); 1123 gen_movl_T0_reg(rd);
1041 break; 1124 break;
  1125 + case 0x17: /* Tick compare */
  1126 + gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
  1127 + gen_movl_T0_reg(rd);
  1128 + break;
  1129 + case 0x18: /* System tick */
  1130 + gen_op_rdtick(); // XXX
  1131 + gen_movl_T0_reg(rd);
  1132 + break;
  1133 + case 0x19: /* System tick compare */
  1134 + gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
  1135 + gen_movl_T0_reg(rd);
  1136 + break;
  1137 + case 0x10: /* Performance Control */
  1138 + case 0x11: /* Performance Instrumentation Counter */
  1139 + case 0x12: /* Dispatch Control */
  1140 + case 0x13: /* Graphics Status */
  1141 + case 0x14: /* Softint set, WO */
  1142 + case 0x15: /* Softint clear, WO */
  1143 + case 0x16: /* Softint write */
1042 #endif 1144 #endif
1043 default: 1145 default:
1044 goto illegal_insn; 1146 goto illegal_insn;
@@ -1549,6 +1651,50 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1549,6 +1651,50 @@ static void disas_sparc_insn(DisasContext * dc)
1549 gen_movl_T0_reg(rd); 1651 gen_movl_T0_reg(rd);
1550 } 1652 }
1551 #endif 1653 #endif
  1654 +#ifdef TARGET_SPARC64
  1655 + } else if (xop == 0x25) { /* sll, V9 sllx ( == sll) */
  1656 + rs1 = GET_FIELD(insn, 13, 17);
  1657 + gen_movl_reg_T0(rs1);
  1658 + if (IS_IMM) { /* immediate */
  1659 + rs2 = GET_FIELDs(insn, 20, 31);
  1660 + gen_movl_simm_T1(rs2);
  1661 + } else { /* register */
  1662 + rs2 = GET_FIELD(insn, 27, 31);
  1663 + gen_movl_reg_T1(rs2);
  1664 + }
  1665 + gen_op_sll();
  1666 + gen_movl_T0_reg(rd);
  1667 + } else if (xop == 0x26) { /* srl, V9 srlx */
  1668 + rs1 = GET_FIELD(insn, 13, 17);
  1669 + gen_movl_reg_T0(rs1);
  1670 + if (IS_IMM) { /* immediate */
  1671 + rs2 = GET_FIELDs(insn, 20, 31);
  1672 + gen_movl_simm_T1(rs2);
  1673 + } else { /* register */
  1674 + rs2 = GET_FIELD(insn, 27, 31);
  1675 + gen_movl_reg_T1(rs2);
  1676 + }
  1677 + if (insn & (1 << 12))
  1678 + gen_op_srlx();
  1679 + else
  1680 + gen_op_srl();
  1681 + gen_movl_T0_reg(rd);
  1682 + } else if (xop == 0x27) { /* sra, V9 srax */
  1683 + rs1 = GET_FIELD(insn, 13, 17);
  1684 + gen_movl_reg_T0(rs1);
  1685 + if (IS_IMM) { /* immediate */
  1686 + rs2 = GET_FIELDs(insn, 20, 31);
  1687 + gen_movl_simm_T1(rs2);
  1688 + } else { /* register */
  1689 + rs2 = GET_FIELD(insn, 27, 31);
  1690 + gen_movl_reg_T1(rs2);
  1691 + }
  1692 + if (insn & (1 << 12))
  1693 + gen_op_srax();
  1694 + else
  1695 + gen_op_sra();
  1696 + gen_movl_T0_reg(rd);
  1697 +#endif
1552 } else if (xop < 0x38) { 1698 } else if (xop < 0x38) {
1553 rs1 = GET_FIELD(insn, 13, 17); 1699 rs1 = GET_FIELD(insn, 13, 17);
1554 gen_movl_reg_T0(rs1); 1700 gen_movl_reg_T0(rs1);
@@ -1660,32 +1806,20 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1660,32 +1806,20 @@ static void disas_sparc_insn(DisasContext * dc)
1660 gen_op_mulscc_T1_T0(); 1806 gen_op_mulscc_T1_T0();
1661 gen_movl_T0_reg(rd); 1807 gen_movl_T0_reg(rd);
1662 break; 1808 break;
1663 - case 0x25: /* sll, V9 sllx ( == sll) */ 1809 +#ifndef TARGET_SPARC64
  1810 + case 0x25: /* sll */
1664 gen_op_sll(); 1811 gen_op_sll();
1665 gen_movl_T0_reg(rd); 1812 gen_movl_T0_reg(rd);
1666 break; 1813 break;
1667 - case 0x26: /* srl, V9 srlx */  
1668 -#ifdef TARGET_SPARC64  
1669 - if (insn & (1 << 12))  
1670 - gen_op_srlx();  
1671 - else  
1672 - gen_op_srl();  
1673 -#else 1814 + case 0x26: /* srl */
1674 gen_op_srl(); 1815 gen_op_srl();
1675 -#endif  
1676 gen_movl_T0_reg(rd); 1816 gen_movl_T0_reg(rd);
1677 break; 1817 break;
1678 - case 0x27: /* sra, V9 srax */  
1679 -#ifdef TARGET_SPARC64  
1680 - if (insn & (1 << 12))  
1681 - gen_op_srax();  
1682 - else  
1683 - gen_op_sra();  
1684 -#else 1818 + case 0x27: /* sra */
1685 gen_op_sra(); 1819 gen_op_sra();
1686 -#endif  
1687 gen_movl_T0_reg(rd); 1820 gen_movl_T0_reg(rd);
1688 break; 1821 break;
  1822 +#endif
1689 case 0x30: 1823 case 0x30:
1690 { 1824 {
1691 switch(rd) { 1825 switch(rd) {
@@ -1709,7 +1843,28 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1709,7 +1843,28 @@ static void disas_sparc_insn(DisasContext * dc)
1709 gen_op_sir(); 1843 gen_op_sir();
1710 #endif 1844 #endif
1711 break; 1845 break;
  1846 + case 0x17: /* Tick compare */
  1847 +#if !defined(CONFIG_USER_ONLY)
  1848 + if (!supervisor(dc))
  1849 + goto illegal_insn;
  1850 +#endif
  1851 + gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
  1852 + break;
  1853 + case 0x18: /* System tick */
  1854 +#if !defined(CONFIG_USER_ONLY)
  1855 + if (!supervisor(dc))
  1856 + goto illegal_insn;
  1857 +#endif
  1858 + gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
  1859 + break;
  1860 + case 0x19: /* System tick compare */
  1861 +#if !defined(CONFIG_USER_ONLY)
  1862 + if (!supervisor(dc))
  1863 + goto illegal_insn;
1712 #endif 1864 #endif
  1865 + gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
  1866 + break;
  1867 +
1713 case 0x10: /* Performance Control */ 1868 case 0x10: /* Performance Control */
1714 case 0x11: /* Performance Instrumentation Counter */ 1869 case 0x11: /* Performance Instrumentation Counter */
1715 case 0x12: /* Dispatch Control */ 1870 case 0x12: /* Dispatch Control */
@@ -1717,9 +1872,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1717,9 +1872,7 @@ static void disas_sparc_insn(DisasContext * dc)
1717 case 0x14: /* Softint set */ 1872 case 0x14: /* Softint set */
1718 case 0x15: /* Softint clear */ 1873 case 0x15: /* Softint clear */
1719 case 0x16: /* Softint write */ 1874 case 0x16: /* Softint write */
1720 - case 0x17: /* Tick compare */  
1721 - case 0x18: /* System tick */  
1722 - case 0x19: /* System tick compare */ 1875 +#endif
1723 default: 1876 default:
1724 goto illegal_insn; 1877 goto illegal_insn;
1725 } 1878 }
@@ -1770,7 +1923,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1770,7 +1923,7 @@ static void disas_sparc_insn(DisasContext * dc)
1770 gen_op_wrtick(); 1923 gen_op_wrtick();
1771 break; 1924 break;
1772 case 5: // tba 1925 case 5: // tba
1773 - gen_op_movl_env_T0(offsetof(CPUSPARCState, tbr)); 1926 + gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
1774 break; 1927 break;
1775 case 6: // pstate 1928 case 6: // pstate
1776 gen_op_wrpstate(); 1929 gen_op_wrpstate();
@@ -1896,7 +2049,6 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1896,7 +2049,6 @@ static void disas_sparc_insn(DisasContext * dc)
1896 } 2049 }
1897 #ifdef TARGET_SPARC64 2050 #ifdef TARGET_SPARC64
1898 } else if (xop == 0x39) { /* V9 return */ 2051 } else if (xop == 0x39) { /* V9 return */
1899 - gen_op_restore();  
1900 rs1 = GET_FIELD(insn, 13, 17); 2052 rs1 = GET_FIELD(insn, 13, 17);
1901 gen_movl_reg_T0(rs1); 2053 gen_movl_reg_T0(rs1);
1902 if (IS_IMM) { /* immediate */ 2054 if (IS_IMM) { /* immediate */
@@ -1920,6 +2072,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1920,6 +2072,7 @@ static void disas_sparc_insn(DisasContext * dc)
1920 } 2072 }
1921 #endif 2073 #endif
1922 } 2074 }
  2075 + gen_op_restore();
1923 gen_mov_pc_npc(dc); 2076 gen_mov_pc_npc(dc);
1924 gen_op_movl_npc_T0(); 2077 gen_op_movl_npc_T0();
1925 dc->npc = DYNAMIC_PC; 2078 dc->npc = DYNAMIC_PC;
@@ -1993,13 +2146,17 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1993,13 +2146,17 @@ static void disas_sparc_insn(DisasContext * dc)
1993 case 0: 2146 case 0:
1994 if (!supervisor(dc)) 2147 if (!supervisor(dc))
1995 goto priv_insn; 2148 goto priv_insn;
  2149 + dc->npc = DYNAMIC_PC;
  2150 + dc->pc = DYNAMIC_PC;
1996 gen_op_done(); 2151 gen_op_done();
1997 - break; 2152 + goto jmp_insn;
1998 case 1: 2153 case 1:
1999 if (!supervisor(dc)) 2154 if (!supervisor(dc))
2000 goto priv_insn; 2155 goto priv_insn;
  2156 + dc->npc = DYNAMIC_PC;
  2157 + dc->pc = DYNAMIC_PC;
2001 gen_op_retry(); 2158 gen_op_retry();
2002 - break; 2159 + goto jmp_insn;
2003 default: 2160 default:
2004 goto illegal_insn; 2161 goto illegal_insn;
2005 } 2162 }
@@ -2317,7 +2474,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2317,7 +2474,7 @@ static void disas_sparc_insn(DisasContext * dc)
2317 gen_op_next_insn(); 2474 gen_op_next_insn();
2318 } else if (dc->npc == JUMP_PC) { 2475 } else if (dc->npc == JUMP_PC) {
2319 /* we can do a static jump */ 2476 /* we can do a static jump */
2320 - gen_op_branch2((long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]); 2477 + gen_branch2(dc, (long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
2321 dc->is_br = 1; 2478 dc->is_br = 1;
2322 } else { 2479 } else {
2323 dc->pc = dc->npc; 2480 dc->pc = dc->npc;
@@ -2365,6 +2522,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -2365,6 +2522,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
2365 gen_opc_ptr = gen_opc_buf; 2522 gen_opc_ptr = gen_opc_buf;
2366 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; 2523 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2367 gen_opparam_ptr = gen_opparam_buf; 2524 gen_opparam_ptr = gen_opparam_buf;
  2525 + nb_gen_labels = 0;
2368 2526
2369 do { 2527 do {
2370 if (env->nb_breakpoints > 0) { 2528 if (env->nb_breakpoints > 0) {
@@ -2421,7 +2579,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -2421,7 +2579,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
2421 if (dc->pc != DYNAMIC_PC && 2579 if (dc->pc != DYNAMIC_PC &&
2422 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) { 2580 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
2423 /* static PC and NPC: we can use direct chaining */ 2581 /* static PC and NPC: we can use direct chaining */
2424 - gen_op_branch((long)tb, dc->pc, dc->npc); 2582 + gen_branch(dc, (long)tb, dc->pc, dc->npc);
2425 } else { 2583 } else {
2426 if (dc->pc != DYNAMIC_PC) 2584 if (dc->pc != DYNAMIC_PC)
2427 gen_jmp_im(dc->pc); 2585 gen_jmp_im(dc->pc);
@@ -2487,15 +2645,16 @@ void cpu_reset(CPUSPARCState *env) @@ -2487,15 +2645,16 @@ void cpu_reset(CPUSPARCState *env)
2487 #else 2645 #else
2488 env->psrs = 1; 2646 env->psrs = 1;
2489 env->psrps = 1; 2647 env->psrps = 1;
2490 - env->pc = 0xffd00000;  
2491 env->gregs[1] = ram_size; 2648 env->gregs[1] = ram_size;
2492 - env->npc = env->pc + 4;  
2493 #ifdef TARGET_SPARC64 2649 #ifdef TARGET_SPARC64
2494 - env->pstate = PS_AM | PS_PRIV; // XXX: Force AM 2650 + env->pstate = PS_PRIV;
2495 env->version = GET_VER(env); 2651 env->version = GET_VER(env);
  2652 + env->pc = 0x1fff0000000ULL;
2496 #else 2653 #else
2497 env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ 2654 env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
  2655 + env->pc = 0xffd00000;
2498 #endif 2656 #endif
  2657 + env->npc = env->pc + 4;
2499 #endif 2658 #endif
2500 } 2659 }
2501 2660
@@ -559,6 +559,7 @@ void pci_set_pic(PCIBus *bus, SetIRQFunc *set_irq, void *irq_opaque); @@ -559,6 +559,7 @@ void pci_set_pic(PCIBus *bus, SetIRQFunc *set_irq, void *irq_opaque);
559 PCIBus *pci_prep_init(void); 559 PCIBus *pci_prep_init(void);
560 PCIBus *pci_grackle_init(uint32_t base); 560 PCIBus *pci_grackle_init(uint32_t base);
561 PCIBus *pci_pmac_init(void); 561 PCIBus *pci_pmac_init(void);
  562 +PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base);
562 563
563 /* openpic.c */ 564 /* openpic.c */
564 typedef struct openpic_t openpic_t; 565 typedef struct openpic_t openpic_t;