Misc HW & UI patches

- Remove deprecated SH4 SHIX machine TC58128 NAND EEPROM (Phil)
 - Remove deprecated CRIS target (Phil)
 - Remove deprecated RISC-V 'any' CPU type (Phil)
 - Add fifo8_peek_buf() to correctly handle FIFO wraparound (Mark)
 - Minor cleanups in Designware PCIe, PL011 and loongson IPI models (Phil)
 - Fixes in TI TMP105 temperature (Guenter)
 - Convert Sun ESCC and ADB mouses to QemuInputHandler (Mark)
 - Prevent heap overflow in VIRTIO sound device (Volker)
 - Cleanups around g_assert_not_reached() call (Pierrick)
 - Add Clément as VT-d reviewer (Clément)
 - Prevent stuck modifier keys and unexpected text input on Windows (Volker)
 - Explicitly set SDL2 swap interval when OpenGL is enabled (Gert)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmbkoOUACgkQ4+MsLN6t
 wN56SBAA1nYl5YTI0BwvToKysoNIJ5aTgDEbT87XYTatKYyWYlN5W1yrAeMcuwFO
 Rw8edtn2YY89ZMG/LPcY1h6+nI2qVMpuOzNP3ve4D+eM6AMUMX0bzeqXndUind7c
 1kTcV7Wctfk34zzs5B9GIU0WswSSbL3FeETS47ySNg6J7GbVWIu41dh52oeg8XWa
 Zfw0FZDt7hSAbsUckBIC9/Nbh0hucxBnQevQLkVb6u8O0yX3wV2OZRIC7+NkvHkH
 ZLPT8lg197PitH0NouUJI5oMv5Ty3PXGHtrIAKvts+fGBpWL+XzEtQmT8RzqgxTl
 9Z6C/PvfMHNtA7BE66D4iLOKBPpV0RCUDOAGsfcWy5GuklzeUy03DxZ/2xO8XERm
 TP0EP0nt2YddnELX7H65b78gJkPvnhME/MtA6Y6R7uxAA8gawZVWZQ1oDGUBNGDI
 zJ62Cu4nYPwpGiewwb+ZTkjeiaYddJsPNsE8f8d4XZCpTwpIM/oYzJapxedBwjrg
 a4eAWiy7xIvvGPxWN7IQPosGYcyO6zhbI+iAbxp1xmWsX0TPgLUcJtK9+pklqWS7
 9ucrvkq5XRZSJMaGF0LZuZH7Qx6us7m0rik5wG96d8qrIXRpi8kXfWxI17SWQkGa
 cG91u+FrKmfBr+yD7Q1gVbaYzkD+X1hPkQmSVmnlNS+5axrnSYQ=
 =sPwb
 -----END PGP SIGNATURE-----

Merge tag 'hw-misc-20240913' of https://github.com/philmd/qemu into staging

Misc HW & UI patches

- Remove deprecated SH4 SHIX machine TC58128 NAND EEPROM (Phil)
- Remove deprecated CRIS target (Phil)
- Remove deprecated RISC-V 'any' CPU type (Phil)
- Add fifo8_peek_buf() to correctly handle FIFO wraparound (Mark)
- Minor cleanups in Designware PCIe, PL011 and loongson IPI models (Phil)
- Fixes in TI TMP105 temperature (Guenter)
- Convert Sun ESCC and ADB mouses to QemuInputHandler (Mark)
- Prevent heap overflow in VIRTIO sound device (Volker)
- Cleanups around g_assert_not_reached() call (Pierrick)
- Add Clément as VT-d reviewer (Clément)
- Prevent stuck modifier keys and unexpected text input on Windows (Volker)
- Explicitly set SDL2 swap interval when OpenGL is enabled (Gert)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmbkoOUACgkQ4+MsLN6t
# wN56SBAA1nYl5YTI0BwvToKysoNIJ5aTgDEbT87XYTatKYyWYlN5W1yrAeMcuwFO
# Rw8edtn2YY89ZMG/LPcY1h6+nI2qVMpuOzNP3ve4D+eM6AMUMX0bzeqXndUind7c
# 1kTcV7Wctfk34zzs5B9GIU0WswSSbL3FeETS47ySNg6J7GbVWIu41dh52oeg8XWa
# Zfw0FZDt7hSAbsUckBIC9/Nbh0hucxBnQevQLkVb6u8O0yX3wV2OZRIC7+NkvHkH
# ZLPT8lg197PitH0NouUJI5oMv5Ty3PXGHtrIAKvts+fGBpWL+XzEtQmT8RzqgxTl
# 9Z6C/PvfMHNtA7BE66D4iLOKBPpV0RCUDOAGsfcWy5GuklzeUy03DxZ/2xO8XERm
# TP0EP0nt2YddnELX7H65b78gJkPvnhME/MtA6Y6R7uxAA8gawZVWZQ1oDGUBNGDI
# zJ62Cu4nYPwpGiewwb+ZTkjeiaYddJsPNsE8f8d4XZCpTwpIM/oYzJapxedBwjrg
# a4eAWiy7xIvvGPxWN7IQPosGYcyO6zhbI+iAbxp1xmWsX0TPgLUcJtK9+pklqWS7
# 9ucrvkq5XRZSJMaGF0LZuZH7Qx6us7m0rik5wG96d8qrIXRpi8kXfWxI17SWQkGa
# cG91u+FrKmfBr+yD7Q1gVbaYzkD+X1hPkQmSVmnlNS+5axrnSYQ=
# =sPwb
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 13 Sep 2024 21:30:29 BST
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* tag 'hw-misc-20240913' of https://github.com/philmd/qemu: (60 commits)
  ui: remove break after g_assert_not_reached()
  ui/sdl2: set swap interval explicitly when OpenGL is enabled
  ui/sdl2: ignore GUI keys in SDL_TEXTINPUT handler
  ui/sdl2: release all modifiers
  system: replace assert(0) with g_assert_not_reached()
  hw/pci-host: remove break after g_assert_not_reached()
  hw/misc: remove break after g_assert_not_reached()
  hw/gpio: remove break after g_assert_not_reached()
  hw/watchdog: replace assert(0) with g_assert_not_reached()
  hw/core: replace assert(0) with g_assert_not_reached()
  hw/char: replace assert(0) with g_assert_not_reached()
  hw/input/adb-mouse: convert to use QemuInputHandler
  hw/char/escc: convert Sun mouse to use QemuInputHandler
  hw/sensor/tmp105: Lower 4 bit of limit registers are always 0
  hw/sensor/tmp105: OS (one-shot) bit in config register always returns 0
  hw/sensor/tmp105: Pass 'oneshot' argument to tmp105_alarm_update()
  hw/sensor/tmp105: Use registerfields API
  hw/sensor/tmp105: Coding style fixes
  tests/unit: Comment FIFO8 tests
  tests/unit: Expand test_fifo8_peek_buf_wrap() coverage
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2024-09-15 18:27:40 +01:00
commit ea9cdbcf3a
227 changed files with 868 additions and 19115 deletions

View File

@ -675,7 +675,7 @@ build-without-defaults:
--disable-pie
--disable-qom-cast-debug
--disable-strip
TARGETS: alpha-softmmu avr-softmmu cris-softmmu hppa-softmmu m68k-softmmu
TARGETS: alpha-softmmu avr-softmmu hppa-softmmu m68k-softmmu
mips-softmmu mips64-softmmu mipsel-softmmu mips64el-softmmu
ppc-softmmu s390x-softmmu sh4-softmmu sh4eb-softmmu sparc-softmmu
sparc64-softmmu tricore-softmmu xtensa-softmmu xtensaeb-softmmu

View File

@ -90,11 +90,6 @@ xtensa-debian-cross-container:
variables:
NAME: debian-xtensa-cross
cris-fedora-cross-container:
extends: .container_job_template
variables:
NAME: fedora-cris-cross
win64-fedora-cross-container:
extends: .container_job_template
variables:

View File

@ -20,7 +20,7 @@
- ccache --zero-stats
- ../configure --enable-werror --disable-docs --enable-fdt=system
--disable-user $QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS
--target-list-exclude="arm-softmmu cris-softmmu
--target-list-exclude="arm-softmmu
i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu
mips64-softmmu ppc-softmmu riscv32-softmmu sh4-softmmu
sparc-softmmu xtensa-softmmu $CROSS_SKIP_TARGETS"
@ -73,7 +73,7 @@
- cd build
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
--disable-system --target-list-exclude="aarch64_be-linux-user
alpha-linux-user cris-linux-user m68k-linux-user microblazeel-linux-user
alpha-linux-user m68k-linux-user microblazeel-linux-user
or1k-linux-user ppc-linux-user sparc-linux-user
xtensa-linux-user $CROSS_SKIP_TARGETS"
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS

View File

@ -227,10 +227,6 @@ F: tests/functional/test_avr_mega2560.py
CRIS TCG CPUs
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
F: target/cris/
F: hw/cris/
F: include/hw/cris/
F: tests/tcg/cris/
F: disas/cris.c
Hexagon TCG CPUs
@ -1215,14 +1211,6 @@ M: Philippe Mathieu-Daudé <philmd@linaro.org>
S: Maintained
F: hw/avr/arduino.c
CRIS Machines
-------------
Axis Dev88
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
F: hw/cris/axis_dev88.c
F: hw/*/etraxfs_*.c
HP-PARISC Machines
------------------
HP B160L, HP C3700
@ -1688,17 +1676,6 @@ F: hw/timer/sh_timer.c
F: include/hw/sh4/sh_intc.h
F: include/hw/timer/tmu012.h
Shix
R: Yoshinori Sato <ysato@users.sourceforge.jp>
R: Magnus Damm <magnus.damm@gmail.com>
S: Odd Fixes
F: hw/block/tc58128.c
F: hw/char/sh_serial.c
F: hw/sh4/shix.c
F: hw/intc/sh_intc.c
F: hw/timer/sh_timer.c
F: include/hw/sh4/sh_intc.h
SPARC Machines
--------------
Sun4m
@ -3690,6 +3667,7 @@ VT-d Emulation
M: Michael S. Tsirkin <mst@redhat.com>
R: Jason Wang <jasowang@redhat.com>
R: Yi Liu <yi.l.liu@intel.com>
R: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
S: Supported
F: hw/i386/intel_iommu.c
F: hw/i386/intel_iommu_internal.h

View File

@ -1,4 +0,0 @@
# Default configuration for cris-softmmu
# Boards are selected by default, uncomment to keep out of the build.
# CONFIG_AXIS=n

View File

@ -7,4 +7,3 @@
# Boards are selected by default, uncomment to keep out of the build.
# CONFIG_R2D=n
# CONFIG_SHIX=n

View File

@ -1 +0,0 @@
TARGET_ARCH=cris

View File

@ -1 +0,0 @@
TARGET_ARCH=cris

4
configure vendored
View File

@ -1250,7 +1250,6 @@ probe_target_compiler() {
aarch64) container_hosts="x86_64 aarch64" ;;
alpha) container_hosts=x86_64 ;;
arm) container_hosts="x86_64 aarch64" ;;
cris) container_hosts=x86_64 ;;
hexagon) container_hosts=x86_64 ;;
hppa) container_hosts=x86_64 ;;
i386) container_hosts=x86_64 ;;
@ -1309,9 +1308,6 @@ probe_target_compiler() {
container_image=debian-armhf-cross
container_cross_prefix=arm-linux-gnueabihf-
;;
cris)
container_image=fedora-cris-cross
;;
hexagon)
container_cross_prefix=hexagon-unknown-linux-musl-
container_cross_cc=${container_cross_prefix}clang

View File

@ -206,14 +206,6 @@ in the QEMU object model anymore. ``Sun-UltraSparc-IIIi+`` and
but for consistency these will get removed in a future release, too.
Use ``Sun-UltraSparc-IIIi-plus`` and ``Sun-UltraSparc-IV-plus`` instead.
CRIS CPU architecture (since 9.0)
'''''''''''''''''''''''''''''''''
The CRIS architecture was pulled from Linux in 4.17 and the compiler
is no longer packaged in any distro making it harder to run the
``check-tcg`` tests. Unless we can improve the testing situation there
is a chance the code will bitrot without anyone noticing.
System emulator machines
------------------------
@ -232,12 +224,6 @@ These old machine types are quite neglected nowadays and thus might have
various pitfalls with regards to live migration. Use a newer machine type
instead.
``shix`` (since 9.0)
''''''''''''''''''''
The machine is no longer in existence and has been long unmaintained
in QEMU. This also holds for the TC51828 16MiB flash that it uses.
``pseries-2.1`` up to ``pseries-2.12`` (since 9.0)
''''''''''''''''''''''''''''''''''''''''''''''''''
@ -347,19 +333,6 @@ QEMU's ``vhost`` feature, which would eliminate the high latency costs under
which the 9p ``proxy`` backend currently suffers. However as of to date nobody
has indicated plans for such kind of reimplementation unfortunately.
RISC-V 'any' CPU type ``-cpu any`` (since 8.2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The 'any' CPU type was introduced back in 2018 and has been around since the
initial RISC-V QEMU port. Its usage has always been unclear: users don't know
what to expect from a CPU called 'any', and in fact the CPU does not do anything
special that isn't already done by the default CPUs rv32/rv64.
After the introduction of the 'max' CPU type, RISC-V now has a good coverage
of generic CPUs: rv32 and rv64 as default CPUs and 'max' as a feature complete
CPU for both 32 and 64 bit builds. Users are then discouraged to use the 'any'
CPU type starting in 8.2.
RISC-V CPU properties which start with capital 'Z' (since 8.2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -26,10 +26,6 @@ depending on the guest architecture.
- :ref:`Yes<AVR-System-emulator>`
- No
- 8 bit micro controller, often used in maker projects
* - Cris
- Yes
- Yes
- Embedded RISC chip developed by AXIS
* - Hexagon
- No
- Yes

View File

@ -850,6 +850,14 @@ The RISC-V no MMU cpus have been removed. The two CPUs: ``rv32imacu-nommu`` and
``rv64imacu-nommu`` can no longer be used. Instead the MMU status can be specified
via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
RISC-V 'any' CPU type ``-cpu any`` (removed in 9.2)
'''''''''''''''''''''''''''''''''''''''''''''''''''
The 'any' CPU type was introduced back in 2018 and was around since the
initial RISC-V QEMU port. Its usage was always been unclear: users don't know
what to expect from a CPU called 'any', and in fact the CPU does not do anything
special that isn't already done by the default CPUs rv32/rv64.
``compat`` property of server class POWER CPUs (removed in 6.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
@ -889,6 +897,13 @@ Nios II CPU (removed in 9.1)
QEMU Nios II architecture was orphan; Intel has EOL'ed the Nios II
processor IP (see `Intel discontinuance notification`_).
CRIS CPU architecture (removed in 9.2)
''''''''''''''''''''''''''''''''''''''
The CRIS architecture was pulled from Linux in 4.17 and the compiler
was no longer packaged in any distro making it harder to run the
``check-tcg`` tests.
System accelerators
-------------------
@ -978,6 +993,11 @@ Nios II ``10m50-ghrd`` and ``nios2-generic-nommu`` machines (removed in 9.1)
The Nios II architecture was orphan.
``shix`` (removed in 9.2)
'''''''''''''''''''''''''
The machine was unmaintained.
linux-user mode CPUs
--------------------

View File

@ -130,10 +130,6 @@ Other binaries
The binary format is detected automatically.
- user mode (Cris)
* ``qemu-cris`` TODO.
- user mode (i386)
* ``qemu-i386`` TODO.

View File

@ -151,8 +151,8 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
#else
/*
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
* S390, SH4, TriCore, and Xtensa. Our other supported targets,
* such CRIS, do not have floating-point.
* S390, SH4, TriCore, and Xtensa. Our other supported targets
* do not have floating-point.
*/
if (snan_bit_is_one(status)) {
/* set all bits other than msb */

View File

@ -50,7 +50,6 @@ source arm/Kconfig
source cpu/Kconfig
source alpha/Kconfig
source avr/Kconfig
source cris/Kconfig
source hppa/Kconfig
source i386/Kconfig
source loongarch/Kconfig

View File

@ -28,9 +28,6 @@ config ECC
config ONENAND
bool
config TC58128
bool
config VIRTIO_BLK
bool
default y

View File

@ -15,7 +15,6 @@ system_ss.add(when: 'CONFIG_SSI_M25P80', if_true: files('m25p80.c'))
system_ss.add(when: 'CONFIG_SSI_M25P80', if_true: files('m25p80_sfdp.c'))
system_ss.add(when: 'CONFIG_SWIM', if_true: files('swim.c'))
system_ss.add(when: 'CONFIG_XEN_BUS', if_true: files('xen-block.c'))
system_ss.add(when: 'CONFIG_TC58128', if_true: files('tc58128.c'))
specific_ss.add(when: 'CONFIG_VIRTIO_BLK', if_true: files('virtio-blk.c', 'virtio-blk-common.c'))
specific_ss.add(when: 'CONFIG_VHOST_USER_BLK', if_true: files('vhost-user-blk.c', 'virtio-blk-common.c'))

View File

@ -1,211 +0,0 @@
/*
* TC58128 NAND EEPROM emulation
*
* Copyright (c) 2005 Samuel Tardieu
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* SPDX-License-Identifier: MIT
*/
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "hw/sh4/sh.h"
#include "hw/loader.h"
#include "sysemu/qtest.h"
#include "qemu/error-report.h"
#define CE1 0x0100
#define CE2 0x0200
#define RE 0x0400
#define WE 0x0800
#define ALE 0x1000
#define CLE 0x2000
#define RDY1 0x4000
#define RDY2 0x8000
#define RDY(n) ((n) == 0 ? RDY1 : RDY2)
typedef enum { WAIT, READ1, READ2, READ3 } state_t;
typedef struct {
uint8_t *flash_contents;
state_t state;
uint32_t address;
uint8_t address_cycle;
} tc58128_dev;
static tc58128_dev tc58128_devs[2];
#define FLASH_SIZE (16 * MiB)
static void init_dev(tc58128_dev * dev, const char *filename)
{
int ret, blocks;
dev->state = WAIT;
dev->flash_contents = g_malloc(FLASH_SIZE);
memset(dev->flash_contents, 0xff, FLASH_SIZE);
if (filename) {
/* Load flash image skipping the first block */
ret = load_image_size(filename, dev->flash_contents + 528 * 32,
FLASH_SIZE - 528 * 32);
if (ret < 0) {
if (!qtest_enabled()) {
error_report("Could not load flash image %s", filename);
exit(1);
}
} else {
/* Build first block with number of blocks */
blocks = DIV_ROUND_UP(ret, 528 * 32);
dev->flash_contents[0] = blocks & 0xff;
dev->flash_contents[1] = (blocks >> 8) & 0xff;
dev->flash_contents[2] = (blocks >> 16) & 0xff;
dev->flash_contents[3] = (blocks >> 24) & 0xff;
fprintf(stderr, "loaded %d bytes for %s into flash\n", ret,
filename);
}
}
}
static void handle_command(tc58128_dev * dev, uint8_t command)
{
switch (command) {
case 0xff:
fprintf(stderr, "reset flash device\n");
dev->state = WAIT;
break;
case 0x00:
fprintf(stderr, "read mode 1\n");
dev->state = READ1;
dev->address_cycle = 0;
break;
case 0x01:
fprintf(stderr, "read mode 2\n");
dev->state = READ2;
dev->address_cycle = 0;
break;
case 0x50:
fprintf(stderr, "read mode 3\n");
dev->state = READ3;
dev->address_cycle = 0;
break;
default:
fprintf(stderr, "unknown flash command 0x%02x\n", command);
abort();
}
}
static void handle_address(tc58128_dev * dev, uint8_t data)
{
switch (dev->state) {
case READ1:
case READ2:
case READ3:
switch (dev->address_cycle) {
case 0:
dev->address = data;
if (dev->state == READ2)
dev->address |= 0x100;
else if (dev->state == READ3)
dev->address |= 0x200;
break;
case 1:
dev->address += data * 528 * 0x100;
break;
case 2:
dev->address += data * 528;
fprintf(stderr, "address pointer in flash: 0x%08x\n",
dev->address);
break;
default:
/* Invalid data */
abort();
}
dev->address_cycle++;
break;
default:
abort();
}
}
static uint8_t handle_read(tc58128_dev * dev)
{
#if 0
if (dev->address % 0x100000 == 0)
fprintf(stderr, "reading flash at address 0x%08x\n", dev->address);
#endif
return dev->flash_contents[dev->address++];
}
/* We never mark the device as busy, so interrupts cannot be triggered
XXXXX */
static int tc58128_cb(uint16_t porta, uint16_t portb,
uint16_t * periph_pdtra, uint16_t * periph_portadir,
uint16_t * periph_pdtrb, uint16_t * periph_portbdir)
{
int dev;
if ((porta & CE1) == 0)
dev = 0;
else if ((porta & CE2) == 0)
dev = 1;
else
return 0; /* No device selected */
if ((porta & RE) && (porta & WE)) {
/* Nothing to do, assert ready and return to input state */
*periph_portadir &= 0xff00;
*periph_portadir |= RDY(dev);
*periph_pdtra |= RDY(dev);
return 1;
}
if (porta & CLE) {
/* Command */
assert((porta & WE) == 0);
handle_command(&tc58128_devs[dev], porta & 0x00ff);
} else if (porta & ALE) {
assert((porta & WE) == 0);
handle_address(&tc58128_devs[dev], porta & 0x00ff);
} else if ((porta & RE) == 0) {
*periph_portadir |= 0x00ff;
*periph_pdtra &= 0xff00;
*periph_pdtra |= handle_read(&tc58128_devs[dev]);
} else {
abort();
}
return 1;
}
static sh7750_io_device tc58128 = {
RE | WE, /* Port A triggers */
0, /* Port B triggers */
tc58128_cb /* Callback */
};
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
{
if (!qtest_enabled()) {
warn_report_once("The TC58128 flash device is deprecated");
}
init_dev(&tc58128_devs[0], zone1);
init_dev(&tc58128_devs[1], zone2);
return sh7750_register_io_device(s, &tc58128);
}

View File

@ -86,7 +86,7 @@ static void update_char_mask(AVRUsartState *usart)
usart->char_mask = 0b11111111;
break;
default:
assert(0);
g_assert_not_reached();
}
}

View File

@ -287,6 +287,7 @@ static void escc_reset_chn(ESCCChannelState *s)
s->rxint = s->txint = 0;
s->rxint_under_svc = s->txint_under_svc = 0;
s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
s->sunmouse_dx = s->sunmouse_dy = s->sunmouse_buttons = 0;
clear_queue(s);
}
@ -952,53 +953,96 @@ static void handle_kbd_command(ESCCChannelState *s, int val)
}
}
static void sunmouse_event(void *opaque,
int dx, int dy, int dz, int buttons_state)
static void sunmouse_handle_event(DeviceState *dev, QemuConsole *src,
InputEvent *evt)
{
ESCCChannelState *s = opaque;
ESCCChannelState *s = (ESCCChannelState *)dev;
InputMoveEvent *move;
InputBtnEvent *btn;
static const int bmap[INPUT_BUTTON__MAX] = {
[INPUT_BUTTON_LEFT] = 0x4,
[INPUT_BUTTON_MIDDLE] = 0x2,
[INPUT_BUTTON_RIGHT] = 0x1,
};
switch (evt->type) {
case INPUT_EVENT_KIND_REL:
move = evt->u.rel.data;
if (move->axis == INPUT_AXIS_X) {
s->sunmouse_dx += move->value;
} else if (move->axis == INPUT_AXIS_Y) {
s->sunmouse_dy -= move->value;
}
break;
case INPUT_EVENT_KIND_BTN:
btn = evt->u.btn.data;
if (bmap[btn->button]) {
if (btn->down) {
s->sunmouse_buttons |= bmap[btn->button];
} else {
s->sunmouse_buttons &= ~bmap[btn->button];
}
/* Indicate we have a supported button event */
s->sunmouse_buttons |= 0x80;
}
break;
default:
/* keep gcc happy */
break;
}
}
static void sunmouse_sync(DeviceState *dev)
{
ESCCChannelState *s = (ESCCChannelState *)dev;
int ch;
trace_escc_sunmouse_event(dx, dy, buttons_state);
if (s->sunmouse_dx == 0 && s->sunmouse_dy == 0 &&
(s->sunmouse_buttons & 0x80) == 0) {
/* Nothing to do after button event filter */
return;
}
/* Clear our button event flag */
s->sunmouse_buttons &= ~0x80;
trace_escc_sunmouse_event(s->sunmouse_dx, s->sunmouse_dy,
s->sunmouse_buttons);
ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
if (buttons_state & MOUSE_EVENT_LBUTTON) {
ch ^= 0x4;
}
if (buttons_state & MOUSE_EVENT_MBUTTON) {
ch ^= 0x2;
}
if (buttons_state & MOUSE_EVENT_RBUTTON) {
ch ^= 0x1;
}
ch ^= s->sunmouse_buttons;
put_queue(s, ch);
ch = dx;
ch = s->sunmouse_dx;
if (ch > 127) {
ch = 127;
} else if (ch < -127) {
ch = -127;
}
put_queue(s, ch & 0xff);
s->sunmouse_dx -= ch;
ch = -dy;
ch = s->sunmouse_dy;
if (ch > 127) {
ch = 127;
} else if (ch < -127) {
ch = -127;
}
put_queue(s, ch & 0xff);
s->sunmouse_dy -= ch;
/* MSC protocol specifies two extra motion bytes */
put_queue(s, 0);
put_queue(s, 0);
}
static const QemuInputHandler sunmouse_handler = {
.name = "QEMU Sun Mouse",
.mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
.event = sunmouse_handle_event,
.sync = sunmouse_sync,
};
static void escc_init1(Object *obj)
{
ESCCState *s = ESCC(obj);
@ -1036,8 +1080,8 @@ static void escc_realize(DeviceState *dev, Error **errp)
}
if (s->chn[0].type == escc_mouse) {
qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
"QEMU Sun Mouse");
s->chn[0].hs = qemu_input_handler_register((DeviceState *)(&s->chn[0]),
&sunmouse_handler);
}
if (s->chn[1].type == escc_kbd) {
s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),

