* Mark Nios II as orphan

* Many s390x emulation fixes
 * Disable flaky complete_in_standby blockjob unit test
 * White space cleanups in various files
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmQYVEoRHHRodXRoQHJl
 ZGhhdC5jb20ACgkQLtnXdP5wLbWu/A//QdVG7wS66lhdkPPu/GN+eDNaNsTzPPZd
 YwH0bpy2YoopInwa1ggZ1zPatmbSOVUcKjUfNYLcQzUBQnmeFtpuAF+4IGDhYfa+
 agkjWvmrCrIww4Wn+OLdLReW1+GtRlKZKu7xbYKkeLyqr9SHUD2lNUZ5RXj2t9Lw
 BXkPDXkMFqfVDzHtAxyXL7Z7yk3UTnZKBjDxiwE3tZ4S+N4r7m/TvNHiopI2bTVg
 JeDTxN40ylbOlBfOLC/qhlLUVnyBsDalIfKffIdLZ5Qn+FnKfZhkt9km4i7OL+ZX
 1wKnTh/J8OCYqHOyhJdZGT8QxZH79qDm12/nKXzIQkxtJoKuz6Fm5FY3ZJNrb+IJ
 ybxSpAFBJB/8sUjbzl8ZjGxbZecIyEBKT518+oBoqjNcy3n8/m2BhBFr6f6F4cJC
 kdTnRS0XYKGLbJLz0+VBARE7hoHNckYsup/DGscppyYKNA6rFXbq/MI3+oMGAnPw
 Ua/+gXU/hwq8TPg97A7O0hS4TKSKMtdZFEDmAGzkejVHvm/3BvcYrVoKDljnUAQV
 SaERp/Elefbt3EufkuZp77AwLU8RcEFscitEIACmLbmwm3aKpqS+R2u1EJ4ZcoFT
 dHUBkokXW1/i+FtNRmjEKV9z398cNYXGEDLPfMnFbknHwbS53pqeQqqlvUidltGk
 LWviyiqKihk=
 =tYCc
 -----END PGP SIGNATURE-----

Merge tag 'pull-request-2023-03-20' of https://gitlab.com/thuth/qemu into staging

* Mark Nios II as orphan
* Many s390x emulation fixes
* Disable flaky complete_in_standby blockjob unit test
* White space cleanups in various files

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmQYVEoRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbWu/A//QdVG7wS66lhdkPPu/GN+eDNaNsTzPPZd
# YwH0bpy2YoopInwa1ggZ1zPatmbSOVUcKjUfNYLcQzUBQnmeFtpuAF+4IGDhYfa+
# agkjWvmrCrIww4Wn+OLdLReW1+GtRlKZKu7xbYKkeLyqr9SHUD2lNUZ5RXj2t9Lw
# BXkPDXkMFqfVDzHtAxyXL7Z7yk3UTnZKBjDxiwE3tZ4S+N4r7m/TvNHiopI2bTVg
# JeDTxN40ylbOlBfOLC/qhlLUVnyBsDalIfKffIdLZ5Qn+FnKfZhkt9km4i7OL+ZX
# 1wKnTh/J8OCYqHOyhJdZGT8QxZH79qDm12/nKXzIQkxtJoKuz6Fm5FY3ZJNrb+IJ
# ybxSpAFBJB/8sUjbzl8ZjGxbZecIyEBKT518+oBoqjNcy3n8/m2BhBFr6f6F4cJC
# kdTnRS0XYKGLbJLz0+VBARE7hoHNckYsup/DGscppyYKNA6rFXbq/MI3+oMGAnPw
# Ua/+gXU/hwq8TPg97A7O0hS4TKSKMtdZFEDmAGzkejVHvm/3BvcYrVoKDljnUAQV
# SaERp/Elefbt3EufkuZp77AwLU8RcEFscitEIACmLbmwm3aKpqS+R2u1EJ4ZcoFT
# dHUBkokXW1/i+FtNRmjEKV9z398cNYXGEDLPfMnFbknHwbS53pqeQqqlvUidltGk
# LWviyiqKihk=
# =tYCc
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 20 Mar 2023 12:40:42 GMT
# gpg:                using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg:                issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* tag 'pull-request-2023-03-20' of https://gitlab.com/thuth/qemu: (24 commits)
  replace TABs with spaces
  qemu/osdep: Switch position of "extern" and "G_NORETURN"
  tests/unit/test-blockjob: Disable complete_in_standby test
  target/s390x/tcg/mem_helper: Remove bad assert() statement
  tests/tcg/s390x: Test unaligned accesses
  target/s390x: Update do_unaligned_access() comment
  target/s390x: Handle STGRL to non-aligned addresses
  target/s390x: Handle STRL to non-aligned addresses
  target/s390x: Handle CLRL and CLGFRL with non-aligned addresses
  target/s390x: Handle CGRL and CLGRL with non-aligned addresses
  target/s390x: Handle CRL and CGFRL with non-aligned addresses
  target/s390x: Handle LLGFRL from non-aligned addresses
  target/s390x: Handle LRL and LGFRL from non-aligned addresses
  target/s390x: Handle LGRL from non-aligned addresses
  target/s390x: Handle EXECUTE of odd addresses
  target/s390x: Handle branching to odd addresses
  tests/tcg/s390x: Add ex-relative-long.c
  target/s390x: Fix EXECUTE of relative long instructions
  tests/tcg/s390x: Add rxsbg.c
  target/s390x: Fix R[NOX]SBG with T=1
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2023-03-20 13:43:14 +00:00
commit 4c6f44644d
65 changed files with 2890 additions and 2078 deletions

View File

@ -257,9 +257,9 @@ F: docs/system/cpu-models-mips.rst.inc
F: tests/tcg/mips/
NiosII TCG CPUs
M: Chris Wulff <crwulff@gmail.com>
M: Marek Vasut <marex@denx.de>
S: Maintained
R: Chris Wulff <crwulff@gmail.com>
R: Marek Vasut <marex@denx.de>
S: Orphan
F: target/nios2/
F: hw/nios2/
F: disas/nios2.c

View File

@ -44,39 +44,39 @@
#define ESC 0x1B
#define BAUM_REQ_DisplayData 0x01
#define BAUM_REQ_GetVersionNumber 0x05
#define BAUM_REQ_GetKeys 0x08
#define BAUM_REQ_SetMode 0x12
#define BAUM_REQ_SetProtocol 0x15
#define BAUM_REQ_GetDeviceIdentity 0x84
#define BAUM_REQ_GetSerialNumber 0x8A
#define BAUM_REQ_DisplayData 0x01
#define BAUM_REQ_GetVersionNumber 0x05
#define BAUM_REQ_GetKeys 0x08
#define BAUM_REQ_SetMode 0x12
#define BAUM_REQ_SetProtocol 0x15
#define BAUM_REQ_GetDeviceIdentity 0x84
#define BAUM_REQ_GetSerialNumber 0x8A
#define BAUM_RSP_CellCount 0x01
#define BAUM_RSP_VersionNumber 0x05
#define BAUM_RSP_ModeSetting 0x11
#define BAUM_RSP_CommunicationChannel 0x16
#define BAUM_RSP_PowerdownSignal 0x17
#define BAUM_RSP_HorizontalSensors 0x20
#define BAUM_RSP_VerticalSensors 0x21
#define BAUM_RSP_RoutingKeys 0x22
#define BAUM_RSP_Switches 0x23
#define BAUM_RSP_TopKeys 0x24
#define BAUM_RSP_HorizontalSensor 0x25
#define BAUM_RSP_VerticalSensor 0x26
#define BAUM_RSP_RoutingKey 0x27
#define BAUM_RSP_FrontKeys6 0x28
#define BAUM_RSP_BackKeys6 0x29
#define BAUM_RSP_CommandKeys 0x2B
#define BAUM_RSP_FrontKeys10 0x2C
#define BAUM_RSP_BackKeys10 0x2D
#define BAUM_RSP_EntryKeys 0x33
#define BAUM_RSP_JoyStick 0x34
#define BAUM_RSP_ErrorCode 0x40
#define BAUM_RSP_InfoBlock 0x42
#define BAUM_RSP_DeviceIdentity 0x84
#define BAUM_RSP_SerialNumber 0x8A
#define BAUM_RSP_BluetoothName 0x8C
#define BAUM_RSP_CellCount 0x01
#define BAUM_RSP_VersionNumber 0x05
#define BAUM_RSP_ModeSetting 0x11
#define BAUM_RSP_CommunicationChannel 0x16
#define BAUM_RSP_PowerdownSignal 0x17
#define BAUM_RSP_HorizontalSensors 0x20
#define BAUM_RSP_VerticalSensors 0x21
#define BAUM_RSP_RoutingKeys 0x22
#define BAUM_RSP_Switches 0x23
#define BAUM_RSP_TopKeys 0x24
#define BAUM_RSP_HorizontalSensor 0x25
#define BAUM_RSP_VerticalSensor 0x26
#define BAUM_RSP_RoutingKey 0x27
#define BAUM_RSP_FrontKeys6 0x28
#define BAUM_RSP_BackKeys6 0x29
#define BAUM_RSP_CommandKeys 0x2B
#define BAUM_RSP_FrontKeys10 0x2C
#define BAUM_RSP_BackKeys10 0x2D
#define BAUM_RSP_EntryKeys 0x33
#define BAUM_RSP_JoyStick 0x34
#define BAUM_RSP_ErrorCode 0x40
#define BAUM_RSP_InfoBlock 0x42
#define BAUM_RSP_DeviceIdentity 0x84
#define BAUM_RSP_SerialNumber 0x8A
#define BAUM_RSP_BluetoothName 0x8C
#define BAUM_TL1 0x01
#define BAUM_TL2 0x02

View File

@ -57,22 +57,22 @@
/*
* These are the definitions for the Printer Status Register
*/
#define PARA_STS_BUSY 0x80 /* Busy complement */
#define PARA_STS_ACK 0x40 /* Acknowledge */
#define PARA_STS_PAPER 0x20 /* Out of paper */
#define PARA_STS_ONLINE 0x10 /* Online */
#define PARA_STS_ERROR 0x08 /* Error complement */
#define PARA_STS_TMOUT 0x01 /* EPP timeout */
#define PARA_STS_BUSY 0x80 /* Busy complement */
#define PARA_STS_ACK 0x40 /* Acknowledge */
#define PARA_STS_PAPER 0x20 /* Out of paper */
#define PARA_STS_ONLINE 0x10 /* Online */
#define PARA_STS_ERROR 0x08 /* Error complement */
#define PARA_STS_TMOUT 0x01 /* EPP timeout */
/*
* These are the definitions for the Printer Control Register
*/
#define PARA_CTR_DIR 0x20 /* Direction (1=read, 0=write) */
#define PARA_CTR_INTEN 0x10 /* IRQ Enable */
#define PARA_CTR_SELECT 0x08 /* Select In complement */
#define PARA_CTR_INIT 0x04 /* Initialize Printer complement */
#define PARA_CTR_AUTOLF 0x02 /* Auto linefeed complement */
#define PARA_CTR_STROBE 0x01 /* Strobe complement */
#define PARA_CTR_DIR 0x20 /* Direction (1=read, 0=write) */
#define PARA_CTR_INTEN 0x10 /* IRQ Enable */
#define PARA_CTR_SELECT 0x08 /* Select In complement */
#define PARA_CTR_INIT 0x04 /* Initialize Printer complement */
#define PARA_CTR_AUTOLF 0x02 /* Auto linefeed complement */
#define PARA_CTR_STROBE 0x01 /* Strobe complement */
#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)

View File

@ -38,20 +38,20 @@
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
#define UART_IIR_CTI 0x0C /* Character Timeout Indication */
#define UART_IIR_FENF 0x80 /* Fifo enabled, but not functionning */
@ -60,33 +60,33 @@
/*
* These are the definitions for the Modem Control Register
*/
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
#define UART_MCR_OUT2 0x08 /* Out2 complement */
#define UART_MCR_OUT1 0x04 /* Out1 complement */
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR complement */
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
#define UART_MCR_OUT2 0x08 /* Out2 complement */
#define UART_MCR_OUT1 0x04 /* Out1 complement */
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR complement */
/*
* These are the definitions for the Modem Status Register
*/
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
#define UART_MSR_RI 0x40 /* Ring Indicator */
#define UART_MSR_DSR 0x20 /* Data Set Ready */
#define UART_MSR_CTS 0x10 /* Clear to Send */
#define UART_MSR_DDCD 0x08 /* Delta DCD */
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
#define UART_MSR_DDSR 0x02 /* Delta DSR */
#define UART_MSR_DCTS 0x01 /* Delta CTS */
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
#define UART_MSR_RI 0x40 /* Ring Indicator */
#define UART_MSR_DSR 0x20 /* Data Set Ready */
#define UART_MSR_CTS 0x10 /* Clear to Send */
#define UART_MSR_DDCD 0x08 /* Delta DCD */
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
#define UART_MSR_DDSR 0x02 /* Delta DSR */
#define UART_MSR_DCTS 0x01 /* Delta CTS */
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
#define UART_LSR_FE 0x08 /* Frame error indicator */
#define UART_LSR_PE 0x04 /* Parity error indicator */
#define UART_LSR_OE 0x02 /* Overrun error indicator */
#define UART_LSR_DR 0x01 /* Receiver data ready */
#define UART_LSR_INT_ANY 0x1E /* Any of the lsr-interrupt-triggering status bits */
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
#define UART_LSR_FE 0x08 /* Frame error indicator */
#define UART_LSR_PE 0x04 /* Parity error indicator */
#define UART_LSR_OE 0x02 /* Overrun error indicator */
#define UART_LSR_DR 0x01 /* Receiver data ready */
#define UART_LSR_INT_ANY 0x1E /* Any of the lsr-interrupt-triggering status bits */
/* Interrupt trigger levels. The byte-counts are for 16550A - in newer UARTs the byte-count for each ITL is higher. */

View File

