qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 13/24] Add target-alpha/machine.c with es40 machine


From: Tristan Gingold
Subject: [Qemu-devel] [PATCH 13/24] Add target-alpha/machine.c with es40 machine emulation.
Date: Fri, 13 Mar 2009 15:20:32 +0100

The machine emulation is not yet complete, in particular vm save and load is
not yet implemented.

Signed-off-by: Tristan Gingold <address@hidden>
---
 Makefile.target        |    4 +
 hw/boards.h            |    4 +
 hw/es40.c              |  922 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-alpha/machine.c |   22 ++
 4 files changed, 952 insertions(+), 0 deletions(-)
 create mode 100644 hw/es40.c
 create mode 100644 target-alpha/machine.c

diff --git a/Makefile.target b/Makefile.target
index 9a2f123..05eb7ed 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -683,6 +683,10 @@ ifeq ($(TARGET_BASE_ARCH), m68k)
 OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
 OBJS+= m68k-semi.o dummy_m68k.o
 endif
+ifeq ($(TARGET_BASE_ARCH), alpha)
+OBJS+= es40.o 21272.o serial.o i8259.o mc146818rtc.o i8254.o pcspk.o dma.o
+OBJS+= ali1543.o
+endif
 ifdef CONFIG_GDBSTUB
 OBJS+=gdbstub.o gdbstub-xml.o
 endif
diff --git a/hw/boards.h b/hw/boards.h
index 1e62594..85e775d 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -128,4 +128,8 @@ extern QEMUMachine musicpal_machine;
 /* tosa.c */
 extern QEMUMachine tosapda_machine;
 
+/* es40.c */
+extern QEMUMachine es40_machine;
+extern QEMUMachine es40_rombuild_machine;
+
 #endif