View File

@ -1,267 +0,0 @@
/*
* QEMU ETRAX System Emulator
*
* Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/sysbus.h"
#include "chardev/char-fe.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qom/object.h"
#define D(x)
#define RW_TR_CTRL (0x00 / 4)
#define RW_TR_DMA_EN (0x04 / 4)
#define RW_REC_CTRL (0x08 / 4)
#define RW_DOUT (0x1c / 4)
#define RS_STAT_DIN (0x20 / 4)
#define R_STAT_DIN (0x24 / 4)
#define RW_INTR_MASK (0x2c / 4)
#define RW_ACK_INTR (0x30 / 4)
#define R_INTR (0x34 / 4)
#define R_MASKED_INTR (0x38 / 4)
#define R_MAX (0x3c / 4)
#define STAT_DAV 16
#define STAT_TR_IDLE 22
#define STAT_TR_RDY 24
#define TYPE_ETRAX_FS_SERIAL "etraxfs-serial"
typedef struct ETRAXSerial ETRAXSerial;
DECLARE_INSTANCE_CHECKER(ETRAXSerial, ETRAX_SERIAL,
TYPE_ETRAX_FS_SERIAL)
struct ETRAXSerial {
SysBusDevice parent_obj;
MemoryRegion mmio;
CharBackend chr;
qemu_irq irq;
int pending_tx;
uint8_t rx_fifo[16];
unsigned int rx_fifo_pos;
unsigned int rx_fifo_len;
/* Control registers. */
uint32_t regs[R_MAX];
};
static void ser_update_irq(ETRAXSerial *s)
{
if (s->rx_fifo_len) {
s->regs[R_INTR] |= 8;
} else {
s->regs[R_INTR] &= ~8;
}
s->regs[R_MASKED_INTR] = s->regs[R_INTR] & s->regs[RW_INTR_MASK];
qemu_set_irq(s->irq, !!s->regs[R_MASKED_INTR]);
}
static uint64_t
ser_read(void *opaque, hwaddr addr, unsigned int size)
{
ETRAXSerial *s = opaque;
uint32_t r = 0;
addr >>= 2;
switch (addr)
{
case R_STAT_DIN:
r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 15];
if (s->rx_fifo_len) {
r |= 1 << STAT_DAV;
}
r |= 1 << STAT_TR_RDY;
r |= 1 << STAT_TR_IDLE;
break;
case RS_STAT_DIN:
r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 15];
if (s->rx_fifo_len) {
r |= 1 << STAT_DAV;
s->rx_fifo_len--;
}
r |= 1 << STAT_TR_RDY;
r |= 1 << STAT_TR_IDLE;
break;
default:
r = s->regs[addr];
D(qemu_log("%s " HWADDR_FMT_plx "=%x\n", __func__, addr, r));
break;
}
return r;
}
static void
ser_write(void *opaque, hwaddr addr,
uint64_t val64, unsigned int size)
{
ETRAXSerial *s = opaque;
uint32_t value = val64;
unsigned char ch = val64;
D(qemu_log("%s " HWADDR_FMT_plx "=%x\n", __func__, addr, value));
addr >>= 2;
switch (addr)
{
case RW_DOUT:
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(&s->chr, &ch, 1);
s->regs[R_INTR] |= 3;
s->pending_tx = 1;
s->regs[addr] = value;
break;
case RW_ACK_INTR:
if (s->pending_tx) {
value &= ~1;
s->pending_tx = 0;
D(qemu_log("fixedup value=%x r_intr=%x\n",
value, s->regs[R_INTR]));
}
s->regs[addr] = value;
s->regs[R_INTR] &= ~value;
D(printf("r_intr=%x\n", s->regs[R_INTR]));
break;
default:
s->regs[addr] = value;
break;
}
ser_update_irq(s);
}
static const MemoryRegionOps ser_ops = {
.read = ser_read,
.write = ser_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4
}
};
static Property etraxfs_ser_properties[] = {
DEFINE_PROP_CHR("chardev", ETRAXSerial, chr),
DEFINE_PROP_END_OF_LIST(),
};
static void serial_receive(void *opaque, const uint8_t *buf, int size)
{
ETRAXSerial *s = opaque;
int i;
/* Got a byte. */
if (s->rx_fifo_len >= 16) {
D(qemu_log("WARNING: UART dropped char.\n"));
return;
}
for (i = 0; i < size; i++) {
s->rx_fifo[s->rx_fifo_pos] = buf[i];
s->rx_fifo_pos++;
s->rx_fifo_pos &= 15;
s->rx_fifo_len++;
}
ser_update_irq(s);
}
static int serial_can_receive(void *opaque)
{
ETRAXSerial *s = opaque;
/* Is the receiver enabled? */
if (!(s->regs[RW_REC_CTRL] & (1 << 3))) {
return 0;
}
return sizeof(s->rx_fifo) - s->rx_fifo_len;
}
static void serial_event(void *opaque, QEMUChrEvent event)
{
}
static void etraxfs_ser_reset(DeviceState *d)
{
ETRAXSerial *s = ETRAX_SERIAL(d);
/* transmitter begins ready and idle. */
s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY);
s->regs[RS_STAT_DIN] |= (1 << STAT_TR_IDLE);
s->regs[RW_REC_CTRL] = 0x10000;
}
static void etraxfs_ser_init(Object *obj)
{
ETRAXSerial *s = ETRAX_SERIAL(obj);
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
sysbus_init_irq(dev, &s->irq);
memory_region_init_io(&s->mmio, obj, &ser_ops, s,
"etraxfs-serial", R_MAX * 4);
sysbus_init_mmio(dev, &s->mmio);
}
static void etraxfs_ser_realize(DeviceState *dev, Error **errp)
{
ETRAXSerial *s = ETRAX_SERIAL(dev);
qemu_chr_fe_set_handlers(&s->chr,
serial_can_receive, serial_receive,
serial_event, NULL, s, NULL, true);
}
static void etraxfs_ser_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
device_class_set_legacy_reset(dc, etraxfs_ser_reset);
device_class_set_props(dc, etraxfs_ser_properties);
dc->realize = etraxfs_ser_realize;
}
static const TypeInfo etraxfs_ser_info = {
.name = TYPE_ETRAX_FS_SERIAL,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(ETRAXSerial),
.instance_init = etraxfs_ser_init,
.class_init = etraxfs_ser_class_init,
};
static void etraxfs_serial_register_types(void)
{
type_register_static(&etraxfs_ser_info);
}
type_init(etraxfs_serial_register_types)

View File

@ -1,7 +1,6 @@
system_ss.add(when: 'CONFIG_CADENCE', if_true: files('cadence_uart.c'))
system_ss.add(when: 'CONFIG_CMSDK_APB_UART', if_true: files('cmsdk-apb-uart.c'))
system_ss.add(when: 'CONFIG_ESCC', if_true: files('escc.c'))
system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_ser.c'))
system_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_apbuart.c'))
system_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_uart.c'))
system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_serial.c'))

View File

@ -85,7 +85,9 @@ DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
#define CR_OUT1 (1 << 12)
#define CR_RTS (1 << 11)
#define CR_DTR (1 << 10)
#define CR_TXE (1 << 8)
#define CR_LBE (1 << 7)
#define CR_UARTEN (1 << 0)
/* Integer Baud Rate Divider, UARTIBRD */
#define IBRD_MASK 0x3f
@ -138,6 +140,11 @@ static void pl011_update(PL011State *s)
}
}
static bool pl011_loopback_enabled(PL011State *s)
{
return !!(s->cr & CR_LBE);
}
static bool pl011_is_fifo_enabled(PL011State *s)
{
return (s->lcr & LCR_FEN) != 0;
@ -149,41 +156,126 @@ static inline unsigned pl011_get_fifo_depth(PL011State *s)
return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
}
static inline void pl011_reset_fifo(PL011State *s)
static inline void pl011_reset_rx_fifo(PL011State *s)
{
s->read_count = 0;
s->read_pos = 0;
/* Reset FIFO flags */
s->flags &= ~(PL011_FLAG_RXFF | PL011_FLAG_TXFF);
s->flags |= PL011_FLAG_RXFE | PL011_FLAG_TXFE;
s->flags &= ~PL011_FLAG_RXFF;
s->flags |= PL011_FLAG_RXFE;
}
static inline void pl011_reset_tx_fifo(PL011State *s)
{
/* Reset FIFO flags */
s->flags &= ~PL011_FLAG_TXFF;
s->flags |= PL011_FLAG_TXFE;
}
static void pl011_fifo_rx_put(void *opaque, uint32_t value)
{
PL011State *s = (PL011State *)opaque;
int slot;
unsigned pipe_depth;
pipe_depth = pl011_get_fifo_depth(s);
slot = (s->read_pos + s->read_count) & (pipe_depth - 1);
s->read_fifo[slot] = value;
s->read_count++;
s->flags &= ~PL011_FLAG_RXFE;
trace_pl011_fifo_rx_put(value, s->read_count);
if (s->read_count == pipe_depth) {
trace_pl011_fifo_rx_full();
s->flags |= PL011_FLAG_RXFF;
}
if (s->read_count == s->read_trigger) {
s->int_level |= INT_RX;
pl011_update(s);
}
}
static void pl011_loopback_tx(PL011State *s, uint32_t value)
{
if (!pl011_loopback_enabled(s)) {
return;
}
/*
* Caveat:
*
* In real hardware, TX loopback happens at the serial-bit level
* and then reassembled by the RX logics back into bytes and placed
* into the RX fifo. That is, loopback happens after TX fifo.
*
* Because the real hardware TX fifo is time-drained at the frame
* rate governed by the configured serial format, some loopback
* bytes in TX fifo may still be able to get into the RX fifo
* that could be full at times while being drained at software
* pace.
*
* In such scenario, the RX draining pace is the major factor
* deciding which loopback bytes get into the RX fifo, unless
* hardware flow-control is enabled.
*
* For simplicity, the above described is not emulated.
*/
pl011_fifo_rx_put(s, value);
}
static void pl011_write_txdata(PL011State *s, uint8_t data)
{
if (!(s->cr & CR_UARTEN)) {
qemu_log_mask(LOG_GUEST_ERROR,
"PL011 data written to disabled UART\n");
}
if (!(s->cr & CR_TXE)) {
qemu_log_mask(LOG_GUEST_ERROR,
"PL011 data written to disabled TX UART\n");
}
/*
* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks
*/
qemu_chr_fe_write_all(&s->chr, &data, 1);
pl011_loopback_tx(s, data);
s->int_level |= INT_TX;
pl011_update(s);
}
static uint32_t pl011_read_rxdata(PL011State *s)
{
uint32_t c;
s->flags &= ~PL011_FLAG_RXFF;
c = s->read_fifo[s->read_pos];
if (s->read_count > 0) {
s->read_count--;
s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
}
if (s->read_count == 0) {
s->flags |= PL011_FLAG_RXFE;
}
if (s->read_count == s->read_trigger - 1) {
s->int_level &= ~INT_RX;
}
trace_pl011_read_fifo(s->read_count);
s->rsr = c >> 8;
pl011_update(s);
qemu_chr_fe_accept_input(&s->chr);
return c;
}
static uint64_t pl011_read(void *opaque, hwaddr offset,
unsigned size)
{
PL011State *s = (PL011State *)opaque;
uint32_t c;
uint64_t r;
switch (offset >> 2) {
case 0: /* UARTDR */
s->flags &= ~PL011_FLAG_RXFF;
c = s->read_fifo[s->read_pos];
if (s->read_count > 0) {
s->read_count--;
s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
}
if (s->read_count == 0) {
s->flags |= PL011_FLAG_RXFE;
}
if (s->read_count == s->read_trigger - 1)
s->int_level &= ~ INT_RX;
trace_pl011_read_fifo(s->read_count);
s->rsr = c >> 8;
pl011_update(s);
qemu_chr_fe_accept_input(&s->chr);
r = c;
r = pl011_read_rxdata(s);
break;
case 1: /* UARTRSR */
r = s->rsr;
@ -268,11 +360,6 @@ static void pl011_trace_baudrate_change(const PL011State *s)
s->ibrd, s->fbrd);
}
static bool pl011_loopback_enabled(PL011State *s)
{
return !!(s->cr & CR_LBE);
}
static void pl011_loopback_mdmctrl(PL011State *s)
{
uint32_t cr, fr, il;
@ -314,36 +401,6 @@ static void pl011_loopback_mdmctrl(PL011State *s)
pl011_update(s);
}
static void pl011_put_fifo(void *opaque, uint32_t value);
static void pl011_loopback_tx(PL011State *s, uint32_t value)
{
if (!pl011_loopback_enabled(s)) {
return;
}
/*
* Caveat:
*
* In real hardware, TX loopback happens at the serial-bit level
* and then reassembled by the RX logics back into bytes and placed
* into the RX fifo. That is, loopback happens after TX fifo.
*
* Because the real hardware TX fifo is time-drained at the frame
* rate governed by the configured serial format, some loopback
* bytes in TX fifo may still be able to get into the RX fifo
* that could be full at times while being drained at software
* pace.
*
* In such scenario, the RX draining pace is the major factor
* deciding which loopback bytes get into the RX fifo, unless
* hardware flow-control is enabled.
*
* For simplicity, the above described is not emulated.
*/
pl011_put_fifo(s, value);
}
static void pl011_loopback_break(PL011State *s, int brk_enable)
{
if (brk_enable) {
@ -361,14 +418,8 @@ static void pl011_write(void *opaque, hwaddr offset,
switch (offset >> 2) {
case 0: /* UARTDR */
/* ??? Check if transmitter is enabled. */
ch = value;
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(&s->chr, &ch, 1);
pl011_loopback_tx(s, ch);
s->int_level |= INT_TX;
pl011_update(s);
pl011_write_txdata(s, ch);
break;
case 1: /* UARTRSR/UARTECR */
s->rsr = 0;
@ -390,7 +441,8 @@ static void pl011_write(void *opaque, hwaddr offset,
case 11: /* UARTLCR_H */
/* Reset the FIFO state on FIFO enable or disable */
if ((s->lcr ^ value) & LCR_FEN) {
pl011_reset_fifo(s);
pl011_reset_rx_fifo(s);
pl011_reset_tx_fifo(s);
}
if ((s->lcr ^ value) & LCR_BRK) {
int break_enable = value & LCR_BRK;
@ -440,28 +492,6 @@ static int pl011_can_receive(void *opaque)
return r;
}
static void pl011_put_fifo(void *opaque, uint32_t value)
{
PL011State *s = (PL011State *)opaque;
int slot;
unsigned pipe_depth;
pipe_depth = pl011_get_fifo_depth(s);
slot = (s->read_pos + s->read_count) & (pipe_depth - 1);
s->read_fifo[slot] = value;
s->read_count++;
s->flags &= ~PL011_FLAG_RXFE;
trace_pl011_put_fifo(value, s->read_count);
if (s->read_count == pipe_depth) {
trace_pl011_put_fifo_full();
s->flags |= PL011_FLAG_RXFF;
}
if (s->read_count == s->read_trigger) {
s->int_level |= INT_RX;
pl011_update(s);
}
}
static void pl011_receive(void *opaque, const uint8_t *buf, int size)
{
/*
@ -473,13 +503,13 @@ static void pl011_receive(void *opaque, const uint8_t *buf, int size)
return;
}
pl011_put_fifo(opaque, *buf);
pl011_fifo_rx_put(opaque, *buf);
}
static void pl011_event(void *opaque, QEMUChrEvent event)
{
if (event == CHR_EVENT_BREAK && !pl011_loopback_enabled(opaque)) {
pl011_put_fifo(opaque, DR_BE);
pl011_fifo_rx_put(opaque, DR_BE);
}
}
@ -549,7 +579,7 @@ static const VMStateDescription vmstate_pl011 = {
.minimum_version_id = 2,
.post_load = pl011_post_load,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(readbuff, PL011State),
VMSTATE_UNUSED(sizeof(uint32_t)),
VMSTATE_UINT32(flags, PL011State),
VMSTATE_UINT32(lcr, PL011State),
VMSTATE_UINT32(rsr, PL011State),
@ -621,7 +651,8 @@ static void pl011_reset(DeviceState *dev)
s->ifl = 0x12;
s->cr = 0x300;
s->flags = 0;
pl011_reset_fifo(s);
pl011_reset_rx_fifo(s);
pl011_reset_tx_fifo(s);
}
static void pl011_class_init(ObjectClass *oc, void *data)

View File

@ -58,8 +58,8 @@ pl011_read(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x valu
pl011_read_fifo(int read_count) "FIFO read, read_count now %d"
pl011_write(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s"
pl011_can_receive(uint32_t lcr, int read_count, int r) "LCR 0x%08x read_count %d returning %d"
pl011_put_fifo(uint32_t c, int read_count) "new char 0x%x read_count now %d"
pl011_put_fifo_full(void) "FIFO now full, RXFF set"
pl011_fifo_rx_put(uint32_t c, int read_count) "new char 0x%02x read_count now %d"
pl011_fifo_rx_full(void) "RX FIFO now full, RXFF set"
pl011_baudrate_change(unsigned int baudrate, uint64_t clock, uint32_t ibrd, uint32_t fbrd) "new baudrate %u (clk: %" PRIu64 "hz, ibrd: %" PRIu32 ", fbrd: %" PRIu32 ")"
# cmsdk-apb-uart.c

View File

@ -380,7 +380,7 @@ void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node,
}
lb_data.data = node->bandwidth;
} else {
assert(0);
g_assert_not_reached();
}
g_array_append_val(hmat_lb->list, lb_data);

View File

@ -1,11 +0,0 @@
config AXIS
bool
default y
depends on CRIS
select ETRAXFS
select PFLASH_CFI02
select NAND
config ETRAXFS
bool
select PTIMER

View File

@ -1,351 +0,0 @@
/*
* QEMU model for the AXIS devboard 88.
*
* Copyright (c) 2009 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "cpu.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/block/flash.h"
#include "hw/boards.h"
#include "hw/cris/etraxfs.h"
#include "hw/loader.h"
#include "elf.h"
#include "boot.h"
#include "sysemu/qtest.h"
#include "sysemu/sysemu.h"
#define D(x)
#define DNAND(x)
struct nand_state_t
{
DeviceState *nand;
MemoryRegion iomem;
unsigned int rdy:1;
unsigned int ale:1;
unsigned int cle:1;
unsigned int ce:1;
};
static struct nand_state_t nand_state;
static uint64_t nand_read(void *opaque, hwaddr addr, unsigned size)
{
struct nand_state_t *s = opaque;
uint32_t r;
int rdy;
r = nand_getio(s->nand);
nand_getpins(s->nand, &rdy);
s->rdy = rdy;
DNAND(printf("%s addr=%x r=%x\n", __func__, addr, r));
return r;
}
static void
nand_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
{
struct nand_state_t *s = opaque;
int rdy;
DNAND(printf("%s addr=%x v=%x\n", __func__, addr, (unsigned)value));
nand_setpins(s->nand, s->cle, s->ale, s->ce, 1, 0);
nand_setio(s->nand, value);
nand_getpins(s->nand, &rdy);
s->rdy = rdy;
}
static const MemoryRegionOps nand_ops = {
.read = nand_read,
.write = nand_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};
struct tempsensor_t
{
unsigned int shiftreg;
unsigned int count;
enum {
ST_OUT, ST_IN, ST_Z
} state;
uint16_t regs[3];
};
static void tempsensor_clkedge(struct tempsensor_t *s,
unsigned int clk, unsigned int data_in)
{
D(printf("%s clk=%d state=%d sr=%x\n", __func__,
clk, s->state, s->shiftreg));
if (s->count == 0) {
s->count = 16;
s->state = ST_OUT;
}
switch (s->state) {
case ST_OUT:
/* Output reg is clocked at negedge. */
if (!clk) {
s->count--;
s->shiftreg <<= 1;
if (s->count == 0) {
s->shiftreg = 0;
s->state = ST_IN;
s->count = 16;
}
}
break;
case ST_Z:
if (clk) {
s->count--;
if (s->count == 0) {
s->shiftreg = 0;
s->state = ST_OUT;
s->count = 16;
}
}
break;
case ST_IN:
/* Indata is sampled at posedge. */
if (clk) {
s->count--;
s->shiftreg <<= 1;
s->shiftreg |= data_in & 1;
if (s->count == 0) {
D(printf("%s cfgreg=%x\n", __func__, s->shiftreg));
s->regs[0] = s->shiftreg;
s->state = ST_OUT;
s->count = 16;
if ((s->regs[0] & 0xff) == 0) {
/* 25 degrees celsius. */
s->shiftreg = 0x0b9f;
} else if ((s->regs[0] & 0xff) == 0xff) {
/* Sensor ID, 0x8100 LM70. */
s->shiftreg = 0x8100;
} else
printf("Invalid tempsens state %x\n", s->regs[0]);
}
}
break;
}
}
#define RW_PA_DOUT 0x00
#define R_PA_DIN 0x01
#define RW_PA_OE 0x02
#define RW_PD_DOUT 0x10
#define R_PD_DIN 0x11
#define RW_PD_OE 0x12
static struct gpio_state_t
{
MemoryRegion iomem;
struct nand_state_t *nand;
struct tempsensor_t tempsensor;
uint32_t regs[0x5c / 4];
} gpio_state;
static uint64_t gpio_read(void *opaque, hwaddr addr, unsigned size)
{
struct gpio_state_t *s = opaque;
uint32_t r = 0;
addr >>= 2;
switch (addr)
{
case R_PA_DIN:
r = s->regs[RW_PA_DOUT] & s->regs[RW_PA_OE];
/* Encode pins from the nand. */
r |= s->nand->rdy << 7;
break;
case R_PD_DIN:
r = s->regs[RW_PD_DOUT] & s->regs[RW_PD_OE];
/* Encode temp sensor pins. */
r |= (!!(s->tempsensor.shiftreg & 0x10000)) << 4;
break;
default:
r = s->regs[addr];
break;
}
return r;
D(printf("%s %x=%x\n", __func__, addr, r));
}
static void gpio_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
{
struct gpio_state_t *s = opaque;
D(printf("%s %x=%x\n", __func__, addr, (unsigned)value));
addr >>= 2;
switch (addr)
{
case RW_PA_DOUT:
/* Decode nand pins. */
s->nand->ale = !!(value & (1 << 6));
s->nand->cle = !!(value & (1 << 5));
s->nand->ce = !!(value & (1 << 4));
s->regs[addr] = value;
break;
case RW_PD_DOUT:
/* Temp sensor clk. */
if ((s->regs[addr] ^ value) & 2)
tempsensor_clkedge(&s->tempsensor, !!(value & 2),
!!(value & 16));
s->regs[addr] = value;
break;
default:
s->regs[addr] = value;
break;
}
}
static const MemoryRegionOps gpio_ops = {
.read = gpio_read,
.write = gpio_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4,
},
};
#define INTMEM_SIZE (128 * KiB)
static struct cris_load_info li;
static
void axisdev88_init(MachineState *machine)
{
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
CRISCPU *cpu;
DeviceState *dev;
SysBusDevice *s;
DriveInfo *nand;
qemu_irq irq[30], nmi[2];
void *etraxfs_dmac;
struct etraxfs_dma_client *dma_eth;
int i;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *phys_intmem = g_new(MemoryRegion, 1);
/* init CPUs */
cpu = CRIS_CPU(cpu_create(machine->cpu_type));
memory_region_add_subregion(address_space_mem, 0x40000000, machine->ram);
/* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the
internal memory. */
memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram",
INTMEM_SIZE, &error_fatal);
memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);
/* Attach a NAND flash to CS1. */
nand = drive_get(IF_MTD, 0, 0);
nand_state.nand = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
NAND_MFR_STMICRO, 0x39);
memory_region_init_io(&nand_state.iomem, NULL, &nand_ops, &nand_state,
"nand", 0x05000000);
memory_region_add_subregion(address_space_mem, 0x10000000,
&nand_state.iomem);
gpio_state.nand = &nand_state;
memory_region_init_io(&gpio_state.iomem, NULL, &gpio_ops, &gpio_state,
"gpio", 0x5c);
memory_region_add_subregion(address_space_mem, 0x3001a000,
&gpio_state.iomem);
dev = qdev_new("etraxfs-pic");
s = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(s, &error_fatal);
sysbus_mmio_map(s, 0, 0x3001c000);
sysbus_connect_irq(s, 0, qdev_get_gpio_in(DEVICE(cpu), CRIS_CPU_IRQ));
sysbus_connect_irq(s, 1, qdev_get_gpio_in(DEVICE(cpu), CRIS_CPU_NMI));
for (i = 0; i < 30; i++) {
irq[i] = qdev_get_gpio_in(dev, i);
}
nmi[0] = qdev_get_gpio_in(dev, 30);
nmi[1] = qdev_get_gpio_in(dev, 31);
etraxfs_dmac = etraxfs_dmac_init(0x30000000, 10);
for (i = 0; i < 10; i++) {
/* On ETRAX, odd numbered channels are inputs. */
etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1);
}
/* Add the two ethernet blocks. */
dma_eth = g_malloc0(sizeof dma_eth[0] * 4); /* Allocate 4 channels. */
etraxfs_eth_init(0x30034000, 1, &dma_eth[0], &dma_eth[1]);
/* The DMA Connector block is missing, hardwire things for now. */
etraxfs_dmac_connect_client(etraxfs_dmac, 0, &dma_eth[0]);
etraxfs_dmac_connect_client(etraxfs_dmac, 1, &dma_eth[1]);
if (qemu_find_nic_info("etraxfs-eth", true, "fseth")) {
etraxfs_eth_init(0x30036000, 2, &dma_eth[2], &dma_eth[3]);
etraxfs_dmac_connect_client(etraxfs_dmac, 6, &dma_eth[2]);
etraxfs_dmac_connect_client(etraxfs_dmac, 7, &dma_eth[3]);
}
/* 2 timers. */
sysbus_create_varargs("etraxfs-timer", 0x3001e000, irq[0x1b], nmi[1], NULL);
sysbus_create_varargs("etraxfs-timer", 0x3005e000, irq[0x1b], nmi[1], NULL);
for (i = 0; i < 4; i++) {
etraxfs_ser_create(0x30026000 + i * 0x2000, irq[0x14 + i], serial_hd(i));
}
if (kernel_filename) {
li.image_filename = kernel_filename;
li.cmdline = kernel_cmdline;
li.ram_size = machine->ram_size;
cris_load_image(cpu, &li);
} else if (!qtest_enabled()) {
fprintf(stderr, "Kernel image must be specified\n");
exit(1);
}
}
static void axisdev88_machine_init(MachineClass *mc)
{
mc->desc = "AXIS devboard 88";
mc->init = axisdev88_init;
mc->is_default = true;
mc->default_cpu_type = CRIS_CPU_TYPE_NAME("crisv32");
mc->default_ram_id = "axisdev88.ram";
}
DEFINE_MACHINE("axis-dev88", axisdev88_machine_init)