@ -35,7 +35,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
@ -210,8 +210,8 @@ static void bswap_ahdr(struct exec *e)
#define ZMAGIC 0413
#define QMAGIC 0314
#define _N_HDROFF(x) (1024 - sizeof (struct exec))
#define N_TXTOFF(x) \
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
#define N_TXTOFF(x) \
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
(N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
#define N_TXTADDR(x, target_page_size) (N_MAGIC(x) == QMAGIC ? target_page_size : 0)
#define _N_SEGMENT_ROUND(x, target_page_size) (((x) + target_page_size - 1) & ~(target_page_size - 1))
@ -300,10 +300,10 @@ static void *load_at(int fd, off_t offset, size_t size)
#define ELF_CLASS ELFCLASS32
#include "elf.h"
#define SZ 32
#define SZ 32
#define elf_word uint32_t
#define elf_sword int32_t
#define bswapSZs bswap32s
#define elf_sword int32_t
#define bswapSZs bswap32s
#include "hw/elf_ops.h"
#undef elfhdr
@ -316,16 +316,16 @@ static void *load_at(int fd, off_t offset, size_t size)
#undef elf_sword
#undef bswapSZs
#undef SZ
#define elfhdr elf64_hdr
#define elf_phdr elf64_phdr
#define elf_note elf64_note
#define elf_shdr elf64_shdr
#define elf_sym elf64_sym
#define elfhdr elf64_hdr
#define elf_phdr elf64_phdr
#define elf_note elf64_note
#define elf_shdr elf64_shdr
#define elf_sym elf64_sym
#define elf_rela elf64_rela
#define elf_word uint64_t
#define elf_sword int64_t
#define bswapSZs bswap64s
#define SZ 64
#define elf_sword int64_t
#define bswapSZs bswap64s
#define SZ 64
#include "hw/elf_ops.h"
const char *load_elf_strerror(ssize_t error)
@ -527,7 +527,7 @@ static void bswap_uboot_header(uboot_image_header_t *hdr)
}
#define ZALLOC_ALIGNMENT 16
#define ZALLOC_ALIGNMENT 16
static void *zalloc(void *x, unsigned items, unsigned size)
{
@ -547,13 +547,13 @@ static void zfree(void *x, void *addr)
}
#define HEAD_CRC 2
#define EXTRA_FIELD 4
#define ORIG_NAME 8
#define COMMENT 0x10
#define RESERVED 0xe0
#define HEAD_CRC 2
#define EXTRA_FIELD 4
#define ORIG_NAME 8
#define COMMENT 0x10
#define RESERVED 0xe0
#define DEFLATED 8
#define DEFLATED 8
ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, size_t srclen)
{

View File

@ -160,38 +160,38 @@ enum {
enum dma_ch_state
{
RST = 1,
STOPPED = 2,
RUNNING = 4
RST = 1,
STOPPED = 2,
RUNNING = 4
};
struct fs_dma_channel
{
qemu_irq irq;
struct etraxfs_dma_client *client;
qemu_irq irq;
struct etraxfs_dma_client *client;
/* Internal status. */
int stream_cmd_src;
enum dma_ch_state state;
/* Internal status. */
int stream_cmd_src;
enum dma_ch_state state;
unsigned int input : 1;
unsigned int eol : 1;
unsigned int input : 1;
unsigned int eol : 1;
struct dma_descr_group current_g;
struct dma_descr_context current_c;
struct dma_descr_data current_d;
struct dma_descr_group current_g;
struct dma_descr_context current_c;
struct dma_descr_data current_d;
/* Control registers. */
uint32_t regs[DMA_REG_MAX];
/* Control registers. */
uint32_t regs[DMA_REG_MAX];
};
struct fs_dma_ctrl
{
MemoryRegion mmio;
int nr_channels;
struct fs_dma_channel *channels;
MemoryRegion mmio;
int nr_channels;
struct fs_dma_channel *channels;
QEMUBH *bh;
QEMUBH *bh;
};
static void DMA_run(void *opaque);
@ -199,72 +199,72 @@ static int channel_out_run(struct fs_dma_ctrl *ctrl, int c);
static inline uint32_t channel_reg(struct fs_dma_ctrl *ctrl, int c, int reg)
{
return ctrl->channels[c].regs[reg];
return ctrl->channels[c].regs[reg];
}
static inline int channel_stopped(struct fs_dma_ctrl *ctrl, int c)
{
return channel_reg(ctrl, c, RW_CFG) & 2;
return channel_reg(ctrl, c, RW_CFG) & 2;
}
static inline int channel_en(struct fs_dma_ctrl *ctrl, int c)
{
return (channel_reg(ctrl, c, RW_CFG) & 1)
&& ctrl->channels[c].client;
return (channel_reg(ctrl, c, RW_CFG) & 1)
&& ctrl->channels[c].client;
}
static inline int fs_channel(hwaddr addr)
{
/* Every channel has a 0x2000 ctrl register map. */
return addr >> 13;
/* Every channel has a 0x2000 ctrl register map. */
return addr >> 13;
}
#ifdef USE_THIS_DEAD_CODE
static void channel_load_g(struct fs_dma_ctrl *ctrl, int c)
{
hwaddr addr = channel_reg(ctrl, c, RW_GROUP);
hwaddr addr = channel_reg(ctrl, c, RW_GROUP);
/* Load and decode. FIXME: handle endianness. */
/* Load and decode. FIXME: handle endianness. */
cpu_physical_memory_read(addr, &ctrl->channels[c].current_g,
sizeof(ctrl->channels[c].current_g));
}
static void dump_c(int ch, struct dma_descr_context *c)
{
printf("%s ch=%d\n", __func__, ch);
printf("next=%x\n", c->next);
printf("saved_data=%x\n", c->saved_data);
printf("saved_data_buf=%x\n", c->saved_data_buf);
printf("eol=%x\n", (uint32_t) c->eol);
printf("%s ch=%d\n", __func__, ch);
printf("next=%x\n", c->next);
printf("saved_data=%x\n", c->saved_data);
printf("saved_data_buf=%x\n", c->saved_data_buf);
printf("eol=%x\n", (uint32_t) c->eol);
}
static void dump_d(int ch, struct dma_descr_data *d)
{
printf("%s ch=%d\n", __func__, ch);
printf("next=%x\n", d->next);
printf("buf=%x\n", d->buf);
printf("after=%x\n", d->after);
printf("intr=%x\n", (uint32_t) d->intr);
printf("out_eop=%x\n", (uint32_t) d->out_eop);
printf("in_eop=%x\n", (uint32_t) d->in_eop);
printf("eol=%x\n", (uint32_t) d->eol);
printf("%s ch=%d\n", __func__, ch);
printf("next=%x\n", d->next);
printf("buf=%x\n", d->buf);
printf("after=%x\n", d->after);
printf("intr=%x\n", (uint32_t) d->intr);
printf("out_eop=%x\n", (uint32_t) d->out_eop);
printf("in_eop=%x\n", (uint32_t) d->in_eop);
printf("eol=%x\n", (uint32_t) d->eol);
}
#endif
static void channel_load_c(struct fs_dma_ctrl *ctrl, int c)
{
hwaddr addr = channel_reg(ctrl, c, RW_GROUP_DOWN);
hwaddr addr = channel_reg(ctrl, c, RW_GROUP_DOWN);
/* Load and decode. FIXME: handle endianness. */
/* Load and decode. FIXME: handle endianness. */
cpu_physical_memory_read(addr, &ctrl->channels[c].current_c,
sizeof(ctrl->channels[c].current_c));
D(dump_c(c, &ctrl->channels[c].current_c));
/* I guess this should update the current pos. */
ctrl->channels[c].regs[RW_SAVED_DATA] =
(uint32_t)(unsigned long)ctrl->channels[c].current_c.saved_data;
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
(uint32_t)(unsigned long)ctrl->channels[c].current_c.saved_data_buf;
D(dump_c(c, &ctrl->channels[c].current_c));
/* I guess this should update the current pos. */
ctrl->channels[c].regs[RW_SAVED_DATA] =
(uint32_t)(unsigned long)ctrl->channels[c].current_c.saved_data;
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
(uint32_t)(unsigned long)ctrl->channels[c].current_c.saved_data_buf;
}
static void channel_load_d(struct fs_dma_ctrl *ctrl, int c)
@ -303,273 +303,273 @@ static void channel_store_d(struct fs_dma_ctrl *ctrl, int c)
static inline void channel_stop(struct fs_dma_ctrl *ctrl, int c)
{
/* FIXME: */
/* FIXME: */
}
static inline void channel_start(struct fs_dma_ctrl *ctrl, int c)
{
if (ctrl->channels[c].client)
{
ctrl->channels[c].eol = 0;
ctrl->channels[c].state = RUNNING;
if (!ctrl->channels[c].input)
channel_out_run(ctrl, c);
} else
printf("WARNING: starting DMA ch %d with no client\n", c);
if (ctrl->channels[c].client)
{
ctrl->channels[c].eol = 0;
ctrl->channels[c].state = RUNNING;
if (!ctrl->channels[c].input)
channel_out_run(ctrl, c);
} else
printf("WARNING: starting DMA ch %d with no client\n", c);
qemu_bh_schedule_idle(ctrl->bh);
qemu_bh_schedule_idle(ctrl->bh);
}
static void channel_continue(struct fs_dma_ctrl *ctrl, int c)
{
if (!channel_en(ctrl, c)
|| channel_stopped(ctrl, c)
|| ctrl->channels[c].state != RUNNING
/* Only reload the current data descriptor if it has eol set. */
|| !ctrl->channels[c].current_d.eol) {
D(printf("continue failed ch=%d state=%d stopped=%d en=%d eol=%d\n",
c, ctrl->channels[c].state,
channel_stopped(ctrl, c),
channel_en(ctrl,c),
ctrl->channels[c].eol));
D(dump_d(c, &ctrl->channels[c].current_d));
return;
}
if (!channel_en(ctrl, c)
|| channel_stopped(ctrl, c)
|| ctrl->channels[c].state != RUNNING
/* Only reload the current data descriptor if it has eol set. */
|| !ctrl->channels[c].current_d.eol) {
D(printf("continue failed ch=%d state=%d stopped=%d en=%d eol=%d\n",
c, ctrl->channels[c].state,
channel_stopped(ctrl, c),
channel_en(ctrl,c),
ctrl->channels[c].eol));
D(dump_d(c, &ctrl->channels[c].current_d));
return;
}
/* Reload the current descriptor. */
channel_load_d(ctrl, c);
/* Reload the current descriptor. */
channel_load_d(ctrl, c);
/* If the current descriptor cleared the eol flag and we had already
reached eol state, do the continue. */
if (!ctrl->channels[c].current_d.eol && ctrl->channels[c].eol) {
D(printf("continue %d ok %x\n", c,
ctrl->channels[c].current_d.next));
ctrl->channels[c].regs[RW_SAVED_DATA] =
(uint32_t)(unsigned long)ctrl->channels[c].current_d.next;
channel_load_d(ctrl, c);
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
(uint32_t)(unsigned long)ctrl->channels[c].current_d.buf;
/* If the current descriptor cleared the eol flag and we had already
reached eol state, do the continue. */
if (!ctrl->channels[c].current_d.eol && ctrl->channels[c].eol) {
D(printf("continue %d ok %x\n", c,
ctrl->channels[c].current_d.next));
ctrl->channels[c].regs[RW_SAVED_DATA] =
(uint32_t)(unsigned long)ctrl->channels[c].current_d.next;
channel_load_d(ctrl, c);
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
(uint32_t)(unsigned long)ctrl->channels[c].current_d.buf;
channel_start(ctrl, c);
}
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
(uint32_t)(unsigned long)ctrl->channels[c].current_d.buf;
channel_start(ctrl, c);
}
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
(uint32_t)(unsigned long)ctrl->channels[c].current_d.buf;
}
static void channel_stream_cmd(struct fs_dma_ctrl *ctrl, int c, uint32_t v)
{
unsigned int cmd = v & ((1 << 10) - 1);
unsigned int cmd = v & ((1 << 10) - 1);
D(printf("%s ch=%d cmd=%x\n",
__func__, c, cmd));
if (cmd & regk_dma_load_d) {
channel_load_d(ctrl, c);
if (cmd & regk_dma_burst)
channel_start(ctrl, c);
}
D(printf("%s ch=%d cmd=%x\n",
__func__, c, cmd));
if (cmd & regk_dma_load_d) {
channel_load_d(ctrl, c);
if (cmd & regk_dma_burst)
channel_start(ctrl, c);
}
if (cmd & regk_dma_load_c) {
channel_load_c(ctrl, c);
}
if (cmd & regk_dma_load_c) {
channel_load_c(ctrl, c);
}
}
static void channel_update_irq(struct fs_dma_ctrl *ctrl, int c)
{
D(printf("%s %d\n", __func__, c));
ctrl->channels[c].regs[R_INTR] &=
~(ctrl->channels[c].regs[RW_ACK_INTR]);
D(printf("%s %d\n", __func__, c));
ctrl->channels[c].regs[R_INTR] &=
~(ctrl->channels[c].regs[RW_ACK_INTR]);
ctrl->channels[c].regs[R_MASKED_INTR] =
ctrl->channels[c].regs[R_INTR]
& ctrl->channels[c].regs[RW_INTR_MASK];
ctrl->channels[c].regs[R_MASKED_INTR] =
ctrl->channels[c].regs[R_INTR]
& ctrl->channels[c].regs[RW_INTR_MASK];
D(printf("%s: chan=%d masked_intr=%x\n", __func__,
c,
ctrl->channels[c].regs[R_MASKED_INTR]));
D(printf("%s: chan=%d masked_intr=%x\n", __func__,
c,
ctrl->channels[c].regs[R_MASKED_INTR]));
qemu_set_irq(ctrl->channels[c].irq,
!!ctrl->channels[c].regs[R_MASKED_INTR]);
qemu_set_irq(ctrl->channels[c].irq,
!!ctrl->channels[c].regs[R_MASKED_INTR]);
}
static int channel_out_run(struct fs_dma_ctrl *ctrl, int c)
{
uint32_t len;
uint32_t saved_data_buf;
unsigned char buf[2 * 1024];
uint32_t len;
uint32_t saved_data_buf;
unsigned char buf[2 * 1024];
struct dma_context_metadata meta;
bool send_context = true;
struct dma_context_metadata meta;
bool send_context = true;
if (ctrl->channels[c].eol)
return 0;
if (ctrl->channels[c].eol)
return 0;
do {
bool out_eop;
D(printf("ch=%d buf=%x after=%x\n",
c,
(uint32_t)ctrl->channels[c].current_d.buf,
(uint32_t)ctrl->channels[c].current_d.after));
do {
bool out_eop;
D(printf("ch=%d buf=%x after=%x\n",
c,
(uint32_t)ctrl->channels[c].current_d.buf,
(uint32_t)ctrl->channels[c].current_d.after));
if (send_context) {
if (ctrl->channels[c].client->client.metadata_push) {
meta.metadata = ctrl->channels[c].current_d.md;
ctrl->channels[c].client->client.metadata_push(
ctrl->channels[c].client->client.opaque,
&meta);
}
send_context = false;
}
if (send_context) {
if (ctrl->channels[c].client->client.metadata_push) {
meta.metadata = ctrl->channels[c].current_d.md;
ctrl->channels[c].client->client.metadata_push(
ctrl->channels[c].client->client.opaque,
&meta);
}
send_context = false;
}
channel_load_d(ctrl, c);
saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
len = (uint32_t)(unsigned long)
ctrl->channels[c].current_d.after;
len -= saved_data_buf;
channel_load_d(ctrl, c);
saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
len = (uint32_t)(unsigned long)
ctrl->channels[c].current_d.after;
len -= saved_data_buf;
if (len > sizeof buf)
len = sizeof buf;
cpu_physical_memory_read (saved_data_buf, buf, len);
if (len > sizeof buf)
len = sizeof buf;
cpu_physical_memory_read (saved_data_buf, buf, len);
out_eop = ((saved_data_buf + len) ==
ctrl->channels[c].current_d.after) &&
ctrl->channels[c].current_d.out_eop;
out_eop = ((saved_data_buf + len) ==
ctrl->channels[c].current_d.after) &&
ctrl->channels[c].current_d.out_eop;
D(printf("channel %d pushes %x %u bytes eop=%u\n", c,
saved_data_buf, len, out_eop));
D(printf("channel %d pushes %x %u bytes eop=%u\n", c,
saved_data_buf, len, out_eop));
if (ctrl->channels[c].client->client.push) {
if (len > 0) {
ctrl->channels[c].client->client.push(
ctrl->channels[c].client->client.opaque,
buf, len, out_eop);
}
} else {
printf("WARNING: DMA ch%d dataloss,"
" no attached client.\n", c);
}
if (ctrl->channels[c].client->client.push) {
if (len > 0) {
ctrl->channels[c].client->client.push(
ctrl->channels[c].client->client.opaque,
buf, len, out_eop);
}
} else {
printf("WARNING: DMA ch%d dataloss,"
" no attached client.\n", c);
}
saved_data_buf += len;
saved_data_buf += len;
if (saved_data_buf == (uint32_t)(unsigned long)
ctrl->channels[c].current_d.after) {
/* Done. Step to next. */
if (ctrl->channels[c].current_d.out_eop) {
send_context = true;
}
if (ctrl->channels[c].current_d.intr) {
/* data intr. */
D(printf("signal intr %d eol=%d\n",
len, ctrl->channels[c].current_d.eol));
ctrl->channels[c].regs[R_INTR] |= (1 << 2);
channel_update_irq(ctrl, c);
}
channel_store_d(ctrl, c);
if (ctrl->channels[c].current_d.eol) {
D(printf("channel %d EOL\n", c));
ctrl->channels[c].eol = 1;
if (saved_data_buf == (uint32_t)(unsigned long)
ctrl->channels[c].current_d.after) {
/* Done. Step to next. */
if (ctrl->channels[c].current_d.out_eop) {
send_context = true;
}
if (ctrl->channels[c].current_d.intr) {
/* data intr. */
D(printf("signal intr %d eol=%d\n",
len, ctrl->channels[c].current_d.eol));
ctrl->channels[c].regs[R_INTR] |= (1 << 2);
channel_update_irq(ctrl, c);
}
channel_store_d(ctrl, c);
if (ctrl->channels[c].current_d.eol) {
D(printf("channel %d EOL\n", c));
ctrl->channels[c].eol = 1;
/* Mark the context as disabled. */
ctrl->channels[c].current_c.dis = 1;
channel_store_c(ctrl, c);
/* Mark the context as disabled. */
ctrl->channels[c].current_c.dis = 1;
channel_store_c(ctrl, c);
channel_stop(ctrl, c);
} else {
ctrl->channels[c].regs[RW_SAVED_DATA] =
(uint32_t)(unsigned long)ctrl->
channels[c].current_d.next;
/* Load new descriptor. */
channel_load_d(ctrl, c);
saved_data_buf = (uint32_t)(unsigned long)
ctrl->channels[c].current_d.buf;
}
channel_stop(ctrl, c);
} else {
ctrl->channels[c].regs[RW_SAVED_DATA] =
(uint32_t)(unsigned long)ctrl->
channels[c].current_d.next;
/* Load new descriptor. */
channel_load_d(ctrl, c);
saved_data_buf = (uint32_t)(unsigned long)
ctrl->channels[c].current_d.buf;
}
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
saved_data_buf;
D(dump_d(c, &ctrl->channels[c].current_d));
}
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
} while (!ctrl->channels[c].eol);
return 1;
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
saved_data_buf;
D(dump_d(c, &ctrl->channels[c].current_d));
}
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
} while (!ctrl->channels[c].eol);
return 1;
}
static int channel_in_process(struct fs_dma_ctrl *ctrl, int c,
unsigned char *buf, int buflen, int eop)
unsigned char *buf, int buflen, int eop)
{
uint32_t len;
uint32_t saved_data_buf;
uint32_t len;
uint32_t saved_data_buf;
if (ctrl->channels[c].eol == 1)
return 0;
if (ctrl->channels[c].eol == 1)
return 0;
channel_load_d(ctrl, c);
saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
len = (uint32_t)(unsigned long)ctrl->channels[c].current_d.after;
len -= saved_data_buf;
if (len > buflen)
len = buflen;
channel_load_d(ctrl, c);
saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
len = (uint32_t)(unsigned long)ctrl->channels[c].current_d.after;
len -= saved_data_buf;
cpu_physical_memory_write (saved_data_buf, buf, len);
saved_data_buf += len;
if (len > buflen)
len = buflen;
if (saved_data_buf ==
(uint32_t)(unsigned long)ctrl->channels[c].current_d.after
|| eop) {
uint32_t r_intr = ctrl->channels[c].regs[R_INTR];
cpu_physical_memory_write (saved_data_buf, buf, len);
saved_data_buf += len;
D(printf("in dscr end len=%d\n",
ctrl->channels[c].current_d.after
- ctrl->channels[c].current_d.buf));
ctrl->channels[c].current_d.after = saved_data_buf;
if (saved_data_buf ==
(uint32_t)(unsigned long)ctrl->channels[c].current_d.after
|| eop) {
uint32_t r_intr = ctrl->channels[c].regs[R_INTR];
/* Done. Step to next. */
if (ctrl->channels[c].current_d.intr) {
/* TODO: signal eop to the client. */
/* data intr. */
ctrl->channels[c].regs[R_INTR] |= 3;
}
if (eop) {
ctrl->channels[c].current_d.in_eop = 1;
ctrl->channels[c].regs[R_INTR] |= 8;
}
if (r_intr != ctrl->channels[c].regs[R_INTR])
channel_update_irq(ctrl, c);
D(printf("in dscr end len=%d\n",
ctrl->channels[c].current_d.after
- ctrl->channels[c].current_d.buf));
ctrl->channels[c].current_d.after = saved_data_buf;
channel_store_d(ctrl, c);
D(dump_d(c, &ctrl->channels[c].current_d));
/* Done. Step to next. */
if (ctrl->channels[c].current_d.intr) {
/* TODO: signal eop to the client. */
/* data intr. */
ctrl->channels[c].regs[R_INTR] |= 3;
}
if (eop) {
ctrl->channels[c].current_d.in_eop = 1;
ctrl->channels[c].regs[R_INTR] |= 8;
}
if (r_intr != ctrl->channels[c].regs[R_INTR])
channel_update_irq(ctrl, c);
if (ctrl->channels[c].current_d.eol) {
D(printf("channel %d EOL\n", c));
ctrl->channels[c].eol = 1;
channel_store_d(ctrl, c);
D(dump_d(c, &ctrl->channels[c].current_d));
/* Mark the context as disabled. */
ctrl->channels[c].current_c.dis = 1;
channel_store_c(ctrl, c);
if (ctrl->channels[c].current_d.eol) {
D(printf("channel %d EOL\n", c));
ctrl->channels[c].eol = 1;
channel_stop(ctrl, c);
} else {
ctrl->channels[c].regs[RW_SAVED_DATA] =
(uint32_t)(unsigned long)ctrl->
channels[c].current_d.next;
/* Load new descriptor. */
channel_load_d(ctrl, c);
saved_data_buf = (uint32_t)(unsigned long)
ctrl->channels[c].current_d.buf;
}
}
/* Mark the context as disabled. */
ctrl->channels[c].current_c.dis = 1;
channel_store_c(ctrl, c);
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
return len;
channel_stop(ctrl, c);
} else {
ctrl->channels[c].regs[RW_SAVED_DATA] =
(uint32_t)(unsigned long)ctrl->
channels[c].current_d.next;
/* Load new descriptor. */
channel_load_d(ctrl, c);
saved_data_buf = (uint32_t)(unsigned long)
ctrl->channels[c].current_d.buf;
}
}
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
return len;
}
static inline int channel_in_run(struct fs_dma_ctrl *ctrl, int c)
{
if (ctrl->channels[c].client->client.pull) {
ctrl->channels[c].client->client.pull(
ctrl->channels[c].client->client.opaque);
return 1;
} else
return 0;
if (ctrl->channels[c].client->client.pull) {
ctrl->channels[c].client->client.pull(
ctrl->channels[c].client->client.opaque);
return 1;
} else
return 0;
}
static uint32_t dma_rinvalid (void *opaque, hwaddr addr)
@ -581,33 +581,33 @@ static uint32_t dma_rinvalid (void *opaque, hwaddr addr)
static uint64_t
dma_read(void *opaque, hwaddr addr, unsigned int size)
{
struct fs_dma_ctrl *ctrl = opaque;
int c;
uint32_t r = 0;
struct fs_dma_ctrl *ctrl = opaque;
int c;
uint32_t r = 0;
if (size != 4) {
dma_rinvalid(opaque, addr);
}
if (size != 4) {
dma_rinvalid(opaque, addr);
}
/* Make addr relative to this channel and bounded to nr regs. */
c = fs_channel(addr);
addr &= 0xff;
addr >>= 2;
switch (addr)
{
case RW_STAT:
r = ctrl->channels[c].state & 7;
r |= ctrl->channels[c].eol << 5;
r |= ctrl->channels[c].stream_cmd_src << 8;
break;
/* Make addr relative to this channel and bounded to nr regs. */
c = fs_channel(addr);
addr &= 0xff;
addr >>= 2;
switch (addr)
{
case RW_STAT:
r = ctrl->channels[c].state & 7;
r |= ctrl->channels[c].eol << 5;
r |= ctrl->channels[c].stream_cmd_src << 8;
break;
default:
r = ctrl->channels[c].regs[addr];
D(printf("%s c=%d addr=" HWADDR_FMT_plx "\n",
__func__, c, addr));
break;
}
return r;
default:
r = ctrl->channels[c].regs[addr];
D(printf("%s c=%d addr=" HWADDR_FMT_plx "\n",
__func__, c, addr));
break;
}
return r;
}
static void
@ -619,133 +619,133 @@ dma_winvalid (void *opaque, hwaddr addr, uint32_t value)
static void
dma_update_state(struct fs_dma_ctrl *ctrl, int c)
{
if (ctrl->channels[c].regs[RW_CFG] & 2)
ctrl->channels[c].state = STOPPED;
if (!(ctrl->channels[c].regs[RW_CFG] & 1))
ctrl->channels[c].state = RST;
if (ctrl->channels[c].regs[RW_CFG] & 2)
ctrl->channels[c].state = STOPPED;
if (!(ctrl->channels[c].regs[RW_CFG] & 1))
ctrl->channels[c].state = RST;
}
static void
dma_write(void *opaque, hwaddr addr,
uint64_t val64, unsigned int size)
uint64_t val64, unsigned int size)
{
struct fs_dma_ctrl *ctrl = opaque;
uint32_t value = val64;
int c;
struct fs_dma_ctrl *ctrl = opaque;
uint32_t value = val64;
int c;
if (size != 4) {
dma_winvalid(opaque, addr, value);
}
if (size != 4) {
dma_winvalid(opaque, addr, value);
}
/* Make addr relative to this channel and bounded to nr regs. */
c = fs_channel(addr);
addr &= 0xff;
addr >>= 2;
switch (addr)
{
case RW_DATA:
ctrl->channels[c].regs[addr] = value;
break;
c = fs_channel(addr);
addr &= 0xff;
addr >>= 2;
switch (addr)
{
case RW_DATA:
ctrl->channels[c].regs[addr] = value;
break;
case RW_CFG:
ctrl->channels[c].regs[addr] = value;
dma_update_state(ctrl, c);
break;
case RW_CMD:
/* continue. */
if (value & ~1)
printf("Invalid store to ch=%d RW_CMD %x\n",
c, value);
ctrl->channels[c].regs[addr] = value;
channel_continue(ctrl, c);
break;
case RW_CFG:
ctrl->channels[c].regs[addr] = value;
dma_update_state(ctrl, c);
break;
case RW_CMD:
/* continue. */
if (value & ~1)
printf("Invalid store to ch=%d RW_CMD %x\n",
c, value);
ctrl->channels[c].regs[addr] = value;
channel_continue(ctrl, c);
break;
case RW_SAVED_DATA:
case RW_SAVED_DATA_BUF:
case RW_GROUP:
case RW_GROUP_DOWN:
ctrl->channels[c].regs[addr] = value;
break;
case RW_SAVED_DATA:
case RW_SAVED_DATA_BUF:
case RW_GROUP:
case RW_GROUP_DOWN:
ctrl->channels[c].regs[addr] = value;
break;
case RW_ACK_INTR:
case RW_INTR_MASK:
ctrl->channels[c].regs[addr] = value;
channel_update_irq(ctrl, c);
if (addr == RW_ACK_INTR)
ctrl->channels[c].regs[RW_ACK_INTR] = 0;
break;
case RW_ACK_INTR:
case RW_INTR_MASK:
ctrl->channels[c].regs[addr] = value;
channel_update_irq(ctrl, c);
if (addr == RW_ACK_INTR)
ctrl->channels[c].regs[RW_ACK_INTR] = 0;
break;
case RW_STREAM_CMD:
if (value & ~1023)
printf("Invalid store to ch=%d "
"RW_STREAMCMD %x\n",
c, value);
ctrl->channels[c].regs[addr] = value;
D(printf("stream_cmd ch=%d\n", c));
channel_stream_cmd(ctrl, c, value);
break;
case RW_STREAM_CMD:
if (value & ~1023)
printf("Invalid store to ch=%d "
"RW_STREAMCMD %x\n",
c, value);
ctrl->channels[c].regs[addr] = value;
D(printf("stream_cmd ch=%d\n", c));
channel_stream_cmd(ctrl, c, value);
break;
default:
D(printf("%s c=%d " HWADDR_FMT_plx "\n",
__func__, c, addr));
break;
}
default:
D(printf("%s c=%d " HWADDR_FMT_plx "\n",
__func__, c, addr));
break;
}
}
static const MemoryRegionOps dma_ops = {
.read = dma_read,
.write = dma_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 4
}
.read = dma_read,
.write = dma_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 4
}
};
static int etraxfs_dmac_run(void *opaque)
{
struct fs_dma_ctrl *ctrl = opaque;
int i;
int p = 0;
struct fs_dma_ctrl *ctrl = opaque;
int i;
int p = 0;
for (i = 0;
i < ctrl->nr_channels;
i++)
{
if (ctrl->channels[i].state == RUNNING)
{
if (ctrl->channels[i].input) {
p += channel_in_run(ctrl, i);
} else {
p += channel_out_run(ctrl, i);
}
}
}
return p;
for (i = 0;
i < ctrl->nr_channels;
i++)
{
if (ctrl->channels[i].state == RUNNING)
{
if (ctrl->channels[i].input) {
p += channel_in_run(ctrl, i);
} else {
p += channel_out_run(ctrl, i);
}
}
}
return p;
}
int etraxfs_dmac_input(struct etraxfs_dma_client *client,
void *buf, int len, int eop)
void *buf, int len, int eop)
{
return channel_in_process(client->ctrl, client->channel,
buf, len, eop);
return channel_in_process(client->ctrl, client->channel,
buf, len, eop);
}
/* Connect an IRQ line with a channel. */
void etraxfs_dmac_connect(void *opaque, int c, qemu_irq *line, int input)
{
struct fs_dma_ctrl *ctrl = opaque;
ctrl->channels[c].irq = *line;
ctrl->channels[c].input = input;
struct fs_dma_ctrl *ctrl = opaque;
ctrl->channels[c].irq = *line;
ctrl->channels[c].input = input;
}
void etraxfs_dmac_connect_client(void *opaque, int c,
struct etraxfs_dma_client *cl)
struct etraxfs_dma_client *cl)
{
struct fs_dma_ctrl *ctrl = opaque;
cl->ctrl = ctrl;
cl->channel = c;
ctrl->channels[c].client = cl;
struct fs_dma_ctrl *ctrl = opaque;
cl->ctrl = ctrl;
cl->channel = c;
ctrl->channels[c].client = cl;
}
@ -763,18 +763,18 @@ static void DMA_run(void *opaque)
void *etraxfs_dmac_init(hwaddr base, int nr_channels)
{
struct fs_dma_ctrl *ctrl = NULL;
struct fs_dma_ctrl *ctrl = NULL;
ctrl = g_malloc0(sizeof *ctrl);
ctrl = g_malloc0(sizeof *ctrl);
ctrl->bh = qemu_bh_new(DMA_run, ctrl);
ctrl->bh = qemu_bh_new(DMA_run, ctrl);
ctrl->nr_channels = nr_channels;
ctrl->channels = g_malloc0(sizeof ctrl->channels[0] * nr_channels);
ctrl->nr_channels = nr_channels;
ctrl->channels = g_malloc0(sizeof ctrl->channels[0] * nr_channels);
memory_region_init_io(&ctrl->mmio, NULL, &dma_ops, ctrl, "etraxfs-dma",
nr_channels * 0x2000);
memory_region_add_subregion(get_system_memory(), base, &ctrl->mmio);
memory_region_init_io(&ctrl->mmio, NULL, &dma_ops, ctrl, "etraxfs-dma",
nr_channels * 0x2000);
memory_region_add_subregion(get_system_memory(), base, &ctrl->mmio);
return ctrl;
return ctrl;
}