diff --git a/hw/es40.c b/hw/es40.c
new file mode 100644
index 0000000..2299727
--- /dev/null
+++ b/hw/es40.c
@@ -0,0 +1,922 @@
+/*
+ * QEMU ES-40 System Emulator
+ *
+ * Copyright (c) 2009 AdaCore
+ *
+ * Written by Tristan Gingold.
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+#include <time.h>
+#include <sys/time.h>
+#include "hw.h"
+#include "net.h"
+#include "sysemu.h"
+#include "devices.h"
+#include "boards.h"
+#include "pc.h"
+#include "isa.h"
+#include "pci.h"
+
+/* Building the firmware for es40:
+
+   The main part of the firmware is called SRM.  You can get an original
+   image from HP web site:
+
+   
ftp://ftp.hp.com/pub/alphaserver/firmware/current_platforms/v7.3_release/ES40_series/ES40/es40.zip
+
+   Extract the archive and copy cl67srmrom.exe into a directory.
+
+   Then start Qemu using es40-rombuild machine:
+
+   $ qemu-system-alpha -M es40-rombuild -boot n -L .
+
+   This builds the rom, writes es40.rom file and exits.  Now you have it.
+*/
+
+//#define DEBUG_TIGBUS
+
+/* For Rombuild.  */
+#define ROMBUILD_BIOS_FILENAME "cl67srmrom.exe"
+#define LFU_HDR_SIZE 0x240
+#define LFU_START_ADDR 0x900000
+#define LFU_LOAD_ADDR  0x900000
+#define LFU_MEM_SIZE   0x1000000
+#define LFU_RAM_OFFSET 0x400000
+
+#define SRM_SIZE 0x200000
+
+/* For es40.  */
+#define BIOS_FILENAME "es40.rom"
+
+static ram_addr_t ram_offset;
+
+static void illegal_write (void *opaque,
+                           target_phys_addr_t addr, uint32_t value)
+{
+    qemu_log("illegal_write at addr="TARGET_FMT_lx"\n", addr);
+}
+
+static uint32_t illegal_read (void *opaque, target_phys_addr_t addr)
+{
+    qemu_log("illegal_read at addr="TARGET_FMT_lx"\n", addr);
+    return 0;
+}
+
+typedef struct tigbus_t tigbus_t;
+struct tigbus_t {
+    /* See 264dptrm.pdf.  */
+    unsigned char halt_a;
+    unsigned char halt_b;
+};
+
+static uint32_t tigbus_readl (void *opaque, target_phys_addr_t addr)
+{
+    tigbus_t *s = opaque;
+    uint32_t ret;
+    int reg = addr >> 6;
+
+    /* TIGbus registers are mostly only 8 bits.  */
+    if (addr & 0x04)
+       return 0;
+
+    switch (reg) {
+    case 0x17:
+       ret = s->halt_b;
+       break;
+    case 0x12: /* Power fault detected.  */
+       ret = 0;
+       break;
+    case 0x04:
+       ret = 0;
+       break;
+    default:
+       qemu_log("tigbus: unhandled read reg=%02x\n", reg);
+        ret = 0;
+        break;
+    }
+
+#ifdef DEBUG_TIGBUS
+    fprintf(stderr,"tigbus read  reg=%02x, val=%08x\n", reg, ret);
+#endif
+    return ret;
+}
+
+static void tigbus_writel (void *opaque,
+                           target_phys_addr_t addr, uint32_t value)
+{
+    tigbus_t *s = opaque;
+    int reg = addr >> 6;
+
+    if (addr & 0x04)
+       return;
+
+#ifdef DEBUG_TIGBUS
+    fprintf(stderr,"tigbus write reg=%02x, val=%08x\n", reg, value);
+#endif
+
+    switch (reg) {
+    case 0x17:
+       s->halt_b = value & 0x0f;
+       break;
+    case 0x12: /* Power fault detected.  */
+       break;
+    default:
+       qemu_log("tigbus: unhandled write to reg=0x%02x (%08x)\n",
+                reg, value);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc *tigbus_read[] = {
+    &illegal_read,
+    &illegal_read,
+    &tigbus_readl,
+};
+
+static CPUWriteMemoryFunc *tigbus_write[] = {
+    &illegal_write,
+    &illegal_write,
+    &tigbus_writel,
+};
+
+/* Dual Port Ram.
+
+0 0 SROM EV6 BIST status 1=good  0=bad 
+1 1 SROM Bit[7]=Master Bits[0,1]=CPU_ID 
+2 2 SROM Test STR status 1=good  0=bad 
+3 3 SROM Test CSC status 1=good  0=bad 
+4 4 SROM Test Pchip 0 PCTL status 1=good, 0=bad 
+5 5 SROM Test Pchip 1  PCTL status 1=good, 0=bad 
+6 6 SROM Test DIMx status 1=good  0=bad 
+7 7 SROM Test TIG bus status 
+8 8 SROM Dual-Port RAM test DD= started 
+9 9 SROM Status of DPR test 1=good  0=bad 
+A A SROM Status of CPU speed function  FF=good, 0=bad 
+B B SROM Lower byte of CPU speed in MHz 
+C C SROM Upper byte of CPU speed in MHz 
+D:F - - Reserved 
+10:15 SROM Power On Time Stamp for CPU 0—written as BCD 
+ Byte 10 = Hours (0-23) 
+ Byte 11 = Minutes (0-59) 
+ Byte 12 = Seconds (0-59) 
+ Byte 13 = Day of Month (1-31) 
+ Byte 14 = Month (1-12) 
+ Byte 15 = Year (0-99)
+16 SROM SROM Power On Error Indication for CPU is “alive.”
+ For example; 0 = no error, 2 = Secondary time-out Error, 3 = Bcache Error 
+17:1D Unused 
+1E SROM Last “sync state” reached;  80=Finished GOOD 
+1F SROM Size of Bcache in MB 
+20:3F 20 Repeat  for CPU1 of CPU0    0-1F 
+40:5F 20 Repeat  for CPU2 of CPU0    0-1F 
+60:7F 20 Repeat  for CPU3 of CPU0    0-1F 
+80 80 SROM Array 0 (AAR 0)  Configuration 
+   Bits<7:4> 
+ 4 = non split -  lower set only 
+ 5 = split - lower set only 
+ 9 = split -  upper set only 
+ D = split - 8 DIMMs 
+ F = Twice split -  8 DIMMs 
+     Bits<3:0> 
+ 0 = Configured -  Lowest array 
+ 1 = Configured -  Next lowest array 
+ 2 = Configured -  Second highest  array 
+ 3 = Configured -  Highest array 
+ 4 = Misconfigured -  Missing DIMM(s) 
+ 8 = Miconfigured -  Illegal DIMM(s) 
+ C = Misconfigured -  Incompatible  DIMM(s)
+81 81 SROM Array 0 (AAR 0)Size (x64 Mbytes) 
+  0 = no good memory 
+  1 =   64 Mbyte 
+  2 = 128 Mbyte 
+  4 = 256 Mbyte 
+  8 = 512 Mbyte 
+ 10 =     1 Gbyte 
+ 20 =     2 Gbyte 
+ 40 =     4 Gbyte 
+ 80 =     8 Gbyte 
+82 82 SROM Array 1 (AAR 1) Configuration 
+83 83 SROM Array 1 (AAR 1) Size (x64 Mbytes) 
+84 84 SROM Array 2  (AAR 2) Configuration 
+85 85 SROM Array 2 (AAR  2) Size (x64 Mbytes) 
+86 86 SROM Array 3  (AAR 3) Configuration 
+87 87 SROM Array 3 (AAR 3) Size (x64 Mbytes) 
+88:8B SROM Byte to define failed DIMMs for MMBs 
+88 - MMB 0 
+89 - MMB 1 
+8A - MMB 2 
+8B - MMB 3 
+ Bit set indicates failure. 
+ Bit definitions ( bit 0 = DIMM 1, bit 1 = DIMM2, 
+ bit 2 = DIMM 3, bit 7 = DIMM 8) 
+8C:8F 8C-8F SROM Byte to define misconfigured DIMMs for MMBs 
+8C – MMB 0 
+8D – MMB 1 
+8E – MMB 2 
+8F – MMB 3 
+ Bit definitions ( bit 0 = DIMM 1, bit 1 = DIMM2, 
+ bit 2 = DIMM 3, bit 7 = DIMM 8) 
+90 90 RMC Power Supply/VTERM  present 
+91 91 RMC Power Supply  PS_POK bits 
+92 92 RMC AC input value from Power Supply
+93:96 93 RMC Temperature from CPU(x) in BCD 
+97:99 97 RMC Temperature Zone(x) from 3 PCI temp sensors 
+9A:9F 9A RMC Fan Status; Raw Fan speed value 
+A0:A9 A0 RMC Failure registers used as part of the 680 machine 
+ check logout frame.  See Appendix D. 
+AA RMC Fan status (bit 0 = fan 1, bit 1 = fan 2, 
+ 1- indicates good; 0 indicates fan failure 
+AB RMC Status of RMC to read I2C bus of MMB0  DIMMs 
+ Definition: 
+   Bit 7 - DIMM 8   0=OK  1=Fail 
+   Bit 6 - DIMM 7 
+   Bit 5 - DIMM 6 
+    ……………… 
+   Bit 0 - DIMM 1 
+AC RMC Status of RMC to read I2C bus of MMB1 DIMMs 
+AD RMC Status of RMC to read I2C bus of MMB2 DIMMs 
+AE RMC Status of RMC to read I2C bus of MMB3 DIMMs 
+AF RMC Status of RMC to read MMB and CPU I2C buses 
+ Definition: 
+  Bit 7 - MMB3     0=OK  1=Fail 
+  Bit 6 - MMB2 
+  Bit 5 - MMB1 
+  Bit 4 - MMB0 
+  Bit 3 - CPU3 
+  Bit 2 - CPU2 
+  Bit 1 - CPU1 
+  Bit 0 - CPU0 
+B0 RMC Status of RMC to read CPB (PCI backplane) I2C EEROM 0=OK  1 = fail 
+B1 RMC Status of RMC to read CSB (motherboard) I2C EEROM  0=OK  1 = fail
+B2 RMC Status of RMC to read SCSI backplane 
+Definition: 
+  Bit 0 — SCSI backplane 0 
+  Bit 1 — SCSI backplane 1 
+  Bit 4 — Power supply 0 
+  Bit 5 — Power supply 1 
+  Bit 6 — Power supply 2 
+B3:B9 Unused Unused 
+BA RMC I2C done, BA =  finished 
+BB RMC RMC Power on Error indicates error during power-up (1=Flash Corrupted) 
+BC RMC RMC flash update error status 
+BD RMC Copy of PS input Value.  See Appendix D. 
+BE RMC Copy of the byte from the I/O expanders on the 
+ SPC loaded by the RMC on fatal errors.  See Appendix D. 
+BF RMC Reason for system failure.  See Appendix D. 
+C0:D8 Unused 
+D9 RMC Baud rate 
+DA TIG Indicates TIG finished loading its code (0xAA indicates done) 
+DB:E3 RMC Fan/Temp info from PS1 
+E4:EC RMC Fan/Temp info from PS2 
+ED:F5 RMC Fan/Temp info from PS3 
+F6:F8 Unused Unused 
+F9 Firmware Buffer Size (0-0xFF) or 1 to 256 bytes 
+FA:FB FA Firmware Command address qualifier 
+FA = lower byte, FB = upper byte
+FC FC RMC Command status associated with the RMC 
+ response to a request from the firmware 
+  0 = successful completion 
+80 = unsuccessful completion 
+81 = invalid command code 
+82 = invalid command qualifier 
+FD FD RMC Command ID associated with the RMC 
+  response to a request from the firmware 
+FE FE Firmware Command Code associated with a “command” 
+sent to the RMC 
+  1 = update I2C EEROM 
+  2 = update baud rate 
+  3 = display to OCP 
+F0 = update RMC flash 
+FF FF Firmware Command ID associated with a “command” sent to the RMC 
+100:1FF 100 RMC Copy of EEROM on MMB0 J1 DIMM 1, 
+ initially read on I2C bus by RMC when 5 
+ volts supply turned on. Written by Compaq 
+ Analyze after error diagnosed to particular FRU 
+200:2FF 200 RMC Copy of EEROM on MMB0 J2 DIMM 2 
+300:3FF 300 RMC Copy of EEROM on MMB0 J3 DIMM 3 
+400:4FF 400 RMC Copy of EEROM on MMB0 J4 DIMM 4 
+500:5FF 500 RMC Copy of EEROM on MMB0 J5 DIMM 5 
+600:7FF 600 RMC Copy of EEROM on MMB0 J6 DIMM 6 
+700:7FF 700 RMC Copy of EEROM on MMB0 J7 DIMM 7 
+800:8FF 800 RMC Copy of EEROM on MMB0 J8 DIMM 8 
+900:9FF 900 RMC Copy of EEROM on MMB1 J1 DIMM 1 
+A00:AFF A00 RMC Copy of EEROM on MMB1 J2 DIMM 2 
+B00:BFF B00 RMC Copy of EEROM on MMB1 J3 DIMM 3 
+C00:CFF C00 RMC Copy of EEROM on MMB1 J4 DIMM 4 
+D00:DFF D00 RMC Copy of EEROM on MMB1 J5 DIMM 5 
+E00:EFF E00 RMC Copy of EEROM on MMB1 J6 DIMM 6 
+F00:FFF F00 RMC Copy of EEROM on MMB1 J7 DIMM 7
+1000:10FF 1000 RMC Copy of EEROM on MMB1 J8 DIMM 8 
+1100:11FF 1100 RMC Copy of EEROM on MMB2 J1 DIMM 1 
+1200:12FF 1200 RMC Copy of EEROM on MMB2 J2 DIMM 2 
+1300:13FF 1300 RMC Copy of EEROM on MMB2 J3 DIMM 3 
+1400:14FF 1400 RMC Copy of EEROM on MMB2 J4 DIMM 4 
+1500:15FF 1500 RMC Copy of EEROM on MMB2 J5 DIMM 5 
+1600:16FF 1600 RMC Copy of EEROM on MMB2 J6 DIMM 6 
+1700:17FF 1700 RMC Copy of EEROM on MMB2 J7 DIMM 7 
+1800:18FF 1800 RMC Copy of EEROM on MMB2 J8 DIMM 8 
+1900:19FF 1900 RMC Copy of EEROM on MMB3 J1 DIMM 1 
+1A00:1AFF 1A00 RMC Copy of EEROM on MMB3 J2 DIMM 2 
+1B00:1BFF 1B00 RMC Copy of EEROM on MMB3 J3 DIMM 3 
+1C00:1CFF 1C00 RMC Copy of EEROM on MMB3 J4 DIMM 4 
+1D00:1DFF 1D00 RMC Copy of EEROM on MMB3 J5 DIMM 5 
+1E00:1EFF 1E00 RMC Copy of EEROM on MMB3 J6 DIMM 6 
+1F00:1FFF 1F00 RMC Copy of EEROM on MMB3 J7 DIMM 7 
+2000:20FF 2000 RMC Copy of EEROM on MMB3 J8 DIMM 8 
+2100:21FF 2100 RMC Copy of EEROM from CPU0 
+2200:22FF 2200 RMC Copy of EEROM from CPU1 
+2300:23FF 2300 RMC Copy of EEROM from CPU2 
+2400:24FF 2400 RMC Copy of EEROM from CPU3 
+2500:25FF 2500 RMC Copy of MMB 0  J5 FRU EEROM 
+2600:26FF 2600 RMC Copy of MMB 1  J7 FRU EEROM 
+2700:27FF 2700 RMC Copy of MMB 2  J6 FRU EEROM 
+2800:28FF 2800 RMC Copy of MMB 3  J8 FRU EEROM 
+2900:29FF 2900 RMC Copy of EEROM on CPB (PCI backplane) 
+2A00:2AFF 2A00 RMC Copy of EEROM on CSB (motherboard) 
+2B00:2BFF 2B00 RMC Last EV6 Correctable Error—ASCII 
+ character string that indicates correctable 
+ error occurred, type, FRU, and so on.  Backed 
+ up in CSB (motherboard) EEROM. Written by Compaq Analyze
+2C00:2CFF 2C00 RMC Last Redundant Failure—ASCII 
+ character string that indicates redundant 
+ failure occurred, type, FRU, and so on. 
+ Backed up in system CSB (motherboard) EEROM. Written by Compaq Analyze 
+2D00:2DFF 2D00 RMC Last System Failure—ASCII character 
+ string that indicates system failure occurred, type, FRU, and so on. Backed 
+ up in CSB (motherboard) EEROM. Written by Compaq Analyze. 
+2E00:2FFF 2E00 RMC Uncorrectable machine logout frame (512 bytes) 
+3000:3008 SROM SROM Version  (ASCII string) 
+3009:300B RMC Rev Level of RMC first byte is letter Rev 
+ [x/t/v] second 2 bytes are major/minor. 
+ This is the rev level of the RMC on-chip code. 
+300C:300E RMC Rev Level of RMC first byte is letter Rev 
+ [x/t/v] second 2 bytes are major/minor. 
+ This is the rev level of the RMC flash code. 
+300F:3010 300F RMC Revision Field of the DPR Structure 
+3011:30FF Unused Unused 
+3100:31FF RMC Copy of PS0 EEROM (first 256 bytes) 
+3200:32FF RMC Copy of PS1  EEROM (first 256 bytes) 
+3300:33FF RMC Copy of PS2  EEROM (first 256 bytes) 
+3400 SROM Size of Bcache in MB 
+3401 SROM Flash SROM is valid flag; 8 = valid, 0 = invalid 
+3402 SROM System’s errors determined by SROM 
+3403:340F SROM/SRM Reserved for future SROM/SRM communication 
+3410:3417 SROM/SRM Jump to address for CPU0
+3418 SROM/SRM Waiting to jump to flag for CPU0 
+3419 SROM Shadow of value written to EV6 DC_CTL register. 
+341A:341E SROM Shadow of most recent writes to EV6 CBOX “Write-many” 
chain. 
+341F SROM/SRM Reserved for future SROM/SRM communication 
+3420:342F SROM/SRM Repeat  for CPU1 of CPU0    3410-341F 
+3430:343F SROM/SRM Repeat  for CPU2 of CPU0    3410-341F 
+3440:344F SROM/SRM Repeat  for CPU3 of CPU0    3410-341F 
+3450:349F SROM/RMC Reserved for SROM mini-console via 
+ RMC communication area. Future design. 
+34A0:34A7 SROM Array 0 to DIMM ID translation 
+ Bits<7:5> 
+ 0 = Exists, No Error 
+ 1 = Expected Missing 
+ 2 = Error - Missing  DIMM(s) 
+ 4 = Error - Illegal DIMM(s) 
+ 6 = Error - Incompatible DIMM(s) 
+ Bits<4:0> 
+ Bits <2:0> = DIMM + 1 (1-8) 
+ Bits <4:3> = MMB (0-3) 
+34A8:34AF SROM Repeat for Array 1 of Array 0 
+34A0:34A7 
+34B0:34B7 SROM Repeat for Array 2 of Array 0 
+34A0:34A7 
+34B8:34CF SROM Repeat for Array 3 of Array 0 
+34A0:34A7 
+34C0:34FF 34C0 SROM Used as scratch area for SROM
+3500:35FF Firmware Used as the dedicated buffer in which 
+ SRM writes OCP or FRU EEROM data. 
+ Firmware will write this data, RMC will only read this data. 
+3600:36FF 3600 SRM Reserved 
+3700:37FF SRM Reserved 
+3800:3AFF RMC RMC scratch space 
+3B00:3BFF RMC First SCSI backplane EEROM 
+3C00:3CFF RMC Second SCSI backplane EEROM 
+3D00:3DFF RMC PS0 second 256 bytes 
+3E00:3EFF RMC PS1 second 256 bytes 
+3F00:3FFF RMC PS2 second 256 bytes
+*/
+
+struct dpram_t {
+    unsigned char mem[0x4000];
+    uint32_t set_vec[0x4000 >> 5];
+};
+typedef struct dpram_t dpram_t;
+
+static uint32_t tigbus_dpram_readl (void *opaque, target_phys_addr_t addr)
+{
+    dpram_t *dpr = opaque;
+    int reg = addr >> 6;
+
+    /* Discard upper long word.  */
+    if (addr & 0x4)
+       return 0;
+
+#if 0
+    if (!(dpr->set_vec[reg >> 5] &(1 << (reg & 0x1f))))
+       fprintf(stderr,"tigbus dpram: reading uninitialized 0x%04x\n", reg);
+#endif
+
+    return dpr->mem[reg];
+}
+
+static void tigbus_dpram_writel (void *opaque,
+                              target_phys_addr_t addr, uint32_t value)
+{
+    dpram_t *dpr = opaque;
+    int reg = addr >> 6;
+    
+    /* Discard upper long word.  */
+    if (addr & 0x4)
+       return;
+
+#if 0
+    fprintf(stderr, "tigbus dpram write %02x at %08x (%04x)\n",
+           value, (unsigned int) addr, reg);
+#endif
+
+    dpr->mem[reg] = value;
+    dpr->set_vec[reg >> 5] |= (1 << (reg & 0x1f));
+    if (reg == 0xff) {
+       const char *cmd;
+       dpr->mem[0xfc] = 0;
+       dpr->mem[0xfd] = dpr->mem[0xff];
+       switch (dpr->mem[0xfe]) {
+       case 0x01:
+           cmd = "eeprom update";
+           break;
+       case 0x02:
+           cmd = "baud rate update";
+           break;
+       case 0x03:
+       {
+           char buf[17];
+           memcpy(buf, &dpr->mem[0x3500], 16);
+           buf[16] = 0;
+           fprintf(stderr,"OCP message: [%s]\n", buf);
+#if 0
+           if (strncmp (buf, "create powerup  ", 16) == 0) {
+               loglevel = CPU_LOG_TB_IN_ASM | CPU_LOG_EXEC | CPU_LOG_TB_CPU;
+           }
+#endif
+           if (1)
+             cmd = NULL;
+           else
+             cmd = "OCP display";
+           break;
+       }
+       case 0xf0:
+           cmd = "update RMC flash";
+           break;
+       default:
+           cmd = NULL;
+           fprintf(stderr,"tigbus dpram: cmd unknown 0x%02x\n",
+                   dpr->mem[0xfe]);
+           dpr->mem[0xfc] = 0x81;
+           break;
+       }
+       if (cmd) {
+           fprintf(stderr,
+                   "tigbus dpram: cmd %02x, id=%02x: %s, addr=%04x len=%d\n",
+                   dpr->mem[0xfe], dpr->mem[0xff],
+                   cmd, (dpr->mem[0xfb] << 8) | dpr->mem[0xfa],
+                   dpr->mem[0xf9] + 1);
+       }
+    }
+}
+
+static CPUReadMemoryFunc *tigbus_dpram_read[] = {
+    &illegal_read,
+    &illegal_read,
+    &tigbus_dpram_readl,
+};
+
+static CPUWriteMemoryFunc *tigbus_dpram_write[] = {
+    &illegal_write,
+    &illegal_write,
+    &tigbus_dpram_writel,
+};
+
+static void dpr_set(dpram_t *dpr, int reg, unsigned char val)
+{
+    dpr->mem[reg] = val;
+    dpr->set_vec[reg >> 5] |= (1 << (reg & 0x1f));
+}
+
+static void tigbus_reset (void *opaque)
+{
+    /* tigbus_t *s = opaque; */
+}
+
+static void tigbus_init (uint64_t arr[])
+{
+    tigbus_t *s;
+    int mem;
+    int dpram_io;
+    dpram_t *dpram;
+    int i;
+
+    s = qemu_mallocz(sizeof(tigbus_t));
+    mem = cpu_register_io_memory(0, tigbus_read, tigbus_write, s);
+    cpu_register_physical_memory(0x80130000000ULL, 0x0002000, mem);
+
+    dpram = qemu_mallocz(sizeof(dpram_t));
+    dpram_io = cpu_register_io_memory(0, tigbus_dpram_read,
+                                     tigbus_dpram_write, dpram);
+    cpu_register_physical_memory(0x80110000000ULL, 0x0100000, dpram_io);
+
+    /* Initialize dpram.  */
+#define S(r,v) dpr_set(dpram,r,v)
+    S(0x00, 1); /* BIST OK */
+    S(0x01, 0x80); /* CPU 0 is master */
+    S(0x02, 1); /* STR ok */
+    S(0x03, 1); /* CSC ok */
+    S(0x04, 1); /* Pchip0 ok */
+    S(0x05, 1); /* Pchip1 ok */
+    S(0x06, 1); /* DIMx ok */
+    S(0x07, 1); /* TIG ok */
+    S(0x08, 0xdd); /* DPRam ok */
+    S(0x09, 0x1); /* DPRDDam ok */
+    S(0x0a, 0xff); /* cpu speed ok */
+    S(0x0b, 600 % 256);
+    S(0x0c, 600 / 256);
+    /* Unused.  */
+    S(0x0d, 0);
+    S(0x0e, 0);
+    S(0x0f, 0);
+    /* Power On time stamp.  Use RTC ?  */
+    S(0x10, 0x12);
+    S(0x11, 0x30);
+    S(0x12, 0x25);
+    S(0x13, 0x15);
+    S(0x14, 0x02);
+    S(0x15, 0x05);
+    S(0x16, 0x0); /* Power On indicator.  */
+    /* Unused.  */
+    S(0x17, 0);
+    S(0x18, 0);
+    S(0x19, 0);
+    S(0x1a, 0);
+    S(0x1b, 0);
+    S(0x1c, 0);
+    S(0x1d, 0);
+    S(0x1e, 0x80); /* Finished good */
+    S(0x1f, 0x8); /* Bcache size */
+
+    for (i = 0x20; i < 0x80; i++)
+       S(i, 0);    /* For other cpus.  */
+
+    /* Array configuration */
+    for (i = 0x0; i < 0x4; i++) {
+       S(0x80 + 2 * i, arr[i] ? 0xf0 | i : 4);
+       if (arr[i]) {
+           int msb = ((arr[i] >> 12) & 0x0f) - 1;
+           if (msb < 2)
+               msb = 2;
+           S(0x80 + 2 * i + 1, 1 << (msb - 2));
+       }
+       else
+           S(0x80 + 2 * i + 1, 0);
+    }
+    for (i = 0x88; i < 0x90; i++)
+       S(i, 0);
+    S(0x90, 0xff); /* PSU */
+    S(0x91, 0x00); /* PSU */
+    S(0x92, 0x07); /* AC */
+    S(0x93, 0x30); /* CPU 0 */
+    S(0x94, 0x00); /* CPU 1 */
+    S(0x95, 0x00); /* CPU 2 */
+    S(0x96, 0x00); /* CPU 3 */
+    S(0x97, 0x22); /* Pci 0 */
+    S(0x98, 0x22); /* Pci 1 */
+    S(0x99, 0x22); /* Pci 2 */
+    S(0x9a, 0x90); /* fan speed */
+    S(0x9b, 0x90); /* fan speed */
+    S(0x9c, 0x90); /* fan speed */
+    S(0x9d, 0x90); /* fan speed */
+    S(0x9e, 0x90); /* fan speed */
+    S(0x9f, 0x90); /* fan speed */
+    for (i = 0xa0; i < 0xaa; i++)
+       S(i, 0); /* 680 logout frame */
+    S(0xaa, 0); /* Fan status */
+    S(0xab, 0); /* MMB0 dimm i2c */
+    S(0xac, 0); /* MMB1 dimm i2c */
+    S(0xad, 0); /* MMB2 dimm i2c */
+    S(0xae, 0); /* MMB3 dimm i2c */
+    S(0xaf, 0); /* MMB & cpu i2c */
+    S(0xb0, 0); /* cpb i2c */
+    S(0xb1, 0); /* csb i2c */
+    S(0xb2, 0); /* scsi and ps i2c */
+    for (i = 0xb3; i < 0xba; i++)
+       S(i, 0); /* usued */
+    S(0xba, 0xba); /* i2c done */
+    S(0xbb, 0x0); /* rmc flash ok */
+    S(0xbc, 0x0); /* rmc flash ok */
+
+    S(0xbd, 0x7); /* PS val */
+    S(0xbe, 0x0); /* SPC fault */
+    S(0xbf, 0x0); /* system fault */
+
+    for (i = 0xc0; i <= 0xd8; i++)
+       S(i, 0); /* usued */
+
+    S(0xd9, 2); /* RMC baud rate.  */
+    S(0xda, 0xaa); /* TIG loaded.  */
+    for (i = 0; i < 3; i++) {
+       S(0xdb + i * 9, 0xf4 + i); /* PS id */
+       S(0xdc + i * 9, 0x45);
+       S(0xdd + i * 9, 0x51);
+       S(0xde + i * 9, 0x37);
+       S(0xdf + i * 9, 0x90); /* Fan speed */
+       S(0xe0 + i * 9, 0xd6);
+       S(0xe1 + i * 9, 0x49);
+       S(0xe2 + i * 9, 0x4b);
+       S(0xe3 + i * 9, 0x0);
+    }
+    S(0xf6, 0); /* unused.  */
+    S(0xf7, 0); /* unused.  */
+    S(0xf8, 0); /* unused.  */
+    S(0xf9, 0); /* buffer size.  */
+    S(0xfa, 0); /* cmd addr.  */
+    S(0xfb, 0); /* cmd addr.  */
+    S(0xfc, 0); /* command status.  */
+    S(0xfd, 1); /* command id.  */
+    S(0xff, 1); /* command id.  */
+
+    for (i = 0x2900; i < 0x2a00; i++)
+       S(i, 0);    /* PCI backplane FRU.  */
+    for (i = 0x2a00; i < 0x2b00; i++)
+       S(i, 0);    /* motherboard FRU.  */
+    for (i = 0x2b00; i < 0x2c00; i++)
+       S(i, 0);    /* last correctable error.  */
+    for (i = 0x2c00; i < 0x2d00; i++)
+       S(i, 0);    /* last redundant error.  */
+    for (i = 0x2d00; i < 0x2e00; i++)
+       S(i, 0);    /* last system failure.  */
+
+    S(0x3000, 'V'); /* SROM version  */
+    S(0x3001, '2');
+    S(0x3002, '.');
+    S(0x3003, '2');
+    S(0x3004, '2');
+    S(0x3005, 'G');
+    S(0x3006, 0);
+    S(0x3007, 0);
+    S(0x3008, 0);
+    S(0x3009, 'V'); /* RMC rom version */
+    S(0x300a, 1);
+    S(0x300b, 0);
+    S(0x300c, 'V'); /* RMC flash version */
+    S(0x300d, 1);
+    S(0x300e, 0);
+    S(0x300f, 1); /* RMC revision field */
+    S(0x3010, 0);
+    for (i = 0x3011; i <= 0x30ff; i++)
+       S(i, 0);    /* unsued */
+
+    S(0x3400, 8); /* Size of Bcache */
+    S(0x3401, 8); /* Flash rom valid */
+    S(0x3402, 0); /* system errors */
+    for (i = 0x3403; i < 0x3410; i++)
+       S(i, 0);    /* Reserved.  */
+    for (i = 0x3410; i < 0x3420; i++)
+       S(i, 0);    /* Jump to address.  */
+    for (i = 0x3420; i <= 0x349f; i++) 
+       S(i, 0);    /* cpu 1-3 */
+    /* Array map.  */
+    for (i = 0; i < 0x20; i++) {
+       if (arr[i / 8])
+           S(0x34a0 + i, (((i >> 0) & 1) | (((i >> 1) & 1) << 3)
+                          | (((i >> 2) & 1) << 2) | (((i >> 3) & 1) << 1)
+                          | (((i >> 4) & 1) << 4)));
+       else
+           S(0x34a0 + i, 0x20);
+    }
+#undef S
+
+    tigbus_reset(s);
+    qemu_register_reset(&tigbus_reset, s);
+}
+
+struct srm_patch {
+  uint64_t addr;
+  uint32_t old_insn;
+  uint32_t new_insn;
+};
+
+static const struct srm_patch srm_patches[] = {
+  { 0x142a0, 0x259f11e2, 0x259f0000 }, /* ldah s3, 0x11e2 */
+  { 0x142a4, 0x218ca300, 0x218c0001 }, /* lda s3,-23808(s3) */
+  { 0x14260, 0x259f00e5, 0x259f0000 }, /* ldah s3,229 */
+  { 0x14264, 0x218ce1c0, 0x218c0001 }, /* lda s3,-7744(s3) */
+
+#if 1
+  /* Disable memory testing.  */
+  { 0x8bb88, 0xe4200004, 0xc3e00004 }, /* beq t0,0x8bb9c -- aa */
+  { 0x8bbc0, 0xe400001b, 0xc3e0001b }, /* beq v0,0x8bc30 -- 55 */
+  { 0x8bc48, 0xe4a0001b, 0xc3e0001b }, /* beq t4,0x8bcb8 -- 00 */
+#endif
+  { 0, 0, 0}
+};
+
+void alpha_21264_srm_write(CPUState *env)
+{
+    int fd;
+    int i;
+    uint32_t insn;
+    static const char rom_file[] = BIOS_FILENAME;
+
+    env->a21264.pal_reloc_val = 1;
+    env->a21264.pal_reloc_mask = 0;
+    env->a21264.pal_reloc_offset = 0;
+    
+    /* Apply patch list.  */
+    for (i = 0; srm_patches[i].addr; i++) {
+       insn = ldl_phys(srm_patches[i].addr);
+       if (insn != srm_patches[i].old_insn)
+           fprintf(stderr, "SRM patch mismatch at %"PRIx64": insn=%x\n",
+                   srm_patches[i].addr, insn);
+       else
+           stl_phys(srm_patches[i].addr, srm_patches[i].new_insn);
+    }
+
+    /* Save SRM.  */
+    fd = open(rom_file, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
+    if (fd < 0) {
+      save_error:
+       fprintf(stderr,"qemu: can't open %s\n", rom_file);
+       exit(1);
+    }
+    if (write(fd, phys_ram_base + ram_offset, SRM_SIZE) != SRM_SIZE)
+       goto save_error;
+    close(fd);
+    printf ("Bios written to %s\nExit\n", rom_file);
+    exit (0);
+}
+
+static void es40_rombuild_init(ram_addr_t ram_size, int vga_ram_size,
+                              const char *boot_device,
+                              const char *kernel_filename,
+                              const char *kernel_cmdline,
+                              const char *initrd_filename,
+                              const char *cpu_model)
+{
+    CPUState *env;
+    int bios_size;
+    int srm_ram_size;
+    int fd;
+    char buf[1024];
+
+    if (!cpu_model)
+        cpu_model = "21264";
+
+    printf("Initializing CPU\n");
+    env = cpu_init(cpu_model);
+    if (!env) {
+        fprintf(stderr, "Unable to find Alpha CPU definition\n");
+        exit(1);
+    }
+
+    /* BIOS load */
+    if (bios_name == NULL)
+        bios_name = ROMBUILD_BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
+    fd = open(buf, O_RDONLY | O_BINARY);
+    if (fd < 0) {
+      load_error:
+       fprintf(stderr,"qemu: can't open %s\n", buf);
+       exit(1);
+    }
+    bios_size = lseek(fd, 0, SEEK_END);
+    if (bios_size <= 0)
+       goto load_error;
+    bios_size -= LFU_HDR_SIZE;
+    srm_ram_size = TARGET_PAGE_ALIGN(bios_size);
+    ram_offset = qemu_ram_alloc(LFU_MEM_SIZE);
+    lseek(fd, LFU_HDR_SIZE, SEEK_SET);
+    if (read(fd, phys_ram_base + ram_offset + LFU_LOAD_ADDR, bios_size)
+       != bios_size)
+       goto load_error;
+    close(fd);
+    memcpy(phys_ram_base + ram_offset + LFU_LOAD_ADDR + LFU_RAM_OFFSET,
+          phys_ram_base + ram_offset + LFU_LOAD_ADDR,
+          bios_size);
+    printf ("SRM loaded\n");
+
+    cpu_register_physical_memory(0, LFU_MEM_SIZE, ram_offset);
+
+    env->pc = LFU_START_ADDR;
+    env->a21264.pal_reloc_val = LFU_LOAD_ADDR;
+    env->a21264.pal_reloc_mask = ~(uint64_t)0xfffffU;
+    env->a21264.pal_reloc_offset = LFU_RAM_OFFSET;
+}
+
+static void es40_cpu_reset(void *opaque)
+{
+    CPUState *env = opaque;
+
+    env->pc = 0x8000;
+}
+
+static void configure_mem_array(ram_addr_t ram_size, uint64_t *aar)
+{
+    int msb;
+    uint32_t base;
+    int i;
+    uint32_t size;
+
+    for (i = 0; i < 4; i++)
+       aar[i] = 0;
+
+    /* Configure cchip array address.  */
+    size = ram_size >> 24;
+    base = 0;
+    for (i = 0; i < 4; i++) {
+       msb = ffs(size);
+       if (msb == 0)
+           break;
+       msb--;
+       if (msb > 8)
+           msb = 8;
+       aar[i] = (((uint64_t)base) << 24)
+           | ((msb + 1) << 12) | (1 << 2) | (1 << 0);
+       base += 1 << msb;
+       size -= 1 << msb;
+       printf ("es40: arr[%d]=%016"PRIx64": %4uMB at %5uMB\n",
+               i, aar[i], 16 << msb, base << 4);
+    }
+}
+
+static void es40_init(ram_addr_t ram_size, int vga_ram_size,
+                     const char *boot_device,
+                     const char *kernel_filename, const char *kernel_cmdline,
+                     const char *initrd_filename, const char *cpu_model)
+{
+    CPUState *env;
+    char buf[1024];
+    qemu_irq *cchip_irqs;
+    qemu_irq tim_irq;
+    typhoon_t *typhoon;
+    ali1543_t *ali;
+    PCIBus *hose0;
+    uint64_t arr[4];
+
+    if (!cpu_model)
+        cpu_model = "21264";
+
+    env = cpu_init(cpu_model);
+    if (!env) {
+        fprintf(stderr, "Unable to find Alpha CPU definition\n");
+        exit(1);
+    }
+    qemu_register_reset(es40_cpu_reset, env);
+
+    /* Allocate RAM.  */
+    ram_offset = qemu_ram_alloc(ram_size);
+    cpu_register_physical_memory(0, ram_size, ram_offset);
+
+    /* SRM load */
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
+    if (load_image(buf, phys_ram_base + ram_offset) != SRM_SIZE) {
+       fprintf(stderr,"qemu: can't read %s - (or bad size)\n", buf);
+       exit(1);
+    }
+
+    configure_mem_array(ram_size, arr);
+    typhoon = typhoon_21272_init(arr, &cchip_irqs, &tim_irq, env);
+    tigbus_init(arr);
+
+    hose0 = typhoon_get_pci_bus(typhoon, 0);
+
+    ali = ali1543_init(hose0, PCI_DEVFN(7,0), cchip_irqs[55]);
+
+    typhoon_set_iack_handler(typhoon, 0,
+                            (int (*)(void *))pic_read_irq, isa_pic);
+
+    rtc_init_sqw(0x70, ali1543_get_irq(ali, 8), tim_irq, 2000);
+
+    es40_cpu_reset(env);
+}
+
+
+QEMUMachine es40_rombuild_machine = {
+    .name = "es40-rombuild",
+    .desc = "Alpha es40 rom builder",
+    .init = es40_rombuild_init,
+    .ram_require = 16 << 20
+};
+
+QEMUMachine es40_machine = {
+    .name = "es40",
+    .desc = "Alpha es40",
+    .init = es40_init,
+    .ram_require = 64 << 20
+};
diff --git a/target-alpha/machine.c b/target-alpha/machine.c
new file mode 100644
index 0000000..ed42af9
--- /dev/null
+++ b/target-alpha/machine.c
@@ -0,0 +1,22 @@
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "qemu-timer.h"
+
+#include "exec-all.h"
+
+void register_machines(void)
+{
+    qemu_register_machine(&es40_machine);
+    qemu_register_machine(&es40_rombuild_machine);
+}
+
+void cpu_save(QEMUFile *f, void *opaque)
+{
+    /* FIXME: todo  */
+    abort();
+}
+
+int cpu_load(QEMUFile *f, void *opaque, int version_id)
+{
+    return -EINVAL;
+}
-- 
1.6.2





reply via email to

[Prev in Thread] Current Thread [Next in Thread]