View File

@ -1,102 +0,0 @@
/*
* CRIS image loading.
*
* Copyright (c) 2010 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "hw/loader.h"
#include "elf.h"
#include "boot.h"
#include "qemu/cutils.h"
#include "sysemu/reset.h"
static void main_cpu_reset(void *opaque)
{
CRISCPU *cpu = opaque;
CPUCRISState *env = &cpu->env;
struct cris_load_info *li;
li = env->load_info;
cpu_reset(CPU(cpu));
if (!li) {
/* nothing more to do. */
return;
}
env->pc = li->entry;
if (li->image_filename) {
env->regs[8] = 0x56902387; /* RAM boot magic. */
env->regs[9] = 0x40004000 + li->image_size;
}
if (li->cmdline) {
/* Let the kernel know we are modifying the cmdline. */
env->regs[10] = 0x87109563;
env->regs[11] = 0x40000000;
}
}
static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
{
return addr - 0x80000000LL;
}
void cris_load_image(CRISCPU *cpu, struct cris_load_info *li)
{
CPUCRISState *env = &cpu->env;
uint64_t entry;
int kcmdline_len;
int image_size;
env->load_info = li;
/* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis
devboard SDK. */
image_size = load_elf(li->image_filename, NULL,
translate_kernel_address, NULL,
&entry, NULL, NULL, NULL, 0, EM_CRIS, 0, 0);
li->entry = entry;
if (image_size < 0) {
/* Takes a kimage from the axis devboard SDK. */
image_size = load_image_targphys(li->image_filename, 0x40004000,
li->ram_size);
li->entry = 0x40004000;
}
if (image_size < 0) {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
li->image_filename);
exit(1);
}
if (li->cmdline && (kcmdline_len = strlen(li->cmdline))) {
if (kcmdline_len > 256) {
fprintf(stderr, "Too long CRIS kernel cmdline (max 256)\n");
exit(1);
}
pstrcpy_targphys("cmdline", 0x40000000, 256, li->cmdline);
}
qemu_register_reset(main_cpu_reset, cpu);
}

View File

@ -1,16 +0,0 @@
#ifndef HW_CRIS_BOOT_H
#define HW_CRIS_BOOT_H
struct cris_load_info
{
const char *image_filename;
const char *cmdline;
int image_size;
ram_addr_t ram_size;
hwaddr entry;
};
void cris_load_image(CRISCPU *cpu, struct cris_load_info *li);
#endif

View File

@ -1,5 +0,0 @@
cris_ss = ss.source_set()
cris_ss.add(files('boot.c'))
cris_ss.add(when: 'CONFIG_AXIS', if_true: files('axis_dev88.c'))
hw_arch += {'cris': cris_ss}

View File

@ -1,781 +0,0 @@
/*
* QEMU ETRAX DMA Controller.
*
* Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/irq.h"
#include "qemu/main-loop.h"
#include "sysemu/runstate.h"
#include "exec/address-spaces.h"
#include "exec/memory.h"
#include "hw/cris/etraxfs_dma.h"
#define D(x)
#define RW_DATA (0x0 / 4)
#define RW_SAVED_DATA (0x58 / 4)
#define RW_SAVED_DATA_BUF (0x5c / 4)
#define RW_GROUP (0x60 / 4)
#define RW_GROUP_DOWN (0x7c / 4)
#define RW_CMD (0x80 / 4)
#define RW_CFG (0x84 / 4)
#define RW_STAT (0x88 / 4)
#define RW_INTR_MASK (0x8c / 4)
#define RW_ACK_INTR (0x90 / 4)
#define R_INTR (0x94 / 4)
#define R_MASKED_INTR (0x98 / 4)
#define RW_STREAM_CMD (0x9c / 4)
#define DMA_REG_MAX (0x100 / 4)
/* descriptors */
// ------------------------------------------------------------ dma_descr_group
typedef struct dma_descr_group {
uint32_t next;
unsigned eol : 1;
unsigned tol : 1;
unsigned bol : 1;
unsigned : 1;
unsigned intr : 1;
unsigned : 2;
unsigned en : 1;
unsigned : 7;
unsigned dis : 1;
unsigned md : 16;
struct dma_descr_group *up;
union {
struct dma_descr_context *context;
struct dma_descr_group *group;
} down;
} dma_descr_group;
// ---------------------------------------------------------- dma_descr_context
typedef struct dma_descr_context {
uint32_t next;
unsigned eol : 1;
unsigned : 3;
unsigned intr : 1;
unsigned : 1;
unsigned store_mode : 1;
unsigned en : 1;
unsigned : 7;
unsigned dis : 1;
unsigned md0 : 16;
unsigned md1;
unsigned md2;
unsigned md3;
unsigned md4;
uint32_t saved_data;
uint32_t saved_data_buf;
} dma_descr_context;
// ------------------------------------------------------------- dma_descr_data
typedef struct dma_descr_data {
uint32_t next;
uint32_t buf;
unsigned eol : 1;
unsigned : 2;
unsigned out_eop : 1;
unsigned intr : 1;
unsigned wait : 1;
unsigned : 2;
unsigned : 3;
unsigned in_eop : 1;
unsigned : 4;
unsigned md : 16;
uint32_t after;
} dma_descr_data;
/* Constants */
enum {
regk_dma_ack_pkt = 0x00000100,
regk_dma_anytime = 0x00000001,
regk_dma_array = 0x00000008,
regk_dma_burst = 0x00000020,
regk_dma_client = 0x00000002,
regk_dma_copy_next = 0x00000010,
regk_dma_copy_up = 0x00000020,
regk_dma_data_at_eol = 0x00000001,
regk_dma_dis_c = 0x00000010,
regk_dma_dis_g = 0x00000020,
regk_dma_idle = 0x00000001,
regk_dma_intern = 0x00000004,
regk_dma_load_c = 0x00000200,
regk_dma_load_c_n = 0x00000280,
regk_dma_load_c_next = 0x00000240,
regk_dma_load_d = 0x00000140,
regk_dma_load_g = 0x00000300,
regk_dma_load_g_down = 0x000003c0,
regk_dma_load_g_next = 0x00000340,
regk_dma_load_g_up = 0x00000380,
regk_dma_next_en = 0x00000010,
regk_dma_next_pkt = 0x00000010,
regk_dma_no = 0x00000000,
regk_dma_only_at_wait = 0x00000000,
regk_dma_restore = 0x00000020,
regk_dma_rst = 0x00000001,
regk_dma_running = 0x00000004,
regk_dma_rw_cfg_default = 0x00000000,
regk_dma_rw_cmd_default = 0x00000000,
regk_dma_rw_intr_mask_default = 0x00000000,
regk_dma_rw_stat_default = 0x00000101,
regk_dma_rw_stream_cmd_default = 0x00000000,
regk_dma_save_down = 0x00000020,
regk_dma_save_up = 0x00000020,
regk_dma_set_reg = 0x00000050,
regk_dma_set_w_size1 = 0x00000190,
regk_dma_set_w_size2 = 0x000001a0,
regk_dma_set_w_size4 = 0x000001c0,
regk_dma_stopped = 0x00000002,
regk_dma_store_c = 0x00000002,
regk_dma_store_descr = 0x00000000,
regk_dma_store_g = 0x00000004,
regk_dma_store_md = 0x00000001,
regk_dma_sw = 0x00000008,
regk_dma_update_down = 0x00000020,
regk_dma_yes = 0x00000001
};
enum dma_ch_state
{
RST = 1,
STOPPED = 2,
RUNNING = 4
};
struct fs_dma_channel
{
qemu_irq irq;
struct etraxfs_dma_client *client;
/* Internal status. */
int stream_cmd_src;
enum dma_ch_state state;
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;
/* Control registers. */
uint32_t regs[DMA_REG_MAX];
};
struct fs_dma_ctrl
{
MemoryRegion mmio;
int nr_channels;
struct fs_dma_channel *channels;
QEMUBH *bh;
};
static void DMA_run(void *opaque);
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];
}
static inline int channel_stopped(struct fs_dma_ctrl *ctrl, int c)
{
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;
}
static inline int fs_channel(hwaddr addr)
{
/* 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);
/* 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);
}
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);
}
#endif
static void channel_load_c(struct fs_dma_ctrl *ctrl, int c)
{
hwaddr addr = channel_reg(ctrl, c, RW_GROUP_DOWN);
/* 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;
}
static void channel_load_d(struct fs_dma_ctrl *ctrl, int c)
{
hwaddr addr = channel_reg(ctrl, c, RW_SAVED_DATA);
/* Load and decode. FIXME: handle endianness. */
D(printf("%s ch=%d addr=" HWADDR_FMT_plx "\n", __func__, c, addr));
cpu_physical_memory_read(addr, &ctrl->channels[c].current_d,
sizeof(ctrl->channels[c].current_d));
D(dump_d(c, &ctrl->channels[c].current_d));
ctrl->channels[c].regs[RW_DATA] = addr;
}
static void channel_store_c(struct fs_dma_ctrl *ctrl, int c)
{
hwaddr addr = channel_reg(ctrl, c, RW_GROUP_DOWN);
/* Encode and store. FIXME: handle endianness. */
D(printf("%s ch=%d addr=" HWADDR_FMT_plx "\n", __func__, c, addr));
D(dump_d(c, &ctrl->channels[c].current_d));
cpu_physical_memory_write(addr, &ctrl->channels[c].current_c,
sizeof(ctrl->channels[c].current_c));
}
static void channel_store_d(struct fs_dma_ctrl *ctrl, int c)
{
hwaddr addr = channel_reg(ctrl, c, RW_SAVED_DATA);
/* Encode and store. FIXME: handle endianness. */
D(printf("%s ch=%d addr=" HWADDR_FMT_plx "\n", __func__, c, addr));
cpu_physical_memory_write(addr, &ctrl->channels[c].current_d,
sizeof(ctrl->channels[c].current_d));
}
static inline void channel_stop(struct fs_dma_ctrl *ctrl, int c)
{
/* 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);
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;
}
/* 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;
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);
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);
}
}
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]);
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]));
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];
struct dma_context_metadata meta;
bool send_context = true;
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));
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;
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;
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);
}
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;
/* 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;
}
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)
{
uint32_t len;
uint32_t saved_data_buf;
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;
cpu_physical_memory_write (saved_data_buf, buf, len);
saved_data_buf += len;
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];
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;
/* 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);
channel_store_d(ctrl, c);
D(dump_d(c, &ctrl->channels[c].current_d));
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);
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;
}
static uint32_t dma_rinvalid (void *opaque, hwaddr addr)
{
hw_error("Unsupported short raccess. reg=" HWADDR_FMT_plx "\n", addr);
return 0;
}
static uint64_t
dma_read(void *opaque, hwaddr addr, unsigned int size)
{
struct fs_dma_ctrl *ctrl = opaque;
int c;
uint32_t r = 0;
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;
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
dma_winvalid (void *opaque, hwaddr addr, uint32_t value)
{
hw_error("Unsupported short waccess. reg=" HWADDR_FMT_plx "\n", addr);
}
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;
}
static void
dma_write(void *opaque, hwaddr addr,
uint64_t val64, unsigned int size)
{
struct fs_dma_ctrl *ctrl = opaque;
uint32_t value = val64;
int c;
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;
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_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;
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
}
};
static int etraxfs_dmac_run(void *opaque)
{
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;
}
int etraxfs_dmac_input(struct etraxfs_dma_client *client,
void *buf, int len, int 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;
}
void etraxfs_dmac_connect_client(void *opaque, int c,
struct etraxfs_dma_client *cl)
{
struct fs_dma_ctrl *ctrl = opaque;
cl->ctrl = ctrl;
cl->channel = c;
ctrl->channels[c].client = cl;
}
static void DMA_run(void *opaque)
{
struct fs_dma_ctrl *etraxfs_dmac = opaque;
int p = 1;
if (runstate_is_running())
p = etraxfs_dmac_run(etraxfs_dmac);
if (p)
qemu_bh_schedule_idle(etraxfs_dmac->bh);
}
void *etraxfs_dmac_init(hwaddr base, int nr_channels)
{
struct fs_dma_ctrl *ctrl = NULL;
ctrl = g_malloc0(sizeof *ctrl);
ctrl->bh = qemu_bh_new(DMA_run, ctrl);
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);
return ctrl;
}

View File

@ -5,7 +5,6 @@ system_ss.add(when: 'CONFIG_I82374', if_true: files('i82374.c'))
system_ss.add(when: 'CONFIG_I8257', if_true: files('i8257.c'))
system_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('xilinx_axidma.c'))
system_ss.add(when: 'CONFIG_ZYNQ_DEVCFG', if_true: files('xlnx-zynq-devcfg.c'))
system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_dma.c'))
system_ss.add(when: 'CONFIG_STP2000', if_true: files('sparc32_dma.c'))
system_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx_dpdma.c'))
system_ss.add(when: 'CONFIG_XLNX_ZDMA', if_true: files('xlnx-zdma.c'))

View File

@ -40,7 +40,6 @@ static bool is_connected(uint32_t config, uint32_t level)
break;
default:
g_assert_not_reached();
break;
}
return state;

View File

@ -38,6 +38,7 @@ struct MouseState {
ADBDevice parent_obj;
/*< private >*/
QemuInputHandlerState *hs;
int buttons_state, last_buttons_state;
int dx, dy, dz;
};
@ -51,17 +52,57 @@ struct ADBMouseClass {
DeviceRealize parent_realize;
};
static void adb_mouse_event(void *opaque,
int dx1, int dy1, int dz1, int buttons_state)
{
MouseState *s = opaque;
#define ADB_MOUSE_BUTTON_LEFT 0x01
#define ADB_MOUSE_BUTTON_RIGHT 0x02
s->dx += dx1;
s->dy += dy1;
s->dz += dz1;
s->buttons_state = buttons_state;
static void adb_mouse_handle_event(DeviceState *dev, QemuConsole *src,
InputEvent *evt)
{
MouseState *s = (MouseState *)dev;
InputMoveEvent *move;
InputBtnEvent *btn;
static const int bmap[INPUT_BUTTON__MAX] = {
[INPUT_BUTTON_LEFT] = ADB_MOUSE_BUTTON_LEFT,
[INPUT_BUTTON_RIGHT] = ADB_MOUSE_BUTTON_RIGHT,
};
switch (evt->type) {
case INPUT_EVENT_KIND_REL:
move = evt->u.rel.data;
if (move->axis == INPUT_AXIS_X) {
s->dx += move->value;
} else if (move->axis == INPUT_AXIS_Y) {
s->dy += move->value;
}
break;
case INPUT_EVENT_KIND_BTN:
btn = evt->u.btn.data;
if (bmap[btn->button]) {
if (btn->down) {
s->buttons_state |= bmap[btn->button];
} else {
s->buttons_state &= ~bmap[btn->button];
}
}
break;
default:
/* keep gcc happy */
break;
}
}
static const QemuInputHandler adb_mouse_handler = {
.name = "QEMU ADB Mouse",
.mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
.event = adb_mouse_handle_event,
/*
* We do not need the .sync handler because unlike e.g. PS/2 where async
* mouse events are sent over the serial port, an ADB mouse is constantly
* polled by the host via the adb_mouse_poll() callback.
*/
};
static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
{
@ -94,10 +135,10 @@ static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
dx &= 0x7f;
dy &= 0x7f;
if (!(s->buttons_state & MOUSE_EVENT_LBUTTON)) {
if (!(s->buttons_state & ADB_MOUSE_BUTTON_LEFT)) {
dy |= 0x80;
}
if (!(s->buttons_state & MOUSE_EVENT_RBUTTON)) {
if (!(s->buttons_state & ADB_MOUSE_BUTTON_RIGHT)) {
dx |= 0x80;
}
@ -236,7 +277,7 @@ static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
amc->parent_realize(dev, errp);
qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
s->hs = qemu_input_handler_register(dev, &adb_mouse_handler);
}
static void adb_mouse_initfn(Object *obj)

View File

@ -1,172 +0,0 @@
/*
* QEMU ETRAX Interrupt Controller.
*
* Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "qemu/module.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qom/object.h"
#define D(x)
#define R_RW_MASK 0
#define R_R_VECT 1
#define R_R_MASKED_VECT 2
#define R_R_NMI 3
#define R_R_GURU 4
#define R_MAX 5
#define TYPE_ETRAX_FS_PIC "etraxfs-pic"
DECLARE_INSTANCE_CHECKER(struct etrax_pic, ETRAX_FS_PIC,
TYPE_ETRAX_FS_PIC)
struct etrax_pic
{
SysBusDevice parent_obj;
MemoryRegion mmio;
qemu_irq parent_irq;
qemu_irq parent_nmi;
uint32_t regs[R_MAX];
};
static void pic_update(struct etrax_pic *fs)
{
uint32_t vector = 0;
int i;
fs->regs[R_R_MASKED_VECT] = fs->regs[R_R_VECT] & fs->regs[R_RW_MASK];
/* The ETRAX interrupt controller signals interrupts to the core
through an interrupt request wire and an irq vector bus. If
multiple interrupts are simultaneously active it chooses vector
0x30 and lets the sw choose the priorities. */
if (fs->regs[R_R_MASKED_VECT]) {
uint32_t mv = fs->regs[R_R_MASKED_VECT];
for (i = 0; i < 31; i++) {
if (mv & 1) {
vector = 0x31 + i;
/* Check for multiple interrupts. */
if (mv > 1)
vector = 0x30;
break;
}
mv >>= 1;
}
}
qemu_set_irq(fs->parent_irq, vector);
}
static uint64_t
pic_read(void *opaque, hwaddr addr, unsigned int size)
{
struct etrax_pic *fs = opaque;
uint32_t rval;
rval = fs->regs[addr >> 2];
D(printf("%s %x=%x\n", __func__, addr, rval));
return rval;
}
static void pic_write(void *opaque, hwaddr addr,
uint64_t value, unsigned int size)
{
struct etrax_pic *fs = opaque;
D(printf("%s addr=%x val=%x\n", __func__, addr, value));
if (addr == R_RW_MASK) {
fs->regs[R_RW_MASK] = value;
pic_update(fs);
}
}
static const MemoryRegionOps pic_ops = {
.read = pic_read,
.write = pic_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4
}
};
static void nmi_handler(void *opaque, int irq, int level)
{
struct etrax_pic *fs = (void *)opaque;
uint32_t mask;
mask = 1 << irq;
if (level)
fs->regs[R_R_NMI] |= mask;
else
fs->regs[R_R_NMI] &= ~mask;
qemu_set_irq(fs->parent_nmi, !!fs->regs[R_R_NMI]);
}
static void irq_handler(void *opaque, int irq, int level)
{
struct etrax_pic *fs = (void *)opaque;
if (irq >= 30) {
nmi_handler(opaque, irq, level);
return;
}
irq -= 1;
fs->regs[R_R_VECT] &= ~(1 << irq);
fs->regs[R_R_VECT] |= (!!level << irq);
pic_update(fs);
}
static void etraxfs_pic_init(Object *obj)
{
DeviceState *dev = DEVICE(obj);
struct etrax_pic *s = ETRAX_FS_PIC(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
qdev_init_gpio_in(dev, irq_handler, 32);
sysbus_init_irq(sbd, &s->parent_irq);
sysbus_init_irq(sbd, &s->parent_nmi);
memory_region_init_io(&s->mmio, obj, &pic_ops, s,
"etraxfs-pic", R_MAX * 4);
sysbus_init_mmio(sbd, &s->mmio);
}
static const TypeInfo etraxfs_pic_info = {
.name = TYPE_ETRAX_FS_PIC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct etrax_pic),
.instance_init = etraxfs_pic_init,
};
static void etraxfs_pic_register_types(void)
{
type_register_static(&etraxfs_pic_info);
}
type_init(etraxfs_pic_register_types)

View File

@ -6,18 +6,9 @@
*/
#include "qemu/osdep.h"
#include "hw/boards.h"
#include "hw/sysbus.h"
#include "hw/intc/loongson_ipi.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "exec/address-spaces.h"
#include "exec/memory.h"
#include "migration/vmstate.h"
#include "target/mips/cpu.h"
#include "trace.h"
static AddressSpace *get_iocsr_as(CPUState *cpu)
{

View File

@ -15,7 +15,6 @@ system_ss.add(when: 'CONFIG_ARM_GICV3_TCG', if_true: files(
system_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_vic.c'))
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_intc.c'))
system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_gic.c', 'exynos4210_combiner.c'))
system_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: files('goldfish_pic.c'))
system_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))

View File

@ -48,7 +48,6 @@ subdir('fsi')
subdir('alpha')
subdir('arm')
subdir('avr')
subdir('cris')
subdir('hppa')
subdir('i386')
subdir('loongarch')

View File

@ -301,7 +301,6 @@ static uint64_t imx6_analog_get_periph_clk(IMX6CCMState *dev)
default:
/* We should never get there */
g_assert_not_reached();
break;
}
trace_imx6_analog_get_periph_clk(freq);

View File

@ -495,7 +495,6 @@ static void via1_rtc_update(MOS6522Q800VIA1State *v1s)
break;
default:
g_assert_not_reached();
break;
}
return;
}
@ -556,7 +555,6 @@ static void via1_rtc_update(MOS6522Q800VIA1State *v1s)
break;
default:
g_assert_not_reached();
break;
}
return;
}

View File