View File

@ -49,22 +49,22 @@ static uint8_t max7310_rx(I2CSlave *i2c)
MAX7310State *s = MAX7310(i2c);
switch (s->command) {
case 0x00: /* Input port */
case 0x00: /* Input port */
return s->level ^ s->polarity;
case 0x01: /* Output port */
case 0x01: /* Output port */
return s->level & ~s->direction;
case 0x02: /* Polarity inversion */
case 0x02: /* Polarity inversion */
return s->polarity;
case 0x03: /* Configuration */
case 0x03: /* Configuration */
return s->direction;
case 0x04: /* Timeout */
case 0x04: /* Timeout */
return s->status;
case 0xff: /* Reserved */
case 0xff: /* Reserved */
return 0xff;
default:
@ -95,7 +95,7 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
}
switch (s->command) {
case 0x01: /* Output port */
case 0x01: /* Output port */
for (diff = (data ^ s->level) & ~s->direction; diff;
diff &= ~(1 << line)) {
line = ctz32(diff);
@ -105,20 +105,20 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
s->level = (s->level & s->direction) | (data & ~s->direction);
break;
case 0x02: /* Polarity inversion */
case 0x02: /* Polarity inversion */
s->polarity = data;
break;
case 0x03: /* Configuration */
case 0x03: /* Configuration */
s->level &= ~(s->direction ^ data);
s->direction = data;
break;
case 0x04: /* Timeout */
case 0x04: /* Timeout */
s->status = data;
break;
case 0x00: /* Input port - ignore writes */
case 0x00: /* Input port - ignore writes */
break;
default:
qemu_log_mask(LOG_UNIMP, "%s: Unsupported register 0x02%" PRIx8 "\n",

View File

@ -34,28 +34,28 @@ struct ADS7846State {
OBJECT_DECLARE_SIMPLE_TYPE(ADS7846State, ADS7846)
/* Control-byte bitfields */
#define CB_PD0 (1 << 0)
#define CB_PD1 (1 << 1)
#define CB_SER (1 << 2)
#define CB_MODE (1 << 3)
#define CB_A0 (1 << 4)
#define CB_A1 (1 << 5)
#define CB_A2 (1 << 6)
#define CB_START (1 << 7)
#define CB_PD0 (1 << 0)
#define CB_PD1 (1 << 1)
#define CB_SER (1 << 2)
#define CB_MODE (1 << 3)
#define CB_A0 (1 << 4)
#define CB_A1 (1 << 5)
#define CB_A2 (1 << 6)
#define CB_START (1 << 7)
#define X_AXIS_DMAX 3470
#define X_AXIS_MIN 290
#define Y_AXIS_DMAX 3450
#define Y_AXIS_MIN 200
#define X_AXIS_DMAX 3470
#define X_AXIS_MIN 290
#define Y_AXIS_DMAX 3450
#define Y_AXIS_MIN 200
#define ADS_VBAT 2000
#define ADS_VAUX 2000
#define ADS_TEMP0 2000
#define ADS_TEMP1 3000
#define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
#define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
#define ADS_Z1POS(x, y) 600
#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y))
#define ADS_VBAT 2000
#define ADS_VAUX 2000
#define ADS_TEMP0 2000
#define ADS_TEMP1 3000
#define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
#define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
#define ADS_Z1POS(x, y) 600
#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y))
static void ads7846_int_update(ADS7846State *s)
{
@ -86,7 +86,7 @@ static uint32_t ads7846_transfer(SSIPeripheral *dev, uint32_t value)
}
if (value & CB_MODE)
s->output >>= 4; /* 8 bits instead of 12 */
s->output >>= 4; /* 8 bits instead of 12 */
break;
case 1:
@ -147,10 +147,10 @@ static void ads7846_realize(SSIPeripheral *d, Error **errp)
qdev_init_gpio_out(dev, &s->interrupt, 1);
s->input[0] = ADS_TEMP0; /* TEMP0 */
s->input[2] = ADS_VBAT; /* VBAT */
s->input[6] = ADS_VAUX; /* VAUX */
s->input[7] = ADS_TEMP1; /* TEMP1 */
s->input[0] = ADS_TEMP0; /* TEMP0 */
s->input[2] = ADS_VBAT; /* VBAT */
s->input[6] = ADS_VAUX; /* VAUX */
s->input[7] = ADS_TEMP1; /* TEMP1 */
/* We want absolute coordinates */
qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,

View File

@ -93,9 +93,9 @@ static void alarm_cb (void *opaque)
qemu_set_irq(NVRAM->IRQ, 1);
if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
/* Repeat once a month */
qemu_get_timedate(&tm, NVRAM->time_offset);
tm.tm_mon++;
@ -105,21 +105,21 @@ static void alarm_cb (void *opaque)
}
next_time = qemu_timedate_diff(&tm) - NVRAM->time_offset;
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
/* Repeat once a day */
next_time = 24 * 60 * 60;
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
/* Repeat once an hour */
next_time = 60 * 60;
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
/* Repeat once a minute */
next_time = 60;
} else {
@ -161,13 +161,13 @@ static void watchdog_cb (void *opaque)
NVRAM->buffer[0x1FF0] |= 0x80;
if (NVRAM->buffer[0x1FF7] & 0x80) {
NVRAM->buffer[0x1FF7] = 0x00;
NVRAM->buffer[0x1FFC] &= ~0x40;
NVRAM->buffer[0x1FF7] = 0x00;
NVRAM->buffer[0x1FFC] &= ~0x40;
/* May it be a hw CPU Reset instead ? */
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
} else {
qemu_set_irq(NVRAM->IRQ, 1);
qemu_set_irq(NVRAM->IRQ, 0);
qemu_set_irq(NVRAM->IRQ, 1);
qemu_set_irq(NVRAM->IRQ, 0);
}
}
@ -262,80 +262,80 @@ void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val)
case 0x1FF9:
case 0x07F9:
/* seconds (BCD) */
tmp = from_bcd(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
get_time(NVRAM, &tm);
tm.tm_sec = tmp;
set_time(NVRAM, &tm);
}
tmp = from_bcd(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
get_time(NVRAM, &tm);
tm.tm_sec = tmp;
set_time(NVRAM, &tm);
}
if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
if (val & 0x80) {
NVRAM->stop_time = time(NULL);
} else {
NVRAM->time_offset += NVRAM->stop_time - time(NULL);
NVRAM->stop_time = 0;
}
}
if (val & 0x80) {
NVRAM->stop_time = time(NULL);
} else {
NVRAM->time_offset += NVRAM->stop_time - time(NULL);
NVRAM->stop_time = 0;
}
}
NVRAM->buffer[addr] = val & 0x80;
break;
case 0x1FFA:
case 0x07FA:
/* minutes (BCD) */
tmp = from_bcd(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
get_time(NVRAM, &tm);
tm.tm_min = tmp;
set_time(NVRAM, &tm);
}
tmp = from_bcd(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
get_time(NVRAM, &tm);
tm.tm_min = tmp;
set_time(NVRAM, &tm);
}
break;
case 0x1FFB:
case 0x07FB:
/* hours (BCD) */
tmp = from_bcd(val & 0x3F);
if (tmp >= 0 && tmp <= 23) {
get_time(NVRAM, &tm);
tm.tm_hour = tmp;
set_time(NVRAM, &tm);
}
tmp = from_bcd(val & 0x3F);
if (tmp >= 0 && tmp <= 23) {
get_time(NVRAM, &tm);
tm.tm_hour = tmp;
set_time(NVRAM, &tm);
}
break;
case 0x1FFC:
case 0x07FC:
/* day of the week / century */
tmp = from_bcd(val & 0x07);
get_time(NVRAM, &tm);
tm.tm_wday = tmp;
set_time(NVRAM, &tm);
tmp = from_bcd(val & 0x07);
get_time(NVRAM, &tm);
tm.tm_wday = tmp;
set_time(NVRAM, &tm);
NVRAM->buffer[addr] = val & 0x40;
break;
case 0x1FFD:
case 0x07FD:
/* date (BCD) */
tmp = from_bcd(val & 0x3F);
if (tmp != 0) {
get_time(NVRAM, &tm);
tm.tm_mday = tmp;
set_time(NVRAM, &tm);
}
tmp = from_bcd(val & 0x3F);
if (tmp != 0) {
get_time(NVRAM, &tm);
tm.tm_mday = tmp;
set_time(NVRAM, &tm);
}
break;
case 0x1FFE:
case 0x07FE:
/* month */
tmp = from_bcd(val & 0x1F);
if (tmp >= 1 && tmp <= 12) {
get_time(NVRAM, &tm);
tm.tm_mon = tmp - 1;
set_time(NVRAM, &tm);
}
tmp = from_bcd(val & 0x1F);
if (tmp >= 1 && tmp <= 12) {
get_time(NVRAM, &tm);
tm.tm_mon = tmp - 1;
set_time(NVRAM, &tm);
}
break;
case 0x1FFF:
case 0x07FF:
/* year */
tmp = from_bcd(val);
if (tmp >= 0 && tmp <= 99) {
get_time(NVRAM, &tm);
tmp = from_bcd(val);
if (tmp >= 0 && tmp <= 99) {
get_time(NVRAM, &tm);
tm.tm_year = from_bcd(val) + NVRAM->base_year - 1900;
set_time(NVRAM, &tm);
}
set_time(NVRAM, &tm);
}
break;
default:
/* Check lock registers state */
@ -346,7 +346,7 @@ void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val)
do_write:
if (addr < NVRAM->size) {
NVRAM->buffer[addr] = val & 0xFF;
}
}
break;
}
}
@ -367,34 +367,34 @@ uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr)
switch (addr) {
case 0x1FF0:
/* flags register */
goto do_read;
goto do_read;
case 0x1FF1:
/* unused */
retval = 0;
retval = 0;
break;
case 0x1FF2:
/* alarm seconds */
goto do_read;
goto do_read;
case 0x1FF3:
/* alarm minutes */
goto do_read;
goto do_read;
case 0x1FF4:
/* alarm hours */
goto do_read;
goto do_read;
case 0x1FF5:
/* alarm date */
goto do_read;
goto do_read;
case 0x1FF6:
/* interrupts */
goto do_read;
goto do_read;
case 0x1FF7:
/* A read resets the watchdog */
set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
goto do_read;
/* A read resets the watchdog */
set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
goto do_read;
case 0x1FF8:
case 0x07F8:
/* control */
goto do_read;
goto do_read;
case 0x1FF9:
case 0x07F9:
/* seconds (BCD) */
@ -446,7 +446,7 @@ uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr)
do_read:
if (addr < NVRAM->size) {
retval = NVRAM->buffer[addr];
}
}
break;
}
trace_m48txx_nvram_mem_read(addr, retval);

View File

@ -112,19 +112,19 @@ static void menelaus_rtc_hz(void *opaque)
s->rtc.alm_sec --;
s->rtc.next += 1000;
timer_mod(s->rtc.hz_tm, s->rtc.next);
if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */
if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */
menelaus_rtc_update(s);
if (((s->rtc.ctrl >> 3) & 3) == 1 && !s->rtc.tm.tm_sec)
s->status |= 1 << 8; /* RTCTMR */
s->status |= 1 << 8; /* RTCTMR */
else if (((s->rtc.ctrl >> 3) & 3) == 2 && !s->rtc.tm.tm_min)
s->status |= 1 << 8; /* RTCTMR */
s->status |= 1 << 8; /* RTCTMR */
else if (!s->rtc.tm.tm_hour)
s->status |= 1 << 8; /* RTCTMR */
s->status |= 1 << 8; /* RTCTMR */
} else
s->status |= 1 << 8; /* RTCTMR */
if ((s->rtc.ctrl >> 1) & 1) { /* RTC_AL_EN */
s->status |= 1 << 8; /* RTCTMR */
if ((s->rtc.ctrl >> 1) & 1) { /* RTC_AL_EN */
if (s->rtc.alm_sec == 0)
s->status |= 1 << 9; /* RTCALM */
s->status |= 1 << 9; /* RTCALM */
/* TODO: wake-up */
}
if (s->rtc.next_comp <= 0) {
@ -140,19 +140,19 @@ static void menelaus_reset(I2CSlave *i2c)
s->reg = 0x00;
s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */
s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */
s->vcore[1] = 0x05;
s->vcore[2] = 0x02;
s->vcore[3] = 0x0c;
s->vcore[4] = 0x03;
s->dcdc[0] = 0x33; /* Depends on wiring */
s->dcdc[0] = 0x33; /* Depends on wiring */
s->dcdc[1] = 0x03;
s->dcdc[2] = 0x00;
s->ldo[0] = 0x95;
s->ldo[1] = 0x7e;
s->ldo[2] = 0x00;
s->ldo[3] = 0x00; /* Depends on wiring */
s->ldo[4] = 0x03; /* Depends on wiring */
s->ldo[3] = 0x00; /* Depends on wiring */
s->ldo[4] = 0x03; /* Depends on wiring */
s->ldo[5] = 0x00;
s->ldo[6] = 0x00;
s->ldo[7] = 0x00;
@ -203,70 +203,70 @@ static void menelaus_gpio_set(void *opaque, int line, int level)
}
if (!s->pwrbtn_state && level) {
s->status |= 1 << 11; /* PSHBTN */
s->status |= 1 << 11; /* PSHBTN */
menelaus_update(s);
}
s->pwrbtn_state = level;
}
#define MENELAUS_REV 0x01
#define MENELAUS_VCORE_CTRL1 0x02
#define MENELAUS_VCORE_CTRL2 0x03
#define MENELAUS_VCORE_CTRL3 0x04
#define MENELAUS_VCORE_CTRL4 0x05
#define MENELAUS_VCORE_CTRL5 0x06
#define MENELAUS_DCDC_CTRL1 0x07
#define MENELAUS_DCDC_CTRL2 0x08
#define MENELAUS_DCDC_CTRL3 0x09
#define MENELAUS_LDO_CTRL1 0x0a
#define MENELAUS_LDO_CTRL2 0x0b
#define MENELAUS_LDO_CTRL3 0x0c
#define MENELAUS_LDO_CTRL4 0x0d
#define MENELAUS_LDO_CTRL5 0x0e
#define MENELAUS_LDO_CTRL6 0x0f
#define MENELAUS_LDO_CTRL7 0x10
#define MENELAUS_LDO_CTRL8 0x11
#define MENELAUS_SLEEP_CTRL1 0x12
#define MENELAUS_SLEEP_CTRL2 0x13
#define MENELAUS_DEVICE_OFF 0x14
#define MENELAUS_OSC_CTRL 0x15
#define MENELAUS_DETECT_CTRL 0x16
#define MENELAUS_INT_MASK1 0x17
#define MENELAUS_INT_MASK2 0x18
#define MENELAUS_INT_STATUS1 0x19
#define MENELAUS_INT_STATUS2 0x1a
#define MENELAUS_INT_ACK1 0x1b
#define MENELAUS_INT_ACK2 0x1c
#define MENELAUS_GPIO_CTRL 0x1d
#define MENELAUS_GPIO_IN 0x1e
#define MENELAUS_GPIO_OUT 0x1f
#define MENELAUS_BBSMS 0x20
#define MENELAUS_RTC_CTRL 0x21
#define MENELAUS_RTC_UPDATE 0x22
#define MENELAUS_RTC_SEC 0x23
#define MENELAUS_RTC_MIN 0x24
#define MENELAUS_RTC_HR 0x25
#define MENELAUS_RTC_DAY 0x26
#define MENELAUS_RTC_MON 0x27
#define MENELAUS_RTC_YR 0x28
#define MENELAUS_RTC_WKDAY 0x29
#define MENELAUS_RTC_AL_SEC 0x2a
#define MENELAUS_RTC_AL_MIN 0x2b
#define MENELAUS_RTC_AL_HR 0x2c
#define MENELAUS_RTC_AL_DAY 0x2d
#define MENELAUS_RTC_AL_MON 0x2e
#define MENELAUS_RTC_AL_YR 0x2f
#define MENELAUS_RTC_COMP_MSB 0x30
#define MENELAUS_RTC_COMP_LSB 0x31
#define MENELAUS_S1_PULL_EN 0x32
#define MENELAUS_S1_PULL_DIR 0x33
#define MENELAUS_S2_PULL_EN 0x34
#define MENELAUS_S2_PULL_DIR 0x35
#define MENELAUS_MCT_CTRL1 0x36
#define MENELAUS_MCT_CTRL2 0x37
#define MENELAUS_MCT_CTRL3 0x38
#define MENELAUS_MCT_PIN_ST 0x39
#define MENELAUS_DEBOUNCE1 0x3a
#define MENELAUS_REV 0x01
#define MENELAUS_VCORE_CTRL1 0x02
#define MENELAUS_VCORE_CTRL2 0x03
#define MENELAUS_VCORE_CTRL3 0x04
#define MENELAUS_VCORE_CTRL4 0x05
#define MENELAUS_VCORE_CTRL5 0x06
#define MENELAUS_DCDC_CTRL1 0x07
#define MENELAUS_DCDC_CTRL2 0x08
#define MENELAUS_DCDC_CTRL3 0x09
#define MENELAUS_LDO_CTRL1 0x0a
#define MENELAUS_LDO_CTRL2 0x0b
#define MENELAUS_LDO_CTRL3 0x0c
#define MENELAUS_LDO_CTRL4 0x0d
#define MENELAUS_LDO_CTRL5 0x0e
#define MENELAUS_LDO_CTRL6 0x0f
#define MENELAUS_LDO_CTRL7 0x10
#define MENELAUS_LDO_CTRL8 0x11
#define MENELAUS_SLEEP_CTRL1 0x12
#define MENELAUS_SLEEP_CTRL2 0x13
#define MENELAUS_DEVICE_OFF 0x14
#define MENELAUS_OSC_CTRL 0x15
#define MENELAUS_DETECT_CTRL 0x16
#define MENELAUS_INT_MASK1 0x17
#define MENELAUS_INT_MASK2 0x18
#define MENELAUS_INT_STATUS1 0x19
#define MENELAUS_INT_STATUS2 0x1a
#define MENELAUS_INT_ACK1 0x1b
#define MENELAUS_INT_ACK2 0x1c
#define MENELAUS_GPIO_CTRL 0x1d
#define MENELAUS_GPIO_IN 0x1e
#define MENELAUS_GPIO_OUT 0x1f
#define MENELAUS_BBSMS 0x20
#define MENELAUS_RTC_CTRL 0x21
#define MENELAUS_RTC_UPDATE 0x22
#define MENELAUS_RTC_SEC 0x23
#define MENELAUS_RTC_MIN 0x24
#define MENELAUS_RTC_HR 0x25
#define MENELAUS_RTC_DAY 0x26
#define MENELAUS_RTC_MON 0x27
#define MENELAUS_RTC_YR 0x28
#define MENELAUS_RTC_WKDAY 0x29
#define MENELAUS_RTC_AL_SEC 0x2a
#define MENELAUS_RTC_AL_MIN 0x2b
#define MENELAUS_RTC_AL_HR 0x2c
#define MENELAUS_RTC_AL_DAY 0x2d
#define MENELAUS_RTC_AL_MON 0x2e
#define MENELAUS_RTC_AL_YR 0x2f
#define MENELAUS_RTC_COMP_MSB 0x30
#define MENELAUS_RTC_COMP_LSB 0x31
#define MENELAUS_S1_PULL_EN 0x32
#define MENELAUS_S1_PULL_DIR 0x33
#define MENELAUS_S2_PULL_EN 0x34
#define MENELAUS_S2_PULL_DIR 0x35
#define MENELAUS_MCT_CTRL1 0x36
#define MENELAUS_MCT_CTRL2 0x37
#define MENELAUS_MCT_CTRL3 0x38
#define MENELAUS_MCT_PIN_ST 0x39
#define MENELAUS_DEBOUNCE1 0x3a
static uint8_t menelaus_read(void *opaque, uint8_t addr)
{
@ -293,7 +293,7 @@ static uint8_t menelaus_read(void *opaque, uint8_t addr)
return 0;
case MENELAUS_OSC_CTRL:
return s->osc | (1 << 7); /* CLK32K_GOOD */
return s->osc | (1 << 7); /* CLK32K_GOOD */
case MENELAUS_DETECT_CTRL:
return s->detect;
@ -334,9 +334,9 @@ static uint8_t menelaus_read(void *opaque, uint8_t addr)
return to_bcd(s->rtc.tm.tm_min);
case MENELAUS_RTC_HR:
menelaus_rtc_update(s);
if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */
if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */
return to_bcd((s->rtc.tm.tm_hour % 12) + 1) |
(!!(s->rtc.tm.tm_hour >= 12) << 7); /* PM_nAM */
(!!(s->rtc.tm.tm_hour >= 12) << 7); /* PM_nAM */
else
return to_bcd(s->rtc.tm.tm_hour);
case MENELAUS_RTC_DAY:
@ -356,7 +356,7 @@ static uint8_t menelaus_read(void *opaque, uint8_t addr)
case MENELAUS_RTC_AL_MIN:
return to_bcd(s->rtc.alm.tm_min);
case MENELAUS_RTC_AL_HR:
if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */
if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */
return to_bcd((s->rtc.alm.tm_hour % 12) + 1) |
(!!(s->rtc.alm.tm_hour >= 12) << 7);/* AL_PM_nAM */
else
@ -541,7 +541,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
break;
case MENELAUS_RTC_CTRL:
if ((s->rtc.ctrl ^ value) & 1) { /* RTC_EN */
if ((s->rtc.ctrl ^ value) & 1) { /* RTC_EN */
if (value & 1)
menelaus_rtc_start(s);
else
@ -603,7 +603,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
default:
fprintf(stderr, "%s: bad RTC_UPDATE value %02x\n",
__func__, value);
s->status |= 1 << 10; /* RTCERR */
s->status |= 1 << 10; /* RTCERR */
menelaus_update(s);
}
s->rtc.sec_offset = qemu_timedate_diff(&tm);
@ -615,7 +615,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
s->rtc.tm.tm_min = from_bcd(value & 0x7f);
break;
case MENELAUS_RTC_HR:
s->rtc.tm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */
s->rtc.tm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */
MIN(from_bcd(value & 0x3f), 12) + ((value >> 7) ? 11 : -1) :
from_bcd(value & 0x3f);
break;
@ -640,7 +640,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
menelaus_alm_update(s);
break;
case MENELAUS_RTC_AL_HR:
s->rtc.alm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */
s->rtc.alm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */
MIN(from_bcd(value & 0x3f), 12) + ((value >> 7) ? 11 : -1) :
from_bcd(value & 0x3f);
menelaus_alm_update(s);
@ -792,14 +792,14 @@ static int menelaus_post_load(void *opaque, int version_id)
{
MenelausState *s = opaque;
if (s->rtc.ctrl & 1) /* RTC_EN */
if (s->rtc.ctrl & 1) /* RTC_EN */
menelaus_rtc_stop(s);
s->rtc.next = s->rtc_next_vmstate;
menelaus_alm_update(s);
menelaus_update(s);
if (s->rtc.ctrl & 1) /* RTC_EN */
if (s->rtc.ctrl & 1) /* RTC_EN */
menelaus_rtc_start(s);
return 0;
}

View File

@ -199,8 +199,8 @@ static void scsi_dma_restart_cb(void *opaque, bool running, RunState state)
}
static bool scsi_bus_is_address_free(SCSIBus *bus,
int channel, int target, int lun,
SCSIDevice **p_dev)
int channel, int target, int lun,
SCSIDevice **p_dev)
{
SCSIDevice *d;

View File

@ -342,39 +342,39 @@ static void sd_set_scr(SDState *sd)
sd->scr[7] = 0x00;
}
#define MID 0xaa
#define OID "XY"
#define PNM "QEMU!"
#define PRV 0x01
#define MDT_YR 2006
#define MDT_MON 2
#define MID 0xaa
#define OID "XY"
#define PNM "QEMU!"
#define PRV 0x01
#define MDT_YR 2006
#define MDT_MON 2
static void sd_set_cid(SDState *sd)
{
sd->cid[0] = MID; /* Fake card manufacturer ID (MID) */
sd->cid[1] = OID[0]; /* OEM/Application ID (OID) */
sd->cid[0] = MID; /* Fake card manufacturer ID (MID) */
sd->cid[1] = OID[0]; /* OEM/Application ID (OID) */
sd->cid[2] = OID[1];
sd->cid[3] = PNM[0]; /* Fake product name (PNM) */
sd->cid[3] = PNM[0]; /* Fake product name (PNM) */
sd->cid[4] = PNM[1];
sd->cid[5] = PNM[2];
sd->cid[6] = PNM[3];
sd->cid[7] = PNM[4];
sd->cid[8] = PRV; /* Fake product revision (PRV) */
sd->cid[9] = 0xde; /* Fake serial number (PSN) */
sd->cid[8] = PRV; /* Fake product revision (PRV) */
sd->cid[9] = 0xde; /* Fake serial number (PSN) */
sd->cid[10] = 0xad;
sd->cid[11] = 0xbe;
sd->cid[12] = 0xef;
sd->cid[13] = 0x00 | /* Manufacture date (MDT) */
sd->cid[13] = 0x00 | /* Manufacture date (MDT) */
((MDT_YR - 2000) / 10);
sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
}
#define HWBLOCK_SHIFT 9 /* 512 bytes */
#define SECTOR_SHIFT 5 /* 16 kilobytes */
#define WPGROUP_SHIFT 7 /* 2 megs */
#define CMULT_SHIFT 9 /* 512 times HWBLOCK_SIZE */
#define WPGROUP_SIZE (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
#define HWBLOCK_SHIFT 9 /* 512 bytes */
#define SECTOR_SHIFT 5 /* 16 kilobytes */
#define WPGROUP_SHIFT 7 /* 2 megs */
#define CMULT_SHIFT 9 /* 512 times HWBLOCK_SIZE */
#define WPGROUP_SIZE (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
static const uint8_t sd_csd_rw_mask[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -395,31 +395,31 @@ static void sd_set_csd(SDState *sd, uint64_t size)
csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
sd->csd[0] = 0x00; /* CSD structure */
sd->csd[1] = 0x26; /* Data read access-time-1 */
sd->csd[2] = 0x00; /* Data read access-time-2 */
sd->csd[0] = 0x00; /* CSD structure */
sd->csd[1] = 0x26; /* Data read access-time-1 */
sd->csd[2] = 0x00; /* Data read access-time-2 */
sd->csd[3] = 0x32; /* Max. data transfer rate: 25 MHz */
sd->csd[4] = 0x5f; /* Card Command Classes */
sd->csd[5] = 0x50 | /* Max. read data block length */
sd->csd[4] = 0x5f; /* Card Command Classes */
sd->csd[5] = 0x50 | /* Max. read data block length */
hwblock_shift;
sd->csd[6] = 0xe0 | /* Partial block for read allowed */
sd->csd[6] = 0xe0 | /* Partial block for read allowed */
((csize >> 10) & 0x03);
sd->csd[7] = 0x00 | /* Device size */
sd->csd[7] = 0x00 | /* Device size */
((csize >> 2) & 0xff);
sd->csd[8] = 0x3f | /* Max. read current */
sd->csd[8] = 0x3f | /* Max. read current */
((csize << 6) & 0xc0);
sd->csd[9] = 0xfc | /* Max. write current */
sd->csd[9] = 0xfc | /* Max. write current */
((CMULT_SHIFT - 2) >> 1);
sd->csd[10] = 0x40 | /* Erase sector size */
sd->csd[10] = 0x40 | /* Erase sector size */
(((CMULT_SHIFT - 2) << 7) & 0x80) | (sectsize >> 1);
sd->csd[11] = 0x00 | /* Write protect group size */
sd->csd[11] = 0x00 | /* Write protect group size */
((sectsize << 7) & 0x80) | wpsize;
sd->csd[12] = 0x90 | /* Write speed factor */
sd->csd[12] = 0x90 | /* Write speed factor */
(hwblock_shift >> 2);
sd->csd[13] = 0x20 | /* Max. write data block length */
sd->csd[13] = 0x20 | /* Max. write data block length */
((hwblock_shift << 6) & 0xc0);
sd->csd[14] = 0x00; /* File format group */
} else { /* SDHC */
sd->csd[14] = 0x00; /* File format group */
} else { /* SDHC */
size /= 512 * KiB;
size -= 1;
sd->csd[0] = 0x40;
@ -513,7 +513,7 @@ static int sd_req_crc_validate(SDRequest *req)
buffer[0] = 0x40 | req->cmd;
stl_be_p(&buffer[1], req->arg);
return 0;
return sd_crc7(buffer, 5) != req->crc; /* TODO */
return sd_crc7(buffer, 5) != req->crc; /* TODO */
}
static void sd_response_r1_make(SDState *sd, uint8_t *response)
@ -851,19 +851,19 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
int i, mode, new_func;
mode = !!(arg & 0x80000000);
sd->data[0] = 0x00; /* Maximum current consumption */
sd->data[0] = 0x00; /* Maximum current consumption */
sd->data[1] = 0x01;
sd->data[2] = 0x80; /* Supported group 6 functions */
sd->data[2] = 0x80; /* Supported group 6 functions */
sd->data[3] = 0x01;
sd->data[4] = 0x80; /* Supported group 5 functions */
sd->data[4] = 0x80; /* Supported group 5 functions */
sd->data[5] = 0x01;
sd->data[6] = 0x80; /* Supported group 4 functions */
sd->data[6] = 0x80; /* Supported group 4 functions */
sd->data[7] = 0x01;
sd->data[8] = 0x80; /* Supported group 3 functions */
sd->data[8] = 0x80; /* Supported group 3 functions */
sd->data[9] = 0x01;
sd->data[10] = 0x80; /* Supported group 2 functions */
sd->data[10] = 0x80; /* Supported group 2 functions */
sd->data[11] = 0x43;
sd->data[12] = 0x80; /* Supported group 1 functions */
sd->data[12] = 0x80; /* Supported group 1 functions */
sd->data[13] = 0x03;
memset(&sd->data[14], 0, 3);
@ -1001,7 +1001,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
switch (req.cmd) {
/* Basic commands (Class 0 and Class 1) */
case 0: /* CMD0: GO_IDLE_STATE */
case 0: /* CMD0: GO_IDLE_STATE */
switch (sd->state) {
case sd_inactive_state:
return sd->spi ? sd_r1 : sd_r0;
@ -1013,14 +1013,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 1: /* CMD1: SEND_OP_CMD */
case 1: /* CMD1: SEND_OP_CMD */
if (!sd->spi)
goto bad_cmd;
sd->state = sd_transfer_state;
return sd_r1;
case 2: /* CMD2: ALL_SEND_CID */
case 2: /* CMD2: ALL_SEND_CID */
if (sd->spi)
goto bad_cmd;
switch (sd->state) {
@ -1033,7 +1033,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 3: /* CMD3: SEND_RELATIVE_ADDR */
case 3: /* CMD3: SEND_RELATIVE_ADDR */
if (sd->spi)
goto bad_cmd;
switch (sd->state) {
@ -1048,7 +1048,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 4: /* CMD4: SEND_DSR */
case 4: /* CMD4: SEND_DSR */
if (sd->spi)
goto bad_cmd;
switch (sd->state) {
@ -1063,7 +1063,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
case 5: /* CMD5: reserved for SDIO cards */
return sd_illegal;
case 6: /* CMD6: SWITCH_FUNCTION */
case 6: /* CMD6: SWITCH_FUNCTION */
switch (sd->mode) {
case sd_data_transfer_mode:
sd_function_switch(sd, req.arg);
@ -1077,7 +1077,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 7: /* CMD7: SELECT/DESELECT_CARD */
case 7: /* CMD7: SELECT/DESELECT_CARD */
if (sd->spi)
goto bad_cmd;
switch (sd->state) {
@ -1115,7 +1115,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 8: /* CMD8: SEND_IF_COND */
case 8: /* CMD8: SEND_IF_COND */
if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
break;
}
@ -1133,7 +1133,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
sd->vhs = req.arg;
return sd_r7;
case 9: /* CMD9: SEND_CSD */
case 9: /* CMD9: SEND_CSD */
switch (sd->state) {
case sd_standby_state:
if (sd->rca != rca)
@ -1155,7 +1155,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 10: /* CMD10: SEND_CID */
case 10: /* CMD10: SEND_CID */
switch (sd->state) {
case sd_standby_state:
if (sd->rca != rca)
@ -1177,7 +1177,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 12: /* CMD12: STOP_TRANSMISSION */
case 12: /* CMD12: STOP_TRANSMISSION */
switch (sd->state) {
case sd_sendingdata_state:
sd->state = sd_transfer_state;
@ -1194,7 +1194,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 13: /* CMD13: SEND_STATUS */
case 13: /* CMD13: SEND_STATUS */
switch (sd->mode) {
case sd_data_transfer_mode:
if (!sd->spi && sd->rca != rca) {
@ -1208,7 +1208,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 15: /* CMD15: GO_INACTIVE_STATE */
case 15: /* CMD15: GO_INACTIVE_STATE */
if (sd->spi)
goto bad_cmd;
switch (sd->mode) {
@ -1225,7 +1225,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
/* Block read commands (Classs 2) */
case 16: /* CMD16: SET_BLOCKLEN */
case 16: /* CMD16: SET_BLOCKLEN */
switch (sd->state) {
case sd_transfer_state:
if (req.arg > (1 << HWBLOCK_SHIFT)) {
@ -1242,8 +1242,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 17: /* CMD17: READ_SINGLE_BLOCK */
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
case 17: /* CMD17: READ_SINGLE_BLOCK */
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
switch (sd->state) {
case sd_transfer_state:
@ -1287,8 +1287,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
/* Block write commands (Class 4) */
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
switch (sd->state) {
case sd_transfer_state:
@ -1316,7 +1316,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 26: /* CMD26: PROGRAM_CID */
case 26: /* CMD26: PROGRAM_CID */
if (sd->spi)
goto bad_cmd;
switch (sd->state) {
@ -1331,7 +1331,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 27: /* CMD27: PROGRAM_CSD */
case 27: /* CMD27: PROGRAM_CSD */
switch (sd->state) {
case sd_transfer_state:
sd->state = sd_receivingdata_state;
@ -1345,7 +1345,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
/* Write protection (Class 6) */
case 28: /* CMD28: SET_WRITE_PROT */
case 28: /* CMD28: SET_WRITE_PROT */
if (sd->size > SDSC_MAX_CAPACITY) {
return sd_illegal;
}
@ -1367,7 +1367,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 29: /* CMD29: CLR_WRITE_PROT */
case 29: /* CMD29: CLR_WRITE_PROT */
if (sd->size > SDSC_MAX_CAPACITY) {
return sd_illegal;
}
@ -1389,7 +1389,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 30: /* CMD30: SEND_WRITE_PROT */
case 30: /* CMD30: SEND_WRITE_PROT */
if (sd->size > SDSC_MAX_CAPACITY) {
return sd_illegal;
}
@ -1413,7 +1413,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
/* Erase commands (Class 5) */
case 32: /* CMD32: ERASE_WR_BLK_START */
case 32: /* CMD32: ERASE_WR_BLK_START */
switch (sd->state) {
case sd_transfer_state:
sd->erase_start = req.arg;
@ -1424,7 +1424,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 33: /* CMD33: ERASE_WR_BLK_END */
case 33: /* CMD33: ERASE_WR_BLK_END */
switch (sd->state) {
case sd_transfer_state:
sd->erase_end = req.arg;
@ -1435,7 +1435,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 38: /* CMD38: ERASE */
case 38: /* CMD38: ERASE */
switch (sd->state) {
case sd_transfer_state:
if (sd->csd[14] & 0x30) {
@ -1455,7 +1455,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
/* Lock card commands (Class 7) */
case 42: /* CMD42: LOCK_UNLOCK */
case 42: /* CMD42: LOCK_UNLOCK */
switch (sd->state) {
case sd_transfer_state:
sd->state = sd_receivingdata_state;
@ -1478,7 +1478,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
return sd_illegal;
/* Application specific commands (Class 8) */
case 55: /* CMD55: APP_CMD */
case 55: /* CMD55: APP_CMD */
switch (sd->state) {
case sd_ready_state:
case sd_identification_state:
@ -1501,7 +1501,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
sd->card_status |= APP_CMD;
return sd_r1;
case 56: /* CMD56: GEN_CMD */
case 56: /* CMD56: GEN_CMD */
switch (sd->state) {
case sd_transfer_state:
sd->data_offset = 0;
@ -1546,7 +1546,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
req.cmd, req.arg, sd_state_name(sd->state));
sd->card_status |= APP_CMD;
switch (req.cmd) {
case 6: /* ACMD6: SET_BUS_WIDTH */
case 6: /* ACMD6: SET_BUS_WIDTH */
if (sd->spi) {
goto unimplemented_spi_cmd;
}
@ -1561,7 +1561,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
}
break;
case 13: /* ACMD13: SD_STATUS */
case 13: /* ACMD13: SD_STATUS */
switch (sd->state) {
case sd_transfer_state:
sd->state = sd_sendingdata_state;
@ -1574,7 +1574,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
}
break;
case 22: /* ACMD22: SEND_NUM_WR_BLOCKS */
case 22: /* ACMD22: SEND_NUM_WR_BLOCKS */
switch (sd->state) {
case sd_transfer_state:
*(uint32_t *) sd->data = sd->blk_written;
@ -1589,7 +1589,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
}
break;
case 23: /* ACMD23: SET_WR_BLK_ERASE_COUNT */
case 23: /* ACMD23: SET_WR_BLK_ERASE_COUNT */
switch (sd->state) {
case sd_transfer_state:
return sd_r1;
@ -1599,7 +1599,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
}
break;
case 41: /* ACMD41: SD_APP_OP_COND */
case 41: /* ACMD41: SD_APP_OP_COND */
if (sd->spi) {
/* SEND_OP_CMD */
sd->state = sd_transfer_state;
@ -1641,7 +1641,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
return sd_r3;
case 42: /* ACMD42: SET_CLR_CARD_DETECT */
case 42: /* ACMD42: SET_CLR_CARD_DETECT */
switch (sd->state) {
case sd_transfer_state:
/* Bringing in the 50KOhm pull-up resistor... Done. */
@ -1652,7 +1652,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
}
break;
case 51: /* ACMD51: SEND_SCR */
case 51: /* ACMD51: SEND_SCR */
switch (sd->state) {
case sd_transfer_state:
sd->state = sd_sendingdata_state;
@ -1840,7 +1840,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
sd_acmd_name(sd->current_cmd),
sd->current_cmd, value);
switch (sd->current_cmd) {
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
sd->data[sd->data_offset ++] = value;
if (sd->data_offset >= sd->blk_len) {
/* TODO: Check CRC before committing */
@ -1853,7 +1853,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
}
break;
case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
if (sd->data_offset == 0) {
/* Start of the block - let's check the address is valid */
if (!address_in_range(sd, "WRITE_MULTIPLE_BLOCK",
@ -1890,7 +1890,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
}
break;
case 26: /* CMD26: PROGRAM_CID */
case 26: /* CMD26: PROGRAM_CID */
sd->data[sd->data_offset ++] = value;
if (sd->data_offset >= sizeof(sd->cid)) {
/* TODO: Check CRC before committing */
@ -1909,7 +1909,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
}
break;
case 27: /* CMD27: PROGRAM_CSD */
case 27: /* CMD27: PROGRAM_CSD */
sd->data[sd->data_offset ++] = value;
if (sd->data_offset >= sizeof(sd->csd)) {
/* TODO: Check CRC before committing */
@ -1933,7 +1933,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
}
break;
case 42: /* CMD42: LOCK_UNLOCK */
case 42: /* CMD42: LOCK_UNLOCK */
sd->data[sd->data_offset ++] = value;
if (sd->data_offset >= sd->blk_len) {
/* TODO: Check CRC before committing */
@ -1944,7 +1944,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
}
break;
case 56: /* CMD56: GEN_CMD */
case 56: /* CMD56: GEN_CMD */
sd->data[sd->data_offset ++] = value;
if (sd->data_offset >= sd->blk_len) {
APP_WRITE_BLOCK(sd->data_start, sd->data_offset);
@ -1996,29 +1996,29 @@ uint8_t sd_read_byte(SDState *sd)
sd_acmd_name(sd->current_cmd),
sd->current_cmd, io_len);
switch (sd->current_cmd) {
case 6: /* CMD6: SWITCH_FUNCTION */
case 6: /* CMD6: SWITCH_FUNCTION */
ret = sd->data[sd->data_offset ++];
if (sd->data_offset >= 64)
sd->state = sd_transfer_state;
break;
case 9: /* CMD9: SEND_CSD */
case 10: /* CMD10: SEND_CID */
case 9: /* CMD9: SEND_CSD */
case 10: /* CMD10: SEND_CID */
ret = sd->data[sd->data_offset ++];
if (sd->data_offset >= 16)
sd->state = sd_transfer_state;
break;
case 13: /* ACMD13: SD_STATUS */
case 13: /* ACMD13: SD_STATUS */
ret = sd->sd_status[sd->data_offset ++];
if (sd->data_offset >= sizeof(sd->sd_status))
sd->state = sd_transfer_state;
break;
case 17: /* CMD17: READ_SINGLE_BLOCK */
case 17: /* CMD17: READ_SINGLE_BLOCK */
if (sd->data_offset == 0)
BLK_READ_BLOCK(sd->data_start, io_len);
ret = sd->data[sd->data_offset ++];
@ -2027,7 +2027,7 @@ uint8_t sd_read_byte(SDState *sd)
sd->state = sd_transfer_state;
break;
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
if (sd->data_offset == 0) {
if (!address_in_range(sd, "READ_MULTIPLE_BLOCK",
sd->data_start, io_len)) {
@ -2058,28 +2058,28 @@ uint8_t sd_read_byte(SDState *sd)
ret = sd_tuning_block_pattern[sd->data_offset++];
break;
case 22: /* ACMD22: SEND_NUM_WR_BLOCKS */
case 22: /* ACMD22: SEND_NUM_WR_BLOCKS */
ret = sd->data[sd->data_offset ++];
if (sd->data_offset >= 4)
sd->state = sd_transfer_state;
break;
case 30: /* CMD30: SEND_WRITE_PROT */
case 30: /* CMD30: SEND_WRITE_PROT */
ret = sd->data[sd->data_offset ++];
if (sd->data_offset >= 4)
sd->state = sd_transfer_state;
break;
case 51: /* ACMD51: SEND_SCR */
case 51: /* ACMD51: SEND_SCR */
ret = sd->scr[sd->data_offset ++];
if (sd->data_offset >= sizeof(sd->scr))
sd->state = sd_transfer_state;
break;
case 56: /* CMD56: GEN_CMD */
case 56: /* CMD56: GEN_CMD */
if (sd->data_offset == 0)
APP_READ_BLOCK(sd->data_start, sd->blk_len);
ret = sd->data[sd->data_offset ++];

View File

@ -30,7 +30,7 @@
/*#define IB700_DEBUG 1*/
#ifdef IB700_DEBUG
#define ib700_debug(fs,...) \
#define ib700_debug(fs,...) \
fprintf(stderr,"ib700: %s: "fs,__func__,##__VA_ARGS__)
#else
#define ib700_debug(fs,...)

View File

@ -18,14 +18,14 @@ typedef struct aes_key_st AES_KEY;
#define AES_decrypt QEMU_AES_decrypt
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
AES_KEY *key);
void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
const AES_KEY *key);
extern const uint8_t AES_sbox[256];
extern const uint8_t AES_isbox[256];

View File

@ -15,30 +15,30 @@
/* d3des.h -
*
* Headers and defines for d3des.c
* Graven Imagery, 1992.
* Headers and defines for d3des.c
* Graven Imagery, 1992.
*
* Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
* (GEnie : OUTER; CIS : [71755,204])
* (GEnie : OUTER; CIS : [71755,204])
*/
#define EN0 0 /* MODE == encrypt */
#define DE1 1 /* MODE == decrypt */
#define EN0 0 /* MODE == encrypt */
#define DE1 1 /* MODE == decrypt */
void deskey(unsigned char *, int);
/* hexkey[8] MODE
/* hexkey[8] MODE
* Sets the internal key register according to the hexadecimal
* key contained in the 8 bytes of hexkey, according to the DES,
* for encryption or decryption according to MODE.
*/
void usekey(unsigned long *);
/* cookedkey[32]
/* cookedkey[32]
* Loads the internal key register with the data in cookedkey.
*/
void des(unsigned char *, unsigned char *);
/* from[8] to[8]
/* from[8] to[8]
* Encrypts/Decrypts (according to the key currently loaded in the
* internal key register) one block of eight bytes at address 'from'
* into the block at address 'to'. They can be the same.

View File

@ -188,20 +188,20 @@ enum bfd_architecture
#define bfd_mach_alpha_ev5 0x20
#define bfd_mach_alpha_ev6 0x30
bfd_arch_arm, /* Advanced Risc Machines ARM */
#define bfd_mach_arm_unknown 0
#define bfd_mach_arm_2 1
#define bfd_mach_arm_2a 2
#define bfd_mach_arm_3 3
#define bfd_mach_arm_3M 4
#define bfd_mach_arm_4 5
#define bfd_mach_arm_4T 6
#define bfd_mach_arm_5 7
#define bfd_mach_arm_5T 8
#define bfd_mach_arm_5TE 9
#define bfd_mach_arm_XScale 10
#define bfd_mach_arm_ep9312 11
#define bfd_mach_arm_iWMMXt 12
#define bfd_mach_arm_iWMMXt2 13
#define bfd_mach_arm_unknown 0
#define bfd_mach_arm_2 1
#define bfd_mach_arm_2a 2
#define bfd_mach_arm_3 3
#define bfd_mach_arm_3M 4
#define bfd_mach_arm_4 5
#define bfd_mach_arm_4T 6
#define bfd_mach_arm_5 7
#define bfd_mach_arm_5T 8
#define bfd_mach_arm_5TE 9
#define bfd_mach_arm_XScale 10
#define bfd_mach_arm_ep9312 11
#define bfd_mach_arm_iWMMXt 12
#define bfd_mach_arm_iWMMXt2 13
bfd_arch_ns32k, /* National Semiconductors ns32000 */
bfd_arch_w65, /* WDC 65816 */
bfd_arch_tic30, /* Texas Instruments TMS320C30 */
@ -241,7 +241,7 @@ enum bfd_architecture
bfd_arch_ia64, /* HP/Intel ia64 */
#define bfd_mach_ia64_elf64 64
#define bfd_mach_ia64_elf32 32
bfd_arch_nios2, /* Nios II */
bfd_arch_nios2, /* Nios II */
#define bfd_mach_nios2 0
#define bfd_mach_nios2r1 1
#define bfd_mach_nios2r2 2
@ -269,14 +269,14 @@ typedef int (*fprintf_function)(FILE *f, const char *fmt, ...)
G_GNUC_PRINTF(2, 3);
enum dis_insn_type {
dis_noninsn, /* Not a valid instruction */
dis_nonbranch, /* Not a branch instruction */
dis_branch, /* Unconditional branch */
dis_condbranch, /* Conditional branch */
dis_jsr, /* Jump to subroutine */
dis_condjsr, /* Conditional jump to subroutine */
dis_dref, /* Data reference instruction */
dis_dref2 /* Two data references in instruction */
dis_noninsn, /* Not a valid instruction */
dis_nonbranch, /* Not a branch instruction */
dis_branch, /* Unconditional branch */
dis_condbranch, /* Conditional branch */
dis_jsr, /* Jump to subroutine */
dis_condjsr, /* Conditional jump to subroutine */
dis_dref, /* Data reference instruction */
dis_dref2 /* Two data references in instruction */
};
/* This struct is passed into the instruction decoding routine,
@ -319,8 +319,8 @@ typedef struct disassemble_info {
The top 16 bits are reserved for public use (and are documented here).
The bottom 16 bits are for the internal use of the disassembler. */
unsigned long flags;
#define INSN_HAS_RELOC 0x80000000
#define INSN_ARM_BE32 0x00010000
#define INSN_HAS_RELOC 0x80000000
#define INSN_ARM_BE32 0x00010000
PTR private_data;
/* Function used to get bytes to disassemble. MEMADDR is the
@ -330,7 +330,7 @@ typedef struct disassemble_info {
Returns an errno value or 0 for success. */
int (*read_memory_func)
(bfd_vma memaddr, bfd_byte *myaddr, int length,
struct disassemble_info *info);
struct disassemble_info *info);
/* Function which should be called if we get an error that we can't
recover from. STATUS is the errno value from read_memory_func and
@ -384,14 +384,14 @@ typedef struct disassemble_info {
To determine whether this decoder supports this information, set
insn_info_valid to 0, decode an instruction, then check it. */
char insn_info_valid; /* Branch info has been set. */
char branch_delay_insns; /* How many sequential insn's will run before
a branch takes effect. (0 = normal) */
char data_size; /* Size of data reference in insn, in bytes */
enum dis_insn_type insn_type; /* Type of instruction */
bfd_vma target; /* Target address of branch or dref, if known;
zero if unknown. */
bfd_vma target2; /* Second target address for dref2 */
char insn_info_valid; /* Branch info has been set. */
char branch_delay_insns; /* How many sequential insn's will run before
a branch takes effect. (0 = normal) */
char data_size; /* Size of data reference in insn, in bytes */
enum dis_insn_type insn_type; /* Type of instruction */
bfd_vma target; /* Target address of branch or dref, if known;
zero if unknown. */
bfd_vma target2; /* Second target address for dref2 */
/* Command line options specific to the target disassembler. */
char * disassembler_options;

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
#include "hw/core/cpu.h"
#include "qemu/rcu.h"
#define EXCP_INTERRUPT 0x10000 /* async interruption */
#define EXCP_INTERRUPT 0x10000 /* async interruption */
#define EXCP_HLT 0x10001 /* hlt instruction reached */
#define EXCP_DEBUG 0x10002 /* cpu stopped after a breakpoint or singlestep */
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */

View File

@ -66,7 +66,7 @@
#define ACPI_BITMASK_POWER_BUTTON_STATUS 0x0100
#define ACPI_BITMASK_SLEEP_BUTTON_STATUS 0x0200
#define ACPI_BITMASK_RT_CLOCK_STATUS 0x0400
#define ACPI_BITMASK_PCIEXP_WAKE_STATUS 0x4000 /* ACPI 3.0 */
#define ACPI_BITMASK_PCIEXP_WAKE_STATUS 0x4000 /* ACPI 3.0 */
#define ACPI_BITMASK_WAKE_STATUS 0x8000
#define ACPI_BITMASK_ALL_FIXED_STATUS (\
@ -84,7 +84,7 @@
#define ACPI_BITMASK_POWER_BUTTON_ENABLE 0x0100
#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE 0x0200
#define ACPI_BITMASK_RT_CLOCK_ENABLE 0x0400
#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE 0x4000 /* ACPI 3.0 */
#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE 0x4000 /* ACPI 3.0 */
#define ACPI_BITMASK_PM1_COMMON_ENABLED ( \
ACPI_BITMASK_RT_CLOCK_ENABLE | \

View File

@ -1,30 +1,30 @@
static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
{
bswap16s(&ehdr->e_type); /* Object file type */
bswap16s(&ehdr->e_machine); /* Architecture */
bswap32s(&ehdr->e_version); /* Object file version */
bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
bswap32s(&ehdr->e_flags); /* Processor-specific flags */
bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
bswap16s(&ehdr->e_phnum); /* Program header table entry count */
bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
bswap16s(&ehdr->e_shnum); /* Section header table entry count */
bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
bswap16s(&ehdr->e_type); /* Object file type */
bswap16s(&ehdr->e_machine); /* Architecture */
bswap32s(&ehdr->e_version); /* Object file version */
bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
bswap32s(&ehdr->e_flags); /* Processor-specific flags */
bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
bswap16s(&ehdr->e_phnum); /* Program header table entry count */
bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
bswap16s(&ehdr->e_shnum); /* Section header table entry count */
bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
}
static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
{
bswap32s(&phdr->p_type); /* Segment type */
bswapSZs(&phdr->p_offset); /* Segment file offset */
bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
bswapSZs(&phdr->p_paddr); /* Segment physical address */
bswapSZs(&phdr->p_filesz); /* Segment size in file */
bswapSZs(&phdr->p_memsz); /* Segment size in memory */
bswap32s(&phdr->p_flags); /* Segment flags */
bswapSZs(&phdr->p_align); /* Segment alignment */
bswap32s(&phdr->p_type); /* Segment type */
bswapSZs(&phdr->p_offset); /* Segment file offset */
bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
bswapSZs(&phdr->p_paddr); /* Segment physical address */
bswapSZs(&phdr->p_filesz); /* Segment size in file */
bswapSZs(&phdr->p_memsz); /* Segment size in memory */
bswap32s(&phdr->p_flags); /* Segment flags */
bswapSZs(&phdr->p_align); /* Segment alignment */
}
static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)

View File

@ -137,11 +137,11 @@ void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
pci_map_irq_fn map_irq);
/* TODO: add this define to pci_regs.h in linux and then in qemu. */
#define PCI_BRIDGE_CTL_VGA_16BIT 0x10 /* VGA 16-bit decode */
#define PCI_BRIDGE_CTL_DISCARD 0x100 /* Primary discard timer */
#define PCI_BRIDGE_CTL_SEC_DISCARD 0x200 /* Secondary discard timer */
#define PCI_BRIDGE_CTL_DISCARD_STATUS 0x400 /* Discard timer status */
#define PCI_BRIDGE_CTL_DISCARD_SERR 0x800 /* Discard timer SERR# enable */
#define PCI_BRIDGE_CTL_VGA_16BIT 0x10 /* VGA 16-bit decode */
#define PCI_BRIDGE_CTL_DISCARD 0x100 /* Primary discard timer */
#define PCI_BRIDGE_CTL_SEC_DISCARD 0x200 /* Secondary discard timer */
#define PCI_BRIDGE_CTL_DISCARD_STATUS 0x400 /* Discard timer status */
#define PCI_BRIDGE_CTL_DISCARD_SERR 0x800 /* Discard timer SERR# enable */
typedef struct PCIBridgeQemuCap {
uint8_t id; /* Standard PCI capability header field */

View File

@ -43,22 +43,22 @@ struct PCMCIACardClass {
void (*io_write)(PCMCIACardState *card, uint32_t address, uint16_t value);
};
#define CISTPL_DEVICE 0x01 /* 5V Device Information Tuple */
#define CISTPL_NO_LINK 0x14 /* No Link Tuple */
#define CISTPL_VERS_1 0x15 /* Level 1 Version Tuple */
#define CISTPL_JEDEC_C 0x18 /* JEDEC ID Tuple */
#define CISTPL_JEDEC_A 0x19 /* JEDEC ID Tuple */
#define CISTPL_CONFIG 0x1a /* Configuration Tuple */
#define CISTPL_CFTABLE_ENTRY 0x1b /* 16-bit PCCard Configuration */
#define CISTPL_DEVICE_OC 0x1c /* Additional Device Information */
#define CISTPL_DEVICE_OA 0x1d /* Additional Device Information */
#define CISTPL_DEVICE_GEO 0x1e /* Additional Device Information */
#define CISTPL_DEVICE_GEO_A 0x1f /* Additional Device Information */
#define CISTPL_MANFID 0x20 /* Manufacture ID Tuple */
#define CISTPL_FUNCID 0x21 /* Function ID Tuple */
#define CISTPL_FUNCE 0x22 /* Function Extension Tuple */
#define CISTPL_END 0xff /* Tuple End */
#define CISTPL_ENDMARK 0xff
#define CISTPL_DEVICE 0x01 /* 5V Device Information Tuple */
#define CISTPL_NO_LINK 0x14 /* No Link Tuple */
#define CISTPL_VERS_1 0x15 /* Level 1 Version Tuple */
#define CISTPL_JEDEC_C 0x18 /* JEDEC ID Tuple */
#define CISTPL_JEDEC_A 0x19 /* JEDEC ID Tuple */
#define CISTPL_CONFIG 0x1a /* Configuration Tuple */
#define CISTPL_CFTABLE_ENTRY 0x1b /* 16-bit PCCard Configuration */
#define CISTPL_DEVICE_OC 0x1c /* Additional Device Information */
#define CISTPL_DEVICE_OA 0x1d /* Additional Device Information */
#define CISTPL_DEVICE_GEO 0x1e /* Additional Device Information */
#define CISTPL_DEVICE_GEO_A 0x1f /* Additional Device Information */
#define CISTPL_MANFID 0x20 /* Manufacture ID Tuple */
#define CISTPL_FUNCID 0x21 /* Function ID Tuple */
#define CISTPL_FUNCE 0x22 /* Function Extension Tuple */
#define CISTPL_END 0xff /* Tuple End */
#define CISTPL_ENDMARK 0xff
/* dscm1xxxx.c */
PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv);

View File

@ -8,7 +8,7 @@
#include "qemu/notify.h"
#include "qom/object.h"
#define MAX_SCSI_DEVS 255
#define MAX_SCSI_DEVS 255
typedef struct SCSIBus SCSIBus;
typedef struct SCSIBusInfo SCSIBusInfo;

View File

@ -77,10 +77,10 @@ typedef enum {
typedef enum {
sd_none = -1,
sd_bc = 0, /* broadcast -- no response */
sd_bcr, /* broadcast with response */
sd_ac, /* addressed -- no data transfer */
sd_adtc, /* addressed with data transfer */
sd_bc = 0, /* broadcast -- no response */
sd_bcr, /* broadcast with response */
sd_ac, /* addressed -- no data transfer */
sd_adtc, /* addressed with data transfer */
} sd_cmd_type_t;
typedef struct {

View File

@ -29,7 +29,7 @@
* vhost-user to advertise VHOST_USER_F_PROTOCOL_FEATURES between QEMU
* and a vhost-user backend.
*/
#define VIRTIO_F_BAD_FEATURE 30
#define VIRTIO_F_BAD_FEATURE 30
#define VIRTIO_LEGACY_FEATURES ((0x1ULL << VIRTIO_F_BAD_FEATURE) | \
(0x1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | \

View File

@ -22,23 +22,23 @@
* Note that nbits should be always a compile time evaluable constant.
* Otherwise many inlines will generate horrible code.
*
* bitmap_zero(dst, nbits) *dst = 0UL
* bitmap_fill(dst, nbits) *dst = ~0UL
* bitmap_copy(dst, src, nbits) *dst = *src
* bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2
* bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2
* bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2
* bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2)
* bitmap_complement(dst, src, nbits) *dst = ~(*src)
* bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal?
* bitmap_zero(dst, nbits) *dst = 0UL
* bitmap_fill(dst, nbits) *dst = ~0UL
* bitmap_copy(dst, src, nbits) *dst = *src
* bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2
* bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2
* bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2
* bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2)
* bitmap_complement(dst, src, nbits) *dst = ~(*src)
* bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal?
* bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap?
* bitmap_empty(src, nbits) Are all bits zero in *src?
* bitmap_full(src, nbits) Are all bits set in *src?
* bitmap_set(dst, pos, nbits) Set specified bit area
* bitmap_set_atomic(dst, pos, nbits) Set specified bit area with atomic ops
* bitmap_clear(dst, pos, nbits) Clear specified bit area
* bitmap_empty(src, nbits) Are all bits zero in *src?
* bitmap_full(src, nbits) Are all bits set in *src?
* bitmap_set(dst, pos, nbits) Set specified bit area
* bitmap_set_atomic(dst, pos, nbits) Set specified bit area with atomic ops
* bitmap_clear(dst, pos, nbits) Clear specified bit area
* bitmap_test_and_clear_atomic(dst, pos, nbits) Test and clear area
* bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
* bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
* bitmap_to_le(dst, src, nbits) Convert bitmap to little endian
* bitmap_from_le(dst, src, nbits) Convert bitmap from little endian
* bitmap_copy_with_src_offset(dst, src, offset, nbits)
@ -50,17 +50,17 @@
/*
* Also the following operations apply to bitmaps.
*
* set_bit(bit, addr) *addr |= bit
* clear_bit(bit, addr) *addr &= ~bit
* change_bit(bit, addr) *addr ^= bit
* test_bit(bit, addr) Is bit set in *addr?
* test_and_set_bit(bit, addr) Set bit and return old value
* test_and_clear_bit(bit, addr) Clear bit and return old value
* test_and_change_bit(bit, addr) Change bit and return old value
* find_first_zero_bit(addr, nbits) Position first zero bit in *addr
* find_first_bit(addr, nbits) Position first set bit in *addr
* find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit
* find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
* set_bit(bit, addr) *addr |= bit
* clear_bit(bit, addr) *addr &= ~bit
* change_bit(bit, addr) *addr ^= bit
* test_bit(bit, addr) Is bit set in *addr?
* test_and_set_bit(bit, addr) Set bit and return old value
* test_and_clear_bit(bit, addr) Clear bit and return old value
* test_and_change_bit(bit, addr) Change bit and return old value
* find_first_zero_bit(addr, nbits) Position first zero bit in *addr
* find_first_bit(addr, nbits) Position first set bit in *addr
* find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit
* find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
*/
#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))

View File

@ -33,8 +33,8 @@
#ifndef glue
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
#define tostring(s) #s
#define stringify(s) tostring(s)
#define tostring(s) #s
#endif
#ifndef likely

View File

@ -237,7 +237,7 @@ extern "C" {
* supports QEMU_ERROR, this will be reported at compile time; otherwise
* this will be reported at link time due to the missing symbol.
*/
extern G_NORETURN
G_NORETURN extern
void QEMU_ERROR("code path is reachable")
qemu_build_not_reached_always(void);
#if defined(__OPTIMIZE__) && !defined(__NO_INLINE__)

View File

@ -59,16 +59,16 @@
* as described in RFC 2396 but separated for further processing.
*/
typedef struct URI {
char *scheme; /* the URI scheme */
char *opaque; /* opaque part */
char *authority; /* the authority part */
char *server; /* the server part */
char *user; /* the user part */
int port; /* the port number */
char *path; /* the path string */
char *fragment; /* the fragment identifier */
int cleanup; /* parsing potentially unclean URI */
char *query; /* the query string (as it appears in the URI) */
char *scheme; /* the URI scheme */
char *opaque; /* opaque part */
char *authority; /* the authority part */
char *server; /* the server part */
char *user; /* the user part */
int port; /* the port number */
char *path; /* the path string */
char *fragment; /* the fragment identifier */
int cleanup; /* parsing potentially unclean URI */
char *query; /* the query string (as it appears in the URI) */
} URI;
URI *uri_new(void);
@ -84,16 +84,16 @@ void uri_free(URI *uri);
/* Single web service query parameter 'name=value'. */
typedef struct QueryParam {
char *name; /* Name (unescaped). */
char *value; /* Value (unescaped). */
int ignore; /* Ignore this field in qparam_get_query */
char *name; /* Name (unescaped). */
char *value; /* Value (unescaped). */
int ignore; /* Ignore this field in qparam_get_query */
} QueryParam;
/* Set of parameters. */
typedef struct QueryParams {
int n; /* number of parameters used */
int alloc; /* allocated space */
QueryParam *p; /* array of parameters */
int n; /* number of parameters used */
int alloc; /* allocated space */
QueryParam *p; /* array of parameters */
} QueryParams;
struct QueryParams *query_params_new (int init_alloc);

View File

@ -34,8 +34,8 @@
#define FW_CFG_SETUP_SIZE 0x17
#define FW_CFG_SETUP_DATA 0x18
#define BIOS_CFG_IOPORT_CFG 0x510
#define BIOS_CFG_IOPORT_DATA 0x511
#define BIOS_CFG_IOPORT_CFG 0x510
#define BIOS_CFG_IOPORT_DATA 0x511
#define FW_CFG_DMA_CTL_ERROR 0x01
#define FW_CFG_DMA_CTL_READ 0x02
@ -49,65 +49,65 @@
#define BIOS_CFG_DMA_ADDR_LOW 0x518
/* Break the translation block flow so -d cpu shows us values */
#define DEBUG_HERE \
jmp 1f; \
1:
#define DEBUG_HERE \
jmp 1f; \
1:
/*
* Read a variable from the fw_cfg device.
* Clobbers: %edx
* Out: %eax
* Clobbers: %edx
* Out: %eax
*/
.macro read_fw VAR
mov $\VAR, %ax
mov $BIOS_CFG_IOPORT_CFG, %dx
outw %ax, (%dx)
mov $BIOS_CFG_IOPORT_DATA, %dx
inb (%dx), %al
shl $8, %eax
inb (%dx), %al
shl $8, %eax
inb (%dx), %al
shl $8, %eax
inb (%dx), %al
bswap %eax
mov $\VAR, %ax
mov $BIOS_CFG_IOPORT_CFG, %dx
outw %ax, (%dx)
mov $BIOS_CFG_IOPORT_DATA, %dx
inb (%dx), %al
shl $8, %eax
inb (%dx), %al
shl $8, %eax
inb (%dx), %al
shl $8, %eax
inb (%dx), %al
bswap %eax
.endm
/*
* Read data from the fw_cfg device using DMA.
* Clobbers: %edx, %eax, ADDR, SIZE, memory[%esp-16] to memory[%esp]
* Clobbers: %edx, %eax, ADDR, SIZE, memory[%esp-16] to memory[%esp]
*/
.macro read_fw_dma VAR, SIZE, ADDR
/* Address */
bswapl \ADDR
pushl \ADDR
bswapl \ADDR
pushl \ADDR
/* We only support 32 bit target addresses */
xorl %eax, %eax
pushl %eax
mov $BIOS_CFG_DMA_ADDR_HIGH, %dx
outl %eax, (%dx)
/* We only support 32 bit target addresses */
xorl %eax, %eax
pushl %eax
mov $BIOS_CFG_DMA_ADDR_HIGH, %dx
outl %eax, (%dx)
/* Size */
bswapl \SIZE
pushl \SIZE
/* Size */
bswapl \SIZE
pushl \SIZE
/* Control */
movl $(\VAR << 16) | (FW_CFG_DMA_CTL_READ | FW_CFG_DMA_CTL_SELECT), %eax
bswapl %eax
pushl %eax
movl $(\VAR << 16) | (FW_CFG_DMA_CTL_READ | FW_CFG_DMA_CTL_SELECT), %eax
bswapl %eax
pushl %eax
movl %esp, %eax /* Address of the struct we generated */
bswapl %eax
mov $BIOS_CFG_DMA_ADDR_LOW, %dx
outl %eax, (%dx) /* Initiate DMA */
movl %esp, %eax /* Address of the struct we generated */
bswapl %eax
mov $BIOS_CFG_DMA_ADDR_LOW, %dx
outl %eax, (%dx) /* Initiate DMA */
1: mov (%esp), %eax /* Wait for completion */
bswapl %eax
testl $~FW_CFG_DMA_CTL_ERROR, %eax
jnz 1b
addl $16, %esp
1: mov (%esp), %eax /* Wait for completion */
bswapl %eax
testl $~FW_CFG_DMA_CTL_ERROR, %eax
jnz 1b
addl $16, %esp
.endm
@ -115,116 +115,116 @@
* Read a blob from the fw_cfg device using DMA
* Requires _ADDR, _SIZE and _DATA values for the parameter.
*
* Clobbers: %eax, %edx, %es, %ecx, %edi and adresses %esp-20 to %esp
* Clobbers: %eax, %edx, %es, %ecx, %edi and adresses %esp-20 to %esp
*/
#ifdef USE_FW_CFG_DMA
#define read_fw_blob_dma(var) \
read_fw var ## _SIZE; \
mov %eax, %ecx; \
read_fw var ## _ADDR; \
mov %eax, %edi ;\
read_fw_dma var ## _DATA, %ecx, %edi
#define read_fw_blob_dma(var) \
read_fw var ## _SIZE; \
mov %eax, %ecx; \
read_fw var ## _ADDR; \
mov %eax, %edi ; \
read_fw_dma var ## _DATA, %ecx, %edi
#else
#define read_fw_blob_dma(var) read_fw_blob(var)
#endif
#define read_fw_blob_pre(var) \
read_fw var ## _SIZE; \
mov %eax, %ecx; \
mov $var ## _DATA, %ax; \
mov $BIOS_CFG_IOPORT_CFG, %edx; \
outw %ax, (%dx); \
mov $BIOS_CFG_IOPORT_DATA, %dx; \
cld
#define read_fw_blob_pre(var) \
read_fw var ## _SIZE; \
mov %eax, %ecx; \
mov $var ## _DATA, %ax; \
mov $BIOS_CFG_IOPORT_CFG, %edx; \
outw %ax, (%dx); \
mov $BIOS_CFG_IOPORT_DATA, %dx; \
cld
/*
* Read a blob from the fw_cfg device.
* Requires _ADDR, _SIZE and _DATA values for the parameter.
*
* Clobbers: %eax, %edx, %es, %ecx, %edi
* Clobbers: %eax, %edx, %es, %ecx, %edi
*/
#define read_fw_blob(var) \
read_fw var ## _ADDR; \
mov %eax, %edi; \
read_fw_blob_pre(var); \
/* old as(1) doesn't like this insn so emit the bytes instead: \
rep insb (%dx), %es:(%edi); \
*/ \
.dc.b 0xf3,0x6c
#define read_fw_blob(var) \
read_fw var ## _ADDR; \
mov %eax, %edi; \
read_fw_blob_pre(var); \
/* old as(1) doesn't like this insn so emit the bytes instead: \
rep insb (%dx), %es:(%edi); \
*/ \
.dc.b 0xf3,0x6c
/*
* Read a blob from the fw_cfg device in forced addr32 mode.
* Requires _ADDR, _SIZE and _DATA values for the parameter.
*
* Clobbers: %eax, %edx, %es, %ecx, %edi
* Clobbers: %eax, %edx, %es, %ecx, %edi
*/
#define read_fw_blob_addr32(var) \
read_fw var ## _ADDR; \
mov %eax, %edi; \
read_fw_blob_pre(var); \
/* old as(1) doesn't like this insn so emit the bytes instead: \
addr32 rep insb (%dx), %es:(%edi); \
*/ \
.dc.b 0x67,0xf3,0x6c
#define read_fw_blob_addr32(var) \
read_fw var ## _ADDR; \
mov %eax, %edi; \
read_fw_blob_pre(var); \
/* old as(1) doesn't like this insn so emit the bytes instead: \
addr32 rep insb (%dx), %es:(%edi); \
*/ \
.dc.b 0x67,0xf3,0x6c
/*
* Read a blob from the fw_cfg device in forced addr32 mode, address is in %edi.
* Requires _SIZE and _DATA values for the parameter.
*
* Clobbers: %eax, %edx, %edi, %es, %ecx
* Clobbers: %eax, %edx, %edi, %es, %ecx
*/
#define read_fw_blob_addr32_edi(var) \
read_fw_blob_pre(var); \
/* old as(1) doesn't like this insn so emit the bytes instead: \
addr32 rep insb (%dx), %es:(%edi); \
*/ \
.dc.b 0x67,0xf3,0x6c
#define read_fw_blob_addr32_edi(var) \
read_fw_blob_pre(var); \
/* old as(1) doesn't like this insn so emit the bytes instead: \
addr32 rep insb (%dx), %es:(%edi); \
*/ \
.dc.b 0x67,0xf3,0x6c
#define OPTION_ROM_START \
.code16; \
.text; \
.global _start; \
_start:; \
.short 0xaa55; \
.byte (_end - _start) / 512;
#define OPTION_ROM_START \
.code16; \
.text; \
.global _start; \
_start:; \
.short 0xaa55; \
.byte (_end - _start) / 512;
#define BOOT_ROM_START \
OPTION_ROM_START \
lret; \
.org 0x18; \
.short 0; \
.short _pnph; \
_pnph: \
.ascii "$PnP"; \
.byte 0x01; \
.byte ( _pnph_len / 16 ); \
.short 0x0000; \
.byte 0x00; \
.byte 0x00; \
.long 0x00000000; \
.short _manufacturer; \
.short _product; \
.long 0x00000000; \
.short 0x0000; \
.short 0x0000; \
.short _bev; \
.short 0x0000; \
.short 0x0000; \
.equ _pnph_len, . - _pnph; \
_bev:; \
/* DS = CS */ \
movw %cs, %ax; \
movw %ax, %ds;
#define BOOT_ROM_START \
OPTION_ROM_START \
lret; \
.org 0x18; \
.short 0; \
.short _pnph; \
_pnph: \
.ascii "$PnP"; \
.byte 0x01; \
.byte ( _pnph_len / 16 ); \
.short 0x0000; \
.byte 0x00; \
.byte 0x00; \
.long 0x00000000; \
.short _manufacturer; \
.short _product; \
.long 0x00000000; \
.short 0x0000; \
.short 0x0000; \
.short _bev; \
.short 0x0000; \
.short 0x0000; \
.equ _pnph_len, . - _pnph; \
_bev:; \
/* DS = CS */ \
movw %cs, %ax; \
movw %ax, %ds;
#define OPTION_ROM_END \
.byte 0; \
.align 512, 0; \
#define OPTION_ROM_END \
.byte 0; \
.align 512, 0; \
_end:
#define BOOT_ROM_END \
_manufacturer:; \
.asciz "QEMU"; \
_product:; \
.asciz BOOT_ROM_PRODUCT; \
OPTION_ROM_END
#define BOOT_ROM_END \
_manufacturer:; \
.asciz "QEMU"; \
_product:; \
.asciz BOOT_ROM_PRODUCT; \
OPTION_ROM_END

View File

@ -3175,7 +3175,7 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
* cache->xlat and the end of the section.
*/
diff = int128_sub(cache->mrs.size,
int128_make64(cache->xlat - cache->mrs.offset_within_region));
int128_make64(cache->xlat - cache->mrs.offset_within_region));
l = int128_get64(int128_min(diff, int128_make64(l)));
mr = cache->mrs.mr;

View File

@ -41,6 +41,26 @@
#define CR0_RESET 0xE0UL
#define CR14_RESET 0xC2000000UL;
#ifndef CONFIG_USER_ONLY
static bool is_early_exception_psw(uint64_t mask, uint64_t addr)
{
if (mask & PSW_MASK_RESERVED) {
return true;
}
switch (mask & (PSW_MASK_32 | PSW_MASK_64)) {
case 0:
return addr & ~0xffffffULL;
case PSW_MASK_32:
return addr & ~0x7fffffffULL;
case PSW_MASK_32 | PSW_MASK_64:
return false;
default: /* PSW_MASK_64 */
return true;
}
}
#endif
void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
{
#ifndef CONFIG_USER_ONLY
@ -57,6 +77,12 @@ void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
env->cc_op = (mask >> 44) & 3;
#ifndef CONFIG_USER_ONLY
if (is_early_exception_psw(mask, addr)) {
env->int_pgm_ilen = 0;
trigger_pgm_exception(env, PGM_SPECIFICATION);
return;
}
if ((old_mask ^ mask) & PSW_MASK_PER) {
s390_cpu_recompute_watchpoints(env_cpu(env));
}

View File

@ -29,6 +29,7 @@
#include "cpu_models.h"
#include "exec/cpu-defs.h"
#include "qemu/cpu-float.h"
#include "tcg/tcg_s390x.h"
#define ELF_MACHINE_UNAME "S390X"
@ -87,6 +88,7 @@ struct CPUArchState {
uint64_t cc_vr;
uint64_t ex_value;
uint64_t ex_target;
uint64_t __excp_addr;
uint64_t psa;
@ -292,6 +294,7 @@ extern const VMStateDescription vmstate_s390_cpu;
#define PSW_MASK_32 0x0000000080000000ULL
#define PSW_MASK_SHORT_ADDR 0x000000007fffffffULL
#define PSW_MASK_SHORT_CTRL 0xffffffff80000000ULL
#define PSW_MASK_RESERVED 0xb80800fe7fffffffULL
#undef PSW_ASC_PRIMARY
#undef PSW_ASC_ACCREG
@ -381,6 +384,14 @@ static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch)
static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
target_ulong *cs_base, uint32_t *flags)
{
if (env->psw.addr & 1) {
/*
* Instructions must be at even addresses.
* This needs to be checked before address translation.
*/
env->int_pgm_ilen = 2; /* see s390_cpu_tlb_fill() */
tcg_s390_program_interrupt(env, PGM_SPECIFICATION, 0);
}
*pc = env->psw.addr;
*cs_base = env->ex_value;
*flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;

View File

@ -85,8 +85,8 @@ void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
/*
* Unaligned accesses are only diagnosed with MO_ALIGN. At the moment,
* this is only for the atomic operations, for which we want to raise a
* specification exception.
* this is only for the atomic and relative long operations, for which we want
* to raise a specification exception.
*/
static G_NORETURN
void do_unaligned_access(CPUState *cs, uintptr_t retaddr)
@ -212,7 +212,8 @@ static void do_program_interrupt(CPUS390XState *env)
LowCore *lowcore;
int ilen = env->int_pgm_ilen;
assert(ilen == 2 || ilen == 4 || ilen == 6);
assert((env->int_pgm_code == PGM_SPECIFICATION && ilen == 0) ||
ilen == 2 || ilen == 4 || ilen == 6);
switch (env->int_pgm_code) {
case PGM_PER:

View File

@ -410,12 +410,12 @@
/* LOAD */
C(0x1800, LR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, 0)
C(0x5800, L, RX_a, Z, 0, a2, new, r1_32, ld32s, 0)
C(0xe358, LY, RXY_a, LD, 0, a2, new, r1_32, ld32s, 0)
D(0x5800, L, RX_a, Z, 0, a2, new, r1_32, ld32s, 0, 0)
D(0xe358, LY, RXY_a, LD, 0, a2, new, r1_32, ld32s, 0, 0)
C(0xb904, LGR, RRE, Z, 0, r2_o, 0, r1, mov2, 0)
C(0xb914, LGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, 0)
C(0xe304, LG, RXY_a, Z, 0, a2, r1, 0, ld64, 0)
C(0xe314, LGF, RXY_a, Z, 0, a2, r1, 0, ld32s, 0)
D(0xe304, LG, RXY_a, Z, 0, a2, r1, 0, ld64, 0, 0)
D(0xe314, LGF, RXY_a, Z, 0, a2, r1, 0, ld32s, 0, 0)
F(0x2800, LDR, RR_a, Z, 0, f2, 0, f1, mov2, 0, IF_AFP1 | IF_AFP2)
F(0x6800, LD, RX_a, Z, 0, m2_64, 0, f1, mov2, 0, IF_AFP1)
F(0xed65, LDY, RXY_a, LD, 0, m2_64, 0, f1, mov2, 0, IF_AFP1)
@ -426,9 +426,9 @@
/* LOAD IMMEDIATE */
C(0xc001, LGFI, RIL_a, EI, 0, i2, 0, r1, mov2, 0)
/* LOAD RELATIVE LONG */
C(0xc40d, LRL, RIL_b, GIE, 0, ri2, new, r1_32, ld32s, 0)
C(0xc408, LGRL, RIL_b, GIE, 0, ri2, r1, 0, ld64, 0)
C(0xc40c, LGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32s, 0)
D(0xc40d, LRL, RIL_b, GIE, 0, ri2, new, r1_32, ld32s, 0, MO_ALIGN)
D(0xc408, LGRL, RIL_b, GIE, 0, ri2, r1, 0, ld64, 0, MO_ALIGN)
D(0xc40c, LGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32s, 0, MO_ALIGN)
/* LOAD ADDRESS */
C(0x4100, LA, RX_a, Z, 0, a2, 0, r1, mov2, 0)
C(0xe371, LAY, RXY_a, LD, 0, a2, 0, r1, mov2, 0)
@ -456,9 +456,9 @@
C(0x1200, LTR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, s32)
C(0xb902, LTGR, RRE, Z, 0, r2_o, 0, r1, mov2, s64)
C(0xb912, LTGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, s64)
C(0xe312, LT, RXY_a, EI, 0, a2, new, r1_32, ld32s, s64)
C(0xe302, LTG, RXY_a, EI, 0, a2, r1, 0, ld64, s64)
C(0xe332, LTGF, RXY_a, GIE, 0, a2, r1, 0, ld32s, s64)
D(0xe312, LT, RXY_a, EI, 0, a2, new, r1_32, ld32s, s64, 0)
D(0xe302, LTG, RXY_a, EI, 0, a2, r1, 0, ld64, s64, 0)
D(0xe332, LTGF, RXY_a, GIE, 0, a2, r1, 0, ld32s, s64, 0)
F(0xb302, LTEBR, RRE, Z, 0, e2, 0, cond_e1e2, mov2, f32, IF_BFP)
F(0xb312, LTDBR, RRE, Z, 0, f2, 0, f1, mov2, f64, IF_BFP)
F(0xb342, LTXBR, RRE, Z, x2h, x2l, 0, x1_P, movx, f128, IF_BFP)
@ -502,16 +502,16 @@
C(0xc405, LHRL, RIL_b, GIE, 0, ri2, new, r1_32, ld16s, 0)
C(0xc404, LGHRL, RIL_b, GIE, 0, ri2, r1, 0, ld16s, 0)
/* LOAD HIGH */
C(0xe3ca, LFH, RXY_a, HW, 0, a2, new, r1_32h, ld32u, 0)
D(0xe3ca, LFH, RXY_a, HW, 0, a2, new, r1_32h, ld32u, 0, 0)
/* LOAG HIGH AND TRAP */
C(0xe3c8, LFHAT, RXY_a, LAT, 0, m2_32u, r1, 0, lfhat, 0)
/* LOAD LOGICAL */
C(0xb916, LLGFR, RRE, Z, 0, r2_32u, 0, r1, mov2, 0)
C(0xe316, LLGF, RXY_a, Z, 0, a2, r1, 0, ld32u, 0)
D(0xe316, LLGF, RXY_a, Z, 0, a2, r1, 0, ld32u, 0, 0)
/* LOAD LOGICAL AND TRAP */
C(0xe39d, LLGFAT, RXY_a, LAT, 0, a2, r1, 0, llgfat, 0)
/* LOAD LOGICAL RELATIVE LONG */
C(0xc40e, LLGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32u, 0)
D(0xc40e, LLGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32u, 0, MO_ALIGN)
/* LOAD LOGICAL CHARACTER */
C(0xb994, LLCR, RRE, EI, 0, r2_8u, 0, r1_32, mov2, 0)
C(0xb984, LLGCR, RRE, EI, 0, r2_8u, 0, r1, mov2, 0)
@ -840,16 +840,16 @@
F(0xed15, SQDB, RXE, Z, 0, m2_64, new, f1, sqdb, 0, IF_BFP)
/* STORE */
C(0x5000, ST, RX_a, Z, r1_o, a2, 0, 0, st32, 0)
C(0xe350, STY, RXY_a, LD, r1_o, a2, 0, 0, st32, 0)
C(0xe324, STG, RXY_a, Z, r1_o, a2, 0, 0, st64, 0)
F(0x6000, STD, RX_a, Z, f1, a2, 0, 0, st64, 0, IF_AFP1)
F(0xed67, STDY, RXY_a, LD, f1, a2, 0, 0, st64, 0, IF_AFP1)
F(0x7000, STE, RX_a, Z, e1, a2, 0, 0, st32, 0, IF_AFP1)
F(0xed66, STEY, RXY_a, LD, e1, a2, 0, 0, st32, 0, IF_AFP1)
D(0x5000, ST, RX_a, Z, r1_o, a2, 0, 0, st32, 0, 0)
D(0xe350, STY, RXY_a, LD, r1_o, a2, 0, 0, st32, 0, 0)
D(0xe324, STG, RXY_a, Z, r1_o, a2, 0, 0, st64, 0, 0)
E(0x6000, STD, RX_a, Z, f1, a2, 0, 0, st64, 0, 0, IF_AFP1)
E(0xed67, STDY, RXY_a, LD, f1, a2, 0, 0, st64, 0, 0, IF_AFP1)
E(0x7000, STE, RX_a, Z, e1, a2, 0, 0, st32, 0, 0, IF_AFP1)
E(0xed66, STEY, RXY_a, LD, e1, a2, 0, 0, st32, 0, 0, IF_AFP1)
/* STORE RELATIVE LONG */
C(0xc40f, STRL, RIL_b, GIE, r1_o, ri2, 0, 0, st32, 0)
C(0xc40b, STGRL, RIL_b, GIE, r1_o, ri2, 0, 0, st64, 0)
D(0xc40f, STRL, RIL_b, GIE, r1_o, ri2, 0, 0, st32, 0, MO_ALIGN)
D(0xc40b, STGRL, RIL_b, GIE, r1_o, ri2, 0, 0, st64, 0, MO_ALIGN)
/* STORE CHARACTER */
C(0x4200, STC, RX_a, Z, r1_o, a2, 0, 0, st8, 0)
C(0xe372, STCY, RXY_a, LD, r1_o, a2, 0, 0, st8, 0)
@ -867,7 +867,7 @@
/* STORE HALFWORD RELATIVE LONG */
C(0xc407, STHRL, RIL_b, GIE, r1_o, ri2, 0, 0, st16, 0)
/* STORE HIGH */
C(0xe3cb, STFH, RXY_a, HW, r1_sr32, a2, 0, 0, st32, 0)
D(0xe3cb, STFH, RXY_a, HW, r1_sr32, a2, 0, 0, st32, 0, 0)
/* STORE ON CONDITION */
D(0xebf3, STOC, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 0)
D(0xebe3, STOCG, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 1)

View File

@ -149,7 +149,6 @@ static inline int s390_probe_access(CPUArchState *env, target_ulong addr,
nonfault, phost, ra);
if (unlikely(flags & TLB_INVALID_MASK)) {
assert(!nonfault);
#ifdef CONFIG_USER_ONLY
/* Address is in TEC in system mode; see s390_cpu_record_sigsegv. */
env->__excp_addr = addr & TARGET_PAGE_MASK;
@ -2468,8 +2467,16 @@ void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
*/
void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
{
uint64_t insn = cpu_lduw_code(env, addr);
uint8_t opc = insn >> 8;
uint64_t insn;
uint8_t opc;
/* EXECUTE targets must be at even addresses. */
if (addr & 1) {
tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
}
insn = cpu_lduw_code(env, addr);
opc = insn >> 8;
/* Or in the contents of R1[56:63]. */
insn |= r1 & 0xff;
@ -2530,6 +2537,7 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
that ex_value is non-zero, which flags that we are in a state
that requires such execution. */
env->ex_value = insn | ilen;
env->ex_target = addr;
}
uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,

View File

@ -2770,19 +2770,22 @@ static DisasJumpType op_ld16u(DisasContext *s, DisasOps *o)
static DisasJumpType op_ld32s(DisasContext *s, DisasOps *o)
{
tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s));
tcg_gen_qemu_ld_tl(o->out, o->in2, get_mem_index(s),
MO_TESL | s->insn->data);
return DISAS_NEXT;
}
static DisasJumpType op_ld32u(DisasContext *s, DisasOps *o)
{
tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
tcg_gen_qemu_ld_tl(o->out, o->in2, get_mem_index(s),
MO_TEUL | s->insn->data);
return DISAS_NEXT;
}
static DisasJumpType op_ld64(DisasContext *s, DisasOps *o)
{
tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s),
MO_TEUQ | s->insn->data);
return DISAS_NEXT;
}
@ -2910,19 +2913,21 @@ static DisasJumpType op_lpp(DisasContext *s, DisasOps *o)
static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o)
{
TCGv_i64 t1, t2;
TCGv_i64 mask, addr;
per_breaking_event(s);
t1 = tcg_temp_new_i64();
t2 = tcg_temp_new_i64();
tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s),
MO_TEUL | MO_ALIGN_8);
tcg_gen_addi_i64(o->in2, o->in2, 4);
tcg_gen_qemu_ld32u(t2, o->in2, get_mem_index(s));
/* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK. */
tcg_gen_shli_i64(t1, t1, 32);
gen_helper_load_psw(cpu_env, t1, t2);
/*
* Convert the short PSW into the normal PSW, similar to what
* s390_cpu_load_normal() does.
*/
mask = tcg_temp_new_i64();
addr = tcg_temp_new_i64();
tcg_gen_qemu_ld_i64(mask, o->in2, get_mem_index(s), MO_TEUQ | MO_ALIGN_8);
tcg_gen_andi_i64(addr, mask, PSW_MASK_SHORT_ADDR);
tcg_gen_andi_i64(mask, mask, PSW_MASK_SHORT_CTRL);
tcg_gen_xori_i64(mask, mask, PSW_MASK_SHORTPSW);
gen_helper_load_psw(cpu_env, mask, addr);
return DISAS_NORETURN;
}
@ -3695,11 +3700,15 @@ static DisasJumpType op_rosbg(DisasContext *s, DisasOps *o)
int i3 = get_field(s, i3);
int i4 = get_field(s, i4);
int i5 = get_field(s, i5);
TCGv_i64 orig_out;
uint64_t mask;
/* If this is a test-only form, arrange to discard the result. */
if (i3 & 0x80) {
tcg_debug_assert(o->out != NULL);
orig_out = o->out;
o->out = tcg_temp_new_i64();
tcg_gen_mov_i64(o->out, orig_out);
}
i3 &= 63;
@ -4066,9 +4075,23 @@ static DisasJumpType op_sske(DisasContext *s, DisasOps *o)
return DISAS_NEXT;
}
static void gen_check_psw_mask(DisasContext *s)
{
TCGv_i64 reserved = tcg_temp_new_i64();
TCGLabel *ok = gen_new_label();
tcg_gen_andi_i64(reserved, psw_mask, PSW_MASK_RESERVED);
tcg_gen_brcondi_i64(TCG_COND_EQ, reserved, 0, ok);
gen_program_exception(s, PGM_SPECIFICATION);
gen_set_label(ok);
}
static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
{
tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
gen_check_psw_mask(s);
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
s->exit_to_mainloop = true;
return DISAS_TOO_MANY;
@ -4329,6 +4352,8 @@ static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
}
gen_check_psw_mask(s);
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
s->exit_to_mainloop = true;
return DISAS_TOO_MANY;
@ -4367,13 +4392,15 @@ static DisasJumpType op_st16(DisasContext *s, DisasOps *o)
static DisasJumpType op_st32(DisasContext *s, DisasOps *o)
{
tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
tcg_gen_qemu_st_tl(o->in1, o->in2, get_mem_index(s),
MO_TEUL | s->insn->data);
return DISAS_NEXT;
}
static DisasJumpType op_st64(DisasContext *s, DisasOps *o)
{
tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s),
MO_TEUQ | s->insn->data);
return DISAS_NEXT;
}
@ -5747,7 +5774,18 @@ static void in2_a2(DisasContext *s, DisasOps *o)
static TCGv gen_ri2(DisasContext *s)
{
return tcg_constant_i64(s->base.pc_next + (int64_t)get_field(s, i2) * 2);
int64_t delta = (int64_t)get_field(s, i2) * 2;
TCGv ri2;
if (unlikely(s->ex_value)) {
ri2 = tcg_temp_new_i64();
tcg_gen_ld_i64(ri2, cpu_env, offsetof(CPUS390XState, ex_target));
tcg_gen_addi_i64(ri2, ri2, delta);
} else {
ri2 = tcg_constant_i64(s->base.pc_next + delta);
}
return ri2;
}
static void in2_ri2(DisasContext *s, DisasOps *o)
@ -5855,21 +5893,24 @@ static void in2_mri2_16u(DisasContext *s, DisasOps *o)
static void in2_mri2_32s(DisasContext *s, DisasOps *o)
{
o->in2 = tcg_temp_new_i64();
tcg_gen_qemu_ld32s(o->in2, gen_ri2(s), get_mem_index(s));
tcg_gen_qemu_ld_tl(o->in2, gen_ri2(s), get_mem_index(s),
MO_TESL | MO_ALIGN);
}
#define SPEC_in2_mri2_32s 0
static void in2_mri2_32u(DisasContext *s, DisasOps *o)
{
o->in2 = tcg_temp_new_i64();
tcg_gen_qemu_ld32u(o->in2, gen_ri2(s), get_mem_index(s));
tcg_gen_qemu_ld_tl(o->in2, gen_ri2(s), get_mem_index(s),
MO_TEUL | MO_ALIGN);
}
#define SPEC_in2_mri2_32u 0
static void in2_mri2_64(DisasContext *s, DisasOps *o)
{
o->in2 = tcg_temp_new_i64();
tcg_gen_qemu_ld64(o->in2, gen_ri2(s), get_mem_index(s));
tcg_gen_qemu_ld_i64(o->in2, gen_ri2(s), get_mem_index(s),
MO_TEUQ | MO_ALIGN);
}
#define SPEC_in2_mri2_64 0

View File

@ -1,11 +1,25 @@
S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
VPATH+=$(S390X_SRC)
QEMU_OPTS=-action panic=exit-failure -kernel
LINK_SCRIPT=$(S390X_SRC)/softmmu.ld
LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT) -Wl,--build-id=none
%: %.S
$(CC) -march=z13 -m64 -nostdlib -static -Wl,-Ttext=0 \
-Wl,--build-id=none $< -o $@
%.o: %.S
$(CC) -march=z13 -m64 -c $< -o $@
%: %.o $(LINK_SCRIPT)
$(CC) $< -o $@ $(LDFLAGS)
TESTS += unaligned-lowcore
TESTS += bal
TESTS += sam
TESTS += lpsw
TESTS += lpswe-early
TESTS += ssm-early
TESTS += stosm-early
TESTS += exrl-ssm-early
include $(S390X_SRC)/pgm-specification.mak
$(PGM_SPECIFICATION_TESTS): pgm-specification-softmmu.o
$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-softmmu.o
TESTS += $(PGM_SPECIFICATION_TESTS)

View File

@ -2,6 +2,9 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
VPATH+=$(S390X_SRC)
CFLAGS+=-march=zEC12 -m64
%.o: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
config-cc.mak: Makefile
$(quiet-@)( \
$(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \
@ -29,10 +32,19 @@ TESTS+=clst
TESTS+=long-double
TESTS+=cdsg
TESTS+=chrl
TESTS+=rxsbg
TESTS+=ex-relative-long
cdsg: CFLAGS+=-pthread
cdsg: LDFLAGS+=-pthread
rxsbg: CFLAGS+=-O2
include $(S390X_SRC)/pgm-specification.mak
$(PGM_SPECIFICATION_TESTS): pgm-specification-user.o
$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o
TESTS += $(PGM_SPECIFICATION_TESTS)
Z13_TESTS=vistr
$(Z13_TESTS): CFLAGS+=-march=z13 -O2
TESTS+=$(Z13_TESTS)

16
tests/tcg/s390x/br-odd.S Normal file
View File

@ -0,0 +1,16 @@
/*
* Test BRanching to a non-mapped odd address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
lgrl %r1,odd_addr
br %r1
.align 8
odd_addr:
.quad 0xDDDDDDDDDDDDDDDD
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,0xDDDDDDDDDDDDDDDD

View File

@ -0,0 +1,16 @@
/*
* Test CGRL with a non-doubleword aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
cgrl %r1,unaligned
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,test
.long 0
unaligned:
.quad 0

View File

@ -0,0 +1,16 @@
/*
* Test CLRL with a non-word aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
clrl %r1,unaligned
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,test
.short 0
unaligned:
.long 0

View File

@ -0,0 +1,16 @@
/*
* Test CRL with a non-word aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
crl %r1,unaligned
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,test
.short 0
unaligned:
.long 0

17
tests/tcg/s390x/ex-odd.S Normal file
View File

@ -0,0 +1,17 @@
/*
* Test EXECUTing a non-mapped odd address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
lgrl %r1,odd_addr
fail:
ex 0,0(%r1)
.align 8
odd_addr:
.quad 0xDDDDDDDDDDDDDDDD
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,fail

View File

@ -0,0 +1,156 @@
/* Check EXECUTE with relative long instructions as targets. */
#include <stdlib.h>
#include <stdio.h>
struct test {
const char *name;
long (*func)(long reg, long *cc);
long exp_reg;
long exp_mem;
long exp_cc;
};
/*
* Each test sets the MEM_IDXth element of the mem array to MEM and uses a
* single relative long instruction on it. The other elements remain zero.
* This is in order to prevent stumbling upon MEM in random memory in case
* there is an off-by-a-small-value bug.
*
* Note that while gcc supports the ZL constraint for relative long operands,
* clang doesn't, so the assembly code accesses mem[MEM_IDX] using MEM_ASM.
*/
static long mem[0x1000];
#define MEM_IDX 0x800
#define MEM_ASM "mem+0x800*8"
/* Initial %r2 value. */
#define REG 0x1234567887654321
/* Initial mem[MEM_IDX] value. */
#define MEM 0xfedcba9889abcdef
/* Initial cc value. */
#define CC 0
/* Relative long instructions and their expected effects. */
#define FOR_EACH_INSN(F) \
F(cgfrl, REG, MEM, 2) \
F(cghrl, REG, MEM, 2) \
F(cgrl, REG, MEM, 2) \
F(chrl, REG, MEM, 1) \
F(clgfrl, REG, MEM, 2) \
F(clghrl, REG, MEM, 2) \
F(clgrl, REG, MEM, 1) \
F(clhrl, REG, MEM, 2) \
F(clrl, REG, MEM, 1) \
F(crl, REG, MEM, 1) \
F(larl, (long)&mem[MEM_IDX], MEM, CC) \
F(lgfrl, 0xfffffffffedcba98, MEM, CC) \
F(lghrl, 0xfffffffffffffedc, MEM, CC) \
F(lgrl, MEM, MEM, CC) \
F(lhrl, 0x12345678fffffedc, MEM, CC) \
F(llghrl, 0x000000000000fedc, MEM, CC) \
F(llhrl, 0x123456780000fedc, MEM, CC) \
F(lrl, 0x12345678fedcba98, MEM, CC) \
F(stgrl, REG, REG, CC) \
F(sthrl, REG, 0x4321ba9889abcdef, CC) \
F(strl, REG, 0x8765432189abcdef, CC)
/* Test functions. */
#define DEFINE_EX_TEST(insn, exp_reg, exp_mem, exp_cc) \
static long test_ex_ ## insn(long reg, long *cc) \
{ \
register long r2 asm("r2"); \
char mask = 0x20; /* make target use %r2 */ \
long pm, target; \
\
r2 = reg; \
asm("larl %[target],0f\n" \
"cr %%r0,%%r0\n" /* initial cc */ \
"ex %[mask],0(%[target])\n" \
"jg 1f\n" \
"0: " #insn " %%r0," MEM_ASM "\n" \
"1: ipm %[pm]\n" \
: [target] "=&a" (target), [r2] "+r" (r2), [pm] "=r" (pm) \
: [mask] "a" (mask) \
: "cc", "memory"); \
reg = r2; \
*cc = (pm >> 28) & 3; \
\
return reg; \
}
#define DEFINE_EXRL_TEST(insn, exp_reg, exp_mem, exp_cc) \
static long test_exrl_ ## insn(long reg, long *cc) \
{ \
register long r2 asm("r2"); \
char mask = 0x20; /* make target use %r2 */ \
long pm; \
\
r2 = reg; \
asm("cr %%r0,%%r0\n" /* initial cc */ \
"exrl %[mask],0f\n" \
"jg 1f\n" \
"0: " #insn " %%r0," MEM_ASM "\n" \
"1: ipm %[pm]\n" \
: [r2] "+r" (r2), [pm] "=r" (pm) \
: [mask] "a" (mask) \
: "cc", "memory"); \
reg = r2; \
*cc = (pm >> 28) & 3; \
\
return reg; \
}
FOR_EACH_INSN(DEFINE_EX_TEST)
FOR_EACH_INSN(DEFINE_EXRL_TEST)
/* Test definitions. */
#define REGISTER_EX_EXRL_TEST(ex_insn, insn, _exp_reg, _exp_mem, _exp_cc) \
{ \
.name = #ex_insn " " #insn, \
.func = test_ ## ex_insn ## _ ## insn, \
.exp_reg = (_exp_reg), \
.exp_mem = (_exp_mem), \
.exp_cc = (_exp_cc), \
},
#define REGISTER_EX_TEST(insn, exp_reg, exp_mem, exp_cc) \
REGISTER_EX_EXRL_TEST(ex, insn, exp_reg, exp_mem, exp_cc)
#define REGISTER_EXRL_TEST(insn, exp_reg, exp_mem, exp_cc) \
REGISTER_EX_EXRL_TEST(exrl, insn, exp_reg, exp_mem, exp_cc)
static const struct test tests[] = {
FOR_EACH_INSN(REGISTER_EX_TEST)
FOR_EACH_INSN(REGISTER_EXRL_TEST)
};
/* Loop over all tests and run them. */
int main(void)
{
const struct test *test;
int ret = EXIT_SUCCESS;
long reg, cc;
size_t i;
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
test = &tests[i];
mem[MEM_IDX] = MEM;
cc = -1;
reg = test->func(REG, &cc);
#define ASSERT_EQ(expected, actual) do { \
if (expected != actual) { \
fprintf(stderr, "%s: " #expected " (0x%lx) != " #actual " (0x%lx)\n", \
test->name, expected, actual); \
ret = EXIT_FAILURE; \
} \
} while (0)
ASSERT_EQ(test->exp_reg, reg);
ASSERT_EQ(test->exp_mem, mem[MEM_IDX]);
ASSERT_EQ(test->exp_cc, cc);
#undef ASSERT_EQ
}
return ret;
}

View File

@ -0,0 +1,43 @@
/*
* Test early exception recognition using EXRL + SSM.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.org 0x8d
ilc:
.org 0x8e
program_interruption_code:
.org 0x150
program_old_psw:
.org 0x1D0 /* program new PSW */
.quad 0,pgm
.org 0x200 /* lowcore padding */
.globl _start
_start:
exrl %r0,ssm
expected_pswa:
j failure
ssm:
ssm ssm_op
pgm:
chhsi program_interruption_code,0x6 /* specification exception? */
jne failure
cli ilc,6 /* ilc for EXRL? */
jne failure
clc program_old_psw(16),expected_old_psw /* correct old PSW? */
jne failure
lpswe success_psw
failure:
lpswe failure_psw
ssm_op:
.byte 0x08 /* bit 4 set */
.align 8
expected_old_psw:
.quad 0x0800000180000000,expected_pswa /* bit 2 set */
success_psw:
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
failure_psw:
.quad 0x2000000000000,0 /* disabled wait */

View File

@ -0,0 +1,16 @@
/*
* Test LGRL from a non-doubleword aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
lgrl %r1,unaligned
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,test
.long 0
unaligned:
.quad 0

View File

@ -0,0 +1,16 @@
/*
* Test LLGFRL from a non-word aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
llgfrl %r1,unaligned
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,test
.short 0
unaligned:
.long 0

36
tests/tcg/s390x/lpsw.S Normal file
View File

@ -0,0 +1,36 @@
/*
* Test the LPSW instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.org 0x140
svc_old_psw:
.org 0x1c0 /* supervisor call new PSW */
.quad 0x80000000,svc /* 31-bit mode */
.org 0x200 /* lowcore padding */
.globl _start
_start:
lpsw short_psw
lpsw_target:
svc 0
expected_pswa:
j failure
svc:
clc svc_old_psw(16),expected_psw /* correct full PSW? */
jne failure
lpswe success_psw
failure:
lpswe failure_psw
.align 8
short_psw:
.long 0x90001,0x80000000+lpsw_target /* problem state,
64-bit mode */
expected_psw:
.quad 0x1000180000000,expected_pswa /* corresponds to short_psw */
success_psw:
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
failure_psw:
.quad 0x2000000000000,0 /* disabled wait */

View File

@ -0,0 +1,38 @@
/*
* Test early exception recognition using LPSWE.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.org 0x8d
ilc:
.org 0x8e
program_interruption_code:
.org 0x150
program_old_psw:
.org 0x1D0 /* program new PSW */
.quad 0,pgm
.org 0x200 /* lowcore padding */
.globl _start
_start:
lpswe bad_psw
j failure
pgm:
chhsi program_interruption_code,0x6 /* specification exception? */
jne failure
cli ilc,0 /* ilc zero? */
jne failure
clc program_old_psw(16),bad_psw /* correct old PSW? */
jne failure
lpswe success_psw
failure:
lpswe failure_psw
.align 8
bad_psw:
.quad 0x8000000000000000,0xfedcba9876543210 /* bit 0 set */
success_psw:
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
failure_psw:
.quad 0x2000000000000,0 /* disabled wait */

View File

@ -0,0 +1,18 @@
/*
* Test LPSWE from a non-doubleword aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
larl %r1,unaligned
fail:
lpswe 0(%r1)
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,fail
.long 0
unaligned:
.quad 0

View File

@ -0,0 +1,16 @@
/*
* Test LRL from a non-word aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
lrl %r1,unaligned
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,test
.short 0
unaligned:
.long 0

View File

@ -0,0 +1,40 @@
/*
* Common softmmu code for specification exception testing.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.section .head
.org 0x8d
ilc:
.org 0x8e
program_interruption_code:
.org 0x150
program_old_psw:
.org 0x1D0 /* program new PSW */
.quad 0x180000000,pgm /* 64-bit mode */
.org 0x200 /* lowcore padding */
.globl _start
_start:
lpswe test_psw
pgm:
chhsi program_interruption_code,0x6 /* PGM_SPECIFICATION? */
jne failure
lg %r0,expected_old_psw+8 /* ilc adjustment */
llgc %r1,ilc
agr %r0,%r1
stg %r0,expected_old_psw+8
clc expected_old_psw(16),program_old_psw /* correct location? */
jne failure
lpswe success_psw
failure:
lpswe failure_psw
.align 8
test_psw:
.quad 0x180000000,test /* 64-bit mode */
success_psw:
.quad 0x2000180000000,0xfff /* see is_special_wait_psw() */
failure_psw:
.quad 0x2000180000000,0 /* disabled wait */

View File

@ -0,0 +1,37 @@
/*
* Common user code for specification exception testing.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
extern void test(void);
extern long expected_old_psw[2];
static void handle_sigill(int sig, siginfo_t *info, void *ucontext)
{
if ((long)info->si_addr != expected_old_psw[1]) {
_exit(EXIT_FAILURE);
}
_exit(EXIT_SUCCESS);
}
int main(void)
{
struct sigaction act;
int err;
memset(&act, 0, sizeof(act));
act.sa_sigaction = handle_sigill;
act.sa_flags = SA_SIGINFO;
err = sigaction(SIGILL, &act, NULL);
assert(err == 0);
test();
return EXIT_FAILURE;
}

View File

@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# List of specification exception tests.
# Shared between the softmmu and the user makefiles.
PGM_SPECIFICATION_TESTS = \
br-odd \
cgrl-unaligned \
clrl-unaligned \
crl-unaligned \
ex-odd \
lgrl-unaligned \
llgfrl-unaligned \
lpswe-unaligned \
lrl-unaligned \
stgrl-unaligned \
strl-unaligned

46
tests/tcg/s390x/rxsbg.c Normal file
View File

@ -0,0 +1,46 @@
/*
* Test the RXSBG instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <stdlib.h>
static inline __attribute__((__always_inline__)) void
rxsbg(unsigned long *r1, unsigned long r2, int i3, int i4, int i5, int *cc)
{
asm("rxsbg %[r1],%[r2],%[i3],%[i4],%[i5]\n"
"ipm %[cc]"
: [r1] "+r" (*r1), [cc] "=r" (*cc)
: [r2] "r" (r2) , [i3] "i" (i3) , [i4] "i" (i4) , [i5] "i" (i5)
: "cc");
*cc = (*cc >> 28) & 3;
}
void test_cc0(void)
{
unsigned long r1 = 6;
int cc;
rxsbg(&r1, 3, 61 | 0x80, 62, 1, &cc);
assert(r1 == 6);
assert(cc == 0);
}
void test_cc1(void)
{
unsigned long r1 = 2;
int cc;
rxsbg(&r1, 3, 61 | 0x80, 62, 1, &cc);
assert(r1 == 2);
assert(cc == 1);
}
int main(void)
{
test_cc0();
test_cc1();
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,20 @@
/*
* Linker script for the softmmu test kernels.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
ENTRY(_start)
SECTIONS {
. = 0;
.text : {
*(.head)
*(.text)
}
/DISCARD/ : {
*(*)
}
}

View File

@ -0,0 +1,41 @@
/*
* Test early exception recognition using SSM.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.org 0x8d
ilc:
.org 0x8e
program_interruption_code:
.org 0x150
program_old_psw:
.org 0x1D0 /* program new PSW */
.quad 0,pgm
.org 0x200 /* lowcore padding */
.globl _start
_start:
ssm ssm_op
expected_pswa:
j failure
pgm:
chhsi program_interruption_code,0x6 /* specification exception? */
jne failure
cli ilc,4 /* ilc for SSM? */
jne failure
clc program_old_psw(16),expected_old_psw /* correct old PSW? */
jne failure
lpswe success_psw
failure:
lpswe failure_psw
ssm_op:
.byte 0x20 /* bit 2 set */
.align 8
expected_old_psw:
.quad 0x2000000180000000,expected_pswa /* bit 2 set */
success_psw:
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
failure_psw:
.quad 0x2000000000000,0 /* disabled wait */

View File

@ -0,0 +1,16 @@
/*
* Test STGRL to a non-doubleword aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
stgrl %r1,unaligned
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,test
.long 0
unaligned:
.quad 0

View File

@ -0,0 +1,41 @@
/*
* Test early exception recognition using STOSM.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.org 0x8d
ilc:
.org 0x8e
program_interruption_code:
.org 0x150
program_old_psw:
.org 0x1D0 /* program new PSW */
.quad 0,pgm
.org 0x200 /* lowcore padding */
.globl _start
_start:
stosm ssm_op,0x10 /* bit 3 set */
expected_pswa:
j failure
pgm:
chhsi program_interruption_code,0x6 /* specification exception? */
jne failure
cli ilc,4 /* ilc for STOSM? */
jne failure
clc program_old_psw(16),expected_old_psw /* correct old PSW? */
jne failure
lpswe success_psw
failure:
lpswe failure_psw
ssm_op:
.byte 0
.align 8
expected_old_psw:
.quad 0x1000000180000000,expected_pswa /* bit 3 set */
success_psw:
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
failure_psw:
.quad 0x2000000000000,0 /* disabled wait */

View File

@ -0,0 +1,16 @@
/*
* Test STRL to a non-word aligned address.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.globl test
test:
strl %r1,unaligned
.align 8
.globl expected_old_psw
expected_old_psw:
.quad 0x180000000,test
.short 0
unaligned:
.long 0

View File

@ -531,6 +531,13 @@ int main(int argc, char **argv)
g_test_add_func("/blockjob/cancel/standby", test_cancel_standby);
g_test_add_func("/blockjob/cancel/pending", test_cancel_pending);
g_test_add_func("/blockjob/cancel/concluded", test_cancel_concluded);
g_test_add_func("/blockjob/complete_in_standby", test_complete_in_standby);
/*
* This test is flaky and sometimes fails in CI and otherwise:
* don't run unless user opts in via environment variable.
*/
if (getenv("QEMU_TEST_FLAKY_TESTS")) {
g_test_add_func("/blockjob/complete_in_standby", test_complete_in_standby);
}
return g_test_run();
}

View File

@ -151,7 +151,7 @@ static QSLIST_HEAD(, list_element) Q_list_head;
#define TEST_NAME "qslist"
#define TEST_LIST_REMOVE_RCU(el, f) \
QSLIST_REMOVE_RCU(&Q_list_head, el, list_element, f)
QSLIST_REMOVE_RCU(&Q_list_head, el, list_element, f)
#define TEST_LIST_INSERT_AFTER_RCU(list_el, el, f) \
QSLIST_INSERT_AFTER_RCU(&Q_list_head, list_el, el, f)

View File

@ -71,8 +71,8 @@ unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
found_first:
tmp &= (~0UL >> (BITS_PER_LONG - size));
if (tmp == 0UL) { /* Are any bits set? */
return result + size; /* Nope. */
if (tmp == 0UL) { /* Are any bits set? */
return result + size; /* Nope. */
}
found_middle:
return result + ctzl(tmp);
@ -120,8 +120,8 @@ unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
found_first:
tmp |= ~0UL << size;
if (tmp == ~0UL) { /* Are any bits zero? */
return result + size; /* Nope. */
if (tmp == ~0UL) { /* Are any bits zero? */
return result + size; /* Nope. */
}
found_middle:
return result + ctzl(~tmp);

View File

@ -3,13 +3,13 @@
#include "qemu/envlist.h"
struct envlist_entry {
const char *ev_var; /* actual env value */
QLIST_ENTRY(envlist_entry) ev_link;
const char *ev_var; /* actual env value */
QLIST_ENTRY(envlist_entry) ev_link;
};
struct envlist {
QLIST_HEAD(, envlist_entry) el_entries; /* actual entries */
size_t el_count; /* number of entries */
QLIST_HEAD(, envlist_entry) el_entries; /* actual entries */
size_t el_count; /* number of entries */
};
static int envlist_parse(envlist_t *envlist,
@ -21,14 +21,14 @@ static int envlist_parse(envlist_t *envlist,
envlist_t *
envlist_create(void)
{
envlist_t *envlist;
envlist_t *envlist;
envlist = g_malloc(sizeof(*envlist));
envlist = g_malloc(sizeof(*envlist));
QLIST_INIT(&envlist->el_entries);
envlist->el_count = 0;
QLIST_INIT(&envlist->el_entries);
envlist->el_count = 0;
return (envlist);
return (envlist);
}
/*
@ -37,18 +37,18 @@ envlist_create(void)
void
envlist_free(envlist_t *envlist)
{
struct envlist_entry *entry;
struct envlist_entry *entry;
assert(envlist != NULL);
assert(envlist != NULL);
while (envlist->el_entries.lh_first != NULL) {
entry = envlist->el_entries.lh_first;
QLIST_REMOVE(entry, ev_link);
while (envlist->el_entries.lh_first != NULL) {
entry = envlist->el_entries.lh_first;
QLIST_REMOVE(entry, ev_link);
g_free((char *)entry->ev_var);
g_free(entry);
}
g_free(envlist);
g_free((char *)entry->ev_var);
g_free(entry);
}
g_free(envlist);
}
/*
@ -65,7 +65,7 @@ envlist_free(envlist_t *envlist)
int
envlist_parse_set(envlist_t *envlist, const char *env)
{
return (envlist_parse(envlist, env, &envlist_setenv));
return (envlist_parse(envlist, env, &envlist_setenv));
}
/*
@ -77,7 +77,7 @@ envlist_parse_set(envlist_t *envlist, const char *env)
int
envlist_parse_unset(envlist_t *envlist, const char *env)
{
return (envlist_parse(envlist, env, &envlist_unsetenv));
return (envlist_parse(envlist, env, &envlist_unsetenv));
}
/*
@ -90,15 +90,15 @@ static int
envlist_parse(envlist_t *envlist, const char *env,
int (*callback)(envlist_t *, const char *))
{
char *tmpenv, *envvar;
char *envsave = NULL;
char *tmpenv, *envvar;
char *envsave = NULL;
int ret = 0;
assert(callback != NULL);
if ((envlist == NULL) || (env == NULL))
return (EINVAL);
if ((envlist == NULL) || (env == NULL))
return (EINVAL);
tmpenv = g_strdup(env);
tmpenv = g_strdup(env);
envsave = tmpenv;
do {
@ -109,7 +109,7 @@ envlist_parse(envlist_t *envlist, const char *env,
if ((*callback)(envlist, tmpenv) != 0) {
ret = errno;
break;
}
}
tmpenv = envvar + 1;
} while (envvar != NULL);
@ -126,42 +126,42 @@ envlist_parse(envlist_t *envlist, const char *env,
int
envlist_setenv(envlist_t *envlist, const char *env)
{
struct envlist_entry *entry = NULL;
const char *eq_sign;
size_t envname_len;
struct envlist_entry *entry = NULL;
const char *eq_sign;
size_t envname_len;
if ((envlist == NULL) || (env == NULL))
return (EINVAL);
if ((envlist == NULL) || (env == NULL))
return (EINVAL);
/* find out first equals sign in given env */
if ((eq_sign = strchr(env, '=')) == NULL)
return (EINVAL);
envname_len = eq_sign - env + 1;
/* find out first equals sign in given env */
if ((eq_sign = strchr(env, '=')) == NULL)
return (EINVAL);
envname_len = eq_sign - env + 1;
/*
* If there already exists variable with given name
* we remove and release it before allocating a whole
* new entry.
*/
for (entry = envlist->el_entries.lh_first; entry != NULL;
entry = entry->ev_link.le_next) {
if (strncmp(entry->ev_var, env, envname_len) == 0)
break;
}
/*
* If there already exists variable with given name
* we remove and release it before allocating a whole
* new entry.
*/
for (entry = envlist->el_entries.lh_first; entry != NULL;
entry = entry->ev_link.le_next) {
if (strncmp(entry->ev_var, env, envname_len) == 0)
break;
}
if (entry != NULL) {
QLIST_REMOVE(entry, ev_link);
g_free((char *)entry->ev_var);
g_free(entry);
} else {
envlist->el_count++;
}
if (entry != NULL) {
QLIST_REMOVE(entry, ev_link);
g_free((char *)entry->ev_var);
g_free(entry);
} else {
envlist->el_count++;
}
entry = g_malloc(sizeof(*entry));
entry->ev_var = g_strdup(env);
QLIST_INSERT_HEAD(&envlist->el_entries, entry, ev_link);
entry = g_malloc(sizeof(*entry));
entry->ev_var = g_strdup(env);
QLIST_INSERT_HEAD(&envlist->el_entries, entry, ev_link);
return (0);
return (0);
}
/*
@ -171,34 +171,34 @@ envlist_setenv(envlist_t *envlist, const char *env)
int
envlist_unsetenv(envlist_t *envlist, const char *env)
{
struct envlist_entry *entry;
size_t envname_len;
struct envlist_entry *entry;
size_t envname_len;
if ((envlist == NULL) || (env == NULL))
return (EINVAL);
if ((envlist == NULL) || (env == NULL))
return (EINVAL);
/* env is not allowed to contain '=' */
if (strchr(env, '=') != NULL)
return (EINVAL);
/* env is not allowed to contain '=' */
if (strchr(env, '=') != NULL)
return (EINVAL);
/*
* Find out the requested entry and remove
* it from the list.
*/
envname_len = strlen(env);
for (entry = envlist->el_entries.lh_first; entry != NULL;
entry = entry->ev_link.le_next) {
if (strncmp(entry->ev_var, env, envname_len) == 0)
break;
}
if (entry != NULL) {
QLIST_REMOVE(entry, ev_link);
g_free((char *)entry->ev_var);
g_free(entry);
/*
* Find out the requested entry and remove
* it from the list.
*/
envname_len = strlen(env);
for (entry = envlist->el_entries.lh_first; entry != NULL;
entry = entry->ev_link.le_next) {
if (strncmp(entry->ev_var, env, envname_len) == 0)
break;
}
if (entry != NULL) {
QLIST_REMOVE(entry, ev_link);
g_free((char *)entry->ev_var);
g_free(entry);
envlist->el_count--;
}
return (0);
envlist->el_count--;
}
return (0);
}
/*
@ -214,19 +214,19 @@ envlist_unsetenv(envlist_t *envlist, const char *env)
char **
envlist_to_environ(const envlist_t *envlist, size_t *count)
{
struct envlist_entry *entry;
char **env, **penv;
struct envlist_entry *entry;
char **env, **penv;
penv = env = g_new(char *, envlist->el_count + 1);
penv = env = g_new(char *, envlist->el_count + 1);
for (entry = envlist->el_entries.lh_first; entry != NULL;
entry = entry->ev_link.le_next) {
*(penv++) = g_strdup(entry->ev_var);
}
*penv = NULL; /* NULL terminate the list */
for (entry = envlist->el_entries.lh_first; entry != NULL;
entry = entry->ev_link.le_next) {
*(penv++) = g_strdup(entry->ev_var);
}
*penv = NULL; /* NULL terminate the list */
if (count != NULL)
*count = envlist->el_count;
if (count != NULL)
*count = envlist->el_count;
return (env);
return (env);
}