@ -1,688 +0,0 @@
/*
* QEMU ETRAX Ethernet Controller.
*
* Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/cris/etraxfs.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "trace.h"
#include "qom/object.h"
#define D(x)
/* Advertisement control register. */
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
/*
* The MDIO extensions in the TDK PHY model were reversed engineered from the
* linux driver (PHYID and Diagnostics reg).
* TODO: Add friendly names for the register nums.
*/
struct qemu_phy
{
uint32_t regs[32];
int link;
unsigned int (*read)(struct qemu_phy *phy, unsigned int req);
void (*write)(struct qemu_phy *phy, unsigned int req, unsigned int data);
};
static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
{
int regnum;
unsigned r = 0;
regnum = req & 0x1f;
switch (regnum) {
case 1:
if (!phy->link) {
break;
}
/* MR1. */
/* Speeds and modes. */
r |= (1 << 13) | (1 << 14);
r |= (1 << 11) | (1 << 12);
r |= (1 << 5); /* Autoneg complete. */
r |= (1 << 3); /* Autoneg able. */
r |= (1 << 2); /* link. */
break;
case 5:
/* Link partner ability.
We are kind; always agree with whatever best mode
the guest advertises. */
r = 1 << 14; /* Success. */
/* Copy advertised modes. */
r |= phy->regs[4] & (15 << 5);
/* Autoneg support. */
r |= 1;
break;
case 18:
{
/* Diagnostics reg. */
int duplex = 0;
int speed_100 = 0;
if (!phy->link) {
break;
}
/* Are we advertising 100 half or 100 duplex ? */
speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF);
speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL);
/* Are we advertising 10 duplex or 100 duplex ? */
duplex = !!(phy->regs[4] & ADVERTISE_100FULL);
duplex |= !!(phy->regs[4] & ADVERTISE_10FULL);
r = (speed_100 << 10) | (duplex << 11);
}
break;
default:
r = phy->regs[regnum];
break;
}
trace_mdio_phy_read(regnum, r);
return r;
}
static void
tdk_write(struct qemu_phy *phy, unsigned int req, unsigned int data)
{
int regnum;
regnum = req & 0x1f;
trace_mdio_phy_write(regnum, data);
switch (regnum) {
default:
phy->regs[regnum] = data;
break;
}
}
static void
tdk_reset(struct qemu_phy *phy)
{
phy->regs[0] = 0x3100;
/* PHY Id. */
phy->regs[2] = 0x0300;
phy->regs[3] = 0xe400;
/* Autonegotiation advertisement reg. */
phy->regs[4] = 0x01E1;
phy->link = 1;
}
struct qemu_mdio
{
/* bus. */
int mdc;
int mdio;
/* decoder. */
enum {
PREAMBLE,
SOF,
OPC,
ADDR,
REQ,
TURNAROUND,
DATA
} state;
unsigned int drive;
unsigned int cnt;
unsigned int addr;
unsigned int opc;
unsigned int req;
unsigned int data;
struct qemu_phy *devs[32];
};
static void
mdio_attach(struct qemu_mdio *bus, struct qemu_phy *phy, unsigned int addr)
{
bus->devs[addr & 0x1f] = phy;
}
#ifdef USE_THIS_DEAD_CODE
static void
mdio_detach(struct qemu_mdio *bus, struct qemu_phy *phy, unsigned int addr)
{
bus->devs[addr & 0x1f] = NULL;
}
#endif
static void mdio_read_req(struct qemu_mdio *bus)
{
struct qemu_phy *phy;
phy = bus->devs[bus->addr];
if (phy && phy->read) {
bus->data = phy->read(phy, bus->req);
} else {
bus->data = 0xffff;
}
}
static void mdio_write_req(struct qemu_mdio *bus)
{
struct qemu_phy *phy;
phy = bus->devs[bus->addr];
if (phy && phy->write) {
phy->write(phy, bus->req, bus->data);
}
}
static void mdio_cycle(struct qemu_mdio *bus)
{
bus->cnt++;
trace_mdio_bitbang(bus->mdc, bus->mdio, bus->state, bus->cnt, bus->drive);
#if 0
if (bus->mdc) {
printf("%d", bus->mdio);
}
#endif
switch (bus->state) {
case PREAMBLE:
if (bus->mdc) {
if (bus->cnt >= (32 * 2) && !bus->mdio) {
bus->cnt = 0;
bus->state = SOF;
bus->data = 0;
}
}
break;
case SOF:
if (bus->mdc) {
if (bus->mdio != 1) {
printf("WARNING: no SOF\n");
}
if (bus->cnt == 1*2) {
bus->cnt = 0;
bus->opc = 0;
bus->state = OPC;
}
}
break;
case OPC:
if (bus->mdc) {
bus->opc <<= 1;
bus->opc |= bus->mdio & 1;
if (bus->cnt == 2*2) {
bus->cnt = 0;
bus->addr = 0;
bus->state = ADDR;
}
}
break;
case ADDR:
if (bus->mdc) {
bus->addr <<= 1;
bus->addr |= bus->mdio & 1;
if (bus->cnt == 5*2) {
bus->cnt = 0;
bus->req = 0;
bus->state = REQ;
}
}
break;
case REQ:
if (bus->mdc) {
bus->req <<= 1;
bus->req |= bus->mdio & 1;
if (bus->cnt == 5*2) {
bus->cnt = 0;
bus->state = TURNAROUND;
}
}
break;
case TURNAROUND:
if (bus->mdc && bus->cnt == 2*2) {
bus->mdio = 0;
bus->cnt = 0;
if (bus->opc == 2) {
bus->drive = 1;
mdio_read_req(bus);
bus->mdio = bus->data & 1;
}
bus->state = DATA;
}
break;
case DATA:
if (!bus->mdc) {
if (bus->drive) {
bus->mdio = !!(bus->data & (1 << 15));
bus->data <<= 1;
}
} else {
if (!bus->drive) {
bus->data <<= 1;
bus->data |= bus->mdio;
}
if (bus->cnt == 16 * 2) {
bus->cnt = 0;
bus->state = PREAMBLE;
if (!bus->drive) {
mdio_write_req(bus);
}
bus->drive = 0;
}
}
break;
default:
break;
}
}
/* ETRAX-FS Ethernet MAC block starts here. */
#define RW_MA0_LO 0x00
#define RW_MA0_HI 0x01
#define RW_MA1_LO 0x02
#define RW_MA1_HI 0x03
#define RW_GA_LO 0x04
#define RW_GA_HI 0x05
#define RW_GEN_CTRL 0x06
#define RW_REC_CTRL 0x07
#define RW_TR_CTRL 0x08
#define RW_CLR_ERR 0x09
#define RW_MGM_CTRL 0x0a
#define R_STAT 0x0b
#define FS_ETH_MAX_REGS 0x17
#define TYPE_ETRAX_FS_ETH "etraxfs-eth"
OBJECT_DECLARE_SIMPLE_TYPE(ETRAXFSEthState, ETRAX_FS_ETH)
struct ETRAXFSEthState {
SysBusDevice parent_obj;
MemoryRegion mmio;
NICState *nic;
NICConf conf;
/* Two addrs in the filter. */
uint8_t macaddr[2][6];
uint32_t regs[FS_ETH_MAX_REGS];
struct etraxfs_dma_client *dma_out;
struct etraxfs_dma_client *dma_in;
/* MDIO bus. */
struct qemu_mdio mdio_bus;
unsigned int phyaddr;
int duplex_mismatch;
/* PHY. */
struct qemu_phy phy;
};
static void eth_validate_duplex(ETRAXFSEthState *eth)
{
struct qemu_phy *phy;
unsigned int phy_duplex;
unsigned int mac_duplex;
int new_mm = 0;
phy = eth->mdio_bus.devs[eth->phyaddr];
phy_duplex = !!(phy->read(phy, 18) & (1 << 11));
mac_duplex = !!(eth->regs[RW_REC_CTRL] & 128);
if (mac_duplex != phy_duplex) {
new_mm = 1;
}
if (eth->regs[RW_GEN_CTRL] & 1) {
if (new_mm != eth->duplex_mismatch) {
if (new_mm) {
printf("HW: WARNING ETH duplex mismatch MAC=%d PHY=%d\n",
mac_duplex, phy_duplex);
} else {
printf("HW: ETH duplex ok.\n");
}
}
eth->duplex_mismatch = new_mm;
}
}
static uint64_t
eth_read(void *opaque, hwaddr addr, unsigned int size)
{
ETRAXFSEthState *eth = opaque;
uint32_t r = 0;
addr >>= 2;
switch (addr) {
case R_STAT:
r = eth->mdio_bus.mdio & 1;
break;
default:
r = eth->regs[addr];
D(printf("%s %x\n", __func__, addr * 4));
break;
}
return r;
}
static void eth_update_ma(ETRAXFSEthState *eth, int ma)
{
int reg;
int i = 0;
ma &= 1;
reg = RW_MA0_LO;
if (ma) {
reg = RW_MA1_LO;
}
eth->macaddr[ma][i++] = eth->regs[reg];
eth->macaddr[ma][i++] = eth->regs[reg] >> 8;
eth->macaddr[ma][i++] = eth->regs[reg] >> 16;
eth->macaddr[ma][i++] = eth->regs[reg] >> 24;
eth->macaddr[ma][i++] = eth->regs[reg + 1];
eth->macaddr[ma][i] = eth->regs[reg + 1] >> 8;
D(printf("set mac%d=%x.%x.%x.%x.%x.%x\n", ma,
eth->macaddr[ma][0], eth->macaddr[ma][1],
eth->macaddr[ma][2], eth->macaddr[ma][3],
eth->macaddr[ma][4], eth->macaddr[ma][5]));
}
static void
eth_write(void *opaque, hwaddr addr,
uint64_t val64, unsigned int size)
{
ETRAXFSEthState *eth = opaque;
uint32_t value = val64;
addr >>= 2;
switch (addr) {
case RW_MA0_LO:
case RW_MA0_HI:
eth->regs[addr] = value;
eth_update_ma(eth, 0);
break;
case RW_MA1_LO:
case RW_MA1_HI:
eth->regs[addr] = value;
eth_update_ma(eth, 1);
break;
case RW_MGM_CTRL:
/* Attach an MDIO/PHY abstraction. */
if (value & 2) {
eth->mdio_bus.mdio = value & 1;
}
if (eth->mdio_bus.mdc != (value & 4)) {
mdio_cycle(&eth->mdio_bus);
eth_validate_duplex(eth);
}
eth->mdio_bus.mdc = !!(value & 4);
eth->regs[addr] = value;
break;
case RW_REC_CTRL:
eth->regs[addr] = value;
eth_validate_duplex(eth);
break;
default:
eth->regs[addr] = value;
D(printf("%s %x %x\n", __func__, addr, value));
break;
}
}
/* The ETRAX FS has a groupt address table (GAT) which works like a k=1 bloom
filter dropping group addresses we have not joined. The filter has 64
bits (m). The has function is a simple nible xor of the group addr. */
static int eth_match_groupaddr(ETRAXFSEthState *eth, const unsigned char *sa)
{
unsigned int hsh;
int m_individual = eth->regs[RW_REC_CTRL] & 4;
int match;
/* First bit on the wire of a MAC address signals multicast or
physical address. */
if (!m_individual && !(sa[0] & 1)) {
return 0;
}
/* Calculate the hash index for the GA registers. */
hsh = 0;
hsh ^= (*sa) & 0x3f;
hsh ^= ((*sa) >> 6) & 0x03;
++sa;
hsh ^= ((*sa) << 2) & 0x03c;
hsh ^= ((*sa) >> 4) & 0xf;
++sa;
hsh ^= ((*sa) << 4) & 0x30;
hsh ^= ((*sa) >> 2) & 0x3f;
++sa;
hsh ^= (*sa) & 0x3f;
hsh ^= ((*sa) >> 6) & 0x03;
++sa;
hsh ^= ((*sa) << 2) & 0x03c;
hsh ^= ((*sa) >> 4) & 0xf;
++sa;
hsh ^= ((*sa) << 4) & 0x30;
hsh ^= ((*sa) >> 2) & 0x3f;
hsh &= 63;
if (hsh > 31) {
match = eth->regs[RW_GA_HI] & (1 << (hsh - 32));
} else {
match = eth->regs[RW_GA_LO] & (1 << hsh);
}
D(printf("hsh=%x ga=%x.%x mtch=%d\n", hsh,
eth->regs[RW_GA_HI], eth->regs[RW_GA_LO], match));
return match;
}
static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
ETRAXFSEthState *eth = qemu_get_nic_opaque(nc);
int use_ma0 = eth->regs[RW_REC_CTRL] & 1;
int use_ma1 = eth->regs[RW_REC_CTRL] & 2;
int r_bcast = eth->regs[RW_REC_CTRL] & 8;
if (size < 12) {
return -1;
}
D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
use_ma0, use_ma1, r_bcast));
/* Does the frame get through the address filters? */
if ((!use_ma0 || memcmp(buf, eth->macaddr[0], 6))
&& (!use_ma1 || memcmp(buf, eth->macaddr[1], 6))
&& (!r_bcast || memcmp(buf, sa_bcast, 6))
&& !eth_match_groupaddr(eth, buf)) {
return size;
}
/* FIXME: Find another way to pass on the fake csum. */
etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1);
return size;
}
static int eth_tx_push(void *opaque, unsigned char *buf, int len, bool eop)
{
ETRAXFSEthState *eth = opaque;
D(printf("%s buf=%p len=%d\n", __func__, buf, len));
qemu_send_packet(qemu_get_queue(eth->nic), buf, len);
return len;
}
static void eth_set_link(NetClientState *nc)
{
ETRAXFSEthState *eth = qemu_get_nic_opaque(nc);
D(printf("%s %d\n", __func__, nc->link_down));
eth->phy.link = !nc->link_down;
}
static const MemoryRegionOps eth_ops = {
.read = eth_read,
.write = eth_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4
}
};
static NetClientInfo net_etraxfs_info = {
.type = NET_CLIENT_DRIVER_NIC,
.size = sizeof(NICState),
.receive = eth_receive,
.link_status_changed = eth_set_link,
};
static void etraxfs_eth_reset(DeviceState *dev)
{
ETRAXFSEthState *s = ETRAX_FS_ETH(dev);
memset(s->regs, 0, sizeof(s->regs));
memset(s->macaddr, 0, sizeof(s->macaddr));
s->duplex_mismatch = 0;
s->mdio_bus.mdc = 0;
s->mdio_bus.mdio = 0;
s->mdio_bus.state = 0;
s->mdio_bus.drive = 0;
s->mdio_bus.cnt = 0;
s->mdio_bus.addr = 0;
s->mdio_bus.opc = 0;
s->mdio_bus.req = 0;
s->mdio_bus.data = 0;
tdk_reset(&s->phy);
}
static void etraxfs_eth_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
ETRAXFSEthState *s = ETRAX_FS_ETH(dev);
if (!s->dma_out || !s->dma_in) {
error_setg(errp, "Unconnected ETRAX-FS Ethernet MAC");
return;
}
s->dma_out->client.push = eth_tx_push;
s->dma_out->client.opaque = s;
s->dma_in->client.opaque = s;
s->dma_in->client.pull = NULL;
memory_region_init_io(&s->mmio, OBJECT(dev), &eth_ops, s,
"etraxfs-eth", 0x5c);
sysbus_init_mmio(sbd, &s->mmio);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
object_get_typename(OBJECT(s)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
s->phy.read = tdk_read;
s->phy.write = tdk_write;
mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr);
}
static Property etraxfs_eth_properties[] = {
DEFINE_PROP_UINT32("phyaddr", ETRAXFSEthState, phyaddr, 1),
DEFINE_NIC_PROPERTIES(ETRAXFSEthState, conf),
DEFINE_PROP_END_OF_LIST(),
};
static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = etraxfs_eth_realize;
device_class_set_legacy_reset(dc, etraxfs_eth_reset);
device_class_set_props(dc, etraxfs_eth_properties);
/* Reason: dma_out, dma_in are not user settable */
dc->user_creatable = false;
}
/* Instantiate an ETRAXFS Ethernet MAC. */
DeviceState *
etraxfs_eth_init(hwaddr base, int phyaddr,
struct etraxfs_dma_client *dma_out,
struct etraxfs_dma_client *dma_in)
{
DeviceState *dev;
dev = qdev_new("etraxfs-eth");
qemu_configure_nic_device(dev, true, "fseth");
qdev_prop_set_uint32(dev, "phyaddr", phyaddr);
/*
* TODO: QOM design, define a QOM interface for "I am an etraxfs
* DMA client" (which replaces the current 'struct
* etraxfs_dma_client' ad-hoc interface), implement it on the
* ethernet device, and then have QOM link properties on the DMA
* controller device so that you can pass the interface
* implementations to it.
*/
ETRAX_FS_ETH(dev)->dma_out = dma_out;
ETRAX_FS_ETH(dev)->dma_in = dma_in;
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
return dev;
}
static const TypeInfo etraxfs_eth_info = {
.name = TYPE_ETRAX_FS_ETH,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(ETRAXFSEthState),
.class_init = etraxfs_eth_class_init,
};
static void etraxfs_eth_register_types(void)
{
type_register_static(&etraxfs_eth_info);
}
type_init(etraxfs_eth_register_types)

View File

@ -40,7 +40,6 @@ system_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
system_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c', 'npcm_gmac.c'))
system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
system_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_llan.c'))
system_ss.add(when: 'CONFIG_XILINX_ETHLITE', if_true: files('xilinx_ethlite.c'))

View File

@ -10,11 +10,6 @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
# etraxfs_eth.c
mdio_phy_read(int regnum, uint16_t value) "read phy_reg:%d value:0x%04x"
mdio_phy_write(int regnum, uint16_t value) "write phy_reg:%d value:0x%04x"
mdio_bitbang(bool mdc, bool mdio, int state, uint16_t cnt, unsigned int drive) "bitbang mdc=%u mdio=%u state=%d cnt=%u drv=%d"
# lance.c
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"

View File

@ -395,6 +395,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
{
DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(dev);
DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
MemoryRegion *host_mem = get_system_memory();
MemoryRegion *address_space = &host->pci.memory;
PCIBridge *br = PCI_BRIDGE(dev);
DesignwarePCIEViewport *viewport;
@ -435,7 +436,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM;
source = &host->pci.address_space_root;
destination = get_system_memory();
destination = host_mem;
direction = "Inbound";
/*
@ -460,7 +461,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
destination = &host->pci.memory;
direction = "Outbound";
source = get_system_memory();
source = host_mem;
/*
* Configure MemoryRegion implementing CPU -> PCI memory
@ -752,28 +753,23 @@ static void designware_pcie_host_init(Object *obj)
qdev_prop_set_bit(DEVICE(root), "multifunction", false);
}
static const TypeInfo designware_pcie_root_info = {
.name = TYPE_DESIGNWARE_PCIE_ROOT,
.parent = TYPE_PCI_BRIDGE,
.instance_size = sizeof(DesignwarePCIERoot),
.class_init = designware_pcie_root_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
{ }
static const TypeInfo designware_pcie_types[] = {
{
.name = TYPE_DESIGNWARE_PCIE_HOST,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(DesignwarePCIEHost),
.instance_init = designware_pcie_host_init,
.class_init = designware_pcie_host_class_init,
}, {
.name = TYPE_DESIGNWARE_PCIE_ROOT,
.parent = TYPE_PCI_BRIDGE,
.instance_size = sizeof(DesignwarePCIERoot),
.class_init = designware_pcie_root_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
{ }
},
},
};
static const TypeInfo designware_pcie_host_info = {
.name = TYPE_DESIGNWARE_PCIE_HOST,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(DesignwarePCIEHost),
.instance_init = designware_pcie_host_init,
.class_init = designware_pcie_host_class_init,
};
static void designware_pcie_register(void)
{
type_register_static(&designware_pcie_root_info);
type_register_static(&designware_pcie_host_info);
}
type_init(designware_pcie_register)
DEFINE_TYPES(designware_pcie_types)

View File

@ -689,7 +689,6 @@ static void gt64120_writel(void *opaque, hwaddr addr,
case GT_PCI0_CFGDATA:
/* Mapped via in gt64120_pci_mapping() */
g_assert_not_reached();
break;
/* Interrupts */
case GT_INTRCAUSE:
@ -933,7 +932,6 @@ static uint64_t gt64120_readl(void *opaque,
case GT_PCI0_CFGDATA:
/* Mapped via in gt64120_pci_mapping() */
g_assert_not_reached();
break;
case GT_PCI0_CMD:
case GT_PCI0_TOR:

View File

@ -26,22 +26,27 @@
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/module.h"
#include "hw/registerfields.h"
FIELD(CONFIG, SHUTDOWN_MODE, 0, 1)
FIELD(CONFIG, THERMOSTAT_MODE, 1, 1)
FIELD(CONFIG, POLARITY, 2, 1)
FIELD(CONFIG, FAULT_QUEUE, 3, 2)
FIELD(CONFIG, CONVERTER_RESOLUTION, 5, 2)
FIELD(CONFIG, ONE_SHOT, 7, 1)
static void tmp105_interrupt_update(TMP105State *s)
{
qemu_set_irq(s->pin, s->alarm ^ ((~s->config >> 2) & 1)); /* POL */
qemu_set_irq(s->pin, s->alarm ^ FIELD_EX8(~s->config, CONFIG, POLARITY));
}
static void tmp105_alarm_update(TMP105State *s)
static void tmp105_alarm_update(TMP105State *s, bool one_shot)
{
if ((s->config >> 0) & 1) { /* SD */
if ((s->config >> 7) & 1) /* OS */
s->config &= ~(1 << 7); /* OS */
else
return;
if (FIELD_EX8(s->config, CONFIG, SHUTDOWN_MODE) && !one_shot) {
return;
}
if (s->config >> 1 & 1) {
if (FIELD_EX8(s->config, CONFIG, THERMOSTAT_MODE)) {
/*
* TM == 1 : Interrupt mode. We signal Alert when the
* temperature rises above T_high, and expect the guest to clear
@ -89,7 +94,8 @@ static void tmp105_get_temperature(Object *obj, Visitor *v, const char *name,
visit_type_int(v, name, &value, errp);
}
/* Units are 0.001 centigrades relative to 0 C. s->temperature is 8.8
/*
* Units are 0.001 centigrades relative to 0 C. s->temperature is 8.8
* fixed point, so units are 1/256 centigrades. A simple ratio will do.
*/
static void tmp105_set_temperature(Object *obj, Visitor *v, const char *name,
@ -109,7 +115,7 @@ static void tmp105_set_temperature(Object *obj, Visitor *v, const char *name,
s->temperature = (int16_t) (temp * 256 / 1000);
tmp105_alarm_update(s);
tmp105_alarm_update(s, false);
}
static const int tmp105_faultq[4] = { 1, 2, 4, 6 };
@ -118,30 +124,30 @@ static void tmp105_read(TMP105State *s)
{
s->len = 0;
if ((s->config >> 1) & 1) { /* TM */
if (FIELD_EX8(s->config, CONFIG, THERMOSTAT_MODE)) {
s->alarm = 0;
tmp105_interrupt_update(s);
}
switch (s->pointer & 3) {
case TMP105_REG_TEMPERATURE:
s->buf[s->len ++] = (((uint16_t) s->temperature) >> 8);
s->buf[s->len ++] = (((uint16_t) s->temperature) >> 0) &
(0xf0 << ((~s->config >> 5) & 3)); /* R */
s->buf[s->len++] = (((uint16_t) s->temperature) >> 8);
s->buf[s->len++] = (((uint16_t) s->temperature) >> 0) &
(0xf0 << (FIELD_EX8(~s->config, CONFIG, CONVERTER_RESOLUTION)));
break;
case TMP105_REG_CONFIG:
s->buf[s->len ++] = s->config;
s->buf[s->len++] = s->config;
break;
case TMP105_REG_T_LOW:
s->buf[s->len ++] = ((uint16_t) s->limit[0]) >> 8;
s->buf[s->len ++] = ((uint16_t) s->limit[0]) >> 0;
s->buf[s->len++] = ((uint16_t) s->limit[0]) >> 8;
s->buf[s->len++] = ((uint16_t) s->limit[0]) >> 0;
break;
case TMP105_REG_T_HIGH:
s->buf[s->len ++] = ((uint16_t) s->limit[1]) >> 8;
s->buf[s->len ++] = ((uint16_t) s->limit[1]) >> 0;
s->buf[s->len++] = ((uint16_t) s->limit[1]) >> 8;
s->buf[s->len++] = ((uint16_t) s->limit[1]) >> 0;
break;
}
}
@ -153,19 +159,21 @@ static void tmp105_write(TMP105State *s)
break;
case TMP105_REG_CONFIG:
if (s->buf[0] & ~s->config & (1 << 0)) /* SD */
if (FIELD_EX8(s->buf[0] & ~s->config, CONFIG, SHUTDOWN_MODE)) {
printf("%s: TMP105 shutdown\n", __func__);
s->config = s->buf[0];
s->faults = tmp105_faultq[(s->config >> 3) & 3]; /* F */
tmp105_alarm_update(s);
}
s->config = FIELD_DP8(s->buf[0], CONFIG, ONE_SHOT, 0);
s->faults = tmp105_faultq[FIELD_EX8(s->config, CONFIG, FAULT_QUEUE)];
tmp105_alarm_update(s, FIELD_EX8(s->buf[0], CONFIG, ONE_SHOT));
break;
case TMP105_REG_T_LOW:
case TMP105_REG_T_HIGH:
if (s->len >= 3)
if (s->len >= 3) {
s->limit[s->pointer & 1] = (int16_t)
((((uint16_t) s->buf[0]) << 8) | s->buf[1]);
tmp105_alarm_update(s);
((((uint16_t) s->buf[0]) << 8) | (s->buf[1] & 0xf0));
}
tmp105_alarm_update(s, false);
break;
}
}
@ -175,7 +183,7 @@ static uint8_t tmp105_rx(I2CSlave *i2c)
TMP105State *s = TMP105(i2c);
if (s->len < 2) {
return s->buf[s->len ++];
return s->buf[s->len++];
} else {
return 0xff;
}
@ -215,7 +223,7 @@ static int tmp105_post_load(void *opaque, int version_id)
{
TMP105State *s = opaque;
s->faults = tmp105_faultq[(s->config >> 3) & 3]; /* F */
s->faults = tmp105_faultq[FIELD_EX8(s->config, CONFIG, FAULT_QUEUE)];
tmp105_interrupt_update(s);
return 0;
@ -273,7 +281,7 @@ static void tmp105_reset(I2CSlave *i2c)
s->temperature = 0;
s->pointer = 0;
s->config = 0;
s->faults = tmp105_faultq[(s->config >> 3) & 3];
s->faults = tmp105_faultq[FIELD_EX8(s->config, CONFIG, FAULT_QUEUE)];
s->alarm = 0;
s->detect_falling = false;

View File

@ -13,13 +13,6 @@ config R2D
select SH7750
select SH_PCI
config SHIX
bool
default y
depends on SH4
select SH7750
select TC58128
config SH7750
bool
select SH_INTC

View File

@ -4,6 +4,5 @@ sh4_ss.add(when: 'CONFIG_SH7750', if_true: files(
'sh7750_regnames.c',
))
sh4_ss.add(when: 'CONFIG_R2D', if_true: files('r2d.c'))
sh4_ss.add(when: 'CONFIG_SHIX', if_true: files('shix.c'))
hw_arch += {'sh4': sh4_ss}

View File

@ -38,8 +38,6 @@
#include "exec/exec-all.h"
#include "trace.h"
#define NB_DEVICES 4
typedef struct SH7750State {
MemoryRegion iomem;
MemoryRegion iomem_1f0;
@ -75,7 +73,6 @@ typedef struct SH7750State {
uint16_t periph_portdira; /* Direction seen from the peripherals */
uint16_t periph_pdtrb; /* Imposed by the peripherals */
uint16_t periph_portdirb; /* Direction seen from the peripherals */
sh7750_io_device *devices[NB_DEVICES]; /* External peripherals */
/* Cache */
uint32_t ccr;
@ -92,19 +89,6 @@ static inline int has_bcr3_and_bcr4(SH7750State *s)
* I/O ports
*/
int sh7750_register_io_device(SH7750State *s, sh7750_io_device *device)
{
int i;
for (i = 0; i < NB_DEVICES; i++) {
if (s->devices[i] == NULL) {
s->devices[i] = device;
return 0;
}
}
return -1;
}
static uint16_t portdir(uint32_t v)
{
#define EVENPORTMASK(n) ((v & (1 << ((n) << 1))) >> (n))
@ -142,63 +126,26 @@ static uint16_t portb_lines(SH7750State *s)
(~(s->portdirb | s->periph_portdirb) & s->portpullupb); /* Pullups */
}
static void gen_port_interrupts(SH7750State *s)
{
/* XXXXX interrupts not generated */
}
static void porta_changed(SH7750State *s, uint16_t prev)
{
uint16_t currenta, changes;
int i, r = 0;
uint16_t currenta;
currenta = porta_lines(s);
if (currenta == prev) {
return;
}
trace_sh7750_porta(prev, currenta, s->pdtra, s->pctra);
changes = currenta ^ prev;
for (i = 0; i < NB_DEVICES; i++) {
if (s->devices[i] && (s->devices[i]->portamask_trigger & changes)) {
r |= s->devices[i]->port_change_cb(currenta, portb_lines(s),
&s->periph_pdtra,
&s->periph_portdira,
&s->periph_pdtrb,
&s->periph_portdirb);
}
}
if (r) {
gen_port_interrupts(s);
}
}
static void portb_changed(SH7750State *s, uint16_t prev)
{
uint16_t currentb, changes;
int i, r = 0;
uint16_t currentb;
currentb = portb_lines(s);
if (currentb == prev) {
return;
}
trace_sh7750_portb(prev, currentb, s->pdtrb, s->pctrb);
changes = currentb ^ prev;
for (i = 0; i < NB_DEVICES; i++) {
if (s->devices[i] && (s->devices[i]->portbmask_trigger & changes)) {
r |= s->devices[i]->port_change_cb(portb_lines(s), currentb,
&s->periph_pdtra,
&s->periph_portdira,
&s->periph_pdtrb,
&s->periph_portdirb);
}
}
if (r) {
gen_port_interrupts(s);
}
}
/*

View File

@ -1,86 +0,0 @@
/*
* SHIX 2.0 board description
*
* Copyright (c) 2005 Samuel Tardieu
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
* Shix 2.0 board by Alexis Polti, described at
* https://web.archive.org/web/20070917001736/perso.enst.fr/~polti/realisations/shix20
*
* More information in target/sh4/README.sh4
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "cpu.h"
#include "hw/sh4/sh.h"
#include "sysemu/qtest.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
#define BIOS_FILENAME "shix_bios.bin"
#define BIOS_ADDRESS 0xA0000000
static void shix_init(MachineState *machine)
{
int ret;
SuperHCPU *cpu;
struct SH7750State *s;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *rom = g_new(MemoryRegion, 1);
MemoryRegion *sdram = g_new(MemoryRegion, 2);
const char *bios_name = machine->firmware ?: BIOS_FILENAME;
cpu = SUPERH_CPU(cpu_create(machine->cpu_type));
/* Allocate memory space */
memory_region_init_rom(rom, NULL, "shix.rom", 0x4000, &error_fatal);
memory_region_add_subregion(sysmem, 0x00000000, rom);
memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000,
&error_fatal);
memory_region_add_subregion(sysmem, 0x08000000, &sdram[0]);
memory_region_init_ram(&sdram[1], NULL, "shix.sdram2", 0x01000000,
&error_fatal);
memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);
/* Load BIOS in 0 (and access it through P2, 0xA0000000) */
ret = load_image_targphys(bios_name, 0, 0x4000);
if (ret < 0 && !qtest_enabled()) {
error_report("Could not load SHIX bios '%s'", bios_name);
exit(1);
}
/* Register peripherals */
s = sh7750_init(cpu, sysmem);
/* XXXXX Check success */
tc58128_init(s, "shix_linux_nand.bin", NULL);
}
static void shix_machine_init(MachineClass *mc)
{
mc->desc = "shix card";
mc->init = shix_init;
mc->is_default = true;
mc->default_cpu_type = TYPE_SH7750R_CPU;
mc->deprecation_reason = "old and unmaintained";
}
DEFINE_MACHINE("shix", shix_machine_init)

View File

@ -1,407 +0,0 @@
/*
* QEMU ETRAX Timers
*
* Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "hw/irq.h"
#include "hw/ptimer.h"
#include "qom/object.h"
#define D(x)
#define RW_TMR0_DIV 0x00
#define R_TMR0_DATA 0x04
#define RW_TMR0_CTRL 0x08
#define RW_TMR1_DIV 0x10
#define R_TMR1_DATA 0x14
#define RW_TMR1_CTRL 0x18
#define R_TIME 0x38
#define RW_WD_CTRL 0x40
#define R_WD_STAT 0x44
#define RW_INTR_MASK 0x48
#define RW_ACK_INTR 0x4c
#define R_INTR 0x50
#define R_MASKED_INTR 0x54
#define TYPE_ETRAX_FS_TIMER "etraxfs-timer"
typedef struct ETRAXTimerState ETRAXTimerState;
DECLARE_INSTANCE_CHECKER(ETRAXTimerState, ETRAX_TIMER,
TYPE_ETRAX_FS_TIMER)
struct ETRAXTimerState {
SysBusDevice parent_obj;
MemoryRegion mmio;
qemu_irq irq;
qemu_irq nmi;
ptimer_state *ptimer_t0;
ptimer_state *ptimer_t1;
ptimer_state *ptimer_wd;
uint32_t wd_hits;
/* Control registers. */
uint32_t rw_tmr0_div;
uint32_t r_tmr0_data;
uint32_t rw_tmr0_ctrl;
uint32_t rw_tmr1_div;
uint32_t r_tmr1_data;
uint32_t rw_tmr1_ctrl;
uint32_t rw_wd_ctrl;
uint32_t rw_intr_mask;
uint32_t rw_ack_intr;
uint32_t r_intr;
uint32_t r_masked_intr;
};
static const VMStateDescription vmstate_etraxfs = {
.name = "etraxfs",
.version_id = 0,
.minimum_version_id = 0,
.fields = (const VMStateField[]) {
VMSTATE_PTIMER(ptimer_t0, ETRAXTimerState),
VMSTATE_PTIMER(ptimer_t1, ETRAXTimerState),
VMSTATE_PTIMER(ptimer_wd, ETRAXTimerState),
VMSTATE_UINT32(wd_hits, ETRAXTimerState),
VMSTATE_UINT32(rw_tmr0_div, ETRAXTimerState),
VMSTATE_UINT32(r_tmr0_data, ETRAXTimerState),
VMSTATE_UINT32(rw_tmr0_ctrl, ETRAXTimerState),
VMSTATE_UINT32(rw_tmr1_div, ETRAXTimerState),
VMSTATE_UINT32(r_tmr1_data, ETRAXTimerState),
VMSTATE_UINT32(rw_tmr1_ctrl, ETRAXTimerState),
VMSTATE_UINT32(rw_wd_ctrl, ETRAXTimerState),
VMSTATE_UINT32(rw_intr_mask, ETRAXTimerState),
VMSTATE_UINT32(rw_ack_intr, ETRAXTimerState),
VMSTATE_UINT32(r_intr, ETRAXTimerState),
VMSTATE_UINT32(r_masked_intr, ETRAXTimerState),
VMSTATE_END_OF_LIST()
}
};
static uint64_t
timer_read(void *opaque, hwaddr addr, unsigned int size)
{
ETRAXTimerState *t = opaque;
uint32_t r = 0;
switch (addr) {
case R_TMR0_DATA:
r = ptimer_get_count(t->ptimer_t0);
break;
case R_TMR1_DATA:
r = ptimer_get_count(t->ptimer_t1);
break;
case R_TIME:
r = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 10;
break;
case RW_INTR_MASK:
r = t->rw_intr_mask;
break;
case R_MASKED_INTR:
r = t->r_intr & t->rw_intr_mask;
break;
default:
D(printf ("%s %x\n", __func__, addr));
break;
}
return r;
}
static void update_ctrl(ETRAXTimerState *t, int tnum)
{
unsigned int op;
unsigned int freq;
unsigned int freq_hz;
unsigned int div;
uint32_t ctrl;
ptimer_state *timer;
if (tnum == 0) {
ctrl = t->rw_tmr0_ctrl;
div = t->rw_tmr0_div;
timer = t->ptimer_t0;
} else {
ctrl = t->rw_tmr1_ctrl;
div = t->rw_tmr1_div;
timer = t->ptimer_t1;
}
op = ctrl & 3;
freq = ctrl >> 2;
freq_hz = 32000000;
switch (freq)
{
case 0:
case 1:
D(printf ("extern or disabled timer clock?\n"));
break;
case 4: freq_hz = 29493000; break;
case 5: freq_hz = 32000000; break;
case 6: freq_hz = 32768000; break;
case 7: freq_hz = 100000000; break;
default:
abort();
break;
}
D(printf ("freq_hz=%d div=%d\n", freq_hz, div));
ptimer_transaction_begin(timer);
ptimer_set_freq(timer, freq_hz);
ptimer_set_limit(timer, div, 0);
switch (op)
{
case 0:
/* Load. */
ptimer_set_limit(timer, div, 1);
break;
case 1:
/* Hold. */
ptimer_stop(timer);
break;
case 2:
/* Run. */
ptimer_run(timer, 0);
break;
default:
abort();
break;
}
ptimer_transaction_commit(timer);
}
static void timer_update_irq(ETRAXTimerState *t)
{
t->r_intr &= ~(t->rw_ack_intr);
t->r_masked_intr = t->r_intr & t->rw_intr_mask;
D(printf("%s: masked_intr=%x\n", __func__, t->r_masked_intr));
qemu_set_irq(t->irq, !!t->r_masked_intr);
}
static void timer0_hit(void *opaque)
{
ETRAXTimerState *t = opaque;
t->r_intr |= 1;
timer_update_irq(t);
}
static void timer1_hit(void *opaque)
{
ETRAXTimerState *t = opaque;
t->r_intr |= 2;
timer_update_irq(t);
}
static void watchdog_hit(void *opaque)
{
ETRAXTimerState *t = opaque;
if (t->wd_hits == 0) {
/* real hw gives a single tick before resetting but we are
a bit friendlier to compensate for our slower execution. */
ptimer_set_count(t->ptimer_wd, 10);
ptimer_run(t->ptimer_wd, 1);
qemu_irq_raise(t->nmi);
}
else
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
t->wd_hits++;
}
static inline void timer_watchdog_update(ETRAXTimerState *t, uint32_t value)
{
unsigned int wd_en = t->rw_wd_ctrl & (1 << 8);
unsigned int wd_key = t->rw_wd_ctrl >> 9;
unsigned int wd_cnt = t->rw_wd_ctrl & 511;
unsigned int new_key = value >> 9 & ((1 << 7) - 1);
unsigned int new_cmd = (value >> 8) & 1;
/* If the watchdog is enabled, they written key must match the
complement of the previous. */
wd_key = ~wd_key & ((1 << 7) - 1);
if (wd_en && wd_key != new_key)
return;
D(printf("en=%d new_key=%x oldkey=%x cmd=%d cnt=%d\n",
wd_en, new_key, wd_key, new_cmd, wd_cnt));
if (t->wd_hits)
qemu_irq_lower(t->nmi);
t->wd_hits = 0;
ptimer_transaction_begin(t->ptimer_wd);
ptimer_set_freq(t->ptimer_wd, 760);
if (wd_cnt == 0)
wd_cnt = 256;
ptimer_set_count(t->ptimer_wd, wd_cnt);
if (new_cmd)
ptimer_run(t->ptimer_wd, 1);
else
ptimer_stop(t->ptimer_wd);
t->rw_wd_ctrl = value;
ptimer_transaction_commit(t->ptimer_wd);
}
static void
timer_write(void *opaque, hwaddr addr,
uint64_t val64, unsigned int size)
{
ETRAXTimerState *t = opaque;
uint32_t value = val64;
switch (addr)
{
case RW_TMR0_DIV:
t->rw_tmr0_div = value;
break;
case RW_TMR0_CTRL:
D(printf ("RW_TMR0_CTRL=%x\n", value));
t->rw_tmr0_ctrl = value;
update_ctrl(t, 0);
break;
case RW_TMR1_DIV:
t->rw_tmr1_div = value;
break;
case RW_TMR1_CTRL:
D(printf ("RW_TMR1_CTRL=%x\n", value));
t->rw_tmr1_ctrl = value;
update_ctrl(t, 1);
break;
case RW_INTR_MASK:
D(printf ("RW_INTR_MASK=%x\n", value));
t->rw_intr_mask = value;
timer_update_irq(t);
break;
case RW_WD_CTRL:
timer_watchdog_update(t, value);
break;
case RW_ACK_INTR:
t->rw_ack_intr = value;
timer_update_irq(t);
t->rw_ack_intr = 0;
break;
default:
printf("%s " HWADDR_FMT_plx " %x\n", __func__, addr, value);
break;
}
}
static const MemoryRegionOps timer_ops = {
.read = timer_read,
.write = timer_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4
}
};
static void etraxfs_timer_reset_enter(Object *obj, ResetType type)
{
ETRAXTimerState *t = ETRAX_TIMER(obj);
ptimer_transaction_begin(t->ptimer_t0);
ptimer_stop(t->ptimer_t0);
ptimer_transaction_commit(t->ptimer_t0);
ptimer_transaction_begin(t->ptimer_t1);
ptimer_stop(t->ptimer_t1);
ptimer_transaction_commit(t->ptimer_t1);
ptimer_transaction_begin(t->ptimer_wd);
ptimer_stop(t->ptimer_wd);
ptimer_transaction_commit(t->ptimer_wd);
t->rw_wd_ctrl = 0;
t->r_intr = 0;
t->rw_intr_mask = 0;
}
static void etraxfs_timer_reset_hold(Object *obj, ResetType type)
{
ETRAXTimerState *t = ETRAX_TIMER(obj);
qemu_irq_lower(t->irq);
}
static void etraxfs_timer_realize(DeviceState *dev, Error **errp)
{
ETRAXTimerState *t = ETRAX_TIMER(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
t->ptimer_t0 = ptimer_init(timer0_hit, t, PTIMER_POLICY_LEGACY);
t->ptimer_t1 = ptimer_init(timer1_hit, t, PTIMER_POLICY_LEGACY);
t->ptimer_wd = ptimer_init(watchdog_hit, t, PTIMER_POLICY_LEGACY);
sysbus_init_irq(sbd, &t->irq);
sysbus_init_irq(sbd, &t->nmi);
memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t,
"etraxfs-timer", 0x5c);
sysbus_init_mmio(sbd, &t->mmio);
}
static void etraxfs_timer_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
dc->realize = etraxfs_timer_realize;
dc->vmsd = &vmstate_etraxfs;
rc->phases.enter = etraxfs_timer_reset_enter;
rc->phases.hold = etraxfs_timer_reset_hold;
}
static const TypeInfo etraxfs_timer_info = {
.name = TYPE_ETRAX_FS_TIMER,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(ETRAXTimerState),
.class_init = etraxfs_timer_class_init,
};
static void etraxfs_timer_register_types(void)
{
type_register_static(&etraxfs_timer_info);
}
type_init(etraxfs_timer_register_types)

View File

@ -10,7 +10,6 @@ system_ss.add(when: 'CONFIG_CMSDK_APB_TIMER', if_true: files('cmsdk-apb-timer.c'
system_ss.add(when: 'CONFIG_RENESAS_TMR', if_true: files('renesas_tmr.c'))
system_ss.add(when: 'CONFIG_RENESAS_CMT', if_true: files('renesas_cmt.c'))
system_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic-timer.c'))
system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_timer.c'))
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_mct.c'))
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_pwm.c'))
system_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_gptimer.c'))

View File

@ -85,7 +85,7 @@ void watchdog_perform_action(void)
break;
default:
assert(0);
g_assert_not_reached();
}
}

View File

@ -11,7 +11,6 @@
#pragma GCC poison TARGET_AARCH64
#pragma GCC poison TARGET_ALPHA
#pragma GCC poison TARGET_ARM
#pragma GCC poison TARGET_CRIS
#pragma GCC poison TARGET_HEXAGON
#pragma GCC poison TARGET_HPPA
#pragma GCC poison TARGET_LOONGARCH64

View File

@ -46,6 +46,9 @@ typedef struct ESCCChannelState {
uint8_t rx, tx;
QemuInputHandlerState *hs;
char *sunkbd_layout;
int sunmouse_dx;
int sunmouse_dy;
int sunmouse_buttons;
} ESCCChannelState;
struct ESCCState {

View File

@ -32,7 +32,6 @@ struct PL011State {
SysBusDevice parent_obj;
MemoryRegion iomem;
uint32_t readbuff;
uint32_t flags;
uint32_t lcr;
uint32_t rsr;

View File

@ -1,54 +0,0 @@
/*
* QEMU ETRAX System Emulator
*
* Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef HW_ETRAXFS_H
#define HW_ETRAXFS_H
#include "net/net.h"
#include "hw/cris/etraxfs_dma.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "qapi/error.h"
DeviceState *etraxfs_eth_init(hwaddr base, int phyaddr,
struct etraxfs_dma_client *dma_out,
struct etraxfs_dma_client *dma_in);
static inline DeviceState *etraxfs_ser_create(hwaddr addr,
qemu_irq irq,
Chardev *chr)
{
DeviceState *dev;
SysBusDevice *s;
dev = qdev_new("etraxfs-serial");
s = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", chr);
sysbus_realize_and_unref(s, &error_fatal);
sysbus_mmio_map(s, 0, addr);
sysbus_connect_irq(s, 0, irq);
return dev;
}
#endif

View File

@ -1,36 +0,0 @@
#ifndef HW_ETRAXFS_DMA_H
#define HW_ETRAXFS_DMA_H
#include "exec/hwaddr.h"
struct dma_context_metadata {
/* data descriptor md */
uint16_t metadata;
};
struct etraxfs_dma_client
{
/* DMA controller. */
int channel;
void *ctrl;
/* client. */
struct {
int (*push)(void *opaque, unsigned char *buf,
int len, bool eop);
void (*pull)(void *opaque);
void (*metadata_push)(void *opaque,
const struct dma_context_metadata *md);
void *opaque;
} client;
};
void *etraxfs_dmac_init(hwaddr base, int nr_channels);
void etraxfs_dmac_connect(void *opaque, int channel, qemu_irq *line,
int input);
void etraxfs_dmac_connect_client(void *opaque, int c,
struct etraxfs_dma_client *cl);
int etraxfs_dmac_input(struct etraxfs_dma_client *client,
void *buf, int len, int eop);
#endif

View File

@ -31,8 +31,6 @@ OBJECT_DECLARE_SIMPLE_TYPE(DesignwarePCIEHost, DESIGNWARE_PCIE_HOST)
#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
OBJECT_DECLARE_SIMPLE_TYPE(DesignwarePCIERoot, DESIGNWARE_PCIE_ROOT)
struct DesignwarePCIERoot;
typedef struct DesignwarePCIEViewport {
DesignwarePCIERoot *root;

View File

@ -38,29 +38,10 @@ struct SH7750State;
struct SH7750State *sh7750_init(SuperHCPU *cpu, MemoryRegion *sysmem);
typedef struct {
/* The callback will be triggered if any of the designated lines change */
uint16_t portamask_trigger;
uint16_t portbmask_trigger;
/* Return 0 if no action was taken */
int (*port_change_cb) (uint16_t porta, uint16_t portb,
uint16_t *periph_pdtra,
uint16_t *periph_portdira,
uint16_t *periph_pdtrb,
uint16_t *periph_portdirb);
} sh7750_io_device;
int sh7750_register_io_device(struct SH7750State *s,
sh7750_io_device *device);
/* sh_serial.c */
#define TYPE_SH_SERIAL "sh-serial"
#define SH_SERIAL_FEAT_SCIF (1 << 0)
/* sh7750.c */
qemu_irq sh7750_irl(struct SH7750State *s);
/* tc58128.c */
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2);
#endif

View File

@ -62,6 +62,17 @@ void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num);
*/
uint8_t fifo8_pop(Fifo8 *fifo);
/**
* fifo8_peek:
* @fifo: fifo to peek from
*
* Peek the data byte at the current head of the FIFO. Clients are responsible
* for checking for emptyness using fifo8_is_empty().
*
* Returns: The peeked data byte.
*/
uint8_t fifo8_peek(Fifo8 *fifo);
/**
* fifo8_pop_buf:
* @fifo: FIFO to pop from
@ -76,6 +87,20 @@ uint8_t fifo8_pop(Fifo8 *fifo);
*/
uint32_t fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, uint32_t destlen);
/**
* fifo8_peek_buf:
* @fifo: FIFO to read from
* @dest: the buffer to write the data into (can be NULL)
* @destlen: size of @dest and maximum number of bytes to peek
*
* Peek a number of elements from the FIFO up to a maximum of @destlen.
* The peeked data is copied into the @dest buffer.
* Care is taken when the data wraps around in the ring buffer.
*
* Returns: number of bytes peeked.
*/
uint32_t fifo8_peek_buf(Fifo8 *fifo, uint8_t *dest, uint32_t destlen);
/**
* fifo8_pop_bufptr:
* @fifo: FIFO to pop from

View File

@ -6,7 +6,6 @@ enum {
QEMU_ARCH_ALL = -1,
QEMU_ARCH_ALPHA = (1 << 0),
QEMU_ARCH_ARM = (1 << 1),
QEMU_ARCH_CRIS = (1 << 2),
QEMU_ARCH_I386 = (1 << 3),
QEMU_ARCH_M68K = (1 << 4),
QEMU_ARCH_MICROBLAZE = (1 << 6),

View File

@ -42,6 +42,7 @@ struct sdl2_console {
int updates;
int idle_counter;
int ignore_hotkeys;
bool gui_keysym;
SDL_GLContext winctx;
QKbdState *kbd;
#ifdef CONFIG_OPENGL
@ -60,6 +61,7 @@ void sdl2_poll_events(struct sdl2_console *scon);
void sdl2_process_key(struct sdl2_console *scon,
SDL_KeyboardEvent *ev);
void sdl2_release_modifiers(struct sdl2_console *scon);
void sdl2_2d_update(DisplayChangeListener *dcl,
int x, int y, int w, int h);

View File

@ -21,13 +21,6 @@
#define ABI_LLONG_ALIGNMENT 2
#endif
#ifdef TARGET_CRIS
#define ABI_SHORT_ALIGNMENT 1
#define ABI_INT_ALIGNMENT 1
#define ABI_LONG_ALIGNMENT 1
#define ABI_LLONG_ALIGNMENT 1
#endif
#if (defined(TARGET_I386) && !defined(TARGET_X86_64)) \
|| defined(TARGET_SH4) \
|| defined(TARGET_OPENRISC) \

View File

@ -1,95 +0,0 @@
/*
* qemu user cpu loop
*
* Copyright (c) 2003-2008 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qemu.h"
#include "user-internals.h"
#include "cpu_loop-common.h"
#include "signal-common.h"
void cpu_loop(CPUCRISState *env)
{
CPUState *cs = env_cpu(env);
int trapnr, ret;
while (1) {
cpu_exec_start(cs);
trapnr = cpu_exec(cs);
cpu_exec_end(cs);
process_queued_cpu_work(cs);
switch (trapnr) {
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
break;
case EXCP_BREAK:
ret = do_syscall(env,
env->regs[9],
env->regs[10],
env->regs[11],
env->regs[12],
env->regs[13],
env->pregs[7],
env->pregs[11],
0, 0);
if (ret == -QEMU_ERESTARTSYS) {
env->pc -= 2;
} else if (ret != -QEMU_ESIGRETURN) {
env->regs[10] = ret;
}
break;
case EXCP_DEBUG:
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
break;
default:
fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(cs, stderr, 0);
exit(EXIT_FAILURE);
}
process_pending_signals (env);
}
}
void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
{
CPUState *cpu = env_cpu(env);
TaskState *ts = get_task_state(cpu);
struct image_info *info = ts->info;
env->regs[0] = regs->r0;
env->regs[1] = regs->r1;
env->regs[2] = regs->r2;
env->regs[3] = regs->r3;
env->regs[4] = regs->r4;
env->regs[5] = regs->r5;
env->regs[6] = regs->r6;
env->regs[7] = regs->r7;
env->regs[8] = regs->r8;
env->regs[9] = regs->r9;
env->regs[10] = regs->r10;
env->regs[11] = regs->r11;
env->regs[12] = regs->r12;
env->regs[13] = regs->r13;
env->regs[14] = info->start_stack;
env->regs[15] = regs->acr;
env->pc = regs->erp;
}

View File

@ -1,194 +0,0 @@
/*
* Emulation of Linux signals
*
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qemu.h"
#include "user-internals.h"
#include "signal-common.h"
#include "linux-user/trace.h"
struct target_sigcontext {
struct target_pt_regs regs; /* needs to be first */
uint32_t oldmask;
uint32_t usp; /* usp before stacking this gunk on it */
};
/* Signal frames. */
struct target_signal_frame {
struct target_sigcontext sc;
uint32_t extramask[TARGET_NSIG_WORDS - 1];
uint16_t retcode[4]; /* Trampoline code. */
};
static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
{
__put_user(env->regs[0], &sc->regs.r0);
__put_user(env->regs[1], &sc->regs.r1);
__put_user(env->regs[2], &sc->regs.r2);
__put_user(env->regs[3], &sc->regs.r3);
__put_user(env->regs[4], &sc->regs.r4);
__put_user(env->regs[5], &sc->regs.r5);
__put_user(env->regs[6], &sc->regs.r6);
__put_user(env->regs[7], &sc->regs.r7);
__put_user(env->regs[8], &sc->regs.r8);
__put_user(env->regs[9], &sc->regs.r9);
__put_user(env->regs[10], &sc->regs.r10);
__put_user(env->regs[11], &sc->regs.r11);
__put_user(env->regs[12], &sc->regs.r12);
__put_user(env->regs[13], &sc->regs.r13);
__put_user(env->regs[14], &sc->usp);
__put_user(env->regs[15], &sc->regs.acr);
__put_user(env->pregs[PR_MOF], &sc->regs.mof);
__put_user(env->pregs[PR_SRP], &sc->regs.srp);
__put_user(env->pc, &sc->regs.erp);
}
static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
{
__get_user(env->regs[0], &sc->regs.r0);
__get_user(env->regs[1], &sc->regs.r1);
__get_user(env->regs[2], &sc->regs.r2);
__get_user(env->regs[3], &sc->regs.r3);
__get_user(env->regs[4], &sc->regs.r4);
__get_user(env->regs[5], &sc->regs.r5);
__get_user(env->regs[6], &sc->regs.r6);
__get_user(env->regs[7], &sc->regs.r7);
__get_user(env->regs[8], &sc->regs.r8);
__get_user(env->regs[9], &sc->regs.r9);
__get_user(env->regs[10], &sc->regs.r10);
__get_user(env->regs[11], &sc->regs.r11);
__get_user(env->regs[12], &sc->regs.r12);
__get_user(env->regs[13], &sc->regs.r13);
__get_user(env->regs[14], &sc->usp);
__get_user(env->regs[15], &sc->regs.acr);
__get_user(env->pregs[PR_MOF], &sc->regs.mof);
__get_user(env->pregs[PR_SRP], &sc->regs.srp);
__get_user(env->pc, &sc->regs.erp);
}
static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
{
abi_ulong sp;
/* Align the stack downwards to 4. */
sp = (env->regs[R_SP] & ~3);
return sp - framesize;
}
static void setup_sigreturn(uint16_t *retcode)
{
/* This is movu.w __NR_sigreturn, r9; break 13; */
__put_user(0x9c5f, retcode + 0);
__put_user(TARGET_NR_sigreturn, retcode + 1);
__put_user(0xe93d, retcode + 2);
}
void setup_frame(int sig, struct target_sigaction *ka,
target_sigset_t *set, CPUCRISState *env)
{
struct target_signal_frame *frame;
abi_ulong frame_addr;
int i;
frame_addr = get_sigframe(env, sizeof *frame);
trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto badframe;
/*
* The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
* use this trampoline anymore but it sets it up for GDB.
*/
setup_sigreturn(frame->retcode);
/* Save the mask. */
__put_user(set->sig[0], &frame->sc.oldmask);
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
__put_user(set->sig[i], &frame->extramask[i - 1]);
}
setup_sigcontext(&frame->sc, env);
/* Move the stack and setup the arguments for the handler. */
env->regs[R_SP] = frame_addr;
env->regs[10] = sig;
env->pc = (unsigned long) ka->_sa_handler;
/* Link SRP so the guest returns through the trampoline. */
env->pregs[PR_SRP] = default_sigreturn;
unlock_user_struct(frame, frame_addr, 1);
return;
badframe:
force_sigsegv(sig);
}
void setup_rt_frame(int sig, struct target_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUCRISState *env)
{
qemu_log_mask(LOG_UNIMP, "setup_rt_frame: not implemented\n");
}
long do_sigreturn(CPUCRISState *env)
{
struct target_signal_frame *frame;
abi_ulong frame_addr;
target_sigset_t target_set;
sigset_t set;
int i;
frame_addr = env->regs[R_SP];
trace_user_do_sigreturn(env, frame_addr);
/* Make sure the guest isn't playing games. */
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1)) {
goto badframe;
}
/* Restore blocked signals */
__get_user(target_set.sig[0], &frame->sc.oldmask);
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
__get_user(target_set.sig[i], &frame->extramask[i - 1]);
}
target_to_host_sigset_internal(&set, &target_set);
set_sigmask(&set);
restore_sigcontext(&frame->sc, env);
unlock_user_struct(frame, frame_addr, 0);
return -QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
return -QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUCRISState *env)
{
trace_user_do_rt_sigreturn(env, 0);
qemu_log_mask(LOG_UNIMP, "do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
void setup_sigtramp(abi_ulong sigtramp_page)
{
uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 6, 0);
assert(tramp != NULL);
default_sigreturn = sigtramp_page;
setup_sigreturn(tramp);
unlock_user(tramp, sigtramp_page, 6);
}

View File

@ -1 +0,0 @@
#include "../generic/sockbits.h"

View File

@ -1,367 +0,0 @@
/*
* This file contains the system call numbers, and stub macros for libc.
*/
#ifndef LINUX_USER_CRIS_SYSCALL_NR_H
#define LINUX_USER_CRIS_SYSCALL_NR_H
#define TARGET_NR_restart_syscall 0
#define TARGET_NR_exit 1
#define TARGET_NR_fork 2
#define TARGET_NR_read 3
#define TARGET_NR_write 4
#define TARGET_NR_open 5
#define TARGET_NR_close 6
#define TARGET_NR_waitpid 7
#define TARGET_NR_creat 8
#define TARGET_NR_link 9
#define TARGET_NR_unlink 10
#define TARGET_NR_execve 11
#define TARGET_NR_chdir 12
#define TARGET_NR_time 13
#define TARGET_NR_mknod 14
#define TARGET_NR_chmod 15
#define TARGET_NR_lchown 16
#define TARGET_NR_break 17
#define TARGET_NR_oldstat 18
#define TARGET_NR_lseek 19
#define TARGET_NR_getpid 20
#define TARGET_NR_mount 21
#define TARGET_NR_umount 22
#define TARGET_NR_setuid 23
#define TARGET_NR_getuid 24
#define TARGET_NR_stime 25
#define TARGET_NR_ptrace 26
#define TARGET_NR_alarm 27
#define TARGET_NR_oldfstat 28
#define TARGET_NR_pause 29
#define TARGET_NR_utime 30
#define TARGET_NR_stty 31
#define TARGET_NR_gtty 32
#define TARGET_NR_access 33
#define TARGET_NR_nice 34
#define TARGET_NR_ftime 35
#define TARGET_NR_sync 36
#define TARGET_NR_kill 37
#define TARGET_NR_rename 38
#define TARGET_NR_mkdir 39
#define TARGET_NR_rmdir 40
#define TARGET_NR_dup 41
#define TARGET_NR_pipe 42
#define TARGET_NR_times 43
#define TARGET_NR_prof 44
#define TARGET_NR_brk 45
#define TARGET_NR_setgid 46
#define TARGET_NR_getgid 47
#define TARGET_NR_signal 48
#define TARGET_NR_geteuid 49
#define TARGET_NR_getegid 50
#define TARGET_NR_acct 51
#define TARGET_NR_umount2 52
#define TARGET_NR_lock 53
#define TARGET_NR_ioctl 54
#define TARGET_NR_fcntl 55
#define TARGET_NR_mpx 56
#define TARGET_NR_setpgid 57
#define TARGET_NR_ulimit 58
#define TARGET_NR_oldolduname 59
#define TARGET_NR_umask 60
#define TARGET_NR_chroot 61
#define TARGET_NR_ustat 62
#define TARGET_NR_dup2 63
#define TARGET_NR_getppid 64
#define TARGET_NR_getpgrp 65
#define TARGET_NR_setsid 66
#define TARGET_NR_sigaction 67
#define TARGET_NR_sgetmask 68
#define TARGET_NR_ssetmask 69
#define TARGET_NR_setreuid 70
#define TARGET_NR_setregid 71
#define TARGET_NR_sigsuspend 72
#define TARGET_NR_sigpending 73
#define TARGET_NR_sethostname 74
#define TARGET_NR_setrlimit 75
#define TARGET_NR_getrlimit 76
#define TARGET_NR_getrusage 77
#define TARGET_NR_gettimeofday 78
#define TARGET_NR_settimeofday 79
#define TARGET_NR_getgroups 80
#define TARGET_NR_setgroups 81
#define TARGET_NR_select 82
#define TARGET_NR_symlink 83
#define TARGET_NR_oldlstat 84
#define TARGET_NR_readlink 85
#define TARGET_NR_uselib 86
#define TARGET_NR_swapon 87
#define TARGET_NR_reboot 88
#define TARGET_NR_readdir 89
#define TARGET_NR_mmap 90
#define TARGET_NR_munmap 91
#define TARGET_NR_truncate 92
#define TARGET_NR_ftruncate 93
#define TARGET_NR_fchmod 94
#define TARGET_NR_fchown 95
#define TARGET_NR_getpriority 96
#define TARGET_NR_setpriority 97
#define TARGET_NR_profil 98
#define TARGET_NR_statfs 99
#define TARGET_NR_fstatfs 100
#define TARGET_NR_ioperm 101
#define TARGET_NR_socketcall 102
#define TARGET_NR_syslog 103
#define TARGET_NR_setitimer 104
#define TARGET_NR_getitimer 105
#define TARGET_NR_stat 106
#define TARGET_NR_lstat 107
#define TARGET_NR_fstat 108
#define TARGET_NR_olduname 109
#define TARGET_NR_iopl 110
#define TARGET_NR_vhangup 111
#define TARGET_NR_idle 112
#define TARGET_NR_vm86 113
#define TARGET_NR_wait4 114
#define TARGET_NR_swapoff 115
#define TARGET_NR_sysinfo 116
#define TARGET_NR_ipc 117
#define TARGET_NR_fsync 118
#define TARGET_NR_sigreturn 119
#define TARGET_NR_clone 120
#define TARGET_NR_setdomainname 121
#define TARGET_NR_uname 122
#define TARGET_NR_modify_ldt 123
#define TARGET_NR_adjtimex 124
#define TARGET_NR_mprotect 125
#define TARGET_NR_sigprocmask 126
#define TARGET_NR_create_module 127
#define TARGET_NR_init_module 128
#define TARGET_NR_delete_module 129
#define TARGET_NR_get_kernel_syms 130
#define TARGET_NR_quotactl 131
#define TARGET_NR_getpgid 132
#define TARGET_NR_fchdir 133
#define TARGET_NR_bdflush 134
#define TARGET_NR_sysfs 135
#define TARGET_NR_personality 136
#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */
#define TARGET_NR_setfsuid 138
#define TARGET_NR_setfsgid 139
#define TARGET_NR__llseek 140
#define TARGET_NR_getdents 141
#define TARGET_NR__newselect 142
#define TARGET_NR_flock 143
#define TARGET_NR_msync 144
#define TARGET_NR_readv 145
#define TARGET_NR_writev 146
#define TARGET_NR_getsid 147
#define TARGET_NR_fdatasync 148
#define TARGET_NR__sysctl 149
#define TARGET_NR_mlock 150
#define TARGET_NR_munlock 151
#define TARGET_NR_mlockall 152
#define TARGET_NR_munlockall 153
#define TARGET_NR_sched_setparam 154
#define TARGET_NR_sched_getparam 155
#define TARGET_NR_sched_setscheduler 156
#define TARGET_NR_sched_getscheduler 157
#define TARGET_NR_sched_yield 158
#define TARGET_NR_sched_get_priority_max 159
#define TARGET_NR_sched_get_priority_min 160
#define TARGET_NR_sched_rr_get_interval 161
#define TARGET_NR_nanosleep 162
#define TARGET_NR_mremap 163
#define TARGET_NR_setresuid 164
#define TARGET_NR_getresuid 165
#define TARGET_NR_query_module 167
#define TARGET_NR_poll 168
#define TARGET_NR_nfsservctl 169
#define TARGET_NR_setresgid 170
#define TARGET_NR_getresgid 171
#define TARGET_NR_prctl 172
#define TARGET_NR_rt_sigreturn 173
#define TARGET_NR_rt_sigaction 174
#define TARGET_NR_rt_sigprocmask 175
#define TARGET_NR_rt_sigpending 176
#define TARGET_NR_rt_sigtimedwait 177
#define TARGET_NR_rt_sigqueueinfo 178
#define TARGET_NR_rt_sigsuspend 179
#define TARGET_NR_pread64 180
#define TARGET_NR_pwrite64 181
#define TARGET_NR_chown 182
#define TARGET_NR_getcwd 183
#define TARGET_NR_capget 184
#define TARGET_NR_capset 185
#define TARGET_NR_sigaltstack 186
#define TARGET_NR_sendfile 187
#define TARGET_NR_getpmsg 188 /* some people actually want streams */
#define TARGET_NR_putpmsg 189 /* some people actually want streams */
#define TARGET_NR_vfork 190
#define TARGET_NR_ugetrlimit 191 /* SuS compliant getrlimit */
#define TARGET_NR_mmap2 192
#define TARGET_NR_truncate64 193
#define TARGET_NR_ftruncate64 194
#define TARGET_NR_stat64 195
#define TARGET_NR_lstat64 196
#define TARGET_NR_fstat64 197
#define TARGET_NR_lchown32 198
#define TARGET_NR_getuid32 199
#define TARGET_NR_getgid32 200
#define TARGET_NR_geteuid32 201
#define TARGET_NR_getegid32 202
#define TARGET_NR_setreuid32 203
#define TARGET_NR_setregid32 204
#define TARGET_NR_getgroups32 205
#define TARGET_NR_setgroups32 206
#define TARGET_NR_fchown32 207
#define TARGET_NR_setresuid32 208
#define TARGET_NR_getresuid32 209
#define TARGET_NR_setresgid32 210
#define TARGET_NR_getresgid32 211
#define TARGET_NR_chown32 212
#define TARGET_NR_setuid32 213
#define TARGET_NR_setgid32 214
#define TARGET_NR_setfsuid32 215
#define TARGET_NR_setfsgid32 216
#define TARGET_NR_pivot_root 217
#define TARGET_NR_mincore 218
#define TARGET_NR_madvise 219
#define TARGET_NR_getdents64 220
#define TARGET_NR_fcntl64 221
/* 223 is unused */
#define TARGET_NR_gettid 224
#define TARGET_NR_readahead 225
#define TARGET_NR_setxattr 226
#define TARGET_NR_lsetxattr 227
#define TARGET_NR_fsetxattr 228
#define TARGET_NR_getxattr 229
#define TARGET_NR_lgetxattr 230
#define TARGET_NR_fgetxattr 231
#define TARGET_NR_listxattr 232
#define TARGET_NR_llistxattr 233
#define TARGET_NR_flistxattr 234
#define TARGET_NR_removexattr 235
#define TARGET_NR_lremovexattr 236
#define TARGET_NR_fremovexattr 237
#define TARGET_NR_tkill 238
#define TARGET_NR_sendfile64 239
#define TARGET_NR_futex 240
#define TARGET_NR_sched_setaffinity 241
#define TARGET_NR_sched_getaffinity 242
#define TARGET_NR_set_thread_area 243
#define TARGET_NR_get_thread_area 244
#define TARGET_NR_io_setup 245
#define TARGET_NR_io_destroy 246
#define TARGET_NR_io_getevents 247
#define TARGET_NR_io_submit 248
#define TARGET_NR_io_cancel 249
#define TARGET_NR_fadvise64 250
#define TARGET_NR_exit_group 252
#define TARGET_NR_lookup_dcookie 253
#define TARGET_NR_epoll_create 254
#define TARGET_NR_epoll_ctl 255
#define TARGET_NR_epoll_wait 256
#define TARGET_NR_remap_file_pages 257
#define TARGET_NR_set_tid_address 258
#define TARGET_NR_timer_create 259
#define TARGET_NR_timer_settime (TARGET_NR_timer_create+1)
#define TARGET_NR_timer_gettime (TARGET_NR_timer_create+2)
#define TARGET_NR_timer_getoverrun (TARGET_NR_timer_create+3)
#define TARGET_NR_timer_delete (TARGET_NR_timer_create+4)
#define TARGET_NR_clock_settime (TARGET_NR_timer_create+5)
#define TARGET_NR_clock_gettime (TARGET_NR_timer_create+6)
#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7)
#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8)
#define TARGET_NR_statfs64 268
#define TARGET_NR_fstatfs64 269
#define TARGET_NR_tgkill 270
#define TARGET_NR_utimes 271
#define TARGET_NR_fadvise64_64 272
#define TARGET_NR_vserver 273
#define TARGET_NR_mbind 274
#define TARGET_NR_get_mempolicy 275
#define TARGET_NR_set_mempolicy 276
#define TARGET_NR_mq_open 277
#define TARGET_NR_mq_unlink (TARGET_NR_mq_open+1)
#define TARGET_NR_mq_timedsend (TARGET_NR_mq_open+2)
#define TARGET_NR_mq_timedreceive (TARGET_NR_mq_open+3)
#define TARGET_NR_mq_notify (TARGET_NR_mq_open+4)
#define TARGET_NR_mq_getsetattr (TARGET_NR_mq_open+5)
#define TARGET_NR_kexec_load 283
#define TARGET_NR_waitid 284
/* #define TARGET_NR_sys_setaltroot 285 */
#define TARGET_NR_add_key 286
#define TARGET_NR_request_key 287
#define TARGET_NR_keyctl 288
#define TARGET_NR_ioprio_set 289
#define TARGET_NR_ioprio_get 290
#define TARGET_NR_inotify_init 291
#define TARGET_NR_inotify_add_watch 292
#define TARGET_NR_inotify_rm_watch 293
#define TARGET_NR_migrate_pages 294
#define TARGET_NR_openat 295
#define TARGET_NR_mkdirat 296
#define TARGET_NR_mknodat 297
#define TARGET_NR_fchownat 298
#define TARGET_NR_futimesat 299
#define TARGET_NR_fstatat64 300
#define TARGET_NR_unlinkat 301
#define TARGET_NR_renameat 302
#define TARGET_NR_linkat 303
#define TARGET_NR_symlinkat 304
#define TARGET_NR_readlinkat 305
#define TARGET_NR_fchmodat 306
#define TARGET_NR_faccessat 307
#define TARGET_NR_pselect6 308
#define TARGET_NR_ppoll 309
#define TARGET_NR_unshare 310
#define TARGET_NR_set_robust_list 311
#define TARGET_NR_get_robust_list 312
#define TARGET_NR_splice 313
#define TARGET_NR_sync_file_range 314
#define TARGET_NR_tee 315
#define TARGET_NR_vmsplice 316
#define TARGET_NR_move_pages 317
#define TARGET_NR_getcpu 318
#define TARGET_NR_epoll_pwait 319
#define TARGET_NR_utimensat 320
#define TARGET_NR_signalfd 321
#define TARGET_NR_timerfd_create 322
#define TARGET_NR_eventfd 323
#define TARGET_NR_fallocate 324
#define TARGET_NR_timerfd_settime 325
#define TARGET_NR_timerfd_gettime 326
#define TARGET_NR_signalfd4 327
#define TARGET_NR_eventfd2 328
#define TARGET_NR_epoll_create1 329
#define TARGET_NR_dup3 330
#define TARGET_NR_pipe2 331
#define TARGET_NR_inotify_init1 332
#define TARGET_NR_preadv 333
#define TARGET_NR_pwritev 334
#define TARGET_NR_setns 335
#define TARGET_NR_name_to_handle_at 336
#define TARGET_NR_open_by_handle_at 337
#define TARGET_NR_rt_tgsigqueueinfo 338
#define TARGET_NR_perf_event_open 339
#define TARGET_NR_recvmmsg 340
#define TARGET_NR_accept4 341
#define TARGET_NR_fanotify_init 342
#define TARGET_NR_fanotify_mark 343
#define TARGET_NR_prlimit64 344
#define TARGET_NR_clock_adjtime 345
#define TARGET_NR_syncfs 346
#define TARGET_NR_sendmmsg 347
#define TARGET_NR_process_vm_readv 348
#define TARGET_NR_process_vm_writev 349
#define TARGET_NR_kcmp 350
#define TARGET_NR_finit_module 351
#define TARGET_NR_sched_setattr 352
#define TARGET_NR_sched_getattr 353
#define TARGET_NR_renameat2 354
#define TARGET_NR_seccomp 355
#define TARGET_NR_getrandom 356
#define TARGET_NR_memfd_create 357
#define TARGET_NR_bpf 358
#define TARGET_NR_execveat 359
#endif

View File

@ -1,45 +0,0 @@
/*
* CRIS specific CPU ABI and functions for linux-user
*
* Copyright (c) 2007 AXIS Communications AB
* Written by Edgar E. Iglesias
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CRIS_TARGET_CPU_H
#define CRIS_TARGET_CPU_H
static inline void cpu_clone_regs_child(CPUCRISState *env, target_ulong newsp,
unsigned flags)
{
if (newsp) {
env->regs[14] = newsp;
}
env->regs[10] = 0;
}
static inline void cpu_clone_regs_parent(CPUCRISState *env, unsigned flags)
{
}
static inline void cpu_set_tls(CPUCRISState *env, target_ulong newtls)
{
env->pregs[PR_PID] = (env->pregs[PR_PID] & 0xff) | newtls;
}
static inline abi_ulong get_sp_from_cpustate(CPUCRISState *state)
{
return state->regs[14];
}
#endif

View File

@ -1,14 +0,0 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation, or (at your option) any
* later version. See the COPYING file in the top-level directory.
*/
#ifndef CRIS_TARGET_ELF_H
#define CRIS_TARGET_ELF_H
static inline const char *cpu_get_model(uint32_t eflags)
{
return "any";
}
#endif

View File

@ -1,7 +0,0 @@
#ifndef CRIS_TARGET_ERRNO_DEFS_H
#define CRIS_TARGET_ERRNO_DEFS_H
/* Target uses generic errno */
#include "../generic/target_errno_defs.h"
#endif

View File

@ -1,11 +0,0 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation, or (at your option) any
* later version. See the COPYING file in the top-level directory.
*/
#ifndef CRIS_TARGET_FCNTL_H
#define CRIS_TARGET_FCNTL_H
#include "../generic/fcntl.h"
#endif

View File

@ -1,13 +0,0 @@
/*
* arch/cris/include/asm/processor.h:
* TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
*
* arch/cris/include/arch-v32/arch/processor.h
* TASK_SIZE 0xb0000000
*/
#define TASK_UNMAPPED_BASE TARGET_PAGE_ALIGN(0xb0000000 / 3)
/* arch/cris/include/uapi/asm/elf.h */
#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2)
#include "../generic/target_mman.h"

View File

@ -1 +0,0 @@
/* No special prctl support required. */

View File

@ -1 +0,0 @@
/* No target-specific /proc support */

View File

@ -1 +0,0 @@
#include "../generic/target_resource.h"

View File

@ -1,9 +0,0 @@
#ifndef CRIS_TARGET_SIGNAL_H
#define CRIS_TARGET_SIGNAL_H
#include "../generic/signal.h"
#define TARGET_ARCH_HAS_SETUP_FRAME
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
#endif /* CRIS_TARGET_SIGNAL_H */

View File

@ -1 +0,0 @@
#include "../generic/target_structs.h"

View File

@ -1,46 +0,0 @@
#ifndef CRIS_TARGET_SYSCALL_H
#define CRIS_TARGET_SYSCALL_H
#define UNAME_MACHINE "cris"
#define UNAME_MINIMUM_RELEASE "2.6.32"
/* pt_regs not only specifies the format in the user-struct during
* ptrace but is also the frame format used in the kernel prologue/epilogues
* themselves
*/
struct target_pt_regs {
unsigned long orig_r10;
/* pushed by movem r13, [sp] in SAVE_ALL. */
unsigned long r0;
unsigned long r1;
unsigned long r2;
unsigned long r3;
unsigned long r4;
unsigned long r5;
unsigned long r6;
unsigned long r7;
unsigned long r8;
unsigned long r9;
unsigned long r10;
unsigned long r11;
unsigned long r12;
unsigned long r13;
unsigned long acr;
unsigned long srs;
unsigned long mof;
unsigned long spc;
unsigned long ccs;
unsigned long srp;
unsigned long erp; /* This is actually the debugged process's PC */
/* For debugging purposes; saved only when needed. */
unsigned long exs;
unsigned long eda;
};
#define TARGET_CLONE_BACKWARDS2
#define TARGET_MCL_CURRENT 1
#define TARGET_MCL_FUTURE 2
#define TARGET_MCL_ONFAULT 4
#endif

View File

@ -1,225 +0,0 @@
/* from asm/termbits.h */
#ifndef LINUX_USER_CRIS_TERMBITS_H
#define LINUX_USER_CRIS_TERMBITS_H
#define TARGET_NCCS 19
typedef unsigned char target_cc_t; /* cc_t */
typedef unsigned int target_speed_t; /* speed_t */
typedef unsigned int target_tcflag_t; /* tcflag_t */
struct target_termios {
target_tcflag_t c_iflag; /* input mode flags */
target_tcflag_t c_oflag; /* output mode flags */
target_tcflag_t c_cflag; /* control mode flags */
target_tcflag_t c_lflag; /* local mode flags */
target_cc_t c_line; /* line discipline */
target_cc_t c_cc[TARGET_NCCS]; /* control characters */
};
/* c_iflag bits */
#define TARGET_IGNBRK 0000001
#define TARGET_BRKINT 0000002
#define TARGET_IGNPAR 0000004
#define TARGET_PARMRK 0000010
#define TARGET_INPCK 0000020
#define TARGET_ISTRIP 0000040
#define TARGET_INLCR 0000100
#define TARGET_IGNCR 0000200
#define TARGET_ICRNL 0000400
#define TARGET_IUCLC 0001000
#define TARGET_IXON 0002000
#define TARGET_IXANY 0004000
#define TARGET_IXOFF 0010000
#define TARGET_IMAXBEL 0020000
#define TARGET_IUTF8 0040000
/* c_oflag bits */
#define TARGET_OPOST 0000001
#define TARGET_OLCUC 0000002
#define TARGET_ONLCR 0000004
#define TARGET_OCRNL 0000010
#define TARGET_ONOCR 0000020
#define TARGET_ONLRET 0000040
#define TARGET_OFILL 0000100
#define TARGET_OFDEL 0000200
#define TARGET_NLDLY 0000400
#define TARGET_NL0 0000000
#define TARGET_NL1 0000400
#define TARGET_CRDLY 0003000
#define TARGET_CR0 0000000
#define TARGET_CR1 0001000
#define TARGET_CR2 0002000
#define TARGET_CR3 0003000
#define TARGET_TABDLY 0014000
#define TARGET_TAB0 0000000
#define TARGET_TAB1 0004000
#define TARGET_TAB2 0010000
#define TARGET_TAB3 0014000
#define TARGET_XTABS 0014000
#define TARGET_BSDLY 0020000
#define TARGET_BS0 0000000
#define TARGET_BS1 0020000
#define TARGET_VTDLY 0040000
#define TARGET_VT0 0000000
#define TARGET_VT1 0040000
#define TARGET_FFDLY 0100000
#define TARGET_FF0 0000000
#define TARGET_FF1 0100000
/* c_cflag bit meaning */
#define TARGET_CBAUD 0010017
#define TARGET_B0 0000000 /* hang up */
#define TARGET_B50 0000001
#define TARGET_B75 0000002
#define TARGET_B110 0000003
#define TARGET_B134 0000004
#define TARGET_B150 0000005
#define TARGET_B200 0000006
#define TARGET_B300 0000007
#define TARGET_B600 0000010
#define TARGET_B1200 0000011
#define TARGET_B1800 0000012
#define TARGET_B2400 0000013
#define TARGET_B4800 0000014
#define TARGET_B9600 0000015
#define TARGET_B19200 0000016
#define TARGET_B38400 0000017
#define TARGET_EXTA B19200
#define TARGET_EXTB B38400
#define TARGET_CSIZE 0000060
#define TARGET_CS5 0000000
#define TARGET_CS6 0000020
#define TARGET_CS7 0000040
#define TARGET_CS8 0000060
#define TARGET_CSTOPB 0000100
#define TARGET_CREAD 0000200
#define TARGET_PARENB 0000400
#define TARGET_PARODD 0001000
#define TARGET_HUPCL 0002000
#define TARGET_CLOCAL 0004000
#define TARGET_CBAUDEX 0010000
#define TARGET_B57600 0010001
#define TARGET_B115200 0010002
#define TARGET_B230400 0010003
#define TARGET_B460800 0010004
#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */
#define TARGET_CRTSCTS 020000000000 /* flow control */
/* c_lflag bits */
#define TARGET_ISIG 0000001
#define TARGET_ICANON 0000002
#define TARGET_XCASE 0000004
#define TARGET_ECHO 0000010
#define TARGET_ECHOE 0000020
#define TARGET_ECHOK 0000040
#define TARGET_ECHONL 0000100
#define TARGET_NOFLSH 0000200
#define TARGET_TOSTOP 0000400
#define TARGET_ECHOCTL 0001000
#define TARGET_ECHOPRT 0002000
#define TARGET_ECHOKE 0004000
#define TARGET_FLUSHO 0010000
#define TARGET_PENDIN 0040000
#define TARGET_IEXTEN 0100000
#define TARGET_EXTPROC 0200000
/* c_cc character offsets */
#define TARGET_VINTR 0
#define TARGET_VQUIT 1
#define TARGET_VERASE 2
#define TARGET_VKILL 3
#define TARGET_VEOF 4
#define TARGET_VTIME 5
#define TARGET_VMIN 6
#define TARGET_VSWTC 7
#define TARGET_VSTART 8
#define TARGET_VSTOP 9
#define TARGET_VSUSP 10
#define TARGET_VEOL 11
#define TARGET_VREPRINT 12
#define TARGET_VDISCARD 13
#define TARGET_VWERASE 14
#define TARGET_VLNEXT 15
#define TARGET_VEOL2 16
/* ioctls */
#define TARGET_TCGETS 0x5401
#define TARGET_TCSETS 0x5402
#define TARGET_TCSETSW 0x5403
#define TARGET_TCSETSF 0x5404
#define TARGET_TCGETA 0x5405
#define TARGET_TCSETA 0x5406
#define TARGET_TCSETAW 0x5407
#define TARGET_TCSETAF 0x5408
#define TARGET_TCSBRK 0x5409
#define TARGET_TCXONC 0x540A
#define TARGET_TCFLSH 0x540B
#define TARGET_TIOCEXCL 0x540C
#define TARGET_TIOCNXCL 0x540D
#define TARGET_TIOCSCTTY 0x540E
#define TARGET_TIOCGPGRP 0x540F
#define TARGET_TIOCSPGRP 0x5410
#define TARGET_TIOCOUTQ 0x5411
#define TARGET_TIOCSTI 0x5412
#define TARGET_TIOCGWINSZ 0x5413
#define TARGET_TIOCSWINSZ 0x5414
#define TARGET_TIOCMGET 0x5415
#define TARGET_TIOCMBIS 0x5416
#define TARGET_TIOCMBIC 0x5417
#define TARGET_TIOCMSET 0x5418
#define TARGET_TIOCGSOFTCAR 0x5419
#define TARGET_TIOCSSOFTCAR 0x541A
#define TARGET_FIONREAD 0x541B
#define TARGET_TIOCINQ TARGET_FIONREAD
#define TARGET_TIOCLINUX 0x541C
#define TARGET_TIOCCONS 0x541D
#define TARGET_TIOCGSERIAL 0x541E
#define TARGET_TIOCSSERIAL 0x541F
#define TARGET_TIOCPKT 0x5420
#define TARGET_FIONBIO 0x5421
#define TARGET_TIOCNOTTY 0x5422
#define TARGET_TIOCSETD 0x5423
#define TARGET_TIOCGETD 0x5424
#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */
#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) /* Safely open the slave */
#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */
#define TARGET_FIOCLEX 0x5451
#define TARGET_FIOASYNC 0x5452
#define TARGET_TIOCSERCONFIG 0x5453
#define TARGET_TIOCSERGWILD 0x5454
#define TARGET_TIOCSERSWILD 0x5455
#define TARGET_TIOCGLCKTRMIOS 0x5456
#define TARGET_TIOCSLCKTRMIOS 0x5457
#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */
#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */
#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */
#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
/* Used for packet mode */
#define TARGET_TIOCPKT_DATA 0
#define TARGET_TIOCPKT_FLUSHREAD 1
#define TARGET_TIOCPKT_FLUSHWRITE 2
#define TARGET_TIOCPKT_STOP 4
#define TARGET_TIOCPKT_START 8
#define TARGET_TIOCPKT_NOSTOP 16
#define TARGET_TIOCPKT_DOSTOP 32
#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
#endif

View File

@ -1647,21 +1647,6 @@ static uint32_t get_elf_hwcap(void)
#endif
#ifdef TARGET_CRIS
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_CRIS
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
regs->erp = infop->entry;
}
#define ELF_EXEC_PAGESIZE 8192
#endif
#ifdef TARGET_M68K
#define ELF_CLASS ELFCLASS32

View File

@ -10484,7 +10484,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
case TARGET_NR_mmap:
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
(defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
defined(TARGET_M68K) || defined(TARGET_MICROBLAZE) \
|| defined(TARGET_S390X)
{
abi_ulong *v;
@ -12638,14 +12638,6 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
#if defined(TARGET_MIPS)
cpu_env->active_tc.CP0_UserLocal = arg1;
return 0;
#elif defined(TARGET_CRIS)
if (arg1 & 0xff)
ret = -TARGET_EINVAL;
else {
cpu_env->pregs[PR_PID] = arg1;
ret = 0;
}
return ret;
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
return do_set_thread_area(cpu_env, arg1);
#elif defined(TARGET_M68K)

View File

@ -62,7 +62,7 @@
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) \
|| (defined(TARGET_ARM) && defined(TARGET_ABI32)) \
|| (defined(TARGET_SPARC) && defined(TARGET_ABI32)) \
|| defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
|| defined(TARGET_M68K) || defined(TARGET_SH4)
/* 16 bit uid wrappers emulation */
#define USE_UID16
#define target_id uint16_t
@ -71,7 +71,7 @@
#endif
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
|| defined(TARGET_M68K) || defined(TARGET_CRIS) \
|| defined(TARGET_M68K) \
|| defined(TARGET_S390X) || defined(TARGET_OPENRISC) \
|| defined(TARGET_RISCV) \
|| defined(TARGET_XTENSA) || defined(TARGET_LOONGARCH64)
@ -1234,8 +1234,7 @@ struct target_winsize {
#include "target_mman.h"
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) \
|| (defined(TARGET_ARM) && defined(TARGET_ABI32)) \
|| defined(TARGET_CRIS)
|| (defined(TARGET_ARM) && defined(TARGET_ABI32))
#define TARGET_STAT_HAVE_NSEC
struct target_stat {
abi_ushort st_dev;

View File

@ -33,7 +33,7 @@
# Since: 3.0
##
{ 'enum' : 'SysEmuTarget',
'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386',
'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'hppa', 'i386',
'loongarch64', 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
'mips64el', 'mipsel', 'or1k', 'ppc',
'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4',

View File

@ -9,9 +9,6 @@ arm
avr
~ .*/qemu((/include)?/hw/avr/.*|/target/avr/.*)
cris
~ .*/qemu((/include)?/hw/cris/.*|/target/cris/.*)
hexagon-gen (component should be ignored in analysis)
~ .*/qemu(/target/hexagon/.*generated.*)

View File

@ -28,7 +28,6 @@ mappings = {
"armv7": "arm",
"armv8-a" : ["aarch64", "aarch64_be"],
"avr" : "avr",
"cris" : "cris",
# no hexagon in upstream gdb
"hppa1.0" : "hppa",
"i386" : "i386",

View File

@ -47,10 +47,10 @@ const struct scmp_arg_cmp sched_setscheduler_arg[] = {
};
/*
* See 'NOTES' in 'man 2 clone' - s390 & cross have 'flags' in
* See 'NOTES' in 'man 2 clone' - s390 has 'flags' in
* different position to other architectures
*/
#if defined(HOST_S390X) || defined(HOST_S390) || defined(HOST_CRIS)
#if defined(HOST_S390X) || defined(HOST_S390)
#define CLONE_FLAGS_ARG 1
#else
#define CLONE_FLAGS_ARG 0

View File

@ -62,7 +62,7 @@ static time_t qemu_ref_timedate(QEMUClockType clock)
}
break;
default:
assert(0);
g_assert_not_reached();
}
return value;
}

View File

@ -1,7 +1,6 @@
source alpha/Kconfig
source arm/Kconfig
source avr/Kconfig
source cris/Kconfig
source hppa/Kconfig
source i386/Kconfig
source loongarch/Kconfig

View File

@ -1,2 +0,0 @@
config CRIS
bool

View File

@ -1,16 +0,0 @@
/*
* CRIS cpu parameters for qemu.
*
* Copyright (c) 2007 AXIS Communications AB
* SPDX-License-Identifier: LGPL-2.0+
*/
#ifndef CRIS_CPU_PARAM_H
#define CRIS_CPU_PARAM_H
#define TARGET_LONG_BITS 32
#define TARGET_PAGE_BITS 13
#define TARGET_PHYS_ADDR_SPACE_BITS 32
#define TARGET_VIRT_ADDR_SPACE_BITS 32
#endif

View File

@ -1,32 +0,0 @@
/*
* QEMU CRIS CPU QOM header (target agnostic)
*
* Copyright (c) 2012 SUSE LINUX Products GmbH
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>
*/
#ifndef QEMU_CRIS_CPU_QOM_H
#define QEMU_CRIS_CPU_QOM_H
#include "hw/core/cpu.h"
#define TYPE_CRIS_CPU "cris-cpu"
OBJECT_DECLARE_CPU_TYPE(CRISCPU, CRISCPUClass, CRIS_CPU)
#define CRIS_CPU_TYPE_SUFFIX "-" TYPE_CRIS_CPU
#define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX)
#endif

View File

@ -1,323 +0,0 @@
/*
* QEMU CRIS CPU
*
* Copyright (c) 2008 AXIS Communications AB
* Written by Edgar E. Iglesias.
*
* Copyright (c) 2012 SUSE LINUX Products GmbH
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/qemu-print.h"
#include "cpu.h"
#include "mmu.h"
static void cris_cpu_set_pc(CPUState *cs, vaddr value)
{
CRISCPU *cpu = CRIS_CPU(cs);
cpu->env.pc = value;
}
static vaddr cris_cpu_get_pc(CPUState *cs)
{
CRISCPU *cpu = CRIS_CPU(cs);
return cpu->env.pc;
}
static void cris_restore_state_to_opc(CPUState *cs,
const TranslationBlock *tb,
const uint64_t *data)
{
CRISCPU *cpu = CRIS_CPU(cs);
cpu->env.pc = data[0];
}
static bool cris_cpu_has_work(CPUState *cs)
{
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
}
static int cris_cpu_mmu_index(CPUState *cs, bool ifetch)
{
return !!(cpu_env(cs)->pregs[PR_CCS] & U_FLAG);
}
static void cris_cpu_reset_hold(Object *obj, ResetType type)
{
CPUState *cs = CPU(obj);
CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj);
CPUCRISState *env = cpu_env(cs);
uint32_t vr;
if (ccc->parent_phases.hold) {
ccc->parent_phases.hold(obj, type);
}
vr = env->pregs[PR_VR];
memset(env, 0, offsetof(CPUCRISState, end_reset_fields));
env->pregs[PR_VR] = vr;
#if defined(CONFIG_USER_ONLY)
/* start in user mode with interrupts enabled. */
env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG;
#else
cris_mmu_init(env);
env->pregs[PR_CCS] = 0;
#endif
}
static ObjectClass *cris_cpu_class_by_name(const char *cpu_model)
{
ObjectClass *oc;
char *typename;
#if defined(CONFIG_USER_ONLY)
if (strcasecmp(cpu_model, "any") == 0) {
return object_class_by_name(CRIS_CPU_TYPE_NAME("crisv32"));
}
#endif
typename = g_strdup_printf(CRIS_CPU_TYPE_NAME("%s"), cpu_model);
oc = object_class_by_name(typename);
g_free(typename);
return oc;
}
static void cris_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(dev);
Error *local_err = NULL;
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
}
cpu_reset(cs);
qemu_init_vcpu(cs);
ccc->parent_realize(dev, errp);
}
#ifndef CONFIG_USER_ONLY
static void cris_cpu_set_irq(void *opaque, int irq, int level)
{
CRISCPU *cpu = opaque;
CPUState *cs = CPU(cpu);
int type = irq == CRIS_CPU_IRQ ? CPU_INTERRUPT_HARD : CPU_INTERRUPT_NMI;
if (irq == CRIS_CPU_IRQ) {
/*
* The PIC passes us the vector for the IRQ as the value it sends
* over the qemu_irq line
*/
cpu->env.interrupt_vector = level;
}
if (level) {
cpu_interrupt(cs, type);
} else {
cpu_reset_interrupt(cs, type);
}
}
#endif
static void cris_disas_set_info(CPUState *cpu, disassemble_info *info)
{
if (cpu_env(cpu)->pregs[PR_VR] != 32) {
info->mach = bfd_mach_cris_v0_v10;
info->print_insn = print_insn_crisv10;
} else {
info->mach = bfd_mach_cris_v32;
info->print_insn = print_insn_crisv32;
}
}
static void cris_cpu_initfn(Object *obj)
{
CRISCPU *cpu = CRIS_CPU(obj);
CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj);
CPUCRISState *env = &cpu->env;
env->pregs[PR_VR] = ccc->vr;
#ifndef CONFIG_USER_ONLY
/* IRQ and NMI lines. */
qdev_init_gpio_in(DEVICE(cpu), cris_cpu_set_irq, 2);
#endif
}
#ifndef CONFIG_USER_ONLY
#include "hw/core/sysemu-cpu-ops.h"
static const struct SysemuCPUOps cris_sysemu_ops = {
.get_phys_page_debug = cris_cpu_get_phys_page_debug,
};
#endif
#include "hw/core/tcg-cpu-ops.h"
static const TCGCPUOps crisv10_tcg_ops = {
.initialize = cris_initialize_crisv10_tcg,
.restore_state_to_opc = cris_restore_state_to_opc,
#ifndef CONFIG_USER_ONLY
.tlb_fill = cris_cpu_tlb_fill,
.cpu_exec_interrupt = cris_cpu_exec_interrupt,
.cpu_exec_halt = cris_cpu_has_work,
.do_interrupt = crisv10_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */
};
static const TCGCPUOps crisv32_tcg_ops = {
.initialize = cris_initialize_tcg,
.restore_state_to_opc = cris_restore_state_to_opc,
#ifndef CONFIG_USER_ONLY
.tlb_fill = cris_cpu_tlb_fill,
.cpu_exec_interrupt = cris_cpu_exec_interrupt,
.cpu_exec_halt = cris_cpu_has_work,
.do_interrupt = cris_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */
};
static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 8;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
cc->tcg_ops = &crisv10_tcg_ops;
}
static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 9;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
cc->tcg_ops = &crisv10_tcg_ops;
}
static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 10;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
cc->tcg_ops = &crisv10_tcg_ops;
}
static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 11;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
cc->tcg_ops = &crisv10_tcg_ops;
}
static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 17;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
cc->tcg_ops = &crisv10_tcg_ops;
}
static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 32;
cc->tcg_ops = &crisv32_tcg_ops;
}
static void cris_cpu_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ResettableClass *rc = RESETTABLE_CLASS(oc);
device_class_set_parent_realize(dc, cris_cpu_realizefn,
&ccc->parent_realize);
resettable_class_set_parent_phases(rc, NULL, cris_cpu_reset_hold, NULL,
&ccc->parent_phases);
cc->class_by_name = cris_cpu_class_by_name;
cc->has_work = cris_cpu_has_work;
cc->mmu_index = cris_cpu_mmu_index;
cc->dump_state = cris_cpu_dump_state;
cc->set_pc = cris_cpu_set_pc;
cc->get_pc = cris_cpu_get_pc;
cc->gdb_read_register = cris_cpu_gdb_read_register;
cc->gdb_write_register = cris_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
dc->vmsd = &vmstate_cris_cpu;
cc->sysemu_ops = &cris_sysemu_ops;
#endif
cc->gdb_num_core_regs = 49;
cc->gdb_stop_before_watchpoint = true;
cc->disas_set_info = cris_disas_set_info;
}
#define DEFINE_CRIS_CPU_TYPE(cpu_model, initfn) \
{ \
.parent = TYPE_CRIS_CPU, \
.class_init = initfn, \
.name = CRIS_CPU_TYPE_NAME(cpu_model), \
}
static const TypeInfo cris_cpu_model_type_infos[] = {
{
.name = TYPE_CRIS_CPU,
.parent = TYPE_CPU,
.instance_size = sizeof(CRISCPU),
.instance_align = __alignof(CRISCPU),
.instance_init = cris_cpu_initfn,
.abstract = true,
.class_size = sizeof(CRISCPUClass),
.class_init = cris_cpu_class_init,
},
DEFINE_CRIS_CPU_TYPE("crisv8", crisv8_cpu_class_init),
DEFINE_CRIS_CPU_TYPE("crisv9", crisv9_cpu_class_init),
DEFINE_CRIS_CPU_TYPE("crisv10", crisv10_cpu_class_init),
DEFINE_CRIS_CPU_TYPE("crisv11", crisv11_cpu_class_init),
DEFINE_CRIS_CPU_TYPE("crisv17", crisv17_cpu_class_init),
DEFINE_CRIS_CPU_TYPE("crisv32", crisv32_cpu_class_init),
};
DEFINE_TYPES(cris_cpu_model_type_infos)

View File

@ -1,286 +0,0 @@
/*
* CRIS virtual CPU header
*
* Copyright (c) 2007 AXIS Communications AB
* Written by Edgar E. Iglesias
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CRIS_CPU_H
#define CRIS_CPU_H
#include "cpu-qom.h"
#include "exec/cpu-defs.h"
#define EXCP_NMI 1
#define EXCP_GURU 2
#define EXCP_BUSFAULT 3
#define EXCP_IRQ 4
#define EXCP_BREAK 5
/* CRIS-specific interrupt pending bits. */
#define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3
/* CRUS CPU device objects interrupt lines. */
/* PIC passes the vector for the IRQ as the value of it sends over qemu_irq */
#define CRIS_CPU_IRQ 0
#define CRIS_CPU_NMI 1
/* Register aliases. R0 - R15 */
#define R_FP 8
#define R_SP 14
#define R_ACR 15
/* Support regs, P0 - P15 */
#define PR_BZ 0
#define PR_VR 1
#define PR_PID 2
#define PR_SRS 3
#define PR_WZ 4
#define PR_EXS 5
#define PR_EDA 6
#define PR_PREFIX 6 /* On CRISv10 P6 is reserved, we use it as prefix. */
#define PR_MOF 7
#define PR_DZ 8
#define PR_EBP 9
#define PR_ERP 10
#define PR_SRP 11
#define PR_NRP 12
#define PR_CCS 13
#define PR_USP 14
#define PRV10_BRP 14
#define PR_SPC 15
/* CPU flags. */
#define Q_FLAG 0x80000000
#define M_FLAG_V32 0x40000000
#define PFIX_FLAG 0x800 /* CRISv10 Only. */
#define F_FLAG_V10 0x400
#define P_FLAG_V10 0x200
#define S_FLAG 0x200
#define R_FLAG 0x100
#define P_FLAG 0x80
#define M_FLAG_V10 0x80
#define U_FLAG 0x40
#define I_FLAG 0x20
#define X_FLAG 0x10
#define N_FLAG 0x08
#define Z_FLAG 0x04
#define V_FLAG 0x02
#define C_FLAG 0x01
#define ALU_FLAGS 0x1F
/* Condition codes. */
#define CC_CC 0
#define CC_CS 1
#define CC_NE 2
#define CC_EQ 3
#define CC_VC 4
#define CC_VS 5
#define CC_PL 6
#define CC_MI 7
#define CC_LS 8
#define CC_HI 9
#define CC_GE 10
#define CC_LT 11
#define CC_GT 12
#define CC_LE 13
#define CC_A 14
#define CC_P 15
typedef struct {
uint32_t hi;
uint32_t lo;
} TLBSet;
typedef struct CPUArchState {
uint32_t regs[16];
/* P0 - P15 are referred to as special registers in the docs. */
uint32_t pregs[16];
/* Pseudo register for the PC. Not directly accessible on CRIS. */
uint32_t pc;
/* Pseudo register for the kernel stack. */
uint32_t ksp;
/* Branch. */
int dslot;
int btaken;
uint32_t btarget;
/* Condition flag tracking. */
uint32_t cc_op;
uint32_t cc_mask;
uint32_t cc_dest;
uint32_t cc_src;
uint32_t cc_result;
/* size of the operation, 1 = byte, 2 = word, 4 = dword. */
int cc_size;
/* X flag at the time of cc snapshot. */
int cc_x;
/* CRIS has certain insns that lockout interrupts. */
int locked_irq;
int interrupt_vector;
int fault_vector;
int trap_vector;
/* FIXME: add a check in the translator to avoid writing to support
register sets beyond the 4th. The ISA allows up to 256! but in
practice there is no core that implements more than 4.
Support function registers are used to control units close to the
core. Accesses do not pass down the normal hierarchy.
*/
uint32_t sregs[4][16];
/* Linear feedback shift reg in the mmu. Used to provide pseudo
randomness for the 'hint' the mmu gives to sw for choosing valid
sets on TLB refills. */
uint32_t mmu_rand_lfsr;
/*
* We just store the stores to the tlbset here for later evaluation
* when the hw needs access to them.
*
* One for I and another for D.
*/
TLBSet tlbsets[2][4][16];
/* Fields up to this point are cleared by a CPU reset */
struct {} end_reset_fields;
/* Members from load_info on are preserved across resets. */
void *load_info;
} CPUCRISState;
/**
* CRISCPU:
* @env: #CPUCRISState
*
* A CRIS CPU.
*/
struct ArchCPU {
CPUState parent_obj;
CPUCRISState env;
};
/**
* CRISCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_phases: The parent class' reset phase handlers.
* @vr: Version Register value.
*
* A CRIS CPU model.
*/
struct CRISCPUClass {
CPUClass parent_class;
DeviceRealize parent_realize;
ResettablePhases parent_phases;
uint32_t vr;
};
#ifndef CONFIG_USER_ONLY
extern const VMStateDescription vmstate_cris_cpu;
void cris_cpu_do_interrupt(CPUState *cpu);
void crisv10_cpu_do_interrupt(CPUState *cpu);
bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif
void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
int crisv10_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int cris_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void cris_initialize_tcg(void);
void cris_initialize_crisv10_tcg(void);
/* Instead of computing the condition codes after each CRIS instruction,
* QEMU just stores one operand (called CC_SRC), the result
* (called CC_DEST) and the type of operation (called CC_OP). When the
* condition codes are needed, the condition codes can be calculated
* using this information. Condition codes are not generated if they
* are only needed for conditional branches.
*/
enum {
CC_OP_DYNAMIC, /* Use env->cc_op */
CC_OP_FLAGS,
CC_OP_CMP,
CC_OP_MOVE,
CC_OP_ADD,
CC_OP_ADDC,
CC_OP_MCP,
CC_OP_ADDU,
CC_OP_SUB,
CC_OP_SUBU,
CC_OP_NEG,
CC_OP_BTST,
CC_OP_MULS,
CC_OP_MULU,
CC_OP_DSTEP,
CC_OP_MSTEP,
CC_OP_BOUND,
CC_OP_OR,
CC_OP_AND,
CC_OP_XOR,
CC_OP_LSL,
CC_OP_LSR,
CC_OP_ASR,
CC_OP_LZ
};
/* CRIS uses 8k pages. */
#define MMAP_SHIFT TARGET_PAGE_BITS
#define CPU_RESOLVING_TYPE TYPE_CRIS_CPU
/* MMU modes definitions */
#define MMU_USER_IDX 1
/* Support function regs. */
#define SFR_RW_GC_CFG 0][0
#define SFR_RW_MM_CFG env->pregs[PR_SRS]][0
#define SFR_RW_MM_KBASE_LO env->pregs[PR_SRS]][1
#define SFR_RW_MM_KBASE_HI env->pregs[PR_SRS]][2
#define SFR_R_MM_CAUSE env->pregs[PR_SRS]][3
#define SFR_RW_MM_TLB_SEL env->pregs[PR_SRS]][4
#define SFR_RW_MM_TLB_LO env->pregs[PR_SRS]][5
#define SFR_RW_MM_TLB_HI env->pregs[PR_SRS]][6
#include "exec/cpu-all.h"
static inline void cpu_get_tb_cpu_state(CPUCRISState *env, vaddr *pc,
uint64_t *cs_base, uint32_t *flags)
{
*pc = env->pc;
*cs_base = 0;
*flags = env->dslot |
(env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG
| X_FLAG | PFIX_FLAG));
}
#endif

View File

@ -1,112 +0,0 @@
/*
* CRISv10 insn decoding macros.
*
* Copyright (c) 2010 AXIS Communications AB
* Written by Edgar E. Iglesias.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TARGET_CRIS_CRISV10_DECODE_H
#define TARGET_CRIS_CRISV10_DECODE_H
#define CRISV10_MODE_QIMMEDIATE 0
#define CRISV10_MODE_REG 1
#define CRISV10_MODE_INDIRECT 2
#define CRISV10_MODE_AUTOINC 3
/* Quick Immediate. */
#define CRISV10_QIMM_BCC_R0 0
#define CRISV10_QIMM_BCC_R1 1
#define CRISV10_QIMM_BCC_R2 2
#define CRISV10_QIMM_BCC_R3 3
#define CRISV10_QIMM_BDAP_R0 4
#define CRISV10_QIMM_BDAP_R1 5
#define CRISV10_QIMM_BDAP_R2 6
#define CRISV10_QIMM_BDAP_R3 7
#define CRISV10_QIMM_ADDQ 8
#define CRISV10_QIMM_MOVEQ 9
#define CRISV10_QIMM_SUBQ 10
#define CRISV10_QIMM_CMPQ 11
#define CRISV10_QIMM_ANDQ 12
#define CRISV10_QIMM_ORQ 13
#define CRISV10_QIMM_ASHQ 14
#define CRISV10_QIMM_LSHQ 15
#define CRISV10_REG_ADDX 0
#define CRISV10_REG_MOVX 1
#define CRISV10_REG_SUBX 2
#define CRISV10_REG_LSL 3
#define CRISV10_REG_ADDI 4
#define CRISV10_REG_BIAP 5
#define CRISV10_REG_NEG 6
#define CRISV10_REG_BOUND 7
#define CRISV10_REG_ADD 8
#define CRISV10_REG_MOVE_R 9
#define CRISV10_REG_MOVE_SPR_R 9
#define CRISV10_REG_MOVE_R_SPR 8
#define CRISV10_REG_SUB 10
#define CRISV10_REG_CMP 11
#define CRISV10_REG_AND 12
#define CRISV10_REG_OR 13
#define CRISV10_REG_ASR 14
#define CRISV10_REG_LSR 15
#define CRISV10_REG_BTST 3
#define CRISV10_REG_SCC 4
#define CRISV10_REG_SETF 6
#define CRISV10_REG_CLEARF 7
#define CRISV10_REG_BIAP 5
#define CRISV10_REG_ABS 10
#define CRISV10_REG_DSTEP 11
#define CRISV10_REG_LZ 12
#define CRISV10_REG_NOT 13
#define CRISV10_REG_SWAP 13
#define CRISV10_REG_XOR 14
#define CRISV10_REG_MSTEP 15
/* Indirect, var size. */
#define CRISV10_IND_TEST 14
#define CRISV10_IND_MUL 4
#define CRISV10_IND_BDAP_M 5
#define CRISV10_IND_ADD 8
#define CRISV10_IND_MOVE_M_R 9
/* indirect fixed size. */
#define CRISV10_IND_ADDX 0
#define CRISV10_IND_MOVX 1
#define CRISV10_IND_SUBX 2
#define CRISV10_IND_CMPX 3
#define CRISV10_IND_JUMP_M 4
#define CRISV10_IND_DIP 5
#define CRISV10_IND_JUMP_R 6
#define CRISV17_IND_ADDC 6
#define CRISV10_IND_BOUND 7
#define CRISV10_IND_BCC_M 7
#define CRISV10_IND_MOVE_M_SPR 8
#define CRISV10_IND_MOVE_SPR_M 9
#define CRISV10_IND_SUB 10
#define CRISV10_IND_CMP 11
#define CRISV10_IND_AND 12
#define CRISV10_IND_OR 13
#define CRISV10_IND_MOVE_R_M 15
#define CRISV10_IND_MOVEM_M_R 14
#define CRISV10_IND_MOVEM_R_M 15
#endif

View File

@ -1,133 +0,0 @@
/*
* CRIS insn decoding macros.
*
* Copyright (c) 2007 AXIS Communications AB
* Written by Edgar E. Iglesias.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CRISV32_DECODE_H
#define CRISV32_DECODE_H
/* Convenient binary macros. */
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+ ((x&0x000000F0LU)?2:0) \
+ ((x&0x00000F00LU)?4:0) \
+ ((x&0x0000F000LU)?8:0) \
+ ((x&0x000F0000LU)?16:0) \
+ ((x&0x00F00000LU)?32:0) \
+ ((x&0x0F000000LU)?64:0) \
+ ((x&0xF0000000LU)?128:0)
#define B8(d) ((unsigned char)B8__(HEX__(d)))
/* Quick imm. */
#define DEC_BCCQ {B8(00000000), B8(11110000)}
#define DEC_ADDOQ {B8(00010000), B8(11110000)}
#define DEC_ADDQ {B8(00100000), B8(11111100)}
#define DEC_MOVEQ {B8(00100100), B8(11111100)}
#define DEC_SUBQ {B8(00101000), B8(11111100)}
#define DEC_CMPQ {B8(00101100), B8(11111100)}
#define DEC_ANDQ {B8(00110000), B8(11111100)}
#define DEC_ORQ {B8(00110100), B8(11111100)}
#define DEC_BTSTQ {B8(00111000), B8(11111110)}
#define DEC_ASRQ {B8(00111010), B8(11111110)}
#define DEC_LSLQ {B8(00111100), B8(11111110)}
#define DEC_LSRQ {B8(00111110), B8(11111110)}
/* Register. */
#define DEC_MOVU_R {B8(01000100), B8(11111110)}
#define DEC_MOVU_R {B8(01000100), B8(11111110)}
#define DEC_MOVS_R {B8(01000110), B8(11111110)}
#define DEC_MOVE_R {B8(01100100), B8(11111100)}
#define DEC_MOVE_RP {B8(01100011), B8(11111111)}
#define DEC_MOVE_PR {B8(01100111), B8(11111111)}
#define DEC_DSTEP_R {B8(01101111), B8(11111111)}
#define DEC_MOVE_RS {B8(10110111), B8(11111111)}
#define DEC_MOVE_SR {B8(11110111), B8(11111111)}
#define DEC_ADDU_R {B8(01000000), B8(11111110)}
#define DEC_ADDS_R {B8(01000010), B8(11111110)}
#define DEC_ADD_R {B8(01100000), B8(11111100)}
#define DEC_ADDI_R {B8(01010000), B8(11111100)}
#define DEC_MULS_R {B8(11010000), B8(11111100)}
#define DEC_MULU_R {B8(10010000), B8(11111100)}
#define DEC_ADDI_ACR {B8(01010100), B8(11111100)}
#define DEC_NEG_R {B8(01011000), B8(11111100)}
#define DEC_BOUND_R {B8(01011100), B8(11111100)}
#define DEC_SUBU_R {B8(01001000), B8(11111110)}
#define DEC_SUBS_R {B8(01001010), B8(11111110)}
#define DEC_SUB_R {B8(01101000), B8(11111100)}
#define DEC_CMP_R {B8(01101100), B8(11111100)}
#define DEC_AND_R {B8(01110000), B8(11111100)}
#define DEC_ABS_R {B8(01101011), B8(11111111)}
#define DEC_LZ_R {B8(01110011), B8(11111111)}
#define DEC_MCP_R {B8(01111111), B8(11111111)}
#define DEC_SWAP_R {B8(01110111), B8(11111111)}
#define DEC_XOR_R {B8(01111011), B8(11111111)}
#define DEC_LSL_R {B8(01001100), B8(11111100)}
#define DEC_LSR_R {B8(01111100), B8(11111100)}
#define DEC_ASR_R {B8(01111000), B8(11111100)}
#define DEC_OR_R {B8(01110100), B8(11111100)}
#define DEC_BTST_R {B8(01001111), B8(11111111)}
/* Fixed. */
#define DEC_SETF {B8(01011011), B8(11111111)}
#define DEC_CLEARF {B8(01011111), B8(11111111)}
/* Memory. */
#define DEC_ADDU_M {B8(10000000), B8(10111110)}
#define DEC_ADDS_M {B8(10000010), B8(10111110)}
#define DEC_MOVU_M {B8(10000100), B8(10111110)}
#define DEC_MOVS_M {B8(10000110), B8(10111110)}
#define DEC_SUBU_M {B8(10001000), B8(10111110)}
#define DEC_SUBS_M {B8(10001010), B8(10111110)}
#define DEC_CMPU_M {B8(10001100), B8(10111110)}
#define DEC_CMPS_M {B8(10001110), B8(10111110)}
#define DEC_ADDO_M {B8(10010100), B8(10111100)}
#define DEC_BOUND_M {B8(10011100), B8(10111100)}
#define DEC_ADD_M {B8(10100000), B8(10111100)}
#define DEC_MOVE_MR {B8(10100100), B8(10111100)}
#define DEC_SUB_M {B8(10101000), B8(10111100)}
#define DEC_CMP_M {B8(10101100), B8(10111100)}
#define DEC_AND_M {B8(10110000), B8(10111100)}
#define DEC_OR_M {B8(10110100), B8(10111100)}
#define DEC_TEST_M {B8(10111000), B8(10111100)}
#define DEC_MOVE_RM {B8(10111100), B8(10111100)}
#define DEC_ADDC_R {B8(01010111), B8(11111111)}
#define DEC_ADDC_MR {B8(10011010), B8(10111111)}
#define DEC_LAPCQ {B8(10010111), B8(11111111)}
#define DEC_LAPC_IM {B8(11010111), B8(11111111)}
#define DEC_MOVE_MP {B8(10100011), B8(10111111)}
#define DEC_MOVE_PM {B8(10100111), B8(10111111)}
#define DEC_SCC_R {B8(01010011), B8(11111111)}
#define DEC_RFE_ETC {B8(10010011), B8(11111111)}
#define DEC_JUMP_P {B8(10011111), B8(11111111)}
#define DEC_BCC_IM {B8(11011111), B8(11111111)}
#define DEC_JAS_R {B8(10011011), B8(11111111)}
#define DEC_JASC_R {B8(10110011), B8(11111111)}
#define DEC_JAS_IM {B8(11011011), B8(11111111)}
#define DEC_JASC_IM {B8(11110011), B8(11111111)}
#define DEC_BAS_IM {B8(11101011), B8(11111111)}
#define DEC_BASC_IM {B8(11101111), B8(11111111)}
#define DEC_MOVEM_MR {B8(10111011), B8(10111111)}
#define DEC_MOVEM_RM {B8(10111111), B8(10111111)}
#define DEC_FTAG_FIDX_D_M {B8(10101011), B8(11111111)}
#define DEC_FTAG_FIDX_I_M {B8(11010011), B8(11111111)}
#endif

View File

@ -1,127 +0,0 @@
/*
* CRIS gdb server stub
*
* Copyright (c) 2003-2005 Fabrice Bellard
* Copyright (c) 2013 SUSE LINUX Products GmbH
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "gdbstub/helpers.h"
int crisv10_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
CPUCRISState *env = cpu_env(cs);
if (n < 15) {
return gdb_get_reg32(mem_buf, env->regs[n]);
}
if (n == 15) {
return gdb_get_reg32(mem_buf, env->pc);
}
if (n < 32) {
switch (n) {
case 16:
return gdb_get_reg8(mem_buf, env->pregs[n - 16]);
case 17:
return gdb_get_reg8(mem_buf, env->pregs[n - 16]);
case 20:
case 21:
return gdb_get_reg16(mem_buf, env->pregs[n - 16]);
default:
if (n >= 23) {
return gdb_get_reg32(mem_buf, env->pregs[n - 16]);
}
break;
}
}
return 0;
}
int cris_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
CPUCRISState *env = cpu_env(cs);
uint8_t srs;
srs = env->pregs[PR_SRS];
if (n < 16) {
return gdb_get_reg32(mem_buf, env->regs[n]);
}
if (n >= 21 && n < 32) {
return gdb_get_reg32(mem_buf, env->pregs[n - 16]);
}
if (n >= 33 && n < 49) {
return gdb_get_reg32(mem_buf, env->sregs[srs][n - 33]);
}
switch (n) {
case 16:
return gdb_get_reg8(mem_buf, env->pregs[0]);
case 17:
return gdb_get_reg8(mem_buf, env->pregs[1]);
case 18:
return gdb_get_reg32(mem_buf, env->pregs[2]);
case 19:
return gdb_get_reg8(mem_buf, srs);
case 20:
return gdb_get_reg16(mem_buf, env->pregs[4]);
case 32:
return gdb_get_reg32(mem_buf, env->pc);
}
return 0;
}
int cris_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
CPUCRISState *env = cpu_env(cs);
uint32_t tmp;
if (n > 49) {
return 0;
}
tmp = ldl_p(mem_buf);
if (n < 16) {
env->regs[n] = tmp;
}
if (n >= 21 && n < 32) {
env->pregs[n - 16] = tmp;
}
/* FIXME: Should support function regs be writable? */
switch (n) {
case 16:
return 1;
case 17:
return 1;
case 18:
env->pregs[PR_PID] = tmp;
break;
case 19:
return 1;
case 20:
return 2;
case 32:
env->pc = tmp;
break;
}
return 4;
}

View File

@ -1,287 +0,0 @@
/*
* CRIS helper routines.
*
* Copyright (c) 2007 AXIS Communications AB
* Written by Edgar E. Iglesias.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
#include "hw/core/tcg-cpu-ops.h"
#include "mmu.h"
#include "qemu/host-utils.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#include "exec/helper-proto.h"
//#define CRIS_HELPER_DEBUG
#ifdef CRIS_HELPER_DEBUG
#define D(x) x
#define D_LOG(...) qemu_log(__VA_ARGS__)
#else
#define D(x)
#define D_LOG(...) do { } while (0)
#endif
static void cris_shift_ccs(CPUCRISState *env)
{
uint32_t ccs;
/* Apply the ccs shift. */
ccs = env->pregs[PR_CCS];
ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
env->pregs[PR_CCS] = ccs;
}
bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr)
{
CPUCRISState *env = cpu_env(cs);
struct cris_mmu_result res;
int prot, miss;
target_ulong phy;
miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
access_type, mmu_idx, 0);
if (likely(!miss)) {
/*
* Mask off the cache selection bit. The ETRAX busses do not
* see the top bit.
*/
phy = res.phy & ~0x80000000;
prot = res.prot;
tlb_set_page(cs, address & TARGET_PAGE_MASK, phy,
prot, mmu_idx, TARGET_PAGE_SIZE);
return true;
}
if (probe) {
return false;
}
if (cs->exception_index == EXCP_BUSFAULT) {
cpu_abort(cs, "CRIS: Illegal recursive bus fault."
"addr=%" VADDR_PRIx " access_type=%d\n",
address, access_type);
}
env->pregs[PR_EDA] = address;
cs->exception_index = EXCP_BUSFAULT;
env->fault_vector = res.bf_vec;
if (retaddr) {
if (cpu_restore_state(cs, retaddr)) {
/* Evaluate flags after retranslation. */
helper_top_evaluate_flags(env);
}
}
cpu_loop_exit(cs);
}
void crisv10_cpu_do_interrupt(CPUState *cs)
{
CPUCRISState *env = cpu_env(cs);
int ex_vec = -1;
D_LOG("exception index=%d interrupt_req=%d\n",
cs->exception_index,
cs->interrupt_request);
if (env->dslot) {
/* CRISv10 never takes interrupts while in a delay-slot. */
cpu_abort(cs, "CRIS: Interrupt on delay-slot\n");
}
assert(!(env->pregs[PR_CCS] & PFIX_FLAG));
switch (cs->exception_index) {
case EXCP_BREAK:
/* These exceptions are generated by the core itself.
ERP should point to the insn following the brk. */
ex_vec = env->trap_vector;
env->pregs[PRV10_BRP] = env->pc;
break;
case EXCP_NMI:
/* NMI is hardwired to vector zero. */
ex_vec = 0;
env->pregs[PR_CCS] &= ~M_FLAG_V10;
env->pregs[PRV10_BRP] = env->pc;
break;
case EXCP_BUSFAULT:
cpu_abort(cs, "Unhandled busfault");
break;
default:
/* The interrupt controller gives us the vector. */
ex_vec = env->interrupt_vector;
/* Normal interrupts are taken between
TB's. env->pc is valid here. */
env->pregs[PR_ERP] = env->pc;
break;
}
if (env->pregs[PR_CCS] & U_FLAG) {
/* Swap stack pointers. */
env->pregs[PR_USP] = env->regs[R_SP];
env->regs[R_SP] = env->ksp;
}
/* Now that we are in kernel mode, load the handlers address. */
env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
env->locked_irq = 1;
env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */
qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
__func__, env->pc, ex_vec,
env->pregs[PR_CCS],
env->pregs[PR_PID],
env->pregs[PR_ERP]);
}
void cris_cpu_do_interrupt(CPUState *cs)
{
CPUCRISState *env = cpu_env(cs);
int ex_vec = -1;
D_LOG("exception index=%d interrupt_req=%d\n",
cs->exception_index,
cs->interrupt_request);
switch (cs->exception_index) {
case EXCP_BREAK:
/* These exceptions are generated by the core itself.
ERP should point to the insn following the brk. */
ex_vec = env->trap_vector;
env->pregs[PR_ERP] = env->pc;
break;
case EXCP_NMI:
/* NMI is hardwired to vector zero. */
ex_vec = 0;
env->pregs[PR_CCS] &= ~M_FLAG_V32;
env->pregs[PR_NRP] = env->pc;
break;
case EXCP_BUSFAULT:
ex_vec = env->fault_vector;
env->pregs[PR_ERP] = env->pc;
break;
default:
/* The interrupt controller gives us the vector. */
ex_vec = env->interrupt_vector;
/* Normal interrupts are taken between
TB's. env->pc is valid here. */
env->pregs[PR_ERP] = env->pc;
break;
}
/* Fill in the IDX field. */
env->pregs[PR_EXS] = (ex_vec & 0xff) << 8;
if (env->dslot) {
D_LOG("excp isr=%x PC=%x ds=%d SP=%x"
" ERP=%x pid=%x ccs=%x cc=%d %x\n",
ex_vec, env->pc, env->dslot,
env->regs[R_SP],
env->pregs[PR_ERP], env->pregs[PR_PID],
env->pregs[PR_CCS],
env->cc_op, env->cc_mask);
/* We loose the btarget, btaken state here so rexec the
branch. */
env->pregs[PR_ERP] -= env->dslot;
/* Exception starts with dslot cleared. */
env->dslot = 0;
}
if (env->pregs[PR_CCS] & U_FLAG) {
/* Swap stack pointers. */
env->pregs[PR_USP] = env->regs[R_SP];
env->regs[R_SP] = env->ksp;
}
/* Apply the CRIS CCS shift. Clears U if set. */
cris_shift_ccs(env);
/* Now that we are in kernel mode, load the handlers address.
This load may not fault, real hw leaves that behaviour as
undefined. */
env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
/* Clear the excption_index to avoid spurious hw_aborts for recursive
bus faults. */
cs->exception_index = -1;
D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
__func__, env->pc, ex_vec,
env->pregs[PR_CCS],
env->pregs[PR_PID],
env->pregs[PR_ERP]);
}
hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
CRISCPU *cpu = CRIS_CPU(cs);
uint32_t phy = addr;
struct cris_mmu_result res;
int miss;
miss = cris_mmu_translate(&res, &cpu->env, addr, MMU_DATA_LOAD, 0, 1);
/* If D TLB misses, try I TLB. */
if (miss) {
miss = cris_mmu_translate(&res, &cpu->env, addr, MMU_INST_FETCH, 0, 1);
}
if (!miss) {
phy = res.phy;
}
D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
return phy;
}
bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
CPUClass *cc = CPU_GET_CLASS(cs);
CPUCRISState *env = cpu_env(cs);
bool ret = false;
if (interrupt_request & CPU_INTERRUPT_HARD
&& (env->pregs[PR_CCS] & I_FLAG)
&& !env->locked_irq) {
cs->exception_index = EXCP_IRQ;
cc->tcg_ops->do_interrupt(cs);
ret = true;
}
if (interrupt_request & CPU_INTERRUPT_NMI) {
unsigned int m_flag_archval;
if (env->pregs[PR_VR] < 32) {
m_flag_archval = M_FLAG_V10;
} else {
m_flag_archval = M_FLAG_V32;
}
if ((env->pregs[PR_CCS] & m_flag_archval)) {
cs->exception_index = EXCP_NMI;
cc->tcg_ops->do_interrupt(cs);
ret = true;
}
}
return ret;
}

View File

@ -1,23 +0,0 @@
DEF_HELPER_2(raise_exception, noreturn, env, i32)
DEF_HELPER_2(tlb_flush_pid, void, env, i32)
DEF_HELPER_2(spc_write, void, env, i32)
DEF_HELPER_1(rfe, void, env)
DEF_HELPER_1(rfn, void, env)
DEF_HELPER_3(movl_sreg_reg, void, env, i32, i32)
DEF_HELPER_3(movl_reg_sreg, void, env, i32, i32)
DEF_HELPER_FLAGS_4(btst, TCG_CALL_NO_SE, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(evaluate_flags_muls, TCG_CALL_NO_SE, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(evaluate_flags_mulu, TCG_CALL_NO_SE, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_5(evaluate_flags_mcp, TCG_CALL_NO_SE, i32, env,
i32, i32, i32, i32)
DEF_HELPER_FLAGS_5(evaluate_flags_alu_4, TCG_CALL_NO_SE, i32, env,
i32, i32, i32, i32)
DEF_HELPER_FLAGS_5(evaluate_flags_sub_4, TCG_CALL_NO_SE, i32, env,
i32, i32, i32, i32)
DEF_HELPER_FLAGS_3(evaluate_flags_move_4, TCG_CALL_NO_SE, i32, env, i32, i32)
DEF_HELPER_FLAGS_3(evaluate_flags_move_2, TCG_CALL_NO_SE, i32, env, i32, i32)
DEF_HELPER_1(evaluate_flags, void, env)
DEF_HELPER_1(top_evaluate_flags, void, env)

View File

@ -1,93 +0,0 @@
/*
* CRIS virtual CPU state save/load support
*
* Copyright (c) 2012 Red Hat, Inc.
* Written by Juan Quintela <quintela@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "migration/cpu.h"
static const VMStateDescription vmstate_tlbset = {
.name = "cpu/tlbset",
.version_id = 1,
.minimum_version_id = 1,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(lo, TLBSet),
VMSTATE_UINT32(hi, TLBSet),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_cris_env = {
.name = "env",
.version_id = 2,
.minimum_version_id = 2,
.fields = (const VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, CPUCRISState, 16),
VMSTATE_UINT32_ARRAY(pregs, CPUCRISState, 16),
VMSTATE_UINT32(pc, CPUCRISState),
VMSTATE_UINT32(ksp, CPUCRISState),
VMSTATE_INT32(dslot, CPUCRISState),
VMSTATE_INT32(btaken, CPUCRISState),
VMSTATE_UINT32(btarget, CPUCRISState),
VMSTATE_UINT32(cc_op, CPUCRISState),
VMSTATE_UINT32(cc_mask, CPUCRISState),
VMSTATE_UINT32(cc_dest, CPUCRISState),
VMSTATE_UINT32(cc_src, CPUCRISState),
VMSTATE_UINT32(cc_result, CPUCRISState),
VMSTATE_INT32(cc_size, CPUCRISState),
VMSTATE_INT32(cc_x, CPUCRISState),
VMSTATE_INT32(locked_irq, CPUCRISState),
VMSTATE_INT32(interrupt_vector, CPUCRISState),
VMSTATE_INT32(fault_vector, CPUCRISState),
VMSTATE_INT32(trap_vector, CPUCRISState),
VMSTATE_UINT32_ARRAY(sregs[0], CPUCRISState, 16),
VMSTATE_UINT32_ARRAY(sregs[1], CPUCRISState, 16),
VMSTATE_UINT32_ARRAY(sregs[2], CPUCRISState, 16),
VMSTATE_UINT32_ARRAY(sregs[3], CPUCRISState, 16),
VMSTATE_UINT32(mmu_rand_lfsr, CPUCRISState),
VMSTATE_STRUCT_ARRAY(tlbsets[0][0], CPUCRISState, 16, 0,
vmstate_tlbset, TLBSet),
VMSTATE_STRUCT_ARRAY(tlbsets[0][1], CPUCRISState, 16, 0,
vmstate_tlbset, TLBSet),
VMSTATE_STRUCT_ARRAY(tlbsets[0][2], CPUCRISState, 16, 0,
vmstate_tlbset, TLBSet),
VMSTATE_STRUCT_ARRAY(tlbsets[0][3], CPUCRISState, 16, 0,
vmstate_tlbset, TLBSet),
VMSTATE_STRUCT_ARRAY(tlbsets[1][0], CPUCRISState, 16, 0,
vmstate_tlbset, TLBSet),
VMSTATE_STRUCT_ARRAY(tlbsets[1][1], CPUCRISState, 16, 0,
vmstate_tlbset, TLBSet),
VMSTATE_STRUCT_ARRAY(tlbsets[1][2], CPUCRISState, 16, 0,
vmstate_tlbset, TLBSet),
VMSTATE_STRUCT_ARRAY(tlbsets[1][3], CPUCRISState, 16, 0,
vmstate_tlbset, TLBSet),
VMSTATE_END_OF_LIST()
}
};
const VMStateDescription vmstate_cris_cpu = {
.name = "cpu",
.version_id = 1,
.minimum_version_id = 1,
.fields = (const VMStateField[]) {
VMSTATE_CPU(),
VMSTATE_STRUCT(env, CRISCPU, 1, vmstate_cris_env, CPUCRISState),
VMSTATE_END_OF_LIST()
}
};

Some files were not shown because too many files have changed in this diff Show More